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