]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmGic: Use the GIC Redistributor instead of GIC Distributor for GICv3
authorOlivier Martin <olivier.martin@arm.com>
Mon, 16 Feb 2015 10:23:42 +0000 (10:23 +0000)
committeroliviermartin <oliviermartin@Edk2>
Mon, 16 Feb 2015 10:23:42 +0000 (10:23 +0000)
GICv3 controller with no GICv2 legacy support must use the GIC
Redistributor registers instead of the GIC Distributor registers
for some operations (eg: enable/disable interrupts).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Tested-by: Ard Biesheuvel <ard@linaro.org>
Reviewed-by: Ard Biesheuvel <ard@linaro.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16874 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Drivers/ArmGic/ArmGicLib.c
ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
ArmPkg/Include/Library/ArmGicLib.h

index 1e213019fee9c72c731e22e5768de9bc15de5323..7c53e39793df7f9c1c2368c587bb6e16cc1e55a6 100644 (file)
@@ -172,53 +172,99 @@ VOID
 EFIAPI\r
 ArmGicEnableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
 EFIAPI\r
 ArmGicEnableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   )\r
 {\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
 \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
+    // 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
 }\r
 \r
 VOID\r
 EFIAPI\r
 ArmGicDisableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   )\r
 {\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
 \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
+    // 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
 }\r
 \r
 BOOLEAN\r
 EFIAPI\r
 ArmGicIsInterruptEnabled (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   )\r
 {\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
 \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
+    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
 }\r
 \r
 VOID\r
index 06367f9d77af075800407022cedc8d11734beab8..e2538f1798f89be56428de3d10f0899f4e6cf6ef 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
 /** @file\r
 *\r
-*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
@@ -22,9 +22,16 @@ ArmGicEnableDistributor (
   IN  INTN          GicDistributorBase\r
   )\r
 {\r
   IN  INTN          GicDistributorBase\r
   )\r
 {\r
+  ARM_GIC_ARCH_REVISION Revision;\r
+\r
   /*\r
    * Enable GIC distributor in Non-Secure world.\r
    * Note: The ICDDCR register is banked when Security extensions are implemented\r
    */\r
   /*\r
    * Enable GIC distributor in Non-Secure world.\r
    * Note: The ICDDCR register is banked when Security extensions are implemented\r
    */\r
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);\r
+  Revision = ArmGicGetSupportedArchRevision ();\r
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);\r
+  } else {\r
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);\r
+  }\r
 }\r
 }\r
index f37e95ede98f0829dd94b533b31a945f2595f98f..743c534e04d9d8bc27002588e4303ceeca7c2494 100644 (file)
@@ -2,7 +2,7 @@
 \r
 Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>\r
 Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
 \r
 Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>\r
 Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
-Portions copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>\r
+Portions copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -54,7 +54,7 @@ GicV2EnableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicEnableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicEnableInterrupt (mGicDistributorBase, 0, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -81,7 +81,7 @@ GicV2DisableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicDisableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicDisableInterrupt (mGicDistributorBase, 0, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -110,7 +110,7 @@ GicV2GetInterruptSourceState (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);\r
+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 0, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
index 51212811e31d57f4954b4ee08579bf2f38233eee..e94e015e1ff098d34e625c2bad575e05cbc010a6 100644 (file)
@@ -44,7 +44,7 @@ GicV3EnableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicEnableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicEnableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -71,7 +71,7 @@ GicV3DisableInterruptSource (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ArmGicDisableInterrupt (mGicDistributorBase, Source);\r
+  ArmGicDisableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -100,7 +100,7 @@ GicV3GetInterruptSourceState (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);\r
+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, mGicRedistributorsBase, Source);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -239,7 +239,8 @@ GicV3DxeInitialize (
   UINTN                   Index;\r
   UINT32                  RegOffset;\r
   UINTN                   RegShift;\r
   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
 \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
   // 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
   }\r
 \r
   // Set binary point reg to 0x7 (no preemption)\r
index ac4bb2f77fe6878f289b68020d5c5aea543bc6d9..794e8788a60ba63ff1f734c3fd7c8b72baa19607 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
 /** @file\r
 *\r
-*  Copyright (c) 2014, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2014-2015, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials are licensed and made available\r
 *  under the terms and conditions of the BSD License which accompanies this\r
 *\r
 *  This program and the accompanying materials are licensed and made available\r
 *  under the terms and conditions of the BSD License which accompanies this\r
@@ -17,6 +17,8 @@
 \r
 #define ICC_SRE_EL2_SRE         (1 << 0)\r
 \r
 \r
 #define ICC_SRE_EL2_SRE         (1 << 0)\r
 \r
+#define ARM_GICD_IROUTER_IRM BIT31\r
+\r
 UINT32\r
 EFIAPI\r
 ArmGicV3GetControlSystemRegisterEnable (\r
 UINT32\r
 EFIAPI\r
 ArmGicV3GetControlSystemRegisterEnable (\r
index 6cd93a1f54f64b7990546ee9a0fa3a12cd9812b3..2ab99772d1e1a88ca18c8f732aa6b75d13b1e585 100644 (file)
@@ -208,6 +208,7 @@ VOID
 EFIAPI\r
 ArmGicEnableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
 EFIAPI\r
 ArmGicEnableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   );\r
 \r
   IN UINTN                  Source\r
   );\r
 \r
@@ -215,6 +216,7 @@ VOID
 EFIAPI\r
 ArmGicDisableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
 EFIAPI\r
 ArmGicDisableInterrupt (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   );\r
 \r
   IN UINTN                  Source\r
   );\r
 \r
@@ -222,6 +224,7 @@ BOOLEAN
 EFIAPI\r
 ArmGicIsInterruptEnabled (\r
   IN UINTN                  GicDistributorBase,\r
 EFIAPI\r
 ArmGicIsInterruptEnabled (\r
   IN UINTN                  GicDistributorBase,\r
+  IN UINTN                  GicRedistributorBase,\r
   IN UINTN                  Source\r
   );\r
 \r
   IN UINTN                  Source\r
   );\r
 \r