47#define PHYSICAL_PRESENCE_VERSION_TAG "$PV"
48#define PHYSICAL_PRESENCE_VERSION_SIZE 4
53#define TPM_HID_TAG "NNNN0000"
54#define TPM_HID_PNP_SIZE 8
55#define TPM_HID_ACPI_SIZE 9
57#define TPM_PRS_RESL "RESL"
58#define TPM_PRS_RESS "RESS"
59#define TPM_PRS_RES_NAME_SIZE 4
69#define TPM_POS_RES_TEMPLATE_MIN_SIZE (1 + 1 + 2 + 12 + 5 + 2)
75#define MAX_PRS_INT_BUF_SIZE (15*4)
85 UINT64 AddressOfControlArea;
87 UINT8 PlatformSpecificParameters[12];
97 sizeof (mTpm2AcpiTemplate),
98 EFI_TPM2_ACPI_TABLE_REVISION,
107 EFI_TPM2_ACPI_TABLE_START_METHOD_TIS,
135 MemoryAddress = SIZE_4GB - 1;
144 if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
145 (OpRegion->NameString == Name) &&
146 (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
147 (OpRegion->BytePrefix == AML_BYTE_PREFIX))
150 ASSERT (GuidHob !=
NULL);
151 Tcg2AcpiCommunicateBufferHob = GET_GUID_HOB_DATA (GuidHob);
153 ASSERT (MemoryAddress != 0);
157 OpRegion->RegionOffset = (UINT32)(
UINTN)MemoryAddress;
158 OpRegion->RegionLen = (UINT8)Size;
164 return (VOID *)(
UINTN)MemoryAddress;
188 UINTN CommBufferSize;
192 if (TcgNvs ==
NULL) {
193 DEBUG ((DEBUG_ERROR,
"%a - Input argument is NULL!\n", __func__));
194 return EFI_INVALID_PARAMETER;
199 if (EFI_ERROR (Status)) {
200 DEBUG ((DEBUG_ERROR,
"%a - Failed to locate SMM communciation common buffer - %r!\n", __func__, Status));
207 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
215 MmCommMemRegion = (
EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MmCommMemRegion + PiSmmCommunicationRegionTable->DescriptorSize);
218 if (Index >= PiSmmCommunicationRegionTable->NumberOfEntries) {
220 DEBUG ((DEBUG_ERROR,
"%a - Could not find a common buffer that is big enough for NVS!\n", __func__));
221 return EFI_OUT_OF_RESOURCES;
228 ZeroMem (CommHeader, CommBufferSize);
234 CommBuffer->Function = TpmNvsMmExchangeInfo;
238 Status =
gBS->LocateProtocol (&gEfiMmCommunicationProtocolGuid,
NULL, (VOID **)&MmCommunication);
239 if (!EFI_ERROR (Status)) {
240 Status = MmCommunication->Communicate (MmCommunication, CommHeader, &CommBufferSize);
241 DEBUG ((DEBUG_INFO,
"%a - Communicate() = %r\n", __func__, Status));
243 DEBUG ((DEBUG_ERROR,
"%a - Failed to locate MmCommunication protocol - %r\n", __func__, Status));
248 if (!EFI_ERROR (CommBuffer->ReturnStatus)) {
250 TcgNvs->PhysicalPresence.SoftwareSmi = (UINT8)CommBuffer->RegisteredPpSwiValue;
251 TcgNvs->MemoryClear.SoftwareSmi = (UINT8)CommBuffer->RegisteredMcSwiValue;
254 "%a Communication returned software SMI value. PP: 0x%x; MC: 0x%x.\n",
256 TcgNvs->PhysicalPresence.SoftwareSmi,
257 TcgNvs->MemoryClear.SoftwareSmi
286 for (DataPtr = (UINT8 *)(Table + 1);
287 DataPtr <= (UINT8 *)((UINT8 *)Table + Table->Length - PHYSICAL_PRESENCE_VERSION_SIZE);
290 if (
AsciiStrCmp ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) == 0) {
291 Status =
AsciiStrCpyS ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_SIZE, PPVer);
292 DEBUG ((DEBUG_INFO,
"TPM2 Physical Presence Interface Version update status 0x%x\n", Status));
297 return EFI_NOT_FOUND;
315 IN UINT32 *IrqBuffer,
316 IN UINT32 IrqBuffserSize,
317 OUT BOOLEAN *IsShortFormPkgLength
323 UINT32 OrignalPkgLength;
326 OrignalPkgLength = 0;
367 for (DataPtr = (UINT8 *)(Table + 1);
368 DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));
371 if (
CompareMem (DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) == 0) {
375 DataPtr += TPM_PRS_RES_NAME_SIZE + 1;
377 if ((*DataPtr & (BIT7|BIT6)) == 0) {
378 OrignalPkgLength = (UINT32)*DataPtr;
379 DataEndPtr = DataPtr + OrignalPkgLength;
389 if (*(DataPtr + 1) == AML_BYTE_PREFIX) {
391 }
else if (*(DataPtr + 1) == AML_WORD_PREFIX) {
393 }
else if (*(DataPtr + 1) == AML_DWORD_PREFIX) {
397 return EFI_UNSUPPORTED;
401 return EFI_UNSUPPORTED;
407 NewPkgLength += 19 + IrqBuffserSize;
408 if (NewPkgLength > 63) {
412 if (NewPkgLength > OrignalPkgLength) {
414 return EFI_INVALID_PARAMETER;
420 *DataPtr = (UINT8)NewPkgLength;
426 *(DataPtr + 2) = (UINT8)(IrqBuffserSize + 19);
431 *IsShortFormPkgLength =
TRUE;
440 if (NewPkgLength > 63) {
442 OrignalPkgLength = 0;
443 for (DataPtr = (UINT8 *)(Table + 1);
444 DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));
447 if (
CompareMem (DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) == 0) {
451 DataPtr += TPM_PRS_RES_NAME_SIZE + 1;
453 if ((*DataPtr & (BIT7|BIT6)) != 0) {
454 OrignalPkgLength = (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr & 0x0F);
455 DataEndPtr = DataPtr + OrignalPkgLength;
459 NewPkgLength += 1 + ((*DataPtr & (BIT7|BIT6)) >> 6);
464 if (*(DataPtr + NewPkgLength) == AML_BYTE_PREFIX) {
466 }
else if (*(DataPtr + NewPkgLength) == AML_WORD_PREFIX) {
468 }
else if (*(DataPtr + NewPkgLength) == AML_DWORD_PREFIX) {
472 return EFI_UNSUPPORTED;
476 return EFI_UNSUPPORTED;
482 NewPkgLength += 19 + IrqBuffserSize;
484 if (NewPkgLength > OrignalPkgLength) {
486 return EFI_INVALID_PARAMETER;
492 *DataPtr = (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x0F);
493 *(DataPtr + 1) = (UINT8)((NewPkgLength & 0xFF0) >> 4);
499 *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) = (UINT8)(IrqBuffserSize + 19);
504 *IsShortFormPkgLength =
FALSE;
510 if (DataPtr >= (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE))) {
511 return EFI_NOT_FOUND;
518 DataPtr += NewPkgLength - (5 + IrqBuffserSize + 2);
522 *(DataPtr + 1) = (UINT8)(2 + IrqBuffserSize);
526 *(DataPtr + 4) = (UINT8)(IrqBuffserSize /
sizeof (UINT32));
530 CopyMem (DataPtr + 5, IrqBuffer, IrqBuffserSize);
535 DataPtr += 5 + IrqBuffserSize;
536 *DataPtr = ACPI_END_TAG_DESCRIPTOR;
543 if (DataPtr < DataEndPtr) {
565 CHAR8 Hid[TPM_HID_ACPI_SIZE];
566 UINT32 ManufacturerID;
567 UINT32 FirmwareVersion1;
568 UINT32 FirmwareVersion2;
576 ZeroMem (Hid, TPM_HID_ACPI_SIZE);
582 if (!EFI_ERROR (Status)) {
583 DEBUG ((DEBUG_INFO,
"TPM_PT_MANUFACTURER 0x%08x\n", ManufacturerID));
588 if (((ManufacturerID >> 24) == 0x00) || ((ManufacturerID >> 24) == 0x20)) {
593 CopyMem (Hid, &ManufacturerID, 3);
599 CopyMem (Hid, &ManufacturerID, 4);
603 DEBUG ((DEBUG_ERROR,
"Get TPM_PT_MANUFACTURER failed %x!\n", Status));
609 if (!EFI_ERROR (Status)) {
610 DEBUG ((DEBUG_INFO,
"TPM_PT_FIRMWARE_VERSION_1 0x%x\n", FirmwareVersion1));
611 DEBUG ((DEBUG_INFO,
"TPM_PT_FIRMWARE_VERSION_2 0x%x\n", FirmwareVersion2));
616 AsciiSPrint (Hid + 3, TPM_HID_PNP_SIZE - 3,
"%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));
618 AsciiSPrint (Hid + 4, TPM_HID_ACPI_SIZE - 4,
"%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));
621 DEBUG ((DEBUG_ERROR,
"Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", Status));
629 for (DataPtr = (UINT8 *)(Table + 1);
630 DataPtr <= (UINT8 *)((UINT8 *)Table + Table->Length - TPM_HID_PNP_SIZE);
633 if (
AsciiStrCmp ((CHAR8 *)DataPtr, TPM_HID_TAG) == 0) {
635 CopyMem (DataPtr, Hid, TPM_HID_PNP_SIZE);
639 *(DataPtr + TPM_HID_PNP_SIZE) = AML_NOOP_OP;
641 CopyMem (DataPtr, Hid, TPM_HID_ACPI_SIZE);
644 DEBUG ((DEBUG_INFO,
"TPM2 ACPI _HID is patched to %a\n", Hid));
650 DEBUG ((DEBUG_ERROR,
"TPM2 ACPI HID TAG for patch not found!\n"));
651 return EFI_NOT_FOUND;
671 UINT32 *PossibleIrqNumBuf;
672 UINT32 PossibleIrqNumBufSize;
673 BOOLEAN IsShortFormPkgLength;
675 IsShortFormPkgLength =
FALSE;
695 EV_POSTCODE_INFO_ACPI_DATA,
709 "Current physical presence interface version - %a\n",
710 (CHAR8 *)
PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer)
717 if (EFI_ERROR (Status)) {
721 if (
PcdGet32 (PcdTpm2CurrentIrqNum) != 0) {
725 PossibleIrqNumBuf = (UINT32 *)
PcdGetPtr (PcdTpm2PossibleIrqNumBuf);
726 PossibleIrqNumBufSize = (UINT32)
PcdGetSize (PcdTpm2PossibleIrqNumBuf);
728 if ((PossibleIrqNumBufSize <= MAX_PRS_INT_BUF_SIZE) && ((PossibleIrqNumBufSize %
sizeof (UINT32)) == 0)) {
732 "UpdatePossibleResource status - %x. TPM2 service may not ready in OS.\n",
738 "PcdTpm2PossibleIrqNumBuf size %x is not correct. TPM2 service may not ready in OS.\n",
739 PossibleIrqNumBufSize
744 ASSERT (Table->OemTableId ==
SIGNATURE_64 (
'T',
'p',
'm',
'2',
'T',
'a',
'b',
'l'));
745 CopyMem (Table->OemId,
PcdGetPtr (PcdAcpiDefaultOemId),
sizeof (Table->OemId));
747 ASSERT (mTcgNvs !=
NULL);
748 mTcgNvs->TpmIrqNum =
PcdGet32 (PcdTpm2CurrentIrqNum);
749 mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength;
756 Status =
gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid,
NULL, (VOID **)&AcpiTable);
760 Status = AcpiTable->InstallAcpiTable (
788 TPM2_PTP_INTERFACE_TYPE InterfaceType;
799 EV_POSTCODE_INFO_ACPI_DATA,
802 mTpm2AcpiTemplate.Header.Length
805 mTpm2AcpiTemplate.Header.Revision =
PcdGet8 (PcdTpm2AcpiTableRev);
806 DEBUG ((DEBUG_INFO,
"Tpm2 ACPI table revision is %d\n", mTpm2AcpiTemplate.Header.Revision));
813 if (mTpm2AcpiTemplate.Header.Revision >= EFI_TPM2_ACPI_TABLE_REVISION_4) {
814 mTpm2AcpiTemplate.Flags = (mTpm2AcpiTemplate.Flags & 0xFFFF0000) |
PcdGet8 (PcdTpmPlatformClass);
815 DEBUG ((DEBUG_INFO,
"Tpm2 ACPI table PlatformClass is %d\n", (mTpm2AcpiTemplate.Flags & 0x0000FFFF)));
818 mTpm2AcpiTemplate.Laml =
PcdGet32 (PcdTpm2AcpiTableLaml);
819 mTpm2AcpiTemplate.Lasa =
PcdGet64 (PcdTpm2AcpiTableLasa);
820 if ((mTpm2AcpiTemplate.Header.Revision < EFI_TPM2_ACPI_TABLE_REVISION_4) ||
821 (mTpm2AcpiTemplate.Laml == 0) || (mTpm2AcpiTemplate.Lasa == 0))
829 InterfaceType =
PcdGet8 (PcdActiveTpmInterfaceType);
830 switch (InterfaceType) {
831 case Tpm2PtpInterfaceCrb:
832 mTpm2AcpiTemplate.StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE;
833 mTpm2AcpiTemplate.AddressOfControlArea =
PcdGet64 (PcdTpmBaseAddress) + 0x40;
835 ControlArea->CommandSize = 0xF80;
836 ControlArea->ResponseSize = 0xF80;
837 ControlArea->Command =
PcdGet64 (PcdTpmBaseAddress) + 0x80;
838 ControlArea->Response =
PcdGet64 (PcdTpmBaseAddress) + 0x80;
840 case Tpm2PtpInterfaceFifo:
841 case Tpm2PtpInterfaceTis:
844 DEBUG ((DEBUG_ERROR,
"TPM2 InterfaceType get error! %d\n", InterfaceType));
848 CopyMem (mTpm2AcpiTemplate.Header.OemId,
PcdGetPtr (PcdAcpiDefaultOemId),
sizeof (mTpm2AcpiTemplate.Header.OemId));
849 OemTableId =
PcdGet64 (PcdAcpiDefaultOemTableId);
850 CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
851 mTpm2AcpiTemplate.Header.OemRevision =
PcdGet32 (PcdAcpiDefaultOemRevision);
852 mTpm2AcpiTemplate.Header.CreatorId =
PcdGet32 (PcdAcpiDefaultCreatorId);
853 mTpm2AcpiTemplate.Header.CreatorRevision =
PcdGet32 (PcdAcpiDefaultCreatorRevision);
858 Status =
gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid,
NULL, (VOID **)&AcpiTable);
861 Status = AcpiTable->InstallAcpiTable (
864 mTpm2AcpiTemplate.Header.Length,
895 DEBUG ((DEBUG_ERROR,
"No TPM2 DTPM instance required!\n"));
896 return EFI_UNSUPPORTED;
#define EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI GetSectionFromFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
#define SIGNATURE_64(A, B, C, D, E, F, G, H)
#define OFFSET_OF(TYPE, Field)
#define SIGNATURE_32(A, B, C, D)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGetSize(TokenName)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define PcdGetPtr(TokenName)
EFI_STATUS PublishTpm2(VOID)
VOID * AssignOpRegion(EFI_ACPI_DESCRIPTION_HEADER *Table, UINT32 Name, UINT16 Size)
EFI_STATUS UpdatePossibleResource(IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, IN UINT32 *IrqBuffer, IN UINT32 IrqBuffserSize, OUT BOOLEAN *IsShortFormPkgLength)
EFI_STATUS EFIAPI InitializeTcgAcpi(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS PublishAcpiTable(VOID)
EFI_STATUS UpdatePPVersion(EFI_ACPI_DESCRIPTION_HEADER *Table, CHAR8 *PPVer)
EFI_STATUS EFIAPI ExchangeCommonBuffer(IN OUT TCG_NVS *TcgNvs)
EFI_STATUS UpdateHID(EFI_ACPI_DESCRIPTION_HEADER *Table)
EFI_STATUS EFIAPI Tpm2GetCapabilityFirmwareVersion(OUT UINT32 *FirmwareVersion1, OUT UINT32 *FirmwareVersion2)
EFI_STATUS EFIAPI Tpm2GetCapabilityManufactureID(OUT UINT32 *ManufactureId)
EFI_STATUS EFIAPI TpmMeasureAndLogData(IN UINT32 PcrIndex, IN UINT32 EventType, IN VOID *EventLog, IN UINT32 LogLen, IN VOID *HashData, IN UINT64 HashDataLen)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
EFI_PHYSICAL_ADDRESS PhysicalStart
EFI_PHYSICAL_ADDRESS Tcg2AcpiCommunicateBuffer