]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm
Fix bug in UncachedMemoryAllocationLib, Assembler, make DefaultExceptionHandler lib...
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / ExceptionSupport.ARMv6.asm
CommitLineData
8595f12d
A
1//------------------------------------------------------------------------------
2//
8a4d81e6 3// Copyright (c) 2008-2010 Apple Inc. All rights reserved.
8595f12d
A
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
8a4d81e6
A
19This 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 === ======
8595f12d
A
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
8a4d81e6 48 CPSR 0x5c
8595f12d
A
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
8a4d81e6
A
62//
63// This code gets copied to the ARM vector table
64// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
65//
8595f12d
A
66ExceptionHandlersStart
67
68Reset
69 b ResetEntry
70
71UndefinedInstruction
72 b UndefinedInstructionEntry
73
74SoftwareInterrupt
75 b SoftwareInterruptEntry
76
77PrefetchAbort
78 b PrefetchAbortEntry
79
80DataAbort
81 b DataAbortEntry
82
83ReservedException
84 b ReservedExceptionEntry
85
86Irq
87 b IrqEntry
88
89Fiq
90 b FiqEntry
91
92ResetEntry
93 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 94 ; We are already in SVC mode
8595f12d
A
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
8a4d81e6 99 mov R0,#0 ; ExceptionType
8595f12d
A
100 ldr R1,CommonExceptionEntry
101 bx R1
102
103UndefinedInstructionEntry
6f72e28d 104 sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
8595f12d 105 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 106 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6
A
111 mov R0,#1 ; ExceptionType
112 ldr R1,CommonExceptionEntry;
8595f12d
A
113 bx R1
114
115SoftwareInterruptEntry
6f72e28d 116 sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
8595f12d 117 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 118 ; We are already in SVC mode
8595f12d
A
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
8a4d81e6 123 mov R0,#2 ; ExceptionType
8595f12d
A
124 ldr R1,CommonExceptionEntry
125 bx R1
126
127PrefetchAbortEntry
128 sub LR,LR,#4
129 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 130 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 135 mov R0,#3 ; ExceptionType
8595f12d
A
136 ldr R1,CommonExceptionEntry
137 bx R1
138
139DataAbortEntry
140 sub LR,LR,#8
141 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 142 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 147 mov R0,#4 ; ExceptionType
8595f12d
A
148 ldr R1,CommonExceptionEntry
149 bx R1
150
151ReservedExceptionEntry
152 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 153 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 158 mov R0,#5 ; ExceptionType
8595f12d
A
159 ldr R1,CommonExceptionEntry
160 bx R1
161
162IrqEntry
163 sub LR,LR,#4
164 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 165 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 170 mov R0,#6 ; ExceptionType
8595f12d
A
171 ldr R1,CommonExceptionEntry
172 bx R1
173
174FiqEntry
175 sub LR,LR,#4
176 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 177 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6
A
181 ; Since we have already switch to SVC R8_fiq - R12_fiq
182 ; never get used or saved
183 mov R0,#7 ; ExceptionType
8595f12d
A
184 ldr R1,CommonExceptionEntry
185 bx R1
186
8a4d81e6
A
187//
188// This gets patched by the C code that patches in the vector table
189//
8595f12d
A
190CommonExceptionEntry
191 dcd 0x12345678
192
193ExceptionHandlersEnd
194
8a4d81e6
A
195//
196// This code runs from CpuDxe driver loaded address. It is patched into
197// CommonExceptionEntry.
198//
8595f12d
A
199AsmCommonExceptionEntry
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
8a4d81e6 215 add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
6f72e28d 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 ;
8a4d81e6
A
219 stmeqed R2, {lr}^ ; save unbanked lr
220 ; else
221 stmneed R2, {lr} ; save SVC lr
222
6f72e28d 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;
65e27445 232 str R5,[SP,#0x58] ; Update LR value pused by srsfd
6f72e28d 233
234NoAdjustNeeded
235
236 str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
8595f12d
A
237
238 sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
239 str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
240
8a4d81e6
A
241 ; R0 is ExceptionType
242 mov R1,SP ; R1 is SystemContext
243
244/*
6f72e28d 245VOID
246EFIAPI
247CommonCExceptionHandler (
248 IN EFI_EXCEPTION_TYPE ExceptionType, R0
249 IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
250 )
251
8a4d81e6 252*/
8595f12d
A
253 blx CommonCExceptionHandler ; Call exception handler
254
8a4d81e6
A
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
8595f12d 257
8a4d81e6
A
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
bbd8fad2 264 cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
8a4d81e6
A
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
8595f12d 270 ldmfd SP!,{R0-R12} ; Restore general purpose registers
8a4d81e6 271 ; Exception handler can not change SP
8595f12d
A
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
277 END
278
279