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