]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
SecurityPkg: TcgSmm: Handle invalid parameter in MOR SMI handler
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Smm / Tcg2Smm.c
index 3ca6958a6eb313dc9616600c1dc3a2b6f79bf248..4a1a293bfcd3dda32f46c7c61e1772db3dd69a75 100644 (file)
@@ -9,69 +9,19 @@
 \r
   PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.\r
 \r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution.  The full text of the license may be found at \r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
 #include "Tcg2Smm.h"\r
 \r
-typedef enum {\r
-  PtpInterfaceTis,\r
-  PtpInterfaceFifo,\r
-  PtpInterfaceCrb,\r
-  PtpInterfaceMax,\r
-} PTP_INTERFACE_TYPE;\r
-\r
-/**\r
-  Return PTP interface type.\r
-\r
-  @param[in] Register                Pointer to PTP register.\r
-\r
-  @return PTP interface type.\r
-**/\r
-PTP_INTERFACE_TYPE\r
-GetPtpInterface (\r
-  IN VOID *Register\r
-  )\r
-{\r
-  PTP_CRB_INTERFACE_IDENTIFIER  InterfaceId;\r
-  PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;\r
-\r
-  //\r
-  // Check interface id\r
-  //\r
-  InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
-  InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);\r
-\r
-  if (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) {\r
-    return PtpInterfaceTis;\r
-  }\r
-\r
-  if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) &&\r
-      (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_CRB) &&\r
-      (InterfaceId.Bits.CapCRB != 0)) {\r
-    return PtpInterfaceCrb;\r
-  }\r
-\r
-  if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO) &&\r
-      (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO) &&\r
-      (InterfaceId.Bits.CapFIFO != 0) &&\r
-      (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP)) {\r
-    return PtpInterfaceFifo;\r
-  }\r
-\r
-  //\r
-  // No Ptp interface available\r
-  //\r
-  return PtpInterfaceMax;\r
-}\r
 \r
 EFI_TPM2_ACPI_TABLE  mTpm2AcpiTemplate = {\r
   {\r
@@ -83,7 +33,8 @@ EFI_TPM2_ACPI_TABLE  mTpm2AcpiTemplate = {
     // These fields should be filled in in production\r
     //\r
   },\r
-  0, // Flags\r
+  0, // BIT0~15:  PlatformClass\r
+     // BIT16~31: Reserved\r
   0, // Control Area\r
   EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod\r
 };\r
@@ -131,7 +82,7 @@ PhysicalPresenceCallback (
     mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest;\r
     mTcgNvs->PhysicalPresence.Response = Response;\r
     return EFI_SUCCESS;\r
-  } else if ((mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) \r
+  } else if ((mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)\r
           || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) {\r
 \r
     OperationRequest = mTcgNvs->PhysicalPresence.Request;\r
@@ -202,6 +153,10 @@ MemoryClearCallback (
       return EFI_SUCCESS;\r
     }\r
     MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;\r
+  } else {\r
+    mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
+    DEBUG ((EFI_D_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", mTcgNvs->MemoryClear.Parameter));\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   DataSize = sizeof (UINT8);\r
@@ -212,7 +167,7 @@ MemoryClearCallback (
                            DataSize,\r
                            &MorControl\r
                            );\r
-  if (EFI_ERROR (Status)) { \r
+  if (EFI_ERROR (Status)) {\r
     mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
     DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));\r
   }\r
@@ -250,7 +205,7 @@ AssignOpRegion (
   for (OpRegion  = (AML_OP_REGION_32_8 *) (Table + 1);\r
        OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);\r
        OpRegion  = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {\r
-    if ((OpRegion->OpRegionOp  == AML_EXT_REGION_OP) && \r
+    if ((OpRegion->OpRegionOp  == AML_EXT_REGION_OP) &&\r
         (OpRegion->NameString  == Name) &&\r
         (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&\r
         (OpRegion->BytePrefix  == AML_BYTE_PREFIX)) {\r
@@ -268,7 +223,7 @@ AssignOpRegion (
 }\r
 \r
 /**\r
-  Patch version string of Physical Presence interface supported by platform. The initial string tag in TPM \r
+  Patch version string of Physical Presence interface supported by platform. The initial string tag in TPM\r
 ACPI table is "$PV".\r
 \r
   @param[in, out] Table          The TPM item in ACPI table.\r
@@ -302,6 +257,254 @@ UpdatePPVersion (
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Patch interrupt resources returned by TPM _PRS. ResourceTemplate to patch is determined by input\r
+  interrupt buffer size. BufferSize, PkgLength and interrupt descirptor in ByteList need to be patched\r
+\r
+  @param[in, out] Table            The TPM item in ACPI table.\r
+  @param[in]      IrqBuffer        Input new IRQ buffer.\r
+  @param[in]      IrqBuffserSize   Input new IRQ buffer size.\r
+  @param[out]     IsShortFormPkgLength   If _PRS returns Short length Package(ACPI spec 20.2.4).\r
+\r
+  @return                          patch status.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdatePossibleResource (\r
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER    *Table,\r
+  IN      UINT32                         *IrqBuffer,\r
+  IN      UINT32                         IrqBuffserSize,\r
+  OUT     BOOLEAN                        *IsShortFormPkgLength\r
+  )\r
+{\r
+  UINT8       *DataPtr;\r
+  UINT8       *DataEndPtr;\r
+  UINT32      NewPkgLength;\r
+  UINT32      OrignalPkgLength;\r
+\r
+  NewPkgLength     = 0;\r
+  OrignalPkgLength = 0;\r
+  DataEndPtr       = NULL;\r
+\r
+  //\r
+  // Follow ACPI spec\r
+  //           6.4.3   Extend Interrupt Descriptor.\r
+  //           19.3.3 ASL Resource Template\r
+  //           20      AML specification\r
+  // to patch TPM ACPI object _PRS returned ResourceTemplate() containing 2 resource descriptors and an auto appended End Tag\r
+  //\r
+  //  AML data is organized by following rule.\r
+  //  Code need to patch BufferSize and PkgLength and interrupt descirptor in ByteList\r
+  //\r
+  // =============  Buffer ====================\r
+  //           DefBuffer := BufferOp PkgLength BufferSize ByteList\r
+  //            BufferOp := 0x11\r
+  //\r
+  // ==============PkgLength==================\r
+  //          PkgLength := PkgLeadByte |\r
+  //                              <PkgLeadByte ByteData> |\r
+  //                              <PkgLeadByte ByteData ByteData> |\r
+  //                              <PkgLeadByte ByteData ByteData ByteData>\r
+  //\r
+  //       PkgLeadByte := <bit 7-6: ByteData count that follows (0-3)>\r
+  //                               <bit 5-4: Only used if PkgLength <= 63 >\r
+  //                               <bit 3-0: Least significant package length nybble>\r
+  //\r
+  //==============BufferSize==================\r
+  //        BufferSize := Integar\r
+  //           Integar := ByteConst|WordConst|DwordConst....\r
+  //\r
+  //           ByteConst := BytePrefix ByteData\r
+  //\r
+  //==============ByteList===================\r
+  //          ByteList := ByteData ByteList\r
+  //\r
+  //=========================================\r
+\r
+  //\r
+  // 1. Check TPM_PRS_RESS with PkgLength <=63 can hold the input interrupt number buffer for patching\r
+  //\r
+  for (DataPtr  = (UINT8 *)(Table + 1);\r
+       DataPtr < (UINT8 *) ((UINT8 *) Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));\r
+       DataPtr += 1) {\r
+    if (CompareMem(DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) == 0) {\r
+      //\r
+      // Jump over object name & BufferOp\r
+      //\r
+      DataPtr += TPM_PRS_RES_NAME_SIZE + 1;\r
+\r
+      if ((*DataPtr & (BIT7|BIT6)) == 0) {\r
+        OrignalPkgLength = (UINT32)*DataPtr;\r
+        DataEndPtr       = DataPtr + OrignalPkgLength;\r
+\r
+        //\r
+        // Jump over PkgLength = PkgLeadByte only\r
+        //\r
+        NewPkgLength++;\r
+\r
+        //\r
+        // Jump over BufferSize\r
+        //\r
+        if (*(DataPtr + 1) == AML_BYTE_PREFIX) {\r
+          NewPkgLength += 2;\r
+        } else if (*(DataPtr + 1) == AML_WORD_PREFIX) {\r
+          NewPkgLength += 3;\r
+        } else if (*(DataPtr + 1) == AML_DWORD_PREFIX) {\r
+          NewPkgLength += 5;\r
+        } else {\r
+          ASSERT(FALSE);\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+      } else {\r
+        ASSERT(FALSE);\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descriptor header(5 Bytes) + End Tag(2 Bytes)\r
+      //\r
+      NewPkgLength += 19 + IrqBuffserSize;\r
+      if (NewPkgLength > 63) {\r
+        break;\r
+      }\r
+\r
+      if (NewPkgLength > OrignalPkgLength) {\r
+        ASSERT(FALSE);\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // 1.1 Patch PkgLength\r
+      //\r
+      *DataPtr = (UINT8)NewPkgLength;\r
+\r
+      //\r
+      // 1.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).\r
+      //      It is Little endian. So only patch lowest byte of BufferSize due to current interrupt number limit.\r
+      //\r
+      *(DataPtr + 2) = (UINT8)(IrqBuffserSize + 19);\r
+\r
+      //\r
+      // Notify _PRS to report short formed ResourceTemplate\r
+      //\r
+      *IsShortFormPkgLength = TRUE;\r
+\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // 2. Use TPM_PRS_RESL with PkgLength > 63 to hold longer input interrupt number buffer for patching\r
+  //\r
+  if (NewPkgLength > 63) {\r
+    NewPkgLength     = 0;\r
+    OrignalPkgLength = 0;\r
+    for (DataPtr  = (UINT8 *)(Table + 1);\r
+         DataPtr < (UINT8 *) ((UINT8 *) Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));\r
+         DataPtr += 1) {\r
+      if (CompareMem(DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) == 0) {\r
+        //\r
+        // Jump over object name & BufferOp\r
+        //\r
+        DataPtr += TPM_PRS_RES_NAME_SIZE + 1;\r
+\r
+        if ((*DataPtr & (BIT7|BIT6)) != 0) {\r
+          OrignalPkgLength = (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr & 0x0F);\r
+          DataEndPtr       = DataPtr + OrignalPkgLength;\r
+          //\r
+          // Jump over PkgLength = PkgLeadByte + ByteData length\r
+          //\r
+          NewPkgLength += 1 + ((*DataPtr & (BIT7|BIT6)) >> 6);\r
+\r
+          //\r
+          // Jump over BufferSize\r
+          //\r
+          if (*(DataPtr + NewPkgLength) == AML_BYTE_PREFIX) {\r
+            NewPkgLength += 2;\r
+          } else if (*(DataPtr + NewPkgLength) == AML_WORD_PREFIX) {\r
+            NewPkgLength += 3;\r
+          } else if (*(DataPtr + NewPkgLength) == AML_DWORD_PREFIX) {\r
+            NewPkgLength += 5;\r
+          } else {\r
+            ASSERT(FALSE);\r
+            return EFI_UNSUPPORTED;\r
+          }\r
+        } else {\r
+          ASSERT(FALSE);\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+\r
+        //\r
+        // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descriptor header(5 Bytes) + End Tag(2  Bytes)\r
+        //\r
+        NewPkgLength += 19 + IrqBuffserSize;\r
+\r
+        if (NewPkgLength > OrignalPkgLength) {\r
+          ASSERT(FALSE);\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+\r
+        //\r
+        // 2.1 Patch PkgLength. Only patch PkgLeadByte and first ByteData\r
+        //\r
+        *DataPtr = (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x0F);\r
+        *(DataPtr + 1) = (UINT8)((NewPkgLength & 0xFF0) >> 4);\r
+\r
+        //\r
+        // 2.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).\r
+        //     It is Little endian. Only patch lowest byte of BufferSize due to current interrupt number limit.\r
+        //\r
+        *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) = (UINT8)(IrqBuffserSize + 19);\r
+\r
+        //\r
+        // Notify _PRS to report long formed ResourceTemplate\r
+        //\r
+        *IsShortFormPkgLength = FALSE;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (DataPtr >= (UINT8 *) ((UINT8 *) Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE))) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // 3. Move DataPtr to Interrupt descriptor header and patch interrupt descriptor.\r
+  //     5 bytes for interrupt descriptor header, 2 bytes for End Tag\r
+  //\r
+  DataPtr += NewPkgLength - (5 + IrqBuffserSize + 2);\r
+  //\r
+  //   3.1 Patch Length bit[7:0] of Interrupt descirptor patch interrupt descriptor\r
+  //\r
+  *(DataPtr + 1) = (UINT8)(2 + IrqBuffserSize);\r
+  //\r
+  //   3.2 Patch Interrupt Table Length\r
+  //\r
+  *(DataPtr + 4) = (UINT8)(IrqBuffserSize / sizeof(UINT32));\r
+  //\r
+  //   3.3 Copy patched InterruptNumBuffer\r
+  //\r
+  CopyMem(DataPtr + 5, IrqBuffer, IrqBuffserSize);\r
+\r
+  //\r
+  // 4. Jump over Interrupt descirptor and Patch END Tag, set Checksum field to 0\r
+  //\r
+  DataPtr       += 5 + IrqBuffserSize;\r
+  *DataPtr       = ACPI_END_TAG_DESCRIPTOR;\r
+  *(DataPtr + 1) = 0;\r
+\r
+  //\r
+  // 5. Jump over new ResourceTemplate. Stuff rest bytes to NOOP\r
+  //\r
+  DataPtr += 2;\r
+  if (DataPtr < DataEndPtr) {\r
+    SetMem(DataPtr, (UINTN)DataEndPtr - (UINTN)DataPtr, AML_NOOP_OP);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Patch TPM2 device HID string.  The initial string tag in TPM2 ACPI table is "NNN0000".\r
 \r
@@ -337,7 +540,7 @@ UpdateHID (
   if (!EFI_ERROR(Status)) {\r
     DEBUG((EFI_D_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", ManufacturerID));\r
     //\r
-    // ManufacturerID defined in TCG Vendor ID Registry \r
+    // ManufacturerID defined in TCG Vendor ID Registry\r
     // may tailed with 0x00 or 0x20\r
     //\r
     if ((ManufacturerID >> 24) == 0x00 || ((ManufacturerID >> 24) == 0x20)) {\r
@@ -368,11 +571,11 @@ UpdateHID (
     //   #### is Firmware Version 1\r
     //\r
     if (PnpHID) {\r
-      AsciiSPrint(Hid + 3, TPM_HID_PNP_SIZE - 3, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 && 0x0000FFFF));\r
+      AsciiSPrint(Hid + 3, TPM_HID_PNP_SIZE - 3, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));\r
     } else {\r
-      AsciiSPrint(Hid + 4, TPM_HID_ACPI_SIZE - 4, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 && 0x0000FFFF));\r
+      AsciiSPrint(Hid + 4, TPM_HID_ACPI_SIZE - 4, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));\r
     }\r
-    \r
+\r
   } else {\r
     DEBUG ((EFI_D_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", Status));\r
     ASSERT(FALSE);\r
@@ -423,6 +626,11 @@ PublishAcpiTable (
   UINTN                          TableKey;\r
   EFI_ACPI_DESCRIPTION_HEADER    *Table;\r
   UINTN                          TableSize;\r
+  UINT32                         *PossibleIrqNumBuf;\r
+  UINT32                         PossibleIrqNumBufSize;\r
+  BOOLEAN                        IsShortFormPkgLength;\r
+\r
+  IsShortFormPkgLength = FALSE;\r
 \r
   Status = GetSectionFromFv (\r
              &gEfiCallerIdGuid,\r
@@ -439,6 +647,12 @@ PublishAcpiTable (
   Status = UpdatePPVersion(Table, (CHAR8 *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer));\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "Current physical presence interface version - %a\n",\r
+    (CHAR8 *) PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer)\r
+    ));\r
+\r
   //\r
   // Update TPM2 HID before measuring it to PCR\r
   //\r
@@ -447,6 +661,29 @@ PublishAcpiTable (
     return Status;\r
   }\r
 \r
+  if (PcdGet32(PcdTpm2CurrentIrqNum) != 0) {\r
+    //\r
+    // Patch _PRS interrupt resource only when TPM interrupt is supported\r
+    //\r
+    PossibleIrqNumBuf     = (UINT32 *)PcdGetPtr(PcdTpm2PossibleIrqNumBuf);\r
+    PossibleIrqNumBufSize = (UINT32)PcdGetSize(PcdTpm2PossibleIrqNumBuf);\r
+\r
+    if (PossibleIrqNumBufSize <= MAX_PRS_INT_BUF_SIZE && (PossibleIrqNumBufSize % sizeof(UINT32)) == 0) {\r
+      Status = UpdatePossibleResource(Table, PossibleIrqNumBuf, PossibleIrqNumBufSize, &IsShortFormPkgLength);\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "UpdatePossibleResource status - %x. TPM2 service may not ready in OS.\n",\r
+        Status\r
+        ));\r
+    } else {\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "PcdTpm2PossibleIrqNumBuf size %x is not correct. TPM2 service may not ready in OS.\n",\r
+        PossibleIrqNumBufSize\r
+      ));\r
+    }\r
+  }\r
+\r
   //\r
   // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
   //\r
@@ -464,6 +701,8 @@ PublishAcpiTable (
   CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) );\r
   mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS));\r
   ASSERT (mTcgNvs != NULL);\r
+  mTcgNvs->TpmIrqNum            = PcdGet32(PcdTpm2CurrentIrqNum);\r
+  mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength;\r
 \r
   //\r
   // Publish the TPM ACPI table. Table is re-checksumed.\r
@@ -500,7 +739,20 @@ PublishTpm2 (
   UINTN                          TableKey;\r
   UINT64                         OemTableId;\r
   EFI_TPM2_ACPI_CONTROL_AREA     *ControlArea;\r
-  PTP_INTERFACE_TYPE             InterfaceType;\r
+  TPM2_PTP_INTERFACE_TYPE        InterfaceType;\r
+\r
+  mTpm2AcpiTemplate.Header.Revision = PcdGet8(PcdTpm2AcpiTableRev);\r
+  DEBUG((DEBUG_INFO, "Tpm2 ACPI table revision is %d\n", mTpm2AcpiTemplate.Header.Revision));\r
+\r
+  //\r
+  // PlatformClass is only valid for version 4 and above\r
+  //    BIT0~15:  PlatformClass\r
+  //    BIT16~31: Reserved\r
+  //\r
+  if (mTpm2AcpiTemplate.Header.Revision >= EFI_TPM2_ACPI_TABLE_REVISION_4) {\r
+    mTpm2AcpiTemplate.Flags = (mTpm2AcpiTemplate.Flags & 0xFFFF0000) | PcdGet8(PcdTpmPlatformClass);\r
+    DEBUG((DEBUG_INFO, "Tpm2 ACPI table PlatformClass is %d\n", (mTpm2AcpiTemplate.Flags & 0x0000FFFF)));\r
+  }\r
 \r
   //\r
   // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
@@ -514,9 +766,9 @@ PublishTpm2 (
     sizeof(mTpm2AcpiTemplate)\r
     );\r
 \r
-  InterfaceType = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+  InterfaceType = PcdGet8(PcdActiveTpmInterfaceType);\r
   switch (InterfaceType) {\r
-  case PtpInterfaceCrb:\r
+  case Tpm2PtpInterfaceCrb:\r
     mTpm2AcpiTemplate.StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE;\r
     mTpm2AcpiTemplate.AddressOfControlArea = PcdGet64 (PcdTpmBaseAddress) + 0x40;\r
     ControlArea = (EFI_TPM2_ACPI_CONTROL_AREA *)(UINTN)mTpm2AcpiTemplate.AddressOfControlArea;\r
@@ -525,8 +777,8 @@ PublishTpm2 (
     ControlArea->Command      = PcdGet64 (PcdTpmBaseAddress) + 0x80;\r
     ControlArea->Response     = PcdGet64 (PcdTpmBaseAddress) + 0x80;\r
     break;\r
-  case PtpInterfaceFifo:\r
-  case PtpInterfaceTis:\r
+  case Tpm2PtpInterfaceFifo:\r
+  case Tpm2PtpInterfaceTis:\r
     break;\r
   default:\r
     DEBUG((EFI_D_ERROR, "TPM2 InterfaceType get error! %d\n", InterfaceType));\r
@@ -560,12 +812,12 @@ PublishTpm2 (
 /**\r
   The driver's entry point.\r
 \r
-  It install callbacks for TPM physical presence and MemoryClear, and locate \r
+  It install callbacks for TPM physical presence and MemoryClear, and locate\r
   SMM variable to be used in the callback function.\r
 \r
-  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable  A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval Others          Some error occurs when executing this entry point.\r
 \r
@@ -610,7 +862,7 @@ InitializeTcgSmm (
     return Status;\r
   }\r
   mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;\r
-  \r
+\r
   //\r
   // Locate SmmVariableProtocol.\r
   //\r