diff options
Diffstat (limited to 'EmbeddedPkg/TemplateCpuDxe/Arm/Exceptions.S')
-rwxr-xr-x | EmbeddedPkg/TemplateCpuDxe/Arm/Exceptions.S | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/EmbeddedPkg/TemplateCpuDxe/Arm/Exceptions.S b/EmbeddedPkg/TemplateCpuDxe/Arm/Exceptions.S new file mode 100755 index 0000000000..d864759afd --- /dev/null +++ b/EmbeddedPkg/TemplateCpuDxe/Arm/Exceptions.S @@ -0,0 +1,158 @@ +#------------------------------------------------------------------------------ +# +# 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. +# +#------------------------------------------------------------------------------ + +.text +.align 2 + +.globl _ExceptionHandlersStart +.globl _ExceptionHandlersEnd +.globl _CommonExceptionEntry +.globl _AsmCommonExceptionEntry +.globl _gExceptionHandlers + +_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: + stmfd sp!,{r0-r1} + mov r0,#0 + ldr r1,_CommonExceptionEntry + bx r1 + +_UndefinedInstructionEntry: + stmfd sp!,{r0-r1} + mov r0,#1 + ldr r1,_CommonExceptionEntry + bx r1 + +_SoftwareInterruptEntry: + stmfd sp!,{r0-r1} + mov r0,#2 + ldr r1,_CommonExceptionEntry + bx r1 + +_PrefetchAbortEntry: + stmfd sp!,{r0-r1} + mov r0,#3 + sub lr,lr,#4 + ldr r1,_CommonExceptionEntry + bx r1 + +_DataAbortEntry: + stmfd sp!,{r0-r1} + mov r0,#4 + sub lr,lr,#8 + ldr r1,_CommonExceptionEntry + bx r1 + +_ReservedExceptionEntry: + stmfd sp!,{r0-r1} + mov r0,#5 + ldr r1,_CommonExceptionEntry + bx r1 + +_IrqEntry: + stmfd sp!,{r0-r1} + mov r0,#6 + sub lr,lr,#4 + ldr r1,_CommonExceptionEntry + bx r1 + +_FiqEntry: + stmfd sp!,{r0-r1} + mov r0,#7 + sub lr,lr,#4 + ldr r1,_CommonExceptionEntry + bx r1 + +_CommonExceptionEntry: + .byte 0x12 + .byte 0x34 + .byte 0x56 + .byte 0x78 + +_ExceptionHandlersEnd: + +LIndirectgExceptionHandlers: + .long _gExceptionHandlers + +_AsmCommonExceptionEntry: + mrc p15, 0, r1, c6, c0, 2 @ Read IFAR + stmfd sp!,{r1} @ Store the IFAR + + mrc p15, 0, r1, c5, c0, 1 @ Read IFSR + stmfd sp!,{r1} @ Store the IFSR + + mrc p15, 0, r1, c6, c0, 0 @ Read DFAR + stmfd sp!,{r1} @ Store the DFAR + + mrc p15, 0, r1, c5, c0, 0 @ Read DFSR + stmfd sp!,{r1} @ Store the DFSR + + mrs r1,spsr @ Read SPSR (which is the pre-exception CPSR) + stmfd sp!,{r1} @ Store the SPSR + + stmfd sp!,{lr} @ Store the link register (which is the pre-exception PC) + stmfd sp,{sp,lr}^ @ Store user/system mode stack pointer and link register + nop @ Required by ARM architecture + sub sp,sp,#0x08 @ Adjust stack pointer + stmfd sp!,{r2-r12} @ Store general purpose registers + + ldr r3,[sp,#0x40] @ Read saved R1 from the stack (it was saved by the exception entry routine) + ldr r2,[sp,#0x3C] @ Read saved R0 from the stack (it was saved by the exception entry routine) + stmfd sp!,{r2-r3} @ Store general purpose registers R0 and R1 + + mov r1,sp @ Prepare System Context pointer as an argument for the exception handler + + ldr r2,LIndirectgExceptionHandlers @ Offset to 32-bit address of exception handler + ldr r2,[r2] @ Load exception handler table + ldr r3,[r2,r0,lsl #2] @ Index to find the handler for this exception + +// blx r3 @ Call exception handler + bx r3 @ Call exception handler + + ldr r2,[sp,#0x40] @ Load CPSR from context, in case it has changed + msr SPSR_cxsf,r2 @ Store it back to the SPSR to be restored when exiting this handler + + ldmfd sp!,{r0-r12} @ Restore general purpose registers + ldmia sp,{sp,lr}^ @ Restore user/system mode stack pointer and link register + nop @ Required by ARM architecture + add sp,sp,#0x08 @ Adjust stack pointer + ldmfd sp!,{lr} @ Restore the link register (which is the pre-exception PC) + add sp,sp,#0x1C @ Clear out the remaining stack space + movs pc,lr @ Return from exception + |