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