Adding support for a single stack, GCC check in will follow
[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
104 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 105 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
106 stmfd SP!,{LR} ; Store the link register for the current mode
107 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
108 stmfd SP!,{R0-R12} ; Store the register state
109
8a4d81e6
A
110 mov R0,#1 ; ExceptionType
111 ldr R1,CommonExceptionEntry;
8595f12d
A
112 bx R1
113
114SoftwareInterruptEntry
115 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 116 ; We are already in SVC mode
8595f12d
A
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
8a4d81e6 121 mov R0,#2 ; ExceptionType
8595f12d
A
122 ldr R1,CommonExceptionEntry
123 bx R1
124
125PrefetchAbortEntry
126 sub LR,LR,#4
127 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 128 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 133 mov R0,#3 ; ExceptionType
8595f12d
A
134 ldr R1,CommonExceptionEntry
135 bx R1
136
137DataAbortEntry
138 sub LR,LR,#8
139 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 140 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
141 stmfd SP!,{LR} ; Store the link register for the current mode
142 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
143 stmfd SP!,{R0-R12} ; Store the register state
144
8a4d81e6 145 mov R0,#4 ; ExceptionType
8595f12d
A
146 ldr R1,CommonExceptionEntry
147 bx R1
148
149ReservedExceptionEntry
150 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 151 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 156 mov R0,#5 ; ExceptionType
8595f12d
A
157 ldr R1,CommonExceptionEntry
158 bx R1
159
160IrqEntry
161 sub LR,LR,#4
162 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 163 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
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
8a4d81e6 168 mov R0,#6 ; ExceptionType
8595f12d
A
169 ldr R1,CommonExceptionEntry
170 bx R1
171
172FiqEntry
173 sub LR,LR,#4
174 srsfd #0x13! ; Store return state on SVC stack
8a4d81e6 175 cps #0x13 ; Switch to SVC for common stack
8595f12d
A
176 stmfd SP!,{LR} ; Store the link register for the current mode
177 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
178 stmfd SP!,{R0-R12} ; Store the register state
8a4d81e6
A
179 ; Since we have already switch to SVC R8_fiq - R12_fiq
180 ; never get used or saved
181 mov R0,#7 ; ExceptionType
8595f12d
A
182 ldr R1,CommonExceptionEntry
183 bx R1
184
8a4d81e6
A
185//
186// This gets patched by the C code that patches in the vector table
187//
8595f12d
A
188CommonExceptionEntry
189 dcd 0x12345678
190
191ExceptionHandlersEnd
192
8a4d81e6
A
193//
194// This code runs from CpuDxe driver loaded address. It is patched into
195// CommonExceptionEntry.
196//
8595f12d
A
197AsmCommonExceptionEntry
198 mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
199 str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
200
201 mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
202 str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
203
204 mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
205 str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
206
207 mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
208 str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
209
210 ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
211 str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
212
8a4d81e6
A
213 add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
214 and R1, R1, #0x1f ; Check CPSR to see if User or System Mode
215 cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
216 cmpne R1, #0x10 ;
217 stmeqed R2, {lr}^ ; save unbanked lr
218 ; else
219 stmneed R2, {lr} ; save SVC lr
220
8595f12d
A
221 ldr R1, [SP, #0x58] ; PC is the LR pushed by srsfd
222 str R1, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
8595f12d
A
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
8a4d81e6
A
227 ; R0 is ExceptionType
228 mov R1,SP ; R1 is SystemContext
229
230/*
231VOID\r
232EFIAPI\r
233CommonCExceptionHandler (\r
234 IN EFI_EXCEPTION_TYPE ExceptionType, R0\r
235 IN OUT EFI_SYSTEM_CONTEXT SystemContext R1\r
236 )\r
237*/
8595f12d
A
238 blx CommonCExceptionHandler ; Call exception handler
239
8a4d81e6
A
240 ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
241 str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
8595f12d 242
8a4d81e6
A
243 ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
244 str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
245
246 add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
247 add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
248 and R1, R1, #0x1f ; Check to see if User or System Mode
249 cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
250 cmpne R1, #0x10 ;
251 ldmeqed R2, {lr}^ ; restore unbanked lr
252 ; else
253 ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
254
8595f12d 255 ldmfd SP!,{R0-R12} ; Restore general purpose registers
8a4d81e6 256 ; Exception handler can not change SP
8595f12d
A
257
258 add SP,SP,#0x20 ; Clear out the remaining stack space
259 ldmfd SP!,{LR} ; restore the link register for this context
260 rfefd SP! ; return from exception via srsfd stack slot
261
262 END
263
264