]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmVirtPkg/Library/ArmVirtGicArchLib/ArmVirtGicArchLib.c
ArmVirtPkg/ArmGicArchLib: move to FdtClient protocol
[mirror_edk2.git] / ArmVirtPkg / Library / ArmVirtGicArchLib / ArmVirtGicArchLib.c
index 732860cadfe63072c0e7885a9d9b7ba79e3fe332..7ef829ff2d26d3775bde1b58ee76e21e5028aa9c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   ArmGicArchLib library class implementation for DT based virt platforms\r
 \r
-  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2016, Linaro 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
 \r
 #include <Base.h>\r
+#include <Uefi.h>\r
 \r
 #include <Library/ArmGicLib.h>\r
 #include <Library/ArmGicArchLib.h>\r
-#include <Library/PcdLib.h>\r
+#include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Protocol/FdtClient.h>\r
 \r
 STATIC ARM_GIC_ARCH_REVISION        mGicArchRevision;\r
 \r
@@ -28,11 +33,61 @@ ArmVirtGicArchLibConstructor (
   VOID\r
   )\r
 {\r
-  UINT32  IccSre;\r
+  UINT32                IccSre;\r
+  FDT_CLIENT_PROTOCOL   *FdtClient;\r
+  CONST UINT64          *Reg;\r
+  UINT32                RegElemSize, RegSize;\r
+  UINTN                 GicRevision;\r
+  EFI_STATUS            Status;\r
+  UINT64                DistBase, CpuBase, RedistBase;\r
 \r
-  switch (PcdGet32 (PcdArmGicRevision)) {\r
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
+                  (VOID **)&FdtClient);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  GicRevision = 2;\r
+  Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,cortex-a15-gic",\r
+                        (CONST VOID **)&Reg, &RegElemSize, &RegSize);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    GicRevision = 3;\r
+    Status = FdtClient->FindCompatibleNodeReg (FdtClient, "arm,gic-v3",\r
+                          (CONST VOID **)&Reg, &RegElemSize, &RegSize);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  switch (GicRevision) {\r
 \r
   case 3:\r
+    //\r
+    // The GIC v3 DT binding describes a series of at least 3 physical (base\r
+    // addresses, size) pairs: the distributor interface (GICD), at least one\r
+    // redistributor region (GICR) containing dedicated redistributor\r
+    // interfaces for all individual CPUs, and the CPU interface (GICC).\r
+    // Under virtualization, we assume that the first redistributor region\r
+    // listed covers the boot CPU. Also, our GICv3 driver only supports the\r
+    // system register CPU interface, so we can safely ignore the MMIO version\r
+    // which is listed after the sequence of redistributor interfaces.\r
+    // This means we are only interested in the first two memory regions\r
+    // supplied, and ignore everything else.\r
+    //\r
+    ASSERT (RegSize >= 32);\r
+\r
+    // RegProp[0..1] == { GICD base, GICD size }\r
+    DistBase = SwapBytes64 (Reg[0]);\r
+    ASSERT (DistBase < MAX_UINT32);\r
+\r
+    // RegProp[2..3] == { GICR base, GICR size }\r
+    RedistBase = SwapBytes64 (Reg[2]);\r
+    ASSERT (RedistBase < MAX_UINT32);\r
+\r
+    PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);\r
+    PcdSet32 (PcdGicRedistributorsBase, (UINT32)RedistBase);\r
+\r
+    DEBUG ((EFI_D_INFO, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",\r
+      DistBase, RedistBase));\r
+\r
     //\r
     // The default implementation of ArmGicArchLib is responsible for enabling\r
     // the system register interface on the GICv3 if one is found. So let's do\r
@@ -55,6 +110,18 @@ ArmVirtGicArchLibConstructor (
     break;\r
 \r
   case 2:\r
+    ASSERT (RegSize == 32);\r
+\r
+    DistBase = SwapBytes64 (Reg[0]);\r
+    CpuBase  = SwapBytes64 (Reg[2]);\r
+    ASSERT (DistBase < MAX_UINT32);\r
+    ASSERT (CpuBase < MAX_UINT32);\r
+\r
+    PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);\r
+    PcdSet32 (PcdGicInterruptInterfaceBase, (UINT32)CpuBase);\r
+\r
+    DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));\r
+\r
     mGicArchRevision = ARM_GIC_ARCH_REVISION_2;\r
     break;\r
 \r