summaryrefslogtreecommitdiffstats
path: root/ShellPkg
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg')
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h26
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c650
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c1
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf1
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni1
5 files changed, 679 insertions, 0 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index a37b62bc7e..0b7726b9d5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -613,6 +613,32 @@ ParseAcpiGtdt (
);
/**
+ This function parses the ACPI HMAT table.
+ When trace is enabled this function parses the HMAT table and
+ traces the ACPI table fields.
+
+ This function parses the following HMAT structures:
+ - Memory Proximity Domain Attributes Structure (Type 0)
+ - System Locality Latency and Bandwidth Info Structure (Type 1)
+ - Memory Side Cache Info structure (Type 2)
+
+ 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
+ParseAcpiHmat (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/**
This function parses the ACPI IORT table.
When trace is enabled this function parses the IORT table and
traces the ACPI fields.
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
new file mode 100644
index 0000000000..1d1bc4bdc3
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
@@ -0,0 +1,650 @@
+/** @file
+ HMAT table parser
+
+ Copyright (c) 2020, Arm Limited.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification - January 2019
+
+ @par Glossary:
+ - MPDA - Memory Proximity Domain Attributes
+ - SLLBI - System Locality Latency and Bandwidth Information
+ - MSCI - Memory Side Cache Information
+ - Dom - Domain
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+
+// Maximum Memory Domain matrix print size.
+#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10
+
+// Local variables
+STATIC CONST UINT16* HmatStructureType;
+STATIC CONST UINT32* HmatStructureLength;
+
+STATIC CONST UINT32* NumberInitiatorProximityDomain;
+STATIC CONST UINT32* NumberTargetProximityDomain;
+STATIC CONST
+EFI_ACPI_6_3_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS*
+SllbiFlags;
+
+STATIC CONST UINT8* SllbiDataType;
+STATIC CONST UINT16* NumberSMBIOSHandles;
+
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/**
+ Names of System Locality Latency Bandwidth Information (SLLBI) data types
+**/
+STATIC CONST CHAR16* SllbiNames[] = {
+ L"Access %sLatency%s",
+ L"Read %sLatency%s",
+ L"Write %sLatency%s",
+ L"Access %sBandwidth%s",
+ L"Read %sBandwidth%s",
+ L"Write %sBandwidth%s"
+};
+
+/**
+ This function validates the Cache Attributes field.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateCacheAttributes (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES*
+ Attributes;
+
+ Attributes =
+ (EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES*)Ptr;
+
+ if (Attributes->TotalCacheLevels > 0x3) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Attributes bits [3:0] have invalid value: 0x%x",
+ Attributes->TotalCacheLevels
+ );
+ }
+ if (Attributes->CacheLevel > 0x3) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Attributes bits [7:4] have invalid value: 0x%x",
+ Attributes->CacheLevel
+ );
+ }
+ if (Attributes->CacheAssociativity > 0x2) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Attributes bits [11:8] have invalid value: 0x%x",
+ Attributes->CacheAssociativity
+ );
+ }
+ if (Attributes->WritePolicy > 0x2) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Attributes bits [15:12] have invalid value: 0x%x",
+ Attributes->WritePolicy
+ );
+ }
+}
+
+/**
+ Dumps the cache attributes field
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+**/
+STATIC
+VOID
+EFIAPI
+DumpCacheAttributes (
+ IN CONST CHAR16* Format OPTIONAL,
+ IN UINT8* Ptr
+ )
+{
+ EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES*
+ Attributes;
+
+ Attributes =
+ (EFI_ACPI_6_3_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES*)Ptr;
+
+ Print (L"\n");
+ PrintFieldName (4, L"Total Cache Levels");
+ Print (L"%d\n", Attributes->TotalCacheLevels);
+ PrintFieldName (4, L"Cache Level");
+ Print (L"%d\n", Attributes->CacheLevel);
+ PrintFieldName (4, L"Cache Associativity");
+ Print (L"%d\n", Attributes->CacheAssociativity);
+ PrintFieldName (4, L"Write Policy");
+ Print (L"%d\n", Attributes->WritePolicy);
+ PrintFieldName (4, L"Cache Line Size");
+ Print (L"%d\n", Attributes->CacheLineSize);
+}
+
+/**
+ An ACPI_PARSER array describing the ACPI HMAT Table.
+*/
+STATIC CONST ACPI_PARSER HmatParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Reserved", 4, 36, NULL, NULL, NULL, NULL, NULL}
+};
+
+/**
+ An ACPI_PARSER array describing the HMAT structure header.
+*/
+STATIC CONST ACPI_PARSER HmatStructureHeaderParser[] = {
+ {L"Type", 2, 0, NULL, NULL, (VOID**)&HmatStructureType, NULL, NULL},
+ {L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL},
+ {L"Length", 4, 4, NULL, NULL, (VOID**)&HmatStructureLength, NULL, NULL}
+};
+
+/**
+ An ACPI PARSER array describing the Memory Proximity Domain Attributes
+ Structure - Type 0.
+*/
+STATIC CONST ACPI_PARSER MemProximityDomainAttributeParser[] = {
+ {L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL},
+ {L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 10, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Proximity Dom for initiator", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Proximity Dom for memory", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}
+};
+
+/**
+ An ACPI PARSER array describing the System Locality Latency and Bandwidth
+ Information Structure - Type 1.
+*/
+STATIC CONST ACPI_PARSER SllbiParser[] = {
+ {L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL},
+ {L"Flags", 1, 8, L"0x%x", NULL, (VOID**)&SllbiFlags, NULL, NULL},
+ {L"Data type", 1, 9, L"0x%x", NULL, (VOID**)&SllbiDataType, NULL, NULL},
+ {L"Reserved", 2, 10, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Initiator Proximity Dom Count", 4, 12, L"%d", NULL,
+ (VOID**)&NumberInitiatorProximityDomain, NULL, NULL},
+ {L"Target Proximity Dom Count", 4, 16, L"%d", NULL,
+ (VOID**)&NumberTargetProximityDomain, NULL, NULL},
+ {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Entry Base Unit", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL}
+ // initiator Proximity Domain list ...
+ // target Proximity Domain list ...
+ // Latency/Bandwidth matrix ...
+};
+
+/**
+ An ACPI PARSER array describing the Memory Side Cache Information
+ Structure - Type 2.
+*/
+STATIC CONST ACPI_PARSER MemSideCacheInfoParser[] = {
+ {L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL},
+ {L"Proximity Dom for memory", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Memory Side Cache Size", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Cache Attributes", 4, 24, NULL, DumpCacheAttributes, NULL,
+ ValidateCacheAttributes, NULL},
+ {L"Reserved", 2, 28, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SMBIOS Handle Count", 2, 30, L"%d", NULL,
+ (VOID**)&NumberSMBIOSHandles, NULL, NULL}
+ // SMBIOS handles List ...
+};
+
+/**
+ This function parses the Memory Proximity Domain Attributes
+ Structure (Type 0).
+
+ @param [in] Ptr Pointer to the start of the Memory Proximity Domain
+ Attributes Structure data.
+ @param [in] Length Length of the Memory Proximity Domain Attributes
+ Structure.
+**/
+STATIC
+VOID
+DumpMpda (
+ IN UINT8* Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Memory Proximity Domain Attributes Structure",
+ Ptr,
+ Length,
+ PARSER_PARAMS (MemProximityDomainAttributeParser)
+ );
+}
+
+/**
+ This function parses the System Locality Latency and Bandwidth Information
+ Structure (Type 1).
+
+ @param [in] Ptr Pointer to the start of the System Locality Latency and
+ Bandwidth Information Structure data.
+ @param [in] Length Length of the System Locality Latency and Bandwidth
+ Information Structure.
+**/
+STATIC
+VOID
+DumpSllbi (
+ IN UINT8* Ptr,
+ IN UINT32 Length
+ )
+{
+ CONST UINT32* InitiatorProximityDomainList;
+ CONST UINT32* TargetProximityDomainList;
+ CONST UINT16* LatencyBandwidthMatrix;
+ UINT32 Offset;
+ CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
+ CHAR16 SecondBuffer[OUTPUT_FIELD_COLUMN_WIDTH];
+ UINT32 RequiredTableSize;
+ UINT32 Index;
+ UINT32 IndexInitiator;
+ UINT32 IndexTarget;
+ UINT32 TargetStartOffset;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "System Locality Latency and Bandwidth Information Structure",
+ Ptr,
+ Length,
+ PARSER_PARAMS (SllbiParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((SllbiFlags == NULL) ||
+ (SllbiDataType == NULL) ||
+ (NumberInitiatorProximityDomain == NULL) ||
+ (NumberTargetProximityDomain == NULL)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient remaining table buffer length to read the " \
+ L"SLLBI structure header. Length = %d.\n",
+ Length
+ );
+ return;
+ }
+
+ RequiredTableSize = (*NumberInitiatorProximityDomain * sizeof (UINT32)) +
+ (*NumberTargetProximityDomain * sizeof (UINT32)) +
+ (*NumberInitiatorProximityDomain *
+ *NumberTargetProximityDomain * sizeof (UINT16)) +
+ Offset;
+
+ if (RequiredTableSize > Length) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient System Locality Latency and Bandwidth" \
+ L"Information Structure length. TableLength = %d. " \
+ L"RequiredTableLength = %d.\n",
+ Length,
+ RequiredTableSize
+ );
+ return;
+ }
+
+ InitiatorProximityDomainList = (UINT32*) (Ptr + Offset);
+ TargetProximityDomainList = InitiatorProximityDomainList +
+ *NumberInitiatorProximityDomain;
+ LatencyBandwidthMatrix = (UINT16*) (TargetProximityDomainList +
+ *NumberTargetProximityDomain);
+
+ // Display each element of the Initiator Proximity Domain list
+ for (Index = 0; Index < *NumberInitiatorProximityDomain; Index++) {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Initiator Proximity Dom [%d]",
+ Index
+ );
+
+ PrintFieldName (4, Buffer);
+ Print (
+ L"0x%x\n",
+ InitiatorProximityDomainList[Index]
+ );
+ }
+
+ // Display each element of the Target Proximity Domain list
+ for (Index = 0; Index < *NumberTargetProximityDomain; Index++) {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Target Proximity Dom [%d]",
+ Index
+ );
+
+ PrintFieldName (4, Buffer);
+ Print (
+ L"0x%x\n",
+ TargetProximityDomainList[Index]
+ );
+ }
+
+ // Create base name depending on Data Type in this Structure
+ if (*SllbiDataType >= ARRAY_SIZE (SllbiNames)) {
+ IncrementErrorCount ();
+ Print (L"Error: Unkown Data Type. DataType = 0x%x.\n", *SllbiDataType);
+ return;
+ }
+ StrCpyS (Buffer, sizeof (Buffer), SllbiNames[*SllbiDataType]);
+
+ // Adjust base name depending on Memory Hierarchy in this Structure
+ switch (SllbiFlags->MemoryHierarchy) {
+ case 0:
+ UnicodeSPrint (
+ SecondBuffer,
+ sizeof (SecondBuffer),
+ Buffer,
+ L"",
+ L"%s"
+ );
+ break;
+ case 1:
+ case 2:
+ case 3:
+ UnicodeSPrint (
+ SecondBuffer,
+ sizeof (SecondBuffer),
+ Buffer,
+ L"Hit ",
+ L"%s"
+ );
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (
+ L"Error: Invalid Memory Hierarchy. MemoryHierarchy = %d.\n",
+ SllbiFlags->MemoryHierarchy
+ );
+ return;
+
+ } // switch
+
+ if (*NumberTargetProximityDomain <= MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX) {
+ // Display the latency/bandwidth matrix as a matrix
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ SecondBuffer,
+ L""
+ );
+ PrintFieldName (4, Buffer);
+
+ Print (L"\n Target : X-axis (Horizontal)");
+ Print (L"\n Initiator : Y-axis (Vertical)");
+ Print (L"\n |");
+
+ for (IndexTarget = 0;
+ IndexTarget < *NumberTargetProximityDomain;
+ IndexTarget++) {
+ Print (L" %2d", IndexTarget);
+ }
+
+ Print (L"\n ---+");
+ for (IndexTarget = 0;
+ IndexTarget < *NumberTargetProximityDomain;
+ IndexTarget++) {
+ Print (L"------");
+ }
+ Print (L"\n");
+
+ TargetStartOffset = 0;
+ for (IndexInitiator = 0;
+ IndexInitiator < *NumberInitiatorProximityDomain;
+ IndexInitiator++) {
+ Print (L" %2d |", IndexInitiator);
+ for (IndexTarget = 0;
+ IndexTarget < *NumberTargetProximityDomain;
+ IndexTarget++) {
+ Print (
+ L" %5d",
+ LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
+ );
+ } // for Target
+ Print (L"\n");
+ TargetStartOffset += (*NumberTargetProximityDomain);
+ } // for Initiator
+ Print (L"\n");
+ } else {
+ // Display the latency/bandwidth matrix as a list
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ SecondBuffer,
+ L" [%d][%d]"
+ );
+
+ TargetStartOffset = 0;
+ for (IndexInitiator = 0;
+ IndexInitiator < *NumberInitiatorProximityDomain;
+ IndexInitiator++) {
+ for (IndexTarget = 0;
+ IndexTarget < *NumberTargetProximityDomain;
+ IndexTarget++) {
+ UnicodeSPrint (
+ SecondBuffer,
+ sizeof (SecondBuffer),
+ Buffer,
+ IndexInitiator,
+ IndexTarget
+ );
+
+ PrintFieldName (4, SecondBuffer);
+ Print (
+ L"%d\n",
+ LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
+ );
+ } // for Target
+ TargetStartOffset += (*NumberTargetProximityDomain);
+ } // for Initiator
+ }
+}
+
+/**
+ This function parses the Memory Side Cache Information Structure (Type 2).
+
+ @param [in] Ptr Pointer to the start of the Memory Side Cache Information
+ Structure data.
+ @param [in] Length Length of the Memory Side Cache Information Structure.
+**/
+STATIC
+VOID
+DumpMsci (
+ IN UINT8* Ptr,
+ IN UINT32 Length
+ )
+{
+ CONST UINT16* SMBIOSHandlesList;
+ CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
+ UINT32 Offset;
+ UINT16 Index;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "Memory Side Cache Information Structure",
+ Ptr,
+ Length,
+ PARSER_PARAMS (MemSideCacheInfoParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if (NumberSMBIOSHandles == NULL) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient remaining table buffer length to read the " \
+ L"MSCI structure header. Length = %d.\n",
+ Length
+ );
+ return;
+ }
+
+ if ((*NumberSMBIOSHandles * sizeof (UINT16)) > (Length - Offset)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Number of SMBIOS Handles. SMBIOSHandlesCount = %d." \
+ L"RemainingBufferLength = %d.\n",
+ *NumberSMBIOSHandles,
+ Length - Offset
+ );
+ return;
+ }
+
+ SMBIOSHandlesList = (UINT16*) (Ptr + Offset);
+
+ for (Index = 0; Index < *NumberSMBIOSHandles; Index++) {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"SMBIOS Handles [%d]",
+ Index
+ );
+
+ PrintFieldName (4, Buffer);
+ Print (
+ L"0x%x\n",
+ SMBIOSHandlesList[Index]
+ );
+ }
+}
+
+/**
+ This function parses the ACPI HMAT table.
+ When trace is enabled this function parses the HMAT table and
+ traces the ACPI table fields.
+
+ This function parses the following HMAT structures:
+ - Memory Proximity Domain Attributes Structure (Type 0)
+ - System Locality Latency and Bandwidth Info Structure (Type 1)
+ - Memory Side Cache Info structure (Type 2)
+
+ 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
+ParseAcpiHmat (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT8* HmatStructurePtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ Trace,
+ 0,
+ "HMAT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (HmatParser)
+ );
+
+ HmatStructurePtr = Ptr + Offset;
+
+ while (Offset < AcpiTableLength) {
+ // Parse HMAT Structure Header to obtain Type and Length.
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ HmatStructurePtr,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (HmatStructureHeaderParser)
+ );
+
+ // Check if the values used to control the parsing logic have been
+ // successfully read.
+ if ((HmatStructureType == NULL) ||
+ (HmatStructureLength == NULL)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Insufficient remaining table buffer length to read the " \
+ L"HMAT structure header. Length = %d.\n",
+ AcpiTableLength - Offset
+ );
+ return;
+ }
+
+ // Validate HMAT Structure length.
+ if ((*HmatStructureLength == 0) ||
+ ((Offset + (*HmatStructureLength)) > AcpiTableLength)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid HMAT Structure length. " \
+ L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
+ *HmatStructureLength,
+ Offset,
+ AcpiTableLength
+ );
+ return;
+ }
+
+ switch (*HmatStructureType) {
+ case EFI_ACPI_6_3_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES:
+ DumpMpda (
+ HmatStructurePtr,
+ *HmatStructureLength
+ );
+ break;
+ case EFI_ACPI_6_3_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO:
+ DumpSllbi (
+ HmatStructurePtr,
+ *HmatStructureLength
+ );
+ break;
+ case EFI_ACPI_6_3_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO:
+ DumpMsci (
+ HmatStructurePtr,
+ *HmatStructureLength
+ );
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Unknown HMAT structure:"
+ L" Type = %d, Length = %d\n",
+ *HmatStructureType,
+ *HmatStructureLength
+ );
+ break;
+ } // switch
+
+ HmatStructurePtr += *HmatStructureLength;
+ Offset += *HmatStructureLength;
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index 90e8741175..b30ed3fc85 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -55,6 +55,7 @@ ACPI_TABLE_PARSER ParserList[] = {
{EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs},
{EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt},
{EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt},
+ {EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat},
{EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort},
{EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
{EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index 947fb1f375..63fc5a1281 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -34,6 +34,7 @@
Parsers/Facs/FacsParser.c
Parsers/Fadt/FadtParser.c
Parsers/Gtdt/GtdtParser.c
+ Parsers/Hmat/HmatParser.c
Parsers/Iort/IortParser.c
Parsers/Madt/MadtParser.c
Parsers/Madt/MadtParser.h
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
index 9dbffcd7c5..393110e0ee 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
@@ -85,6 +85,7 @@
" DSDT - Differentiated System Description Table\r\n"
" FACP - Fixed ACPI Description Table (FADT)\r\n"
" GTDT - Generic Timer Description Table\r\n"
+" HMAT - Heterogeneous Memory Attributes Table\r\n"
" IORT - IO Remapping Table\r\n"
" MCFG - Memory Mapped Config Space Base Address Description Table\r\n"
" PPTT - Processor Properties Topology Table\r\n"