summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c')
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c1334
1 files changed, 667 insertions, 667 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
index 2a1357c853..06520bb7e7 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
@@ -1,667 +1,667 @@
-/** @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_4_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_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
- Attributes;
-
- Attributes =
- (EFI_ACPI_6_4_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_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
- Attributes;
-
- Attributes =
- (EFI_ACPI_6_4_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"Min Transfer Size", 1, 10, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 11, 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_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES:
- DumpMpda (
- HmatStructurePtr,
- *HmatStructureLength
- );
- break;
- case EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO:
- DumpSllbi (
- HmatStructurePtr,
- *HmatStructureLength
- );
- break;
- case EFI_ACPI_6_4_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
-}
+/** @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_4_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_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
+ Attributes;
+
+ Attributes =
+ (EFI_ACPI_6_4_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_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
+ Attributes;
+
+ Attributes =
+ (EFI_ACPI_6_4_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"Min Transfer Size", 1, 10, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 1, 11, 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_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES:
+ DumpMpda (
+ HmatStructurePtr,
+ *HmatStructureLength
+ );
+ break;
+ case EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO:
+ DumpSllbi (
+ HmatStructurePtr,
+ *HmatStructureLength
+ );
+ break;
+ case EFI_ACPI_6_4_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
+}