diff --git a/ArmPkg/Drivers/ArmGicDxe/ArmGicCommonDxe.c b/ArmPkg/Drivers/ArmGicDxe/ArmGicCommonDxe.c index e777aee468..f40797b734 100644 --- a/ArmPkg/Drivers/ArmGicDxe/ArmGicCommonDxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/ArmGicCommonDxe.c @@ -111,10 +111,6 @@ InstallAndRegisterInterruptService ( CONST UINTN RihArraySize = (sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); - // Locate the CPU arch protocol - cannot fail because of DEPEX - Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpuArch); - ASSERT_EFI_ERROR (Status); - // Initialize the array for the Interrupt Handlers gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize); if (gRegisteredInterruptHandlers == NULL) { diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV2/ArmGicV2Dxe.c b/ArmPkg/Drivers/ArmGicDxe/GicV2/ArmGicV2Dxe.c index 258869b2c7..6dabece1da 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV2/ArmGicV2Dxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/GicV2/ArmGicV2Dxe.c @@ -22,6 +22,9 @@ Abstract: #define ARM_GIC_DEFAULT_PRIORITY 0x80 +#define GICD_V2_SIZE SIZE_4KB +#define GICC_V2_SIZE SIZE_8KB + // Interrupts from 1020 to 1023 are considered as special interrupts // (eg: spurious interrupts) #define ARM_GIC_IS_SPECIAL_INTERRUPTS(Interrupt) \ @@ -529,9 +532,28 @@ GicV2DxeInitialize ( ASSERT (PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN); ASSERT (PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN); + // Locate the CPU arch protocol - cannot fail because of DEPEX + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpuArch); + ASSERT_EFI_ERROR (Status); + mGicInterruptInterfaceBase = (UINTN)PcdGet64 (PcdGicInterruptInterfaceBase); mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase); - mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); + + Status = gCpuArch->SetMemoryAttributes (gCpuArch, mGicDistributorBase, GICD_V2_SIZE, EFI_MEMORY_UC | EFI_MEMORY_XP); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to map GICv2 distributor MMIO interface: %r\n", __func__, Status)); + ASSERT_EFI_ERROR (Status); + return Status; + } + + mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); + + Status = gCpuArch->SetMemoryAttributes (gCpuArch, mGicInterruptInterfaceBase, GICC_V2_SIZE, EFI_MEMORY_UC | EFI_MEMORY_XP); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to map GICv2 CPU MMIO interface: %r\n", __func__, Status)); + ASSERT_EFI_ERROR (Status); + return Status; + } for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c index 34fe8d295c..798b01d0d6 100644 --- a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c +++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c @@ -23,6 +23,8 @@ + ARM_GICR_SGI_VLPI_FRAME_SIZE \ + ARM_GICR_SGI_RESERVED_FRAME_SIZE) +#define GICD_V3_SIZE SIZE_64KB + #define ISENABLER_ADDRESS(base, offset) ((base) +\ ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + 4 * (offset)) @@ -62,11 +64,12 @@ GicGetCpuRedistributorBase ( IN UINTN GicRedistributorBase ) { - UINTN MpId; - UINTN CpuAffinity; - UINTN Affinity; - UINTN GicCpuRedistributorBase; - UINT64 TypeRegister; + UINTN MpId; + UINTN CpuAffinity; + UINTN Affinity; + UINTN GicCpuRedistributorBase; + UINT64 TypeRegister; + EFI_STATUS Status; MpId = ArmReadMpidr (); // Define CPU affinity as: @@ -78,6 +81,24 @@ GicGetCpuRedistributorBase ( GicCpuRedistributorBase = GicRedistributorBase; do { + Status = gCpuArch->SetMemoryAttributes ( + gCpuArch, + GicCpuRedistributorBase, + GIC_V3_REDISTRIBUTOR_GRANULARITY, + EFI_MEMORY_UC | EFI_MEMORY_XP + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to map GICv3 redistributor MMIO interface at 0x%lx: %r\n", + __func__, + GicCpuRedistributorBase, + Status + )); + ASSERT_EFI_ERROR (Status); + return 0; + } + TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER); Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister); if (Affinity == CpuAffinity) { @@ -589,7 +610,19 @@ GicV3DxeInitialize ( // the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); - mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase); + // Locate the CPU arch protocol - cannot fail because of DEPEX + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpuArch); + ASSERT_EFI_ERROR (Status); + + mGicDistributorBase = (UINTN)PcdGet64 (PcdGicDistributorBase); + + Status = gCpuArch->SetMemoryAttributes (gCpuArch, mGicDistributorBase, GICD_V3_SIZE, EFI_MEMORY_UC | EFI_MEMORY_XP); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to map GICv3 distributor MMIO interface: %r\n", __func__, Status)); + ASSERT_EFI_ERROR (Status); + return Status; + } + mGicRedistributorBase = GicGetCpuRedistributorBase (PcdGet64 (PcdGicRedistributorsBase)); mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);