On 7 March 2016 at 16:16, Cohen, Eugene <[email protected]> wrote: > Use the new ARM/AArch64 implementation of the base > CpuExceptionHandlerLib library from CpuDxe to centralize > exception handling. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Eugene Cohen <[email protected]>
The patches look fine to me. I will proceed and apply the first two. However, this third one needs to wait until all users of CpuDxe have the correct resolution for CpuExceptionHandlerLib. I think this is only ArmVirtPkg/ArmVirt.dsc.inc, but I'd like a nod from Leif before pushing this final change through. Thanks, Ard. > --- > ArmPkg/Drivers/CpuDxe/AArch64/Exception.c | 154 --------- > ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S | 402 > ----------------------- > ArmPkg/Drivers/CpuDxe/Arm/Exception.c | 234 ------------- > ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.S | 304 ----------------- > ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.asm | 301 ----------------- > ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 10 +- > ArmPkg/Drivers/CpuDxe/Exception.c | 95 ++++++ > 7 files changed, 98 insertions(+), 1402 deletions(-) > delete mode 100644 ArmPkg/Drivers/CpuDxe/AArch64/Exception.c > delete mode 100644 ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S > delete mode 100644 ArmPkg/Drivers/CpuDxe/Arm/Exception.c > delete mode 100644 ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.S > delete mode 100644 ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.asm > create mode 100644 ArmPkg/Drivers/CpuDxe/Exception.c > > diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c > b/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c > deleted file mode 100644 > index ce1c6ce..0000000 > --- a/ArmPkg/Drivers/CpuDxe/AArch64/Exception.c > +++ /dev/null > @@ -1,154 +0,0 @@ > -/** @file > - > - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> > - Portions Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR> > - > - 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. > - > -**/ > - > -#include "CpuDxe.h" > - > -#include <Chipset/AArch64.h> > - > -VOID > -ExceptionHandlersStart ( > - VOID > - ); > - > -VOID > -ExceptionHandlersEnd ( > - VOID > - ); > - > -VOID > -CommonExceptionEntry ( > - VOID > - ); > - > -VOID > -AsmCommonExceptionEntry ( > - VOID > - ); > - > - > -EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_AARCH64_EXCEPTION + 1]; > -EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_AARCH64_EXCEPTION + > 1]; > - > - > - > -/** > - This function registers and enables the handler specified by > InterruptHandler for a processor > - interrupt or exception type specified by InterruptType. If > InterruptHandler is NULL, then the > - handler for the processor interrupt or exception type specified by > InterruptType is uninstalled. > - The installed handler is called once for each processor interrupt or > exception. > - > - @param InterruptType A pointer to the processor's current interrupt > state. Set to TRUE if interrupts > - are enabled and FALSE if interrupts are disabled. > - @param InterruptHandler A pointer to a function of type > EFI_CPU_INTERRUPT_HANDLER that is called > - when a processor interrupt occurs. If this > parameter is NULL, then the handler > - will be uninstalled. > - > - @retval EFI_SUCCESS The handler for the processor interrupt was > successfully installed or uninstalled. > - @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler > for InterruptType was > - previously installed. > - @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for > InterruptType was not > - previously installed. > - @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is > not supported. > - > -**/ > -EFI_STATUS > -RegisterInterruptHandler ( > - IN EFI_EXCEPTION_TYPE InterruptType, > - IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > - ) > -{ > - if (InterruptType > MAX_AARCH64_EXCEPTION) { > - return EFI_UNSUPPORTED; > - } > - > - if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != > NULL)) { > - return EFI_ALREADY_STARTED; > - } > - > - gExceptionHandlers[InterruptType] = InterruptHandler; > - > - return EFI_SUCCESS; > -} > - > - > - > -VOID > -EFIAPI > -CommonCExceptionHandler ( > - IN EFI_EXCEPTION_TYPE ExceptionType, > - IN OUT EFI_SYSTEM_CONTEXT SystemContext > - ) > -{ > - if (ExceptionType <= MAX_AARCH64_EXCEPTION) { > - if (gExceptionHandlers[ExceptionType]) { > - gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext); > - return; > - } > - } else { > - DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %016lx\n", > ExceptionType, SystemContext.SystemContextAArch64->ELR)); > - ASSERT (FALSE); > - } > - > - DefaultExceptionHandler (ExceptionType, SystemContext); > -} > - > - > - > -EFI_STATUS > -InitializeExceptions ( > - IN EFI_CPU_ARCH_PROTOCOL *Cpu > - ) > -{ > - EFI_STATUS Status; > - BOOLEAN IrqEnabled; > - BOOLEAN FiqEnabled; > - > - Status = EFI_SUCCESS; > - ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers)); > - > - // > - // Disable interrupts > - // > - Cpu->GetInterruptState (Cpu, &IrqEnabled); > - Cpu->DisableInterrupt (Cpu); > - > - // > - // EFI does not use the FIQ, but a debugger might so we must disable > - // as we take over the exception vectors. > - // > - FiqEnabled = ArmGetFiqState (); > - ArmDisableFiq (); > - > - // The AArch64 Vector table must be 2k-byte aligned - if this assertion > fails ensure 'Align=4K' > - // is defined into your FDF for this module. > - ASSERT (((UINTN)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) == 0); > - > - // We do not copy the Exception Table at > PcdGet32(PcdCpuVectorBaseAddress). We just set Vector > - // Base Address to point into CpuDxe code. > - ArmWriteVBar ((UINTN)ExceptionHandlersStart); > - > - if (FiqEnabled) { > - ArmEnableFiq (); > - } > - > - if (IrqEnabled) { > - // > - // Restore interrupt state > - // > - Status = Cpu->EnableInterrupt (Cpu); > - } > - > - return Status; > -} > diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S > b/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S > deleted file mode 100644 > index edf9973..0000000 > --- a/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S > +++ /dev/null > @@ -1,402 +0,0 @@ > -// > -// Copyright (c) 2011 - 2014 ARM LTD. All rights reserved.<BR> > -// Portion of Copyright (c) 2014 NVIDIA Corporation. All rights reserved.<BR> > -// > -// 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. > -// > -//------------------------------------------------------------------------------ > - > -#include <Chipset/AArch64.h> > -#include <Library/PcdLib.h> > -#include <AsmMacroIoLibV8.h> > - > -/* > - This is the stack constructed by the exception handler (low address to > high address). > - X0 to FAR makes up the EFI_SYSTEM_CONTEXT for AArch64. > - > - UINT64 X0; 0x000 > - UINT64 X1; 0x008 > - UINT64 X2; 0x010 > - UINT64 X3; 0x018 > - UINT64 X4; 0x020 > - UINT64 X5; 0x028 > - UINT64 X6; 0x030 > - UINT64 X7; 0x038 > - UINT64 X8; 0x040 > - UINT64 X9; 0x048 > - UINT64 X10; 0x050 > - UINT64 X11; 0x058 > - UINT64 X12; 0x060 > - UINT64 X13; 0x068 > - UINT64 X14; 0x070 > - UINT64 X15; 0x078 > - UINT64 X16; 0x080 > - UINT64 X17; 0x088 > - UINT64 X18; 0x090 > - UINT64 X19; 0x098 > - UINT64 X20; 0x0a0 > - UINT64 X21; 0x0a8 > - UINT64 X22; 0x0b0 > - UINT64 X23; 0x0b8 > - UINT64 X24; 0x0c0 > - UINT64 X25; 0x0c8 > - UINT64 X26; 0x0d0 > - UINT64 X27; 0x0d8 > - UINT64 X28; 0x0e0 > - UINT64 FP; 0x0e8 // x29 - Frame Pointer > - UINT64 LR; 0x0f0 // x30 - Link Register > - UINT64 SP; 0x0f8 // x31 - Stack Pointer > - > - // FP/SIMD Registers. 128bit if used as Q-regs. > - UINT64 V0[2]; 0x100 > - UINT64 V1[2]; 0x110 > - UINT64 V2[2]; 0x120 > - UINT64 V3[2]; 0x130 > - UINT64 V4[2]; 0x140 > - UINT64 V5[2]; 0x150 > - UINT64 V6[2]; 0x160 > - UINT64 V7[2]; 0x170 > - UINT64 V8[2]; 0x180 > - UINT64 V9[2]; 0x190 > - UINT64 V10[2]; 0x1a0 > - UINT64 V11[2]; 0x1b0 > - UINT64 V12[2]; 0x1c0 > - UINT64 V13[2]; 0x1d0 > - UINT64 V14[2]; 0x1e0 > - UINT64 V15[2]; 0x1f0 > - UINT64 V16[2]; 0x200 > - UINT64 V17[2]; 0x210 > - UINT64 V18[2]; 0x220 > - UINT64 V19[2]; 0x230 > - UINT64 V20[2]; 0x240 > - UINT64 V21[2]; 0x250 > - UINT64 V22[2]; 0x260 > - UINT64 V23[2]; 0x270 > - UINT64 V24[2]; 0x280 > - UINT64 V25[2]; 0x290 > - UINT64 V26[2]; 0x2a0 > - UINT64 V27[2]; 0x2b0 > - UINT64 V28[2]; 0x2c0 > - UINT64 V29[2]; 0x2d0 > - UINT64 V30[2]; 0x2e0 > - UINT64 V31[2]; 0x2f0 > - > - // System Context > - UINT64 ELR; 0x300 // Exception Link Register > - UINT64 SPSR; 0x308 // Saved Processor Status Register > - UINT64 FPSR; 0x310 // Floating Point Status Register > - UINT64 ESR; 0x318 // Exception syndrome register > - UINT64 FAR; 0x320 // Fault Address Register > - UINT64 Padding;0x328 // Required for stack alignment > -*/ > - > -GCC_ASM_EXPORT(ExceptionHandlersEnd) > -GCC_ASM_EXPORT(CommonExceptionEntry) > -GCC_ASM_EXPORT(AsmCommonExceptionEntry) > -GCC_ASM_EXPORT(CommonCExceptionHandler) > - > -.text > - > -#define GP_CONTEXT_SIZE (32 * 8) > -#define FP_CONTEXT_SIZE (32 * 16) > -#define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement > (ie: the stack must be aligned on 0x10) > - > -// Cannot str x31 directly > -#define ALL_GP_REGS \ > - REG_PAIR (x0, x1, 0x000, GP_CONTEXT_SIZE); \ > - REG_PAIR (x2, x3, 0x010, GP_CONTEXT_SIZE); \ > - REG_PAIR (x4, x5, 0x020, GP_CONTEXT_SIZE); \ > - REG_PAIR (x6, x7, 0x030, GP_CONTEXT_SIZE); \ > - REG_PAIR (x8, x9, 0x040, GP_CONTEXT_SIZE); \ > - REG_PAIR (x10, x11, 0x050, GP_CONTEXT_SIZE); \ > - REG_PAIR (x12, x13, 0x060, GP_CONTEXT_SIZE); \ > - REG_PAIR (x14, x15, 0x070, GP_CONTEXT_SIZE); \ > - REG_PAIR (x16, x17, 0x080, GP_CONTEXT_SIZE); \ > - REG_PAIR (x18, x19, 0x090, GP_CONTEXT_SIZE); \ > - REG_PAIR (x20, x21, 0x0a0, GP_CONTEXT_SIZE); \ > - REG_PAIR (x22, x23, 0x0b0, GP_CONTEXT_SIZE); \ > - REG_PAIR (x24, x25, 0x0c0, GP_CONTEXT_SIZE); \ > - REG_PAIR (x26, x27, 0x0d0, GP_CONTEXT_SIZE); \ > - REG_PAIR (x28, x29, 0x0e0, GP_CONTEXT_SIZE); \ > - REG_ONE (x30, 0x0f0, GP_CONTEXT_SIZE); > - > -// In order to save the SP we need to put it somewhere else first. > -// STR only works with XZR/WZR directly > -#define SAVE_SP \ > - add x1, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE); \ > - REG_ONE (x1, 0x0f8, GP_CONTEXT_SIZE); > - > -#define ALL_FP_REGS \ > - REG_PAIR (q0, q1, 0x000, FP_CONTEXT_SIZE); \ > - REG_PAIR (q2, q3, 0x020, FP_CONTEXT_SIZE); \ > - REG_PAIR (q4, q5, 0x040, FP_CONTEXT_SIZE); \ > - REG_PAIR (q6, q7, 0x060, FP_CONTEXT_SIZE); \ > - REG_PAIR (q8, q9, 0x080, FP_CONTEXT_SIZE); \ > - REG_PAIR (q10, q11, 0x0a0, FP_CONTEXT_SIZE); \ > - REG_PAIR (q12, q13, 0x0c0, FP_CONTEXT_SIZE); \ > - REG_PAIR (q14, q15, 0x0e0, FP_CONTEXT_SIZE); \ > - REG_PAIR (q16, q17, 0x100, FP_CONTEXT_SIZE); \ > - REG_PAIR (q18, q19, 0x120, FP_CONTEXT_SIZE); \ > - REG_PAIR (q20, q21, 0x140, FP_CONTEXT_SIZE); \ > - REG_PAIR (q22, q23, 0x160, FP_CONTEXT_SIZE); \ > - REG_PAIR (q24, q25, 0x180, FP_CONTEXT_SIZE); \ > - REG_PAIR (q26, q27, 0x1a0, FP_CONTEXT_SIZE); \ > - REG_PAIR (q28, q29, 0x1c0, FP_CONTEXT_SIZE); \ > - REG_PAIR (q30, q31, 0x1e0, FP_CONTEXT_SIZE); > - > -#define ALL_SYS_REGS \ > - REG_PAIR (x1, x2, 0x000, SYS_CONTEXT_SIZE); \ > - REG_PAIR (x3, x4, 0x010, SYS_CONTEXT_SIZE); \ > - REG_ONE (x5, 0x020, SYS_CONTEXT_SIZE); > - > -// > -// This code gets copied to the ARM vector table > -// VectorTableStart - VectorTableEnd gets copied > -// > -VECTOR_BASE(ExceptionHandlersStart) > - > -// > -// Current EL with SP0 : 0x0 - 0x180 > -// > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SP0_SYNC) > -ASM_PFX(SynchronousExceptionSP0): > - b ASM_PFX(SynchronousExceptionEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SP0_IRQ) > -ASM_PFX(IrqSP0): > - b ASM_PFX(IrqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SP0_FIQ) > -ASM_PFX(FiqSP0): > - b ASM_PFX(FiqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SP0_SERR) > -ASM_PFX(SErrorSP0): > - b ASM_PFX(SErrorEntry) > - > -// > -// Current EL with SPx: 0x200 - 0x380 > -// > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_SYNC) > -ASM_PFX(SynchronousExceptionSPx): > - b ASM_PFX(SynchronousExceptionEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_IRQ) > -ASM_PFX(IrqSPx): > - b ASM_PFX(IrqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_FIQ) > -ASM_PFX(FiqSPx): > - b ASM_PFX(FiqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_SERR) > -ASM_PFX(SErrorSPx): > - b ASM_PFX(SErrorEntry) > - > -// > -// Lower EL using AArch64 : 0x400 - 0x580 > -// > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A64_SYNC) > -ASM_PFX(SynchronousExceptionA64): > - b ASM_PFX(SynchronousExceptionEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A64_IRQ) > -ASM_PFX(IrqA64): > - b ASM_PFX(IrqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A64_FIQ) > -ASM_PFX(FiqA64): > - b ASM_PFX(FiqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A64_SERR) > -ASM_PFX(SErrorA64): > - b ASM_PFX(SErrorEntry) > - > -// > -// Lower EL using AArch32 : 0x600 - 0x780 > -// > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A32_SYNC) > -ASM_PFX(SynchronousExceptionA32): > - b ASM_PFX(SynchronousExceptionEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A32_IRQ) > -ASM_PFX(IrqA32): > - b ASM_PFX(IrqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A32_FIQ) > -ASM_PFX(FiqA32): > - b ASM_PFX(FiqEntry) > - > -VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_LOW_A32_SERR) > -ASM_PFX(SErrorA32): > - b ASM_PFX(SErrorEntry) > - > -VECTOR_END(ExceptionHandlersStart) > - > -#undef REG_PAIR > -#undef REG_ONE > -#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE) stp REG1, REG2, [sp, > #(OFFSET-CONTEXT_SIZE)] > -#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE) stur REG1, [sp, > #(OFFSET-CONTEXT_SIZE)] > - > -ASM_PFX(SynchronousExceptionEntry): > - // Move the stackpointer so we can reach our structure with the str > instruction. > - sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - > - // Save all the General regs before touching x0 and x1. > - // This does not save r31(SP) as it is special. We do that later. > - ALL_GP_REGS > - > - // Record the type of exception that occurred. > - mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS > - > - // Jump to our general handler to deal with all the common parts and > process the exception. > - ldr x1, ASM_PFX(CommonExceptionEntry) > - br x1 > - > -ASM_PFX(IrqEntry): > - sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - ALL_GP_REGS > - mov x0, #EXCEPT_AARCH64_IRQ > - ldr x1, ASM_PFX(CommonExceptionEntry) > - br x1 > - > -ASM_PFX(FiqEntry): > - sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - ALL_GP_REGS > - mov x0, #EXCEPT_AARCH64_FIQ > - ldr x1, ASM_PFX(CommonExceptionEntry) > - br x1 > - > -ASM_PFX(SErrorEntry): > - sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - ALL_GP_REGS > - mov x0, #EXCEPT_AARCH64_SERROR > - ldr x1, ASM_PFX(CommonExceptionEntry) > - br x1 > - > - > -// > -// This gets patched by the C code that patches in the vector table > -// > -.align 3 > -ASM_PFX(CommonExceptionEntry): > - .8byte ASM_PFX(AsmCommonExceptionEntry) > - > -ASM_PFX(ExceptionHandlersEnd): > - > - > - > -// > -// This code runs from CpuDxe driver loaded address. It is patched into > -// CommonExceptionEntry. > -// > -ASM_PFX(AsmCommonExceptionEntry): > - /* NOTE: > - We have to break up the save code because the immediate value to be used > - with the SP is too big to do it all in one step so we need to shuffle > the SP > - along as we go. (we only have 9bits of immediate to work with) */ > - > - // Save the current Stack pointer before we start modifying it. > - SAVE_SP > - > - // Preserve the stack pointer we came in with before we modify it > - EL1_OR_EL2(x1) > -1:mrs x1, elr_el1 // Exception Link Register > - mrs x2, spsr_el1 // Saved Processor Status Register 32bit > - mrs x3, fpsr // Floating point Status Register 32bit > - mrs x4, esr_el1 // EL1 Exception syndrome register 32bit > - mrs x5, far_el1 // EL1 Fault Address Register > - b 3f > - > -2:mrs x1, elr_el2 // Exception Link Register > - mrs x2, spsr_el2 // Saved Processor Status Register 32bit > - mrs x3, fpsr // Floating point Status Register 32bit > - mrs x4, esr_el2 // EL2 Exception syndrome register 32bit > - mrs x5, far_el2 // EL2 Fault Address Register > - > - // Adjust SP to save next set > -3:add sp, sp, #FP_CONTEXT_SIZE > - > - // Push FP regs to Stack. > - ALL_FP_REGS > - > - // Adjust SP to save next set > - add sp, sp, #SYS_CONTEXT_SIZE > - > - // Save the SYS regs > - ALL_SYS_REGS > - > - // Point to top of struct after all regs saved > - sub sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - > - // x0 still holds the exception type. > - // Set x1 to point to the top of our struct on the Stack > - mov x1, sp > - > -// CommonCExceptionHandler ( > -// IN EFI_EXCEPTION_TYPE ExceptionType, R0 > -// IN OUT EFI_SYSTEM_CONTEXT SystemContext R1 > -// ) > - > - // Call the handler as defined above > - > - // For now we spin in the handler if we received an abort of some kind. > - // We do not try to recover. > - bl ASM_PFX(CommonCExceptionHandler) // Call exception handler > - > - > -// Defines for popping from stack > - > -#undef REG_PAIR > -#undef REG_ONE > -#define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE) ldp REG1, REG2, [sp, > #(OFFSET-CONTEXT_SIZE)] > -#define REG_ONE(REG1, OFFSET, CONTEXT_SIZE) ldur REG1, [sp, > #(OFFSET-CONTEXT_SIZE)] > - > - // > - // Disable interrupt(IRQ and FIQ) before restoring context, > - // or else the context will be corrupted by interrupt reentrance. > - // Interrupt mask will be restored from spsr by hardware when we call eret > - // > - msr daifset, #3 > - isb > - > - // Adjust SP to pop system registers > - add sp, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - ALL_SYS_REGS > - > - EL1_OR_EL2(x6) > -1:msr elr_el1, x1 // Exception Link Register > - msr spsr_el1,x2 // Saved Processor Status Register 32bit > - msr fpsr, x3 // Floating point Status Register 32bit > - msr esr_el1, x4 // EL1 Exception syndrome register 32bit > - msr far_el1, x5 // EL1 Fault Address Register > - b 3f > -2:msr elr_el2, x1 // Exception Link Register > - msr spsr_el2,x2 // Saved Processor Status Register 32bit > - msr fpsr, x3 // Floating point Status Register 32bit > - msr esr_el2, x4 // EL2 Exception syndrome register 32bit > - msr far_el2, x5 // EL2 Fault Address Register > - > -3:// pop all regs and return from exception. > - sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) > - ALL_GP_REGS > - > - // Adjust SP to pop next set > - add sp, sp, #FP_CONTEXT_SIZE > - // Pop FP regs to Stack. > - ALL_FP_REGS > - > - // Adjust SP to be where we started from when we came into the handler. > - // The handler can not change the SP. > - add sp, sp, #SYS_CONTEXT_SIZE > - > - eret > - > -#undef REG_PAIR > -#undef REG_ONE > diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Exception.c > b/ArmPkg/Drivers/CpuDxe/Arm/Exception.c > deleted file mode 100644 > index 4b05199..0000000 > --- a/ArmPkg/Drivers/CpuDxe/Arm/Exception.c > +++ /dev/null > @@ -1,234 +0,0 @@ > -/** @file > - > - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> > - Copyright (c) 2014, ARM Limited. All rights reserved.<BR> > - > - 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. > - > -**/ > - > -#include "CpuDxe.h" > - > -//FIXME: Will not compile on non-ARMv7 builds > -#include <Chipset/ArmV7.h> > - > -VOID > -ExceptionHandlersStart ( > - VOID > - ); > - > -VOID > -ExceptionHandlersEnd ( > - VOID > - ); > - > -VOID > -CommonExceptionEntry ( > - VOID > - ); > - > -VOID > -AsmCommonExceptionEntry ( > - VOID > - ); > - > - > -EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_ARM_EXCEPTION + 1]; > -EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_ARM_EXCEPTION + 1]; > - > - > - > -/** > - This function registers and enables the handler specified by > InterruptHandler for a processor > - interrupt or exception type specified by InterruptType. If > InterruptHandler is NULL, then the > - handler for the processor interrupt or exception type specified by > InterruptType is uninstalled. > - The installed handler is called once for each processor interrupt or > exception. > - > - @param InterruptType A pointer to the processor's current interrupt > state. Set to TRUE if interrupts > - are enabled and FALSE if interrupts are disabled. > - @param InterruptHandler A pointer to a function of type > EFI_CPU_INTERRUPT_HANDLER that is called > - when a processor interrupt occurs. If this > parameter is NULL, then the handler > - will be uninstalled. > - > - @retval EFI_SUCCESS The handler for the processor interrupt was > successfully installed or uninstalled. > - @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler > for InterruptType was > - previously installed. > - @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for > InterruptType was not > - previously installed. > - @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is > not supported. > - > -**/ > -EFI_STATUS > -RegisterInterruptHandler ( > - IN EFI_EXCEPTION_TYPE InterruptType, > - IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > - ) > -{ > - if (InterruptType > MAX_ARM_EXCEPTION) { > - return EFI_UNSUPPORTED; > - } > - > - if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != > NULL)) { > - return EFI_ALREADY_STARTED; > - } > - > - gExceptionHandlers[InterruptType] = InterruptHandler; > - > - return EFI_SUCCESS; > -} > - > - > - > - > -VOID > -EFIAPI > -CommonCExceptionHandler ( > - IN EFI_EXCEPTION_TYPE ExceptionType, > - IN OUT EFI_SYSTEM_CONTEXT SystemContext > - ) > -{ > - if (ExceptionType <= MAX_ARM_EXCEPTION) { > - if (gExceptionHandlers[ExceptionType]) { > - gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext); > - return; > - } > - } else { > - DEBUG ((EFI_D_ERROR, "Unknown exception type %d from %08x\n", > ExceptionType, SystemContext.SystemContextArm->PC)); > - ASSERT (FALSE); > - } > - > - if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) { > - // > - // ARM JTAG debuggers some times use this vector, so it is not an error > to get one > - // > - return; > - } > - > - DefaultExceptionHandler (ExceptionType, SystemContext); > -} > - > - > - > -EFI_STATUS > -InitializeExceptions ( > - IN EFI_CPU_ARCH_PROTOCOL *Cpu > - ) > -{ > - EFI_STATUS Status; > - UINTN Offset; > - UINTN Length; > - UINTN Index; > - BOOLEAN IrqEnabled; > - BOOLEAN FiqEnabled; > - EFI_PHYSICAL_ADDRESS Base; > - UINT32 *VectorBase; > - > - Status = EFI_SUCCESS; > - ZeroMem (gExceptionHandlers,sizeof(*gExceptionHandlers)); > - > - // > - // Disable interrupts > - // > - Cpu->GetInterruptState (Cpu, &IrqEnabled); > - Cpu->DisableInterrupt (Cpu); > - > - // > - // EFI does not use the FIQ, but a debugger might so we must disable > - // as we take over the exception vectors. > - // > - FiqEnabled = ArmGetFiqState (); > - ArmDisableFiq (); > - > - if (FeaturePcdGet(PcdRelocateVectorTable) == TRUE) { > - // > - // Copy an implementation of the ARM exception vectors to > PcdCpuVectorBaseAddress. > - // > - Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart; > - > - // Check if the exception vector is in the low address > - if (PcdGet32 (PcdCpuVectorBaseAddress) == 0x0) { > - // Set SCTLR.V to 0 to enable VBAR to be used > - ArmSetLowVectors (); > - } else { > - ArmSetHighVectors (); > - } > - > - // > - // Reserve space for the exception handlers > - // > - Base = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdCpuVectorBaseAddress); > - VectorBase = (UINT32 *)(UINTN)Base; > - Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, > EFI_SIZE_TO_PAGES (Length), &Base); > - // If the request was for memory that's not in the memory map (which is > often the case for 0x00000000 > - // on embedded systems, for example, we don't want to hang up. So we'll > check here for a status of > - // EFI_NOT_FOUND, and continue in that case. > - if (EFI_ERROR(Status) && (Status != EFI_NOT_FOUND)) { > - ASSERT_EFI_ERROR (Status); > - } > - > - if (FeaturePcdGet(PcdDebuggerExceptionSupport) == TRUE) { > - // Save existing vector table, in case debugger is already hooked in > - CopyMem ((VOID *)gDebuggerExceptionHandlers, (VOID *)VectorBase, > sizeof (gDebuggerExceptionHandlers)); > - } > - > - // Copy our assembly code into the page that contains the exception > vectors. > - CopyMem ((VOID *)VectorBase, (VOID *)ExceptionHandlersStart, Length); > - > - // > - // Patch in the common Assembly exception handler > - // > - Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart; > - *(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) > = (UINTN)AsmCommonExceptionEntry; > - > - // > - // Initialize the C entry points for interrupts > - // > - for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) { > - if (!FeaturePcdGet(PcdDebuggerExceptionSupport) || > - (gDebuggerExceptionHandlers[Index] == 0) || > (gDebuggerExceptionHandlers[Index] == (VOID *)(UINTN)0xEAFFFFFE)) { > - // Exception handler contains branch to vector location (jmp $) so > no handler > - // NOTE: This code assumes vectors are ARM and not Thumb code > - Status = RegisterInterruptHandler (Index, NULL); > - ASSERT_EFI_ERROR (Status); > - } else { > - // If the debugger has already hooked put its vector back > - VectorBase[Index] = (UINT32)(UINTN)gDebuggerExceptionHandlers[Index]; > - } > - } > - > - // Flush Caches since we updated executable stuff > - InvalidateInstructionCacheRange ((VOID > *)PcdGet32(PcdCpuVectorBaseAddress), Length); > - > - //Note: On ARM processor with the Security Extension, the Vector Table > can be located anywhere in the memory. > - // The Vector Base Address Register defines the location > - ArmWriteVBar (PcdGet32(PcdCpuVectorBaseAddress)); > - } else { > - // The Vector table must be 32-byte aligned > - if (((UINT32)ExceptionHandlersStart & ARM_VECTOR_TABLE_ALIGNMENT) != 0) { > - ASSERT (0); > - return EFI_INVALID_PARAMETER; > - } > - > - // We do not copy the Exception Table at > PcdGet32(PcdCpuVectorBaseAddress). We just set Vector Base Address to point > into CpuDxe code. > - ArmWriteVBar ((UINT32)ExceptionHandlersStart); > - } > - > - if (FiqEnabled) { > - ArmEnableFiq (); > - } > - > - if (IrqEnabled) { > - // > - // Restore interrupt state > - // > - Status = Cpu->EnableInterrupt (Cpu); > - } > - > - return Status; > -} > diff --git a/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.S > b/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.S > deleted file mode 100644 > index 673b931..0000000 > --- a/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.S > +++ /dev/null > @@ -1,304 +0,0 @@ > -#------------------------------------------------------------------------------ > -# > -# Use ARMv6 instruction to operate on a single stack > -# > -# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> > -# Copyright (c) 2014, ARM Limited. All rights reserved.<BR> > -# > -# 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. > -# > -#------------------------------------------------------------------------------ > - > -#include <Library/PcdLib.h> > - > -/* > - > -This is the stack constructed by the exception handler (low address to high > address) > - # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM > - Reg Offset > - === ====== > - 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 subtraction 0x20 (32) from 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 > - > - */ > - > - > -GCC_ASM_EXPORT(ExceptionHandlersStart) > -GCC_ASM_EXPORT(ExceptionHandlersEnd) > -GCC_ASM_EXPORT(CommonExceptionEntry) > -GCC_ASM_EXPORT(AsmCommonExceptionEntry) > -GCC_ASM_EXPORT(CommonCExceptionHandler) > - > -.text > -.syntax unified > -#if !defined(__APPLE__) > -.fpu neon @ makes vpush/vpop assemble > -#endif > -.align 5 > - > - > -// > -// This code gets copied to the ARM vector table > -// ExceptionHandlersStart - ExceptionHandlersEnd gets copied > -// > -ASM_PFX(ExceptionHandlersStart): > - > -ASM_PFX(Reset): > - b ASM_PFX(ResetEntry) > - > -ASM_PFX(UndefinedInstruction): > - b ASM_PFX(UndefinedInstructionEntry) > - > -ASM_PFX(SoftwareInterrupt): > - b ASM_PFX(SoftwareInterruptEntry) > - > -ASM_PFX(PrefetchAbort): > - b ASM_PFX(PrefetchAbortEntry) > - > -ASM_PFX(DataAbort): > - b ASM_PFX(DataAbortEntry) > - > -ASM_PFX(ReservedException): > - b ASM_PFX(ReservedExceptionEntry) > - > -ASM_PFX(Irq): > - b ASM_PFX(IrqEntry) > - > -ASM_PFX(Fiq): > - b ASM_PFX(FiqEntry) > - > -ASM_PFX(ResetEntry): > - srsdb #0x13! @ Store return state on SVC stack > - @ We are already in SVC mode > - > - 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 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(UndefinedInstructionEntry): > - sub LR, LR, #4 @ Only -2 for Thumb, adjust in > CommonExceptionEntry > - srsdb #0x13! @ Store return state on SVC stack > - cps #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 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(SoftwareInterruptEntry): > - srsdb #0x13! @ Store return state on SVC stack > - @ We are already in SVC mode > - 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 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(PrefetchAbortEntry): > - sub LR,LR,#4 > - srsdb #0x13! @ Store return state on SVC stack > - cps #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 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(DataAbortEntry): > - sub LR,LR,#8 > - srsdb #0x13! @ Store return state on SVC stack > - cps #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,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(ReservedExceptionEntry): > - srsdb #0x13! @ Store return state on SVC stack > - cps #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,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(IrqEntry): > - sub LR,LR,#4 > - srsdb #0x13! @ Store return state on SVC stack > - cps #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 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -ASM_PFX(FiqEntry): > - sub LR,LR,#4 > - srsdb #0x13! @ Store return state on SVC stack > - cps #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 > - @ Since we have already switch to SVC > R8_fiq - R12_fiq > - @ never get used or saved > - mov R0,#7 @ ExceptionType > - ldr R1,ASM_PFX(CommonExceptionEntry) > - bx R1 > - > -// > -// This gets patched by the C code that patches in the vector table > -// > -ASM_PFX(CommonExceptionEntry): > - .word ASM_PFX(AsmCommonExceptionEntry) > - > -ASM_PFX(ExceptionHandlersEnd): > - > -// > -// This code runs from CpuDxe driver loaded address. It is patched into > -// CommonExceptionEntry. > -// > -ASM_PFX(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] @ srsdb saved pre-exception CPSR on the > stack > - str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR > - > - add R2, SP, #0x38 @ Make R2 point to > EFI_SYSTEM_CONTEXT_ARM.LR > - and R3, R1, #0x1f @ Check CPSR to see if User or System > Mode > - cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) > - cmpne R3, #0x10 @ > - stmdaeq R2, {lr}^ @ save unbanked lr > - @ else > - stmdane R2, {lr} @ save SVC lr > - > - > - ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd > - @ Check to see if we have to adjust for > Thumb entry > - sub r4, r0, #1 @ if (ExceptionType == 1 || > ExceptionType == 2)) { > - cmp r4, #1 @ // UND & SVC have differnt LR adjust > for Thumb > - bhi NoAdjustNeeded > - > - tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb > Mode on entry > - addne R5, R5, #2 @ PC += 2; > - strne R5,[SP,#0x58] @ Update LR value pushed by srsfd > - > -NoAdjustNeeded: > - > - str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC > - > - add R1, SP, #0x60 @ We pushed 0x60 bytes on the stack > - str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP > - > - @ R0 is ExceptionType > - mov R1,SP @ R1 is SystemContext > - > -#if (FixedPcdGet32(PcdVFPEnabled)) > - vpush {d0-d15} @ save vstm registers in case they are > used in optimizations > -#endif > - > - mov R4, SP @ Save current SP > - tst R4, #4 > - subne SP, SP, #4 @ Adjust SP if not 8-byte aligned > - > -/* > -VOID > -EFIAPI > -CommonCExceptionHandler ( > - IN EFI_EXCEPTION_TYPE ExceptionType, R0 > - IN OUT EFI_SYSTEM_CONTEXT SystemContext R1 > - ) > - > -*/ > - blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler > - > - mov SP, R4 @ Restore SP > - > -#if (FixedPcdGet32(PcdVFPEnabled)) > - vpop {d0-d15} > -#endif > - > - ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR > - mcr p15, 0, R1, c5, c0, 1 @ Write IFSR > - > - ldr R1, [SP, #0x44] @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR > - mcr p15, 0, R1, c5, c0, 0 @ Write DFSR > - > - ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC > - str R1,[SP,#0x58] @ Store it back to srsfd stack slot so > it can be restored > - > - ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR > - str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so > it can be restored > - > - add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry > - add R2, SP, #0x38 @ Make R2 point to > EFI_SYSTEM_CONTEXT_ARM.LR > - and R1, R1, #0x1f @ Check to see if User or System Mode > - cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) > - cmpne R1, #0x10 @ > - ldmibeq R2, {lr}^ @ restore unbanked lr > - @ else > - ldmibne R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR} > - > - ldmfd SP!,{R0-R12} @ Restore general purpose registers > - @ Exception handler can not change SP > - > - 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 > - > diff --git a/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.asm > b/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.asm > deleted file mode 100644 > index b28ff9f..0000000 > --- a/ArmPkg/Drivers/CpuDxe/Arm/ExceptionSupport.asm > +++ /dev/null > @@ -1,301 +0,0 @@ > -//------------------------------------------------------------------------------ > -// > -// Use ARMv6 instruction to operate on a single stack > -// > -// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> > -// Copyright (c) 2014, ARM Limited. All rights reserved.<BR> > -// > -// 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. > -// > -//------------------------------------------------------------------------------ > - > -#include <Library/PcdLib.h> > - > -/* > - > -This is the stack constructed by the exception handler (low address to high > address) > - # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM > - Reg Offset > - === ====== > - 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 subtraction 0x20 (32) from 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 > - > - */ > - > - > - EXPORT ExceptionHandlersStart > - EXPORT ExceptionHandlersEnd > - EXPORT CommonExceptionEntry > - EXPORT AsmCommonExceptionEntry > - IMPORT CommonCExceptionHandler > - > - PRESERVE8 > - AREA DxeExceptionHandlers, CODE, READONLY, CODEALIGN, ALIGN=5 > - > -// > -// This code gets copied to the ARM vector table > -// ExceptionHandlersStart - ExceptionHandlersEnd gets copied > -// > -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 > - ; We are already in SVC mode > - 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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -UndefinedInstructionEntry > - sub LR, LR, #4 ; Only -2 for Thumb, adjust in > CommonExceptionEntry > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 ; ExceptionType > - ldr R1,CommonExceptionEntry; > - bx R1 > - > -SoftwareInterruptEntry > - srsfd #0x13! ; Store return state on SVC stack > - ; We are already in SVC mode > - 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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -PrefetchAbortEntry > - sub LR,LR,#4 > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -DataAbortEntry > - sub LR,LR,#8 > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -ReservedExceptionEntry > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -IrqEntry > - sub LR,LR,#4 > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -FiqEntry > - sub LR,LR,#4 > - srsfd #0x13! ; Store return state on SVC stack > - cps #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 > - ; Since we have already switch to SVC > R8_fiq - R12_fiq > - ; never get used or saved > - mov R0,#7 ; ExceptionType > - ldr R1,CommonExceptionEntry > - bx R1 > - > -// > -// This gets patched by the C code that patches in the vector table > -// > -CommonExceptionEntry > - dcd AsmCommonExceptionEntry > - > -ExceptionHandlersEnd > - > -// > -// This code runs from CpuDxe driver loaded address. It is patched into > -// CommonExceptionEntry. > -// > -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 > - > - add R2, SP, #0x38 ; Make R2 point to > EFI_SYSTEM_CONTEXT_ARM.LR > - and R3, R1, #0x1f ; Check CPSR to see if User or System > Mode > - cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f)) > - cmpne R3, #0x10 ; > - stmeqed R2, {lr}^ ; save unbanked lr > - ; else > - stmneed R2, {lr} ; save SVC lr > - > - > - ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd > - ; Check to see if we have to adjust for > Thumb entry > - sub r4, r0, #1 ; if (ExceptionType == 1 || > ExceptionType == 2)) { > - cmp r4, #1 ; // UND & SVC have differnt LR adjust > for Thumb > - bhi NoAdjustNeeded > - > - tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb > Mode on entry > - addne R5, R5, #2 ; PC += 2; > - strne R5,[SP,#0x58] ; Update LR value pushed by srsfd > - > -NoAdjustNeeded > - > - str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC > - > - add R1, SP, #0x60 ; We pushed 0x60 bytes on the stack > - str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP > - > - ; R0 is ExceptionType > - mov R1,SP ; R1 is SystemContext > - > -#if (FixedPcdGet32(PcdVFPEnabled)) > - vpush {d0-d15} ; save vstm registers in case they are > used in optimizations > -#endif > - > - mov R4, SP ; Save current SP > - tst R4, #4 > - subne SP, SP, #4 ; Adjust SP if not 8-byte aligned > - > -/* > -VOID > -EFIAPI > -CommonCExceptionHandler ( > - IN EFI_EXCEPTION_TYPE ExceptionType, R0 > - IN OUT EFI_SYSTEM_CONTEXT SystemContext R1 > - ) > - > -*/ > - blx CommonCExceptionHandler ; Call exception handler > - > - mov SP, R4 ; Restore SP > - > -#if (FixedPcdGet32(PcdVFPEnabled)) > - vpop {d0-d15} > -#endif > - > - ldr R1, [SP, #0x4c] ; Restore EFI_SYSTEM_CONTEXT_ARM.IFSR > - mcr p15, 0, R1, c5, c0, 1 ; Write IFSR > - > - ldr R1, [SP, #0x44] ; Restore EFI_SYSTEM_CONTEXT_ARM.DFSR > - mcr p15, 0, R1, c5, c0, 0 ; Write DFSR > - > - ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC > - str R1,[SP,#0x58] ; Store it back to srsfd stack slot so > it can be restored > - > - ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR > - str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so > it can be restored > - > - add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry > - add R2, SP, #0x38 ; Make R2 point to > EFI_SYSTEM_CONTEXT_ARM.LR > - and R1, R1, #0x1f ; Check to see if User or System Mode > - cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f)) > - cmpne R1, #0x10 ; > - ldmeqed R2, {lr}^ ; restore unbanked lr > - ; else > - ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR} > - > - ldmfd SP!,{R0-R12} ; Restore general purpose registers > - ; Exception handler can not change SP > - > - 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 > - > - > diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf > b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf > index 9ad242a..21cdf31 100644 > --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf > +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf > @@ -29,17 +29,13 @@ > CpuDxe.h > CpuMpCore.c > CpuMmuCommon.c > + Exception.c > > [Sources.ARM] > Arm/Mmu.c > - Arm/Exception.c > - Arm/ExceptionSupport.asm | RVCT > - Arm/ExceptionSupport.S | GCC > > [Sources.AARCH64] > AArch64/Mmu.c > - AArch64/Exception.c > - AArch64/ExceptionSupport.S > > [Packages] > ArmPkg/ArmPkg.dec > @@ -52,6 +48,7 @@ > BaseMemoryLib > CacheMaintenanceLib > CpuLib > + CpuExceptionHandlerLib > DebugLib > DefaultExceptionHandlerLib > DxeServicesTableLib > @@ -69,14 +66,13 @@ > gEfiDebugImageInfoTableGuid > gArmMpCoreInfoGuid > gIdleLoopEventGuid > + gEfiVectorHandoffTableGuid > > [Pcd.common] > gArmTokenSpaceGuid.PcdVFPEnabled > - gArmTokenSpaceGuid.PcdCpuVectorBaseAddress > > [FeaturePcd.common] > gArmTokenSpaceGuid.PcdCpuDxeProduceDebugSupport > - gArmTokenSpaceGuid.PcdRelocateVectorTable > gArmTokenSpaceGuid.PcdDebuggerExceptionSupport > > [Depex] > diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c > b/ArmPkg/Drivers/CpuDxe/Exception.c > new file mode 100644 > index 0000000..c3107cd > --- /dev/null > +++ b/ArmPkg/Drivers/CpuDxe/Exception.c > @@ -0,0 +1,95 @@ > +/** @file > + > + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> > + Portions Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR> > + > + 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. > + > +**/ > + > +#include "CpuDxe.h" > +#include <Library/CpuExceptionHandlerLib.h> > +#include <Guid/VectorHandoffTable.h> > + > +EFI_STATUS > +InitializeExceptions ( > + IN EFI_CPU_ARCH_PROTOCOL *Cpu > + ) { > + EFI_STATUS Status; > + EFI_VECTOR_HANDOFF_INFO *VectorInfoList; > + EFI_VECTOR_HANDOFF_INFO *VectorInfo; > + BOOLEAN IrqEnabled; > + BOOLEAN FiqEnabled; > + > + VectorInfo = (EFI_VECTOR_HANDOFF_INFO *)NULL; > + Status = EfiGetSystemConfigurationTable(&gEfiVectorHandoffTableGuid, (VOID > **)&VectorInfoList); > + if (Status == EFI_SUCCESS && VectorInfoList != NULL) { > + VectorInfo = VectorInfoList; > + } > + > + // intialize the CpuExceptionHandlerLib so we take over the exception > vector table from the DXE Core > + InitializeCpuExceptionHandlers(VectorInfo); > + > + Status = EFI_SUCCESS; > + > + // > + // Disable interrupts > + // > + Cpu->GetInterruptState (Cpu, &IrqEnabled); > + Cpu->DisableInterrupt (Cpu); > + > + // > + // EFI does not use the FIQ, but a debugger might so we must disable > + // as we take over the exception vectors. > + // > + FiqEnabled = ArmGetFiqState (); > + ArmDisableFiq (); > + > + if (FiqEnabled) { > + ArmEnableFiq (); > + } > + > + if (IrqEnabled) { > + // > + // Restore interrupt state > + // > + Status = Cpu->EnableInterrupt (Cpu); > + } > + > + return Status; > +} > + > +/** > +This function registers and enables the handler specified by > InterruptHandler for a processor > +interrupt or exception type specified by InterruptType. If InterruptHandler > is NULL, then the > +handler for the processor interrupt or exception type specified by > InterruptType is uninstalled. > +The installed handler is called once for each processor interrupt or > exception. > + > +@param InterruptType A pointer to the processor's current interrupt > state. Set to TRUE if interrupts > +are enabled and FALSE if interrupts are disabled. > +@param InterruptHandler A pointer to a function of type > EFI_CPU_INTERRUPT_HANDLER that is called > +when a processor interrupt occurs. If this parameter is NULL, then the > handler > +will be uninstalled. > + > +@retval EFI_SUCCESS The handler for the processor interrupt was > successfully installed or uninstalled. > +@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler > for InterruptType was > +previously installed. > +@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for > InterruptType was not > +previously installed. > +@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is > not supported. > + > +**/ > +EFI_STATUS > +RegisterInterruptHandler( > + IN EFI_EXCEPTION_TYPE InterruptType, > + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler > + ) { > + // pass down to CpuExceptionHandlerLib > + return (EFI_STATUS)RegisterCpuInterruptHandler(InterruptType, > InterruptHandler); > +} > -- > 1.9.5.msysgit.0 > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

