Working on having a single stack for all modes. This code currently has an issue...
authorAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 22 Dec 2009 23:23:41 +0000 (23:23 +0000)
committerAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 22 Dec 2009 23:23:41 +0000 (23:23 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9587 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm [new file with mode: 0755]

diff --git a/ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm b/ArmPkg/Drivers/CpuDxe/ExceptionSupport.ARMv6.asm
new file mode 100755 (executable)
index 0000000..98fc962
--- /dev/null
@@ -0,0 +1,225 @@
+//------------------------------------------------------------------------------ 
+//
+// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+//
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution.  The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//------------------------------------------------------------------------------
+
+
+
+/*
+
+This is the stack constructed by the exception handler
+
+  R0    0x00    # stmfd     SP!,{R0-R12}
+  R1    0x04
+  R2    0x08
+  R3    0x0c
+  R4    0x10
+  R5    0x14
+  R6    0x18
+  R7    0x1c
+  R8    0x20
+  R9    0x24
+  R10   0x28
+  R11   0x2c
+  R12   0x30
+  SP    0x34    # reserved via adding 0x20 (32) to the SP
+  LR    0x38
+  PC    0x3c
+  CPSR  0x40
+  DFSR  0x44
+  DFAR  0x48
+  IFSR  0x4c
+  IFAR  0x50
+  
+  LR    0x54    # SVC Link register (we need to restore it)
+  
+  LR    0x58    # pushed by srsfd    
+  CPSR  0x5c    # pushed by srsfd
+
+ */
+  EXPORT  ExceptionHandlersStart
+  EXPORT  ExceptionHandlersEnd
+  EXPORT  CommonExceptionEntry
+  EXPORT  AsmCommonExceptionEntry
+  IMPORT  CommonCExceptionHandler
+
+  PRESERVE8
+  AREA  DxeExceptionHandlers, CODE, READONLY
+  
+ExceptionHandlersStart
+
+Reset
+  b   ResetEntry
+
+UndefinedInstruction
+  b   UndefinedInstructionEntry
+
+SoftwareInterrupt
+  b   SoftwareInterruptEntry
+
+PrefetchAbort
+  b   PrefetchAbortEntry
+
+DataAbort
+  b   DataAbortEntry
+
+ReservedException
+  b   ReservedExceptionEntry
+
+Irq
+  b   IrqEntry
+
+Fiq
+  b   FiqEntry
+
+ResetEntry
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     if,#0x13                  ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+  
+  mov       R0,#0
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+UndefinedInstructionEntry
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     i,#0x13                   ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#1
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+SoftwareInterruptEntry
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     i,#0x13                   ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#2
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+PrefetchAbortEntry
+  sub       LR,LR,#4
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     i,#0x13                   ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#3
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+DataAbortEntry
+  sub       LR,LR,#8
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     i,#0x13                   ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#4
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+ReservedExceptionEntry
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     if,#0x13                  ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#5
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+IrqEntry
+  sub       LR,LR,#4
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     i,#0x13                   ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#6
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+FiqEntry
+  sub       LR,LR,#4
+  srsfd     #0x13!                    ; Store return state on SVC stack
+  cpsid     if,#0x13                  ; Switch to SVC for common stack
+  stmfd     SP!,{LR}                  ; Store the link register for the current mode
+  sub       SP,SP,#0x20               ; Save space for SP, LR, PC, IFAR - CPSR
+  stmfd     SP!,{R0-R12}              ; Store the register state
+
+  mov       R0,#7
+  ldr       R1,CommonExceptionEntry
+  bx        R1
+
+CommonExceptionEntry
+  dcd       0x12345678
+
+ExceptionHandlersEnd
+
+AsmCommonExceptionEntry
+  mrc       p15, 0, R1, c6, c0, 2   ; Read IFAR
+  str       R1, [SP, #0x50]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR 
+  
+  mrc       p15, 0, R1, c5, c0, 1   ; Read IFSR
+  str       R1, [SP, #0x4c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+  
+  mrc       p15, 0, R1, c6, c0, 0   ; Read DFAR
+  str       R1, [SP, #0x48]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+  
+  mrc       p15, 0, R1, c5, c0, 0   ; Read DFSR
+  str       R1, [SP, #0x44]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+  
+  ldr       R1, [SP, #0x5c]         ; srsfd saved pre-exception CPSR on the stack 
+  str       R1, [SP, #0x40]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+  ldr       R1, [SP, #0x58]         ; PC is the LR pushed by srsfd 
+  str       R1, [SP, #0x3c]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+  str       R1, [SP, #0x38]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.LR
+  
+  sub       R1, SP, #0x60           ; We pused 0x60 bytes on the stack 
+  str       R1, [SP, #0x34]         ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+  
+                                    ; R0 is exception type 
+  mov       R1,SP                   ; Prepare System Context pointer as an argument for the exception handler
+  blx       CommonCExceptionHandler ; Call exception handler
+  
+  ldr       R2,[SP,#0x40]           ; EFI_SYSTEM_CONTEXT_ARM.CPSR
+  str       R2,[SP,#0x5c]           ; Store it back to srsfd stack slot so it can be restored 
+
+  ldr       R2,[SP,#0x3c]           ; EFI_SYSTEM_CONTEXT_ARM.PC
+  str       R2,[SP,#0x58]           ; Store it back to srsfd stack slot so it can be restored 
+
+  ldmfd     SP!,{R0-R12}            ; Restore general purpose registers
+                                    ; Exception handler can not change SP or LR as we would blow chunks
+                                    
+  add       SP,SP,#0x20             ; Clear out the remaining stack space
+  ldmfd     SP!,{LR}                ; restore the link register for this context
+  rfefd     SP!                     ; return from exception via srsfd stack slot
+  
+  END
+
+