/** @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 #include #include #include #include #include #include #include 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; CONST CHAR8 *NodeStatus; INT32 Len; INT32 StatusLen; 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) { NodeStatus = fdt_getprop (Base, Node, "status", &StatusLen); if (NodeStatus != NULL && AsciiStrCmp (NodeStatus, "okay") != 0) { continue; } 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; }