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