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