diff options
Diffstat (limited to 'ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c')
-rw-r--r-- | ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c new file mode 100644 index 0000000000..bdf2b57fcb --- /dev/null +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c @@ -0,0 +1,102 @@ +/** @file
+*
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+* Copyright (c) 2014, Linaro Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <libfdt.h>
+
+#include <Guid/EarlyPL011BaseAddress.h>
+#include <Guid/FdtHob.h>
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+ VOID
+ )
+{
+ VOID *Base;
+ VOID *NewBase;
+ UINTN FdtSize;
+ UINTN FdtPages;
+ UINT64 *FdtHobData;
+ UINT64 *UartHobData;
+ INT32 Node, Prev;
+ CONST CHAR8 *Compatible;
+ CONST CHAR8 *CompItem;
+ INT32 Len;
+ CONST UINT64 *RegProp;
+ UINT64 UartBase;
+
+
+ Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+ ASSERT (Base != NULL);
+ ASSERT (fdt_check_header (Base) == 0);
+
+ FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
+ FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
+ NewBase = AllocatePages (FdtPages);
+ ASSERT (NewBase != NULL);
+ fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
+
+ FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
+ ASSERT (FdtHobData != NULL);
+ *FdtHobData = (UINTN)NewBase;
+
+ UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
+ ASSERT (UartHobData != NULL);
+ *UartHobData = 0;
+
+ //
+ // Look for a UART node
+ //
+ for (Prev = 0;; Prev = Node) {
+ Node = fdt_next_node (Base, Prev, NULL);
+ if (Node < 0) {
+ break;
+ }
+
+ //
+ // Check for UART node
+ //
+ Compatible = fdt_getprop (Base, Node, "compatible", &Len);
+
+ //
+ // Iterate over the NULL-separated items in the compatible string
+ //
+ for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
+ CompItem += 1 + AsciiStrLen (CompItem)) {
+
+ if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
+ RegProp = fdt_getprop (Base, Node, "reg", &Len);
+ ASSERT (Len == 16);
+
+ UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+
+ DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
+
+ *UartHobData = UartBase;
+ break;
+ }
+ }
+ }
+
+ BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
+
+ return EFI_SUCCESS;
+}
|