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