]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/ArmGic/ArmGicLib.c
ArmPkg: Apply uncrustify changes
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / ArmGicLib.c
index 248e896c4b94a354f16a578a3fab826cc09b0904..58ab45f812b337dc1e607ed50c93f17c49b66305 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2021, 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
-*  which accompanies this distribution.  The full text of the license may be found at\r
-*  http://opensource.org/licenses/bsd-license.php\r
-*\r
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 *\r
 **/\r
 \r
 #include <Library/IoLib.h>\r
 #include <Library/PcdLib.h>\r
 \r
+// In GICv3, there are 2 x 64KB frames:\r
+// Redistributor control frame + SGI Control & Generation frame\r
+#define GIC_V3_REDISTRIBUTOR_GRANULARITY  (ARM_GICR_CTLR_FRAME_SIZE           \\r
+                                           + ARM_GICR_SGI_PPI_FRAME_SIZE)\r
+\r
+// In GICv4, there are 2 additional 64KB frames:\r
+// VLPI frame + Reserved page frame\r
+#define GIC_V4_REDISTRIBUTOR_GRANULARITY  (GIC_V3_REDISTRIBUTOR_GRANULARITY   \\r
+                                           + ARM_GICR_SGI_VLPI_FRAME_SIZE     \\r
+                                           + ARM_GICR_SGI_RESERVED_FRAME_SIZE)\r
+\r
+#define ISENABLER_ADDRESS(base, offset)  ((base) +\\r
+          ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + 4 * (offset))\r
+\r
+#define ICENABLER_ADDRESS(base, offset)  ((base) +\\r
+          ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + 4 * (offset))\r
+\r
+#define IPRIORITY_ADDRESS(base, offset)  ((base) +\\r
+          ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))\r
+\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
 STATIC\r
 UINTN\r
 GicGetCpuRedistributorBase (\r
-  IN UINTN                 GicRedistributorBase,\r
-  IN ARM_GIC_ARCH_REVISION Revision\r
+  IN UINTN                  GicRedistributorBase,\r
+  IN ARM_GIC_ARCH_REVISION  Revision\r
   )\r
 {\r
-  UINTN Index;\r
-  UINTN MpId;\r
-  UINTN CpuAffinity;\r
-  UINTN Affinity;\r
-  UINTN GicRedistributorGranularity;\r
-  UINTN GicCpuRedistributorBase;\r
+  UINTN   MpId;\r
+  UINTN   CpuAffinity;\r
+  UINTN   Affinity;\r
+  UINTN   GicCpuRedistributorBase;\r
+  UINT64  TypeRegister;\r
 \r
   MpId = ArmReadMpidr ();\r
-  // Define CPU affinity as Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]\r
+  // Define CPU affinity as:\r
+  // Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]\r
   // whereas Affinity3 is defined at [32:39] in MPIDR\r
-  CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | ((MpId & ARM_CORE_AFF3) >> 8);\r
+  CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) |\r
+                ((MpId & ARM_CORE_AFF3) >> 8);\r
 \r
-  if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
-    // 2 x 64KB frame: Redistributor control frame + SGI Control & Generation frame\r
-    GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_SGI_PPI_FRAME_SIZE;\r
-  } else {\r
+  if (Revision < ARM_GIC_ARCH_REVISION_3) {\r
     ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
     return 0;\r
   }\r
 \r
   GicCpuRedistributorBase = GicRedistributorBase;\r
 \r
-  for (Index = 0; Index < PcdGet32 (PcdCoreCount); Index++) {\r
-    Affinity = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER) >> 32;\r
+  do {\r
+    TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);\r
+    Affinity     = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);\r
     if (Affinity == CpuAffinity) {\r
       return GicCpuRedistributorBase;\r
     }\r
 \r
-    // Move to the next GIC Redistributor frame\r
-    GicRedistributorBase += GicRedistributorGranularity;\r
-  }\r
+    // Move to the next GIC Redistributor frame.\r
+    // The GIC specification does not forbid a mixture of redistributors\r
+    // with or without support for virtual LPIs, so we test Virtual LPIs\r
+    // Support (VLPIS) bit for each frame to decide the granularity.\r
+    // Note: The assumption here is that the redistributors are adjacent\r
+    // for all CPUs. However this may not be the case for NUMA systems.\r
+    GicCpuRedistributorBase += (((ARM_GICR_TYPER_VLPIS & TypeRegister) != 0)\r
+                                ? GIC_V4_REDISTRIBUTOR_GRANULARITY\r
+                                : GIC_V3_REDISTRIBUTOR_GRANULARITY);\r
+  } while ((TypeRegister & ARM_GICR_TYPER_LAST) == 0);\r
 \r
   // The Redistributor has not been found for the current CPU\r
   ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
@@ -74,7 +107,7 @@ GicGetCpuRedistributorBase (
 UINTN\r
 EFIAPI\r
 ArmGicGetInterfaceIdentification (\r
-  IN  INTN          GicInterruptInterfaceBase\r
+  IN  INTN  GicInterruptInterfaceBase\r
   )\r
 {\r
   // Read the GIC Identification Register\r
@@ -84,22 +117,32 @@ ArmGicGetInterfaceIdentification (
 UINTN\r
 EFIAPI\r
 ArmGicGetMaxNumInterrupts (\r
-  IN  INTN          GicDistributorBase\r
+  IN  INTN  GicDistributorBase\r
   )\r
 {\r
-  return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);\r
+  UINTN  ItLines;\r
+\r
+  ItLines = MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F;\r
+\r
+  //\r
+  // Interrupt ID 1020-1023 are reserved.\r
+  //\r
+  return (ItLines == 0x1f) ? 1020 : 32 * (ItLines + 1);\r
 }\r
 \r
 VOID\r
 EFIAPI\r
 ArmGicSendSgiTo (\r
-  IN  INTN          GicDistributorBase,\r
-  IN  INTN          TargetListFilter,\r
-  IN  INTN          CPUTargetList,\r
-  IN  INTN          SgiId\r
+  IN  INTN  GicDistributorBase,\r
+  IN  INTN  TargetListFilter,\r
+  IN  INTN  CPUTargetList,\r
+  IN  INTN  SgiId\r
   )\r
 {\r
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);\r
+  MmioWrite32 (\r
+    GicDistributorBase + ARM_GIC_ICDSGIR,\r
+    ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId\r
+    );\r
 }\r
 \r
 /*\r
@@ -110,7 +153,8 @@ ArmGicSendSgiTo (
  * in the GICv3 the register value is only the InterruptId.\r
  *\r
  * @param GicInterruptInterfaceBase   Base Address of the GIC CPU Interface\r
- * @param InterruptId                 InterruptId read from the Interrupt Acknowledge Register\r
+ * @param InterruptId                 InterruptId read from the Interrupt\r
+ *                                    Acknowledge Register\r
  *\r
  * @retval value returned by the Interrupt Acknowledge Register\r
  *\r
@@ -118,12 +162,12 @@ ArmGicSendSgiTo (
 UINTN\r
 EFIAPI\r
 ArmGicAcknowledgeInterrupt (\r
-  IN  UINTN          GicInterruptInterfaceBase,\r
-  OUT UINTN          *InterruptId\r
+  IN  UINTN  GicInterruptInterfaceBase,\r
+  OUT UINTN  *InterruptId\r
   )\r
 {\r
-  UINTN Value;\r
-  ARM_GIC_ARCH_REVISION Revision;\r
+  UINTN                  Value;\r
+  ARM_GIC_ARCH_REVISION  Revision;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
   if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
@@ -149,11 +193,11 @@ ArmGicAcknowledgeInterrupt (
 VOID\r
 EFIAPI\r
 ArmGicEndOfInterrupt (\r
-  IN  UINTN                 GicInterruptInterfaceBase,\r
-  IN UINTN                  Source\r
+  IN  UINTN  GicInterruptInterfaceBase,\r
+  IN UINTN   Source\r
   )\r
 {\r
-  ARM_GIC_ARCH_REVISION Revision;\r
+  ARM_GIC_ARCH_REVISION  Revision;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
   if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
@@ -165,100 +209,180 @@ ArmGicEndOfInterrupt (
   }\r
 }\r
 \r
+VOID\r
+EFIAPI\r
+ArmGicSetInterruptPriority (\r
+  IN UINTN  GicDistributorBase,\r
+  IN UINTN  GicRedistributorBase,\r
+  IN UINTN  Source,\r
+  IN UINTN  Priority\r
+  )\r
+{\r
+  UINT32                 RegOffset;\r
+  UINTN                  RegShift;\r
+  ARM_GIC_ARCH_REVISION  Revision;\r
+  UINTN                  GicCpuRedistributorBase;\r
+\r
+  // Calculate register offset and bit position\r
+  RegOffset = Source / 4;\r
+  RegShift  = (Source % 4) * 8;\r
+\r
+  Revision = ArmGicGetSupportedArchRevision ();\r
+  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+      SourceIsSpi (Source))\r
+  {\r
+    MmioAndThenOr32 (\r
+      GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),\r
+      ~(0xff << RegShift),\r
+      Priority << RegShift\r
+      );\r
+  } else {\r
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (\r
+                                GicRedistributorBase,\r
+                                Revision\r
+                                );\r
+    if (GicCpuRedistributorBase == 0) {\r
+      return;\r
+    }\r
+\r
+    MmioAndThenOr32 (\r
+      IPRIORITY_ADDRESS (GicCpuRedistributorBase, RegOffset),\r
+      ~(0xff << RegShift),\r
+      Priority << RegShift\r
+      );\r
+  }\r
+}\r
+\r
 VOID\r
 EFIAPI\r
 ArmGicEnableInterrupt (\r
-  IN UINTN                  GicDistributorBase,\r
-  IN UINTN                  GicRedistributorBase,\r
-  IN UINTN                  Source\r
+  IN UINTN  GicDistributorBase,\r
+  IN UINTN  GicRedistributorBase,\r
+  IN UINTN  Source\r
   )\r
 {\r
-  UINT32                RegOffset;\r
-  UINTN                 RegShift;\r
-  ARM_GIC_ARCH_REVISION Revision;\r
-  UINTN                 GicCpuRedistributorBase;\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
+  RegShift  = Source % 32;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
-  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {\r
+  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+      SourceIsSpi (Source))\r
+  {\r
     // Write set-enable register\r
-    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);\r
+    MmioWrite32 (\r
+      GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),\r
+      1 << RegShift\r
+      );\r
   } else {\r
-    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (\r
+                                GicRedistributorBase,\r
+                                Revision\r
+                                );\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
+    MmioWrite32 (\r
+      ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),\r
+      1 << RegShift\r
+      );\r
   }\r
 }\r
 \r
 VOID\r
 EFIAPI\r
 ArmGicDisableInterrupt (\r
-  IN UINTN                  GicDistributorBase,\r
-  IN UINTN                  GicRedistributorBase,\r
-  IN UINTN                  Source\r
+  IN UINTN  GicDistributorBase,\r
+  IN UINTN  GicRedistributorBase,\r
+  IN UINTN  Source\r
   )\r
 {\r
-  UINT32                RegOffset;\r
-  UINTN                 RegShift;\r
-  ARM_GIC_ARCH_REVISION Revision;\r
-  UINTN                 GicCpuRedistributorBase;\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
+  RegShift  = Source % 32;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
-  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {\r
+  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+      SourceIsSpi (Source))\r
+  {\r
     // Write clear-enable register\r
-    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);\r
+    MmioWrite32 (\r
+      GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),\r
+      1 << RegShift\r
+      );\r
   } else {\r
-    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (\r
+                                GicRedistributorBase,\r
+                                Revision\r
+                                );\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
+    MmioWrite32 (\r
+      ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),\r
+      1 << RegShift\r
+      );\r
   }\r
 }\r
 \r
 BOOLEAN\r
 EFIAPI\r
 ArmGicIsInterruptEnabled (\r
-  IN UINTN                  GicDistributorBase,\r
-  IN UINTN                  GicRedistributorBase,\r
-  IN UINTN                  Source\r
+  IN UINTN  GicDistributorBase,\r
+  IN UINTN  GicRedistributorBase,\r
+  IN UINTN  Source\r
   )\r
 {\r
-  UINT32                RegOffset;\r
-  UINTN                 RegShift;\r
-  ARM_GIC_ARCH_REVISION Revision;\r
-  UINTN                 GicCpuRedistributorBase;\r
-  UINT32                Interrupts;\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
+  RegShift  = Source % 32;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
-  if ((Revision == ARM_GIC_ARCH_REVISION_2) || FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {\r
-    Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);\r
+  if ((Revision == ARM_GIC_ARCH_REVISION_2) ||\r
+      FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||\r
+      SourceIsSpi (Source))\r
+  {\r
+    Interrupts = ((MmioRead32 (\r
+                     GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)\r
+                     )\r
+                   & (1 << RegShift)) != 0);\r
   } else {\r
-    GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);\r
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase (\r
+                                GicRedistributorBase,\r
+                                Revision\r
+                                );\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
+    Interrupts = MmioRead32 (\r
+                   ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset)\r
+                   );\r
   }\r
 \r
   return ((Interrupts & (1 << RegShift)) != 0);\r
@@ -267,7 +391,7 @@ ArmGicIsInterruptEnabled (
 VOID\r
 EFIAPI\r
 ArmGicDisableDistributor (\r
-  IN  INTN          GicDistributorBase\r
+  IN  INTN  GicDistributorBase\r
   )\r
 {\r
   // Disable Gic Distributor\r
@@ -277,10 +401,10 @@ ArmGicDisableDistributor (
 VOID\r
 EFIAPI\r
 ArmGicEnableInterruptInterface (\r
-  IN  INTN          GicInterruptInterfaceBase\r
+  IN  INTN  GicInterruptInterfaceBase\r
   )\r
 {\r
-  ARM_GIC_ARCH_REVISION Revision;\r
+  ARM_GIC_ARCH_REVISION  Revision;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
   if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
@@ -295,10 +419,10 @@ ArmGicEnableInterruptInterface (
 VOID\r
 EFIAPI\r
 ArmGicDisableInterruptInterface (\r
-  IN  INTN          GicInterruptInterfaceBase\r
+  IN  INTN  GicInterruptInterfaceBase\r
   )\r
 {\r
-  ARM_GIC_ARCH_REVISION Revision;\r
+  ARM_GIC_ARCH_REVISION  Revision;\r
 \r
   Revision = ArmGicGetSupportedArchRevision ();\r
   if (Revision == ARM_GIC_ARCH_REVISION_2) {\r