ArmVirtPkg/HighMemDxe: move to FDT client protocol
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 15 Sep 2016 13:23:11 +0000 (14:23 +0100)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 15 Sep 2016 14:39:34 +0000 (15:39 +0100)
Use the FDT client protocol rather than parsing the DT directly using
fdtlib. While we're at it, update the code so it deals correctly with
memory nodes that describe multiple disjoint regions in their "reg"
properties, and make the code work with #address-cells/#size-cells
properties of <1> as well as <2>.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
ArmVirtPkg/HighMemDxe/HighMemDxe.c
ArmVirtPkg/HighMemDxe/HighMemDxe.inf

index 4d56e62..22f7382 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 *  High memory node enumeration DXE driver for ARM Virtual Machines\r
 *\r
-*  Copyright (c) 2015, Linaro Ltd. All rights reserved.\r
+*  Copyright (c) 2015-2016, Linaro Ltd. 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
 \r
 #include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/HobLib.h>\r
-#include <libfdt.h>\r
 #include <Library/DxeServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Protocol/FdtClient.h>\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -29,76 +29,64 @@ InitializeHighMemDxe (
   IN EFI_SYSTEM_TABLE     *SystemTable\r
   )\r
 {\r
-  VOID             *Hob;\r
-  VOID             *DeviceTreeBase;\r
-  INT32            Node, Prev;\r
-  EFI_STATUS       Status;\r
-  CONST CHAR8      *Type;\r
-  INT32            Len;\r
-  CONST VOID       *RegProp;\r
-  UINT64           CurBase;\r
-  UINT64           CurSize;\r
-\r
-  Hob = GetFirstGuidHob(&gFdtHobGuid);\r
-  if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  DeviceTreeBase = (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);\r
-\r
-  if (fdt_check_header (DeviceTreeBase) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "%a: No DTB found @ 0x%p\n", __FUNCTION__,\r
-      DeviceTreeBase));\r
-    return EFI_NOT_FOUND;\r
-  }\r
+  FDT_CLIENT_PROTOCOL   *FdtClient;\r
+  EFI_STATUS            Status, FindNodeStatus;\r
+  INT32                 Node;\r
+  CONST UINT32          *Reg;\r
+  UINT32                RegSize;\r
+  UINTN                 AddressCells, SizeCells;\r
+  UINT64                CurBase;\r
+  UINT64                CurSize;\r
 \r
-  DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, DeviceTreeBase));\r
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
+                  (VOID **)&FdtClient);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
-  // Check for memory node and add the memory spaces expect the lowest one\r
+  // Check for memory node and add the memory spaces except the lowest one\r
   //\r
-  for (Prev = 0;; Prev = Node) {\r
-    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);\r
-    if (Node < 0) {\r
-      break;\r
-    }\r
-\r
-    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);\r
-    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {\r
-      //\r
-      // Get the 'reg' property of this node. For now, we will assume\r
-      // two 8 byte quantities for base and size, respectively.\r
-      //\r
-      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);\r
-      if (RegProp != NULL && Len == (2 * sizeof (UINT64))) {\r
+  for (FindNodeStatus = FdtClient->FindMemoryNodeReg (FdtClient, &Node,\r
+                                     (CONST VOID **) &Reg, &AddressCells,\r
+                                     &SizeCells, &RegSize);\r
+       !EFI_ERROR (FindNodeStatus);\r
+       FindNodeStatus = FdtClient->FindNextMemoryNodeReg (FdtClient, Node,\r
+                                     &Node, (CONST VOID **) &Reg, &AddressCells,\r
+                                     &SizeCells, &RegSize)) {\r
+    ASSERT (AddressCells <= 2);\r
+    ASSERT (SizeCells <= 2);\r
 \r
-        CurBase = fdt64_to_cpu (((UINT64 *)RegProp)[0]);\r
-        CurSize = fdt64_to_cpu (((UINT64 *)RegProp)[1]);\r
+    while (RegSize > 0) {\r
+      CurBase = SwapBytes32 (*Reg++);\r
+      if (AddressCells > 1) {\r
+        CurBase = (CurBase << 32) | SwapBytes32 (*Reg++);\r
+      }\r
+      CurSize = SwapBytes32 (*Reg++);\r
+      if (SizeCells > 1) {\r
+        CurSize = (CurSize << 32) | SwapBytes32 (*Reg++);\r
+      }\r
+      RegSize -= (AddressCells + SizeCells) * sizeof (UINT32);\r
 \r
-        if (PcdGet64 (PcdSystemMemoryBase) != CurBase) {\r
-          Status = gDS->AddMemorySpace (\r
-                          EfiGcdMemoryTypeSystemMemory,\r
-                          CurBase, CurSize,\r
-                          EFI_MEMORY_WB);\r
+      if (PcdGet64 (PcdSystemMemoryBase) != CurBase) {\r
+        Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, CurBase,\r
+                        CurSize, EFI_MEMORY_WB);\r
 \r
-          if (EFI_ERROR (Status)) {\r
-            DEBUG ((EFI_D_ERROR,\r
-              "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",\r
-              __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));\r
-            continue;\r
-          }\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR,\r
+            "%a: Failed to add System RAM @ 0x%lx - 0x%lx (%r)\n",\r
+            __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));\r
+          continue;\r
+        }\r
 \r
-          Status = gDS->SetMemorySpaceAttributes (\r
-                          CurBase, CurSize,\r
-                          EFI_MEMORY_WB);\r
+        Status = gDS->SetMemorySpaceAttributes (CurBase, CurSize,\r
+                        EFI_MEMORY_WB);\r
 \r
-          if (EFI_ERROR (Status)) {\r
-            DEBUG ((EFI_D_ERROR,\r
-              "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",\r
-              __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));\r
-          } else {\r
-            DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n",\r
-              __FUNCTION__, CurBase, CurBase + CurSize - 1));\r
-          }\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR,\r
+            "%a: Failed to set System RAM @ 0x%lx - 0x%lx attribute (%r)\n",\r
+            __FUNCTION__, CurBase, CurBase + CurSize - 1, Status));\r
+        } else {\r
+          DEBUG ((EFI_D_INFO, "%a: Add System RAM @ 0x%lx - 0x%lx\n",\r
+            __FUNCTION__, CurBase, CurBase + CurSize - 1));\r
         }\r
       }\r
     }\r
index ae632a8..3661cfd 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  High memory node enumeration DXE driver for ARM Virtual Machines\r
 #\r
-#  Copyright (c) 2015, Linaro Ltd. All rights reserved.\r
+#  Copyright (c) 2015-2016, Linaro Ltd. 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
   MdePkg/MdePkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
   ArmPkg/ArmPkg.dec\r
-  ArmPlatformPkg/ArmPlatformPkg.dec\r
   ArmVirtPkg/ArmVirtPkg.dec\r
-  EmbeddedPkg/EmbeddedPkg.dec\r
 \r
 [LibraryClasses]\r
   BaseLib\r
+  DebugLib\r
+  DxeServicesTableLib\r
   PcdLib\r
+  UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
-  FdtLib\r
-  HobLib\r
-  DxeServicesTableLib\r
 \r
-[Guids]\r
-  gFdtHobGuid\r
+[Protocols]\r
+  gFdtClientProtocolGuid                  ## CONSUMES\r
 \r
 [Pcd]\r
   gArmTokenSpaceGuid.PcdSystemMemoryBase\r
 \r
 [Depex]\r
-  gEfiCpuArchProtocolGuid\r
+  gEfiCpuArchProtocolGuid AND gFdtClientProtocolGuid\r