# TcgLegacy

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **ReadUnaligned64** |  |
|  | **DebugPrint** |  |
|  | **DebugAssert** |  |
|  | **ZeroMem** |  |
|  | **IsHobGuidMatch** |  |
|  | **LocateFirmwareVolumeFile** |  |
|  | **AllocateAndZeroPages** |  |
|  | **AllocateAndZeroPagesWrapper** |  |
|  | **ScanAndPatchBfi** |  |
|  | **LinkTPM32Driver** |  |
|  | **UnlinkTPM32FromEFI** |  |
|  | **NullCallback** |  |
|  | **GenericCallback** |  |
|  | **ModuleEntryPoint** |  |
|  | **InitTCGLegacyInterface** |  |
| External | **global data references (populated by ModuleEntryPoint)** |  |
| These | **are written once by the DXE core bootstrap code before the driver's** |  |
| entry | **point is called; the entry point simply caches them in variables.** |  |
| Legacy | **BIOS interface function pointer (stored at 0x1DD0)** |  |
| When | **byte_1DE0 == 0: points to the EFI_LEGACY_BIOS_PROTOCOL instance.** |  |
| When | **byte_1DE0 == 1: set to the TCG2 protocol interface.** |  |
| UINT64 | **qword_1DD0 = 0;** |  |
| Installed | **TPM32 header pointer (stored at 0x1DD8)** |  |
| UINT64 | **qword_1DD8 = 0;** |  |
| Protocol | **selection flag (stored at 0x1DE0 as byte)** |  |
| If | **0: Legacy BIOS Protocol is used.** |  |
| If | **1: TCG2 Protocol is used instead.** |  |
| UINT8 | **byte_1DE0 = 0;** |  |
| TCG2 | **Protocol pointer (stored at 0x1DE8)** |  |
| Valid | **only when byte_1DE0 == 1.** |  |
| UINT64 | **qword_1DE8 = 0;** |  |
| System | **Table pointer (stored at 0x1DF0)** |  |
| EFI_SYSTEM_TABLE | ***gST = NULL;** |  |
| Boot | **Services pointer (stored at 0x1DF8)** |  |
| EFI_BOOT_SERVICES | ***gBS = NULL;** |  |
| Image | **handle (stored at 0x1E00)** |  |
| EFI_HANDLE | **gImageHandle = NULL;** |  |
| Runtime | **Services pointer (stored at 0x1E08)** |  |
| EFI_RUNTIME_SERVICES | ***gRT = NULL;** |  |
| Debug | **Console Output protocol (stored at 0x1E10, cached from GetTcgProtocol)** |  |
| EFI_TCG_PROTOCOL | ***gTcgProtocol = NULL;** |  |
| HOB | **List pointer (stored at 0x1E18)** |  |
| VOID | ***gHobList = NULL;** |  |
| CMOS | **variable byte read from NVRAM index 0x4B (stored at 0x1E20)** |  |
| Used | **by DebugPrint to determine verbosity level.** |  |
| UINT8 | **gDebugNvramByte = 0;** |  |
| LEGX16 | **configuration words (stored at 0x1E28-0x1E30)** |  |
| These | **are saved from the LEGX16 header and written to legacy BIOS** |  |
| configuration | **space during install.** |  |
| UINT16 | **gLegX16Segment  = 0;   // +0x1E28** |  |
| TPM | **Vendor ID Lookup Table (stored at 0x1DC0)** |  |
| Each | **4-byte entry contains a TPM hardware vendor/device ID.** |  |
| The | **table is compared against MEMORY[0xFED40F00] to detect if** |  |
| TPM | **hardware is already present.** |  |
| Entry | **0: 0xF5190100 (vendor:device flags)** |  |
| Entry | **1: 0x011B4E01 (vendor: "NS" = National Semiconductor?)** |  |
| Entry | **2: 0x00020000 (placeholder/end marker)** |  |
| UINT32 | **gTpmVendorIdTable[3] = {** |  |
| GUID | **data blocks (must match the GUIDs declared in the header)** |  |
| EFI_GUID | **gEfiTcgEventLogFormatGuid     = TCG_EVENT_LOG_FORMAT_GUID;** |  |
| Internal | **/ Library function implementations** |  |
| Zero | **the buffer using UINT64-aligned writes for the bulk** |  |
| and | **byte writes for the remainder.** |  |
| ZeroMem | **(Buffer, Length);** |  |
| Read | **CMOS NVRAM index 0x4B to determine debug verbosity.** |  |
| NvramByte | **= IoRead8 (0x70);** |  |
| Read | **platform-specific debug flag from 0xFDAF0490.** |  |
| NvramStatus | **= (*(volatile UINT8 *)0xFDAF0490 & 2) | 1;** |  |
| Determine | **print level: EFI_D_INFO (0x80000004) if verbosity == 1** |  |
| EFI_D_WARN | **(0x80000006) otherwise.** |  |
| if | **((NvramStatus - 1) <= 0xFD) {** |  |
| If | **the message's error level matches the current verbosity, print it.** |  |
| if | **((PrintLevel & ErrorLevel) != 0) {** |  |
| Found | **the HOB List entry; cache the pointer.** |  |
| gHobList | **= gST->ConfigurationTable[Index].VendorTable;** |  |
| Read | **CMOS index 0x4B to determine NVRAM bank size.** |  |
| IoWrite8 | **(0x70, 0x4B);** |  |
| NVRAM | **bank is 16 bytes or fewer; try to locate the TCG protocol.** |  |
| if | **(gBS->LocateProtocol (** |  |
| Locate | **all FV protocol handles.** |  |
| Status | **= gBS->LocateHandleBuffer (** |  |
| Scan | **each FV for the file by GUID.** |  |
| for | **(Index = 0; Index < HandleCount; Index++) {** |  |
| Found | **the file.** |  |
| Forward | **declaration of internal helper.** |  |
| UINT16 | ***** |  |
| Each | **entry is 24 bytes; navigate backwards from the end.** |  |
| EntryBase | **= DevicePathTable + (NumberOfTableEntries - 1 - Index) * 24;** |  |
| Compare | **first 16 bytes against the TCG event log GUID.** |  |
| if | **(InternalCompareMem (** |  |
| Walk | **the vendor data entries following the GUID.** |  |
| Current | **= Entry;** |  |
| Skip | **to next entry (advance by the entry's total length).** |  |
| Current | **= (UINT16 *)((UINT8 *)Current + Current[1]);** |  |
| Type | **4 entry: check if the next 16 bytes match the expected data.** |  |
| Alternative | **GUID for comparison** |  |
| 128 | **KB / 4** |  |
| Size | **field in next dword** |  |
| Calculate | **checksum over the BFI structure bytes.** |  |
| while | **(Count > 0) {** |  |
| Valid | **BFI with matching checksum** |  |
| Patch | **the LEGX16 segment into the BFI structure (offset 35 words = byte 70).** |  |
| Recalculate | **the checksum after patching.** |  |
| Recalculate | **checksum.** |  |
| BfiData | **= BfiEntry + 4;   // Skip the signature dword itself** |  |
| Clear | **first byte of remaining structure** |  |
| Length | **of the checksummed region** |  |
| Store | **the two's complement checksum.** |  |
| Offset | **+0x42 (2 bytes), cleared initially** |  |
| Offset | **+0x04** |  |
| Cache | **the Legacy BIOS interface pointer globally.** |  |
| qword_1DD0 | **= (UINT64)LegBios;** |  |
| TCG2 | **path: register a null callback and use TCG2 protocol for init.** |  |
| if | **(qword_1DE8 == 0) {** |  |
| nullsub_1 | **Status = ((EFI_TCG2_PROTOCOL *)qword_1DE8)->RegisterCallback (** |  |
| 32 | **KB log buffer** |  |
| Legacy | **BIOS Protocol path: call the interface's callback registration.** |  |
| sub_410 | **LegBios->Callback (** |  |
| Ensure | **PM entry is cleared after init** |  |
| TCG2 | **path: unregister via TCG2 protocol.** |  |
| if | **(qword_1DE8 != 0) {** |  |
| Legacy | **BIOS path: unregister via Legacy BIOS Protocol callback.** |  |
| Zero | **TpmLogAddress and TpmLogSize** |  |
| Intentionally | **empty.** |  |
| Main | **initialization and entry point** |  |
| Save | **global handles required by the boot and runtime services libraries.** |  |
| gImageHandle | **= ImageHandle;** |  |
| Initialize | **the HOB list for platform configuration.** |  |
| GetHobList | **();** |  |
| Perform | **the TCG Legacy interface initialization.** |  |
| return | **InitTCGLegacyInterface ();** |  |
| Step | **1: Check if there is already TPM hardware at the legacy TPM** |  |
| for | **(Index = 0; Index < TPM_VENDOR_ID_COUNT; Index++) {** |  |
| TPM | **hardware is already present; nothing for us to do.** |  |
| return | **EFI_SUCCESS;** |  |
| Step | **2: Ensure TPM32 is not already installed.** |  |
| if | **(qword_1DD8 != 0) {** |  |
| Step | **3: Locate the Legacy BIOS Protocol (0x1DB0) or TCG2 protocol.** |  |
| TCG2 | **not found; try the AMI TCG protocol.** |  |
| LegBios | **= NULL;** |  |
| Use | **TCG2 / AMI TCG protocol path** |  |
| Step | **4: Locate the Legacy BIOS Platform Protocol (0x1D80).** |  |
| Step | **5: Locate the Legacy BIOS Protocol (0x1D60).** |  |
| Step | **6: Load the LEGX16 binary from a firmware volume file GUID.** |  |
| LegX16Addr | **= 0;** |  |
| Placeholder | **GUID; actual file GUID** |  |
| Step | **7: Allocate legacy region via Legacy BIOS Platform Protocol (+72).** |  |
| This | **allocates a region in the F000-E000 area for LEGX16.** |  |
| Status | **= LegBiosPlatform->AllocateLegacyRegion (** |  |
| Step | **8: Load the TPM32 binary from firmware volume.** |  |
| Status | **= LocateFirmwareVolumeFile (** |  |
| Placeholder | **(VOID **)&Tpm32Buffer** |  |
| Step | **9: Allocate page-aligned memory for the TPM32 code.** |  |
| TpmCodePhysAddr | **= AllocateAndZeroPagesWrapper (** |  |
| Step | **9b: Copy the TPM32 binary to the allocated page.** |  |
| Step | **10: Allocate a TPM log/data page for the TPM32 driver's use.** |  |
| TpmEntry | **= AllocateAndZeroPagesWrapper (1);   // 1 page = 4 KB** |  |
| Free | **the previously allocated TPM code pages.** |  |
| Step | **11: Check for vendor ACPI table match (MPTPM or ACPI entry).** |  |
| TPM | **hardware already present; find matching ACPI device path entry.** |  |
| UINT16 | ***MatchingEntry;** |  |
| Calculate | **size** |  |
| Skip | **MPTPM loading** |  |
| Step | **12: Load MPTPM (multi-processor TPM) if needed.** |  |
| Placeholder | **(VOID **)&MptpmBuffer** |  |
| Step | **13: Set the TPM32 header fields.** |  |
| TpmSegEntry | **= LegX16Addr;** |  |
| Write | **the TPM32 entry point into the LEGX16 header at the correct offset.** |  |
| Step | **14: Link the TPM32 driver into the legacy BIOS interface.** |  |
| LinkTPM32Driver | **(Tpm32Header, LegBios);** |  |
| Step | **15: Set the LEGX16 control flag (-7424 = 0xE300 shadow enable).** |  |
| Step | **16: Copy the LEGX16 image to the final F000-E000 legacy region.** |  |
| Status | **= LegBiosPlatform->CopyLegacyRegion (** |  |
| Step | **17: Install the legacy interrupt handler.** |  |
| The | **second legacy BIOS protocol instance (0x1D80) provides interrupt** |  |
| LegBiosPlatform | **= (EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *)LegBios; // Reuse for platform operations** |  |
| Initialize | **the shadow region data structure (48 bytes).** |  |
| ZeroMem | **(v46, 48);** |  |
| Use | **Legacy BIOS Platform Protocol function +8 to install the interrupt.** |  |
| Save | **LEGX16 configuration words for later use.** |  |
| gLegX16Segment | **= (UINT16)(ShadowBase >> 4);** |  |
| Step | **18: Allocate legacy region for the configuration data.** |  |
| Write | **the configuration words to the legacy region.** |  |
| Step | **19: Release and re-acquire the legacy region for shadow operations.** |  |
| Step | **20: Scan and patch the BFI marker in the legacy ROM region.** |  |
| ScanAndPatchBfi | **((UINT64)LegBiosPlatform, (UINT64)LegBios, gLegX16Segment);** |  |
| Step | **21: Release the shadow region.** |  |
| Step | **22: Save the installed TPM32 header pointer.** |  |
| qword_1DD8 | **= (UINT64)Tpm32Header;** |  |
| Step | **23: Register a Legacy Boot notification event.** |  |
| Release | **the shadow region on error.** |  |
| Free | **allocated pages on error.** |  |
| if | **(TpmCodePhysAddr != 0xFFFFFFFFFFFFFFFFULL) {** |  |

---
*Generated by HR650X BIOS Decompilation Project*