mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 23:24:03 +02:00
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) {
|
if (Revision == ARM_GIC_ARCH_REVISION_2) {
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
|
||||||
} else {
|
} 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
|
// Targets the interrupts to the Primary Cpu
|
||||||
//
|
//
|
||||||
|
|
||||||
MpId = ArmReadMpidr ();
|
if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
||||||
CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
// 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
|
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
|
||||||
for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
|
// is 0 when we run on a uniprocessor platform.
|
||||||
MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);
|
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)
|
// Set binary point reg to 0x7 (no preemption)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user