Skip to content

Commit 6b25cc1

Browse files
Abdul Lateef AttarAbdul Lateef Attar
authored andcommitted
ShellPkg/AcpiView: Adds FPDT Parser
Add a new parser for the Firmware Performance Data Table (FPDT), as per the ACPI6.5 specification. Signed-off-by: Abdul Lateef Attar <[email protected]>
1 parent 46548b1 commit 6b25cc1

File tree

4 files changed

+289
-1
lines changed

4 files changed

+289
-1
lines changed

ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
55
Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
6-
Copyright (c) 2022, AMD Incorporated. All rights reserved.
6+
Copyright (c) 2022 - 2025, AMD Incorporated. All rights reserved.
77
SPDX-License-Identifier: BSD-2-Clause-Patent
88
**/
99

@@ -795,6 +795,27 @@ ParseAcpiFadt (
795795
IN UINT8 AcpiTableRevision
796796
);
797797

798+
/**
799+
This function parses the ACPI FPDT table.
800+
This function parses the FPDT table and optionally traces the ACPI
801+
table fields.
802+
803+
This function also performs validation of the ACPI table fields.
804+
805+
@param [in] Trace If TRUE, trace the ACPI fields.
806+
@param [in] Ptr Pointer to the start of the buffer.
807+
@param [in] AcpiTableLength Length of the ACPI table.
808+
@param [in] AcpiTableRevision Revision of the ACPI table.
809+
**/
810+
VOID
811+
EFIAPI
812+
ParseAcpiFpdt (
813+
IN BOOLEAN Trace,
814+
IN UINT8 *Ptr,
815+
IN UINT32 AcpiTableLength,
816+
IN UINT8 AcpiTableRevision
817+
);
818+
798819
/**
799820
This function parses the ACPI GTDT table.
800821
When trace is enabled this function parses the GTDT table and
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/** @file
2+
Firmware Performance Data Table (FPDT) table parser
3+
4+
Copyright (c) 2025, AMD Incorporated. All rights reserved.
5+
SPDX-License-Identifier: BSD-2-Clause-Patent
6+
7+
@par Reference(s):
8+
- ACPI 6.5 Specification - August 2022
9+
**/
10+
11+
#include <IndustryStandard/Acpi.h>
12+
#include <Library/UefiLib.h>
13+
#include <Library/DebugLib.h>
14+
#include "AcpiParser.h"
15+
#include "AcpiTableParser.h"
16+
#include "AcpiViewConfig.h"
17+
18+
// Local Variables
19+
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
20+
21+
/**
22+
An ACPI_PARSER array describing the ACPI FPDT performance record header.
23+
**/
24+
STATIC CONST ACPI_PARSER FpdtPerfRecordParser[] = {
25+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
26+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
27+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }
28+
};
29+
30+
/**
31+
An ACPI_PARSER array describing the ACPI FPDT boot performance pointer record.
32+
**/
33+
STATIC CONST ACPI_PARSER FpdtBootPerfPointerParser[] = {
34+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
35+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
36+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
37+
{ L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
38+
{ L"BootPerformanceTablePointer", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }
39+
};
40+
41+
/**
42+
An ACPI_PARSER array describing the ACPI FPDT S3 performance pointer record.
43+
**/
44+
STATIC CONST ACPI_PARSER FpdtS3PerfPointerParser[] = {
45+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
46+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
47+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
48+
{ L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
49+
{ L"S3PerformanceTablePointer", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }
50+
};
51+
52+
/**
53+
An ACPI_PARSER array describing the ACPI FPDT firmware table header.
54+
**/
55+
STATIC CONST ACPI_PARSER AcpiFpdtHdrParser[] = {
56+
{ L"Signature", 4, 0, NULL, Dump4Chars, NULL, NULL, NULL },
57+
{ L"Length", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
58+
};
59+
60+
/**
61+
An ACPI_PARSER array describing the ACPI FPDT firmware basic boot record.
62+
**/
63+
STATIC CONST ACPI_PARSER FpdtBasicBootRecordParser[] = {
64+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
65+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
66+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
67+
{ L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
68+
{ L"ResetEnd", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
69+
{ L"OsLoaderLoadImageStart", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL },
70+
{ L"OsLoaderStartImageStart", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
71+
{ L"ExitBootServicesEntry", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
72+
{ L"ExitBootServicesExit", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }
73+
};
74+
75+
/**
76+
An ACPI_PARSER array describing the ACPI FPDT S3 resume record.
77+
**/
78+
STATIC CONST ACPI_PARSER FpdtS3ResumeRecordParser[] = {
79+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
80+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
81+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
82+
{ L"ResumeCount", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
83+
{ L"FullResume", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
84+
{ L"AverageResume", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL }
85+
};
86+
87+
/**
88+
An ACPI_PARSER array describing the ACPI FPDT S3 suspend record.
89+
**/
90+
STATIC CONST ACPI_PARSER FpdtS3SuspendRecordParser[] = {
91+
{ L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
92+
{ L"Length", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
93+
{ L"Revision", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
94+
{ L"SuspendStart", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
95+
{ L"SuspendEnd", 8, 12, L"0x%lx", NULL, NULL, NULL, NULL }
96+
};
97+
98+
/**
99+
An ACPI_PARSER array describing the ACPI FPDT Table.
100+
**/
101+
STATIC CONST ACPI_PARSER FpdtParser[] = {
102+
PARSE_ACPI_HEADER (&AcpiHdrInfo)
103+
};
104+
105+
/**
106+
This function parses the ACPI FPDT table.
107+
This function parses the FPDT table and optionally traces the ACPI
108+
table fields.
109+
110+
This function also performs validation of the ACPI table fields.
111+
112+
@param [in] Trace If TRUE, trace the ACPI fields.
113+
@param [in] Ptr Pointer to the start of the buffer.
114+
@param [in] AcpiTableLength Length of the ACPI table.
115+
@param [in] AcpiTableRevision Revision of the ACPI table.
116+
**/
117+
VOID
118+
EFIAPI
119+
ParseAcpiFpdt (
120+
IN BOOLEAN Trace,
121+
IN UINT8 *Ptr,
122+
IN UINT32 AcpiTableLength,
123+
IN UINT8 AcpiTableRevision
124+
)
125+
{
126+
EFI_ACPI_6_5_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD *FpdtBasicBootPtr;
127+
EFI_ACPI_6_5_FPDT_FIRMWARE_BASIC_BOOT_RECORD *FpdtBasicBootRec;
128+
EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER *FpdtRecHdr;
129+
EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;
130+
EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER *FpdtHdr;
131+
EFI_ACPI_6_5_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD *FpdtS3Ptr;
132+
EFI_ACPI_6_5_FPDT_S3_RESUME_RECORD *FpdtS3ResumeRec;
133+
EFI_ACPI_6_5_FPDT_S3_SUSPEND_RECORD *FpdtS3SuspendRec;
134+
UINT32 Offset;
135+
UINT32 RecOffset;
136+
UINT8 *RecordPtr;
137+
138+
if (!Trace) {
139+
return;
140+
}
141+
142+
Offset = ParseAcpi (
143+
TRUE,
144+
0,
145+
"FPDT",
146+
Ptr,
147+
AcpiTableLength,
148+
PARSER_PARAMS (FpdtParser)
149+
);
150+
151+
RecordPtr = Ptr + Offset;
152+
153+
while (Offset < AcpiTableLength) {
154+
RecordHeader = (EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER *)RecordPtr;
155+
156+
if (RecordHeader->Type == EFI_ACPI_6_5_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER) {
157+
FpdtBasicBootPtr = (EFI_ACPI_6_5_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD *)RecordPtr;
158+
ParseAcpi (
159+
TRUE,
160+
2,
161+
"FPDT Boot Performance Pointer Record",
162+
RecordPtr,
163+
FpdtBasicBootPtr->Header.Length,
164+
PARSER_PARAMS (FpdtBootPerfPointerParser)
165+
);
166+
// Parse the header AcpiFpdtHdrParser
167+
ParseAcpi (
168+
TRUE,
169+
4,
170+
"Firmware Basic Boot Performance Table",
171+
(UINT8 *)(UINTN)(FpdtBasicBootPtr->BootPerformanceTablePointer),
172+
sizeof (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER),
173+
PARSER_PARAMS (AcpiFpdtHdrParser)
174+
);
175+
FpdtHdr = (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER *)(UINTN)(FpdtBasicBootPtr->BootPerformanceTablePointer);
176+
RecOffset = sizeof (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER);
177+
while (RecOffset < FpdtHdr->Length) {
178+
FpdtBasicBootRec = (EFI_ACPI_6_5_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)((UINT8 *)(UINTN)(FpdtBasicBootPtr->BootPerformanceTablePointer) + RecOffset);
179+
if (FpdtBasicBootRec->Header.Type != EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT) {
180+
/// break the inner-loop if no more basic boot records
181+
break;
182+
}
183+
184+
/// Parse the records inside the Boot Performance Table
185+
ParseAcpi (
186+
TRUE,
187+
4,
188+
"FPDT Boot Performance Table",
189+
(UINT8 *)(UINTN)(FpdtBasicBootPtr->BootPerformanceTablePointer) + RecOffset,
190+
FpdtBasicBootRec->Header.Length,
191+
PARSER_PARAMS (FpdtBasicBootRecordParser)
192+
);
193+
RecOffset += FpdtBasicBootRec->Header.Length;
194+
}
195+
} else if (RecordHeader->Type == EFI_ACPI_6_5_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER) {
196+
FpdtS3Ptr = (EFI_ACPI_6_5_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD *)RecordPtr;
197+
ParseAcpi (
198+
TRUE,
199+
2,
200+
"FPDT S3 Performance Pointer Record",
201+
RecordPtr,
202+
FpdtS3Ptr->Header.Length,
203+
PARSER_PARAMS (FpdtS3PerfPointerParser)
204+
);
205+
206+
ParseAcpi (
207+
TRUE,
208+
4,
209+
"S3 Performance Table Pointer Record",
210+
(UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer),
211+
sizeof (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER),
212+
PARSER_PARAMS (AcpiFpdtHdrParser)
213+
);
214+
FpdtHdr = (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer);
215+
RecOffset = sizeof (EFI_ACPI_6_5_FPDT_PERFORMANCE_TABLE_HEADER);
216+
while (RecOffset < FpdtHdr->Length) {
217+
FpdtRecHdr = (EFI_ACPI_6_5_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer) + RecOffset);
218+
if (FpdtRecHdr->Type == EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME) {
219+
FpdtS3ResumeRec = (EFI_ACPI_6_5_FPDT_S3_RESUME_RECORD *)((UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer) + RecOffset);
220+
/// Parse the S3 Resume Record
221+
ParseAcpi (
222+
TRUE,
223+
4,
224+
"FPDT S3 Resume Record",
225+
(UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer) + RecOffset,
226+
FpdtS3ResumeRec->Header.Length,
227+
PARSER_PARAMS (FpdtS3ResumeRecordParser)
228+
);
229+
} else if (FpdtRecHdr->Type == EFI_ACPI_6_5_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND) {
230+
FpdtS3SuspendRec = (EFI_ACPI_6_5_FPDT_S3_SUSPEND_RECORD *)((UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer) + RecOffset);
231+
/// Parse the S3 Suspend Record
232+
ParseAcpi (
233+
TRUE,
234+
4,
235+
"FPDT S3 Suspend Record",
236+
(UINT8 *)(UINTN)(FpdtS3Ptr->S3PerformanceTablePointer) + RecOffset,
237+
FpdtS3SuspendRec->Header.Length,
238+
PARSER_PARAMS (FpdtS3SuspendRecordParser)
239+
);
240+
} else {
241+
/// break the inner-loop if no more S3 records
242+
break;
243+
}
244+
245+
RecOffset += FpdtRecHdr->Length;
246+
}
247+
} else {
248+
/// Parse the reserved record types
249+
ParseAcpi (
250+
TRUE,
251+
2,
252+
"FPDT Performance Record",
253+
RecordPtr,
254+
RecordHeader->Length,
255+
PARSER_PARAMS (FpdtPerfRecordParser)
256+
);
257+
}
258+
259+
Offset += RecordHeader->Length;
260+
RecordPtr += RecordHeader->Length;
261+
}
262+
}

ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
44
Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
55
Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.<BR>
6+
Copyright (c) 2025, AMD Incorporated. All rights reserved.
7+
68
SPDX-License-Identifier: BSD-2-Clause-Patent
79
**/
810

@@ -60,6 +62,7 @@ ACPI_TABLE_PARSER ParserList[] = {
6062
{ EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, ParseAcpiErst },
6163
{ EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs },
6264
{ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt },
65+
{ EFI_ACPI_6_5_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE, ParseAcpiFpdt },
6366
{ EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt },
6467
{ EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiHest },
6568
{ EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat },

ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
55
# Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.<BR>
6+
# Copyright (c) 2025, AMD Incorporated. All rights reserved.
67
#
78
# SPDX-License-Identifier: BSD-2-Clause-Patent
89
#
@@ -38,6 +39,7 @@
3839
Parsers/Erst/ErstParser.c
3940
Parsers/Facs/FacsParser.c
4041
Parsers/Fadt/FadtParser.c
42+
Parsers/Fpdt/FpdtParser.c
4143
Parsers/Gtdt/GtdtParser.c
4244
Parsers/Hest/HestParser.c
4345
Parsers/Hmat/HmatParser.c

0 commit comments

Comments
 (0)