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