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