diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 75960ed8df..ced3929801 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -69,6 +69,9 @@ # Linux (instead of PSCI) gArmTokenSpaceGuid.PcdArmLinuxSpinTable|FALSE|BOOLEAN|0x00000033 + # Define if the GICv3 controller should use the GICv2 legacy + gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042 + [PcdsFixedAtBuild.common] gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006 diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf index 92f3b1d312..e554301c4b 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf +++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf @@ -1,7 +1,7 @@ #/** @file # # Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
-# Copyright (c) 2012 - 2014, ARM Ltd. All rights reserved.
+# Copyright (c) 2012 - 2015, ARM Ltd. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -54,6 +54,7 @@ gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicRedistributorsBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy [Depex] gEfiCpuArchProtocolGuid diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 7c53e39793..48708e3812 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -186,7 +186,7 @@ ArmGicEnableInterrupt ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if (Revision == ARM_GIC_ARCH_REVISION_2) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { // Write set-enable register MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift); } else { @@ -219,7 +219,7 @@ ArmGicDisableInterrupt ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if (Revision == ARM_GIC_ARCH_REVISION_2) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { // Write clear-enable register MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift); } else { @@ -252,7 +252,7 @@ ArmGicIsInterruptEnabled ( RegShift = Source % 32; Revision = ArmGicGetSupportedArchRevision (); - if (Revision == ARM_GIC_ARCH_REVISION_2) { + if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0); } else { GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision); diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf index 9f466792e9..2ae3fd31e8 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.inf +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf @@ -47,3 +47,6 @@ [Pcd] gArmPlatformTokenSpaceGuid.PcdCoreCount + +[FeaturePcd] + gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy diff --git a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf index 9097b37f2b..7d4e49e4b9 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf +++ b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf @@ -48,3 +48,6 @@ [Pcd] gArmPlatformTokenSpaceGuid.PcdCoreCount + +[FeaturePcd] + gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy diff --git a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c index e94e015e1f..f3bf1910c5 100644 --- a/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c +++ b/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c @@ -249,6 +249,14 @@ GicV3DxeInitialize ( mGicRedistributorsBase = PcdGet32 (PcdGicRedistributorsBase); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); + // + // We will be driving this GIC in native v3 mode, i.e., with Affinity + // Routing enabled. So ensure that the ARE bit is set. + // + if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) { + MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE); + } + for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index); diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h index 2ab99772d1..e2a4818c4c 100644 --- a/ArmPkg/Include/Library/ArmGicLib.h +++ b/ArmPkg/Include/Library/ArmGicLib.h @@ -53,6 +53,9 @@ typedef enum { // GICv3 specific registers #define ARM_GICD_IROUTER 0x6100 // Interrupt Routing Registers +// the Affinity Routing Enable (ARE) bit in GICD_CTLR +#define ARM_GIC_ICDDCR_ARE (1 << 4) + // // GIC Redistributor //