ArmPkg/ArmGicLib: manage GICv3 SPI state at the distributor
Unlike SGIs and PPIs, which are private to the CPU and are managed at the redistributor level (which is also a per-CPU construct), shared interrupts (SPIs) are shared between all CPUs, and therefore managed at the distributor level (just as on GICv2). Reported-by: Narinder Dhillon <ndhillonv2@gmail.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
This commit is contained in:
parent
31441f2983
commit
28f8d28faa
|
@ -19,6 +19,19 @@
|
||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Return whether the Source interrupt index refers to a shared interrupt (SPI)
|
||||||
|
*/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
SourceIsSpi (
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Source >= 32 && Source < 1020;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the base address of the GIC redistributor for the current CPU
|
* Return the base address of the GIC redistributor for the current CPU
|
||||||
*
|
*
|
||||||
|
@ -183,7 +196,9 @@ ArmGicEnableInterrupt (
|
||||||
RegShift = Source % 32;
|
RegShift = Source % 32;
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
Revision = ArmGicGetSupportedArchRevision ();
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
|
SourceIsSpi (Source)) {
|
||||||
// Write set-enable register
|
// Write set-enable register
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
|
||||||
} else {
|
} else {
|
||||||
|
@ -216,7 +231,9 @@ ArmGicDisableInterrupt (
|
||||||
RegShift = Source % 32;
|
RegShift = Source % 32;
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
Revision = ArmGicGetSupportedArchRevision ();
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
|
SourceIsSpi (Source)) {
|
||||||
// Write clear-enable register
|
// Write clear-enable register
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,7 +266,9 @@ ArmGicIsInterruptEnabled (
|
||||||
RegShift = Source % 32;
|
RegShift = Source % 32;
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
Revision = ArmGicGetSupportedArchRevision ();
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
|
SourceIsSpi (Source)) {
|
||||||
Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);
|
Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);
|
||||||
} else {
|
} else {
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|
||||||
|
|
Loading…
Reference in New Issue