diff mbox

[edk2,v4,03/16] ArmPkg: allow dynamic GIC base addresses

Message ID 1409235244-25783-4-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel Aug. 28, 2014, 2:13 p.m. UTC
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 <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmPkg/ArmPkg.dec                         | 15 +++++++------
 ArmPkg/Drivers/ArmGic/ArmGicDxe.inf       |  4 +++-
 ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c | 37 ++++++++++++++++++-------------
 ArmPkg/Library/BdsLib/BdsLib.inf          |  2 +-
 4 files changed, 33 insertions(+), 25 deletions(-)
diff mbox

Patch

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 0392af52758f..e5ed445ca367 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -72,6 +72,14 @@ 
   # Whether to use the virtual rather than the physical architected timer
   gArmTokenSpaceGuid.PcdArmArchTimerUseVirtual|FALSE|BOOLEAN|0x0000003F
 
+[PcdsFixedAtBuild.common,PcdsDynamic.common]
+  #
+  # ARM Generic Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
+  gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025
+
 [PcdsFixedAtBuild.common]
   gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
 
@@ -85,13 +93,6 @@ 
   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
   #
   gArmTokenSpaceGuid.PcdSecureFdBaseAddress|0|UINT32|0x00000015
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
index 7dc14b34ec48..522b5a842dfd 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
@@ -43,15 +43,17 @@ 
   MemoryAllocationLib
   UefiDriverEntryPoint
   IoLib
+  PcdLib
 
 [Protocols]
   gHardwareInterruptProtocolGuid
   gEfiCpuArchProtocolGuid
 
-[FixedPcd.common]
+[Pcd.common]
   gArmTokenSpaceGuid.PcdGicDistributorBase
   gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
 
+[FixedPcd.common]
   gArmTokenSpaceGuid.PcdArmPrimaryCore
 
 [Depex]
diff --git a/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c b/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
index 5561de630d6e..3f9e37b5f2d8 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 27962680159a..3e1ae8914abf 100644
--- a/ArmPkg/Library/BdsLib/BdsLib.inf
+++ b/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -91,7 +91,7 @@ 
 [FixedPcd.ARM]
   gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset
 
-[FixedPcd.AARCH64]
+[Pcd.AARCH64]
   gArmTokenSpaceGuid.PcdGicDistributorBase
   gArmTokenSpaceGuid.PcdGicSgiIntId