Linux Audio

Check our new training course

Loading...
v4.17
  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]
 391:
 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
 
 801:
 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_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
v6.2
  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