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