]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
ArmPkg/ArmGic: Use the GIC Redistributor instead of GIC Distributor for GICv3
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / GicV3 / ArmGicV3Dxe.c
index 51212811e31d57f4954b4ee08579bf2f38233eee..e94e015e1ff098d34e625c2bad575e05cbc010a6 100644 (file)
@@ -44,7 +44,7 @@ GicV3EnableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicEnableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicEnableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -71,7 +71,7 @@ GicV3DisableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicDisableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicDisableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -100,7 +100,7 @@ GicV3GetInterruptSourceState (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);\r
+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -239,7 +239,8 @@ GicV3DxeInitialize (
   UINTN                   Index;\r
   UINT32                  RegOffset;\r
   UINTN                   RegShift;\r
-  UINT32                  CpuTarget;\r
+  UINT64                  CpuTarget;\r
+  UINT64                  MpId;\r
 \r
   // Make sure the Interrupt Controller Protocol is not already installed in the system.\r
   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);\r
@@ -265,22 +266,12 @@ GicV3DxeInitialize (
   // Targets the interrupts to the Primary Cpu\r
   //\r
 \r
-  // Only Primary CPU will run this code. We can identify our GIC CPU ID by reading\r
-  // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each\r
-  // connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.\r
-  // More Info in the GIC Specification about "Interrupt Processor Targets Registers"\r
-  //\r
-  // Read the first Interrupt Processor Targets Register (that corresponds to the 4\r
-  // first SGIs)\r
-  CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);\r
-\r
-  // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value\r
-  // is 0 when we run on a uniprocessor platform.\r
-  if (CpuTarget != 0) {\r
-    // The 8 first Interrupt Processor Targets Registers are read-only\r
-    for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {\r
-      MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);\r
-    }\r
+  MpId = ArmReadMpidr ();\r
+  CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);\r
+\r
+  // Route the SPIs to the primary CPU. SPIs start at the INTID 32\r
+  for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {\r
+    MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);\r
   }\r
 \r
   // Set binary point reg to 0x7 (no preemption)\r