1 /** @file 2 * 3 * Copyright (c) 2011-2014, ARM Limited. All rights reserved. 4 * Copyright (c) 2014, Linaro Limited. All rights reserved. 5 * 6 * This program and the accompanying materials 7 * are licensed and made available under the terms and conditions of the BSD License 8 * which accompanies this distribution. The full text of the license may be found at 9 * http://opensource.org/licenses/bsd-license.php 10 * 11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 * 14 **/ 15 16 #include <PiPei.h> 17 18 #include <Library/MemoryAllocationLib.h> 19 #include <Library/DebugLib.h> 20 #include <Library/HobLib.h> 21 #include <Library/PcdLib.h> 22 #include <libfdt.h> 23 24 #include <Guid/EarlyPL011BaseAddress.h> 25 #include <Guid/FdtHob.h> 26 27 EFI_STATUS 28 EFIAPI 29 PlatformPeim ( 30 VOID 31 ) 32 { 33 VOID *Base; 34 VOID *NewBase; 35 UINTN FdtSize; 36 UINTN FdtPages; 37 UINT64 *FdtHobData; 38 UINT64 *UartHobData; 39 INT32 Node, Prev; 40 CONST CHAR8 *Compatible; 41 CONST CHAR8 *CompItem; 42 INT32 Len; 43 CONST UINT64 *RegProp; 44 UINT64 UartBase; 45 46 47 Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); 48 ASSERT (Base != NULL); 49 ASSERT (fdt_check_header (Base) == 0); 50 51 FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding); 52 FdtPages = EFI_SIZE_TO_PAGES (FdtSize); 53 NewBase = AllocatePages (FdtPages); 54 ASSERT (NewBase != NULL); 55 fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages)); 56 57 FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData); 58 ASSERT (FdtHobData != NULL); 59 *FdtHobData = (UINTN)NewBase; 60 61 UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData); 62 ASSERT (UartHobData != NULL); 63 *UartHobData = 0; 64 65 // 66 // Look for a UART node 67 // 68 for (Prev = 0;; Prev = Node) { 69 Node = fdt_next_node (Base, Prev, NULL); 70 if (Node < 0) { 71 break; 72 } 73 74 // 75 // Check for UART node 76 // 77 Compatible = fdt_getprop (Base, Node, "compatible", &Len); 78 79 // 80 // Iterate over the NULL-separated items in the compatible string 81 // 82 for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len; 83 CompItem += 1 + AsciiStrLen (CompItem)) { 84 85 if (AsciiStrCmp (CompItem, "arm,pl011") == 0) { 86 RegProp = fdt_getprop (Base, Node, "reg", &Len); 87 ASSERT (Len == 16); 88 89 UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); 90 91 DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase)); 92 93 *UartHobData = UartBase; 94 break; 95 } 96 } 97 } 98 99 BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize)); 100 101 return EFI_SUCCESS; 102 } 103