@@ -11,6 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
11
11
#include <IndustryStandard/Acpi.h>
12
12
#include <IndustryStandard/PeImage.h>
13
13
#include <IndustryStandard/TcpaAcpi.h>
14
+ #include <IndustryStandard/Tpm2Acpi.h>
14
15
15
16
#include <Guid/GlobalVariable.h>
16
17
#include <Guid/HobList.h>
@@ -20,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
20
21
#include <Guid/ImageAuthentication.h>
21
22
#include <Guid/TpmInstance.h>
22
23
24
+ #include <Protocol/AcpiTable.h>
23
25
#include <Protocol/DevicePath.h>
24
26
#include <Protocol/MpService.h>
25
27
#include <Protocol/VariableWrite.h>
@@ -45,6 +47,40 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
45
47
#include <Library/ReportStatusCodeLib.h>
46
48
#include <Library/Tcg2PhysicalPresenceLib.h>
47
49
#include <Library/DasharoVariablesLib.h>
50
+ #include <Library/TpmMeasurementLib.h>
51
+
52
+ #pragma pack(1)
53
+
54
+ typedef struct {
55
+ EFI_ACPI_DESCRIPTION_HEADER Header ;
56
+ // Flags field is replaced in version 4 and above
57
+ // BIT0~15: PlatformClass This field is only valid for version 4 and above
58
+ // BIT16~31: Reserved
59
+ UINT32 Flags ;
60
+ UINT64 AddressOfControlArea ;
61
+ UINT32 StartMethod ;
62
+ UINT8 PlatformSpecificParameters [12 ]; // size up to 12
63
+ UINT32 Laml ; // Optional
64
+ UINT64 Lasa ; // Optional
65
+ } EFI_TPM2_ACPI_TABLE_V4 ;
66
+
67
+ EFI_TPM2_ACPI_TABLE_V4 mTpm2AcpiTemplate = {
68
+ {
69
+ EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE ,
70
+ sizeof (mTpm2AcpiTemplate ),
71
+ EFI_TPM2_ACPI_TABLE_REVISION ,
72
+ //
73
+ // Compiler initializes the remaining bytes to 0
74
+ // These fields should be filled in in production
75
+ //
76
+ },
77
+ 0 , // BIT0~15: PlatformClass
78
+ // BIT16~31: Reserved
79
+ 0 , // Control Area
80
+ EFI_TPM2_ACPI_TABLE_START_METHOD_TIS , // StartMethod
81
+ };
82
+
83
+ #pragma pack()
48
84
49
85
#define PERF_ID_TCG2_DXE 0x3120
50
86
@@ -2710,6 +2746,106 @@ InstallTcg2 (
2710
2746
return Status ;
2711
2747
}
2712
2748
2749
+ /**
2750
+ Publish TPM2 ACPI table
2751
+
2752
+ @retval EFI_SUCCESS The TPM2 ACPI table is published successfully.
2753
+ @retval Others The TPM2 ACPI table is not published.
2754
+
2755
+ **/
2756
+ EFI_STATUS
2757
+ PublishTpm2 (
2758
+ VOID
2759
+ )
2760
+ {
2761
+ EFI_STATUS Status ;
2762
+ EFI_ACPI_TABLE_PROTOCOL * AcpiTable ;
2763
+ UINTN TableKey ;
2764
+ UINT64 OemTableId ;
2765
+ EFI_TPM2_ACPI_CONTROL_AREA * ControlArea ;
2766
+ TPM2_PTP_INTERFACE_TYPE InterfaceType ;
2767
+
2768
+ //
2769
+ // Measure to PCR[0] with event EV_POST_CODE ACPI DATA.
2770
+ // The measurement has to be done before any update.
2771
+ // Otherwise, the PCR record would be different after event log update
2772
+ // or the PCD configuration change.
2773
+ //
2774
+ TpmMeasureAndLogData (
2775
+ 0 ,
2776
+ EV_POST_CODE ,
2777
+ EV_POSTCODE_INFO_ACPI_DATA ,
2778
+ ACPI_DATA_LEN ,
2779
+ & mTpm2AcpiTemplate ,
2780
+ mTpm2AcpiTemplate .Header .Length
2781
+ );
2782
+
2783
+ mTpm2AcpiTemplate .Header .Revision = PcdGet8 (PcdTpm2AcpiTableRev );
2784
+ DEBUG ((DEBUG_INFO , "Tpm2 ACPI table revision is %d\n" , mTpm2AcpiTemplate .Header .Revision ));
2785
+
2786
+ //
2787
+ // PlatformClass is only valid for version 4 and above
2788
+ // BIT0~15: PlatformClass
2789
+ // BIT16~31: Reserved
2790
+ //
2791
+ if (mTpm2AcpiTemplate .Header .Revision >= EFI_TPM2_ACPI_TABLE_REVISION_4 ) {
2792
+ mTpm2AcpiTemplate .Flags = (mTpm2AcpiTemplate .Flags & 0xFFFF0000 ) | PcdGet8 (PcdTpmPlatformClass );
2793
+ DEBUG ((DEBUG_INFO , "Tpm2 ACPI table PlatformClass is %d\n" , (mTpm2AcpiTemplate .Flags & 0x0000FFFF )));
2794
+ }
2795
+
2796
+ mTpm2AcpiTemplate .Laml = PcdGet32 (PcdTpm2AcpiTableLaml );
2797
+ mTpm2AcpiTemplate .Lasa = PcdGet64 (PcdTpm2AcpiTableLasa );
2798
+ if ((mTpm2AcpiTemplate .Header .Revision < EFI_TPM2_ACPI_TABLE_REVISION_4 ) ||
2799
+ (mTpm2AcpiTemplate .Laml == 0 ) || (mTpm2AcpiTemplate .Lasa == 0 )) {
2800
+ //
2801
+ // If version is smaller than 4 or Laml/Lasa is not valid, rollback to original Length.
2802
+ //
2803
+ mTpm2AcpiTemplate .Header .Length = sizeof (EFI_TPM2_ACPI_TABLE );
2804
+ }
2805
+
2806
+ InterfaceType = PcdGet8 (PcdActiveTpmInterfaceType );
2807
+ switch (InterfaceType ) {
2808
+ case Tpm2PtpInterfaceCrb :
2809
+ mTpm2AcpiTemplate .StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE ;
2810
+ mTpm2AcpiTemplate .AddressOfControlArea = PcdGet64 (PcdTpmBaseAddress ) + 0x40 ;
2811
+ ControlArea = (EFI_TPM2_ACPI_CONTROL_AREA * )(UINTN )mTpm2AcpiTemplate .AddressOfControlArea ;
2812
+ ControlArea -> CommandSize = 0xF80 ;
2813
+ ControlArea -> ResponseSize = 0xF80 ;
2814
+ ControlArea -> Command = PcdGet64 (PcdTpmBaseAddress ) + 0x80 ;
2815
+ ControlArea -> Response = PcdGet64 (PcdTpmBaseAddress ) + 0x80 ;
2816
+ break ;
2817
+ case Tpm2PtpInterfaceFifo :
2818
+ case Tpm2PtpInterfaceTis :
2819
+ break ;
2820
+ default :
2821
+ DEBUG ((EFI_D_ERROR , "TPM2 InterfaceType get error! %d\n" , InterfaceType ));
2822
+ break ;
2823
+ }
2824
+
2825
+ CopyMem (mTpm2AcpiTemplate .Header .OemId , PcdGetPtr (PcdAcpiDefaultOemId ), sizeof (mTpm2AcpiTemplate .Header .OemId ));
2826
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId );
2827
+ CopyMem (& mTpm2AcpiTemplate .Header .OemTableId , & OemTableId , sizeof (UINT64 ));
2828
+ mTpm2AcpiTemplate .Header .OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision );
2829
+ mTpm2AcpiTemplate .Header .CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId );
2830
+ mTpm2AcpiTemplate .Header .CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision );
2831
+
2832
+ //
2833
+ // Construct ACPI table
2834
+ //
2835
+ Status = gBS -> LocateProtocol (& gEfiAcpiTableProtocolGuid , NULL , (VOID * * ) & AcpiTable );
2836
+ ASSERT_EFI_ERROR (Status );
2837
+
2838
+ Status = AcpiTable -> InstallAcpiTable (
2839
+ AcpiTable ,
2840
+ & mTpm2AcpiTemplate ,
2841
+ mTpm2AcpiTemplate .Header .Length ,
2842
+ & TableKey
2843
+ );
2844
+ ASSERT_EFI_ERROR (Status );
2845
+
2846
+ return Status ;
2847
+ }
2848
+
2713
2849
/**
2714
2850
The driver's entry point. It publishes EFI Tcg2 Protocol.
2715
2851
@@ -2895,5 +3031,11 @@ DriverEntry (
2895
3031
Status = InstallTcg2 ();
2896
3032
DEBUG ((DEBUG_INFO , "InstallTcg2 - %r\n" , Status ));
2897
3033
3034
+ //
3035
+ // Set TPM2 ACPI table
3036
+ //
3037
+ Status = PublishTpm2 ();
3038
+ ASSERT_EFI_ERROR (Status );
3039
+
2898
3040
return Status ;
2899
3041
}
0 commit comments