MdeModulePkg/MdeModulePkg.dsc: add MM_STANDALONE FTW and variable modules
[mirror_edk2.git] / ArmPkg / Library / DebugAgentSymbolsBaseLib / Arm / DebugAgentException.asm
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   EXPORT  DebugAgentVectorTable\r
54   IMPORT  DefaultExceptionHandler\r
55 \r
56   PRESERVE8\r
57   AREA  DebugAgentException, CODE, READONLY, CODEALIGN, ALIGN=5\r
58 \r
59 //\r
60 // This code gets copied to the ARM vector table\r
61 // ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
62 //\r
63 DebugAgentVectorTable FUNCTION\r
64   b   ResetEntry\r
65   b   UndefinedInstructionEntry\r
66   b   SoftwareInterruptEntry\r
67   b   PrefetchAbortEntry\r
68   b   DataAbortEntry\r
69   b   ReservedExceptionEntry\r
70   b   IrqEntry\r
71   b   FiqEntry\r
72   ENDFUNC\r
73 \r
74 ResetEntry\r
75   srsfd     #0x13!                    ; Store return state on SVC stack\r
76                                       ; We are already in SVC mode\r
77   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
78   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
79   stmfd     SP!,{R0-R12}              ; Store the register state\r
80 \r
81   mov       R0,#0                     ; ExceptionType\r
82   ldr       R1,CommonExceptionEntry\r
83   bx        R1\r
84 \r
85 UndefinedInstructionEntry\r
86   sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
87   srsfd     #0x13!                    ; Store return state on SVC stack\r
88   cps       #0x13                     ; Switch to SVC for common stack\r
89   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
90   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
91   stmfd     SP!,{R0-R12}              ; Store the register state\r
92 \r
93   mov       R0,#1                     ; ExceptionType\r
94   ldr       R1,CommonExceptionEntry;\r
95   bx        R1\r
96 \r
97 SoftwareInterruptEntry\r
98   sub       LR, LR, #4                ; Only -2 for Thumb, adjust in CommonExceptionEntry\r
99   srsfd     #0x13!                    ; Store return state on SVC stack\r
100                                       ; We are already in SVC mode\r
101   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
102   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
103   stmfd     SP!,{R0-R12}              ; Store the register state\r
104 \r
105   mov       R0,#2                     ; ExceptionType\r
106   ldr       R1,CommonExceptionEntry\r
107   bx        R1\r
108 \r
109 PrefetchAbortEntry\r
110   sub       LR,LR,#4\r
111   srsfd     #0x13!                    ; Store return state on SVC stack\r
112   cps       #0x13                     ; Switch to SVC for common stack\r
113   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
114   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
115   stmfd     SP!,{R0-R12}              ; Store the register state\r
116 \r
117   mov       R0,#3                     ; ExceptionType\r
118   ldr       R1,CommonExceptionEntry\r
119   bx        R1\r
120 \r
121 DataAbortEntry\r
122   sub       LR,LR,#8\r
123   srsfd     #0x13!                    ; Store return state on SVC stack\r
124   cps       #0x13                     ; Switch to SVC for common stack\r
125   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
126   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
127   stmfd     SP!,{R0-R12}              ; Store the register state\r
128 \r
129   mov       R0,#4                     ; ExceptionType\r
130   ldr       R1,CommonExceptionEntry\r
131   bx        R1\r
132 \r
133 ReservedExceptionEntry\r
134   srsfd     #0x13!                    ; Store return state on SVC stack\r
135   cps       #0x13                     ; Switch to SVC for common stack\r
136   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
137   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
138   stmfd     SP!,{R0-R12}              ; Store the register state\r
139 \r
140   mov       R0,#5                     ; ExceptionType\r
141   ldr       R1,CommonExceptionEntry\r
142   bx        R1\r
143 \r
144 IrqEntry\r
145   sub       LR,LR,#4\r
146   srsfd     #0x13!                    ; Store return state on SVC stack\r
147   cps       #0x13                     ; Switch to SVC for common stack\r
148   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
149   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
150   stmfd     SP!,{R0-R12}              ; Store the register state\r
151 \r
152   mov       R0,#6                     ; ExceptionType\r
153   ldr       R1,CommonExceptionEntry\r
154   bx        R1\r
155 \r
156 FiqEntry\r
157   sub       LR,LR,#4\r
158   srsfd     #0x13!                    ; Store return state on SVC stack\r
159   cps       #0x13                     ; Switch to SVC for common stack\r
160   stmfd     SP!,{LR}                  ; Store the link register for the current mode\r
161   sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR\r
162   stmfd     SP!,{R0-R12}              ; Store the register state\r
163                                       ; Since we have already switch to SVC R8_fiq - R12_fiq\r
164                                       ; never get used or saved\r
165   mov       R0,#7                     ; ExceptionType\r
166   ldr       R1,CommonExceptionEntry\r
167   bx        R1\r
168 \r
169 //\r
170 // This gets patched by the C code that patches in the vector table\r
171 //\r
172 CommonExceptionEntry\r
173   dcd       AsmCommonExceptionEntry\r
174 \r
175 ExceptionHandlersEnd\r
176 \r
177 //\r
178 // This code runs from CpuDxe driver loaded address. It is patched into\r
179 // CommonExceptionEntry.\r
180 //\r
181 AsmCommonExceptionEntry\r
182   mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR\r
183   str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
184 \r
185   mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR\r
186   str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
187 \r
188   mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR\r
189   str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
190 \r
191   mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR\r
192   str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
193 \r
194   ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack\r
195   str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
196 \r
197   add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
198   and       R3, R1, #0x1f           ; Check CPSR to see if User or System Mode\r
199   cmp       R3, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1df))\r
200   cmpne     R3, #0x10               ;\r
201   stmeqed   R2, {lr}^               ;   save unbanked lr\r
202                                     ; else\r
203   stmneed   R2, {lr}                ;   save SVC lr\r
204 \r
205 \r
206   ldr       R5, [SP, #0x58]         ; PC is the LR pushed by srsfd\r
207                                     ; Check to see if we have to adjust for Thumb entry\r
208   sub       r4, r0, #1              ; if (ExceptionType == 1 || ExceptionType ==2)) {\r
209   cmp       r4, #1                  ;   // UND & SVC have different LR adjust for Thumb\r
210   bhi       NoAdjustNeeded\r
211 \r
212   tst       r1, #0x20               ;   if ((CPSR & T)) == T) {  // Thumb Mode on entry\r
213   addne     R5, R5, #2              ;     PC += 2;\r
214   str       R5,[SP,#0x58]           ; Update LR value pused by srsfd\r
215 \r
216 NoAdjustNeeded\r
217 \r
218   str       R5, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
219 \r
220   sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack\r
221   str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
222 \r
223                                     ; R0 is ExceptionType\r
224   mov       R1,SP                   ; R1 is SystemContext\r
225 \r
226 #if (FixedPcdGet32(PcdVFPEnabled))\r
227   vpush    {d0-d15}                  ; save vstm registers in case they are used in optimizations\r
228 #endif\r
229 \r
230 /*\r
231 VOID\r
232 EFIAPI\r
233 DefaultExceptionHandler (\r
234   IN     EFI_EXCEPTION_TYPE           ExceptionType,   R0\r
235   IN OUT EFI_SYSTEM_CONTEXT           SystemContext    R1\r
236   )\r
237 \r
238 */\r
239   blx       DefaultExceptionHandler ; Call exception handler\r
240 \r
241 #if (FixedPcdGet32(PcdVFPEnabled))\r
242   vpop      {d0-d15}\r
243 #endif\r
244 \r
245   ldr       R1, [SP, #0x4c]         ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR\r
246   mcr       p15, 0, R1, c5, c0, 1   ; Write IFSR\r
247 \r
248   ldr       R1, [SP, #0x44]         ; sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR\r
249   mcr       p15, 0, R1, c5, c0, 0   ; Write DFSR\r
250 \r
251   ldr       R1,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC\r
252   str       R1,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored\r
253 \r
254   ldr       R1,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR\r
255   str       R1,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored\r
256 \r
257   add       R3, SP, #0x54           ; Make R3 point to SVC LR saved on entry\r
258   add       R2, SP, #0x38           ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
259   and       R1, R1, #0x1f           ; Check to see if User or System Mode\r
260   cmp       R1, #0x1f               ; if ((CPSR == 0x10) || (CPSR == 0x1f))\r
261   cmpne     R1, #0x10               ;\r
262   ldmeqed   R2, {lr}^               ;   restore unbanked lr\r
263                                     ; else\r
264   ldmneed   R3, {lr}                ;   restore SVC lr, via ldmfd SP!, {LR}\r
265 \r
266   ldmfd     SP!,{R0-R12}            ; Restore general purpose registers\r
267                                     ; Exception handler can not change SP\r
268 \r
269   add       SP,SP,#0x20             ; Clear out the remaining stack space\r
270   ldmfd     SP!,{LR}                ; restore the link register for this context\r
271   rfefd     SP!                     ; return from exception via srsfd stack slot\r
272 \r
273   END\r