From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 57715941E25 for ; Mon, 8 Jul 2024 21:40:03 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=9zAbpLoaX/ZFRuQOAFLafgQ1hoMHdpzA8bt8kyDeyN4=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1720474803; v=1; b=nms+wym3KAW0kA6S8Lx1ifQtOrZQrD6neNUF4bgsN0U9Ku6eqxKUuGGsK4g5nkdOdsvgLepZ 2595Zr/H8eEbcOXQ6tr97jCPBU3e0OQPqHTyKZTg4CfiypVgXdY7d2nFk3TOxjzI8Dzvf0nOS7m 7cEdbCXtDoOIsCyfmw05zAEVsAjYLP1DGjeas1dnBQXE1axHcN5xG5Obw9BgWjPHaDrIDVDkZPE OXXNUn8n6Cn/haNK83jIklboDxbaejq9gmFFPynLTkcWxfgWFsqJkwOW2WFFI7UHMWZt1DgH/GP n1bh63BhiURV66E+28Jo48pkQwca+HeTYAnMsFpaHaGxQ== X-Received: by 127.0.0.2 with SMTP id GtavYY7687511xE1wenHIB5J; Mon, 08 Jul 2024 14:40:01 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.5767.1720474801293012062 for ; Mon, 08 Jul 2024 14:40:01 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B9636139F; Mon, 8 Jul 2024 14:40:25 -0700 (PDT) X-Received: from usa.arm.com (iss-desktop03.cambridge.arm.com [10.1.196.33]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1148A3F641; Mon, 8 Jul 2024 14:39:58 -0700 (PDT) From: "Rohit Mathew" To: devel@edk2.groups.io Cc: James Morse , Sami Mujawar , Thomas Abraham , Yeo Reum Yun , Zhichao Gao Subject: [edk2-devel] [PATCH V6 6/6] ShellPkg/AcpiView: Add MPAM Parser Date: Mon, 8 Jul 2024 22:39:55 +0100 Message-Id: <20240708213955.41590-1-rohit.mathew@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Mon, 08 Jul 2024 14:40:01 -0700 Resent-From: rohit.mathew@arm.com Reply-To: devel@edk2.groups.io,rohit.mathew@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: qlJc1tbuRy1yFOm3PPBdbrxcx7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=nms+wym3; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=arm.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io From: Rohit Mathew Add a parser for the MPAM (Memory system resource partitioning and monitoring) ACPI table. This parser would parse all MPAM related structures embedded as part of the ACPI table. Necessary validations are also performed where and when required. Signed-off-by: Rohit Mathew Cc: James Morse Cc: Sami Mujawar Cc: Thomas Abraham Cc: Yeo Reum Yun Cc: Zhichao Gao Reviewed-by: Zhichao Gao --- ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h = | 21 + ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c = | 1241 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib= .c | 3 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib= .inf | 3 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib= .uni | 3 +- 5 files changed, 1268 insertions(+), 3 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/= ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 414b356fc0..61e9edfb59 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -900,6 +900,27 @@ ParseAcpiMcfg ( IN UINT8 AcpiTableRevision ); =20 +/** + This function parses the ACPI MPAM table. + When trace is enabled this function parses the MPAM table and + traces the ACPI table fields. + + 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 +ParseAcpiMpam ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + /** This function parses the ACPI PCCT table including its sub-structures of type 0 through 4. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/Mp= amParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/Mp= amParser.c new file mode 100644 index 0000000000..acbb859fc3 --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParse= r.c @@ -0,0 +1,1241 @@ +/** @file + MPAM table parser + + Copyright (c) 2024, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - [1] ACPI for Memory System Resource Partitioning and Monitoring 2.0 + (https://developer.arm.com/documentation/den0065/latest) + + @par Glossary: + - MPAM - Memory System Resource Partitioning And Monitoring + - MSC - Memory System Component + - PCC - Platform Communication Channel + - RIS - Resource Instance Selection + - SMMU - Arm System Memory Management Unit + **/ + +#include +#include +#include +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC CONST UINT8 *MscInterfaceType; +STATIC CONST UINT8 *ResourceLocatorType; +STATIC UINT32 MpamMscNodeStart; +STATIC CONST UINT16 *MpamMscNodeLength; +STATIC CONST UINT32 *NumberOfMscResources; +STATIC CONST UINT32 *NumberOfFunctionalDependencies; +STATIC CONST UINT32 *NumberOfInterconnectDescriptors; +STATIC CONST UINT64 *InterconnectTableOffset; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +// Array of locator type names. New types should be added keeping the or= der +// preserved as locator type is used to index into the array while parsi= ng. +STATIC CONST CHAR16 *MpamMscLocatorTitles[] =3D { + L"Processor cache", + L"Memory", + L"SMMU", + L"Memory cache", + L"ACPI device", + L"Interconnect" +}; + +/** + When the length of the table is insufficient to be parsed, this functi= on could + be used to display an appropriate error message. + + @param [in] ErrorMsg Error message string that has to be appended= to the + main error log. This string could explain th= e reason + why a insufficient length error was encounte= red in + the first place. +**/ +STATIC +VOID +EFIAPI +MpamLengthError ( + IN CONST CHAR16 *ErrorMsg + ) +{ + IncrementErrorCount (); + Print (L"\nERROR : "); + Print (ErrorMsg); + Print ( + L"\nError : Insufficient MPAM MSC Node length. Table length : %u.\n"= , + *(AcpiHdrInfo.Length) + ); +} + +/** + This function validates reserved fields. Any reserved field within the= MPAM + specification must be 0. + + @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. For thi= s + particular function, context holds the size of t= he + reserved field that needs to be validated. +**/ +STATIC +VOID +EFIAPI +ValidateReserved ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + while (Length > 0) { + if (Ptr[Length-1] !=3D 0) { + IncrementErrorCount (); + Print (L"\nERROR : Reserved field must be 0\n"); + break; + } + + Length--; + } +} + +/** + This function validates bit-length reserved fields. Any reserved field= within + the MPAM specification must be 0. + + @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. For thi= s + particular function, context holds the size of t= he + reserved field that needs to be validated. +**/ +STATIC +VOID +EFIAPI +ValidateReservedBits ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT32 ByteLength; + + ByteLength =3D (Length + 7) >> 3; + ValidateReserved (Ptr, ByteLength, Context); +} + +/** + This function validates the MMIO size within the MSC node body for MPA= M ACPI + table. MPAM ACPI specification states that the MMIO size for an MSC ha= ving PCC + type interface should be zero. + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interface type. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +ValidateMmioSize ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterfaceType; + UINT32 MmioSize; + + InterfaceType =3D *MscInterfaceType; + + if (InterfaceType =3D=3D EFI_ACPI_MPAM_INTERFACE_PCC) { + MmioSize =3D *((UINT32 *)Ptr); + + if (MmioSize !=3D 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: MMIO size must be 0 for PCC interface type. Size - %u= \n", + MmioSize + ); + } + } +} + +/** + This function decodes and validates the link type for MPAM's interconn= ect + descriptor. Valid links are of NUMA and PROC type. + + @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. For t= his + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeLinkType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 LinkType; + + LinkType =3D *Ptr; + + if (LinkType =3D=3D EFI_ACPI_MPAM_LINK_TYPE_NUMA) { + Print ( + L" (NUMA)" + ); + } else if (LinkType =3D=3D EFI_ACPI_MPAM_LINK_TYPE_PROC) { + Print ( + L" (PROC)" + ); + } else { + IncrementErrorCount (); + Print ( + L"\nERROR: Invalid link type - %u\n", + (UINT32)LinkType + ); + } +} + +/** + This function decodes the hardware ID field present within MPAM ACPI t= able. + The specification states that the hardware ID has to be set to zero if= not + being used. + + @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. For t= his + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeHardwareId ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT64 HardwareId; + + HardwareId =3D *((UINT64 *)Ptr); + + if (HardwareId !=3D 0) { + Print (L" ("); + Dump8Chars (NULL, Ptr, Length); + Print (L")"); + } +} + +/** + This function decodes and validates the interface type for MPAM. Valid + interfaces are of MMIO and PCC type. + + @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. For t= his + function, context is ignored. +**/ +STATIC +VOID +EFIAPI +DecodeInterfaceType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterfaceType; + + InterfaceType =3D *Ptr; + + if (InterfaceType =3D=3D EFI_ACPI_MPAM_INTERFACE_MMIO) { + Print (L" (MMIO)"); + } else if (InterfaceType =3D=3D EFI_ACPI_MPAM_INTERFACE_PCC) { + Print (L" (PCC)"); + } else { + IncrementErrorCount (); + Print ( + L"\nERROR: Invalid interface type - %u\n", + (UINT32)InterfaceType + ); + } +} + +/** + This function decodes the interrupt mode flag for MPAM. Interrupt mode= could + either be "edge triggered" or "level triggered". + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interrupt gsiv. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptMode ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptMode; + + InterruptMode =3D *Ptr; + + if (InterruptMode =3D=3D EFI_ACPI_MPAM_INTERRUPT_LEVEL_TRIGGERED) { + Print (L" (Level triggered)"); + } else { + Print (L" (Edge triggered)"); + } +} + +/** + This function decodes the interrupt type flag for MPAM. Interrupt type= could + be "wired interrupt". Other values are reserved at this point. + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interrupt gsiv. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptType; + + InterruptType =3D *Ptr; + + if (InterruptType =3D=3D EFI_ACPI_MPAM_INTERRUPT_WIRED) { + Print (L" (Wired interrupt)"); + } else { + IncrementWarningCount (); + Print (L" (Reserved value!)"); + } +} + +/** + This function decodes the interrupt affinity valid flag for MPAM. Inte= rrupt + affinity could be either be valid or not. + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interrupt gsiv. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptAffinityValid ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptAffinityValid; + + InterruptAffinityValid =3D *Ptr; + + if (InterruptAffinityValid !=3D EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID= ) { + Print (L" (Affinity not valid)"); + } else { + Print (L" (Affinity valid)"); + } +} + +/** + This function decodes the interrupt affinity type flag for MPAM. Inter= rupt + affinity type could either be "Processor affinity" or "Processor conta= iner + affinity" + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interrupt gsiv. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeInterruptAffinityType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 InterruptAffinityType; + + InterruptAffinityType =3D *Ptr; + + if (InterruptAffinityType =3D=3D EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_AFF= INITY) { + Print (L" (Processor affinity)"); + } else { + Print (L" (Processor container affinity)"); + } +} + +/** + This function decodes the locator type for a particular MPAM MSC resou= rce. + + @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. For th= is + function, context holds the parent/double point= er to a + variable holding the interrupt gsiv. Make sure = to call + the function accordingly. +**/ +STATIC +VOID +EFIAPI +DecodeLocatorType ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN VOID *Context + ) +{ + UINT8 LocatorType; + + LocatorType =3D *Ptr; + + if (LocatorType <=3D EFI_ACPI_MPAM_LOCATION_INTERCONNECT) { + Print (L" (%s)", MpamMscLocatorTitles[LocatorType]); + } else if (LocatorType =3D=3D EFI_ACPI_MPAM_LOCATION_UNKNOWN) { + Print (L" (Unknown)"); + } else { + Print (L" (Reserved)"); + } +} + +/** + ACPI_PARSER array describing MPAM MSC interrupt flags. +**/ +STATIC CONST ACPI_PARSER MpamMscInterruptFlagParser[] =3D { + { L"Interrupt Mode", 1, 0, L"%u", NULL, NULL, + DecodeInterruptMode, NULL }, + { L"Interrupt Type", 2, 1, L"%u", NULL, NULL, + DecodeInterruptType, NULL }, + { L"Affinity Type", 1, 3, L"%u", NULL, NULL, + DecodeInterruptAffinityType, NULL }, + { L"Affinity Valid", 1, 4, L"%u", NULL, NULL, + DecodeInterruptAffinityValid, NULL }, + { L"Reserved", 27, 5, NULL, DumpReservedBits, NULL, + ValidateReservedBits, NULL } +}; + +/** + This function traces MPAM MSC Interrupt Flags. + If no format string is specified the Format must be NULL. + + @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 +DumpMpamMscInterruptFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + Print (L"%u\n", *(UINT32 *)Ptr); + + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (MpamMscInterruptFlagParser) + ); +} + +/** + ACPI_PARSER array describing the MPAM MSC processor cache locator fiel= d. +**/ +STATIC CONST ACPI_PARSER MpamMscProcessorCacheLocatorParser[] =3D { + { L"Cache reference", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC memory locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscMemoryLocatorParser[] =3D { + { L"Proximity domain", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC SMMU locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscSMMULocatorParser[] =3D { + { L"SMMU interface", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC memory cache locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscMemoryCacheLocatorParser[] =3D { + { L"Reserved", 7, 0, NULL, DumpReserved, NULL, + ValidateReserved, NULL }, + { L"Level", 1, 7, L"%u", NULL, NULL,NULL, NULL }, + { L"Reference", 4, 8, L"%u", NULL, NULL,NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC ACPI device locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscAcpiDeviceLocatorParser[] =3D { + { L"ACPI hardware ID", 8, 0, L"0x%lx", NULL, NULL, + DecodeHardwareId, NULL }, + { L"ACPI unique ID", 4, 8, L"%u", NULL, NULL,NULL,NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC interconnect locator field. +**/ +STATIC CONST ACPI_PARSER MpamMscInterconnectLocatorParser[] =3D { + { L"Interconnect desc tbl offset", 8, 0, L"%lu", NULL, + (VOID **)&InterconnectTableOffset, NULL, NULL }, + { L"Reserved", 4, 8, NULL, DumpReserved, + NULL, ValidateReserved, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC generic resource locator fie= ld. +**/ +STATIC CONST ACPI_PARSER MpamMscGenericLocatorParser[] =3D { + { L"Descriptor1", 8, 0, L"%lu", NULL, NULL, NULL, NULL }, + { L"Descriptor2", 4, 8, L"%u", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the locator field within the resource node for AC= PI MPAM + table. The parsing is based on the locator type 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 +ParseLocator ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + Print (L"\n"); + switch (*ResourceLocatorType) { + case EFI_ACPI_MPAM_LOCATION_PROCESSOR_CACHE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscProcessorCacheLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_MEMORY: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscMemoryLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_SMMU: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscSMMULocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_MEMORY_CACHE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscMemoryCacheLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_ACPI_DEVICE: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscAcpiDeviceLocatorParser) + ); + break; + case EFI_ACPI_MPAM_LOCATION_INTERCONNECT: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscInterconnectLocatorParser) + ); + break; + // For both UNKNOWN and RESERVED locator types, the locator is parse= d using + // the generic locator parser as the spec does not define any format= . + case EFI_ACPI_MPAM_LOCATION_UNKNOWN: + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscGenericLocatorParser) + ); + break; + default: + Print (L"\nWARNING : Reserved locator type\n"); + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + 12, + PARSER_PARAMS (MpamMscGenericLocatorParser) + ); + IncrementWarningCount (); + break; + } // switch +} + +/** + ACPI_PARSER array describing the Generic ACPI MPAM table header. +**/ +STATIC CONST ACPI_PARSER MpamParser[] =3D { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + ACPI_PARSER array describing the MPAM MSC node object. +**/ +STATIC CONST ACPI_PARSER MpamMscNodeParser[] =3D { + { L"Length", 2, 0, L"%u", NULL, + (VOID **)&MpamMscNodeLength, NULL, NULL }, + // Once Interface type is decoded, the address of interface type field= is + // captured into InterfaceType pointer so that it could be used to che= ck if + // MMIO Size field is set as per the specification. + { L"Interface type", 1, 2, L"0x%x", NULL, + (VOID **)&MscInterfaceType, DecodeInterfaceType, NULL }, + { L"Reserved", 1, 3, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Identifier", 4, 4, L"%u", NULL, + NULL, NULL, NULL }, + { L"Base address", 8, 8, L"0x%lx", NULL, + NULL, NULL, NULL }, + { L"MMIO Size", 4, 16, L"0x%x", NULL, + NULL, ValidateMmioSize, (VOID **)&MscInterfaceType }, + { L"Overflow interrupt", 4, 20, L"%u", NULL, + NULL, NULL, NULL }, + { L"Overflow interrupt flags", 4, 24, NULL, DumpMpamMscInterru= ptFlags, + NULL, NULL, NULL }, + { L"Reserved1", 4, 28, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Overflow interrupt affinity", 4, 32, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Error interrupt", 4, 36, L"%u", NULL, + NULL, NULL, NULL }, + { L"Error interrupt flags", 4, 40, NULL, DumpMpamMscInterru= ptFlags, + NULL, NULL, NULL }, + { L"Reserved2", 4, 44, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Error interrupt affinity", 4, 48, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"MAX_NRDY_USEC", 4, 52, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Hardware ID of linked device", 8, 56, L"0x%lx", NULL, + NULL, DecodeHardwareId, NULL }, + { L"Instance ID of linked device", 4, 64, L"0x%x", NULL, + NULL, NULL, NULL }, + { L"Number of resource nodes", 4, 68, L"%u", NULL, + (VOID **)&NumberOfMscResources, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC resource. +**/ +STATIC CONST ACPI_PARSER MpamMscResourceParser[] =3D { + { L"Identifier", 4, 0, L"%u", NULL, + NULL, NULL, NULL }, + { L"RIS index", 1, 4, L"%u", NULL, + NULL, NULL, NULL }, + { L"Reserved1", 2, 5, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, + { L"Locator type", 1, 7, L"0x%x", NULL, + (VOID **)&ResourceLocatorType, + DecodeLocatorType, NULL }, + { L"Locator", 12, 8, NULL, ParseLocator, + NULL, NULL, NULL }, + { L"Number of func dependencies", 4, 20, L"%u", NULL, + (VOID **)&NumberOfFunctionalDependencies, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the MPAM MSC resource's functional depend= encies. +**/ +STATIC CONST ACPI_PARSER MpamMscFunctionalDependencyParser[] =3D { + { L"Producer", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 4, NULL, DumpReserved, + NULL, ValidateReserved, NULL }, +}; + +/** + ACPI_PARSER array describing the interconnect descriptor table associa= ted with + the interconnect locator type. +**/ +STATIC CONST ACPI_PARSER MpamInterconnectDescriptorTableParser[] =3D { + { L"Signature", 16, 0, + L"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x", Dump16Chars, NULL, NULL, NU= LL }, + { L"Number of Interconnect desc", 4, 16,L"0x%x", NULL, + (VOID **)&NumberOfInterconnectDescriptors, NULL, NULL } +}; + +/** + ACPI_PARSER array describing the interconnect descriptor associated wi= th the + interconnect locator type. +**/ +STATIC CONST ACPI_PARSER MpamInterconnectDescriptorParser[] =3D { + { L"Source ID", 4, 0, L"%u", NULL, NULL, NULL, NULL }, + { L"Destination ID", 4, 4, L"%u", NULL, NULL, NULL, NULL }, + { L"Link type", 1, 8, L"0x%x", NULL, + NULL, DecodeLinkType, NULL }, + { L"Reserved", 3, 9, NULL, DumpReserved, NULL, + ValidateReserved, NULL } +}; + +/** + PrintBlockTitle could be used to print the title of blocks that + appear more than once in the MPAM ACPI table. + + @param [in] Indent Number of spaces to add to the global = table + indent. The global table indent is 0 b= y + default; however this value is updated= on + entry to the ParseAcpi() by adding the= indent + value provided to ParseAcpi() and rest= ored + back on exit. Therefore the total ind= ent in + the output is dependent on from where = this + function is called. + @param [in] Title Title string to be used for the block. + @param [in] Index Index of the block. +**/ +STATIC +VOID +EFIAPI +PrintBlockTitle ( + IN UINT32 Indent, + IN CONST CHAR16 *Title, + IN CONST UINT32 Index + ) +{ + Print (L"\n"); + PrintFieldName (Indent, Title); + Print (L"%u\n\n", Index); +} + +/** + This function parses the interconnect descriptor(s) associated with + an interconnect type locator object. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is= not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseInterconnectDescriptors ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + UINT32 InterconnectDescriptorIndex; + + InterconnectDescriptorIndex =3D 0; + + if (NumberOfInterconnectDescriptors =3D=3D NULL) { + MpamLengthError (L"Number of interconnect descriptors not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (InterconnectDescriptorIndex < *NumberOfInterconnectDescriptors)= { + PrintBlockTitle ( + 6, + L"* Interconnect descriptor *", + InterconnectDescriptorIndex + ); + + // Parse interconnect descriptor + *Offset +=3D ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamInterconnectDescriptorParser) + ); + + InterconnectDescriptorIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses the interconnect descriptor table associated with= an + interconnect type locator object. It also performs necessary validatio= n to + make sure the interconnect descriptor is at a valid location. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] Offset Pointer to current offset within Ptr. + @param [in] InterconnectOffset Offset to the interconnect descriptor t= able. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is= not + long enough to be parsed correctly. + EFI_INVALID_PARAMETER The Offset parameter encoded within the= Ptr + buffer is not valid. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseInterconnectDescriptorTable ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN UINT32 Offset, + IN CONST UINT64 InterconnectOffset + ) +{ + EFI_STATUS Status; + + // Lower bound check + if (Offset > (MpamMscNodeStart + InterconnectOffset)) { + IncrementErrorCount (); + Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n")= ; + Print ( + L"ERROR : Offset overlaps with other objects within the MSC. Offse= t %u.\n", + InterconnectOffset + ); + + return EFI_INVALID_PARAMETER; + } + + // Upper bound check + if (InterconnectOffset > (*MpamMscNodeLength)) { + IncrementErrorCount (); + Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n")= ; + Print ( + L"ERROR : Offset falls outside MSC's space. Offset %u.\n", + InterconnectOffset + ); + + return EFI_INVALID_PARAMETER; + } + + // It is safe to cast InterconnectOffset to UINT32 as IntercconnectOff= set can + // never exceed the MPAM table length which is at max 2 bytes. + Offset =3D MpamMscNodeStart + (UINT32)InterconnectOffset; + + Print (L"\n"); + PrintFieldName (6, L"* Interconnect desc table *"); + Print (L"\n\n"); + + // Parse interconnect descriptor table + Offset +=3D ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (MpamInterconnectDescriptorTableParser) + ); + + Status =3D ParseInterconnectDescriptors ( + Ptr, + AcpiTableLength, + &Offset + ); + + return Status; +} + +/** + This function parses all the MPAM functional dependency nodes within a + single resource node. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to current offset within P= tr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is= not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscFunctionalDependencies ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + UINT32 FunctionalDependencyIndex; + + FunctionalDependencyIndex =3D 0; + + if (NumberOfFunctionalDependencies =3D=3D NULL) { + MpamLengthError (L"Number of functional dependencies not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (FunctionalDependencyIndex < *NumberOfFunctionalDependencies) { + PrintBlockTitle ( + 6, + L"* Functional dependency *", + FunctionalDependencyIndex + ); + + // Parse functional dependency + *Offset +=3D ParseAcpi ( + TRUE, + 4, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamMscFunctionalDependencyParser) + ); + + FunctionalDependencyIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses all the MPAM resource nodes within a single MSC + node within the MPAM ACPI table. It also invokes helper functions to + validate and parse locators and functional dependency descriptors. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] Offset Pointer to current offset within Ptr. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is= not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscResources ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN UINT32 Offset + ) +{ + EFI_STATUS Status; + UINT32 ResourceIndex; + + ResourceIndex =3D 0; + + if (NumberOfMscResources =3D=3D NULL) { + MpamLengthError (L"Number of MSC resource not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + while (ResourceIndex < *NumberOfMscResources) { + PrintBlockTitle ( + 4, + L"* Resource *", + ResourceIndex + ); + + // Parse MPAM MSC resources within the MSC body. + Offset +=3D ParseAcpi ( + TRUE, + 2, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (MpamMscResourceParser) + ); + + Status =3D ParseMpamMscFunctionalDependencies (Ptr, AcpiTableLength,= &Offset); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // If the InterconnectTableOffset field has been set, proceed to par= se the + // interconnect descriptor table. Please note that the interconnect + // descriptors are placed within the MSC node body in the resource s= pecific + // region. However since its easier to map an interconnect descript= or to + // its corresponding resource, proceed to parse it along with its pa= rent + // resource. This design choice is made to keep the trace view as in= tuitive + // as possible. + // + // +---------------------+ + // | MPAM ACPI Header | + // +---------------------+------- + // | MSC Node 0 Hdr | ^ + // | +-----------------+ | | + // | | Res Node 0 | | | + // | | +-------------+ | | | + // | | | Res Node Hdr| | | | + // | | +-------------+ | | | + // | | | Res Data | | | | + // | | | | | | | + // | | | +---------+ | | | | +---------------------------+ + // | | | | Locator | | | | ..|..| Interconnect locator desc | + // | | | | | | | | | | Descriptor Table Offset |--poin= ts-to->+ + // | | | | | | | | | | Reserved [4] | = | + // | | | +---------+ | | | | +---------------------------+ = | + // | | | |FnDep Cnt| | | | | = | + // | | | +---------+ | | | | = | + // | | | |FnDep 1 | | | | | = | + // | | | +---------+ | | | Interconnect = | + // | | | |FnDep 2 | | | | descriptor = | + // | | | +---------+ | | | table = | + // | | | |FnDep n | | | | offset = | + // | | | +---------+ | | | value = | + // | | +-------------+ | | | = | + // | +-----------------+ | | = | + // | ... | | = | + // | +-----------------+ | | = | + // | | Res Node N | | | = | + // | | +-------------+ | | | = | + // | | | Res Node Hdr| | | | = | + // | | +-------------+ | | | = | + // | | | Res Data | | | | = | + // | | | | | | | = | + // | | | +---------+ | | | | = | + // | | | | Locator | | | | | = | + // | | | | | | | | | = | + // | | | | | | | | | = | + // | | | +---------+ | | | | = | + // | | | |FnDep Cnt| | | | | = | + // | | | +---------+ | | | | = | + // | | | |FnDep 1 | | | | | = | + // | | | +---------+ | | | | = | + // | | | |FnDep 2 | | | | | = | + // | | | +---------+ | | | | = | + // | | | |FnDep n | | | | | = | + // | | | +---------+ | | | | = | + // | | +-------------+ | | | = | + // | +-----------------+ | | = | + // \ Resource-specific / v = | + // / data region. \<----------------------------------------= -------+ + // \ / + // +---------------------+ + // | MSC Node 1 Hdr | + // | ... | + // +---------------------+ + if ( (*ResourceLocatorType =3D=3D EFI_ACPI_MPAM_LOCATION_INTERCONNE= CT) + && (InterconnectTableOffset !=3D NULL)) + { + Status =3D ParseInterconnectDescriptorTable ( + Ptr, + AcpiTableLength, + Offset, + *InterconnectTableOffset + ); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + } + + ResourceIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses all the MPAM MSC nodes within the MPAM ACPI table= . It + also invokes a helper function to detect and parse resource nodes that= maybe + present. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in, out] Offset Pointer to the current offset within Pt= r. + +Returns: + + Status + + EFI_SUCCESS MPAM MSC nodes were parsed properly. + EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is= not + long enough to be parsed correctly. +**/ +STATIC +EFI_STATUS +EFIAPI +ParseMpamMscNodes ( + IN UINT8 *CONST Ptr, + IN CONST UINT32 AcpiTableLength, + IN OUT UINT32 *CONST Offset + ) +{ + EFI_STATUS Status; + UINT32 MscIndex; + + MscIndex =3D 0; + + while (*Offset < AcpiTableLength) { + MpamMscNodeStart =3D *Offset; + + PrintBlockTitle (2, L"* MSC *", MscIndex); + // Parse MPAM MSC node + *Offset +=3D ParseAcpi ( + TRUE, + 0, + NULL, + Ptr + *Offset, + AcpiTableLength - *Offset, + PARSER_PARAMS (MpamMscNodeParser) + ); + + if (MpamMscNodeLength =3D=3D NULL) { + MpamLengthError (L"MPAM MSC node length not set!"); + return EFI_BAD_BUFFER_SIZE; + } + + if (*MpamMscNodeLength < sizeof (EFI_ACPI_MPAM_MSC_NODE)) { + IncrementErrorCount (); + Print (L"\nERROR: MSC length should be at least the size of node b= ody! "); + Print (L"MSC Length %u\n", *MpamMscNodeLength); + return EFI_BAD_BUFFER_SIZE; + } + + // Parse MPAM MSC resources within the MSC body + Status =3D ParseMpamMscResources (Ptr, AcpiTableLength, *Offset); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + *Offset =3D MpamMscNodeStart + *MpamMscNodeLength; + MscIndex++; + } + + return EFI_SUCCESS; +} + +/** + This function parses the MPAM ACPI table's generic header. It also inv= okes a + sub routine that would help with parsing rest of the table. + + @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 +ParseAcpiMpam ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + EFI_STATUS Status; + UINT32 Offset; + + if (!Trace) { + return; + } + + // Parse generic table header + Offset =3D ParseAcpi ( + TRUE, + 0, + "MPAM", + Ptr, + AcpiTableLength, + PARSER_PARAMS (MpamParser) + ); + + Status =3D ParseMpamMscNodes ( + Ptr, + AcpiTableLength, + &Offset + ); + + if (Status =3D=3D EFI_SUCCESS) { + // Check if the length of all MPAM MSCs with the header, matches wit= h the + // ACPI table's length field. + if (*(AcpiHdrInfo.Length) !=3D Offset) { + IncrementErrorCount (); + Print (L"\nERROR: Length mismatch! : "); + Print (L"MSC Length total !=3D MPAM table length."); + Print ( + L"Table length : %u MSC total : %u\n", + *(AcpiHdrInfo.Length), + Offset + ); + } + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiVi= ewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAc= piViewCommandLib.c index 0bdf068fe0..b2f07334e4 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.c @@ -2,7 +2,7 @@ Main file for 'acpiview' Shell command function. =20 Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ =20 @@ -64,6 +64,7 @@ ACPI_TABLE_PARSER ParserList[] =3D { { EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, = ParseAcpiMadt }, { EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDR= ESS_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMcfg }, + { EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SI= GNATURE, ParseAcpiMpam }, { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, ParseAcpiPcct }, { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE= , diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiVi= ewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShell= AcpiViewCommandLib.inf index e62366116c..acbfd7d971 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.inf @@ -2,7 +2,7 @@ # Provides Shell 'acpiview' command functions # # Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. -# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -43,6 +43,7 @@ Parsers/Madt/MadtParser.c Parsers/Madt/MadtParser.h Parsers/Mcfg/McfgParser.c + Parsers/Mpam/MpamParser.c Parsers/Pcct/PcctParser.c Parsers/Pcct/PcctParser.h Parsers/Pptt/PpttParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiVi= ewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShell= AcpiViewCommandLib.uni index e4a9dd5b40..4079a8e51e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.uni +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComma= ndLib.uni @@ -1,6 +1,6 @@ // /** // -// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+// Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause-Patent // // Module Name: @@ -89,6 +89,7 @@ " HMAT - Heterogeneous Memory Attributes Table\r\n" " IORT - IO Remapping Table\r\n" " MCFG - Memory Mapped Config Space Base Address Description Tabl= e\r\n" +" MPAM - Memory System Resource Partitioning and Monitoring Table= \r\n" " PPTT - Processor Properties Topology Table\r\n" " RSDP - Root System Description Pointer\r\n" " SLIT - System Locality Information Table\r\n" --=20 2.34.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#119822): https://edk2.groups.io/g/devel/message/119822 Mute This Topic: https://groups.io/mt/107112194/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-