Newer
Older
AMI-Aptio-BIOS-Reversed / AmiModulePkg / TCG2 / Common / TcgPlatformSetupPolicy / TcgPlatformSetupPolicy.c
@Ajax Dong Ajax Dong 2 days ago 28 KB Full restructure
/** @file
  TcgPlatformSetupPolicy.c -- TCG Platform Setup Policy DXE driver.

  This DXE driver manages TCG (Trusted Computing Group) platform setup policy
  variables and installs a protocol to expose them to other platform drivers.

  Functional overview:

  1. Entry point (TcgPlatformSetupPolicyDxeEntryPoint, =0x860):
     - Caches UEFI table pointers (ImageHandle, SystemTable, BootServices, RuntimeServices)
     - Allocates a runtime pool buffer (40 bytes) for the protocol interface
     - Reads the TcgInternalSyncFlag variable to check for an in-progress sync
     - Reads the 814-byte "Setup" NV variable (gSetupVariableGuid)
     - Initializes the 27-byte TCG_PLATFORM_SETUP_POLICY from Setup fields
     - Reads the "PCRBitmap" variable to apply PCR enable bits
     - Caches individual policy bytes to global shadow variables (byte_1450..byte_1467)
     - Installs the TCG_PLATFORM_SETUP_POLICY_PROTOCOL on ImageHandle
     - Registers a notification event (TPL_CALLBACK) -> TcgPlatformSetupPolicyNotify (=0x7F4)
     - Locates the HOB list via configuration table

  2. SetPolicy callback (TcgPlatformSetPolicyData, =0x408):
     - Accepts updated TPM policy data from other drivers
     - Updates shadow globals from policy bytes
     - Merges policy fields back into the appropriate Setup variable offsets
     - Updates PCRBitmap variable if needed
     - Writes TcgInternalSyncFlag to signal other components

  3. Notification callback (TcgPlatformSetupPolicyNotify, =0x7F4):
     - Triggered when the protocol is installed (EVT_NOTIFY_SIGNAL)
     - Locates the TCG_PLATFORM_SETUP_POLICY_PROTOCOL
     - Copies 27 bytes of policy from protocol interface+1
     - Calls SetPolicy (at protocol interface+32) with (policyData, TRUE)
     - Closes the notification event

  Binary info:
    Module:      TcgPlatformSetupPolicy.efi
    Architecture: x86_64 (UEFI DXE driver)
    Image size:  0x15A0 (5536 bytes)
    MD5:         e203632565eb9a0fd0caad1a87e0bb43
    SHA256:      d51f30be6a4b3c180cc5ab354957ecacf316cb64b639f72287ecf69bfcf528f8

  Copyright (c) Lenovo. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent

  Reverse-engineered from Lenovo HR650X BIOS (2024/3647 AJAX).
**/

#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/HobLib.h>

#include "TcgPlatformSetupPolicy.h"

//=============================================================================
// GUID Definitions
//=============================================================================

///
/// TCG Platform Setup Policy Protocol GUID:
///   {BB6CBEFF-E072-40D2-A6EB-BAB75BDE87E7}
///
EFI_GUID  gTcgPlatformSetupPolicyProtocolGuid = TCG_PLATFORM_SETUP_POLICY_PROTOCOL_GUID;

///
/// TCG Internal Sync Flag variable GUID:
///   {F3ED95DF-828E-41C7-BCA0-16C41965A634}
///
EFI_GUID  gTcgInternalSyncFlagGuid = TCG_INTERNAL_SYNC_FLAG_GUID;

///
/// Setup variable GUID:
///   {EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9}
///
EFI_GUID  gSetupVariableGuid = SETUP_VARIABLE_GUID;

///
/// PCRBitmap variable GUID:
///   {70FFF0FF-A543-45B9-8BE3-1BDB90412080}
///
EFI_GUID  gPcrBitmapVariableGuid = PCR_BITMAP_VARIABLE_GUID;

//=============================================================================
// Global Variables -- .data section (0x1410..0x1467)
//=============================================================================

///
/// mTcgPolicyBuffer -- qword_1410
/// The allocated protocol interface buffer (40 bytes allocated, 32 used).
///   byte  [0] = Revision (3)
///   bytes [1..27] = TCG_PLATFORM_SETUP_POLICY data
///   qword[4] (=offset 32) = SetPolicy function pointer
///
TCG_PLATFORM_SETUP_POLICY_PROTOCOL  *mTcgPolicyProtocol = NULL;

///
/// mHobList -- qword_1440
/// Cached pointer to the HOB list, located from the system configuration table.
///
VOID  *mHobList = NULL;

///
/// mDebugProtocol -- qword_1438
/// Cached pointer to the debug/assert protocol interface.
/// Located (under TPL protection) and cached on first use.
/// Protocol interface has a function pointer at offset +8 for assert.
///
VOID  *mDebugProtocol = NULL;

///
/// mVariableAttributes -- n3 at 0x1448
/// Attributes used for GetVariable/SetVariable calls.
/// Set to 3 (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS).
///
UINT32  mVariableAttributes = 3;

///
/// Shadow copies of policy bytes -- byte_1450..byte_1466
/// These are populated by the entry point and can be read by external
/// debug tools or other firmware components via direct memory access.
///
UINT8   mTpm1Enable         = 0;   // byte_1450 -- Policy[0]: TPM 1.2 Enable
UINT8   mTpmOperation        = 0;   // byte_1451 -- Policy[1]: TPM Operation
UINT8   mTpm2Enable         = 0;   // byte_1452 -- Policy[2]: TPM 2.0 Enable
UINT8   mTpmSelect          = 0;   // byte_1453 -- Policy[3]: TPM Select
UINT8   mReserved1          = 0;   // byte_1454 -- (not set by entry point)
UINT8   mPcrBankTpm2        = 0;   // byte_1455 -- Policy[5]: PCR Bank TPM2
UINT8   mPcrBankTpm12       = 0;   // byte_1456 -- Policy[6]: PCR Bank TPM1.2
UINT8   mReserved2          = 0;   // byte_1457 -- (not set by entry point)
UINT8   mTpm1Support        = 0;   // byte_1458 -- Policy[8]: TPM 1.2 Support
UINT8   mTpm2Support        = 0;   // byte_1459 -- Policy[9]: TPM 2.0 Support
UINT8   mTpmExistence       = 0;   // byte_145A -- Policy[10]: TPM Existence
UINT8   mReserved3          = 0;   // byte_145B -- (not set by entry point)
UINT8   mReserved4          = 0;   // byte_145C -- (not set by entry point)
UINT8   mTpmPolicy          = 0;   // byte_145D -- Policy[13]: TPM Policy
UINT8   mTpmPhysicalPresence = 0;  // byte_145E -- Policy[15]: TPM Physical Presence
UINT8   mTpmPhysPresence2   = 0;   // byte_145F -- Policy[16]: (reserved / extra)
UINT8   mReserved5          = 0;   // byte_1460 -- (not set)
UINT8   mReserved6          = 0;   // byte_1461 -- (not set)
UINT8   mReserved7          = 0;   // byte_1462 -- (not set)
UINT8   mTpmFirmwareUpdate  = 0;   // byte_1463 (actually at 0x1462 in IDA, but Policy[19])
UINT8   mTpmSupplierConfig  = 0;   // byte_1464 -- Policy[20]
UINT8   mTpmSupplier        = 0;   // byte_1465 -- Policy[21]
UINT8   mTpmDevice          = 0;   // byte_1466 -- Policy[22]
UINT32  mPcrBitmap          = 0;   // dword_1467 -- Policy[23..26]

//=============================================================================
// Library Helpers
//=============================================================================

/**
  Locates and caches the debug/assert protocol ({36232936-0E76-31C8-
  A13A-3AF2FC1C3932}). Uses RaiseTPL/RestoreTPL for single-thread safety.

  @return Pointer to the debug protocol, or NULL.
**/
VOID *
LocateDebugProtocol (
  VOID
  )
{
  EFI_TPL  OldTpl;

  if (mDebugProtocol != NULL) {
    return mDebugProtocol;
  }

  //
  // Raise TPL to TPL_HIGH_LEVEL (31) to guard against re-entrancy.
  //
  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
  gBS->RestoreTPL (OldTpl);

  //
  // Only proceed if the system was at TPL_NOTIFY or below.
  //
  if (OldTpl <= TPL_NOTIFY) {
    //
    // Locate the debug protocol via its custom GUID.
    // The actual GUID is proprietary to Lenovo.
    //
    gBS->LocateProtocol (
           &mDebugProtocolGuid,
           NULL,
           &mDebugProtocol
           );
  }

  return mDebugProtocol;
}

/**
  Reports an ASSERT failure via the debug protocol.

  @param[in] FileName       Source file name.
  @param[in] LineNumber     Line number.
  @param[in] Description    Assert description string.
**/
VOID
EFIAPI
ReportAssert (
  IN CONST CHAR8  *FileName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *Description
  )
{
  VOID   *DebugProtocol;
  VOID   (*AssertFunc)(CONST CHAR8 *, UINTN, CONST CHAR8 *);

  DebugProtocol = LocateDebugProtocol ();
  if (DebugProtocol != NULL) {
    //
    // The function pointer is at offset +8 in the protocol interface.
    //
    AssertFunc = (VOID (*)(CONST CHAR8 *, UINTN, CONST CHAR8 *))
                 *((UINT64 *)((UINTN)DebugProtocol + 8));
    AssertFunc (FileName, LineNumber, Description);
  }
}

/**
  Compares two GUIDs by comparing them as two 64-bit halves.

  @param[in] Guid1  Pointer to first GUID.
  @param[in] Guid2  Pointer to second GUID.

  @retval TRUE   GUIDs are equal.
  @retval FALSE  GUIDs differ.
**/
BOOLEAN
EFIAPI
CompareGuid (
  IN CONST EFI_GUID  *Guid1,
  IN CONST EFI_GUID  *Guid2
  )
{
  return (ReadUnaligned64 ((CONST UINT64 *)Guid1) ==
          ReadUnaligned64 ((CONST UINT64 *)Guid2)) &&
         (ReadUnaligned64 ((CONST UINT64 *)Guid1 + 1) ==
          ReadUnaligned64 ((CONST UINT64 *)Guid2 + 1));
}

/**
  Reads a UINT64 from possibly-unaligned memory.

  @param[in] Buffer  The pointer to read from.

  @return The 64-bit value at Buffer.
**/
UINT64
EFIAPI
ReadUnaligned64 (
  IN CONST VOID  *Buffer
  )
{
  if (Buffer == NULL) {
    ReportAssert (
      "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
      192,
      "Buffer != ((void *) 0)"
      );
  }
  return *((UINT64 *)Buffer);
}

/**
  Locates the HOB list from the EFI configuration table.

  Searches the system table's ConfigurationTable[] for the
  gEfiHobListGuid entry ({7739F24C-93D7-11D4-9A3A-0090273FC14D}).

  @return Pointer to the HOB list, or NULL.
**/
VOID *
EFIAPI
GetHobList (
  VOID
  )
{
  UINTN                  Index;
  EFI_CONFIGURATION_TABLE  *ConfigTable;

  if (mHobList != NULL) {
    return mHobList;
  }

  ConfigTable = gST->ConfigurationTable;
  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
    if (CompareGuid (&ConfigTable[Index].VendorGuid, &gEfiHobListGuid)) {
      mHobList = ConfigTable[Index].VendorTable;
      return mHobList;
    }
  }

  //
  // HOB list not found -- assert (this is a fatal firmware error).
  //
  ReportAssert (
    "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
    54,
    "!EFI_ERROR (Status)"
    );
  ReportAssert (
    "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
    55,
    "mHobList != ((void *) 0)"
    );
  return NULL;
}

/**
  Reads TPM boot path from CMOS register 0x4B.

  Checks the TPM boot path configuration stored in CMOS to determine
  whether a given feature (identified by FeatureMask) should be executed.

  @param[in] FeatureMask  Bitmask identifying the feature to check.

  @retval TRUE   The feature should be executed.
  @retval FALSE  The feature should be skipped.
**/
BOOLEAN
EFIAPI
TpmBootPathCmosCheck (
  IN UINT32  FeatureMask
  )
{
  VOID    *DebugProtocol;
  UINT64  (*ExecuteFunc)(UINT32 Feature, UINT64 Arg1, ...);
  UINT8   CmosIndex;
  UINT8   CmosValue;

  DebugProtocol = LocateDebugProtocol ();
  if (DebugProtocol == NULL) {
    return FALSE;
  }

  //
  // Write CMOS address 0x4B to port 0x70 (preserving NMI disable bit 7).
  //
  IoWrite8 (0x70, (IoRead8 (0x70) & 0x80) | 0x4B);

  //
  // Read the TPM boot path value from CMOS port 0x71.
  //
  CmosValue = IoRead8 (0x71);

  if (CmosValue > 3) {
    CmosValue = 0;
  }

  if (CmosValue == 0) {
    //
    // Read the platform type register at MMIO 0xFDAF0490.
    // Bits: bit 0 = TPM present, bit 1 = TPM type.
    //
    CmosValue = (IoRead8 (0xFDAF0490) & 2) | 1;
  }

  //
  // Translate CMOS value:
  //   CmosValue == 1  -> TPM boot is disabled
  //   CmosValue == 2  -> TPM1 boot path
  //   CmosValue == 3  -> TPM2 boot path
  //
  if (CmosValue == 1) {
    //
    // Feature 0x8000000C (debug print) is active.
    //
    ExecuteFunc = (UINT64 (*)(UINT32, UINT64, ...))
                 *((UINT64 *)(UINTN)DebugProtocol);
    return (BOOLEAN)ExecuteFunc (FeatureMask, (UINT64)"\nASSERT_EFI_ERROR (Status = %r)\n");
  } else {
    //
    // Features 0x80000004-0x8000000C may be active.
    //
    return (BOOLEAN)((FeatureMask & TCG_BOOT_PATH_ENABLE) != 0);
  }
}

//=============================================================================
// Core Driver Functions
//=============================================================================

/**
  Initializes the policy structure from the Setup variable buffer.

  Maps Setup variable fields (by byte offset) into the 27-byte
  TCG_PLATFORM_SETUP_POLICY structure.

  @param[out] Policy       The 27-byte policy structure to fill.
  @param[in]  SetupBuffer  The raw 814-byte Setup variable buffer.
  @param[in]  SetupSize    Size of data in SetupBuffer.
**/
VOID
EFIAPI
TcgPlatformInitPolicyFromSetup (
  OUT TCG_PLATFORM_SETUP_POLICY  *Policy,
  IN  UINT8                      *SetupBuffer,
  IN  UINTN                      SetupSize
  )
{
  UINT8  *Bytes;
  UINT32  PcrBitmapValue;

  Bytes = (UINT8 *)Policy;

  //
  // Zero the entire 27-byte policy structure.
  //
  ZeroMem (Bytes, TCG_PLATFORM_SETUP_POLICY_DATA_SIZE);

  //
  // Map each Setup field to the corresponding policy byte.
  //
  Bytes[ 0] = SetupBuffer[18];  // TPM1 Enable
  Bytes[ 1] = SetupBuffer[13];  // TPM Operation
  Bytes[ 2] = SetupBuffer[22];  // TPM2 Enable
  Bytes[ 3] = SetupBuffer[14];  // TPM Select
  Bytes[ 5] = SetupBuffer[26];  // PCR Bank TPM2
  Bytes[ 6] = SetupBuffer[31];  // PCR Bank TPM1.2
  Bytes[ 8] = SetupBuffer[15];  // TPM1 Support
  Bytes[ 9] = SetupBuffer[16];  // TPM2 Support
  Bytes[10] = SetupBuffer[17];  // TPM Existence
  Bytes[13] = SetupBuffer[24];  // TPM Policy
  Bytes[15] = SetupBuffer[32];  // TPM Physical Presence
  Bytes[19] = SetupBuffer[27];  // TPM Firmware Update
  Bytes[20] = SetupBuffer[28];  // TPM Supplier Config
  Bytes[21] = SetupBuffer[29];  // TPM Supplier
  Bytes[22] = SetupBuffer[30];  // TPM Device

  //
  // PCR Bitmap: DWORD at Setup offsets 38-41.
  //
  PcrBitmapValue  = SetupBuffer[38];
  PcrBitmapValue |= SetupBuffer[39] << 8;
  PcrBitmapValue |= SetupBuffer[40] << 16;
  PcrBitmapValue |= SetupBuffer[41] << 24;
  *(UINT32 *)(Bytes + 23) = PcrBitmapValue;
}

/**
  Writes policy data back to UEFI NV variables.

  If WriteToNv is TRUE, reads the current Setup variable, applies the
  policy values to the appropriate byte offsets, writes Setup back,
  and writes the TcgInternalSyncFlag.

  @param[in] PolicyData   Pointer to the policy data.
  @param[in] WriteToNv    TRUE to commit to NV variables.

  @retval EFI_SUCCESS            Policy committed.
  @retval EFI_INVALID_PARAMETER  PolicyData is NULL.
  @retval Others                 Error from GetVariable/SetVariable.
**/
EFI_STATUS
EFIAPI
TcgPlatformSetPolicyData (
  IN TCG_PLATFORM_SETUP_POLICY  *PolicyData,
  IN BOOLEAN                    WriteToNv
  )
{
  EFI_STATUS  Status;
  UINT8       *Bytes;
  UINT8       SetupBuffer[SETUP_VARIABLE_MAX_SIZE];
  UINTN       SetupSize;
  UINTN       SyncFlagSize;
  UINT32      Attributes;
  UINT32      PcrBitmapValue;
  UINT32      PcrBitmapCopy;
  UINTN       PcrBitmapSize;
  UINT32      PcrBitmapArray[5];
  UINT8       *PolicyByte;
  UINT8       Val;
  UINTN       Index;

  Bytes = (UINT8 *)PolicyData;

  if (PolicyData == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Update shadow global variables from the policy data.
  //
  mTpm1Enable         = Bytes[ 0];
  mTpmOperation        = Bytes[ 1];
  mTpm2Enable         = Bytes[ 2];
  mTpmSelect          = Bytes[ 3];
  mPcrBankTpm2        = Bytes[ 5];
  mPcrBankTpm12       = Bytes[ 6];
  mTpm1Support        = Bytes[ 8];
  mTpm2Support        = Bytes[ 9];
  mTpmExistence       = Bytes[10];
  mTpmPolicy          = Bytes[13];
  mTpmPhysicalPresence = Bytes[15];
  mTpmFirmwareUpdate  = Bytes[19];
  mTpmSupplierConfig  = Bytes[20];
  mTpmSupplier        = Bytes[21];
  mTpmDevice          = Bytes[22];
  mPcrBitmap          = *(UINT32 *)(Bytes + 23);

  if (!WriteToNv) {
    return EFI_SUCCESS;
  }

  //
  // Read the current Setup variable.
  //
  Attributes = mVariableAttributes;
  SetupSize  = sizeof (SetupBuffer);
  Status = gRT->GetVariable (
                  VARNAME_SETUP,
                  &gSetupVariableGuid,
                  &Attributes,
                  &SetupSize,
                  SetupBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Write back all policy fields at their respective Setup offsets.
  //
  SetupBuffer[18] = Bytes[ 0];  // TPM1 Enable
  SetupBuffer[13] = Bytes[ 1];  // TPM Operation
  SetupBuffer[22] = Bytes[ 2];  // TPM2 Enable
  SetupBuffer[14] = Bytes[ 3];  // TPM Select
  SetupBuffer[26] = Bytes[ 5];  // PCR Bank TPM2
  SetupBuffer[31] = Bytes[ 6];  // PCR Bank TPM1.2
  SetupBuffer[15] = Bytes[ 8];  // TPM1 Support
  SetupBuffer[16] = Bytes[ 9];  // TPM2 Support
  SetupBuffer[17] = Bytes[10];  // TPM Existence
  SetupBuffer[24] = Bytes[13];  // TPM Policy
  SetupBuffer[32] = Bytes[15];  // TPM Physical Presence
  SetupBuffer[27] = Bytes[19];  // TPM Firmware Update
  SetupBuffer[28] = Bytes[20];  // TPM Supplier Config
  SetupBuffer[29] = Bytes[21];  // TPM Supplier
  SetupBuffer[30] = Bytes[22];  // TPM Device

  //
  // PCR Bitmap DWORD at offsets 38-41.
  //
  PcrBitmapCopy = *(UINT32 *)(Bytes + 23);
  SetupBuffer[38] = (UINT8)(PcrBitmapCopy & 0xFF);
  SetupBuffer[39] = (UINT8)((PcrBitmapCopy >> 8) & 0xFF);
  SetupBuffer[40] = (UINT8)((PcrBitmapCopy >> 16) & 0xFF);
  SetupBuffer[41] = (UINT8)((PcrBitmapCopy >> 24) & 0xFF);

  //
  // Write the modified Setup variable.
  //
  Status = gRT->SetVariable (
                  VARNAME_SETUP,
                  &gSetupVariableGuid,
                  mVariableAttributes,
                  SetupSize,
                  SetupBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Apply PCR variable flags (bits 0-4 -> SHA1/SHA256/SHA384/SHA512/SM3).
  //
  {
    //
    // Read the PCRBitmap variable.
    //
    PcrBitmapSize = sizeof (PcrBitmapArray);
    Status = gRT->GetVariable (
                    VARNAME_PCR_BITMAP,
                    &gPcrBitmapVariableGuid,
                    &Attributes,
                    &PcrBitmapSize,
                    PcrBitmapArray
                    );
    if (!EFI_ERROR (Status)) {
      //
      // Apply PCR enable bits to policy.
      // Bit 0  -> Bytes[4] = 1  (SHA1 enable -- v12 in dec)
      // Bit 1  -> Bytes[5] = 1  (SHA256 enable -- v13 in dec)
      // Bit 2  -> Bytes[6] = 1  (SHA384 enable -- v14 in dec)
      // Bit 3  -> Bytes[7] = 1  (SHA512 enable -- v15 in dec)
      // Bit 4  -> Bytes[8] = 1  (SM3 enable -- v16 in dec)
      //
      if (PcrBitmapArray[0] & 1)  Bytes[4] = 1;
      if (PcrBitmapArray[0] & 2)  Bytes[5] = 1;
      if (PcrBitmapArray[0] & 4)  Bytes[6] = 1;
      if (PcrBitmapArray[0] & 8)  Bytes[7] = 1;
      if (PcrBitmapArray[0] & 0x10) Bytes[8] = 1;
    }
  }

  //
  // Write TcgInternalSyncFlag to 1 to signal sync completion.
  //
  Bytes[14] = 1;  // Set the sync flag in policy
  Status = gRT->SetVariable (
                  VARNAME_TCG_INTERNAL_SYNC,
                  &gTcgInternalSyncFlagGuid,
                  mVariableAttributes,
                  1,
                  &Bytes[14]
                  );
  if (Status == EFI_NOT_FOUND) {
    //
    // Variable does not exist yet; create it.
    //
    Status = gRT->SetVariable (
                    VARNAME_TCG_INTERNAL_SYNC,
                    &gTcgInternalSyncFlagGuid,
                    mVariableAttributes,
                    1,
                    &Bytes[14]
                    );
  }

  return Status;
}

//=============================================================================
// Notification Callback
//=============================================================================

/**
  Notification callback for the SetProtocol interface.

  Triggered by the protocol installation event. Locates the protocol,
  reads the 27-byte policy, and calls SetPolicy to commit it.

  @param[in] Event    The notification event.
  @param[in] Context  Unused.
**/
VOID
EFIAPI
TcgPlatformSetupPolicyNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS                          Status;
  TCG_PLATFORM_SETUP_POLICY_PROTOCOL  *Protocol;
  TCG_PLATFORM_SETUP_POLICY           Policy;

  Protocol = NULL;

  //
  // Locate our protocol interface.
  //
  Status = gBS->LocateProtocol (
                  &gTcgPlatformSetupPolicyProtocolGuid,
                  NULL,
                  (VOID **)&Protocol
                  );
  if (EFI_ERROR (Status) || Protocol == NULL) {
    return;
  }

  //
  // Copy the 27-byte policy data from the protocol interface (offset 1).
  //
  CopyMem (
    &Policy,
    (UINT8 *)Protocol + 1,
    TCG_PLATFORM_SETUP_POLICY_DATA_SIZE
    );

  //
  // Call the SetPolicy function (at offset 32 in the protocol interface).
  //
  Protocol->SetPolicy (&Policy, TRUE);

  //
  // Close the notification event.
  //
  gBS->CloseEvent (Event);
}

//=============================================================================
// Driver Entry Point
//=============================================================================

/**
  Entry point for TcgPlatformSetupPolicy DXE driver.

  @param[in] ImageHandle  EFI image handle.
  @param[in] SystemTable  EFI system table.

  @retval EFI_SUCCESS           Protocol installed.
  @retval EFI_OUT_OF_RESOURCES  Pool allocation failed.
  @retval Others                Protocol install failed.
**/
EFI_STATUS
EFIAPI
TcgPlatformSetupPolicyDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  UINTN               SetupSize;
  UINT8               SetupBuffer[SETUP_VARIABLE_MAX_SIZE];
  UINTN               PcrBitmapSize;
  UINT32              PcrBitmapArray[5];
  UINTN               SyncFlagSize;
  UINT8               SyncFlagValue;
  UINT32              Attributes;
  EFI_EVENT           NotificationEvent;
  VOID                *Registration;

  //
  // The UEFI core initializes gImageHandle, gST, gBS, gRT in the
  // library constructors. sub_DD8 (GetHobList) is called here in the
  // original decompilation.
  //
  GetHobList ();

  //
  // Allocate runtime pool for the protocol interface (40 bytes).
  //
  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  sizeof (TCG_PLATFORM_SETUP_POLICY_PROTOCOL) + 8,
                  (VOID **)&mTcgPolicyProtocol
                  );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }
  ZeroMem (mTcgPolicyProtocol, sizeof (TCG_PLATFORM_SETUP_POLICY_PROTOCOL));
  mTcgPolicyProtocol->Revision = TCG_PLATFORM_SETUP_POLICY_REVISION;

  //
  // Read the TcgInternalSyncFlag to check for pending sync.
  //
  SyncFlagSize = 1;
  Status = gRT->GetVariable (
                  VARNAME_TCG_INTERNAL_SYNC,
                  &gTcgInternalSyncFlagGuid,
                  &Attributes,
                  &SyncFlagSize,
                  &SyncFlagValue
                  );
  if (EFI_ERROR (Status)) {
    SyncFlagValue = 0;
  }

  //
  // Read the Setup variable.
  //
  Attributes = mVariableAttributes;
  SetupSize  = sizeof (SetupBuffer);
  Status = gRT->GetVariable (
                  VARNAME_SETUP,
                  &gSetupVariableGuid,
                  &Attributes,
                  &SetupSize,
                  SetupBuffer
                  );

  if (!EFI_ERROR (Status)) {
    //
    // Initialize policy from Setup.
    //
    TcgPlatformInitPolicyFromSetup (
      &mTcgPolicyProtocol->PolicyData,
      SetupBuffer,
      SetupSize
      );

    //
    // Propagate TcgInternalSyncFlag.
    //
    if (SyncFlagSize == 1) {
      *((UINT8 *)&mTcgPolicyProtocol->PolicyData + 14) = SyncFlagValue;
    }

    //
    // Read PCRBitmap variable and apply PCR enable bits.
    //
    PcrBitmapSize = sizeof (PcrBitmapArray);
    Status = gRT->GetVariable (
                    VARNAME_PCR_BITMAP,
                    &gPcrBitmapVariableGuid,
                    NULL,
                    &PcrBitmapSize,
                    PcrBitmapArray
                    );
    if (!EFI_ERROR (Status)) {
      //
      // Apply PCR bits to the policy structure (v12..v16 fields).
      //
      UINT8 *PolicyBytes = (UINT8 *)&mTcgPolicyProtocol->PolicyData;

      PolicyBytes[ 4] = 0;                              // v12
      if (PcrBitmapArray[0] & 1)  PolicyBytes[ 4] = 1;  // SHA1
      if (PcrBitmapArray[0] & 2)  PolicyBytes[ 5] = 1;  // SHA256 (actually
                                                         // Policy[5], but
                                                         // already set from
                                                         // Setup)
      // Note: bits 4,8,0x10 correspond to different PCR indexes.
    }
  } else {
    //
    // Setup variable not found; policy was zeroed by ZeroMem.
    //
  }

  //===========================================================================
  // Cache all policy fields to shadow global variables.
  //===========================================================================
  {
    UINT8 *Bytes;

    Bytes = (UINT8 *)&mTcgPolicyProtocol->PolicyData;

    mTpm1Enable         = Bytes[ 0];  // byte_1450
    mTpmOperation        = Bytes[ 1];  // byte_1451
    mTpm2Enable         = Bytes[ 2];  // byte_1452
    mTpmSelect          = Bytes[ 3];  // byte_1453
    //                     Bytes[ 4];   // byte_1454 -- NOT saved to global!
    mPcrBankTpm2        = Bytes[ 5];  // byte_1455
    mPcrBankTpm12       = Bytes[ 6];  // byte_1456
    //                     Bytes[ 7];   // byte_1457 -- NOT saved to global!
    mTpm1Support        = Bytes[ 8];  // byte_1458
    mTpm2Support        = Bytes[ 9];  // byte_1459
    mTpmExistence       = Bytes[10];  // byte_145A
    //                     Bytes[11];   // byte_145B -- NOT saved to global!
    //                     Bytes[12];   // byte_145C -- NOT saved to global!
    mTpmPolicy          = Bytes[13];  // byte_145D
    mTpmPhysicalPresence = Bytes[15]; // byte_145E
    mTpmPhysPresence2   = Bytes[16];  // byte_145F
    //                     Bytes[17];   // byte_1460 -- NOT saved to global!
    //                     Bytes[18];   // byte_1461 -- NOT saved to global!
    mTpmFirmwareUpdate  = Bytes[19];  // byte_1462
    mTpmSupplierConfig  = Bytes[20];  // byte_1463
    mTpmSupplier        = Bytes[21];  // byte_1464
    mTpmDevice          = Bytes[22];  // byte_1465
    mPcrBitmap          = *(UINT32 *)(Bytes + 23);  // dword_1467
  }

  //===========================================================================
  // Install the protocol on ImageHandle.
  //===========================================================================
  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gTcgPlatformSetupPolicyProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  (VOID *)mTcgPolicyProtocol
                  );
  if (EFI_ERROR (Status)) {
    gBS->FreePool (mTcgPolicyProtocol);
    return Status;
  }

  //===========================================================================
  // Register the notification event.
  // Type = EVT_NOTIFY_SIGNAL (512), NotifyTpl = TPL_CALLBACK (8),
  // NotifyFunction = TcgPlatformSetupPolicyNotify
  //===========================================================================
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  TcgPlatformSetupPolicyNotify,
                  NULL,
                  &NotificationEvent
                  );
  if (EFI_ERROR (Status)) {
    //
    // Non-fatal; the protocol is already installed even if the
    // notification event fails.
    //
  }

  return EFI_SUCCESS;
}

//=============================================================================
//  Function Summary for Reference
//=============================================================================
//
// Address  Name                          Size  Role
// -------  ----                          ----  ----
//  0x280   ZeroBuffer                     17   memset(buf, val, size)
//  0x350   _ModuleEntryPoint             184   UEFI entry, calls sub_DD8 + sub_860
//  0x408   TcgPlatformSetPolicyData     1002   Read Setup, merge policy, write NV
//  0x7F4   TcgPlatformSetupPolicyNotify  107   Locate protocol, copy policy, call SetPolicy
//  0x860   TcgPlatformSetupPolicyDxe..   990   Main entry: alloc, init, install protocol
//  0xC40   ZeroMem/SetMem                 80   Wrapper for ZeroBuffer
//  0xC90   LocateDebugProtocol           127   RaiseTPL, LocateProtocol, cache result
//  0xD10   TpmBootPathCmosCheck          136   Read CMOS 0x4B for TPM boot path
//  0xD98   ReportAssert                   62   Call assert via debug protocol offset+8
//  0xDD8   GetHobList                    214   Search config table for gEfiHobListGuid
//  0xEB0   ReadUnaligned64                47   64-bit unaligned read with NULL check
//  0xEE0   CompareGuid                   110   Compare two GUIDs via 64-bit halves