]> git.ipfire.org Git - thirdparty/kernel/linux.git/blob - arch/arc/include/asm/entry-arcv2.h
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[thirdparty/kernel/linux.git] / arch / arc / include / asm / entry-arcv2.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __ASM_ARC_ENTRY_ARCV2_H
4 #define __ASM_ARC_ENTRY_ARCV2_H
5
6 #include <asm/asm-offsets.h>
7 #include <asm/irqflags-arcv2.h>
8 #include <asm/thread_info.h> /* For THREAD_SIZE */
9
10 /*------------------------------------------------------------------------*/
11 .macro INTERRUPT_PROLOGUE called_from
12
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
17 ;
18 ; Now manually save: r12, sp, fp, gp, r25
19
20 #ifdef CONFIG_ARC_HAS_ACCL_REGS
21 PUSH r59
22 PUSH r58
23 #endif
24
25 PUSH r30
26 PUSH r12
27
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
32 ;
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
37
38 lr r9, [AUX_USER_SP]
39 1:
40 PUSH r9 ; SP
41
42 PUSH fp
43 PUSH gp
44
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
51
52 .ifnc \called_from, exception
53 sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs
54 .endif
55
56 .endm
57
58 /*------------------------------------------------------------------------*/
59 .macro INTERRUPT_EPILOGUE called_from
60
61 .ifnc \called_from, exception
62 add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss
63 .endif
64
65 #ifdef CONFIG_ARC_CURR_IN_REG
66 POP r25
67 #else
68 add sp, sp, 4
69 #endif
70
71 POP gp
72 POP fp
73
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
78
79 POPAX AUX_USER_SP
80 1:
81 POP r12
82 POP r30
83
84 #ifdef CONFIG_ARC_HAS_ACCL_REGS
85 POP r58
86 POP r59
87 #endif
88
89 .endm
90
91 /*------------------------------------------------------------------------*/
92 .macro EXCEPTION_PROLOGUE
93
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)
97 ;
98 ; Now manually save the complete reg file
99
100 PUSH r9 ; freeup a register: slot of erstatus
101
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
108
109 PUSH r11
110 PUSH r10
111
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
115
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
126
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)
129 ;
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)
134
135 and r10, r10, STATUS_U_MASK
136 xor.f 0, r10, STATUS_U_MASK
137
138 INTERRUPT_PROLOGUE exception
139
140 PUSHAX erbta
141 PUSHAX ecr ; r9 contains ECR, expected by EV_Trap
142
143 PUSH r0 ; orig_r0
144 .endm
145
146 /*------------------------------------------------------------------------*/
147 .macro EXCEPTION_EPILOGUE
148
149 ; Assumes r0 has PT_status32
150 btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE
151
152 add sp, sp, 8 ; orig_r0/ECR don't need restoring
153 POPAX erbta
154
155 INTERRUPT_EPILOGUE exception
156
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
169
170 POP blink
171 POPAX lp_end
172 POPAX lp_start
173
174 POP r9
175 mov lp_count, r9
176
177 add sp, sp, 12 ; skip JLI, LDI, EI
178 POPAX eret
179 POPAX erstatus
180
181 ld.as r9, [sp, -12] ; reload r9 which got clobbered
182 .endm
183
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_L_MASK|STATUS_IE_MASK)
188 kflag r9
189 .endm
190
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
195
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
202
203 #endif