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