]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg/PlatformPeiLib: discover the TPM base address from the DT
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 26 Feb 2020 19:05:08 +0000 (20:05 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 4 Mar 2020 08:48:09 +0000 (08:48 +0000)
Introduce a boolean PCD that tells us whether TPM support is enabled
in the build, and if it is, record the TPM base address in the existing
routine that traverses the device tree in the platform PEIM.

If a TPM is found, install the gOvmfTpmDiscoveredPpiGuid signalling PPI
that will unlock the dispatch of OvmfPkg's Tcg2ConfigPei. If TPM2
support is enabled in the build but no TPM2 device is found, install the
gPeiTpmInitializationDonePpiGuid PPI, which is normally installed by
Tcg2ConfigPei if no TPM2 is found, but in our case Tcg2ConfigPei will
never run so let's do it here instead.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
ArmVirtPkg/ArmVirtPkg.dec
ArmVirtPkg/ArmVirtQemu.dsc
ArmVirtPkg/ArmVirtQemuKernel.dsc
ArmVirtPkg/ArmVirtXen.dsc
ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c
ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf

index a019cc269d10ec3486f36907db4d78fde35160e4..08ddd68a863eb82778fa7a92b20ac1bff271f5e5 100644 (file)
 [Protocols]\r
   gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }\r
 \r
+[PcdsFeatureFlag]\r
+  #\r
+  # Feature Flag PCD that defines whether TPM2 support is enabled\r
+  #\r
+  gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|FALSE|BOOLEAN|0x00000004\r
+\r
 [PcdsFixedAtBuild, PcdsPatchableInModule]\r
   #\r
   # This is the physical address where the device tree is expected to be stored\r
index 7ae6702ac1f05c4fb134c6b8ef068341e32688eb..7d05415d0f93a473cc5a4e6903d0abdc04b6023e 100644 (file)
   gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0\r
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE\r
 \r
+  #\r
+  # TPM2 support\r
+  #\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0\r
+\r
 [PcdsDynamicHii]\r
   gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS\r
 \r
index 3b0f04967a4b244b495c79ee95c69f4db7d2bcc8..720f8fa78b3d72c32569276bb94df13cfce97ca5 100644 (file)
   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3\r
 \r
 [PcdsPatchableInModule.common]\r
+  # we need to provide a resolution for this PCD that supports PcdSet64()\r
+  # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,\r
+  # even though that call will be compiled out on this platform as it does\r
+  # not (and cannot) support the TPM2 driver stack\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0\r
+\r
   #\r
   # This will be overridden in the code\r
   #\r
index 1b42a9a813234967e15a9e10e593c3a7ef6b4beb..baa21f389947b352c9ea5db2d346e839856724d5 100644 (file)
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE\r
 \r
 [PcdsPatchableInModule.common]\r
+  # we need to provide a resolution for this PCD that supports PcdSet64()\r
+  # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,\r
+  # even though that call will be compiled out on this platform as it does\r
+  # not (and cannot) support the TPM2 driver stack\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0\r
+\r
   #\r
   # This will be overridden in the code\r
   #\r
index 0a1469550db09d2c9b9c239b894f4b688fa0b165..8b5b3dd5dc1cd93b9ba0cfa456a941de98e7ddef 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -31,14 +44,18 @@ PlatformPeim (
   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
@@ -58,18 +75,18 @@ PlatformPeim (
   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
@@ -93,10 +110,74 @@ PlatformPeim (
 \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
index 5428040f121da1e1941abaf0f752aff7d36c2945..3f97ef0805208525b1c24e9cfb67d8ce267f4b9c 100644 (file)
@@ -1,7 +1,7 @@
 #/** @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
@@ -11,7 +11,7 @@
   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