Linux Audio

Check our new training course

Loading...
v6.8
  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]
2031:
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
v5.9
  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 *              |      user_r25     |
 22 *              |      gp           |
 23 *              |      fp           |
 24 *              |      sp           |
 25 *              |      r12          |
 26 *              |      r30          |
 27 *              |      r58          |
 28 *              |      r59          |
 29 *  hw autosave ---------------------
 30 *    optional  |      r0           |
 31 *              |      r1           |
 32 *              ~                   ~
 33 *              |      r9           |
 34 *              |      r10          |
 35 *              |      r11          |
 36 *              |      blink        |
 37 *              |      lpe          |
 38 *              |      lps          |
 39 *              |      lpc          |
 40 *              |      ei base      |
 41 *              |      ldi base     |
 42 *              |      jli base     |
 43 *              ---------------------
 44 *  hw autosave |       pc / eret   |
 45 *   mandatory  | stat32 / erstatus |
 46 *              ---------------------
 47 */
 48
 49/*------------------------------------------------------------------------*/
 50.macro INTERRUPT_PROLOGUE
 51
 52	; (A) Before jumping to Interrupt Vector, hardware micro-ops did following:
 53	;   1. SP auto-switched to kernel mode stack
 54	;   2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
 55	;   3. Auto save: (mandatory) Push PC and STAT32 on stack
 56	;                 hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
 57	;   4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
 58	;
 59	; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair
 
 
 
 
 60
 61#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
 62	; carve pt_regs on stack (case #3), PC/STAT32 already on stack
 63	sub	sp, sp, SZ_PT_REGS - 8
 64
 65	__SAVE_REGFILE_HARD
 66#else
 67	; carve pt_regs on stack (case #4), which grew partially already
 68	sub	sp, sp, PT_r0
 69#endif
 70
 71	__SAVE_REGFILE_SOFT
 72.endm
 73
 74/*------------------------------------------------------------------------*/
 75.macro EXCEPTION_PROLOGUE
 76
 77	; (A) Before jumping to Exception Vector, hardware micro-ops did following:
 78	;   1. SP auto-switched to kernel mode stack
 79	;   2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
 80	;
 81	; (B) Manually save the complete reg file below
 
 82
 83	sub	sp, sp, SZ_PT_REGS	; carve pt_regs
 84
 85	; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
 86
 87	__SAVE_REGFILE_HARD
 88	__SAVE_REGFILE_SOFT
 89
 90	st	r0, [sp]	; orig_r0
 91
 92	lr	r10, [eret]
 93	lr	r11, [erstatus]
 94	ST2	r10, r11, PT_ret
 95
 96	lr	r10, [ecr]
 97	lr	r11, [erbta]
 98	ST2	r10, r11, PT_event
 99
100	; OUTPUT: r10 has ECR expected by EV_Trap
101.endm
102
 
 
 
 
 
 
 
 
 
 
103/*------------------------------------------------------------------------
104 * This macro saves the registers manually which would normally be autosaved
105 * by hardware on taken interrupts. It is used by
106 *   - exception handlers (which don't have autosave)
107 *   - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE
108 */
109.macro __SAVE_REGFILE_HARD
110
111	ST2	r0,  r1,  PT_r0
112	ST2	r2,  r3,  PT_r2
113	ST2	r4,  r5,  PT_r4
114	ST2	r6,  r7,  PT_r6
115	ST2	r8,  r9,  PT_r8
116	ST2	r10, r11, PT_r10
117
118	st	blink, [sp, PT_blink]
119
120	lr	r10, [lp_end]
121	lr	r11, [lp_start]
122	ST2	r10, r11, PT_lpe
123
124	st	lp_count, [sp, PT_lpc]
125
126	; skip JLI, LDI, EI for now
127.endm
128
129/*------------------------------------------------------------------------
130 * This macros saves a bunch of other registers which can't be autosaved for
131 * various reasons:
132 *   - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11
133 *   - r30: free reg, used by gcc as scratch
134 *   - ACCL/ACCH pair when they exist
135 */
136.macro __SAVE_REGFILE_SOFT
137
138	ST2	gp, fp, PT_r26		; gp (r26), fp (r27)
139
140	st	r12, [sp, PT_sp + 4]
141	st	r30, [sp, PT_sp + 8]
142
143	; Saving pt_regs->sp correctly requires some extra work due to the way
144	; Auto stack switch works
145	;  - U mode: retrieve it from AUX_USER_SP
146	;  - K mode: add the offset from current SP where H/w starts auto push
147	;
148	; 1. Utilize the fact that Z bit is set if Intr taken in U mode
149	; 2. Upon entry SP is always saved (for any inspection, unwinding etc),
150	;    but on return, restored only if U mode
151
152	lr	r10, [AUX_USER_SP]	; U mode SP
153
154	; ISA requires ADD.nz to have same dest and src reg operands
155	mov.nz	r10, sp
156	add.nz	r10, r10, SZ_PT_REGS	; K mode SP
157
158	st	r10, [sp, PT_sp]	; SP (pt_regs->sp)
159
160#ifdef CONFIG_ARC_CURR_IN_REG
161	st	r25, [sp, PT_user_r25]
162	GET_CURR_TASK_ON_CPU	r25
163#endif
164
165#ifdef CONFIG_ARC_HAS_ACCL_REGS
166	ST2	r58, r59, PT_r58
167#endif
168
169	/* clobbers r10, r11 registers pair */
170	DSP_SAVE_REGFILE_IRQ
 
 
 
 
 
171.endm
172
173/*------------------------------------------------------------------------*/
174.macro __RESTORE_REGFILE_SOFT
175
176	LD2	gp, fp, PT_r26		; gp (r26), fp (r27)
177
178	ld	r12, [sp, PT_r12]
179	ld	r30, [sp, PT_r30]
180
181	; Restore SP (into AUX_USER_SP) only if returning to U mode
182	;  - for K mode, it will be implicitly restored as stack is unwound
183	;  - Z flag set on K is inverse of what hardware does on interrupt entry
184	;    but that doesn't really matter
185	bz	1f
186
187	ld	r10, [sp, PT_sp]	; SP (pt_regs->sp)
188	sr	r10, [AUX_USER_SP]
1891:
190
191#ifdef CONFIG_ARC_CURR_IN_REG
192	ld	r25, [sp, PT_user_r25]
193#endif
194
195	/* clobbers r10, r11 registers pair */
196	DSP_RESTORE_REGFILE_IRQ
197
198#ifdef CONFIG_ARC_HAS_ACCL_REGS
199	LD2	r58, r59, PT_r58
200#endif
201.endm
202
203/*------------------------------------------------------------------------*/
204.macro __RESTORE_REGFILE_HARD
205
206	ld	blink, [sp, PT_blink]
207
208	LD2	r10, r11, PT_lpe
209	sr	r10, [lp_end]
210	sr	r11, [lp_start]
211
212	ld	r10, [sp, PT_lpc]	; lp_count can't be target of LD
213	mov	lp_count, r10
214
215	LD2	r0,  r1,  PT_r0
216	LD2	r2,  r3,  PT_r2
217	LD2	r4,  r5,  PT_r4
218	LD2	r6,  r7,  PT_r6
219	LD2	r8,  r9,  PT_r8
220	LD2	r10, r11, PT_r10
221.endm
222
223
224/*------------------------------------------------------------------------*/
225.macro INTERRUPT_EPILOGUE
226
227	; INPUT: r0 has STAT32 of calling context
228	; INPUT: Z flag set if returning to K mode
229
230	; _SOFT clobbers r10 restored by _HARD hence the order
231
232	__RESTORE_REGFILE_SOFT
233
234#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
235	__RESTORE_REGFILE_HARD
236
237	; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE
238	add	sp, sp, SZ_PT_REGS - 8
239#else
240	add	sp, sp, PT_r0
241#endif
242
243.endm
244
245/*------------------------------------------------------------------------*/
246.macro EXCEPTION_EPILOGUE
247
248	; INPUT: r0 has STAT32 of calling context
249
250	btst	r0, STATUS_U_BIT	; Z flag set if K, used in restoring SP
251
252	ld	r10, [sp, PT_event + 4]
253	sr	r10, [erbta]
254
255	LD2	r10, r11, PT_ret
256	sr	r10, [eret]
257	sr	r11, [erstatus]
258
259	__RESTORE_REGFILE_SOFT
260	__RESTORE_REGFILE_HARD
261
262	add	sp, sp, SZ_PT_REGS
263.endm
264
265.macro FAKE_RET_FROM_EXCPN
266	lr      r9, [status32]
267	bic     r9, r9, STATUS_AE_MASK
268	or      r9, r9, STATUS_IE_MASK
269	kflag   r9
270.endm
271
272/* Get thread_info of "current" tsk */
273.macro GET_CURR_THR_INFO_FROM_SP  reg
274	bmskn \reg, sp, THREAD_SHIFT - 1
275.endm
276
277/* Get CPU-ID of this core */
278.macro  GET_CPU_ID  reg
279	lr  \reg, [identity]
280	xbfu \reg, \reg, 0xE8	/* 00111    01000 */
281				/* M = 8-1  N = 8 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282.endm
283
284#endif