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 <lersek@redhat.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16072 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ard Biesheuvel 2014-09-09 16:00:47 +00:00 committed by oliviermartin
parent e1e2e66cd6
commit dc63be2495
4 changed files with 36 additions and 25 deletions

View File

@ -81,13 +81,6 @@
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004 gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005 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 # ARM Secure Firmware PCDs
# #
@ -216,6 +209,10 @@
gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment|0x00200000|UINT32|0x00000026 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] [PcdsFixedAtBuild.common, PcdsDynamic.common]
# #
# ARM Architectural Timer # ARM Architectural Timer
@ -227,3 +224,10 @@
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036 gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040 gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041 gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
#
# ARM Generic Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
gArmTokenSpaceGuid.PcdGicSgiIntId|0|UINT32|0x00000025

View File

@ -43,12 +43,13 @@
MemoryAllocationLib MemoryAllocationLib
UefiDriverEntryPoint UefiDriverEntryPoint
IoLib IoLib
PcdLib
[Protocols] [Protocols]
gHardwareInterruptProtocolGuid gHardwareInterruptProtocolGuid
gEfiCpuArchProtocolGuid gEfiCpuArchProtocolGuid
[FixedPcd.common] [Pcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase

View File

@ -29,6 +29,9 @@ Abstract:
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol; extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol;
UINT32 mGicInterruptInterfaceBase;
UINT32 mGicDistributorBase;
/** /**
Enable interrupt source Source. Enable interrupt source Source.
@ -51,7 +54,7 @@ GicV2EnableInterruptSource (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
ArmGicEnableInterrupt (FixedPcdGet32 (PcdGicDistributorBase), Source); ArmGicEnableInterrupt (mGicDistributorBase, Source);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -78,7 +81,7 @@ GicV2DisableInterruptSource (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
ArmGicDisableInterrupt (FixedPcdGet32 (PcdGicDistributorBase), Source); ArmGicDisableInterrupt (mGicDistributorBase, Source);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -107,7 +110,7 @@ GicV2GetInterruptSourceState (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
*InterruptState = ArmGicIsInterruptEnabled (FixedPcdGet32 (PcdGicDistributorBase), Source); *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -135,7 +138,7 @@ GicV2EndOfInterrupt (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
ArmGicV2EndOfInterrupt (FixedPcdGet32 (PcdGicInterruptInterfaceBase), Source); ArmGicV2EndOfInterrupt (mGicInterruptInterfaceBase, Source);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -160,7 +163,7 @@ GicV2IrqInterruptHandler (
UINT32 GicInterrupt; UINT32 GicInterrupt;
HARDWARE_INTERRUPT_HANDLER InterruptHandler; 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). // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) { if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
@ -216,7 +219,7 @@ GicV2ExitBootServicesEvent (
// Acknowledge all pending interrupts // Acknowledge all pending interrupts
do { do {
GicInterrupt = ArmGicV2AcknowledgeInterrupt (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) { if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) {
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
@ -224,10 +227,10 @@ GicV2ExitBootServicesEvent (
} while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt)); } while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt));
// Disable Gic Interface // Disable Gic Interface
ArmGicV2DisableInterruptInterface (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase);
// Disable Gic Distributor // 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. // Make sure the Interrupt Controller Protocol is not already installed in the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); 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++) { for (Index = 0; Index < mGicNumInterrupts; Index++) {
GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
@ -265,7 +270,7 @@ GicV2DxeInitialize (
RegOffset = Index / 4; RegOffset = Index / 4;
RegShift = (Index % 4) * 8; RegShift = (Index % 4) * 8;
MmioAndThenOr32 ( MmioAndThenOr32 (
FixedPcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4 * RegOffset), mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
~(0xff << RegShift), ~(0xff << RegShift),
ARM_GIC_DEFAULT_PRIORITY << RegShift ARM_GIC_DEFAULT_PRIORITY << RegShift
); );
@ -282,28 +287,28 @@ GicV2DxeInitialize (
// //
// Read the first Interrupt Processor Targets Register (that corresponds to the 4 // Read the first Interrupt Processor Targets Register (that corresponds to the 4
// first SGIs) // 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 // 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. // is 0 when we run on a uniprocessor platform.
if (CpuTarget != 0) { if (CpuTarget != 0) {
// The 8 first Interrupt Processor Targets Registers are read-only // The 8 first Interrupt Processor Targets Registers are read-only
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) { 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) // 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 // 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 // Enable gic cpu interface
ArmGicEnableInterruptInterface (FixedPcdGet32 (PcdGicInterruptInterfaceBase)); ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase);
// Enable gic distributor // Enable gic distributor
ArmGicEnableDistributor (FixedPcdGet32 (PcdGicDistributorBase)); ArmGicEnableDistributor (mGicDistributorBase);
Status = InstallAndRegisterInterruptService ( Status = InstallAndRegisterInterruptService (
&gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent); &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);

View File

@ -48,6 +48,7 @@
DebugLib DebugLib
DevicePathLib DevicePathLib
HobLib HobLib
PcdLib
PerformanceLib PerformanceLib
SerialPortLib SerialPortLib
FdtLib FdtLib
@ -91,7 +92,7 @@
[FixedPcd.ARM] [FixedPcd.ARM]
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset
[FixedPcd.AARCH64] [Pcd.AARCH64]
gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicSgiIntId gArmTokenSpaceGuid.PcdGicSgiIntId