Linux Audio

Check our new training course

Loading...
v6.8
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
  4 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  5 *
  6 * Vineetg: March 2009 (Supporting 2 levels of Interrupts)
  7 *  Stack switching code can no longer reliably rely on the fact that
  8 *  if we are NOT in user mode, stack is switched to kernel mode.
  9 *  e.g. L2 IRQ interrupted a L1 ISR which had not yet completed
 10 *  it's prologue including stack switching from user mode
 11 *
 12 * Vineetg: Aug 28th 2008: Bug #94984
 13 *  -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap
 14 *   Normally CPU does this automatically, however when doing FAKE rtie,
 15 *   we also need to explicitly do this. The problem in macros
 16 *   FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit
 17 *   was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context
 18 *
 19 * Vineetg: May 5th 2008
 20 *  -Modified CALLEE_REG save/restore macros to handle the fact that
 21 *      r25 contains the kernel current task ptr
 22 *  - Defined Stack Switching Macro to be reused in all intr/excp hdlrs
 23 *  - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the
 24 *      address Write back load ld.ab instead of separate ld/add instn
 25 *
 26 * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
 27 */
 28
 29#ifndef __ASM_ARC_ENTRY_COMPACT_H
 30#define __ASM_ARC_ENTRY_COMPACT_H
 31
 32#include <asm/asm-offsets.h>
 33#include <asm/irqflags-compact.h>
 34#include <asm/thread_info.h>	/* For THREAD_SIZE */
 35
 36/* Note on the LD/ST addr modes with addr reg wback
 37 *
 38 * LD.a same as LD.aw
 39 *
 40 * LD.a    reg1, [reg2, x]  => Pre Incr
 41 *      Eff Addr for load = [reg2 + x]
 42 *
 43 * LD.ab   reg1, [reg2, x]  => Post Incr
 44 *      Eff Addr for load = [reg2]
 45 */
 46
 47.macro PUSHAX aux
 48	lr	r9, [\aux]
 49	push	r9
 50.endm
 51
 52.macro POPAX aux
 53	pop	r9
 54	sr	r9, [\aux]
 55.endm
 56
 57.macro  SAVE_R0_TO_R12
 58	push	r0
 59	push	r1
 60	push	r2
 61	push	r3
 62	push	r4
 63	push	r5
 64	push	r6
 65	push	r7
 66	push	r8
 67	push	r9
 68	push	r10
 69	push	r11
 70	push	r12
 71.endm
 72
 73.macro RESTORE_R12_TO_R0
 74	pop	r12
 75	pop	r11
 76	pop	r10
 77	pop	r9
 78	pop	r8
 79	pop	r7
 80	pop	r6
 81	pop	r5
 82	pop	r4
 83	pop	r3
 84	pop	r2
 85	pop	r1
 86	pop	r0
 87.endm
 88
 89.macro SAVE_ABI_CALLEE_REGS
 90	push	r13
 91	push	r14
 92	push	r15
 93	push	r16
 94	push	r17
 95	push	r18
 96	push	r19
 97	push	r20
 98	push	r21
 99	push	r22
100	push	r23
101	push	r24
102	push	r25
103.endm
104
105.macro RESTORE_ABI_CALLEE_REGS
106	pop	r25
107	pop	r24
108	pop	r23
109	pop	r22
110	pop	r21
111	pop	r20
112	pop	r19
113	pop	r18
114	pop	r17
115	pop	r16
116	pop	r15
117	pop	r14
118	pop	r13
119.endm
120
121/*--------------------------------------------------------------
122 * Switch to Kernel Mode stack if SP points to User Mode stack
123 *
124 * Entry   : r9 contains pre-IRQ/exception/trap status32
125 * Exit    : SP set to K mode stack
126 *           SP at the time of entry (K/U) saved @ pt_regs->sp
127 * Clobbers: r9
128 *-------------------------------------------------------------*/
129
130.macro SWITCH_TO_KERNEL_STK
131
132	/* User Mode when this happened ? Yes: Proceed to switch stack */
133	bbit1   r9, STATUS_U_BIT, 88f
134
135	/* OK we were already in kernel mode when this event happened, thus can
136	 * assume SP is kernel mode SP. _NO_ need to do any stack switching
137	 */
138
139#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
140	/* However....
141	 * If Level 2 Interrupts enabled, we may end up with a corner case:
142	 * 1. User Task executing
143	 * 2. L1 IRQ taken, ISR starts (CPU auto-switched to KERNEL mode)
144	 * 3. But before it could switch SP from USER to KERNEL stack
145	 *      a L2 IRQ "Interrupts" L1
146	 * Thay way although L2 IRQ happened in Kernel mode, stack is still
147	 * not switched.
148	 * To handle this, we may need to switch stack even if in kernel mode
149	 * provided SP has values in range of USER mode stack ( < 0x7000_0000 )
150	 */
151	brlo sp, VMALLOC_START, 88f
152
153	/* TODO: vineetg:
154	 * We need to be a bit more cautious here. What if a kernel bug in
155	 * L1 ISR, caused SP to go whaco (some small value which looks like
156	 * USER stk) and then we take L2 ISR.
157	 * Above brlo alone would treat it as a valid L1-L2 scenario
158	 * instead of shouting around
159	 * The only feasible way is to make sure this L2 happened in
160	 * L1 prelogue ONLY i.e. ilink2 is less than a pre-set marker in
161	 * L1 ISR before it switches stack
162	 */
163
164#endif
165
166    /*------Intr/Ecxp happened in kernel mode, SP already setup ------ */
167	/* save it nevertheless @ pt_regs->sp for uniformity */
168
169	b.d	66f
170	st	sp, [sp, PT_sp - SZ_PT_REGS]
171
17288: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */
173
174	GET_CURR_TASK_ON_CPU   r9
175
176	/* With current tsk in r9, get it's kernel mode stack base */
177	GET_TSK_STACK_BASE  r9, r9
178
179	/* save U mode SP @ pt_regs->sp */
180	st	sp, [r9, PT_sp - SZ_PT_REGS]
181
182	/* final SP switch */
183	mov	sp, r9
18466:
185.endm
186
187/*------------------------------------------------------------
188 * "FAKE" a rtie to return from CPU Exception context
189 * This is to re-enable Exceptions within exception
190 * Look at EV_ProtV to see how this is actually used
191 *-------------------------------------------------------------*/
192
193.macro FAKE_RET_FROM_EXCPN
194
195	lr	r9, [status32]
196	bclr	r9, r9, STATUS_AE_BIT
197	or	r9, r9, (STATUS_E1_MASK|STATUS_E2_MASK)
198	sr	r9, [erstatus]
199	mov	r9, 55f
200	sr	r9, [eret]
201	rtie
20255:
203.endm
204
205/*--------------------------------------------------------------
206 * For early Exception/ISR Prologue, a core reg is temporarily needed to
207 * code the rest of prolog (stack switching). This is done by stashing
208 * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP).
209 *
210 * Before saving the full regfile - this reg is restored back, only
211 * to be saved again on kernel mode stack, as part of pt_regs.
212 *-------------------------------------------------------------*/
213.macro PROLOG_FREEUP_REG	reg, mem
 
 
 
214	st  \reg, [\mem]
 
215.endm
216
217.macro PROLOG_RESTORE_REG	reg, mem
 
 
 
218	ld  \reg, [\mem]
 
219.endm
220
221/*--------------------------------------------------------------
222 * Exception Entry prologue
223 * -Switches stack to K mode (if not already)
224 * -Saves the register file
225 *
226 * After this it is safe to call the "C" handlers
227 *-------------------------------------------------------------*/
228.macro EXCEPTION_PROLOGUE_KEEP_AE
229
230	/* Need at least 1 reg to code the early exception prologue */
231	PROLOG_FREEUP_REG r9, @ex_saved_reg1
232
233	/* U/K mode at time of exception (stack not switched if already K) */
234	lr  r9, [erstatus]
235
236	/* ARC700 doesn't provide auto-stack switching */
237	SWITCH_TO_KERNEL_STK
238
 
 
 
 
 
 
 
 
239	st.a	r0, [sp, -8]    /* orig_r0 needed for syscall (skip ECR slot) */
240	sub	sp, sp, 4	/* skip pt_regs->sp, already saved above */
241
242	/* Restore r9 used to code the early prologue */
243	PROLOG_RESTORE_REG  r9, @ex_saved_reg1
244
245	/* now we are ready to save the regfile */
246	SAVE_R0_TO_R12
247	PUSH	gp
248	PUSH	fp
249	PUSH	blink
250	PUSHAX	eret
251	PUSHAX	erstatus
252	PUSH	lp_count
253	PUSHAX	lp_end
254	PUSHAX	lp_start
255	PUSHAX	erbta
256
257	lr	r10, [ecr]
258	st      r10, [sp, PT_event]
259
260#ifdef CONFIG_ARC_CURR_IN_REG
261	/* gp already saved on stack: now load with "current" */
262	GET_CURR_TASK_ON_CPU   gp
263#endif
264	; OUTPUT: r10 has ECR expected by EV_Trap
265.endm
266
267.macro EXCEPTION_PROLOGUE
268
269	EXCEPTION_PROLOGUE_KEEP_AE	; return ECR in r10
270
271	lr  r0, [efa]
272	mov r1, sp
273
274	FAKE_RET_FROM_EXCPN		; clobbers r9
275.endm
276
277/*--------------------------------------------------------------
278 * Restore all registers used by system call or Exceptions
279 * SP should always be pointing to the next free stack element
280 * when entering this macro.
281 *
282 * NOTE:
283 *
284 * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg
285 * for memory load operations. If used in that way interrupts are deffered
286 * by hardware and that is not good.
287 *-------------------------------------------------------------*/
288.macro EXCEPTION_EPILOGUE
 
 
 
 
 
289
290	POPAX	erbta
291	POPAX	lp_start
292	POPAX	lp_end
293
294	POP	r9
295	mov	lp_count, r9	;LD to lp_count is not allowed
296
297	POPAX	erstatus
298	POPAX	eret
299	POP	blink
300	POP	fp
301	POP	gp
302	RESTORE_R12_TO_R0
303
 
 
 
304	ld  sp, [sp] /* restore original sp */
305	/* orig_r0, ECR skipped automatically */
306.endm
307
308/* Dummy ECR values for Interrupts */
309#define event_IRQ1		0x0031abcd
310#define event_IRQ2		0x0032abcd
311
312.macro INTERRUPT_PROLOGUE  LVL
313
314	/* free up r9 as scratchpad */
315	PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg
316
317	/* Which mode (user/kernel) was the system in when intr occurred */
318	lr  r9, [status32_l\LVL\()]
319
320	SWITCH_TO_KERNEL_STK
321
 
 
 
 
 
 
 
322
323	st.a	0x003\LVL\()abcd, [sp, -4]	/* Dummy ECR */
324	sub	sp, sp, 8	    /* skip orig_r0 (not needed)
325				       skip pt_regs->sp, already saved above */
326
327	/* Restore r9 used to code the early prologue */
328	PROLOG_RESTORE_REG  r9, @int\LVL\()_saved_reg
329
330	SAVE_R0_TO_R12
331	PUSH	gp
332	PUSH	fp
333	PUSH	blink
334	PUSH	ilink\LVL\()
335	PUSHAX	status32_l\LVL\()
336	PUSH	lp_count
337	PUSHAX	lp_end
338	PUSHAX	lp_start
339	PUSHAX	bta_l\LVL\()
340
341#ifdef CONFIG_ARC_CURR_IN_REG
342	/* gp already saved on stack: now load with "current" */
343	GET_CURR_TASK_ON_CPU   gp
 
344#endif
345.endm
346
347/*--------------------------------------------------------------
348 * Restore all registers used by interrupt handlers.
349 *
350 * NOTE:
351 *
352 * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg
353 * for memory load operations. If used in that way interrupts are deffered
354 * by hardware and that is not good.
355 *-------------------------------------------------------------*/
356.macro INTERRUPT_EPILOGUE  LVL
 
 
 
 
 
357
358	POPAX	bta_l\LVL\()
359	POPAX	lp_start
360	POPAX	lp_end
361
362	POP	r9
363	mov	lp_count, r9	;LD to lp_count is not allowed
364
365	POPAX	status32_l\LVL\()
366	POP	ilink\LVL\()
367	POP	blink
368	POP	fp
369	POP	gp
370	RESTORE_R12_TO_R0
371
372	ld  sp, [sp] /* restore original sp; orig_r0, ECR skipped implicitly */
 
 
 
 
373.endm
374
375/* Get thread_info of "current" tsk */
376.macro GET_CURR_THR_INFO_FROM_SP  reg
377	bic \reg, sp, (THREAD_SIZE - 1)
378.endm
379
 
380/* Get CPU-ID of this core */
381.macro  GET_CPU_ID  reg
382	lr  \reg, [identity]
383	lsr \reg, \reg, 8
384	bmsk \reg, \reg, 7
385.endm
 
386
387#endif  /* __ASM_ARC_ENTRY_COMPACT_H */
v5.9
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
  4 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  5 *
  6 * Vineetg: March 2009 (Supporting 2 levels of Interrupts)
  7 *  Stack switching code can no longer reliably rely on the fact that
  8 *  if we are NOT in user mode, stack is switched to kernel mode.
  9 *  e.g. L2 IRQ interrupted a L1 ISR which had not yet completed
 10 *  it's prologue including stack switching from user mode
 11 *
 12 * Vineetg: Aug 28th 2008: Bug #94984
 13 *  -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap
 14 *   Normally CPU does this automatically, however when doing FAKE rtie,
 15 *   we also need to explicitly do this. The problem in macros
 16 *   FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit
 17 *   was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context
 18 *
 19 * Vineetg: May 5th 2008
 20 *  -Modified CALLEE_REG save/restore macros to handle the fact that
 21 *      r25 contains the kernel current task ptr
 22 *  - Defined Stack Switching Macro to be reused in all intr/excp hdlrs
 23 *  - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the
 24 *      address Write back load ld.ab instead of seperate ld/add instn
 25 *
 26 * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
 27 */
 28
 29#ifndef __ASM_ARC_ENTRY_COMPACT_H
 30#define __ASM_ARC_ENTRY_COMPACT_H
 31
 32#include <asm/asm-offsets.h>
 33#include <asm/irqflags-compact.h>
 34#include <asm/thread_info.h>	/* For THREAD_SIZE */
 35
 36#ifdef CONFIG_ARC_PLAT_EZNPS
 37#include <plat/ctop.h>
 38#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 39
 40/*--------------------------------------------------------------
 41 * Switch to Kernel Mode stack if SP points to User Mode stack
 42 *
 43 * Entry   : r9 contains pre-IRQ/exception/trap status32
 44 * Exit    : SP set to K mode stack
 45 *           SP at the time of entry (K/U) saved @ pt_regs->sp
 46 * Clobbers: r9
 47 *-------------------------------------------------------------*/
 48
 49.macro SWITCH_TO_KERNEL_STK
 50
 51	/* User Mode when this happened ? Yes: Proceed to switch stack */
 52	bbit1   r9, STATUS_U_BIT, 88f
 53
 54	/* OK we were already in kernel mode when this event happened, thus can
 55	 * assume SP is kernel mode SP. _NO_ need to do any stack switching
 56	 */
 57
 58#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
 59	/* However....
 60	 * If Level 2 Interrupts enabled, we may end up with a corner case:
 61	 * 1. User Task executing
 62	 * 2. L1 IRQ taken, ISR starts (CPU auto-switched to KERNEL mode)
 63	 * 3. But before it could switch SP from USER to KERNEL stack
 64	 *      a L2 IRQ "Interrupts" L1
 65	 * Thay way although L2 IRQ happened in Kernel mode, stack is still
 66	 * not switched.
 67	 * To handle this, we may need to switch stack even if in kernel mode
 68	 * provided SP has values in range of USER mode stack ( < 0x7000_0000 )
 69	 */
 70	brlo sp, VMALLOC_START, 88f
 71
 72	/* TODO: vineetg:
 73	 * We need to be a bit more cautious here. What if a kernel bug in
 74	 * L1 ISR, caused SP to go whaco (some small value which looks like
 75	 * USER stk) and then we take L2 ISR.
 76	 * Above brlo alone would treat it as a valid L1-L2 scenario
 77	 * instead of shouting around
 78	 * The only feasible way is to make sure this L2 happened in
 79	 * L1 prelogue ONLY i.e. ilink2 is less than a pre-set marker in
 80	 * L1 ISR before it switches stack
 81	 */
 82
 83#endif
 84
 85    /*------Intr/Ecxp happened in kernel mode, SP already setup ------ */
 86	/* save it nevertheless @ pt_regs->sp for uniformity */
 87
 88	b.d	66f
 89	st	sp, [sp, PT_sp - SZ_PT_REGS]
 90
 9188: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */
 92
 93	GET_CURR_TASK_ON_CPU   r9
 94
 95	/* With current tsk in r9, get it's kernel mode stack base */
 96	GET_TSK_STACK_BASE  r9, r9
 97
 98	/* save U mode SP @ pt_regs->sp */
 99	st	sp, [r9, PT_sp - SZ_PT_REGS]
100
101	/* final SP switch */
102	mov	sp, r9
10366:
104.endm
105
106/*------------------------------------------------------------
107 * "FAKE" a rtie to return from CPU Exception context
108 * This is to re-enable Exceptions within exception
109 * Look at EV_ProtV to see how this is actually used
110 *-------------------------------------------------------------*/
111
112.macro FAKE_RET_FROM_EXCPN
113
114	lr	r9, [status32]
115	bclr	r9, r9, STATUS_AE_BIT
116	or	r9, r9, (STATUS_E1_MASK|STATUS_E2_MASK)
117	sr	r9, [erstatus]
118	mov	r9, 55f
119	sr	r9, [eret]
120	rtie
12155:
122.endm
123
124/*--------------------------------------------------------------
125 * For early Exception/ISR Prologue, a core reg is temporarily needed to
126 * code the rest of prolog (stack switching). This is done by stashing
127 * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP).
128 *
129 * Before saving the full regfile - this reg is restored back, only
130 * to be saved again on kernel mode stack, as part of pt_regs.
131 *-------------------------------------------------------------*/
132.macro PROLOG_FREEUP_REG	reg, mem
133#ifndef ARC_USE_SCRATCH_REG
134	sr  \reg, [ARC_REG_SCRATCH_DATA0]
135#else
136	st  \reg, [\mem]
137#endif
138.endm
139
140.macro PROLOG_RESTORE_REG	reg, mem
141#ifndef ARC_USE_SCRATCH_REG
142	lr  \reg, [ARC_REG_SCRATCH_DATA0]
143#else
144	ld  \reg, [\mem]
145#endif
146.endm
147
148/*--------------------------------------------------------------
149 * Exception Entry prologue
150 * -Switches stack to K mode (if not already)
151 * -Saves the register file
152 *
153 * After this it is safe to call the "C" handlers
154 *-------------------------------------------------------------*/
155.macro EXCEPTION_PROLOGUE
156
157	/* Need at least 1 reg to code the early exception prologue */
158	PROLOG_FREEUP_REG r9, @ex_saved_reg1
159
160	/* U/K mode at time of exception (stack not switched if already K) */
161	lr  r9, [erstatus]
162
163	/* ARC700 doesn't provide auto-stack switching */
164	SWITCH_TO_KERNEL_STK
165
166#ifdef CONFIG_ARC_CURR_IN_REG
167	/* Treat r25 as scratch reg (save on stack) and load with "current" */
168	PUSH    r25
169	GET_CURR_TASK_ON_CPU   r25
170#else
171	sub     sp, sp, 4
172#endif
173
174	st.a	r0, [sp, -8]    /* orig_r0 needed for syscall (skip ECR slot) */
175	sub	sp, sp, 4	/* skip pt_regs->sp, already saved above */
176
177	/* Restore r9 used to code the early prologue */
178	PROLOG_RESTORE_REG  r9, @ex_saved_reg1
179
180	/* now we are ready to save the regfile */
181	SAVE_R0_TO_R12
182	PUSH	gp
183	PUSH	fp
184	PUSH	blink
185	PUSHAX	eret
186	PUSHAX	erstatus
187	PUSH	lp_count
188	PUSHAX	lp_end
189	PUSHAX	lp_start
190	PUSHAX	erbta
191
192#ifdef CONFIG_ARC_PLAT_EZNPS
193	.word CTOP_INST_SCHD_RW
194	PUSHAX  CTOP_AUX_GPA1
195	PUSHAX  CTOP_AUX_EFLAGS
 
 
196#endif
 
 
197
198	lr	r10, [ecr]
199	st      r10, [sp, PT_event]    /* EV_Trap expects r10 to have ECR */
 
 
 
 
 
 
200.endm
201
202/*--------------------------------------------------------------
203 * Restore all registers used by system call or Exceptions
204 * SP should always be pointing to the next free stack element
205 * when entering this macro.
206 *
207 * NOTE:
208 *
209 * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg
210 * for memory load operations. If used in that way interrupts are deffered
211 * by hardware and that is not good.
212 *-------------------------------------------------------------*/
213.macro EXCEPTION_EPILOGUE
214#ifdef CONFIG_ARC_PLAT_EZNPS
215	.word CTOP_INST_SCHD_RW
216	POPAX   CTOP_AUX_EFLAGS
217	POPAX   CTOP_AUX_GPA1
218#endif
219
220	POPAX	erbta
221	POPAX	lp_start
222	POPAX	lp_end
223
224	POP	r9
225	mov	lp_count, r9	;LD to lp_count is not allowed
226
227	POPAX	erstatus
228	POPAX	eret
229	POP	blink
230	POP	fp
231	POP	gp
232	RESTORE_R12_TO_R0
233
234#ifdef CONFIG_ARC_CURR_IN_REG
235	ld	r25, [sp, 12]
236#endif
237	ld  sp, [sp] /* restore original sp */
238	/* orig_r0, ECR, user_r25 skipped automatically */
239.endm
240
241/* Dummy ECR values for Interrupts */
242#define event_IRQ1		0x0031abcd
243#define event_IRQ2		0x0032abcd
244
245.macro INTERRUPT_PROLOGUE  LVL
246
247	/* free up r9 as scratchpad */
248	PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg
249
250	/* Which mode (user/kernel) was the system in when intr occurred */
251	lr  r9, [status32_l\LVL\()]
252
253	SWITCH_TO_KERNEL_STK
254
255#ifdef CONFIG_ARC_CURR_IN_REG
256	/* Treat r25 as scratch reg (save on stack) and load with "current" */
257	PUSH    r25
258	GET_CURR_TASK_ON_CPU   r25
259#else
260	sub     sp, sp, 4
261#endif
262
263	PUSH	0x003\LVL\()abcd    /* Dummy ECR */
264	sub	sp, sp, 8	    /* skip orig_r0 (not needed)
265				       skip pt_regs->sp, already saved above */
266
267	/* Restore r9 used to code the early prologue */
268	PROLOG_RESTORE_REG  r9, @int\LVL\()_saved_reg
269
270	SAVE_R0_TO_R12
271	PUSH	gp
272	PUSH	fp
273	PUSH	blink
274	PUSH	ilink\LVL\()
275	PUSHAX	status32_l\LVL\()
276	PUSH	lp_count
277	PUSHAX	lp_end
278	PUSHAX	lp_start
279	PUSHAX	bta_l\LVL\()
280
281#ifdef CONFIG_ARC_PLAT_EZNPS
282	.word CTOP_INST_SCHD_RW
283	PUSHAX  CTOP_AUX_GPA1
284	PUSHAX  CTOP_AUX_EFLAGS
285#endif
286.endm
287
288/*--------------------------------------------------------------
289 * Restore all registers used by interrupt handlers.
290 *
291 * NOTE:
292 *
293 * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg
294 * for memory load operations. If used in that way interrupts are deffered
295 * by hardware and that is not good.
296 *-------------------------------------------------------------*/
297.macro INTERRUPT_EPILOGUE  LVL
298#ifdef CONFIG_ARC_PLAT_EZNPS
299	.word CTOP_INST_SCHD_RW
300	POPAX   CTOP_AUX_EFLAGS
301	POPAX   CTOP_AUX_GPA1
302#endif
303
304	POPAX	bta_l\LVL\()
305	POPAX	lp_start
306	POPAX	lp_end
307
308	POP	r9
309	mov	lp_count, r9	;LD to lp_count is not allowed
310
311	POPAX	status32_l\LVL\()
312	POP	ilink\LVL\()
313	POP	blink
314	POP	fp
315	POP	gp
316	RESTORE_R12_TO_R0
317
318#ifdef CONFIG_ARC_CURR_IN_REG
319	ld	r25, [sp, 12]
320#endif
321	ld  sp, [sp] /* restore original sp */
322	/* orig_r0, ECR, user_r25 skipped automatically */
323.endm
324
325/* Get thread_info of "current" tsk */
326.macro GET_CURR_THR_INFO_FROM_SP  reg
327	bic \reg, sp, (THREAD_SIZE - 1)
328.endm
329
330#ifndef CONFIG_ARC_PLAT_EZNPS
331/* Get CPU-ID of this core */
332.macro  GET_CPU_ID  reg
333	lr  \reg, [identity]
334	lsr \reg, \reg, 8
335	bmsk \reg, \reg, 7
336.endm
337#endif
338
339#endif  /* __ASM_ARC_ENTRY_COMPACT_H */