]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmVirtPkg/VirtFdtDxe/VirtFdtDxe.c
ArmVirtPkg/VirtFdtDxe: move FDT config table installation to FdtClientDxe
[mirror_edk2.git] / ArmVirtPkg / VirtFdtDxe / VirtFdtDxe.c
index 74f80d1d2b78bc30c1e2a56eb3e15b688f4b31a2..cebd4aa91fd9e6f0af50b2af546159bfa2142e6f 100644 (file)
@@ -28,7 +28,6 @@
 #include <libfdt.h>\r
 #include <Library/XenIoMmioLib.h>\r
 \r
-#include <Guid/Fdt.h>\r
 #include <Guid/VirtioMmioTransport.h>\r
 #include <Guid/FdtHob.h>\r
 \r
@@ -42,15 +41,7 @@ typedef struct {
 \r
 typedef enum {\r
   PropertyTypeUnknown,\r
-  PropertyTypeGic,\r
-  PropertyTypeRtc,\r
   PropertyTypeVirtio,\r
-  PropertyTypeUart,\r
-  PropertyTypeTimer,\r
-  PropertyTypePsci,\r
-  PropertyTypeFwCfg,\r
-  PropertyTypePciHost,\r
-  PropertyTypeGicV3,\r
   PropertyTypeXen,\r
 } PROPERTY_TYPE;\r
 \r
@@ -60,26 +51,11 @@ typedef struct {
 } PROPERTY;\r
 \r
 STATIC CONST PROPERTY CompatibleProperties[] = {\r
-  { PropertyTypeGic,     "arm,cortex-a15-gic"    },\r
-  { PropertyTypeRtc,     "arm,pl031"             },\r
   { PropertyTypeVirtio,  "virtio,mmio"           },\r
-  { PropertyTypeUart,    "arm,pl011"             },\r
-  { PropertyTypeTimer,   "arm,armv7-timer"       },\r
-  { PropertyTypeTimer,   "arm,armv8-timer"       },\r
-  { PropertyTypePsci,    "arm,psci-0.2"          },\r
-  { PropertyTypeFwCfg,   "qemu,fw-cfg-mmio"      },\r
-  { PropertyTypePciHost, "pci-host-ecam-generic" },\r
-  { PropertyTypeGicV3,   "arm,gic-v3"            },\r
   { PropertyTypeXen,     "xen,xen"               },\r
   { PropertyTypeUnknown, ""                      }\r
 };\r
 \r
-typedef struct {\r
-  UINT32  Type;\r
-  UINT32  Number;\r
-  UINT32  Flags;\r
-} INTERRUPT_PROPERTY;\r
-\r
 STATIC\r
 PROPERTY_TYPE\r
 GetTypeFromNode (\r
@@ -105,176 +81,6 @@ GetTypeFromNode (
   return PropertyTypeUnknown;\r
 }\r
 \r
-//\r
-// We expect the "ranges" property of "pci-host-ecam-generic" to consist of\r
-// records like this.\r
-//\r
-#pragma pack (1)\r
-typedef struct {\r
-  UINT32 Type;\r
-  UINT64 ChildBase;\r
-  UINT64 CpuBase;\r
-  UINT64 Size;\r
-} DTB_PCI_HOST_RANGE_RECORD;\r
-#pragma pack ()\r
-\r
-#define DTB_PCI_HOST_RANGE_RELOCATABLE  BIT31\r
-#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30\r
-#define DTB_PCI_HOST_RANGE_ALIASED      BIT29\r
-#define DTB_PCI_HOST_RANGE_MMIO32       BIT25\r
-#define DTB_PCI_HOST_RANGE_MMIO64       (BIT25 | BIT24)\r
-#define DTB_PCI_HOST_RANGE_IO           BIT24\r
-#define DTB_PCI_HOST_RANGE_TYPEMASK     (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)\r
-\r
-/**\r
-  Process the device tree node describing the generic PCI host controller.\r
-\r
-  param[in] DeviceTreeBase  Pointer to the device tree.\r
-\r
-  param[in] Node            Offset of the device tree node whose "compatible"\r
-                            property is "pci-host-ecam-generic".\r
-\r
-  param[in] RegProp         Pointer to the "reg" property of Node. The caller\r
-                            is responsible for ensuring that the size of the\r
-                            property is 4 UINT32 cells.\r
-\r
-  @retval EFI_SUCCESS         Parsing successful, properties parsed from Node\r
-                              have been stored in dynamic PCDs.\r
-\r
-  @retval EFI_PROTOCOL_ERROR  Parsing failed. PCDs are left unchanged.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessPciHost (\r
-  IN CONST VOID *DeviceTreeBase,\r
-  IN INT32      Node,\r
-  IN CONST VOID *RegProp\r
-  )\r
-{\r
-  UINT64     ConfigBase, ConfigSize;\r
-  CONST VOID *Prop;\r
-  INT32      Len;\r
-  UINT32     BusMin, BusMax;\r
-  UINT32     RecordIdx;\r
-  UINT64     IoBase, IoSize, IoTranslation;\r
-  UINT64     MmioBase, MmioSize, MmioTranslation;\r
-\r
-  //\r
-  // Fetch the ECAM window.\r
-  //\r
-  ConfigBase = fdt64_to_cpu (((CONST UINT64 *)RegProp)[0]);\r
-  ConfigSize = fdt64_to_cpu (((CONST UINT64 *)RegProp)[1]);\r
-\r
-  //\r
-  // Fetch the bus range (note: inclusive).\r
-  //\r
-  Prop = fdt_getprop (DeviceTreeBase, Node, "bus-range", &Len);\r
-  if (Prop == NULL || Len != 2 * sizeof(UINT32)) {\r
-    DEBUG ((EFI_D_ERROR, "%a: 'bus-range' not found or invalid\n",\r
-      __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-  BusMin = fdt32_to_cpu (((CONST UINT32 *)Prop)[0]);\r
-  BusMax = fdt32_to_cpu (((CONST UINT32 *)Prop)[1]);\r
-\r
-  //\r
-  // Sanity check: the config space must accommodate all 4K register bytes of\r
-  // all 8 functions of all 32 devices of all buses.\r
-  //\r
-  if (BusMax < BusMin || BusMax - BusMin == MAX_UINT32 ||\r
-      DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < BusMax - BusMin + 1) {\r
-    DEBUG ((EFI_D_ERROR, "%a: invalid 'bus-range' and/or 'reg'\n",\r
-      __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  //\r
-  // Iterate over "ranges".\r
-  //\r
-  Prop = fdt_getprop (DeviceTreeBase, Node, "ranges", &Len);\r
-  if (Prop == NULL || Len == 0 ||\r
-      Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  //\r
-  // IoBase, IoTranslation, MmioBase and MmioTranslation are initialized only\r
-  // in order to suppress '-Werror=maybe-uninitialized' warnings *incorrectly*\r
-  // emitted by some gcc versions.\r
-  //\r
-  IoBase = 0;\r
-  IoTranslation = 0;\r
-  MmioBase = 0;\r
-  MmioTranslation = 0;\r
-\r
-  //\r
-  // IoSize and MmioSize are initialized to zero because the logic below\r
-  // requires it.\r
-  //\r
-  IoSize = 0;\r
-  MmioSize = 0;\r
-  for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);\r
-       ++RecordIdx) {\r
-    CONST DTB_PCI_HOST_RANGE_RECORD *Record;\r
-\r
-    Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;\r
-    switch (fdt32_to_cpu (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {\r
-    case DTB_PCI_HOST_RANGE_IO:\r
-      IoBase = fdt64_to_cpu (Record->ChildBase);\r
-      IoSize = fdt64_to_cpu (Record->Size);\r
-      IoTranslation = fdt64_to_cpu (Record->CpuBase) - IoBase;\r
-      break;\r
-\r
-    case DTB_PCI_HOST_RANGE_MMIO32:\r
-      MmioBase = fdt64_to_cpu (Record->ChildBase);\r
-      MmioSize = fdt64_to_cpu (Record->Size);\r
-      MmioTranslation = fdt64_to_cpu (Record->CpuBase) - MmioBase;\r
-\r
-      if (MmioBase > MAX_UINT32 || MmioSize > MAX_UINT32 ||\r
-          MmioBase + MmioSize > SIZE_4GB) {\r
-        DEBUG ((EFI_D_ERROR, "%a: MMIO32 space invalid\n", __FUNCTION__));\r
-        return EFI_PROTOCOL_ERROR;\r
-      }\r
-\r
-      if (MmioTranslation != 0) {\r
-        DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "\r
-          "0x%Lx\n", __FUNCTION__, MmioTranslation));\r
-        return EFI_UNSUPPORTED;\r
-      }\r
-\r
-      break;\r
-    }\r
-  }\r
-  if (IoSize == 0 || MmioSize == 0) {\r
-    DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,\r
-      (IoSize == 0) ? "IO" : "MMIO32"));\r
-    return EFI_PROTOCOL_ERROR;\r
-  }\r
-\r
-  PcdSet64 (PcdPciExpressBaseAddress, ConfigBase);\r
-\r
-  PcdSet32 (PcdPciBusMin, BusMin);\r
-  PcdSet32 (PcdPciBusMax, BusMax);\r
-\r
-  PcdSet64 (PcdPciIoBase,        IoBase);\r
-  PcdSet64 (PcdPciIoSize,        IoSize);\r
-  PcdSet64 (PcdPciIoTranslation, IoTranslation);\r
-\r
-  PcdSet32 (PcdPciMmio32Base, (UINT32)MmioBase);\r
-  PcdSet32 (PcdPciMmio32Size, (UINT32)MmioSize);\r
-\r
-  PcdSetBool (PcdPciDisableBusEnumeration, FALSE);\r
-\r
-  DEBUG ((EFI_D_INFO, "%a: Config[0x%Lx+0x%Lx) Bus[0x%x..0x%x] "\r
-    "Io[0x%Lx+0x%Lx)@0x%Lx Mem[0x%Lx+0x%Lx)@0x%Lx\n", __FUNCTION__, ConfigBase,\r
-    ConfigSize, BusMin, BusMax, IoBase, IoSize, IoTranslation, MmioBase,\r
-    MmioSize, MmioTranslation));\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeVirtFdtDxe (\r
@@ -285,7 +91,6 @@ InitializeVirtFdtDxe (
   VOID                           *Hob;\r
   VOID                           *DeviceTreeBase;\r
   INT32                          Node, Prev;\r
-  INT32                          RtcNode;\r
   EFI_STATUS                     Status;\r
   CONST CHAR8                    *Type;\r
   INT32                          Len;\r
@@ -294,16 +99,6 @@ InitializeVirtFdtDxe (
   VIRTIO_TRANSPORT_DEVICE_PATH   *DevicePath;\r
   EFI_HANDLE                     Handle;\r
   UINT64                         RegBase;\r
-  UINT64                         DistBase, CpuBase, RedistBase;\r
-  CONST INTERRUPT_PROPERTY       *InterruptProp;\r
-  INT32                          SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;\r
-  CONST CHAR8                    *PsciMethod;\r
-  UINT64                         FwCfgSelectorAddress;\r
-  UINT64                         FwCfgSelectorSize;\r
-  UINT64                         FwCfgDataAddress;\r
-  UINT64                         FwCfgDataSize;\r
-  UINT64                         FwCfgDmaAddress;\r
-  UINT64                         FwCfgDmaSize;\r
 \r
   Hob = GetFirstGuidHob(&gFdtHobGuid);\r
   if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {\r
@@ -316,12 +111,8 @@ InitializeVirtFdtDxe (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
   DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase));\r
 \r
-  RtcNode = -1;\r
   //\r
   // Now enumerate the nodes and install peripherals that we are interested in,\r
   // i.e., GIC, RTC and virtio MMIO nodes\r
@@ -348,57 +139,9 @@ InitializeVirtFdtDxe (
     // TODO use #cells root properties instead\r
     //\r
     RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);\r
-    ASSERT ((RegProp != NULL) || (PropType == PropertyTypeTimer) ||\r
-      (PropType == PropertyTypePsci));\r
+    ASSERT (RegProp != NULL);\r
 \r
     switch (PropType) {\r
-    case PropertyTypePciHost:\r
-      ASSERT (Len == 2 * sizeof (UINT64));\r
-      Status = ProcessPciHost (DeviceTreeBase, Node, RegProp);\r
-      ASSERT_EFI_ERROR (Status);\r
-      break;\r
-\r
-    case PropertyTypeFwCfg:\r
-      ASSERT (Len == 2 * sizeof (UINT64));\r
-\r
-      FwCfgDataAddress     = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
-      FwCfgDataSize        = 8;\r
-      FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize;\r
-      FwCfgSelectorSize    = 2;\r
-\r
-      //\r
-      // The following ASSERT()s express\r
-      //\r
-      //   Address + Size - 1 <= MAX_UINTN\r
-      //\r
-      // for both registers, that is, that the last byte in each MMIO range is\r
-      // expressible as a MAX_UINTN. The form below is mathematically\r
-      // equivalent, and it also prevents any unsigned overflow before the\r
-      // comparison.\r
-      //\r
-      ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);\r
-      ASSERT (FwCfgDataAddress     <= MAX_UINTN - FwCfgDataSize     + 1);\r
-\r
-      PcdSet64 (PcdFwCfgSelectorAddress, FwCfgSelectorAddress);\r
-      PcdSet64 (PcdFwCfgDataAddress,     FwCfgDataAddress);\r
-\r
-      DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress,\r
-        FwCfgDataAddress));\r
-\r
-      if (fdt64_to_cpu (((UINT64 *)RegProp)[1]) >= 0x18) {\r
-        FwCfgDmaAddress = FwCfgDataAddress + 0x10;\r
-        FwCfgDmaSize    = 0x08;\r
-\r
-        //\r
-        // See explanation above.\r
-        //\r
-        ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1);\r
-\r
-        PcdSet64 (PcdFwCfgDmaAddress, FwCfgDmaAddress);\r
-        DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress));\r
-      }\r
-      break;\r
-\r
     case PropertyTypeVirtio:\r
       ASSERT (Len == 16);\r
       //\r
@@ -446,103 +189,6 @@ InitializeVirtFdtDxe (
       }\r
       break;\r
 \r
-    case PropertyTypeGic:\r
-      ASSERT (Len == 32);\r
-\r
-      DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
-      CpuBase  = fdt64_to_cpu (((UINT64 *)RegProp)[2]);\r
-      ASSERT (DistBase < MAX_UINT32);\r
-      ASSERT (CpuBase < MAX_UINT32);\r
-\r
-      PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);\r
-      PcdSet32 (PcdGicInterruptInterfaceBase, (UINT32)CpuBase);\r
-      PcdSet32 (PcdArmGicRevision, 2);\r
-\r
-      DEBUG ((EFI_D_INFO, "Found GIC @ 0x%Lx/0x%Lx\n", DistBase, CpuBase));\r
-      break;\r
-\r
-    case PropertyTypeGicV3:\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 (Len >= 32);\r
-\r
-      // RegProp[0..1] == { GICD base, GICD size }\r
-      DistBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
-      ASSERT (DistBase < MAX_UINT32);\r
-\r
-      // RegProp[2..3] == { GICR base, GICR size }\r
-      RedistBase = fdt64_to_cpu (((UINT64 *)RegProp)[2]);\r
-      ASSERT (RedistBase < MAX_UINT32);\r
-\r
-      PcdSet32 (PcdGicDistributorBase, (UINT32)DistBase);\r
-      PcdSet32 (PcdGicRedistributorsBase, (UINT32)RedistBase);\r
-      PcdSet32 (PcdArmGicRevision, 3);\r
-\r
-      DEBUG ((EFI_D_INFO, "Found GIC v3 (re)distributor @ 0x%Lx (0x%Lx)\n",\r
-        DistBase, RedistBase));\r
-      break;\r
-\r
-    case PropertyTypeRtc:\r
-      ASSERT (Len == 16);\r
-\r
-      RegBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
-      ASSERT (RegBase < MAX_UINT32);\r
-\r
-      PcdSet32 (PcdPL031RtcBase, (UINT32)RegBase);\r
-\r
-      DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase));\r
-      RtcNode = Node;\r
-      break;\r
-\r
-    case PropertyTypeTimer:\r
-      //\r
-      // - interrupts : Interrupt list for secure, non-secure, virtual and\r
-      //  hypervisor timers, in that order.\r
-      //\r
-      InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts", &Len);\r
-      ASSERT (Len == 36 || Len == 48);\r
-\r
-      SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number)\r
-                   + (InterruptProp[0].Type ? 16 : 0);\r
-      IntrNum = fdt32_to_cpu (InterruptProp[1].Number)\r
-                + (InterruptProp[1].Type ? 16 : 0);\r
-      VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number)\r
-                    + (InterruptProp[2].Type ? 16 : 0);\r
-      HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu (InterruptProp[3].Number)\r
-                                  + (InterruptProp[3].Type ? 16 : 0);\r
-\r
-      DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",\r
-        SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum));\r
-\r
-      PcdSet32 (PcdArmArchTimerSecIntrNum, SecIntrNum);\r
-      PcdSet32 (PcdArmArchTimerIntrNum, IntrNum);\r
-      PcdSet32 (PcdArmArchTimerVirtIntrNum, VirtIntrNum);\r
-      PcdSet32 (PcdArmArchTimerHypIntrNum, HypIntrNum);\r
-      break;\r
-\r
-    case PropertyTypePsci:\r
-      PsciMethod = fdt_getprop (DeviceTreeBase, Node, "method", &Len);\r
-\r
-      if (PsciMethod && AsciiStrnCmp (PsciMethod, "hvc", 3) == 0) {\r
-        PcdSet32 (PcdArmPsciMethod, 1);\r
-      } else if (PsciMethod && AsciiStrnCmp (PsciMethod, "smc", 3) == 0) {\r
-        PcdSet32 (PcdArmPsciMethod, 2);\r
-      } else {\r
-        DEBUG ((EFI_D_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,\r
-          PsciMethod));\r
-      }\r
-      break;\r
-\r
     case PropertyTypeXen:\r
       ASSERT (Len == 16);\r
 \r
@@ -568,16 +214,5 @@ InitializeVirtFdtDxe (
     }\r
   }\r
 \r
-  //\r
-  // UEFI takes ownership of the RTC hardware, and exposes its functionality\r
-  // through the UEFI Runtime Services GetTime, SetTime, etc. This means we\r
-  // need to disable it in the device tree to prevent the OS from attaching its\r
-  // device driver as well.\r
-  //\r
-  if ((RtcNode != -1) &&\r
-      fdt_setprop_string (DeviceTreeBase, RtcNode, "status",\r
-        "disabled") != 0) {\r
-    DEBUG ((EFI_D_WARN, "Failed to set PL031 status to 'disabled'\n"));\r
-  }\r
   return EFI_SUCCESS;\r
 }\r