98fc96284ef97123f64d97fea50d8db4f39427d3
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / ExceptionSupport.ARMv6.asm
1 //------------------------------------------------------------------------------
2 //
3 // Copyright (c) 2008-2009 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
20
21 R0 0x00 # stmfd SP!,{R0-R12}
22 R1 0x04
23 R2 0x08
24 R3 0x0c
25 R4 0x10
26 R5 0x14
27 R6 0x18
28 R7 0x1c
29 R8 0x20
30 R9 0x24
31 R10 0x28
32 R11 0x2c
33 R12 0x30
34 SP 0x34 # reserved via adding 0x20 (32) to the SP
35 LR 0x38
36 PC 0x3c
37 CPSR 0x40
38 DFSR 0x44
39 DFAR 0x48
40 IFSR 0x4c
41 IFAR 0x50
42
43 LR 0x54 # SVC Link register (we need to restore it)
44
45 LR 0x58 # pushed by srsfd
46 CPSR 0x5c # pushed by srsfd
47
48 */
49
50
51 EXPORT ExceptionHandlersStart
52 EXPORT ExceptionHandlersEnd
53 EXPORT CommonExceptionEntry
54 EXPORT AsmCommonExceptionEntry
55 IMPORT CommonCExceptionHandler
56
57 PRESERVE8
58 AREA DxeExceptionHandlers, CODE, READONLY
59
60 ExceptionHandlersStart
61
62 Reset
63 b ResetEntry
64
65 UndefinedInstruction
66 b UndefinedInstructionEntry
67
68 SoftwareInterrupt
69 b SoftwareInterruptEntry
70
71 PrefetchAbort
72 b PrefetchAbortEntry
73
74 DataAbort
75 b DataAbortEntry
76
77 ReservedException
78 b ReservedExceptionEntry
79
80 Irq
81 b IrqEntry
82
83 Fiq
84 b FiqEntry
85
86 ResetEntry
87 srsfd #0x13! ; Store return state on SVC stack
88 cpsid if,#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,#0
94 ldr R1,CommonExceptionEntry
95 bx R1
96
97 UndefinedInstructionEntry
98 srsfd #0x13! ; Store return state on SVC stack
99 cpsid i,#0x13 ; Switch to SVC for common stack
100 stmfd SP!,{LR} ; Store the link register for the current mode
101 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
102 stmfd SP!,{R0-R12} ; Store the register state
103
104 mov R0,#1
105 ldr R1,CommonExceptionEntry
106 bx R1
107
108 SoftwareInterruptEntry
109 srsfd #0x13! ; Store return state on SVC stack
110 cpsid i,#0x13 ; Switch to SVC for common stack
111 stmfd SP!,{LR} ; Store the link register for the current mode
112 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
113 stmfd SP!,{R0-R12} ; Store the register state
114
115 mov R0,#2
116 ldr R1,CommonExceptionEntry
117 bx R1
118
119 PrefetchAbortEntry
120 sub LR,LR,#4
121 srsfd #0x13! ; Store return state on SVC stack
122 cpsid i,#0x13 ; Switch to SVC for common stack
123 stmfd SP!,{LR} ; Store the link register for the current mode
124 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
125 stmfd SP!,{R0-R12} ; Store the register state
126
127 mov R0,#3
128 ldr R1,CommonExceptionEntry
129 bx R1
130
131 DataAbortEntry
132 sub LR,LR,#8
133 srsfd #0x13! ; Store return state on SVC stack
134 cpsid i,#0x13 ; Switch to SVC for common stack
135 stmfd SP!,{LR} ; Store the link register for the current mode
136 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
137 stmfd SP!,{R0-R12} ; Store the register state
138
139 mov R0,#4
140 ldr R1,CommonExceptionEntry
141 bx R1
142
143 ReservedExceptionEntry
144 srsfd #0x13! ; Store return state on SVC stack
145 cpsid if,#0x13 ; Switch to SVC for common stack
146 stmfd SP!,{LR} ; Store the link register for the current mode
147 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
148 stmfd SP!,{R0-R12} ; Store the register state
149
150 mov R0,#5
151 ldr R1,CommonExceptionEntry
152 bx R1
153
154 IrqEntry
155 sub LR,LR,#4
156 srsfd #0x13! ; Store return state on SVC stack
157 cpsid i,#0x13 ; Switch to SVC for common stack
158 stmfd SP!,{LR} ; Store the link register for the current mode
159 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
160 stmfd SP!,{R0-R12} ; Store the register state
161
162 mov R0,#6
163 ldr R1,CommonExceptionEntry
164 bx R1
165
166 FiqEntry
167 sub LR,LR,#4
168 srsfd #0x13! ; Store return state on SVC stack
169 cpsid if,#0x13 ; Switch to SVC for common stack
170 stmfd SP!,{LR} ; Store the link register for the current mode
171 sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
172 stmfd SP!,{R0-R12} ; Store the register state
173
174 mov R0,#7
175 ldr R1,CommonExceptionEntry
176 bx R1
177
178 CommonExceptionEntry
179 dcd 0x12345678
180
181 ExceptionHandlersEnd
182
183 AsmCommonExceptionEntry
184 mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
185 str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
186
187 mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
188 str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
189
190 mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
191 str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
192
193 mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
194 str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
195
196 ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
197 str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
198
199 ldr R1, [SP, #0x58] ; PC is the LR pushed by srsfd
200 str R1, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
201 str R1, [SP, #0x38] ; Store it in EFI_SYSTEM_CONTEXT_ARM.LR
202
203 sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
204 str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
205
206 ; R0 is exception type
207 mov R1,SP ; Prepare System Context pointer as an argument for the exception handler
208 blx CommonCExceptionHandler ; Call exception handler
209
210 ldr R2,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
211 str R2,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
212
213 ldr R2,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
214 str R2,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
215
216 ldmfd SP!,{R0-R12} ; Restore general purpose registers
217 ; Exception handler can not change SP or LR as we would blow chunks
218
219 add SP,SP,#0x20 ; Clear out the remaining stack space
220 ldmfd SP!,{LR} ; restore the link register for this context
221 rfefd SP! ; return from exception via srsfd stack slot
222
223 END
224
225