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