diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c')
| -rw-r--r-- | ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c | 1334 |
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 +} |
