• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #ifndef __ASM_ARC_ENTRY_ARCV2_H
3 #define __ASM_ARC_ENTRY_ARCV2_H
4 
5 #include <asm/asm-offsets.h>
6 #include <asm/irqflags-arcv2.h>
7 #include <asm/thread_info.h>	/* For THREAD_SIZE */
8 
9 /*------------------------------------------------------------------------*/
10 .macro INTERRUPT_PROLOGUE	called_from
11 
12 	; Before jumping to Interrupt Vector, hardware micro-ops did following:
13 	;   1. SP auto-switched to kernel mode stack
14 	;   2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0)
15 	;   3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32
16 	;
17 	; Now manually save: r12, sp, fp, gp, r25
18 
19 	PUSH	r30
20 	PUSH	r12
21 
22 	; Saving pt_regs->sp correctly requires some extra work due to the way
23 	; Auto stack switch works
24 	;  - U mode: retrieve it from AUX_USER_SP
25 	;  - K mode: add the offset from current SP where H/w starts auto push
26 	;
27 	; Utilize the fact that Z bit is set if Intr taken in U mode
28 	mov.nz	r9, sp
29 	add.nz	r9, r9, SZ_PT_REGS - PT_sp - 4
30 	bnz	1f
31 
32 	lr	r9, [AUX_USER_SP]
33 1:
34 	PUSH	r9	; SP
35 
36 	PUSH	fp
37 	PUSH	gp
38 
39 #ifdef CONFIG_ARC_CURR_IN_REG
40 	PUSH	r25			; user_r25
41 	GET_CURR_TASK_ON_CPU	r25
42 #else
43 	sub	sp, sp, 4
44 #endif
45 
46 .ifnc \called_from, exception
47 	sub	sp, sp, 12	; BTA/ECR/orig_r0 placeholder per pt_regs
48 .endif
49 
50 .endm
51 
52 /*------------------------------------------------------------------------*/
53 .macro INTERRUPT_EPILOGUE	called_from
54 
55 .ifnc \called_from, exception
56 	add	sp, sp, 12	; skip BTA/ECR/orig_r0 placeholderss
57 .endif
58 
59 #ifdef CONFIG_ARC_CURR_IN_REG
60 	POP	r25
61 #else
62 	add	sp, sp, 4
63 #endif
64 
65 	POP	gp
66 	POP	fp
67 
68 	; Don't touch AUX_USER_SP if returning to K mode (Z bit set)
69 	; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE)
70 	add.z	sp, sp, 4
71 	bz	1f
72 
73 	POPAX	AUX_USER_SP
74 1:
75 	POP	r12
76 	POP	r30
77 
78 .endm
79 
80 /*------------------------------------------------------------------------*/
81 .macro EXCEPTION_PROLOGUE
82 
83 	; Before jumping to Exception Vector, hardware micro-ops did following:
84 	;   1. SP auto-switched to kernel mode stack
85 	;   2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0)
86 	;
87 	; Now manually save the complete reg file
88 
89 	PUSH	r9		; freeup a register: slot of erstatus
90 
91 	PUSHAX	eret
92 	sub	sp, sp, 12	; skip JLI, LDI, EI
93 	PUSH	lp_count
94 	PUSHAX	lp_start
95 	PUSHAX	lp_end
96 	PUSH	blink
97 
98 	PUSH	r11
99 	PUSH	r10
100 
101 	ld.as	r9,  [sp, 10]	; load stashed r9 (status32 stack slot)
102 	lr	r10, [erstatus]
103 	st.as	r10, [sp, 10]	; save status32 at it's right stack slot
104 
105 	PUSH	r9
106 	PUSH	r8
107 	PUSH	r7
108 	PUSH	r6
109 	PUSH	r5
110 	PUSH	r4
111 	PUSH	r3
112 	PUSH	r2
113 	PUSH	r1
114 	PUSH	r0
115 
116 	; -- for interrupts, regs above are auto-saved by h/w in that order --
117 	; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25)
118 	;
119 	; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE)
120 	; Although H/w exception micro-ops do set Z flag for U mode (just like
121 	; for interrupts), it could get clobbered in case we soft land here from
122 	; a TLB Miss exception handler (tlbex.S)
123 
124 	and	r10, r10, STATUS_U_MASK
125 	xor.f	0, r10, STATUS_U_MASK
126 
127 	INTERRUPT_PROLOGUE  exception
128 
129 	PUSHAX	erbta
130 	PUSHAX	ecr		; r9 contains ECR, expected by EV_Trap
131 
132 	PUSH	r0		; orig_r0
133 .endm
134 
135 /*------------------------------------------------------------------------*/
136 .macro EXCEPTION_EPILOGUE
137 
138 	; Assumes r0 has PT_status32
139 	btst   r0, STATUS_U_BIT	; Z flag set if K, used in INTERRUPT_EPILOGUE
140 
141 	add	sp, sp, 8	; orig_r0/ECR don't need restoring
142 	POPAX	erbta
143 
144 	INTERRUPT_EPILOGUE  exception
145 
146 	POP	r0
147 	POP	r1
148 	POP	r2
149 	POP	r3
150 	POP	r4
151 	POP	r5
152 	POP	r6
153 	POP	r7
154 	POP	r8
155 	POP	r9
156 	POP	r10
157 	POP	r11
158 
159 	POP	blink
160 	POPAX	lp_end
161 	POPAX	lp_start
162 
163 	POP	r9
164 	mov	lp_count, r9
165 
166 	add	sp, sp, 12	; skip JLI, LDI, EI
167 	POPAX	eret
168 	POPAX	erstatus
169 
170 	ld.as	r9, [sp, -12]	; reload r9 which got clobbered
171 .endm
172 
173 .macro FAKE_RET_FROM_EXCPN
174 	lr      r9, [status32]
175 	bic     r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
176 	or      r9, r9, (STATUS_L_MASK|STATUS_IE_MASK)
177 	kflag   r9
178 .endm
179 
180 /* Get thread_info of "current" tsk */
181 .macro GET_CURR_THR_INFO_FROM_SP  reg
182 	bmskn \reg, sp, THREAD_SHIFT - 1
183 .endm
184 
185 /* Get CPU-ID of this core */
186 .macro  GET_CPU_ID  reg
187 	lr  \reg, [identity]
188 	xbfu \reg, \reg, 0xE8	/* 00111    01000 */
189 				/* M = 8-1  N = 8 */
190 .endm
191 
192 #endif
193