123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /** @file
- *
- * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
- * Copyright (c) 2014-2020, Linaro Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-2-Clause-Patent
- *
- **/
- #include <PiPei.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/DebugLib.h>
- #include <Library/HobLib.h>
- #include <Library/PcdLib.h>
- #include <Library/PeiServicesLib.h>
- #include <libfdt.h>
- #include <Guid/EarlyPL011BaseAddress.h>
- #include <Guid/FdtHob.h>
- STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gOvmfTpmDiscoveredPpiGuid,
- NULL
- };
- STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gPeiTpmInitializationDonePpiGuid,
- NULL
- };
- EFI_STATUS
- EFIAPI
- PlatformPeim (
- VOID
- )
- {
- VOID *Base;
- VOID *NewBase;
- UINTN FdtSize;
- UINTN FdtPages;
- UINT64 *FdtHobData;
- UINT64 *UartHobData;
- INT32 Node, Prev;
- INT32 Parent, Depth;
- CONST CHAR8 *Compatible;
- CONST CHAR8 *CompItem;
- CONST CHAR8 *NodeStatus;
- INT32 Len;
- INT32 RangesLen;
- INT32 StatusLen;
- CONST UINT64 *RegProp;
- CONST UINT32 *RangesProp;
- UINT64 UartBase;
- UINT64 TpmBase;
- EFI_STATUS Status;
- 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;
- TpmBase = 0;
- //
- // Set Parent to suppress incorrect compiler/analyzer warnings.
- //
- Parent = 0;
- for (Prev = Depth = 0; ; Prev = Node) {
- Node = fdt_next_node (Base, Prev, &Depth);
- if (Node < 0) {
- break;
- }
- if (Depth == 1) {
- Parent = 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 ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
- *UartHobData = UartBase;
- break;
- } else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
- (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))
- {
- RegProp = fdt_getprop (Base, Node, "reg", &Len);
- ASSERT (Len == 8 || Len == 16);
- if (Len == 8) {
- TpmBase = fdt32_to_cpu (RegProp[0]);
- } else if (Len == 16) {
- TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp));
- }
- if (Depth > 1) {
- //
- // QEMU/mach-virt may put the TPM on the platform bus, in which case
- // we have to take its 'ranges' property into account to translate the
- // MMIO address. This consists of a <child base, parent base, size>
- // tuple, where the child base and the size use the same number of
- // cells as the 'reg' property above, and the parent base uses 2 cells
- //
- RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen);
- ASSERT (RangesProp != NULL);
- //
- // a plain 'ranges' attribute without a value implies a 1:1 mapping
- //
- if (RangesLen != 0) {
- //
- // assume a single translated range with 2 cells for the parent base
- //
- if (RangesLen != Len + 2 * sizeof (UINT32)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: 'ranges' property has unexpected size %d\n",
- __FUNCTION__,
- RangesLen
- ));
- break;
- }
- if (Len == 8) {
- TpmBase -= fdt32_to_cpu (RangesProp[0]);
- } else {
- TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
- }
- //
- // advance RangesProp to the parent bus address
- //
- RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
- TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
- }
- }
- break;
- }
- }
- }
- if (FeaturePcdGet (PcdTpm2SupportEnabled)) {
- if (TpmBase != 0) {
- DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase));
- Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);
- ASSERT_EFI_ERROR (Status);
- Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
- } else {
- Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);
- }
- ASSERT_EFI_ERROR (Status);
- }
- BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
- return EFI_SUCCESS;
- }
|