+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Use ARMv6 instruction to operate on a single stack\r
-#\r
-# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
-#\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-/*\r
-\r
-This is the stack constructed by the exception handler (low address to high address)\r
- # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM\r
- Reg Offset\r
- === ======\r
- R0 0x00 # stmfd SP!,{R0-R12}\r
- R1 0x04\r
- R2 0x08\r
- R3 0x0c\r
- R4 0x10\r
- R5 0x14\r
- R6 0x18\r
- R7 0x1c\r
- R8 0x20\r
- R9 0x24\r
- R10 0x28\r
- R11 0x2c\r
- R12 0x30\r
- SP 0x34 # reserved via adding 0x20 (32) to the SP\r
- LR 0x38\r
- PC 0x3c\r
- CPSR 0x40\r
- DFSR 0x44\r
- DFAR 0x48\r
- IFSR 0x4c\r
- IFAR 0x50\r
-\r
- LR 0x54 # SVC Link register (we need to restore it)\r
-\r
- LR 0x58 # pushed by srsfd\r
- CPSR 0x5c\r
-\r
- */\r
-\r
-\r
-GCC_ASM_EXPORT(ExceptionHandlersStart)\r
-GCC_ASM_EXPORT(ExceptionHandlersEnd)\r
-GCC_ASM_EXPORT(CommonExceptionEntry)\r
-GCC_ASM_EXPORT(AsmCommonExceptionEntry)\r
-GCC_ASM_EXPORT(GdbExceptionHandler)\r
-\r
-.text\r
-.align 3\r
-\r
-\r
-//\r
-// This code gets copied to the ARM vector table\r
-// ExceptionHandlersStart - ExceptionHandlersEnd gets copied\r
-//\r
-ASM_PFX(ExceptionHandlersStart):\r
-\r
-ASM_PFX(Reset):\r
- b ASM_PFX(Reset)\r
-\r
-ASM_PFX(UndefinedInstruction):\r
- b ASM_PFX(UndefinedInstructionEntry)\r
-\r
-ASM_PFX(SoftwareInterrupt):\r
- b ASM_PFX(SoftwareInterruptEntry)\r
-\r
-ASM_PFX(PrefetchAbort):\r
- b ASM_PFX(PrefetchAbortEntry)\r
-\r
-ASM_PFX(DataAbort):\r
- b ASM_PFX(DataAbortEntry)\r
-\r
-ASM_PFX(ReservedException):\r
- b ASM_PFX(ReservedExceptionEntry)\r
-\r
-ASM_PFX(Irq):\r
- b ASM_PFX(Irq)\r
-\r
-ASM_PFX(Fiq):\r
- b ASM_PFX(FiqEntry)\r
-\r
-\r
-ASM_PFX(UndefinedInstructionEntry):\r
- sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cpsid f,#0x13 @ Switch to SVC for common stack\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
-\r
- mov R0,#1 @ ExceptionType\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-ASM_PFX(SoftwareInterruptEntry):\r
- sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cpsid f @ We are already in SVC mode\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
-\r
- mov R0,#2 @ ExceptionType\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-ASM_PFX(PrefetchAbortEntry):\r
- sub LR,LR,#4\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cpsid f,#0x13 @ Switch to SVC for common stack\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
-\r
- mov R0,#3 @ ExceptionType\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-ASM_PFX(DataAbortEntry):\r
- sub LR,LR,#8\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cpsid f,#0x13 @ Switch to SVC for common stack\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
-\r
- mov R0,#4\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-ASM_PFX(ReservedExceptionEntry):\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cpsid f,#0x13 @ Switch to SVC for common stack\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
-\r
- mov R0,#5\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-ASM_PFX(FiqEntry):\r
- sub LR,LR,#4\r
- srsdb #0x13! @ Store return state on SVC stack\r
- cps #0x13 @ Switch to SVC for common stack\r
- stmfd SP!,{LR} @ Store the link register for the current mode\r
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR\r
- stmfd SP!,{R0-R12} @ Store the register state\r
- @ Since we have already switch to SVC R8_fiq - R12_fiq\r
- @ never get used or saved\r
- mov R0,#7 @ ExceptionType\r
- ldr R1,ASM_PFX(CommonExceptionEntry)\r
- bx R1\r
-\r
-//\r
-// This gets patched by the C code that patches in the vector table\r
-//\r
-ASM_PFX(CommonExceptionEntry):\r
- .byte 0x12\r
- .byte 0x34\r
- .byte 0x56\r
- .byte 0x78\r
-\r
-ASM_PFX(ExceptionHandlersEnd):\r
-\r
-//\r
-// This code runs from CpuDxe driver loaded address. It is patched into\r
-// CommonExceptionEntry.\r
-//\r
-ASM_PFX(AsmCommonExceptionEntry):\r
- mrc p15, 0, R1, c6, c0, 2 @ Read IFAR\r
- str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR\r
-\r
- mrc p15, 0, R1, c5, c0, 1 @ Read IFSR\r
- str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR\r
-\r
- mrc p15, 0, R1, c6, c0, 0 @ Read DFAR\r
- str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR\r
-\r
- mrc p15, 0, R1, c5, c0, 0 @ Read DFSR\r
- str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR\r
-\r
- ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack\r
- str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR\r
-\r
- add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
- and R3, R1, #0x1f @ Check CPSR to see if User or System Mode\r
- cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))\r
- cmpne R3, #0x10 @\r
- stmeqed R2, {lr}^ @ save unbanked lr\r
- @ else\r
- stmneed R2, {lr} @ save SVC lr\r
-\r
-\r
- ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd\r
- @ Check to see if we have to adjust for Thumb entry\r
- sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {\r
- cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb\r
- bhi NoAdjustNeeded\r
-\r
- tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry\r
- addne R5, R5, #2 @ PC += 2@\r
- str R5,[SP,#0x58] @ Update LR value pused by srsfd\r
-\r
-NoAdjustNeeded:\r
-\r
- str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC\r
-\r
- sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack\r
- str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP\r
-\r
- @ R0 is ExceptionType\r
- mov R1,SP @ R1 is SystemContext\r
-\r
-/*\r
-VOID\r
-EFIAPI\r
-GdbExceptionHandler (\r
- IN EFI_EXCEPTION_TYPE ExceptionType, R0\r
- IN OUT EFI_SYSTEM_CONTEXT SystemContext R1\r
- )\r
-\r
-*/\r
- blx ASM_PFX(GdbExceptionHandler) @ Call exception handler\r
-\r
- ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC\r
- str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored\r
-\r
- ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR\r
- str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored\r
-\r
- add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry\r
- add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR\r
- and R1, R1, #0x1f @ Check to see if User or System Mode\r
- cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))\r
- cmpne R1, #0x10 @\r
- ldmeqed R2, {lr}^ @ restore unbanked lr\r
- @ else\r
- ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}\r
-\r
- ldmfd SP!,{R0-R12} @ Restore general purpose registers\r
- @ Exception handler can not change SP\r
-\r
- add SP,SP,#0x20 @ Clear out the remaining stack space\r
- ldmfd SP!,{LR} @ restore the link register for this context\r
- rfefd SP! @ return from exception via srsfd stack slot\r
-\r