PlatformPeiLib.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /** @file
  2. *
  3. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
  4. * Copyright (c) 2014, Linaro Limited. All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause-Patent
  7. *
  8. **/
  9. #include <PiPei.h>
  10. #include <Library/MemoryAllocationLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/HobLib.h>
  13. #include <Library/PcdLib.h>
  14. #include <libfdt.h>
  15. #include <Guid/EarlyPL011BaseAddress.h>
  16. #include <Guid/FdtHob.h>
  17. EFI_STATUS
  18. EFIAPI
  19. PlatformPeim (
  20. VOID
  21. )
  22. {
  23. VOID *Base;
  24. VOID *NewBase;
  25. UINTN FdtSize;
  26. UINTN FdtPages;
  27. UINT64 *FdtHobData;
  28. UINT64 *UartHobData;
  29. INT32 Node, Prev;
  30. CONST CHAR8 *Compatible;
  31. CONST CHAR8 *CompItem;
  32. CONST CHAR8 *NodeStatus;
  33. INT32 Len;
  34. INT32 StatusLen;
  35. CONST UINT64 *RegProp;
  36. UINT64 UartBase;
  37. Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
  38. ASSERT (Base != NULL);
  39. ASSERT (fdt_check_header (Base) == 0);
  40. FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
  41. FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
  42. NewBase = AllocatePages (FdtPages);
  43. ASSERT (NewBase != NULL);
  44. fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
  45. FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
  46. ASSERT (FdtHobData != NULL);
  47. *FdtHobData = (UINTN)NewBase;
  48. UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
  49. ASSERT (UartHobData != NULL);
  50. *UartHobData = 0;
  51. //
  52. // Look for a UART node
  53. //
  54. for (Prev = 0;; Prev = Node) {
  55. Node = fdt_next_node (Base, Prev, NULL);
  56. if (Node < 0) {
  57. break;
  58. }
  59. //
  60. // Check for UART node
  61. //
  62. Compatible = fdt_getprop (Base, Node, "compatible", &Len);
  63. //
  64. // Iterate over the NULL-separated items in the compatible string
  65. //
  66. for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
  67. CompItem += 1 + AsciiStrLen (CompItem)) {
  68. if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
  69. NodeStatus = fdt_getprop (Base, Node, "status", &StatusLen);
  70. if (NodeStatus != NULL && AsciiStrCmp (NodeStatus, "okay") != 0) {
  71. continue;
  72. }
  73. RegProp = fdt_getprop (Base, Node, "reg", &Len);
  74. ASSERT (Len == 16);
  75. UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
  76. DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
  77. *UartHobData = UartBase;
  78. break;
  79. }
  80. }
  81. }
  82. BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
  83. return EFI_SUCCESS;
  84. }