Merge branches 'clk-ingenic', 'clk-mtk-mux', 'clk-qcom-sdm845-pcie', 'clk-mtk-crit...
[sfrench/cifs-2.6.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_IRQ_NO_AUTOSAVE
21 .ifnc \called_from, exception
22         st.as   r9, [sp, -10]   ; save r9 in it's final stack slot
23         sub     sp, sp, 12      ; skip JLI, LDI, EI
24
25         PUSH    lp_count
26         PUSHAX  lp_start
27         PUSHAX  lp_end
28         PUSH    blink
29
30         PUSH    r11
31         PUSH    r10
32
33         sub     sp, sp, 4       ; skip r9
34
35         PUSH    r8
36         PUSH    r7
37         PUSH    r6
38         PUSH    r5
39         PUSH    r4
40         PUSH    r3
41         PUSH    r2
42         PUSH    r1
43         PUSH    r0
44 .endif
45 #endif
46
47 #ifdef CONFIG_ARC_HAS_ACCL_REGS
48         PUSH    r59
49         PUSH    r58
50 #endif
51
52         PUSH    r30
53         PUSH    r12
54
55         ; Saving pt_regs->sp correctly requires some extra work due to the way
56         ; Auto stack switch works
57         ;  - U mode: retrieve it from AUX_USER_SP
58         ;  - K mode: add the offset from current SP where H/w starts auto push
59         ;
60         ; Utilize the fact that Z bit is set if Intr taken in U mode
61         mov.nz  r9, sp
62         add.nz  r9, r9, SZ_PT_REGS - PT_sp - 4
63         bnz     1f
64
65         lr      r9, [AUX_USER_SP]
66 1:
67         PUSH    r9      ; SP
68
69         PUSH    fp
70         PUSH    gp
71
72 #ifdef CONFIG_ARC_CURR_IN_REG
73         PUSH    r25                     ; user_r25
74         GET_CURR_TASK_ON_CPU    r25
75 #else
76         sub     sp, sp, 4
77 #endif
78
79 .ifnc \called_from, exception
80         sub     sp, sp, 12      ; BTA/ECR/orig_r0 placeholder per pt_regs
81 .endif
82
83 .endm
84
85 /*------------------------------------------------------------------------*/
86 .macro INTERRUPT_EPILOGUE       called_from
87
88 .ifnc \called_from, exception
89         add     sp, sp, 12      ; skip BTA/ECR/orig_r0 placeholderss
90 .endif
91
92 #ifdef CONFIG_ARC_CURR_IN_REG
93         POP     r25
94 #else
95         add     sp, sp, 4
96 #endif
97
98         POP     gp
99         POP     fp
100
101         ; Don't touch AUX_USER_SP if returning to K mode (Z bit set)
102         ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE)
103         add.z   sp, sp, 4
104         bz      1f
105
106         POPAX   AUX_USER_SP
107 1:
108         POP     r12
109         POP     r30
110
111 #ifdef CONFIG_ARC_HAS_ACCL_REGS
112         POP     r58
113         POP     r59
114 #endif
115
116 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
117 .ifnc \called_from, exception
118         POP     r0
119         POP     r1
120         POP     r2
121         POP     r3
122         POP     r4
123         POP     r5
124         POP     r6
125         POP     r7
126         POP     r8
127         POP     r9
128         POP     r10
129         POP     r11
130
131         POP     blink
132         POPAX   lp_end
133         POPAX   lp_start
134
135         POP     r9
136         mov     lp_count, r9
137
138         add     sp, sp, 12      ; skip JLI, LDI, EI
139         ld.as   r9, [sp, -10]   ; reload r9 which got clobbered
140 .endif
141 #endif
142
143 .endm
144
145 /*------------------------------------------------------------------------*/
146 .macro EXCEPTION_PROLOGUE
147
148         ; Before jumping to Exception Vector, hardware micro-ops did following:
149         ;   1. SP auto-switched to kernel mode stack
150         ;   2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0)
151         ;
152         ; Now manually save the complete reg file
153
154         PUSH    r9              ; freeup a register: slot of erstatus
155
156         PUSHAX  eret
157         sub     sp, sp, 12      ; skip JLI, LDI, EI
158         PUSH    lp_count
159         PUSHAX  lp_start
160         PUSHAX  lp_end
161         PUSH    blink
162
163         PUSH    r11
164         PUSH    r10
165
166         ld.as   r9,  [sp, 10]   ; load stashed r9 (status32 stack slot)
167         lr      r10, [erstatus]
168         st.as   r10, [sp, 10]   ; save status32 at it's right stack slot
169
170         PUSH    r9
171         PUSH    r8
172         PUSH    r7
173         PUSH    r6
174         PUSH    r5
175         PUSH    r4
176         PUSH    r3
177         PUSH    r2
178         PUSH    r1
179         PUSH    r0
180
181         ; -- for interrupts, regs above are auto-saved by h/w in that order --
182         ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25)
183         ;
184         ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE)
185         ; Although H/w exception micro-ops do set Z flag for U mode (just like
186         ; for interrupts), it could get clobbered in case we soft land here from
187         ; a TLB Miss exception handler (tlbex.S)
188
189         and     r10, r10, STATUS_U_MASK
190         xor.f   0, r10, STATUS_U_MASK
191
192         INTERRUPT_PROLOGUE  exception
193
194         PUSHAX  erbta
195         PUSHAX  ecr             ; r9 contains ECR, expected by EV_Trap
196
197         PUSH    r0              ; orig_r0
198 .endm
199
200 /*------------------------------------------------------------------------*/
201 .macro EXCEPTION_EPILOGUE
202
203         ; Assumes r0 has PT_status32
204         btst   r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE
205
206         add     sp, sp, 8       ; orig_r0/ECR don't need restoring
207         POPAX   erbta
208
209         INTERRUPT_EPILOGUE  exception
210
211         POP     r0
212         POP     r1
213         POP     r2
214         POP     r3
215         POP     r4
216         POP     r5
217         POP     r6
218         POP     r7
219         POP     r8
220         POP     r9
221         POP     r10
222         POP     r11
223
224         POP     blink
225         POPAX   lp_end
226         POPAX   lp_start
227
228         POP     r9
229         mov     lp_count, r9
230
231         add     sp, sp, 12      ; skip JLI, LDI, EI
232         POPAX   eret
233         POPAX   erstatus
234
235         ld.as   r9, [sp, -12]   ; reload r9 which got clobbered
236 .endm
237
238 .macro FAKE_RET_FROM_EXCPN
239         lr      r9, [status32]
240         bic     r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
241         or      r9, r9, STATUS_IE_MASK
242         kflag   r9
243 .endm
244
245 /* Get thread_info of "current" tsk */
246 .macro GET_CURR_THR_INFO_FROM_SP  reg
247         bmskn \reg, sp, THREAD_SHIFT - 1
248 .endm
249
250 /* Get CPU-ID of this core */
251 .macro  GET_CPU_ID  reg
252         lr  \reg, [identity]
253         xbfu \reg, \reg, 0xE8   /* 00111    01000 */
254                                 /* M = 8-1  N = 8 */
255 .endm
256
257 #endif