mirror of https://github.com/acidanthera/audk.git
ArmPkg/ArmGic: Fix GICv3 in GICv2 legacy mode
- GIC distributor needs to be programmed to target interrupts on the boot CPU using the Interrupt Processor Targets Registers - Enabling the GIC Distributor is different following the value of GICD_CTLR.ARE_NS. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16926 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
26a363747d
commit
152ac48945
|
@ -32,6 +32,10 @@ ArmGicEnableDistributor (
|
|||
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
||||
} else {
|
||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
|
||||
if (MmioRead32 (GicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_ARE) {
|
||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
|
||||
} else {
|
||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,12 +274,32 @@ GicV3DxeInitialize (
|
|||
// Targets the interrupts to the Primary Cpu
|
||||
//
|
||||
|
||||
MpId = ArmReadMpidr ();
|
||||
CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
||||
if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
||||
// Only Primary CPU will run this code. We can identify our GIC CPU ID by reading
|
||||
// the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each
|
||||
// connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.
|
||||
// More Info in the GIC Specification about "Interrupt Processor Targets Registers"
|
||||
//
|
||||
// Read the first Interrupt Processor Targets Register (that corresponds to the 4
|
||||
// first SGIs)
|
||||
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
|
||||
|
||||
// Route the SPIs to the primary CPU. SPIs start at the INTID 32
|
||||
for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
|
||||
MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);
|
||||
// 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 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MpId = ArmReadMpidr ();
|
||||
CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
||||
|
||||
// Route the SPIs to the primary CPU. SPIs start at the INTID 32
|
||||
for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
|
||||
MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);
|
||||
}
|
||||
}
|
||||
|
||||
// Set binary point reg to 0x7 (no preemption)
|
||||
|
|
Loading…
Reference in New Issue