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