]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
ArmPlatformPkg/ArmVirtualizationPkg: add ArmVirtualizationPlatformLib library
[mirror_edk2.git] / ArmPlatformPkg / ArmVirtualizationPkg / Library / ArmVirtualizationPlatformLib / Virt.c
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
new file mode 100644 (file)
index 0000000..7961b05
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2014, Linaro Limited. All rights reserved.\r
+*  Copyright (c) 2014, Red Hat, Inc.\r
+*\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
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/ArmPlatformLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <ArmPlatform.h>\r
+#include <libfdt.h>\r
+#include <Pi/PiBootMode.h>\r
+#include <Uefi/UefiBaseType.h>\r
+#include <Uefi/UefiMultiPhase.h>\r
+#include <Pi/PiHob.h>\r
+#include <Library/HobLib.h>\r
+#include <Guid/EarlyPL011BaseAddress.h>\r
+\r
+/**\r
+  Return the current Boot Mode\r
+\r
+  This function returns the boot reason on the platform\r
+\r
+  @return   Return the current Boot Mode of the platform\r
+\r
+**/\r
+EFI_BOOT_MODE\r
+ArmPlatformGetBootMode (\r
+  VOID\r
+  )\r
+{\r
+  return BOOT_WITH_FULL_CONFIGURATION;\r
+}\r
+\r
+/**\r
+  This function is called by PrePeiCore, in the SEC phase.\r
+**/\r
+RETURN_STATUS\r
+ArmPlatformInitialize (\r
+  IN  UINTN                     MpId\r
+  )\r
+{\r
+  //\r
+  // We are relying on ArmPlatformInitializeSystemMemory () being called from\r
+  // InitializeMemory (), which only occurs if the following feature is disabled\r
+  //\r
+  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Initialize the system (or sometimes called permanent) memory\r
+\r
+  This memory is generally represented by the DRAM.\r
+\r
+  This function is called from InitializeMemory() in MemoryInitPeim, in the PEI\r
+  phase.\r
+**/\r
+VOID\r
+ArmPlatformInitializeSystemMemory (\r
+  VOID\r
+  )\r
+{\r
+  VOID         *DeviceTreeBase;\r
+  INT32        Node, Prev;\r
+  UINT64       NewBase;\r
+  UINT64       NewSize;\r
+  BOOLEAN      HaveMemory, HaveUART;\r
+  UINT64       *HobData;\r
+  CONST CHAR8  *Type;\r
+  CONST CHAR8  *Compatible;\r
+  CONST CHAR8  *CompItem;\r
+  INT32        Len;\r
+  CONST UINT64 *RegProp;\r
+  UINT64       UartBase;\r
+\r
+  NewBase = 0;\r
+  NewSize = 0;\r
+\r
+  HaveMemory = FALSE;\r
+  HaveUART   = FALSE;\r
+\r
+  HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *HobData);\r
+  ASSERT (HobData != NULL);\r
+  *HobData = 0;\r
+\r
+  DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);\r
+  ASSERT (DeviceTreeBase != NULL);\r
+\r
+  //\r
+  // Make sure we have a valid device tree blob\r
+  //\r
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);\r
+\r
+  //\r
+  // Look for a memory node\r
+  //\r
+  for (Prev = 0; !(HaveMemory && HaveUART); Prev = Node) {\r
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);\r
+    if (Node < 0) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Check for memory node\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 != 0 && Len == (2 * sizeof (UINT64))) {\r
+\r
+        NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));\r
+        NewSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));\r
+\r
+        //\r
+        // Make sure the start of DRAM matches our expectation\r
+        //\r
+        ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);\r
+        PcdSet64 (PcdSystemMemorySize, NewSize);\r
+\r
+        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",\r
+               __FUNCTION__, NewBase, NewBase + NewSize - 1));\r
+      } else {\r
+        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",\r
+               __FUNCTION__));\r
+      }\r
+      HaveMemory = TRUE;\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Check for UART node\r
+    //\r
+    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);\r
+\r
+    //\r
+    // Iterate over the NULL-separated items in the compatible string\r
+    //\r
+    for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;\r
+      CompItem += 1 + AsciiStrLen (CompItem)) {\r
+\r
+      if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {\r
+        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);\r
+        ASSERT (Len == 16);\r
+\r
+        UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));\r
+\r
+        DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));\r
+\r
+        *HobData = UartBase;\r
+\r
+        HaveUART = TRUE;\r
+        continue;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // We need to make sure that the machine we are running on has at least\r
+  // 128 MB of memory configured, and is currently executing this binary from\r
+  // NOR flash. This prevents a device tree image in DRAM from getting\r
+  // clobbered when our caller installs permanent PEI RAM, before we have a\r
+  // chance of marking its location as reserved or copy it to a freshly\r
+  // allocated block in the permanent PEI RAM in the platform PEIM.\r
+  //\r
+  ASSERT (NewSize >= SIZE_128MB);\r
+  ASSERT (\r
+    (((UINT64)PcdGet32 (PcdFdBaseAddress) +\r
+      (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||\r
+    ((UINT64)PcdGet32 (PcdFdBaseAddress) >= (NewBase + NewSize)));\r
+}\r
+\r
+VOID\r
+ArmPlatformGetPlatformPpiList (\r
+  OUT UINTN                   *PpiListSize,\r
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList\r
+  )\r
+{\r
+  *PpiListSize = 0;\r
+  *PpiList = NULL;\r
+}\r