diff options
author | Ard Biesheuvel <ardb@kernel.org> | 2025-01-17 12:08:51 +0100 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-01-17 18:37:27 +0000 |
commit | 2d2642f4832ebc45cb7d5ba9430b933d953b94f2 (patch) | |
tree | 9843f1120620aacda591befa6159a8a9624694f6 | |
parent | 81e2cd329efc0ed240234f475426cb81bf5d9c84 (diff) | |
download | edk2-2d2642f4832ebc45cb7d5ba9430b933d953b94f2.tar.gz |
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 <ardb@kernel.org>
-rw-r--r-- | ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.h | 10 | ||||
-rw-r--r-- | ArmPkg/Drivers/ArmGicDxe/GicV3/AArch64/ArmGicV3.S | 17 | ||||
-rw-r--r-- | ArmPkg/Drivers/ArmGicDxe/GicV3/Arm/ArmGicV3.S | 16 | ||||
-rw-r--r-- | ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c | 5 | ||||
-rw-r--r-- | ArmPkg/Include/Library/ArmGicLib.h | 3 |
5 files changed, 50 insertions, 1 deletions
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
|