These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / arc / include / asm / entry-arcv2.h
1
2 #ifndef __ASM_ARC_ENTRY_ARCV2_H
3 #define __ASM_ARC_ENTRY_ARCV2_H
4
5 #include <asm/asm-offsets.h>
6 #include <asm/irqflags-arcv2.h>
7 #include <asm/thread_info.h>    /* For THREAD_SIZE */
8
9 /*------------------------------------------------------------------------*/
10 .macro INTERRUPT_PROLOGUE       called_from
11
12         ; Before jumping to Interrupt Vector, hardware micro-ops did following:
13         ;   1. SP auto-switched to kernel mode stack
14         ;   2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0)
15         ;   3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32
16         ;
17         ; Now manually save: r12, sp, fp, gp, r25
18
19         PUSH    r12
20
21         ; Saving pt_regs->sp correctly requires some extra work due to the way
22         ; Auto stack switch works
23         ;  - U mode: retrieve it from AUX_USER_SP
24         ;  - K mode: add the offset from current SP where H/w starts auto push
25         ;
26         ; Utilize the fact that Z bit is set if Intr taken in U mode
27         mov.nz  r9, sp
28         add.nz  r9, r9, SZ_PT_REGS - PT_sp - 4
29         bnz     1f
30
31         lr      r9, [AUX_USER_SP]
32 1:
33         PUSH    r9      ; SP
34
35         PUSH    fp
36         PUSH    gp
37
38 #ifdef CONFIG_ARC_CURR_IN_REG
39         PUSH    r25                     ; user_r25
40         GET_CURR_TASK_ON_CPU    r25
41 #else
42         sub     sp, sp, 4
43 #endif
44
45 .ifnc \called_from, exception
46         sub     sp, sp, 12      ; BTA/ECR/orig_r0 placeholder per pt_regs
47 .endif
48
49 .endm
50
51 /*------------------------------------------------------------------------*/
52 .macro INTERRUPT_EPILOGUE       called_from
53
54 .ifnc \called_from, exception
55         add     sp, sp, 12      ; skip BTA/ECR/orig_r0 placeholderss
56 .endif
57
58 #ifdef CONFIG_ARC_CURR_IN_REG
59         POP     r25
60 #else
61         add     sp, sp, 4
62 #endif
63
64         POP     gp
65         POP     fp
66
67         ; Don't touch AUX_USER_SP if returning to K mode (Z bit set)
68         ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE)
69         add.z   sp, sp, 4
70         bz      1f
71
72         POPAX   AUX_USER_SP
73 1:
74         POP     r12
75
76 .endm
77
78 /*------------------------------------------------------------------------*/
79 .macro EXCEPTION_PROLOGUE
80
81         ; Before jumping to Exception Vector, hardware micro-ops did following:
82         ;   1. SP auto-switched to kernel mode stack
83         ;   2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0)
84         ;
85         ; Now manually save the complete reg file
86
87         PUSH    r9              ; freeup a register: slot of erstatus
88
89         PUSHAX  eret
90         sub     sp, sp, 12      ; skip JLI, LDI, EI
91         PUSH    lp_count
92         PUSHAX  lp_start
93         PUSHAX  lp_end
94         PUSH    blink
95
96         PUSH    r11
97         PUSH    r10
98
99         ld.as   r9,  [sp, 10]   ; load stashed r9 (status32 stack slot)
100         lr      r10, [erstatus]
101         st.as   r10, [sp, 10]   ; save status32 at it's right stack slot
102
103         PUSH    r9
104         PUSH    r8
105         PUSH    r7
106         PUSH    r6
107         PUSH    r5
108         PUSH    r4
109         PUSH    r3
110         PUSH    r2
111         PUSH    r1
112         PUSH    r0
113
114         ; -- for interrupts, regs above are auto-saved by h/w in that order --
115         ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25)
116         ;
117         ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE)
118         ; Although H/w exception micro-ops do set Z flag for U mode (just like
119         ; for interrupts), it could get clobbered in case we soft land here from
120         ; a TLB Miss exception handler (tlbex.S)
121
122         and     r10, r10, STATUS_U_MASK
123         xor.f   0, r10, STATUS_U_MASK
124
125         INTERRUPT_PROLOGUE  exception
126
127         PUSHAX  erbta
128         PUSHAX  ecr             ; r9 contains ECR, expected by EV_Trap
129
130         PUSH    r0              ; orig_r0
131 .endm
132
133 /*------------------------------------------------------------------------*/
134 .macro EXCEPTION_EPILOGUE
135
136         ; Assumes r0 has PT_status32
137         btst   r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE
138
139         add     sp, sp, 8       ; orig_r0/ECR don't need restoring
140         POPAX   erbta
141
142         INTERRUPT_EPILOGUE  exception
143
144         POP     r0
145         POP     r1
146         POP     r2
147         POP     r3
148         POP     r4
149         POP     r5
150         POP     r6
151         POP     r7
152         POP     r8
153         POP     r9
154         POP     r10
155         POP     r11
156
157         POP     blink
158         POPAX   lp_end
159         POPAX   lp_start
160
161         POP     r9
162         mov     lp_count, r9
163
164         add     sp, sp, 12      ; skip JLI, LDI, EI
165         POPAX   eret
166         POPAX   erstatus
167
168         ld.as   r9, [sp, -12]   ; reload r9 which got clobbered
169 .endm
170
171 .macro FAKE_RET_FROM_EXCPN
172         lr      r9, [status32]
173         bic     r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
174         or      r9, r9, (STATUS_L_MASK|STATUS_IE_MASK)
175         kflag   r9
176 .endm
177
178 /* Get thread_info of "current" tsk */
179 .macro GET_CURR_THR_INFO_FROM_SP  reg
180         bmskn \reg, sp, THREAD_SHIFT - 1
181 .endm
182
183 /* Get CPU-ID of this core */
184 .macro  GET_CPU_ID  reg
185         lr  \reg, [identity]
186         xbfu \reg, \reg, 0xE8   /* 00111    01000 */
187                                 /* M = 8-1  N = 8 */
188 .endm
189
190 #endif