summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuan Nguyen <quan@os.amperecomputing.com>2020-12-16 20:25:20 +0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-12-18 18:09:18 +0000
commit0d49b82e4fa5d7eaeb5f73dfb93a932893832437 (patch)
tree751d9b3a2701066f7dc49ce900ad7c7bbb1e398b
parente2bfd172e4b98308aadac98f7c8203950a245e4b (diff)
downloadedk2-0d49b82e4fa5d7eaeb5f73dfb93a932893832437.tar.gz
edk2-0d49b82e4fa5d7eaeb5f73dfb93a932893832437.tar.bz2
edk2-0d49b82e4fa5d7eaeb5f73dfb93a932893832437.zip
ArmPkg/ArmGicLib: Add ArmGicSetInterruptPriority() helper function
According to ARM IHI 0069F, section 11.9.18 GICD_IPRIORITYR<n>, Interrupt Priority Registers, n = 0 - 254, when affinity routing is enabled for the Security state of an interrupt, GICR_IPRIORITYR<n> is used instead of GICD_IPRIORITYR<n> where n = 0 to 7 (that is, for SGIs and PPIs). As setting interrupt priority for SGIs and PPIs are handled using difference registers depends on the mode, this patch instroduces ArmGicSetInterruptPriority() helper function to handle the discrepancy. Cc: Leif Lindholm <leif@nuviainc.com> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com> Reviewed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicLib.c44
-rw-r--r--ArmPkg/Include/Library/ArmGicLib.h9
2 files changed, 53 insertions, 0 deletions
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
index 001e6b1431..8ef32b33a1 100644
--- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c
@@ -201,6 +201,50 @@ ArmGicEndOfInterrupt (
VOID
EFIAPI
+ArmGicSetInterruptPriority (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source,
+ IN UINTN Priority
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+ ARM_GIC_ARCH_REVISION Revision;
+ UINTN GicCpuRedistributorBase;
+
+ // Calculate register offset and bit position
+ RegOffset = Source / 4;
+ RegShift = (Source % 4) * 8;
+
+ Revision = ArmGicGetSupportedArchRevision ();
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
+ FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
+ SourceIsSpi (Source)) {
+ MmioAndThenOr32 (
+ GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
+ ~(0xff << RegShift),
+ Priority << RegShift
+ );
+ } else {
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (
+ GicRedistributorBase,
+ Revision
+ );
+ if (GicCpuRedistributorBase == 0) {
+ return;
+ }
+
+ MmioAndThenOr32 (
+ GicCpuRedistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
+ ~(0xff << RegShift),
+ Priority << RegShift
+ );
+ }
+}
+
+VOID
+EFIAPI
ArmGicEnableInterrupt (
IN UINTN GicDistributorBase,
IN UINTN GicRedistributorBase,
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index 5509318963..7bcfc00111 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -210,6 +210,15 @@ ArmGicSetPriorityMask (
VOID
EFIAPI
+ArmGicSetInterruptPriority (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicRedistributorBase,
+ IN UINTN Source,
+ IN UINTN Priority
+ );
+
+VOID
+EFIAPI
ArmGicEnableInterrupt (
IN UINTN GicDistributorBase,
IN UINTN GicRedistributorBase,