From dc63be2495680e5e156caabbb76041605d628604 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 9 Sep 2014 16:00:47 +0000 Subject: [PATCH] ArmPkg: allow dynamic GIC base addresses Allow the PCDs gArmTokenSpaceGuid.PcdGicDistributorBase and gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase to be redeclared as PcdsDynamic by the platform, so virtual machines can set these properties during boot. As the PcdGet32() calls now call into the PCD database, cache the values that are required during the handling of interrupts. Contributed-under: TianoCore Contribution Agreement 1.0 Acked-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16072 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/ArmPkg.dec | 18 ++++++----- ArmPkg/Drivers/ArmGic/ArmGicDxe.inf | 3 +- ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c | 37 +++++++++++++---------- ArmPkg/Library/BdsLib/BdsLib.inf | 3 +- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index fabecc2641..ae22457b5f 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -81,13 +81,6 @@ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004 gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005 - # - # ARM Generic Interrupt Controller - # - gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C - gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D - gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025 - # # ARM Secure Firmware PCDs # @@ -216,6 +209,10 @@ gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026 +# +# These PCDs are also defined as 'PcdsDynamic' to be redefined when using UEFI in a +# context of virtual machine. +# [PcdsFixedAtBuild.common, PcdsDynamic.common] # # ARM Architectural Timer @@ -227,3 +224,10 @@ gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040 gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041 + + # + # ARM Generic Interrupt Controller + # + gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D + gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025 diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf index 68fc640adc..27303e5792 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf +++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf @@ -43,12 +43,13 @@ MemoryAllocationLib UefiDriverEntryPoint IoLib + PcdLib [Protocols] gHardwareInterruptProtocolGuid gEfiCpuArchProtocolGuid -[FixedPcd.common] +[Pcd.common] gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c index 5561de630d..3f9e37b5f2 100644 --- a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c +++ b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c @@ -29,6 +29,9 @@ Abstract: extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol; +UINT32 mGicInterruptInterfaceBase; +UINT32 mGicDistributorBase; + /** Enable interrupt source Source. @@ -51,7 +54,7 @@ GicV2EnableInterruptSource ( return EFI_UNSUPPORTED; } - ArmGicEnableInterrupt (FixedPcdGet32 (PcdGicDistributorBase), Source); + ArmGicEnableInterrupt (mGicDistributorBase, Source); return EFI_SUCCESS; } @@ -78,7 +81,7 @@ GicV2DisableInterruptSource ( return EFI_UNSUPPORTED; } - ArmGicDisableInterrupt (FixedPcdGet32 (PcdGicDistributorBase), Source); + ArmGicDisableInterrupt (mGicDistributorBase, Source); return EFI_SUCCESS; } @@ -107,7 +110,7 @@ GicV2GetInterruptSourceState ( return EFI_UNSUPPORTED; } - *InterruptState = ArmGicIsInterruptEnabled (FixedPcdGet32 (PcdGicDistributorBase), Source); + *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source); return EFI_SUCCESS; } @@ -135,7 +138,7 @@ GicV2EndOfInterrupt ( return EFI_UNSUPPORTED; } - ArmGicV2EndOfInterrupt (FixedPcdGet32 (PcdGicInterruptInterfaceBase), Source); + ArmGicV2EndOfInterrupt (mGicInterruptInterfaceBase, Source); return EFI_SUCCESS; } @@ -160,7 +163,7 @@ GicV2IrqInterruptHandler ( UINT32 GicInterrupt; HARDWARE_INTERRUPT_HANDLER InterruptHandler; - GicInterrupt = ArmGicV2AcknowledgeInterrupt (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); + GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase); // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt). if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) { @@ -216,7 +219,7 @@ GicV2ExitBootServicesEvent ( // Acknowledge all pending interrupts do { - GicInterrupt = ArmGicV2AcknowledgeInterrupt (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); + GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase); if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) { GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); @@ -224,10 +227,10 @@ GicV2ExitBootServicesEvent ( } while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt)); // Disable Gic Interface - ArmGicV2DisableInterruptInterface (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); + ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase); // Disable Gic Distributor - ArmGicDisableDistributor (FixedPcdGet32 (PcdGicDistributorBase)); + ArmGicDisableDistributor (mGicDistributorBase); } /** @@ -256,7 +259,9 @@ GicV2DxeInitialize ( // Make sure the Interrupt Controller Protocol is not already installed in the system. ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); - mGicNumInterrupts = ArmGicGetMaxNumInterrupts (FixedPcdGet32 (PcdGicDistributorBase)); + mGicInterruptInterfaceBase = PcdGet32 (PcdGicInterruptInterfaceBase); + mGicDistributorBase = PcdGet32 (PcdGicDistributorBase); + mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase); for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); @@ -265,7 +270,7 @@ GicV2DxeInitialize ( RegOffset = Index / 4; RegShift = (Index % 4) * 8; MmioAndThenOr32 ( - FixedPcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4 * RegOffset), + mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset), ~(0xff << RegShift), ARM_GIC_DEFAULT_PRIORITY << RegShift ); @@ -282,28 +287,28 @@ GicV2DxeInitialize ( // // Read the first Interrupt Processor Targets Register (that corresponds to the 4 // first SGIs) - CpuTarget = MmioRead32 (FixedPcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPTR); + CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR); // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value // is 0 when we run on a uniprocessor platform. if (CpuTarget != 0) { // The 8 first Interrupt Processor Targets Registers are read-only for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) { - MmioWrite32 (FixedPcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget); + MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget); } } // Set binary point reg to 0x7 (no preemption) - MmioWrite32 (FixedPcdGet32 (PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7); + MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7); // Set priority mask reg to 0xff to allow all priorities through - MmioWrite32 (FixedPcdGet32 (PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff); + MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff); // Enable gic cpu interface - ArmGicEnableInterruptInterface (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); + ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase); // Enable gic distributor - ArmGicEnableDistributor (FixedPcdGet32 (PcdGicDistributorBase)); + ArmGicEnableDistributor (mGicDistributorBase); Status = InstallAndRegisterInterruptService ( &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent); diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf index 2796268015..ddd65aae8e 100644 --- a/ArmPkg/Library/BdsLib/BdsLib.inf +++ b/ArmPkg/Library/BdsLib/BdsLib.inf @@ -48,6 +48,7 @@ DebugLib DevicePathLib HobLib + PcdLib PerformanceLib SerialPortLib FdtLib @@ -91,7 +92,7 @@ [FixedPcd.ARM] gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset -[FixedPcd.AARCH64] +[Pcd.AARCH64] gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicSgiIntId