From 2d2642f4832ebc45cb7d5ba9430b933d953b94f2 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 17 Jan 2025 12:08:51 +0100 Subject: ArmPkg/ArmGicDxe: Use EOImode 0x0 on GICv3 When re-entering EDK2 from a high level OS such as Linux, the GICv3 may be configured to use split priority drop and deactivate (EOImode == 1), whereas EDK2's GICv3 driver assumes the default setting of EOImode == 0. So clear the EOImode bit explicitly when taking control of the GIC. Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h | 10 ++++++++++ ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S | 17 +++++++++++++++++ ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S | 16 ++++++++++++++++ ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c | 5 +++++ ArmPkg/Include/Library/ArmGicLib.h | 3 ++- 5 files changed, 50 insertions(+), 1 deletion(-) (limited to 'ArmPkg') diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h index 733984265b..57732661d2 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h @@ -139,4 +139,14 @@ ArmGicV3SetPriorityMask ( IN UINTN Priority ); +UINTN +ArmGicV3GetControlRegister ( + VOID + ); + +VOID +ArmGicV3SetControlRegister ( + IN UINTN Value + ); + #endif // ARM_GIC_DXE_H_ diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S b/ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S index 504f026a1d..81aaeefa56 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S +++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S @@ -22,6 +22,7 @@ #define ICC_IAR1_EL1 S3_0_C12_C12_0 #define ICC_PMR_EL1 S3_0_C4_C6_0 #define ICC_BPR1_EL1 S3_0_C12_C12_3 +#define ICC_CTLR_EL1 S3_0_C12_C12_4 #endif @@ -99,3 +100,19 @@ ASM_FUNC(ArmGicV3SetPriorityMask) ASM_FUNC(ArmGicV3SetBinaryPointer) msr ICC_BPR1_EL1, x0 ret + +//UINTN +//ArmGicV3GetControlRegister( +// VOID +// ); +ASM_FUNC(ArmGicV3GetControlRegister) + mrs x0, ICC_CTLR_EL1 + ret + +//VOID +//ArmGicV3SetControlRegister( +// IN UINTN Value +// ); +ASM_FUNC(ArmGicV3SetControlRegister) + msr ICC_CTLR_EL1, x0 + ret diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S b/ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S index 33c0a58464..d57e17b901 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S +++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S @@ -78,3 +78,19 @@ ASM_FUNC(ArmGicV3SetPriorityMask) ASM_FUNC(ArmGicV3SetBinaryPointer) mcr p15, 0, r0, c12, c12, 3 //ICC_BPR1 bx lr + +//UINTN +//ArmGicV3GetControlRegister( +// VOID +// ); +ASM_FUNC(ArmGicV3GetControlRegister) + mrc p15, 0, r0, c12, c12, 4 //ICC_CTLR + bx lr + +//VOID +//ArmGicV3SetControlRegister( +// IN UINTN Value +// ); +ASM_FUNC(ArmGicV3SetControlRegister) + mcr p15, 0, r0, c12, c12, 4 //ICC_CTLR + bx lr diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c index 2b6c0fc9f1..d456e6cb83 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c @@ -704,6 +704,11 @@ GicV3DxeInitialize ( // Set priority mask reg to 0xff to allow all priorities through ArmGicV3SetPriorityMask (0xff); + // Use combined priority drop and deactivate (EOImode == 0) + RegValue = ArmGicV3GetControlRegister (); + RegValue &= ~(UINT64)ICC_CTLR_EOImode; + ArmGicV3SetControlRegister (RegValue); + // Enable gic cpu interface ArmGicV3EnableInterruptInterface (); diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index 02112ebf07..de49c59437 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -118,7 +118,8 @@ // GIC revision 3 specific declarations -#define ICC_SRE_EL2_SRE (1 << 0) +#define ICC_SRE_EL2_SRE (1 << 0) +#define ICC_CTLR_EOImode (1 << 1) #define ARM_GICD_IROUTER_IRM BIT31 -- cgit