mirror of https://github.com/acidanthera/audk.git
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:
parent
e1e2e66cd6
commit
dc63be2495
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue