]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg: Add support for GICv4
authorSami Mujawar <sami.mujawar@arm.com>
Tue, 9 Oct 2018 15:35:22 +0000 (16:35 +0100)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 12 Oct 2018 15:40:33 +0000 (17:40 +0200)
Updated Redistributor base calculation to allow for the fact that
GICv4 has 2 additional 64KB frames (for VLPI and a reserved frame).
The code now tests the VLPIS bit in the GIC Redistributor Type
Register (GICR_TYPER) and calculates the Redistributor granularity
accordingly.

The code changes are:
  GICR_TYPER register fields, etc, added to the header.
  Loop updated to pay attention to GICR_TYPER.Last.
  Derive frame "stride" size from GICR_TYPER.VLPIS.

Note: The assumption is that the redistributors are adjacent for
all CPUs. However this may not be the case for NUMA systems.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
ArmPkg/Drivers/ArmGic/ArmGicLib.c
ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmPkg/Include/Library/ArmGicLib.h

index 0087399fb1dba0e697f7a6ccd6f7432a59311ac6..0be5b14b4f6eba74903739d03912e73fdeb0e4e7 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2017, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2018, 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
 #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
@@ -54,12 +64,11 @@ GicGetCpuRedistributorBase (
   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
+  UINT64 TypeRegister;\r
 \r
   MpId = ArmReadMpidr ();\r
   // Define CPU affinity as:\r
@@ -68,27 +77,30 @@ GicGetCpuRedistributorBase (
   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:\r
-    //   Redistributor control frame + SGI Control & Generation frame\r
-    GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE\r
-                                  + 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
-    GicCpuRedistributorBase += 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
index 047adac85ff40ee4f6bd63d9fc7c17283b44c7e0..93375b7be3eee76cf3c4222cb880a56e4db4c6f3 100644 (file)
@@ -1,5 +1,5 @@
 #/* @file\r
-#  Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
+#  Copyright (c) 2011-2018, 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
@@ -44,8 +44,5 @@
   ArmPlatformPkg/ArmPlatformPkg.dec\r
   MdePkg/MdePkg.dec\r
 \r
-[Pcd]\r
-  gArmPlatformTokenSpaceGuid.PcdCoreCount\r
-\r
 [FeaturePcd]\r
   gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy\r
index 4b21ea9e4e76cb83c0c3421c1d9d88b456192687..5775905ca91baabca13de47b8b9f7ac507becd55 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2017, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2018, 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
 \r
 // GIC Redistributor\r
-#define ARM_GICR_CTLR_FRAME_SIZE    SIZE_64KB\r
-#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB\r
+#define ARM_GICR_CTLR_FRAME_SIZE         SIZE_64KB\r
+#define ARM_GICR_SGI_PPI_FRAME_SIZE      SIZE_64KB\r
+#define ARM_GICR_SGI_VLPI_FRAME_SIZE     SIZE_64KB\r
+#define ARM_GICR_SGI_RESERVED_FRAME_SIZE SIZE_64KB\r
 \r
 // GIC Redistributor Control frame\r
 #define ARM_GICR_TYPER          0x0008  // Redistributor Type Register\r
 \r
+// GIC Redistributor TYPER bit assignments\r
+#define ARM_GICR_TYPER_PLPIS        (1 << 0)              // Physical LPIs\r
+#define ARM_GICR_TYPER_VLPIS        (1 << 1)              // Virtual LPIs\r
+#define ARM_GICR_TYPER_DIRECTLPI    (1 << 3)              // Direct LPIs\r
+#define ARM_GICR_TYPER_LAST         (1 << 4)              // Last Redistributor in series\r
+#define ARM_GICR_TYPER_DPGS         (1 << 5)              // Disable Processor Group\r
+                                                          // Selection Support\r
+#define ARM_GICR_TYPER_PROCNO       (0xFFFF << 8)         // Processor Number\r
+#define ARM_GICR_TYPER_COMMONLPIAFF (0x3 << 24)           // Common LPI Affinity\r
+#define ARM_GICR_TYPER_AFFINITY     (0xFFFFFFFFULL << 32) // Redistributor Affinity\r
+\r
+#define ARM_GICR_TYPER_GET_AFFINITY(TypeReg)  (((TypeReg) & \\r
+                                                ARM_GICR_TYPER_AFFINITY) >> 32)\r
+\r
 // GIC SGI & PPI Redistributor frame\r
 #define ARM_GICR_ISENABLER      0x0100  // Interrupt Set-Enable Registers\r
 #define ARM_GICR_ICENABLER      0x0180  // Interrupt Clear-Enable Registers\r