1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
/** @file
TPM2 table parser
Copyright (c) 2024, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- TCG ACPI Specification - Version 1.4, Revision 15, April 3, 2024.
(https://trustedcomputinggroup.org/resource/tcg-acpi-specification/)
**/
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/Tpm2Acpi.h>
#include <Library/UefiLib.h>
#include "AcpiParser.h"
#include "AcpiTableParser.h"
#define TPM2_ACPI_TABLE_LOG_AREA_SIZE (sizeof(UINT32) + sizeof(UINT64))
// Log area parameter offset is different on ACPI table revision 4 and 5, due to different SMSP max size.
#define TPM2_ACPI_TABLE_SIZE_WITH_LOG_AREA_REVISION_4 (sizeof(EFI_TPM2_ACPI_TABLE) + EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 + TPM2_ACPI_TABLE_LOG_AREA_SIZE)
#define TPM2_ACPI_TABLE_SIZE_WITH_LOG_AREA_REVISION_5 (sizeof(EFI_TPM2_ACPI_TABLE) + EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_5 + TPM2_ACPI_TABLE_LOG_AREA_SIZE)
// Local variables
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
STATIC UINT32 *StartMethod;
/**
An ACPI_PARSER array describing the ACPI TPM 2.0 Table.
**/
STATIC CONST ACPI_PARSER Tpm2Parser[] = {
PARSE_ACPI_HEADER (&AcpiHdrInfo),
{ L"Platform Class", 2, 36, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Reserved", 2, 38, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Address of CRB Control Area",8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
{ L"Start Method", 4, 48, L"0x%x", NULL, (VOID **)&StartMethod, NULL, NULL }
};
/**
An ACPI_PARSER array describing the ACPI TPM 2.0 Table Log Area entries.
**/
STATIC CONST ACPI_PARSER Tpm2LogArea[] = {
{ L"Log Area Minimum Length", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Log Area Start Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL }
};
/**
An ACPI_PARSER array describing the Start Method Specific Parameters for Arm SMC Start Method table.
**/
STATIC CONST ACPI_PARSER Tpm2StartMethodArmSmc[] = {
{ L"Interrupt", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Flags", 1, 4, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Operation Flags", 1, 5, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Attributes", 1, 6, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL },
{ L"SMC/HVC Function ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
};
/**
An ACPI_PARSER array describing the Start Method Specific Parameters for Arm FF-A table.
**/
STATIC CONST ACPI_PARSER Tpm2StartMethodArmFFA[] = {
{ L"Flags", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Attributes", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Partition ID", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
{ L"Reserved", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL },
};
/**
This function parses the ACPI TPM2 table.
When trace is enabled this function parses the TPM2 table and
traces the ACPI table fields.
This function also performs validation of the ACPI table fields.
@param [in] Trace If TRUE, trace the ACPI fields.
@param [in] Ptr Pointer to the start of the buffer.
@param [in] AcpiTableLength Length of the ACPI table.
@param [in] AcpiTableRevision Revision of the ACPI table.
**/
VOID
EFIAPI
ParseAcpiTpm2 (
IN BOOLEAN Trace,
IN UINT8 *Ptr,
IN UINT32 AcpiTableLength,
IN UINT8 AcpiTableRevision
)
{
UINT32 Offset;
BOOLEAN LogAreaPresent;
if (!Trace) {
return;
}
Offset = ParseAcpi (
TRUE,
0,
"TPM2",
Ptr,
AcpiTableLength,
PARSER_PARAMS (Tpm2Parser)
);
// Log area parameters are optional. Presence is determined by table length.
LogAreaPresent = (*AcpiHdrInfo.Revision == EFI_TPM2_ACPI_TABLE_REVISION_4 && AcpiTableLength == TPM2_ACPI_TABLE_SIZE_WITH_LOG_AREA_REVISION_4) ||
(*AcpiHdrInfo.Revision == EFI_TPM2_ACPI_TABLE_REVISION_5 && AcpiTableLength == TPM2_ACPI_TABLE_SIZE_WITH_LOG_AREA_REVISION_5);
switch (*StartMethod) {
case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_SMC:
ParseAcpi (
TRUE,
0,
"Start Method Specific Parameters for Arm SMC",
Ptr + Offset,
AcpiTableLength - Offset,
PARSER_PARAMS (Tpm2StartMethodArmSmc)
);
break;
case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_FFA:
ParseAcpi (
TRUE,
0,
"Start Method Specific Parameters for Arm FF-A",
Ptr + Offset,
AcpiTableLength - Offset,
PARSER_PARAMS (Tpm2StartMethodArmFFA)
);
break;
default:
Print (
L"WARNING: Start Method %u not supported\n",
*StartMethod
);
break;
}
if (LogAreaPresent) {
Offset += (*AcpiHdrInfo.Revision == EFI_TPM2_ACPI_TABLE_REVISION_4) ?
EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 :
EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_5;
ParseAcpi (
TRUE,
0,
"TPM2 Log Area",
Ptr + Offset,
AcpiTableLength - Offset,
PARSER_PARAMS (Tpm2LogArea)
);
}
}
|