diff options
author | Ard Biesheuvel <ardb@kernel.org> | 2025-01-16 18:11:21 +0100 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-01-17 18:37:27 +0000 |
commit | 8edd5fd6d3dfb21fe077427029f1e705cfbcb7a1 (patch) | |
tree | 07f2e4868ff1d3f5319634cb4295e8327203c8c5 | |
parent | 84eed1ef2a84c6716582809b1d1270f5388f8f0d (diff) | |
download | edk2-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.c | 47 | ||||
-rw-r--r-- | ArmPkg/Include/Library/ArmGicLib.h | 2 |
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
|