PlatformPeiLib.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /** @file
  2. *
  3. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
  4. * Copyright (c) 2014-2020, 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 <Library/PeiServicesLib.h>
  15. #include <libfdt.h>
  16. #include <Guid/EarlyPL011BaseAddress.h>
  17. #include <Guid/FdtHob.h>
  18. STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
  19. EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  20. &gOvmfTpmDiscoveredPpiGuid,
  21. NULL
  22. };
  23. STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {
  24. EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  25. &gPeiTpmInitializationDonePpiGuid,
  26. NULL
  27. };
  28. EFI_STATUS
  29. EFIAPI
  30. PlatformPeim (
  31. VOID
  32. )
  33. {
  34. VOID *Base;
  35. VOID *NewBase;
  36. UINTN FdtSize;
  37. UINTN FdtPages;
  38. UINT64 *FdtHobData;
  39. UINT64 *UartHobData;
  40. INT32 Node, Prev;
  41. INT32 Parent, Depth;
  42. CONST CHAR8 *Compatible;
  43. CONST CHAR8 *CompItem;
  44. CONST CHAR8 *NodeStatus;
  45. INT32 Len;
  46. INT32 RangesLen;
  47. INT32 StatusLen;
  48. CONST UINT64 *RegProp;
  49. CONST UINT32 *RangesProp;
  50. UINT64 UartBase;
  51. UINT64 TpmBase;
  52. EFI_STATUS Status;
  53. Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
  54. ASSERT (Base != NULL);
  55. ASSERT (fdt_check_header (Base) == 0);
  56. FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
  57. FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
  58. NewBase = AllocatePages (FdtPages);
  59. ASSERT (NewBase != NULL);
  60. fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
  61. FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
  62. ASSERT (FdtHobData != NULL);
  63. *FdtHobData = (UINTN)NewBase;
  64. UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
  65. ASSERT (UartHobData != NULL);
  66. *UartHobData = 0;
  67. TpmBase = 0;
  68. //
  69. // Set Parent to suppress incorrect compiler/analyzer warnings.
  70. //
  71. Parent = 0;
  72. for (Prev = Depth = 0; ; Prev = Node) {
  73. Node = fdt_next_node (Base, Prev, &Depth);
  74. if (Node < 0) {
  75. break;
  76. }
  77. if (Depth == 1) {
  78. Parent = Node;
  79. }
  80. Compatible = fdt_getprop (Base, Node, "compatible", &Len);
  81. //
  82. // Iterate over the NULL-separated items in the compatible string
  83. //
  84. for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
  85. CompItem += 1 + AsciiStrLen (CompItem))
  86. {
  87. if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
  88. NodeStatus = fdt_getprop (Base, Node, "status", &StatusLen);
  89. if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
  90. continue;
  91. }
  92. RegProp = fdt_getprop (Base, Node, "reg", &Len);
  93. ASSERT (Len == 16);
  94. UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
  95. DEBUG ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
  96. *UartHobData = UartBase;
  97. break;
  98. } else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
  99. (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))
  100. {
  101. RegProp = fdt_getprop (Base, Node, "reg", &Len);
  102. ASSERT (Len == 8 || Len == 16);
  103. if (Len == 8) {
  104. TpmBase = fdt32_to_cpu (RegProp[0]);
  105. } else if (Len == 16) {
  106. TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp));
  107. }
  108. if (Depth > 1) {
  109. //
  110. // QEMU/mach-virt may put the TPM on the platform bus, in which case
  111. // we have to take its 'ranges' property into account to translate the
  112. // MMIO address. This consists of a <child base, parent base, size>
  113. // tuple, where the child base and the size use the same number of
  114. // cells as the 'reg' property above, and the parent base uses 2 cells
  115. //
  116. RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen);
  117. ASSERT (RangesProp != NULL);
  118. //
  119. // a plain 'ranges' attribute without a value implies a 1:1 mapping
  120. //
  121. if (RangesLen != 0) {
  122. //
  123. // assume a single translated range with 2 cells for the parent base
  124. //
  125. if (RangesLen != Len + 2 * sizeof (UINT32)) {
  126. DEBUG ((
  127. DEBUG_WARN,
  128. "%a: 'ranges' property has unexpected size %d\n",
  129. __FUNCTION__,
  130. RangesLen
  131. ));
  132. break;
  133. }
  134. if (Len == 8) {
  135. TpmBase -= fdt32_to_cpu (RangesProp[0]);
  136. } else {
  137. TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
  138. }
  139. //
  140. // advance RangesProp to the parent bus address
  141. //
  142. RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
  143. TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
  144. }
  145. }
  146. break;
  147. }
  148. }
  149. }
  150. if (FeaturePcdGet (PcdTpm2SupportEnabled)) {
  151. if (TpmBase != 0) {
  152. DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase));
  153. Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);
  154. ASSERT_EFI_ERROR (Status);
  155. Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
  156. } else {
  157. Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);
  158. }
  159. ASSERT_EFI_ERROR (Status);
  160. }
  161. BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
  162. return EFI_SUCCESS;
  163. }