Home | History | Annotate | Download | only in PlatformPeiLib
      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