From 0416278cfdd3d657a828fbb977bcd736dd4962a8 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Fri, 5 Mar 2010 02:15:41 +0000 Subject: [PATCH] Added FIQ interrupt primatives. Update exception handler to disable/reenable FIQ when updating in case debug agent library is using FIQ. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10197 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Drivers/CpuDxe/Exception.c | 19 +++++++++++--- ArmPkg/Include/Library/ArmLib.h | 17 +++++++++++++ ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S | 18 +++++++++++++ ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm | 18 +++++++++++++ ArmPkg/Library/ArmLib/Common/ArmLibSupport.S | 25 +++++++++++++++++++ .../Library/ArmLib/Common/ArmLibSupport.asm | 25 +++++++++++++++++++ 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Drivers/CpuDxe/Exception.c index d99d3d1d01..f795c431a2 100644 --- a/ArmPkg/Drivers/CpuDxe/Exception.c +++ b/ArmPkg/Drivers/CpuDxe/Exception.c @@ -178,17 +178,24 @@ InitializeExceptions ( UINTN Offset; UINTN Length; UINTN Index; - BOOLEAN Enabled; + BOOLEAN IrqEnabled; + BOOLEAN FiqEnabled; EFI_PHYSICAL_ADDRESS Base; UINT32 *VectorBase; // // Disable interrupts // - Cpu->GetInterruptState (Cpu, &Enabled); + 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 (); + // // Copy an implementation of the ARM exception vectors to PcdCpuVectorBaseAddress. // @@ -236,7 +243,11 @@ InitializeExceptions ( // Flush Caches since we updated executable stuff InvalidateInstructionCacheRange ((VOID *)PcdGet32(PcdCpuVectorBaseAddress), Length); - if (Enabled) { + if (FiqEnabled) { + ArmEnableFiq (); + } + + if (IrqEnabled) { // // Restore interrupt state // diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h index d0928e7f55..e762489e2f 100644 --- a/ArmPkg/Include/Library/ArmLib.h +++ b/ArmPkg/Include/Library/ArmLib.h @@ -241,6 +241,23 @@ EFIAPI ArmGetInterruptState ( VOID ); +VOID +EFIAPI +ArmEnableFiq ( + VOID + ); + +UINTN +EFIAPI +ArmDisableFiq ( + VOID + ); + +BOOLEAN +EFIAPI +ArmGetFiqState ( + VOID + ); VOID EFIAPI diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S index fac928af36..cdfd3dc9cf 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.S @@ -19,6 +19,9 @@ .globl ASM_PFX(ArmEnableInterrupts) .globl ASM_PFX(ArmDisableInterrupts) .globl ASM_PFX(ArmGetInterruptState) +.globl ASM_PFX(ArmEnableFiq) +.globl ASM_PFX(ArmDisableFiq) +.globl ASM_PFX(ArmGetFiqState) .globl ASM_PFX(ArmInvalidateTlb) .globl ASM_PFX(ArmSetTranslationTableBaseAddress) .globl ASM_PFX(ArmGetTranslationTableBaseAddress) @@ -54,6 +57,21 @@ ASM_PFX(ArmGetInterruptState): movne R0,#0 bx LR +ASM_PFX(ArmEnableFiq): + cpsie f + bx LR + +ASM_PFX(ArmDisableFiq): + cpsid f + bx LR + +ASM_PFX(ArmGetFiqState): + mrs R0,CPSR + tst R0,#0x30 @Check if IRQ is enabled. + moveq R0,#1 + movne R0,#0 + bx LR + ASM_PFX(ArmInvalidateTlb): mov r0,#0 mcr p15,0,r0,c8,c7,0 diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm index 765db9063c..65b3683f26 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupport.asm @@ -18,6 +18,9 @@ EXPORT ArmEnableInterrupts EXPORT ArmDisableInterrupts EXPORT ArmGetInterruptState + EXPORT ArmEnableFiq + EXPORT ArmDisableFiq + EXPORT ArmGetFiqState EXPORT ArmInvalidateTlb EXPORT ArmSetTranslationTableBaseAddress EXPORT ArmGetTranslationTableBaseAddress @@ -51,6 +54,21 @@ ArmGetInterruptState moveq R0,#1 movne R0,#0 bx LR + +ArmEnableFiq + CPSIE f + bx LR + +ArmDisableFiq + CPSID f + bx LR + +ArmGetFiqState + mrs R0,CPSR + tst R0,#0x40 ;Check if IRQ is enabled. + moveq R0,#1 + movne R0,#0 + bx LR ArmInvalidateTlb mov r0,#0 diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S index 57d2734528..c644d3446e 100644 --- a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.S @@ -19,6 +19,9 @@ .globl ASM_PFX(ArmEnableInterrupts) .globl ASM_PFX(ArmDisableInterrupts) .globl ASM_PFX(ArmGetInterruptState) +.globl ASM_PFX(ArmEnableFiq) +.globl ASM_PFX(ArmDisableFiq) +.globl ASM_PFX(ArmGetFiqState) .globl ASM_PFX(ArmInvalidateTlb) .globl ASM_PFX(ArmSetTranslationTableBaseAddress) .globl ASM_PFX(ArmGetTranslationTableBaseAddress) @@ -58,6 +61,28 @@ ASM_PFX(ArmGetInterruptState): movne R0,#0 bx LR +ASM_PFX(ArmEnableFiq): + mrs R0,CPSR + bic R0,R0,#0x40 @Enable FIQ interrupts + msr CPSR_c,R0 + bx LR + +ASM_PFX(ArmDisableFiq): + mrs R0,CPSR + orr R1,R0,#0x40 @Disable FIQ interrupts + msr CPSR_c,R1 + tst R0,#0x80 + moveq R0,#1 + movne R0,#0 + bx LR + +ASM_PFX(ArmGetFiqState): + mrs R0,CPSR + tst R0,#0x80 @Check if FIQ is enabled. + moveq R0,#1 + movne R0,#0 + bx LR + ASM_PFX(ArmInvalidateTlb): mov r0,#0 mcr p15,0,r0,c8,c7,0 diff --git a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm index 630c72fdee..ca8d980b0d 100644 --- a/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm +++ b/ArmPkg/Library/ArmLib/Common/ArmLibSupport.asm @@ -18,6 +18,9 @@ EXPORT ArmEnableInterrupts EXPORT ArmDisableInterrupts EXPORT ArmGetInterruptState + EXPORT ArmEnableFiq + EXPORT ArmDisableFiq + EXPORT ArmGetFiqState EXPORT ArmInvalidateTlb EXPORT ArmSetTranslationTableBaseAddress EXPORT ArmGetTranslationTableBaseAddress @@ -56,6 +59,28 @@ ArmGetInterruptState moveq R0,#1 movne R0,#0 bx LR + +ArmEnableFiq + mrs R0,CPSR + bic R0,R0,#0x40 ;Enable IRQ interrupts + msr CPSR_c,R0 + bx LR + +ArmDisableFiq + mrs R0,CPSR + orr R1,R0,#0x40 ;Disable IRQ interrupts + msr CPSR_c,R1 + tst R0,#0x40 + moveq R0,#1 + movne R0,#0 + bx LR + +ArmGetFiqState + mrs R0,CPSR + tst R0,#0x40 ;Check if IRQ is enabled. + moveq R0,#1 + movne R0,#0 + bx LR ArmInvalidateTlb mov r0,#0 -- 2.39.2