#include <Library/IoLib.h>\r
#include <Library/PcdLib.h>\r
\r
-#include "GicV2/ArmGicV2Lib.h"\r
-#include "GicV3/ArmGicV3Lib.h"\r
+/**\r
+ *\r
+ * Return whether the Source interrupt index refers to a shared interrupt (SPI)\r
+ */\r
+STATIC\r
+BOOLEAN\r
+SourceIsSpi (\r
+ IN UINTN Source\r
+ )\r
+{\r
+ return Source >= 32 && Source < 1020;\r
+}\r
\r
/**\r
* Return the base address of the GIC redistributor for the current CPU\r
}\r
\r
// Move to the next GIC Redistributor frame\r
- GicRedistributorBase += GicRedistributorGranularity;\r
+ GicCpuRedistributorBase += GicRedistributorGranularity;\r
}\r
\r
// The Redistributor has not been found for the current CPU\r
EFIAPI\r
ArmGicEnableInterrupt (\r
IN UINTN GicDistributorBase,\r
+ IN UINTN GicRedistributorBase,\r
IN UINTN Source\r
)\r
{\r
- UINT32 RegOffset;\r
- UINTN RegShift;\r
+ UINT32 RegOffset;\r
+ UINTN RegShift;\r
+ ARM_GIC_ARCH_REVISION Revision;\r
+ UINTN GicCpuRedistributorBase;\r
\r
// Calculate enable register offset and bit position\r
RegOffset = Source / 32;\r
RegShift = Source % 32;\r
\r
- // Write set-enable register\r
- MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);\r
+ Revision = ArmGicGetSupportedArchRevision ();\r
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+ FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+ SourceIsSpi (Source)) {\r
+ // Write set-enable register\r
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);\r
+ } else {\r
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+ if (GicCpuRedistributorBase == 0) {\r
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
+ return;\r
+ }\r
+\r
+ // Write set-enable register\r
+ MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset), 1 << RegShift);\r
+ }\r
}\r
\r
VOID\r
EFIAPI\r
ArmGicDisableInterrupt (\r
IN UINTN GicDistributorBase,\r
+ IN UINTN GicRedistributorBase,\r
IN UINTN Source\r
)\r
{\r
- UINT32 RegOffset;\r
- UINTN RegShift;\r
+ UINT32 RegOffset;\r
+ UINTN RegShift;\r
+ ARM_GIC_ARCH_REVISION Revision;\r
+ UINTN GicCpuRedistributorBase;\r
\r
// Calculate enable register offset and bit position\r
RegOffset = Source / 32;\r
RegShift = Source % 32;\r
\r
- // Write clear-enable register\r
- MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);\r
+ Revision = ArmGicGetSupportedArchRevision ();\r
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+ FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+ SourceIsSpi (Source)) {\r
+ // Write clear-enable register\r
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);\r
+ } else {\r
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+ if (GicCpuRedistributorBase == 0) {\r
+ return;\r
+ }\r
+\r
+ // Write clear-enable register\r
+ MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * RegOffset), 1 << RegShift);\r
+ }\r
}\r
\r
BOOLEAN\r
EFIAPI\r
ArmGicIsInterruptEnabled (\r
IN UINTN GicDistributorBase,\r
+ IN UINTN GicRedistributorBase,\r
IN UINTN Source\r
)\r
{\r
- UINT32 RegOffset;\r
- UINTN RegShift;\r
+ UINT32 RegOffset;\r
+ UINTN RegShift;\r
+ ARM_GIC_ARCH_REVISION Revision;\r
+ UINTN GicCpuRedistributorBase;\r
+ UINT32 Interrupts;\r
\r
// Calculate enable register offset and bit position\r
RegOffset = Source / 32;\r
RegShift = Source % 32;\r
\r
- return ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);\r
+ Revision = ArmGicGetSupportedArchRevision ();\r
+ if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+ FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+ SourceIsSpi (Source)) {\r
+ Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);\r
+ } else {\r
+ GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+ if (GicCpuRedistributorBase == 0) {\r
+ return 0;\r
+ }\r
+\r
+ // Read set-enable register\r
+ Interrupts = MmioRead32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset));\r
+ }\r
+\r
+ return ((Interrupts & (1 << RegShift)) != 0);\r
}\r
\r
VOID\r