[edk2-devel] [PATCH v4 1/1] ShellPkg/AcpiView: HMAT Parser

Vijayenthiran Subramaniam vijayenthiran.subramaniam at arm.com
Thu Jan 28 14:03:48 UTC 2021


Hi,

On Wed, Nov 4, 2020 at 11:17 AM Sami Mujawar <sami.mujawar at arm.com> wrote:
>
> From: Marc Moisson-Franckhauser <marc.moisson-franckhauser at arm.com>
>
> Bugzilla: 3045 (https://bugzilla.tianocore.org/show_bug.cgi?id=3045)
>
> Add a new parser for the Heterogeneous Memory Attribute Table. The
> parser also validates some fields for this table.
>
> The HMAT table is used to describe the memory attributes such as memory
> side cache attributes and bandwidth and latency details related to
> memory proximity domains. The info in the HMAT table can be used by an
> operating system for optimisation.
>
> Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser at arm.com>
> Signed-off-by: Sami Mujawar <sami.mujawar at arm.com>

Tested this patch on Arm's reference design platform with the patch series
https://edk2.groups.io/g/devel/message/70847 applied.

Tested-by: Vijayenthiran Subramaniam <vijayenthiran.subramaniam at arm.com>

> ---
>
> The changes can be seen at:
> https://github.com/samimujawar/edk2/tree/833_hmat_parser_v4
>
> Notes:
>     v4:
>     - Fix data type used for the SMBIOS handle count variable       [SAMI]
>       to match the field width.
>       Ref: https://edk2.groups.io/g/devel/message/66196
>
>     v3:
>      - Updates based on review comments, minor updates to output    [SAMI]
>        formatting and added additional checks.
>
>     v2:
>      - Fixed minor output formatting in DumpCacheAttributes()       [SAMI]
>
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  28 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c       | 650 ++++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c   |   3 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf |   3 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni |   3 +-
>  6 files changed, 685 insertions(+), 6 deletions(-)
>
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> index f81ccac7e118378aa185db4b625e5bcd75f78347..969cc0b371852f01f30c88dc506374a459c9c19e 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI parser
>
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
>
> @@ -592,6 +592,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/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> index 4f92596b90a6ee422d8d0959881015ffd3de4da0..f8e8b5979f3be041bbc8d17042b2db8e0b73f205 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI table parser
>
> -  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2018, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
>
> @@ -11,7 +11,7 @@
>  /**
>    The maximum number of ACPI table parsers.
>  */
> -#define MAX_ACPI_TABLE_PARSERS          16
> +#define MAX_ACPI_TABLE_PARSERS          32
>
>  /** An invalid/NULL signature value.
>  */
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1d1bc4bdc343e65a8c2fd5f983b2078311452329
> --- /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 d2f26ff89f12e596702281c38ab0de3729aa68e4..c9e3054a5c413ba95e6420ce3d02f0d954e99d90 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Main file for 'acpiview' Shell command function.
>
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
>
> @@ -53,6 +53,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 91459f9ec632635ee453c5ef46f67445cd9eee0c..e970c4259c143b5b06fb1a759d5819e7cb93e749 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
> @@ -1,7 +1,7 @@
>  ##  @file
>  # Provides Shell 'acpiview' command functions
>  #
> -# Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -33,6 +33,7 @@ [Sources.common]
>    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 7cd43d0518fd0a23dc547a5cab0d08b62602a113..6b0537b47a751184e8a68a6530aa85eb28ea33ba 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
> @@ -1,6 +1,6 @@
>  // /**
>  //
> -// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>  // SPDX-License-Identifier: BSD-2-Clause-Patent
>  //
>  // Module Name:
> @@ -84,6 +84,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"
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#70851): https://edk2.groups.io/g/devel/message/70851
Mute This Topic: https://groups.io/mt/78026691/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list