diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2016-07-07 19:18:39 +0200 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2016-07-13 16:37:21 +0200 |
commit | 28f8d28faabf50a82ef8d137308592c64ea9e2b6 (patch) | |
tree | d9bd37d2ea526ac3f889bd390fbbfc1f06b517ec /ArmPkg/Drivers/ArmGic/ArmGicLib.c | |
parent | 31441f298365dd182a7a672f1b40fbdb6115c12f (diff) | |
download | edk2-28f8d28faabf50a82ef8d137308592c64ea9e2b6.tar.gz edk2-28f8d28faabf50a82ef8d137308592c64ea9e2b6.tar.bz2 edk2-28f8d28faabf50a82ef8d137308592c64ea9e2b6.zip |
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>
Diffstat (limited to 'ArmPkg/Drivers/ArmGic/ArmGicLib.c')
-rw-r--r-- | ArmPkg/Drivers/ArmGic/ArmGicLib.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 248e896c4b..73795ed4e5 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -20,6 +20,19 @@ #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
*
* @param Revision GIC Revision. The GIC redistributor might have a different
@@ -183,7 +196,9 @@ ArmGicEnableInterrupt ( RegShift = Source % 32;
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
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
} else {
@@ -216,7 +231,9 @@ ArmGicDisableInterrupt ( RegShift = Source % 32;
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
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
} else {
@@ -249,7 +266,9 @@ ArmGicIsInterruptEnabled ( RegShift = Source % 32;
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);
} else {
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|