Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arc/include/asm/entry-arcv2.h
26481 views
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/dsp-impl.h>
8
#include <asm/irqflags-arcv2.h>
9
#include <asm/thread_info.h> /* For THREAD_SIZE */
10
11
/*
12
* Interrupt/Exception stack layout (pt_regs) for ARCv2
13
* (End of struct aligned to end of page [unless nested])
14
*
15
* INTERRUPT EXCEPTION
16
*
17
* manual --------------------- manual
18
* | orig_r0 |
19
* | event/ECR |
20
* | bta |
21
* | gp |
22
* | fp |
23
* | sp |
24
* | r12 |
25
* | r30 |
26
* | r58 |
27
* | r59 |
28
* hw autosave ---------------------
29
* optional | r0 |
30
* | r1 |
31
* ~ ~
32
* | r9 |
33
* | r10 |
34
* | r11 |
35
* | blink |
36
* | lpe |
37
* | lps |
38
* | lpc |
39
* | ei base |
40
* | ldi base |
41
* | jli base |
42
* ---------------------
43
* hw autosave | pc / eret |
44
* mandatory | stat32 / erstatus |
45
* ---------------------
46
*/
47
48
/*------------------------------------------------------------------------*/
49
.macro INTERRUPT_PROLOGUE
50
51
; Before jumping to Interrupt Vector, hardware micro-ops did following:
52
; 1. SP auto-switched to kernel mode stack
53
; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
54
; 3. Auto save: (mandatory) Push PC and STAT32 on stack
55
; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
56
; 4a. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
57
;
58
; Now
59
; 4b. If Auto-save (optional) not enabled in hw, manually save them
60
; 5. Manually save: r12,r30, sp,fp,gp, ACCL pair
61
;
62
; At the end, SP points to pt_regs
63
64
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
65
; carve pt_regs on stack (case #3), PC/STAT32 already on stack
66
sub sp, sp, SZ_PT_REGS - 8
67
68
__SAVE_REGFILE_HARD
69
#else
70
; carve pt_regs on stack (case #4), which grew partially already
71
sub sp, sp, PT_r0
72
#endif
73
74
__SAVE_REGFILE_SOFT
75
.endm
76
77
/*------------------------------------------------------------------------*/
78
.macro EXCEPTION_PROLOGUE_KEEP_AE
79
80
; Before jumping to Exception Vector, hardware micro-ops did following:
81
; 1. SP auto-switched to kernel mode stack
82
; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
83
;
84
; Now manually save rest of reg file
85
; At the end, SP points to pt_regs
86
87
sub sp, sp, SZ_PT_REGS ; carve space for pt_regs
88
89
; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
90
91
__SAVE_REGFILE_HARD
92
__SAVE_REGFILE_SOFT
93
94
st r0, [sp] ; orig_r0
95
96
lr r10, [eret]
97
lr r11, [erstatus]
98
ST2 r10, r11, PT_ret
99
100
lr r10, [ecr]
101
lr r11, [erbta]
102
ST2 r10, r11, PT_event
103
104
; OUTPUT: r10 has ECR expected by EV_Trap
105
.endm
106
107
.macro EXCEPTION_PROLOGUE
108
109
EXCEPTION_PROLOGUE_KEEP_AE ; return ECR in r10
110
111
lr r0, [efa]
112
mov r1, sp
113
114
FAKE_RET_FROM_EXCPN ; clobbers r9
115
.endm
116
117
/*------------------------------------------------------------------------
118
* This macro saves the registers manually which would normally be autosaved
119
* by hardware on taken interrupts. It is used by
120
* - exception handlers (which don't have autosave)
121
* - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE
122
*/
123
.macro __SAVE_REGFILE_HARD
124
125
ST2 r0, r1, PT_r0
126
ST2 r2, r3, PT_r2
127
ST2 r4, r5, PT_r4
128
ST2 r6, r7, PT_r6
129
ST2 r8, r9, PT_r8
130
ST2 r10, r11, PT_r10
131
132
st blink, [sp, PT_blink]
133
134
lr r10, [lp_end]
135
lr r11, [lp_start]
136
ST2 r10, r11, PT_lpe
137
138
st lp_count, [sp, PT_lpc]
139
140
; skip JLI, LDI, EI for now
141
.endm
142
143
/*------------------------------------------------------------------------
144
* This macros saves a bunch of other registers which can't be autosaved for
145
* various reasons:
146
* - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11
147
* - r30: free reg, used by gcc as scratch
148
* - ACCL/ACCH pair when they exist
149
*/
150
.macro __SAVE_REGFILE_SOFT
151
152
st fp, [sp, PT_fp] ; r27
153
st r30, [sp, PT_r30]
154
st r12, [sp, PT_r12]
155
st r26, [sp, PT_r26] ; gp
156
157
; Saving pt_regs->sp correctly requires some extra work due to the way
158
; Auto stack switch works
159
; - U mode: retrieve it from AUX_USER_SP
160
; - K mode: add the offset from current SP where H/w starts auto push
161
;
162
; 1. Utilize the fact that Z bit is set if Intr taken in U mode
163
; 2. Upon entry SP is always saved (for any inspection, unwinding etc),
164
; but on return, restored only if U mode
165
166
lr r10, [AUX_USER_SP] ; U mode SP
167
168
; ISA requires ADD.nz to have same dest and src reg operands
169
mov.nz r10, sp
170
add2.nz r10, r10, SZ_PT_REGS/4 ; K mode SP
171
172
st r10, [sp, PT_sp] ; SP (pt_regs->sp)
173
174
#ifdef CONFIG_ARC_HAS_ACCL_REGS
175
ST2 r58, r59, PT_r58
176
#endif
177
178
/* clobbers r10, r11 registers pair */
179
DSP_SAVE_REGFILE_IRQ
180
181
#ifdef CONFIG_ARC_CURR_IN_REG
182
GET_CURR_TASK_ON_CPU gp
183
#endif
184
185
.endm
186
187
/*------------------------------------------------------------------------*/
188
.macro __RESTORE_REGFILE_SOFT
189
190
ld fp, [sp, PT_fp]
191
ld r30, [sp, PT_r30]
192
ld r12, [sp, PT_r12]
193
ld r26, [sp, PT_r26]
194
195
; Restore SP (into AUX_USER_SP) only if returning to U mode
196
; - for K mode, it will be implicitly restored as stack is unwound
197
; - Z flag set on K is inverse of what hardware does on interrupt entry
198
; but that doesn't really matter
199
bz 1f
200
201
ld r10, [sp, PT_sp] ; SP (pt_regs->sp)
202
sr r10, [AUX_USER_SP]
203
1:
204
205
/* clobbers r10, r11 registers pair */
206
DSP_RESTORE_REGFILE_IRQ
207
208
#ifdef CONFIG_ARC_HAS_ACCL_REGS
209
LD2 r58, r59, PT_r58
210
#endif
211
.endm
212
213
/*------------------------------------------------------------------------*/
214
.macro __RESTORE_REGFILE_HARD
215
216
ld blink, [sp, PT_blink]
217
218
LD2 r10, r11, PT_lpe
219
sr r10, [lp_end]
220
sr r11, [lp_start]
221
222
ld r10, [sp, PT_lpc] ; lp_count can't be target of LD
223
mov lp_count, r10
224
225
LD2 r0, r1, PT_r0
226
LD2 r2, r3, PT_r2
227
LD2 r4, r5, PT_r4
228
LD2 r6, r7, PT_r6
229
LD2 r8, r9, PT_r8
230
LD2 r10, r11, PT_r10
231
.endm
232
233
234
/*------------------------------------------------------------------------*/
235
.macro INTERRUPT_EPILOGUE
236
237
; INPUT: r0 has STAT32 of calling context
238
; INPUT: Z flag set if returning to K mode
239
240
; _SOFT clobbers r10 restored by _HARD hence the order
241
242
__RESTORE_REGFILE_SOFT
243
244
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
245
__RESTORE_REGFILE_HARD
246
247
; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE
248
add sp, sp, SZ_PT_REGS - 8
249
#else
250
add sp, sp, PT_r0
251
#endif
252
253
.endm
254
255
/*------------------------------------------------------------------------*/
256
.macro EXCEPTION_EPILOGUE
257
258
; INPUT: r0 has STAT32 of calling context
259
260
btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP
261
262
ld r10, [sp, PT_bta]
263
sr r10, [erbta]
264
265
LD2 r10, r11, PT_ret
266
sr r10, [eret]
267
sr r11, [erstatus]
268
269
__RESTORE_REGFILE_SOFT
270
__RESTORE_REGFILE_HARD
271
272
add sp, sp, SZ_PT_REGS
273
.endm
274
275
.macro FAKE_RET_FROM_EXCPN
276
lr r9, [status32]
277
bclr r9, r9, STATUS_AE_BIT
278
bset r9, r9, STATUS_IE_BIT
279
kflag r9
280
.endm
281
282
/* Get thread_info of "current" tsk */
283
.macro GET_CURR_THR_INFO_FROM_SP reg
284
bmskn \reg, sp, THREAD_SHIFT - 1
285
.endm
286
287
/* Get CPU-ID of this core */
288
.macro GET_CPU_ID reg
289
lr \reg, [identity]
290
xbfu \reg, \reg, 0xE8 /* 00111 01000 */
291
/* M = 8-1 N = 8 */
292
.endm
293
294
.macro SAVE_ABI_CALLEE_REGS
295
push r13
296
push r14
297
push r15
298
push r16
299
push r17
300
push r18
301
push r19
302
push r20
303
push r21
304
push r22
305
push r23
306
push r24
307
push r25
308
.endm
309
310
.macro RESTORE_ABI_CALLEE_REGS
311
pop r25
312
pop r24
313
pop r23
314
pop r22
315
pop r21
316
pop r20
317
pop r19
318
pop r18
319
pop r17
320
pop r16
321
pop r15
322
pop r14
323
pop r13
324
.endm
325
326
#endif
327
328