| /** @file | |
| HMAT table parser | |
| Copyright (c) 2020 - 2024, Arm Limited. All rights reserved. | |
| 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] Length Length of the field. | |
| @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 UINT32 Length, | |
| 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. | |
| @param [in] Length Length of the field. | |
| **/ | |
| STATIC | |
| VOID | |
| EFIAPI | |
| DumpCacheAttributes ( | |
| IN CONST CHAR16 *Format OPTIONAL, | |
| IN UINT8 *Ptr, | |
| IN UINT32 Length | |
| ) | |
| { | |
| 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 | |
| } |