Fix build break on Apple Xcode, caused by fixing normal gcc build break.
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / ExceptionSupport.ARMv6.S
CommitLineData
98bc0c8c 1#------------------------------------------------------------------------------
2#
3# Use ARMv6 instruction to operate on a single stack
4#
d6ebcab7 5# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
98bc0c8c 6#
d6ebcab7 7# This program and the accompanying materials
98bc0c8c 8# are licensed and made available under the terms and conditions of the BSD License
9# which accompanies this distribution. The full text of the license may be found at
10# http://opensource.org/licenses/bsd-license.php
11#
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14#
15#------------------------------------------------------------------------------
16
17/*
18
19This is the stack constructed by the exception handler (low address to high address)
20 # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
21 Reg Offset
22 === ======
23 R0 0x00 # stmfd SP!,{R0-R12}
24 R1 0x04
25 R2 0x08
26 R3 0x0c
27 R4 0x10
28 R5 0x14
29 R6 0x18
30 R7 0x1c
31 R8 0x20
32 R9 0x24
33 R10 0x28
34 R11 0x2c
35 R12 0x30
36 SP 0x34 # reserved via adding 0x20 (32) to the SP
37 LR 0x38
38 PC 0x3c
39 CPSR 0x40
40 DFSR 0x44
41 DFAR 0x48
42 IFSR 0x4c
43 IFAR 0x50
44
45 LR 0x54 # SVC Link register (we need to restore it)
46
47 LR 0x58 # pushed by srsfd
48 CPSR 0x5c
49
50 */
51
52
53.globl ASM_PFX(ExceptionHandlersStart)
54.globl ASM_PFX(ExceptionHandlersEnd)
55.globl ASM_PFX(CommonExceptionEntry)
56.globl ASM_PFX(AsmCommonExceptionEntry)
57.globl ASM_PFX(CommonCExceptionHandler)
58
59.text
5792e320 60#if !defined(__APPLE__)
fe295078 61.fpu neon @ makes vpush/vpop assemble
5792e320 62#endif
98bc0c8c 63.align 3
64
65
66//
67// This code gets copied to the ARM vector table
68// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
69//
70ASM_PFX(ExceptionHandlersStart):
71
72ASM_PFX(Reset):
73 b ASM_PFX(ResetEntry)
74
75ASM_PFX(UndefinedInstruction):
76 b ASM_PFX(UndefinedInstructionEntry)
77
78ASM_PFX(SoftwareInterrupt):
79 b ASM_PFX(SoftwareInterruptEntry)
80
81ASM_PFX(PrefetchAbort):
82 b ASM_PFX(PrefetchAbortEntry)
83
84ASM_PFX(DataAbort):
85 b ASM_PFX(DataAbortEntry)
86
87ASM_PFX(ReservedException):
88 b ASM_PFX(ReservedExceptionEntry)
89
90ASM_PFX(Irq):
91 b ASM_PFX(IrqEntry)
92
93ASM_PFX(Fiq):
94 b ASM_PFX(FiqEntry)
95
96ASM_PFX(ResetEntry):
97 srsdb #0x13! @ Store return state on SVC stack
98 @ We are already in SVC mode
99
100 stmfd SP!,{LR} @ Store the link register for the current mode
101 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
102 stmfd SP!,{R0-R12} @ Store the register state
103
104 mov R0,#0 @ ExceptionType
105 ldr R1,ASM_PFX(CommonExceptionEntry)
106 bx R1
107
108ASM_PFX(UndefinedInstructionEntry):
109 sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
110 srsdb #0x13! @ Store return state on SVC stack
111 cps #0x13 @ Switch to SVC for common stack
112 stmfd SP!,{LR} @ Store the link register for the current mode
113 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
114 stmfd SP!,{R0-R12} @ Store the register state
115
116 mov R0,#1 @ ExceptionType
117 ldr R1,ASM_PFX(CommonExceptionEntry)
118 bx R1
119
120ASM_PFX(SoftwareInterruptEntry):
121 sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
122 srsdb #0x13! @ Store return state on SVC stack
123 @ We are already in SVC mode
124 stmfd SP!,{LR} @ Store the link register for the current mode
125 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
126 stmfd SP!,{R0-R12} @ Store the register state
127
128 mov R0,#2 @ ExceptionType
129 ldr R1,ASM_PFX(CommonExceptionEntry)
130 bx R1
131
132ASM_PFX(PrefetchAbortEntry):
133 sub LR,LR,#4
134 srsdb #0x13! @ Store return state on SVC stack
135 cps #0x13 @ Switch to SVC for common stack
136 stmfd SP!,{LR} @ Store the link register for the current mode
137 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
138 stmfd SP!,{R0-R12} @ Store the register state
139
140 mov R0,#3 @ ExceptionType
141 ldr R1,ASM_PFX(CommonExceptionEntry)
142 bx R1
143
144ASM_PFX(DataAbortEntry):
145 sub LR,LR,#8
146 srsdb #0x13! @ Store return state on SVC stack
147 cps #0x13 @ Switch to SVC for common stack
148 stmfd SP!,{LR} @ Store the link register for the current mode
149 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
150 stmfd SP!,{R0-R12} @ Store the register state
151
152 mov R0,#4
153 ldr R1,ASM_PFX(CommonExceptionEntry)
154 bx R1
155
156ASM_PFX(ReservedExceptionEntry):
157 srsdb #0x13! @ Store return state on SVC stack
158 cps #0x13 @ Switch to SVC for common stack
159 stmfd SP!,{LR} @ Store the link register for the current mode
160 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
161 stmfd SP!,{R0-R12} @ Store the register state
162
163 mov R0,#5
164 ldr R1,ASM_PFX(CommonExceptionEntry)
165 bx R1
166
167ASM_PFX(IrqEntry):
168 sub LR,LR,#4
169 srsdb #0x13! @ Store return state on SVC stack
170 cps #0x13 @ Switch to SVC for common stack
171 stmfd SP!,{LR} @ Store the link register for the current mode
172 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
173 stmfd SP!,{R0-R12} @ Store the register state
174
175 mov R0,#6 @ ExceptionType
176 ldr R1,ASM_PFX(CommonExceptionEntry)
177 bx R1
178
179ASM_PFX(FiqEntry):
180 sub LR,LR,#4
181 srsdb #0x13! @ Store return state on SVC stack
182 cps #0x13 @ Switch to SVC for common stack
183 stmfd SP!,{LR} @ Store the link register for the current mode
184 sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
185 stmfd SP!,{R0-R12} @ Store the register state
186 @ Since we have already switch to SVC R8_fiq - R12_fiq
187 @ never get used or saved
188 mov R0,#7 @ ExceptionType
189 ldr R1,ASM_PFX(CommonExceptionEntry)
190 bx R1
191
192//
193// This gets patched by the C code that patches in the vector table
194//
195ASM_PFX(CommonExceptionEntry):
196 .byte 0x12
197 .byte 0x34
198 .byte 0x56
199 .byte 0x78
200
201ASM_PFX(ExceptionHandlersEnd):
202
203//
204// This code runs from CpuDxe driver loaded address. It is patched into
205// CommonExceptionEntry.
206//
207ASM_PFX(AsmCommonExceptionEntry):
208 mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
209 str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
210
211 mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
212 str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
213
214 mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
215 str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
216
217 mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
218 str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
219
220 ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
221 str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
222
223 add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
224 and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
225 cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
226 cmpne R3, #0x10 @
227 stmeqed R2, {lr}^ @ save unbanked lr
228 @ else
229 stmneed R2, {lr} @ save SVC lr
230
231
232 ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
233 @ Check to see if we have to adjust for Thumb entry
234 sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
235 cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
236 bhi NoAdjustNeeded
237
238 tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
239 addne R5, R5, #2 @ PC += 2@
240 str R5,[SP,#0x58] @ Update LR value pused by srsfd
241
242NoAdjustNeeded:
243
244 str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
245
246 sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
247 str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
248
249 @ R0 is ExceptionType
250 mov R1,SP @ R1 is SystemContext
251
5792e320 252 vpush {d0-d15} @ save vstm registers in case they are used in optimizations
253
fe295078 254
98bc0c8c 255/*
256VOID
257EFIAPI
258CommonCExceptionHandler (
259 IN EFI_EXCEPTION_TYPE ExceptionType, R0
260 IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
261 )
262
263*/
264 blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
bb02cb80 265
fe295078 266 vpop {d0-d15}
267
bb02cb80 268 ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
269 mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
270
271 ldr R1, [SP, #0x44] @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
272 mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
98bc0c8c 273
274 ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
275 str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
276
277 ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
278 str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
279
280 add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
281 add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
282 and R1, R1, #0x1f @ Check to see if User or System Mode
283 cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
284 cmpne R1, #0x10 @
285 ldmeqed R2, {lr}^ @ restore unbanked lr
286 @ else
287 ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
288
289 ldmfd SP!,{R0-R12} @ Restore general purpose registers
290 @ Exception handler can not change SP
291
292 add SP,SP,#0x20 @ Clear out the remaining stack space
293 ldmfd SP!,{LR} @ restore the link register for this context
294 rfefd SP! @ return from exception via srsfd stack slot
295