]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/DebugAgentSymbolsBaseLib/Arm/DebugAgentException.asm
cf59447bed106863a2a42c4ca85d6f58e0785abc
[mirror_edk2.git] / ArmPkg / Library / DebugAgentSymbolsBaseLib / Arm / DebugAgentException.asm
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 EXPORT DebugAgentVectorTable
54 IMPORT DefaultExceptionHandler
55
56 PRESERVE8
57 AREA DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5
58
59 //
60 // This code gets copied to the ARM vector table
61 // ExceptionHandlersStart - ExceptionHandlersEnd gets copied
62 //
63 DebugAgentVectorTable FUNCTION
64 b ResetEntry
65 b UndefinedInstructionEntry
66 b SoftwareInterruptEntry
67 b PrefetchAbortEntry
68 b DataAbortEntry
69 b ReservedExceptionEntry
70 b IrqEntry
71 b FiqEntry
72 ENDFUNC
73
74 ResetEntry
75 srsfd #0x13! ; Store return state on SVC stack
76 ; We are already in SVC mode
77 stmfd SP!,{LR} ; Store the link register for the current mode
78 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
79 stmfd SP!,{R0-R12} ; Store the register state
80
81 mov R0,#0 ; ExceptionType
82 ldr R1,CommonExceptionEntry
83 bx R1
84
85 UndefinedInstructionEntry
86 sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
87 srsfd #0x13! ; Store return state on SVC stack
88 cps #0x13 ; Switch to SVC for common stack
89 stmfd SP!,{LR} ; Store the link register for the current mode
90 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
91 stmfd SP!,{R0-R12} ; Store the register state
92
93 mov R0,#1 ; ExceptionType
94 ldr R1,CommonExceptionEntry;
95 bx R1
96
97 SoftwareInterruptEntry
98 sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
99 srsfd #0x13! ; Store return state on SVC stack
100 ; We are already in SVC mode
101 stmfd SP!,{LR} ; Store the link register for the current mode
102 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
103 stmfd SP!,{R0-R12} ; Store the register state
104
105 mov R0,#2 ; ExceptionType
106 ldr R1,CommonExceptionEntry
107 bx R1
108
109 PrefetchAbortEntry
110 sub LR,LR,#4
111 srsfd #0x13! ; Store return state on SVC stack
112 cps #0x13 ; Switch to SVC for common stack
113 stmfd SP!,{LR} ; Store the link register for the current mode
114 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
115 stmfd SP!,{R0-R12} ; Store the register state
116
117 mov R0,#3 ; ExceptionType
118 ldr R1,CommonExceptionEntry
119 bx R1
120
121 DataAbortEntry
122 sub LR,LR,#8
123 srsfd #0x13! ; Store return state on SVC stack
124 cps #0x13 ; Switch to SVC for common stack
125 stmfd SP!,{LR} ; Store the link register for the current mode
126 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
127 stmfd SP!,{R0-R12} ; Store the register state
128
129 mov R0,#4 ; ExceptionType
130 ldr R1,CommonExceptionEntry
131 bx R1
132
133 ReservedExceptionEntry
134 srsfd #0x13! ; Store return state on SVC stack
135 cps #0x13 ; Switch to SVC for common stack
136 stmfd SP!,{LR} ; Store the link register for the current mode
137 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
138 stmfd SP!,{R0-R12} ; Store the register state
139
140 mov R0,#5 ; ExceptionType
141 ldr R1,CommonExceptionEntry
142 bx R1
143
144 IrqEntry
145 sub LR,LR,#4
146 srsfd #0x13! ; Store return state on SVC stack
147 cps #0x13 ; Switch to SVC for common stack
148 stmfd SP!,{LR} ; Store the link register for the current mode
149 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
150 stmfd SP!,{R0-R12} ; Store the register state
151
152 mov R0,#6 ; ExceptionType
153 ldr R1,CommonExceptionEntry
154 bx R1
155
156 FiqEntry
157 sub LR,LR,#4
158 srsfd #0x13! ; Store return state on SVC stack
159 cps #0x13 ; Switch to SVC for common stack
160 stmfd SP!,{LR} ; Store the link register for the current mode
161 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
162 stmfd SP!,{R0-R12} ; Store the register state
163 ; Since we have already switch to SVC R8_fiq - R12_fiq
164 ; never get used or saved
165 mov R0,#7 ; ExceptionType
166 ldr R1,CommonExceptionEntry
167 bx R1
168
169 //
170 // This gets patched by the C code that patches in the vector table
171 //
172 CommonExceptionEntry
173 dcd AsmCommonExceptionEntry
174
175 ExceptionHandlersEnd
176
177 //
178 // This code runs from CpuDxe driver loaded address. It is patched into
179 // CommonExceptionEntry.
180 //
181 AsmCommonExceptionEntry
182 mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
183 str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
184
185 mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
186 str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
187
188 mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
189 str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
190
191 mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
192 str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
193
194 ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
195 str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
196
197 add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
198 and R3, R1, #0x1f ; Check CPSR to see if User or System Mode
199 cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
200 cmpne R3, #0x10 ;
201 stmeqed R2, {lr}^ ; save unbanked lr
202 ; else
203 stmneed R2, {lr} ; save SVC lr
204
205
206 ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd
207 ; Check to see if we have to adjust for Thumb entry
208 sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType ==2)) {
209 cmp r4, #1 ; // UND & SVC have different LR adjust for Thumb
210 bhi NoAdjustNeeded
211
212 tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry
213 addne R5, R5, #2 ; PC += 2;
214 str R5,[SP,#0x58] ; Update LR value pused by srsfd
215
216 NoAdjustNeeded
217
218 str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
219
220 sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
221 str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
222
223 ; R0 is ExceptionType
224 mov R1,SP ; R1 is SystemContext
225
226 #if (FixedPcdGet32(PcdVFPEnabled))
227 vpush {d0-d15} ; save vstm registers in case they are used in optimizations
228 #endif
229
230 /*
231 VOID
232 EFIAPI
233 DefaultExceptionHandler (
234 IN EFI_EXCEPTION_TYPE ExceptionType, R0
235 IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
236 )
237
238 */
239 blx DefaultExceptionHandler ; Call exception handler
240
241 #if (FixedPcdGet32(PcdVFPEnabled))
242 vpop {d0-d15}
243 #endif
244
245 ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
246 mcr p15, 0, R1, c5, c0, 1 ; Write IFSR
247
248 ldr R1, [SP, #0x44] ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
249 mcr p15, 0, R1, c5, c0, 0 ; Write DFSR
250
251 ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
252 str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
253
254 ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
255 str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
256
257 add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
258 add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
259 and R1, R1, #0x1f ; Check to see if User or System Mode
260 cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
261 cmpne R1, #0x10 ;
262 ldmeqed R2, {lr}^ ; restore unbanked lr
263 ; else
264 ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
265
266 ldmfd SP!,{R0-R12} ; Restore general purpose registers
267 ; Exception handler can not change SP
268
269 add SP,SP,#0x20 ; Clear out the remaining stack space
270 ldmfd SP!,{LR} ; restore the link register for this context
271 rfefd SP! ; return from exception via srsfd stack slot
272
273 END