/** @file\r
*\r
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
-* Copyright (c) 2014, Linaro Limited. All rights reserved.\r
+* Copyright (c) 2014-2020, Linaro Limited. All rights reserved.\r
*\r
* SPDX-License-Identifier: BSD-2-Clause-Patent\r
*\r
#include <Library/DebugLib.h>\r
#include <Library/HobLib.h>\r
#include <Library/PcdLib.h>\r
+#include <Library/PeiServicesLib.h>\r
#include <libfdt.h>\r
\r
#include <Guid/EarlyPL011BaseAddress.h>\r
#include <Guid/FdtHob.h>\r
\r
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {\r
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+ &gOvmfTpmDiscoveredPpiGuid,\r
+ NULL\r
+};\r
+\r
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {\r
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+ &gPeiTpmInitializationDonePpiGuid,\r
+ NULL\r
+};\r
+\r
EFI_STATUS\r
EFIAPI\r
PlatformPeim (\r
UINT64 *FdtHobData;\r
UINT64 *UartHobData;\r
INT32 Node, Prev;\r
+ INT32 Parent, Depth;\r
CONST CHAR8 *Compatible;\r
CONST CHAR8 *CompItem;\r
CONST CHAR8 *NodeStatus;\r
INT32 Len;\r
+ INT32 RangesLen;\r
INT32 StatusLen;\r
CONST UINT64 *RegProp;\r
+ CONST UINT32 *RangesProp;\r
UINT64 UartBase;\r
-\r
+ UINT64 TpmBase;\r
+ EFI_STATUS Status;\r
\r
Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);\r
ASSERT (Base != NULL);\r
ASSERT (UartHobData != NULL);\r
*UartHobData = 0;\r
\r
- //\r
- // Look for a UART node\r
- //\r
- for (Prev = 0;; Prev = Node) {\r
- Node = fdt_next_node (Base, Prev, NULL);\r
+ TpmBase = 0;\r
+\r
+ for (Prev = Depth = 0;; Prev = Node) {\r
+ Node = fdt_next_node (Base, Prev, &Depth);\r
if (Node < 0) {\r
break;\r
}\r
\r
- //\r
- // Check for UART node\r
- //\r
+ if (Depth == 1) {\r
+ Parent = Node;\r
+ }\r
+\r
Compatible = fdt_getprop (Base, Node, "compatible", &Len);\r
\r
//\r
\r
*UartHobData = UartBase;\r
break;\r
+ } else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&\r
+ AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0) {\r
+\r
+ RegProp = fdt_getprop (Base, Node, "reg", &Len);\r
+ ASSERT (Len == 8 || Len == 16);\r
+ if (Len == 8) {\r
+ TpmBase = fdt32_to_cpu (RegProp[0]);\r
+ } else if (Len == 16) {\r
+ TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp));\r
+ }\r
+\r
+ if (Depth > 1) {\r
+ //\r
+ // QEMU/mach-virt may put the TPM on the platform bus, in which case\r
+ // we have to take its 'ranges' property into account to translate the\r
+ // MMIO address. This consists of a <child base, parent base, size>\r
+ // tuple, where the child base and the size use the same number of\r
+ // cells as the 'reg' property above, and the parent base uses 2 cells\r
+ //\r
+ RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen);\r
+ ASSERT (RangesProp != NULL);\r
+\r
+ //\r
+ // a plain 'ranges' attribute without a value implies a 1:1 mapping\r
+ //\r
+ if (RangesLen != 0) {\r
+ //\r
+ // assume a single translated range with 2 cells for the parent base\r
+ //\r
+ if (RangesLen != Len + 2 * sizeof (UINT32)) {\r
+ DEBUG ((DEBUG_WARN,\r
+ "%a: 'ranges' property has unexpected size %d\n",\r
+ __FUNCTION__, RangesLen));\r
+ break;\r
+ }\r
+\r
+ if (Len == 8) {\r
+ TpmBase -= fdt32_to_cpu (RangesProp[0]);\r
+ } else {\r
+ TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));\r
+ }\r
+\r
+ //\r
+ // advance RangesProp to the parent bus address\r
+ //\r
+ RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);\r
+ TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));\r
+ }\r
+ }\r
+ break;\r
}\r
}\r
}\r
\r
+ if (FeaturePcdGet (PcdTpm2SupportEnabled)) {\r
+ if (TpmBase != 0) {\r
+ DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase));\r
+\r
+ Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);\r
+ } else {\r
+ Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);\r
+ }\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));\r
\r
return EFI_SUCCESS;\r
#/** @file\r
#\r
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
-# Copyright (c) 2014, Linaro Limited. All rights reserved.\r
+# Copyright (c) 2014-2020, Linaro Limited. All rights reserved.\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
INF_VERSION = 0x00010005\r
BASE_NAME = PlatformPeiLib\r
FILE_GUID = 59C11815-F8DA-4F49-B4FB-EC1E41ED1F06\r
- MODULE_TYPE = SEC\r
+ MODULE_TYPE = BASE\r
VERSION_STRING = 1.0\r
LIBRARY_CLASS = PlatformPeiLib\r
\r
[Packages]\r
ArmPkg/ArmPkg.dec\r
ArmVirtPkg/ArmVirtPkg.dec\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
EmbeddedPkg/EmbeddedPkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ MdePkg/MdePkg.dec\r
+ OvmfPkg/OvmfPkg.dec\r
+ SecurityPkg/SecurityPkg.dec\r
+\r
+[FeaturePcd]\r
+ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled\r
\r
[LibraryClasses]\r
DebugLib\r
HobLib\r
FdtLib\r
PcdLib\r
+ PeiServicesLib\r
\r
[FixedPcd]\r
gArmTokenSpaceGuid.PcdFvSize\r
[Pcd]\r
gArmTokenSpaceGuid.PcdFvBaseAddress\r
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress\r
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_PRODUCES\r
+\r
+[Ppis]\r
+ gOvmfTpmDiscoveredPpiGuid ## SOMETIMES_PRODUCES\r
+ gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES\r
\r
[Guids]\r
gEarlyPL011BaseAddressGuid\r