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