summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2025-01-16 18:11:21 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2025-01-17 18:37:27 +0000
commit8edd5fd6d3dfb21fe077427029f1e705cfbcb7a1 (patch)
tree07f2e4868ff1d3f5319634cb4295e8327203c8c5
parent84eed1ef2a84c6716582809b1d1270f5388f8f0d (diff)
downloadedk2-8edd5fd6d3dfb21fe077427029f1e705cfbcb7a1.tar.gz
ArmPkg/ArmGic: Move GICv3 sysreg check into ArmGicDxe
ArmGicArchLib implements a check on the accessibility of the GIC system register interface, which is a prerequisite for using the GIC in v3 mode. It might be possible to use GICv2 compatibility mode on poorly configured platforms where the GIC is v3 capable but not accessible, but in most cases, the GIC is driven in its native mode. This check is now only carried out in a single place, and there is not really any reason to keep this in a separate library. Even though ArmVirtPkg implements its own version, the basic check (and enablement of the sysreg interface) is still needed. So move this check into the DXE driver itself, and drop the dependency on ArmGicArchLib. This allows it to be retired in a subsequent patch. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicDxe.c47
-rw-r--r--ArmPkg/Include/Library/ArmGicLib.h2
2 files changed, 39 insertions, 10 deletions
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
index 1b40d8f942..b0da48e3a3 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -18,6 +18,42 @@ Abstract:
#include "ArmGicDxe.h"
+STATIC
+BOOLEAN
+GicV3Supported (
+ VOID
+ )
+{
+ UINT32 IccSre;
+
+ // Ideally we would like to use the GICC IIDR Architecture version here, but
+ // this does not seem to be very reliable as the implementation could easily
+ // get it wrong. It is more reliable to check if the GICv3 System Register
+ // feature is implemented on the CPU. This is also convenient as our GICv3
+ // driver requires SRE. If only Memory mapped access is available we try to
+ // drive the GIC as a v2.
+ if (ArmHasGicSystemRegisters ()) {
+ // Make sure System Register access is enabled (SRE). This depends on the
+ // higher privilege level giving us permission, otherwise we will either
+ // cause an exception here, or the write doesn't stick in which case we need
+ // to fall back to the GICv2 MMIO interface.
+ // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
+ // at the same exception level.
+ // It is the OS responsibility to set this bit.
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ if (!(IccSre & ICC_SRE_EL2_SRE)) {
+ ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);
+ IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+ }
+
+ if (IccSre & ICC_SRE_EL2_SRE) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/**
Initialize the state information for the CPU Architectural Protocol
@@ -36,17 +72,12 @@ InterruptDxeInitialize (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- ARM_GIC_ARCH_REVISION Revision;
-
- Revision = ArmGicGetSupportedArchRevision ();
+ EFI_STATUS Status;
- if (Revision == ARM_GIC_ARCH_REVISION_2) {
+ if (!GicV3Supported ()) {
Status = GicV2DxeInitialize (ImageHandle, SystemTable);
- } else if (Revision == ARM_GIC_ARCH_REVISION_3) {
- Status = GicV3DxeInitialize (ImageHandle, SystemTable);
} else {
- Status = EFI_UNSUPPORTED;
+ Status = GicV3DxeInitialize (ImageHandle, SystemTable);
}
return Status;
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index df32f47d86..57711ed9df 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -9,8 +9,6 @@
#ifndef ARMGIC_H_
#define ARMGIC_H_
-#include <Library/ArmGicArchLib.h>
-
// GIC Distributor
#define ARM_GIC_ICDDCR 0x000 // Distributor Control Register
#define ARM_GIC_ICDICTR 0x004 // Interrupt Controller Type Register