Hi Swatisri, Thanks for the patch. Please find my comments inline marked [Rohit] -
> -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Name > via groups.io > Sent: 16 August 2022 21:18 > To: devel@edk2.groups.io; Sami Mujawar <sami.muja...@arm.com>; > Alexei Fedorov <alexei.fedo...@arm.com>; michael.d.kin...@intel.com; > gaolim...@byosoft.com.cn; zhiguang....@intel.com > Cc: Swatisri Kantamsetti <swatis...@nvidia.com> > Subject: [edk2-devel] [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM > Generator and supporting files > > From: Swatisri Kantamsetti <swatis...@nvidia.com> > > ACPI header, MSC and Resource Nodes are populated in the MPAM Table > > Signed-off-by: Swatisri Kantamsetti <swatis...@nvidia.com> > --- > DynamicTablesPkg/DynamicTables.dsc.inc | 2 + > DynamicTablesPkg/Include/AcpiTableGenerator.h | 1 + > .../Include/ArmNameSpaceObjects.h | 68 ++ > .../Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf | 30 + > .../Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c | 649 > ++++++++++++++++++ > .../Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h | 47 ++ > 6 files changed, 797 insertions(+) > create mode 100644 > DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.in > f > create mode 100644 > DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c > create mode 100644 > DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h > > diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc > b/DynamicTablesPkg/DynamicTables.dsc.inc > index 3d4fa0c4c4..745d5f0633 100644 > --- a/DynamicTablesPkg/DynamicTables.dsc.inc > +++ b/DynamicTablesPkg/DynamicTables.dsc.inc > @@ -29,6 +29,7 @@ > DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf > DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf > DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf > + > DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.in > f > DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf > DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > @@ -54,6 +55,7 @@ > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibAr > m.inf > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibAr > m.inf > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm. > inf > + > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLib > Arm.i > + nf > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm. > inf > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm. > inf > > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.i > nf > diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h > b/DynamicTablesPkg/Include/AcpiTableGenerator.h > index f962dbff57..56d7375b4a 100644 > --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h > +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h > @@ -94,6 +94,7 @@ typedef enum StdAcpiTableId { > EStdAcpiTableIdIort, ///< IORT Generator > EStdAcpiTableIdPptt, ///< PPTT Generator > EStdAcpiTableIdSrat, ///< SRAT Generator > + EStdAcpiTableIdMpam, ///< MPAM Generator > EStdAcpiTableIdSsdtSerialPort, ///< SSDT Serial-Port > Generator > EStdAcpiTableIdSsdtCmn600, ///< SSDT Cmn-600 Generator > EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology > diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > index 102e0f96be..39a14ed0b3 100644 > --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > @@ -63,6 +63,8 @@ typedef enum ArmObjectID { > EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info > EArmObjRmr, ///< 40 - Reserved Memory Range Node > EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor > + EArmObjMscNodeInfo, ///< 40 - Msc Memory System Controller > Node Info > + EArmObjResNodeInfo, ///< 41 - Res Resource Node Info > EArmObjMax > } EARM_OBJECT_ID; > > @@ -1070,6 +1072,72 @@ typedef struct CmArmRmrDescriptor { > UINT64 Length; > } CM_ARM_MEMORY_RANGE_DESCRIPTOR; > > +/** A structure that describes Memory System Controller Node. > + > + MPAM Memory System Component Nodes are described by > + this object. > + > + ID: EArmObjMscNodeInfo > +*/ > +typedef struct CmArmMscNodeInfo { > + /// An unique token used to identify this object > + CM_OBJECT_TOKEN Token; > + > + /// MPAM Base Address > + UINT64 BaseAddress; > + /// MMIO Size > + UINT32 MmioSize; > + /// Overflow Interrupt > + UINT32 OverflowInterrupt; > + /// Overflow Interrupt Flags > + UINT32 OverflowInterruptFlags; [Rohit] I have added a comment on Flag's type in [PATCH 1/2]. Same comment here. > + /// Overflow Interrupt Affinity > + UINT32 OverflowInterruptAff; > + /// Error Interrupt > + UINT32 ErrorInterrupt; > + /// Error Interrupt Flags > + UINT32 ErrorInterruptFlags; > + /// Error Interrupt Affinity > + UINT32 ErrorInterruptAff; > + /// Not Ready Signal time > + UINT32 MaxNRdyUsec; > + /// Linked Device HWID > + UINT64 LinkedDeviceHwId; > + /// Linked Device Instance ID > + UINT32 LinkedDeviceInstanceHwId; > + /// Number of Resource nodes > + UINT32 NumResourceNodes; > + /// Reference token for the list of resource nodes > + //CM_OBJECT_TOKEN ResourceNodeListToken; > + > +} CM_ARM_MSC_NODE_INFO; > + > +/** A structure that describes Memory System Controller Node. > + > + MPAM Memory System Component Nodes are described by > + this object. > + > + ID: EArmObjResNodeInfo > +*/ > +typedef struct CmArmResNodeInfo { > + /// An unique token used to identify this object > + CM_OBJECT_TOKEN Token; > + > + /// Identifier > + UINT32 Identifier; > + /// RIS Index > + UINT8 RisIndex; > + /// Locator Type > + UINT8 LocatorType; > + /// Locator > + UINT64 Locator; [Rohit] I have added a comment on Locator's type and size in [PATCH 1/2]. Same comment here. > + /// Num functional dependencies > + UINT32 NumFuncDep; > + /// Reference token for the list of resource nodes > + CM_OBJECT_TOKEN FuncDepListToken; > + > +} CM_ARM_RESOURCE_NODE_INFO; > + > #pragma pack() > > #endif // ARM_NAMESPACE_OBJECTS_H_ > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm > .inf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm > .inf > new file mode 100644 > index 0000000000..480130dc21 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm > .in > +++ f > @@ -0,0 +1,30 @@ > +## @file > +# MPAM Table Generator Inf file > +# > +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. > +# Copyright (c) 2022, ARM Limited. All rights reserved. > +# SPDX-License-Identifier: BSD-2-Clause-Patent ## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = AcpiMpamLibArm > + FILE_GUID = 02d0c79f-41cd-45c9-9835-781229c619d1 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiMpamLibConstructor > + DESTRUCTOR = AcpiMpamLibDestructor > + > +[Sources] > + MpamGenerator.c > + MpamGenerator.h > + > +[Packages] > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + BaseLib > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > c > new file mode 100644 > index 0000000000..db3e8e95bc > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > c > @@ -0,0 +1,649 @@ > +/** @file > + MPAM Table Generator > + > + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. > + Copyright (c) 2022, ARM Limited. All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + @par Reference(s): > + - ACPI 6.4 Specification, January 2021 > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > +**/ > + > +#include <IndustryStandard/Mpam.h> > +#include <Library/AcpiLib.h> > +#include <Library/BaseLib.h> > +#include <Library/DebugLib.h> > +#include <Library/MemoryAllocationLib.h> #include > +<Protocol/AcpiTable.h> > + > +// Module specific include files. > +#include <AcpiTableGenerator.h> > +#include <ConfigurationManagerObject.h> #include > +<ConfigurationManagerHelper.h> #include <Library/TableHelperLib.h> > +#include <Protocol/ConfigurationManagerProtocol.h> > + > +#include "MpamGenerator.h" > + > +/** > + ARM standard MPAM Generator > + > + Requirements: > + The following Configuration Manager Object(s) are used by this > Generator: > + - EArmObjMscNodeInfo (REQUIRED) > + - EArmObjResNodeInfo > +*/ > + > +/** > + This macro expands to a function that retrieves the MSC Node > +information > + from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjMscNodeInfo, > + CM_ARM_MSC_NODE_INFO > + ); > + > +/** > + This macro expands to a function that retrieves the Resource Node > + information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjResNodeInfo, > + CM_ARM_RESOURCE_NODE_INFO > + ); > + > +/** > + Returns the size of the MPAM Memory System Controller (MSC) Node > + > + @param [in] Node Pointer to MSC Node Info CM object > + > + @retval Size of the MSC Node in bytes. > +**/ > +STATIC > +UINT32 > +GetMscNodeSize ( > + IN CONST CM_ARM_MSC_NODE_INFO *Node > + ) > +{ > + ASSERT (Node != NULL); > + > + // <size of Memory System Controller Node> > + return (UINT32)(sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE) + > + Node->NumResourceNodes * sizeof > +(EFI_ACPI_6_4_MPAM_RESOURCE_NODE)); [Rohit] Shouldn't the node size include the size of functional dependency descriptor * number of functional dependency descriptor? > +} > + > +/** Returns the total size required for the MSC and > + updates the Node Indexer. > + > + This function calculates the size required for the node group > + and also populates the Node Indexer array with offsets for the > + individual nodes. > + > + @param [in] NodeStartOffset Offset from the start of the > + MPAM where this node group starts. [Rohit] Should it be "start of the MPAM table where .."? > + @param [in] NodeList Pointer to MSC Group node list. > + @param [in] NodeCount Count of the MSC Group nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the ITS Group Nodes. > +**/ > +STATIC > +UINT64 > +GetSizeofMscGroupNodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_MSC_NODE_INFO *NodeList, > + IN UINT32 NodeCount, > + IN OUT MPAM_NODE_INDEXER **CONST NodeIndexer > + ) > +{ > + UINT64 Size; > + > + ASSERT (NodeList != NULL); > + > + Size = 0; > + while (NodeCount-- != 0) { > + (*NodeIndexer)->Token = NodeList->Token; > + (*NodeIndexer)->Object = (VOID *)NodeList; > + (*NodeIndexer)->Offset = (UINT32)(Size + NodeStartOffset); > + DEBUG (( > + DEBUG_INFO, > + "MPAM: MSC Node Indexer = %p, Token = %p, Object = %p, Offset = > 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size += GetMscNodeSize (NodeList); > + > + (*NodeIndexer)++; > + NodeList++; > + } > + > + return Size; > +} > + > +/** Update the MSC Group Node Information. > + > + @param [in] This Pointer to the table Generator. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [in] Mpam Pointer to MPAM table structure. > + @param [in] NodesStartOffset Offset for the start of the Msc Group > + Nodes. > + @param [in] NodeList Pointer to an array of Msc Group Node > + Objects. > + @param [in] NodeCount Number of Msc Group Node Objects. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > +**/ > +STATIC > +EFI_STATUS > +AddMscNodes ( > + IN CONST ACPI_TABLE_GENERATOR > *CONST > This, > + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL > *CONST CfgMgrProtocol, > + IN CONST > EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_HEADER *Mpam, > + IN CONST UINT32 > NodesStartOffset, > + IN CONST CM_ARM_MSC_NODE_INFO > *NodeList, > + IN UINT32 > NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_4_MPAM_MSC_NODE *MscNode; > + EFI_ACPI_6_4_MPAM_RESOURCE_NODE *ResourceNodeArray; > + CM_ARM_RESOURCE_NODE_INFO *ResourceNodeList; > + UINT64 NodeLength; > + UINT32 ResourceNodeCount; > + > + ASSERT (Mpam != NULL); > + > + MscNode = (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)Mpam + > + NodesStartOffset); > + > + // Get the Resource Node info to update the MPAM MSC node Status = > + GetEArmObjResNodeInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &ResourceNodeList, > + &ResourceNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to add resource nodes info. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + while (NodeCount-- != 0) { > + NodeLength = GetMscNodeSize (NodeList); > + > + if (NodeLength > MAX_UINT16) { > + Status = EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: MSC Node length 0x%lx > MAX_UINT16. Status = > %r\n", > + NodeLength, > + Status > + )); > + return Status; > + } > + > + // Populate the node header > + MscNode->Length = (UINT16)NodeLength; > + MscNode->Reserved = EFI_ACPI_RESERVED_WORD; > + MscNode->Identifier = EFI_ACPI_RESERVED_DWORD; [Rohit] MPAM ACPI 1.0, section 2.1, table 4 - MSC node body, defines identifier as a unique value. For systems with multiple MSCs, the OS could expect identifiers to be unique. Could this be addressed, please? > + MscNode->BaseAddress = NodeList->BaseAddress; > + MscNode->MmioSize = NodeList->MmioSize; > + MscNode->OverflowInterrupt = NodeList->OverflowInterrupt; > + MscNode->OverflowInterruptFlags = NodeList->OverflowInterruptFlags; > + MscNode->Reserved1 = EFI_ACPI_RESERVED_DWORD; > + MscNode->OverflowInterruptAff = NodeList->OverflowInterruptAff; > + MscNode->ErrorInterrupt = NodeList->ErrorInterrupt; > + MscNode->ErrorInterruptFlags = NodeList->ErrorInterruptFlags; > + MscNode->Reserved2 = EFI_ACPI_RESERVED_DWORD; > + MscNode->ErrorInterruptAff = NodeList->ErrorInterruptAff; > + MscNode->MaxNRdyUsec = NodeList->MaxNRdyUsec; > + MscNode->LinkedDeviceHwId = NodeList->LinkedDeviceHwId; > + MscNode->LinkedDeviceInstanceHwId = NodeList- > >LinkedDeviceInstanceHwId; > + MscNode->NumResourceNodes = NodeList->NumResourceNodes; > + > + // ResourceNode List for each MSC > + if (MscNode->NumResourceNodes > 0) { > + // Resource Node array for this Msc node > + ResourceNodeArray = (EFI_ACPI_6_4_MPAM_RESOURCE_NODE > *)((UINT8 *)MscNode + sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE)); > + // Adding Resource Node content > + while ( MscNode->NumResourceNodes-- != 0 ) { > + ResourceNodeArray->Identifier = ResourceNodeList->Identifier; > + ResourceNodeArray->RisIndex = ResourceNodeList->RisIndex; > + ResourceNodeArray->Reserved1 = EFI_ACPI_RESERVED_WORD; > + ResourceNodeArray->LocatorType = ResourceNodeList->LocatorType; > + ResourceNodeArray->Locator = ResourceNodeList->Locator; > + ResourceNodeArray->NumFuncDep = ResourceNodeList- > >NumFuncDep; [Rohit] If NumFuncDep > 0, shouldn't we need an additional loop to populate functional dependency list? > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to add Resource Node List. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + ResourceNodeList++; > + ResourceNodeArray++; > + } > + } > + > + // Next MSC Node > + MscNode = (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)MscNode + > MscNode->Length); > + NodeList++; > + } // Msc Node > + > + return EFI_SUCCESS; > +} > + > +/** > + Construct the MPAM ACPI table. > + > + This function invokes the Configuration Manager protocol interface > + to get the required hardware information for generating the ACPI > + table. > + > + If this function allocates any resources then they must be freed in > + the FreeXXXXTableResources function. > + > + @param [in] This Pointer to the table generator. > + @param [in] AcpiTableInfo Pointer to the ACPI table generator to be > used. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for > + the requested object. > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildMpamTable ( > + IN CONST ACPI_TABLE_GENERATOR *CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, > + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table > + ) > +{ > + EFI_STATUS Status; > + UINT64 TableSize; > + UINT64 NodeSize; > + UINT32 MpamNodeCount; > + > + UINT32 MscNodeCount; > + UINT32 MscNodeOffset; > + > + > EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_HEADER *Mpam; > + ACPI_MPAM_GENERATOR > *Generator; > + CM_ARM_MSC_NODE_INFO > *MscNodeList; > + MPAM_NODE_INDEXER > *NodeIndexer; > + > + ASSERT ( > + (This != NULL) && > + (AcpiTableInfo != NULL) && > + (CfgMgrProtocol != NULL) && > + (Table != NULL) && > + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && > + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) > + ); > + > + DEBUG (( > + DEBUG_ERROR, > + "DEBUG PRINT: MPAM: Requested table revision = %d\n", > + AcpiTableInfo->AcpiTableRevision > + )); > + > + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || > + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Requested table revision = %d is not supported. " > + "Supported table revisions: Minimum = %d. Maximum = %d\n", > + AcpiTableInfo->AcpiTableRevision, > + This->MinAcpiTableRevision, > + This->AcpiTableRevision > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + Generator = (ACPI_MPAM_GENERATOR *)This; > + *Table = NULL; > + > + // Get the Memory System Controller Node info and update the MPAM // > + structure count with MSC Node count (Type 0) Status = > + GetEArmObjMscNodeInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &MscNodeList, > + &MscNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to get memory system controller node info. > Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + MpamNodeCount = MscNodeCount; > + Generator->MscNodeCount = MscNodeCount; > + > + // Allocate Node Indexer array > + NodeIndexer = (MPAM_NODE_INDEXER *)AllocateZeroPool ( > + sizeof (MPAM_NODE_INDEXER) * > + MpamNodeCount > + ); if (NodeIndexer == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to allocate memory for Node Indexer. Status = > %r\n ", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG ((DEBUG_INFO, "MPAM INFO: NodeIndexer = %p\n", > NodeIndexer)); > + Generator->MpamNodeCount = MpamNodeCount; > + Generator->NodeIndexer = NodeIndexer; > + > + // Calculate the size of the MPAM table TableSize = sizeof > + > (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_HEA > + DER); > + > + // Include the size of MSC Nodes and index them if > + (Generator->MscNodeCount != 0) { > + MscNodeOffset = TableSize; > + // Size of MSC nodes. > + NodeSize = GetSizeofMscGroupNodes ( > + MscNodeOffset, > + MscNodeList, > + Generator->MscNodeCount, > + &NodeIndexer > + ); [Rohit] MscNodeOffset is sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER), which moves past EFI_ACPI_DESCRIPTION_HEADER by 12 bytes. Should we be having these fields in the table type? UINT32 NumNodes; UINT32 NodeOffset; UINT32 Reserved; I had added a similar comment on [PATCH 1/2]. [/Rohit] > + if (NodeSize > MAX_UINT32) { > + Status = EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Invalid Size of Group Nodes. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + TableSize += NodeSize; > + > + DEBUG (( > + DEBUG_INFO, > + " MscNodeCount = %d\n" \ > + " MscNodeOffset = 0x%x\n", > + Generator->MscNodeCount, > + MscNodeOffset > + )); > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: MPAM:\n" \ > + " MpamNodeCount = %d\n" \ > + " TableSize = 0x%X\n", > + MpamNodeCount, > + TableSize > + )); > + > + if (TableSize > MAX_UINT32) { > + Status = EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: MPAM Table Size 0x%lx > MAX_UINT32," \ > + " Status = %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + // Allocate the Buffer for the MPAM table *Table = > + (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); if > + (*Table == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to allocate memory for MPAM Table. " \ > + "Size = %d. Status = %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Mpam = > + > (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_HEA > + DER *)*Table; > + > + DEBUG (( > + DEBUG_INFO, > + "MPAM: Mpam = 0x%p. TableSize = 0x%x\n", > + Mpam, > + TableSize > + )); > + > + // Add ACPI header > + Status = AddAcpiHeader ( > + CfgMgrProtocol, > + This, > + &Mpam->Header, > + AcpiTableInfo, > + TableSize > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to add ACPI header. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update MPAM table > + Mpam->NumNodes = MscNodeCount; > + Mpam->NodeOffset = sizeof > (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_HEADER); > + Mpam->Reserved = EFI_ACPI_RESERVED_DWORD; > + > + // Add MSC Nodes to the generated table if (Mpam->NumNodes != 0) { > + Status = AddMscNodes ( > + This, > + CfgMgrProtocol, > + Mpam, > + MscNodeOffset, > + MscNodeList, > + MscNodeCount > + ); [Rohit] Same comment as above > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MPAM: Failed to add MSC Nodes. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + return Status; > + > +error_handler: > + if (Generator->NodeIndexer != NULL) { > + FreePool (Generator->NodeIndexer); > + Generator->NodeIndexer = NULL; > + } > + > + if (*Table != NULL) { > + FreePool (*Table); > + *Table = NULL; > + } > + > + return Status; > +} > + > +/** Free any resources allocated for constructing the MPAM [Rohit] Should this be "constructing the MPAM table"? > + > + @param [in] This Pointer to the table generator. > + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [in, out] Table Pointer to the ACPI Table. > + > + @retval EFI_SUCCESS The resources were freed successfully. > + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. > +**/ > +STATIC > +EFI_STATUS > +FreeMpamTableResources ( > + IN CONST ACPI_TABLE_GENERATOR *CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST > AcpiTableInfo, > + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table > + ) > +{ > + ACPI_MPAM_GENERATOR *Generator; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == > + This->AcpiTableSignature); > + > + Generator = (ACPI_MPAM_GENERATOR *)This; > + > + // Free any memory allocated by the generator if > + (Generator->NodeIndexer != NULL) { > + FreePool (Generator->NodeIndexer); > + Generator->NodeIndexer = NULL; > + } > + > + if ((Table == NULL) || (*Table == NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: MPAM: Invalid Table Pointer\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table = NULL; > + > + return EFI_SUCCESS; > +} > + > +/** The MPAM Table Generator revision. > +*/ > +#define MPAM_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the MPAM Table Generator. > +*/ > +STATIC > +ACPI_MPAM_GENERATOR MpamGenerator = { > + // ACPI table generator header > + { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMpam), > + // Generator Description > + L"ACPI.STD.MPAM.GENERATOR", > + // ACPI Table Signature > + > EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_STRUCTURE_SIGNATURE, > + // ACPI Table Revision supported by this Generator > + > EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_REVISION, > + // Minimum supported ACPI Table Revision > + > EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORIN > G_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + MPAM_GENERATOR_REVISION, > + // Build Table function > + BuildMpamTable, > + // Free Resource function > + FreeMpamTableResources, > + // Extended build function not needed > + NULL, > + // Extended build function not implemented by the generator. > + // Hence extended free resource function is not required. > + NULL > + }, > + > + // MPAM Generator private data > + > + // MPAM node count > + 0, > + // MSC node count > + 0, > + > + // Pointer to MPAM Node Indexer > + NULL > +}; > + > +/** > + Register the Generator with the ACPI Table Factory. > + > + @param [in] ImageHandle The handle to the image. > + @param [in] SystemTable Pointer to the System Table. > + > + @retval EFI_SUCCESS The Generator is registered. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID > + is already registered. > +**/ > +EFI_STATUS > +EFIAPI > +AcpiMpamLibConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + Status = RegisterAcpiTableGenerator (&MpamGenerator.Header); > + DEBUG ((DEBUG_INFO, "MPAM: Register Generator. Status = %r\n", > +Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** > + Deregister the Generator from the ACPI Table Factory. > + > + @param [in] ImageHandle The handle to the image. > + @param [in] SystemTable Pointer to the System Table. > + > + @retval EFI_SUCCESS The Generator is deregistered. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The Generator is not registered. > +**/ > +EFI_STATUS > +EFIAPI > +AcpiMpamLibDestructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + Status = DeregisterAcpiTableGenerator (&MpamGenerator.Header); > + DEBUG ((DEBUG_INFO, "MPAM: Deregister Generator. Status = %r\n", > +Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > h > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > h > new file mode 100644 > index 0000000000..1075bd8c6c > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator. > h > @@ -0,0 +1,47 @@ > +/** @file > + Header file for the dynamic MPAM generator > + > + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. > + Copyright (c) 2022, ARM Limited. All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + @par Reference(s): > + - ACPI 6.4 Specification, January 2021 > + - ARM Architecture Reference Manual ARMv8 > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > +**/ > + > +#ifndef MPAM_GENERATOR_H_ > +#define MPAM_GENERATOR_H_ > + > +#pragma pack(1) > + > +/** A structure that describes the Node indexer > + used for indexing the MPAM MSC nodes. > +*/ > +typedef struct MpamNodeIndexer { > + /// Index token for the Node > + CM_OBJECT_TOKEN Token; > + /// Pointer to the node > + VOID *Object; > + /// Node offset from the start of the MPAM table > + UINT32 Offset; > +} MPAM_NODE_INDEXER; > + > +typedef struct AcpiMpamGenerator { > + /// ACPI Table generator header > + ACPI_TABLE_GENERATOR Header; > + /// MPAM structure count > + UINT32 MpamNodeCount; > + /// Count of Msc Nodes > + UINT32 MscNodeCount; > + /// List of indexed CM objects for MPAM generation > + MPAM_NODE_INDEXER *NodeIndexer; > +} ACPI_MPAM_GENERATOR; > + > +#pragma pack() > + > +#endif // MPAM_GENERATOR_H_ > -- > 2.17.1 > > > > > Regards, Rohit -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#92576): https://edk2.groups.io/g/devel/message/92576 Mute This Topic: https://groups.io/mt/93069489/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-