DynamicTablesPkg: IORT generator updates for Rev E.d spec
Bugzilla: 3458 - Add support IORT Rev E.d specification updates
          (https://bugzilla.tianocore.org/show_bug.cgi?id=3458)
The IO Remapping Table, Platform Design Document, Revision E.d,
Feb 2022 (https://developer.arm.com/documentation/den0049/)
introduces the following updates, collectively including the
updates and errata fixes to Rev E, Rev E.a, Rev E.b, Rev E.c:
 - increments the IORT table revision to 5.
 - updates the node definition to add an 'Identifier' field.
 - adds definition of node type 6 - Reserved Memory Range node.
 - adds definition for Memory Range Descriptors.
 - adds flag to indicate PRI support for root complexes.
 - adds flag to indicate if the root complex supports forwarding
   of PASID information on translated transactions to the SMMU.
 - adds flag to indicate if the root complex supports PASID.
 - adds flags to define access privilege and attributes for the
   memory ranges.
Therefore, update the IORT generator to:
  - increment IORT table revision count to 5.
  - populate Identifier filed if revision is greater than 4.
  - add support to populate Reserved Memory Range nodes and
    the Memory range descriptors.
  - add validation to check that the Identifier field is
    unique.
  - Populate the PASID capabilities and Flags field of the
    Root complex node.
 - Added checks to not generate IORT Rev E, Rev E.<a,b,c>.
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
			
			
This commit is contained in:
		
				
					committed by
					
						![mergify[bot]](/avatar/e3df20cd7a67969c41a65f03bea54961?size=40) mergify[bot]
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							de200b7e2c
						
					
				
				
					commit
					e9150618ec
				
			| @@ -5,8 +5,8 @@ | |||||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent |   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||||
|  |  | ||||||
|   @par Reference(s): |   @par Reference(s): | ||||||
|   - IO Remapping Table, Platform Design Document, |   - IO Remapping Table, Platform Design Document, Revision E.d, Feb 2022 | ||||||
|     Document number: ARM DEN 0049D, Issue D, March 2018 |     (https://developer.arm.com/documentation/den0049/) | ||||||
|  |  | ||||||
| **/ | **/ | ||||||
|  |  | ||||||
| @@ -37,9 +37,11 @@ Requirements: | |||||||
|   - EArmObjSmmuV1SmmuV2 |   - EArmObjSmmuV1SmmuV2 | ||||||
|   - EArmObjSmmuV3 |   - EArmObjSmmuV3 | ||||||
|   - EArmObjPmcg |   - EArmObjPmcg | ||||||
|  |   - EArmObjRmr | ||||||
|   - EArmObjGicItsIdentifierArray |   - EArmObjGicItsIdentifierArray | ||||||
|   - EArmObjIdMappingArray |   - EArmObjIdMappingArray | ||||||
|   - EArmObjGicItsIdentifierArray |   - EArmObjSmmuInterruptArray | ||||||
|  |   - EArmObjMemoryRangeDescriptor | ||||||
| */ | */ | ||||||
|  |  | ||||||
| /** This macro expands to a function that retrieves the ITS | /** This macro expands to a function that retrieves the ITS | ||||||
| @@ -96,6 +98,24 @@ GET_OBJECT_LIST ( | |||||||
|   CM_ARM_PMCG_NODE |   CM_ARM_PMCG_NODE | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  | /** This macro expands to a function that retrieves the | ||||||
|  |     RMR node information from the Configuration Manager. | ||||||
|  | */ | ||||||
|  | GET_OBJECT_LIST ( | ||||||
|  |   EObjNameSpaceArm, | ||||||
|  |   EArmObjRmr, | ||||||
|  |   CM_ARM_RMR_NODE | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  | /** This macro expands to a function that retrieves the | ||||||
|  |     Memory Range Descriptor Array information from the Configuration Manager. | ||||||
|  | */ | ||||||
|  | GET_OBJECT_LIST ( | ||||||
|  |   EObjNameSpaceArm, | ||||||
|  |   EArmObjMemoryRangeDescriptor, | ||||||
|  |   CM_ARM_MEMORY_RANGE_DESCRIPTOR | ||||||
|  |   ); | ||||||
|  |  | ||||||
| /** This macro expands to a function that retrieves the | /** This macro expands to a function that retrieves the | ||||||
|     ITS Identifier Array information from the Configuration Manager. |     ITS Identifier Array information from the Configuration Manager. | ||||||
| */ | */ | ||||||
| @@ -177,13 +197,16 @@ GetSizeofItsGroupNodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetItsGroupNodeSize (NodeList); |     Size += GetItsGroupNodeSize (NodeList); | ||||||
| @@ -251,13 +274,16 @@ GetSizeofNamedComponentNodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetNamedComponentNodeSize (NodeList); |     Size += GetNamedComponentNodeSize (NodeList); | ||||||
| @@ -323,13 +349,16 @@ GetSizeofRootComplexNodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetRootComplexNodeSize (NodeList); |     Size += GetRootComplexNodeSize (NodeList); | ||||||
| @@ -401,13 +430,16 @@ GetSizeofSmmuV1V2Nodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetSmmuV1V2NodeSize (NodeList); |     Size += GetSmmuV1V2NodeSize (NodeList); | ||||||
| @@ -473,13 +505,16 @@ GetSizeofSmmuV3Nodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetSmmuV3NodeSize (NodeList); |     Size += GetSmmuV3NodeSize (NodeList); | ||||||
| @@ -545,13 +580,16 @@ GetSizeofPmcgNodes ( | |||||||
|     (*NodeIndexer)->Token      = NodeList->Token; |     (*NodeIndexer)->Token      = NodeList->Token; | ||||||
|     (*NodeIndexer)->Object     = (VOID *)NodeList; |     (*NodeIndexer)->Object     = (VOID *)NodeList; | ||||||
|     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); |     (*NodeIndexer)->Offset     = (UINT32)(Size + NodeStartOffset); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|     DEBUG (( |     DEBUG (( | ||||||
|       DEBUG_INFO, |       DEBUG_INFO, | ||||||
|       "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|       *NodeIndexer, |       *NodeIndexer, | ||||||
|       (*NodeIndexer)->Token, |       (*NodeIndexer)->Token, | ||||||
|       (*NodeIndexer)->Object, |       (*NodeIndexer)->Object, | ||||||
|       (*NodeIndexer)->Offset |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|       )); |       )); | ||||||
|  |  | ||||||
|     Size += GetPmcgNodeSize (NodeList); |     Size += GetPmcgNodeSize (NodeList); | ||||||
| @@ -562,6 +600,84 @@ GetSizeofPmcgNodes ( | |||||||
|   return Size; |   return Size; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** Returns the size of the RMR node. | ||||||
|  |  | ||||||
|  |     @param [in]  Node    Pointer to RMR node. | ||||||
|  |  | ||||||
|  |     @retval Size of the RMR node. | ||||||
|  | **/ | ||||||
|  | STATIC | ||||||
|  | UINT32 | ||||||
|  | GetRmrNodeSize ( | ||||||
|  |   IN  CONST CM_ARM_RMR_NODE  *Node | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   ASSERT (Node != NULL); | ||||||
|  |  | ||||||
|  |   /* Size of RMR node + | ||||||
|  |      Size of ID mapping array + | ||||||
|  |      Size of Memory Range Descriptor array | ||||||
|  |   */ | ||||||
|  |   return (UINT32)(sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE) + | ||||||
|  |                   (Node->IdMappingCount * | ||||||
|  |                    sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)) + | ||||||
|  |                   (Node->MemRangeDescCount * | ||||||
|  |                    sizeof (EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** Returns the total size required for the RMR nodes 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 | ||||||
|  |                                       IORT where this node group starts. | ||||||
|  |     @param [in]       NodeList        Pointer to RMR node list. | ||||||
|  |     @param [in]       NodeCount       Count of the RMR nodes. | ||||||
|  |     @param [in, out]  NodeIndexer     Pointer to the next Node Indexer. | ||||||
|  |  | ||||||
|  |     @retval Total size of the RMR nodes. | ||||||
|  | **/ | ||||||
|  | STATIC | ||||||
|  | UINT64 | ||||||
|  | GetSizeofRmrNodes ( | ||||||
|  |   IN      CONST UINT32                     NodeStartOffset, | ||||||
|  |   IN      CONST CM_ARM_RMR_NODE            *NodeList, | ||||||
|  |   IN            UINT32                     NodeCount, | ||||||
|  |   IN OUT        IORT_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); | ||||||
|  |     (*NodeIndexer)->Identifier = NodeList->Identifier; | ||||||
|  |     DEBUG (( | ||||||
|  |       DEBUG_INFO, | ||||||
|  |       "IORT: Node Indexer = %p, Token = %p, Object = %p," | ||||||
|  |       " Offset = 0x%x, Identifier = 0x%x\n", | ||||||
|  |       *NodeIndexer, | ||||||
|  |       (*NodeIndexer)->Token, | ||||||
|  |       (*NodeIndexer)->Object, | ||||||
|  |       (*NodeIndexer)->Offset, | ||||||
|  |       (*NodeIndexer)->Identifier | ||||||
|  |       )); | ||||||
|  |  | ||||||
|  |     Size += GetRmrNodeSize (NodeList); | ||||||
|  |     (*NodeIndexer)++; | ||||||
|  |     NodeList++; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return Size; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** Returns the offset of the Node referenced by the Token. | /** Returns the offset of the Node referenced by the Token. | ||||||
|  |  | ||||||
|     @param [in]  NodeIndexer  Pointer to node indexer array. |     @param [in]  NodeIndexer  Pointer to node indexer array. | ||||||
| @@ -713,6 +829,7 @@ AddIdMappingArray ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the ITS Group |     @param [in]     NodesStartOffset Offset for the start of the ITS Group | ||||||
|                                      Nodes. |                                      Nodes. | ||||||
| @@ -729,6 +846,7 @@ EFI_STATUS | |||||||
| AddItsGroupNodes ( | AddItsGroupNodes ( | ||||||
|   IN  CONST ACPI_TABLE_GENERATOR                  *CONST  This, |   IN  CONST ACPI_TABLE_GENERATOR                  *CONST  This, | ||||||
|   IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, |   IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, | ||||||
|  |   IN  CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo, | ||||||
|   IN  CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, |   IN  CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, | ||||||
|   IN  CONST UINT32                                        NodesStartOffset, |   IN  CONST UINT32                                        NodesStartOffset, | ||||||
|   IN  CONST CM_ARM_ITS_GROUP_NODE                         *NodeList, |   IN  CONST CM_ARM_ITS_GROUP_NODE                         *NodeList, | ||||||
| @@ -765,11 +883,19 @@ AddItsGroupNodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     ItsGroupNode->Node.Type          = EFI_ACPI_IORT_TYPE_ITS_GROUP; |     ItsGroupNode->Node.Type          = EFI_ACPI_IORT_TYPE_ITS_GROUP; | ||||||
|     ItsGroupNode->Node.Length        = (UINT16)NodeLength; |     ItsGroupNode->Node.Length        = (UINT16)NodeLength; | ||||||
|     ItsGroupNode->Node.Revision      = 0; |  | ||||||
|     ItsGroupNode->Node.Identifier    = EFI_ACPI_RESERVED_DWORD; |  | ||||||
|     ItsGroupNode->Node.NumIdMappings = 0; |     ItsGroupNode->Node.NumIdMappings = 0; | ||||||
|     ItsGroupNode->Node.IdReference   = 0; |     ItsGroupNode->Node.IdReference   = 0; | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|  |       ItsGroupNode->Node.Revision   = 0; | ||||||
|  |       ItsGroupNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |     } else { | ||||||
|  |       ItsGroupNode->Node.Revision   = 1; | ||||||
|  |       ItsGroupNode->Node.Identifier = NodeList->Identifier; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // IORT specific data |     // IORT specific data | ||||||
|     ItsGroupNode->NumItsIdentifiers = NodeList->ItsIdCount; |     ItsGroupNode->NumItsIdentifiers = NodeList->ItsIdCount; | ||||||
|     ItsIds                          = (UINT32 *)((UINT8 *)ItsGroupNode + |     ItsIds                          = (UINT32 *)((UINT8 *)ItsGroupNode + | ||||||
| @@ -820,6 +946,7 @@ AddItsGroupNodes ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the Named |     @param [in]     NodesStartOffset Offset for the start of the Named | ||||||
|                                      Component Nodes. |                                      Component Nodes. | ||||||
| @@ -836,6 +963,7 @@ EFI_STATUS | |||||||
| AddNamedComponentNodes ( | AddNamedComponentNodes ( | ||||||
|   IN      CONST ACPI_TABLE_GENERATOR                   *CONST  This, |   IN      CONST ACPI_TABLE_GENERATOR                   *CONST  This, | ||||||
|   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL   *CONST  CfgMgrProtocol, |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL   *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO             *CONST  AcpiTableInfo, | ||||||
|   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE                *Iort, |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE                *Iort, | ||||||
|   IN      CONST UINT32                                         NodesStartOffset, |   IN      CONST UINT32                                         NodesStartOffset, | ||||||
|   IN      CONST CM_ARM_NAMED_COMPONENT_NODE                    *NodeList, |   IN      CONST CM_ARM_NAMED_COMPONENT_NODE                    *NodeList, | ||||||
| @@ -871,9 +999,17 @@ AddNamedComponentNodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     NcNode->Node.Type          = EFI_ACPI_IORT_TYPE_NAMED_COMP; |     NcNode->Node.Type          = EFI_ACPI_IORT_TYPE_NAMED_COMP; | ||||||
|     NcNode->Node.Length        = (UINT16)NodeLength; |     NcNode->Node.Length        = (UINT16)NodeLength; | ||||||
|  |     NcNode->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|       NcNode->Node.Revision   = 2; |       NcNode->Node.Revision   = 2; | ||||||
|       NcNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD; |       NcNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD; | ||||||
|     NcNode->Node.NumIdMappings = NodeList->IdMappingCount; |     } else { | ||||||
|  |       NcNode->Node.Revision   = 4; | ||||||
|  |       NcNode->Node.Identifier = NodeList->Identifier; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     ObjectNameLength         = AsciiStrLen (NodeList->ObjectName) + 1; |     ObjectNameLength         = AsciiStrLen (NodeList->ObjectName) + 1; | ||||||
|     NcNode->Node.IdReference = (NodeList->IdMappingCount == 0) ? |     NcNode->Node.IdReference = (NodeList->IdMappingCount == 0) ? | ||||||
| @@ -955,6 +1091,7 @@ AddNamedComponentNodes ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the Root Complex |     @param [in]     NodesStartOffset Offset for the start of the Root Complex | ||||||
|                                      Nodes. |                                      Nodes. | ||||||
| @@ -971,6 +1108,7 @@ EFI_STATUS | |||||||
| AddRootComplexNodes ( | AddRootComplexNodes ( | ||||||
|   IN      CONST ACPI_TABLE_GENERATOR                   *CONST  This, |   IN      CONST ACPI_TABLE_GENERATOR                   *CONST  This, | ||||||
|   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL   *CONST  CfgMgrProtocol, |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL   *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO             *CONST  AcpiTableInfo, | ||||||
|   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE                *Iort, |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE                *Iort, | ||||||
|   IN      CONST UINT32                                         NodesStartOffset, |   IN      CONST UINT32                                         NodesStartOffset, | ||||||
|   IN      CONST CM_ARM_ROOT_COMPLEX_NODE                       *NodeList, |   IN      CONST CM_ARM_ROOT_COMPLEX_NODE                       *NodeList, | ||||||
| @@ -1004,12 +1142,23 @@ AddRootComplexNodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     RcNode->Node.Type          = EFI_ACPI_IORT_TYPE_ROOT_COMPLEX; |     RcNode->Node.Type          = EFI_ACPI_IORT_TYPE_ROOT_COMPLEX; | ||||||
|     RcNode->Node.Length        = (UINT16)NodeLength; |     RcNode->Node.Length        = (UINT16)NodeLength; | ||||||
|     RcNode->Node.Revision      = 1; |  | ||||||
|     RcNode->Node.Identifier    = EFI_ACPI_RESERVED_DWORD; |  | ||||||
|     RcNode->Node.NumIdMappings = NodeList->IdMappingCount; |     RcNode->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|     RcNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? |     RcNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? | ||||||
|                                  0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); |                                  0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|  |       RcNode->Node.Revision     = 1; | ||||||
|  |       RcNode->Node.Identifier   = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |       RcNode->PasidCapabilities = EFI_ACPI_RESERVED_WORD; | ||||||
|  |     } else { | ||||||
|  |       RcNode->Node.Revision     = 4; | ||||||
|  |       RcNode->Node.Identifier   = NodeList->Identifier; | ||||||
|  |       RcNode->PasidCapabilities = NodeList->PasidCapabilities; | ||||||
|  |       RcNode->Flags             = NodeList->Flags; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Root Complex specific data |     // Root Complex specific data | ||||||
|     RcNode->CacheCoherent     = NodeList->CacheCoherent; |     RcNode->CacheCoherent     = NodeList->CacheCoherent; | ||||||
|     RcNode->AllocationHints   = NodeList->AllocationHints; |     RcNode->AllocationHints   = NodeList->AllocationHints; | ||||||
| @@ -1018,7 +1167,6 @@ AddRootComplexNodes ( | |||||||
|     RcNode->AtsAttribute      = NodeList->AtsAttribute; |     RcNode->AtsAttribute      = NodeList->AtsAttribute; | ||||||
|     RcNode->PciSegmentNumber  = NodeList->PciSegmentNumber; |     RcNode->PciSegmentNumber  = NodeList->PciSegmentNumber; | ||||||
|     RcNode->MemoryAddressSize = NodeList->MemoryAddressSize; |     RcNode->MemoryAddressSize = NodeList->MemoryAddressSize; | ||||||
|     RcNode->PasidCapabilities = EFI_ACPI_RESERVED_WORD; |  | ||||||
|     RcNode->Reserved1[0]      = EFI_ACPI_RESERVED_BYTE; |     RcNode->Reserved1[0]      = EFI_ACPI_RESERVED_BYTE; | ||||||
|  |  | ||||||
|     if (NodeList->IdMappingCount > 0) { |     if (NodeList->IdMappingCount > 0) { | ||||||
| @@ -1134,6 +1282,7 @@ AddSmmuInterruptArray ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the SMMU v1/v2 |     @param [in]     NodesStartOffset Offset for the start of the SMMU v1/v2 | ||||||
|                                      Nodes. |                                      Nodes. | ||||||
| @@ -1150,6 +1299,7 @@ EFI_STATUS | |||||||
| AddSmmuV1V2Nodes ( | AddSmmuV1V2Nodes ( | ||||||
|   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, |   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, | ||||||
|   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo, | ||||||
|   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, | ||||||
|   IN      CONST UINT32                                        NodesStartOffset, |   IN      CONST UINT32                                        NodesStartOffset, | ||||||
|   IN      CONST CM_ARM_SMMUV1_SMMUV2_NODE                     *NodeList, |   IN      CONST CM_ARM_SMMUV1_SMMUV2_NODE                     *NodeList, | ||||||
| @@ -1186,8 +1336,6 @@ AddSmmuV1V2Nodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     SmmuNode->Node.Type          = EFI_ACPI_IORT_TYPE_SMMUv1v2; |     SmmuNode->Node.Type          = EFI_ACPI_IORT_TYPE_SMMUv1v2; | ||||||
|     SmmuNode->Node.Length        = (UINT16)NodeLength; |     SmmuNode->Node.Length        = (UINT16)NodeLength; | ||||||
|     SmmuNode->Node.Revision      = 0; |  | ||||||
|     SmmuNode->Node.Identifier    = EFI_ACPI_RESERVED_DWORD; |  | ||||||
|     SmmuNode->Node.NumIdMappings = NodeList->IdMappingCount; |     SmmuNode->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|     SmmuNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? |     SmmuNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? | ||||||
|                                    0 : (sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) + |                                    0 : (sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) + | ||||||
| @@ -1196,6 +1344,16 @@ AddSmmuV1V2Nodes ( | |||||||
|                                         (NodeList->PmuInterruptCount * |                                         (NodeList->PmuInterruptCount * | ||||||
|                                          sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT))); |                                          sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT))); | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|  |       SmmuNode->Node.Revision   = 1; | ||||||
|  |       SmmuNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |     } else { | ||||||
|  |       SmmuNode->Node.Revision   = 3; | ||||||
|  |       SmmuNode->Node.Identifier = NodeList->Identifier; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // SMMU v1/v2 specific data |     // SMMU v1/v2 specific data | ||||||
|     SmmuNode->Base  = NodeList->BaseAddress; |     SmmuNode->Base  = NodeList->BaseAddress; | ||||||
|     SmmuNode->Span  = NodeList->Span; |     SmmuNode->Span  = NodeList->Span; | ||||||
| @@ -1339,6 +1497,7 @@ AddSmmuV1V2Nodes ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the SMMUv3 Nodes. |     @param [in]     NodesStartOffset Offset for the start of the SMMUv3 Nodes. | ||||||
|     @param [in]     NodeList         Pointer to an array of SMMUv3 Node Objects. |     @param [in]     NodeList         Pointer to an array of SMMUv3 Node Objects. | ||||||
| @@ -1353,6 +1512,7 @@ EFI_STATUS | |||||||
| AddSmmuV3Nodes ( | AddSmmuV3Nodes ( | ||||||
|   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, |   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, | ||||||
|   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo, | ||||||
|   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, | ||||||
|   IN      CONST UINT32                                        NodesStartOffset, |   IN      CONST UINT32                                        NodesStartOffset, | ||||||
|   IN      CONST CM_ARM_SMMUV3_NODE                            *NodeList, |   IN      CONST CM_ARM_SMMUV3_NODE                            *NodeList, | ||||||
| @@ -1385,12 +1545,20 @@ AddSmmuV3Nodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     SmmuV3Node->Node.Type          = EFI_ACPI_IORT_TYPE_SMMUv3; |     SmmuV3Node->Node.Type          = EFI_ACPI_IORT_TYPE_SMMUv3; | ||||||
|     SmmuV3Node->Node.Length        = (UINT16)NodeLength; |     SmmuV3Node->Node.Length        = (UINT16)NodeLength; | ||||||
|     SmmuV3Node->Node.Revision      = 2; |  | ||||||
|     SmmuV3Node->Node.Identifier    = EFI_ACPI_RESERVED_DWORD; |  | ||||||
|     SmmuV3Node->Node.NumIdMappings = NodeList->IdMappingCount; |     SmmuV3Node->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|     SmmuV3Node->Node.IdReference   = (NodeList->IdMappingCount == 0) ? |     SmmuV3Node->Node.IdReference   = (NodeList->IdMappingCount == 0) ? | ||||||
|                                      0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); |                                      0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|  |       SmmuV3Node->Node.Revision   = 2; | ||||||
|  |       SmmuV3Node->Node.Identifier = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |     } else { | ||||||
|  |       SmmuV3Node->Node.Revision   = 4; | ||||||
|  |       SmmuV3Node->Node.Identifier = NodeList->Identifier; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // SMMUv3 specific data |     // SMMUv3 specific data | ||||||
|     SmmuV3Node->Base         = NodeList->BaseAddress; |     SmmuV3Node->Base         = NodeList->BaseAddress; | ||||||
|     SmmuV3Node->Flags        = NodeList->Flags; |     SmmuV3Node->Flags        = NodeList->Flags; | ||||||
| @@ -1468,6 +1636,7 @@ AddSmmuV3Nodes ( | |||||||
|     @param [in]     This             Pointer to the table Generator. |     @param [in]     This             Pointer to the table Generator. | ||||||
|     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|                                      Protocol Interface. |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|     @param [in]     Iort             Pointer to IORT table structure. |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|     @param [in]     NodesStartOffset Offset for the start of the PMCG Nodes. |     @param [in]     NodesStartOffset Offset for the start of the PMCG Nodes. | ||||||
|     @param [in]     NodeList         Pointer to an array of PMCG Node Objects. |     @param [in]     NodeList         Pointer to an array of PMCG Node Objects. | ||||||
| @@ -1482,6 +1651,7 @@ EFI_STATUS | |||||||
| AddPmcgNodes ( | AddPmcgNodes ( | ||||||
|   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, |   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, | ||||||
|   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo, | ||||||
|   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, | ||||||
|   IN      CONST UINT32                                        NodesStartOffset, |   IN      CONST UINT32                                        NodesStartOffset, | ||||||
|   IN      CONST CM_ARM_PMCG_NODE                              *NodeList, |   IN      CONST CM_ARM_PMCG_NODE                              *NodeList, | ||||||
| @@ -1516,12 +1686,20 @@ AddPmcgNodes ( | |||||||
|     // Populate the node header |     // Populate the node header | ||||||
|     PmcgNode->Node.Type          = EFI_ACPI_IORT_TYPE_PMCG; |     PmcgNode->Node.Type          = EFI_ACPI_IORT_TYPE_PMCG; | ||||||
|     PmcgNode->Node.Length        = (UINT16)NodeLength; |     PmcgNode->Node.Length        = (UINT16)NodeLength; | ||||||
|     PmcgNode->Node.Revision      = 1; |  | ||||||
|     PmcgNode->Node.Identifier    = EFI_ACPI_RESERVED_DWORD; |  | ||||||
|     PmcgNode->Node.NumIdMappings = NodeList->IdMappingCount; |     PmcgNode->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|     PmcgNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? |     PmcgNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? | ||||||
|                                    0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE); |                                    0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE); | ||||||
|  |  | ||||||
|  |     if (AcpiTableInfo->AcpiTableRevision < | ||||||
|  |         EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |     { | ||||||
|  |       PmcgNode->Node.Revision   = 1; | ||||||
|  |       PmcgNode->Node.Identifier = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |     } else { | ||||||
|  |       PmcgNode->Node.Revision   = 2; | ||||||
|  |       PmcgNode->Node.Identifier = NodeList->Identifier; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // PMCG specific data |     // PMCG specific data | ||||||
|     PmcgNode->Base                  = NodeList->BaseAddress; |     PmcgNode->Base                  = NodeList->BaseAddress; | ||||||
|     PmcgNode->OverflowInterruptGsiv = NodeList->OverflowInterrupt; |     PmcgNode->OverflowInterruptGsiv = NodeList->OverflowInterrupt; | ||||||
| @@ -1588,6 +1766,274 @@ AddPmcgNodes ( | |||||||
|   return EFI_SUCCESS; |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** Update the Memory Range Descriptor Array. | ||||||
|  |  | ||||||
|  |     This function retrieves the Memory Range Descriptor objects referenced by | ||||||
|  |     MemRangeDescToken and updates the Memory Range Descriptor array. | ||||||
|  |  | ||||||
|  |     @param [in]     This             Pointer to the table Generator. | ||||||
|  |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|  |                                      Protocol Interface. | ||||||
|  |     @param [in]     DescArray        Pointer to an array of Memory Range | ||||||
|  |                                      Descriptors. | ||||||
|  |     @param [in]     DescCount        Number of Id Descriptors. | ||||||
|  |     @param [in]     DescToken        Reference Token for retrieving the | ||||||
|  |                                      Memory Range Descriptor Array. | ||||||
|  |  | ||||||
|  |     @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 | ||||||
|  | AddMemRangeDescArray ( | ||||||
|  |   IN  CONST ACPI_TABLE_GENERATOR                      *CONST  This, | ||||||
|  |   IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL      *CONST  CfgMgrProtocol, | ||||||
|  |   IN        EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC          *DescArray, | ||||||
|  |   IN        UINT32                                            DescCount, | ||||||
|  |   IN  CONST CM_OBJECT_TOKEN                                   DescToken | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   EFI_STATUS                      Status; | ||||||
|  |   CM_ARM_MEMORY_RANGE_DESCRIPTOR  *MemRangeDesc; | ||||||
|  |   UINT32                          MemRangeDescCount; | ||||||
|  |  | ||||||
|  |   ASSERT (DescArray != NULL); | ||||||
|  |  | ||||||
|  |   // Get the Id Mapping Array | ||||||
|  |   Status = GetEArmObjMemoryRangeDescriptor ( | ||||||
|  |              CfgMgrProtocol, | ||||||
|  |              DescToken, | ||||||
|  |              &MemRangeDesc, | ||||||
|  |              &MemRangeDescCount | ||||||
|  |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     DEBUG (( | ||||||
|  |       DEBUG_ERROR, | ||||||
|  |       "ERROR: IORT: Failed to get Memory Range Descriptor array. Status = %r\n", | ||||||
|  |       Status | ||||||
|  |       )); | ||||||
|  |     return Status; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (MemRangeDescCount < DescCount) { | ||||||
|  |     DEBUG (( | ||||||
|  |       DEBUG_ERROR, | ||||||
|  |       "ERROR: IORT: Failed to get the required number of Memory" | ||||||
|  |       " Range Descriptors.\n" | ||||||
|  |       )); | ||||||
|  |     return EFI_NOT_FOUND; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Populate the Memory Range Descriptor array | ||||||
|  |   while (DescCount-- != 0) { | ||||||
|  |     DescArray->Base     = MemRangeDesc->BaseAddress; | ||||||
|  |     DescArray->Length   = MemRangeDesc->Length; | ||||||
|  |     DescArray->Reserved = EFI_ACPI_RESERVED_DWORD; | ||||||
|  |  | ||||||
|  |     DescArray++; | ||||||
|  |     MemRangeDesc++; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** Update the RMR Node Information. | ||||||
|  |  | ||||||
|  |     This function updates the RMR node information in the IORT table. | ||||||
|  |  | ||||||
|  |     @param [in]     This             Pointer to the table Generator. | ||||||
|  |     @param [in]     CfgMgrProtocol   Pointer to the Configuration Manager | ||||||
|  |                                      Protocol Interface. | ||||||
|  |     @param [in]     AcpiTableInfo    Pointer to the ACPI table info structure. | ||||||
|  |     @param [in]     Iort             Pointer to IORT table structure. | ||||||
|  |     @param [in]     NodesStartOffset Offset for the start of the PMCG Nodes. | ||||||
|  |     @param [in]     NodeList         Pointer to an array of PMCG Node Objects. | ||||||
|  |     @param [in]     NodeCount        Number of PMCG 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 | ||||||
|  | AddRmrNodes ( | ||||||
|  |   IN      CONST ACPI_TABLE_GENERATOR                  *CONST  This, | ||||||
|  |   IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol, | ||||||
|  |   IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo, | ||||||
|  |   IN      CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE               *Iort, | ||||||
|  |   IN      CONST UINT32                                        NodesStartOffset, | ||||||
|  |   IN      CONST CM_ARM_RMR_NODE                               *NodeList, | ||||||
|  |   IN            UINT32                                        NodeCount | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   EFI_STATUS                                Status; | ||||||
|  |   EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE        *RmrNode; | ||||||
|  |   EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE        *IdMapArray; | ||||||
|  |   EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC  *MemRangeDescArray; | ||||||
|  |   UINT64                                    NodeLength; | ||||||
|  |  | ||||||
|  |   ASSERT (Iort != NULL); | ||||||
|  |  | ||||||
|  |   RmrNode = (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE *)((UINT8 *)Iort + | ||||||
|  |                                                    NodesStartOffset); | ||||||
|  |  | ||||||
|  |   while (NodeCount-- != 0) { | ||||||
|  |     NodeLength = GetRmrNodeSize (NodeList); | ||||||
|  |     if (NodeLength > MAX_UINT16) { | ||||||
|  |       Status = EFI_INVALID_PARAMETER; | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: RMR Node length 0x%lx > MAX_UINT16. Status = %r\n", | ||||||
|  |         NodeLength, | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (NodeList->MemRangeDescCount == 0) { | ||||||
|  |       Status = EFI_INVALID_PARAMETER; | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Memory Range Desc count = %d. Status = %r\n", | ||||||
|  |         NodeList->MemRangeDescCount, | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (NodeList->MemRangeDescToken == CM_NULL_TOKEN) { | ||||||
|  |       Status = EFI_INVALID_PARAMETER; | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Invalid Memory Range Descriptor token," | ||||||
|  |         " Token = 0x%x. Status = %r\n", | ||||||
|  |         NodeList->MemRangeDescToken, | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Populate the node header | ||||||
|  |     RmrNode->Node.Type          = EFI_ACPI_IORT_TYPE_RMR; | ||||||
|  |     RmrNode->Node.Length        = (UINT16)NodeLength; | ||||||
|  |     RmrNode->Node.Revision      = 3; | ||||||
|  |     RmrNode->Node.Identifier    = NodeList->Identifier; | ||||||
|  |     RmrNode->Node.NumIdMappings = NodeList->IdMappingCount; | ||||||
|  |     RmrNode->Node.IdReference   = (NodeList->IdMappingCount == 0) ? | ||||||
|  |                                   0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE); | ||||||
|  |  | ||||||
|  |     // RMR specific data | ||||||
|  |     RmrNode->Flags           = NodeList->Flags; | ||||||
|  |     RmrNode->NumMemRangeDesc = NodeList->MemRangeDescCount; | ||||||
|  |     RmrNode->MemRangeDescRef = (NodeList->MemRangeDescCount == 0) ? | ||||||
|  |                                0 : (sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE) + | ||||||
|  |                                     (NodeList->IdMappingCount * | ||||||
|  |                                      sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE))); | ||||||
|  |  | ||||||
|  |     if (NodeList->IdMappingCount > 0) { | ||||||
|  |       if (NodeList->IdMappingToken == CM_NULL_TOKEN) { | ||||||
|  |         Status = EFI_INVALID_PARAMETER; | ||||||
|  |         DEBUG (( | ||||||
|  |           DEBUG_ERROR, | ||||||
|  |           "ERROR: IORT: Invalid Id Mapping token," | ||||||
|  |           " Token = 0x%x, Status =%r\n", | ||||||
|  |           NodeList->IdMappingToken, | ||||||
|  |           Status | ||||||
|  |           )); | ||||||
|  |         return Status; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Ids for RMR node | ||||||
|  |       IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE *)((UINT8 *)RmrNode + | ||||||
|  |                                                           RmrNode->Node.IdReference); | ||||||
|  |  | ||||||
|  |       Status = AddIdMappingArray ( | ||||||
|  |                  This, | ||||||
|  |                  CfgMgrProtocol, | ||||||
|  |                  IdMapArray, | ||||||
|  |                  NodeList->IdMappingCount, | ||||||
|  |                  NodeList->IdMappingToken | ||||||
|  |                  ); | ||||||
|  |       if (EFI_ERROR (Status)) { | ||||||
|  |         DEBUG (( | ||||||
|  |           DEBUG_ERROR, | ||||||
|  |           "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n", | ||||||
|  |           Status | ||||||
|  |           )); | ||||||
|  |         return Status; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Memory Range Descriptors for RMR node | ||||||
|  |     MemRangeDescArray = (EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC *)( | ||||||
|  |                                                                      (UINT8 *)RmrNode + | ||||||
|  |                                                                      RmrNode->MemRangeDescRef | ||||||
|  |                                                                      ); | ||||||
|  |  | ||||||
|  |     Status = AddMemRangeDescArray ( | ||||||
|  |                This, | ||||||
|  |                CfgMgrProtocol, | ||||||
|  |                MemRangeDescArray, | ||||||
|  |                NodeList->MemRangeDescCount, | ||||||
|  |                NodeList->MemRangeDescToken | ||||||
|  |                ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Failed to Memory Range Descriptor Array. Status = %r\n", | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Next RMR Node | ||||||
|  |     RmrNode = (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE *)((UINT8 *)RmrNode + | ||||||
|  |                                                      RmrNode->Node.Length); | ||||||
|  |     NodeList++; | ||||||
|  |   } // RMR Node | ||||||
|  |  | ||||||
|  |   return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** Validates that the IORT nodes Identifier are unique. | ||||||
|  |  | ||||||
|  |     @param [in]     NodeIndexer      Pointer to the Node Indexer. | ||||||
|  |     @param [in]     NodeCount        Number of IORT Nodes. | ||||||
|  |  | ||||||
|  |     @retval EFI_SUCCESS             Success. | ||||||
|  |     @retval EFI_INVALID_PARAMETER   Identifier field not unique. | ||||||
|  | **/ | ||||||
|  | STATIC | ||||||
|  | EFI_STATUS | ||||||
|  | ValidateNodeIdentifiers ( | ||||||
|  |   IN      CONST IORT_NODE_INDEXER                  *CONST  NodeIndexer, | ||||||
|  |   IN            UINT32                                     NodeCount | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   UINT32  IndexI; | ||||||
|  |   UINT32  IndexJ; | ||||||
|  |  | ||||||
|  |   for (IndexI = 0; IndexI < NodeCount; IndexI++) { | ||||||
|  |     for (IndexJ = 0; IndexJ < NodeCount; IndexJ++) { | ||||||
|  |       if ((IndexI != IndexJ) && | ||||||
|  |           (NodeIndexer[IndexI].Identifier == NodeIndexer[IndexJ].Identifier)) | ||||||
|  |       { | ||||||
|  |         DEBUG (( | ||||||
|  |           DEBUG_ERROR, | ||||||
|  |           "ERROR: IORT: UID %d of Token %p matches with that of Token %p.\n", | ||||||
|  |           NodeIndexer[IndexI].Identifier, | ||||||
|  |           NodeIndexer[IndexI].Token, | ||||||
|  |           NodeIndexer[IndexJ].Token | ||||||
|  |           )); | ||||||
|  |         return EFI_INVALID_PARAMETER; | ||||||
|  |       } | ||||||
|  |     }// IndexJ | ||||||
|  |   } // IndexI | ||||||
|  |  | ||||||
|  |   return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** Construct the IORT ACPI table. | /** Construct the IORT ACPI table. | ||||||
|  |  | ||||||
|     This function invokes the Configuration Manager protocol interface |     This function invokes the Configuration Manager protocol interface | ||||||
| @@ -1632,6 +2078,7 @@ BuildIortTable ( | |||||||
|   UINT32  SmmuV1V2NodeCount; |   UINT32  SmmuV1V2NodeCount; | ||||||
|   UINT32  SmmuV3NodeCount; |   UINT32  SmmuV3NodeCount; | ||||||
|   UINT32  PmcgNodeCount; |   UINT32  PmcgNodeCount; | ||||||
|  |   UINT32  RmrNodeCount; | ||||||
|  |  | ||||||
|   UINT32  ItsGroupOffset; |   UINT32  ItsGroupOffset; | ||||||
|   UINT32  NamedComponentOffset; |   UINT32  NamedComponentOffset; | ||||||
| @@ -1639,6 +2086,7 @@ BuildIortTable ( | |||||||
|   UINT32  SmmuV1V2Offset; |   UINT32  SmmuV1V2Offset; | ||||||
|   UINT32  SmmuV3Offset; |   UINT32  SmmuV3Offset; | ||||||
|   UINT32  PmcgOffset; |   UINT32  PmcgOffset; | ||||||
|  |   UINT32  RmrOffset; | ||||||
|  |  | ||||||
|   CM_ARM_ITS_GROUP_NODE        *ItsGroupNodeList; |   CM_ARM_ITS_GROUP_NODE        *ItsGroupNodeList; | ||||||
|   CM_ARM_NAMED_COMPONENT_NODE  *NamedComponentNodeList; |   CM_ARM_NAMED_COMPONENT_NODE  *NamedComponentNodeList; | ||||||
| @@ -1646,6 +2094,7 @@ BuildIortTable ( | |||||||
|   CM_ARM_SMMUV1_SMMUV2_NODE    *SmmuV1V2NodeList; |   CM_ARM_SMMUV1_SMMUV2_NODE    *SmmuV1V2NodeList; | ||||||
|   CM_ARM_SMMUV3_NODE           *SmmuV3NodeList; |   CM_ARM_SMMUV3_NODE           *SmmuV3NodeList; | ||||||
|   CM_ARM_PMCG_NODE             *PmcgNodeList; |   CM_ARM_PMCG_NODE             *PmcgNodeList; | ||||||
|  |   CM_ARM_RMR_NODE              *RmrNodeList; | ||||||
|  |  | ||||||
|   EFI_ACPI_6_0_IO_REMAPPING_TABLE  *Iort; |   EFI_ACPI_6_0_IO_REMAPPING_TABLE  *Iort; | ||||||
|   IORT_NODE_INDEXER                *NodeIndexer; |   IORT_NODE_INDEXER                *NodeIndexer; | ||||||
| @@ -1672,6 +2121,16 @@ BuildIortTable ( | |||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if ((AcpiTableInfo->AcpiTableRevision > EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00) && | ||||||
|  |       (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05)) | ||||||
|  |   { | ||||||
|  |     DEBUG (( | ||||||
|  |       DEBUG_ERROR, | ||||||
|  |       "ERROR: IORT: Revisions E (1), E.a(2),b(3),c(4) are not supported.\n" | ||||||
|  |       )); | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Generator = (ACPI_IORT_GENERATOR *)This; |   Generator = (ACPI_IORT_GENERATOR *)This; | ||||||
|   *Table    = NULL; |   *Table    = NULL; | ||||||
|  |  | ||||||
| @@ -1789,6 +2248,29 @@ BuildIortTable ( | |||||||
|   // Add the PMCG node count |   // Add the PMCG node count | ||||||
|   IortNodeCount += PmcgNodeCount; |   IortNodeCount += PmcgNodeCount; | ||||||
|  |  | ||||||
|  |   if (AcpiTableInfo->AcpiTableRevision >= | ||||||
|  |       EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |   { | ||||||
|  |     // Get the RMR node info | ||||||
|  |     Status = GetEArmObjRmr ( | ||||||
|  |                CfgMgrProtocol, | ||||||
|  |                CM_NULL_TOKEN, | ||||||
|  |                &RmrNodeList, | ||||||
|  |                &RmrNodeCount | ||||||
|  |                ); | ||||||
|  |     if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Failed to get RMR Node Info. Status = %r\n", | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       goto error_handler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Add the RMR node count | ||||||
|  |     IortNodeCount += RmrNodeCount; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Allocate Node Indexer array |   // Allocate Node Indexer array | ||||||
|   NodeIndexer = (IORT_NODE_INDEXER *)AllocateZeroPool ( |   NodeIndexer = (IORT_NODE_INDEXER *)AllocateZeroPool ( | ||||||
|                                        (sizeof (IORT_NODE_INDEXER) * |                                        (sizeof (IORT_NODE_INDEXER) * | ||||||
| @@ -1998,6 +2480,40 @@ BuildIortTable ( | |||||||
|       )); |       )); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // RMR Nodes | ||||||
|  |   if ((AcpiTableInfo->AcpiTableRevision >= | ||||||
|  |        EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) && | ||||||
|  |       (RmrNodeCount > 0)) | ||||||
|  |   { | ||||||
|  |     RmrOffset = (UINT32)TableSize; | ||||||
|  |     // Size of RMR node list. | ||||||
|  |     NodeSize = GetSizeofRmrNodes ( | ||||||
|  |                  RmrOffset, | ||||||
|  |                  RmrNodeList, | ||||||
|  |                  RmrNodeCount, | ||||||
|  |                  &NodeIndexer | ||||||
|  |                  ); | ||||||
|  |     if (NodeSize > MAX_UINT32) { | ||||||
|  |       Status = EFI_INVALID_PARAMETER; | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Invalid Size of RMR Nodes. Status = %r\n", | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       goto error_handler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     TableSize += NodeSize; | ||||||
|  |  | ||||||
|  |     DEBUG (( | ||||||
|  |       DEBUG_INFO, | ||||||
|  |       " RmrNodeCount = %d\n" \ | ||||||
|  |       " RmrOffset = %d\n", | ||||||
|  |       RmrNodeCount, | ||||||
|  |       RmrOffset | ||||||
|  |       )); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   DEBUG (( |   DEBUG (( | ||||||
|     DEBUG_INFO, |     DEBUG_INFO, | ||||||
|     "INFO: IORT:\n" \ |     "INFO: IORT:\n" \ | ||||||
| @@ -2019,6 +2535,21 @@ BuildIortTable ( | |||||||
|     goto error_handler; |     goto error_handler; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // Validate that the identifiers for the nodes are unique | ||||||
|  |   if (AcpiTableInfo->AcpiTableRevision >= | ||||||
|  |       EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) | ||||||
|  |   { | ||||||
|  |     Status = ValidateNodeIdentifiers (Generator->NodeIndexer, IortNodeCount); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Node Identifier not unique. Status = %r\n", | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       goto error_handler; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Allocate the Buffer for IORT table |   // Allocate the Buffer for IORT table | ||||||
|   *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); |   *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); | ||||||
|   if (*Table == NULL) { |   if (*Table == NULL) { | ||||||
| @@ -2067,6 +2598,7 @@ BuildIortTable ( | |||||||
|     Status = AddItsGroupNodes ( |     Status = AddItsGroupNodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                ItsGroupOffset, |                ItsGroupOffset, | ||||||
|                ItsGroupNodeList, |                ItsGroupNodeList, | ||||||
| @@ -2086,6 +2618,7 @@ BuildIortTable ( | |||||||
|     Status = AddNamedComponentNodes ( |     Status = AddNamedComponentNodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                NamedComponentOffset, |                NamedComponentOffset, | ||||||
|                NamedComponentNodeList, |                NamedComponentNodeList, | ||||||
| @@ -2105,6 +2638,7 @@ BuildIortTable ( | |||||||
|     Status = AddRootComplexNodes ( |     Status = AddRootComplexNodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                RootComplexOffset, |                RootComplexOffset, | ||||||
|                RootComplexNodeList, |                RootComplexNodeList, | ||||||
| @@ -2124,6 +2658,7 @@ BuildIortTable ( | |||||||
|     Status = AddSmmuV1V2Nodes ( |     Status = AddSmmuV1V2Nodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                SmmuV1V2Offset, |                SmmuV1V2Offset, | ||||||
|                SmmuV1V2NodeList, |                SmmuV1V2NodeList, | ||||||
| @@ -2143,6 +2678,7 @@ BuildIortTable ( | |||||||
|     Status = AddSmmuV3Nodes ( |     Status = AddSmmuV3Nodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                SmmuV3Offset, |                SmmuV3Offset, | ||||||
|                SmmuV3NodeList, |                SmmuV3NodeList, | ||||||
| @@ -2162,6 +2698,7 @@ BuildIortTable ( | |||||||
|     Status = AddPmcgNodes ( |     Status = AddPmcgNodes ( | ||||||
|                This, |                This, | ||||||
|                CfgMgrProtocol, |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|                Iort, |                Iort, | ||||||
|                PmcgOffset, |                PmcgOffset, | ||||||
|                PmcgNodeList, |                PmcgNodeList, | ||||||
| @@ -2170,7 +2707,27 @@ BuildIortTable ( | |||||||
|     if (EFI_ERROR (Status)) { |     if (EFI_ERROR (Status)) { | ||||||
|       DEBUG (( |       DEBUG (( | ||||||
|         DEBUG_ERROR, |         DEBUG_ERROR, | ||||||
|         "ERROR: IORT: Failed to add SMMUv3 Node. Status = %r\n", |         "ERROR: IORT: Failed to add PMCG Node. Status = %r\n", | ||||||
|  |         Status | ||||||
|  |         )); | ||||||
|  |       goto error_handler; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (RmrNodeCount > 0) { | ||||||
|  |     Status = AddRmrNodes ( | ||||||
|  |                This, | ||||||
|  |                CfgMgrProtocol, | ||||||
|  |                AcpiTableInfo, | ||||||
|  |                Iort, | ||||||
|  |                RmrOffset, | ||||||
|  |                RmrNodeList, | ||||||
|  |                RmrNodeCount | ||||||
|  |                ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       DEBUG (( | ||||||
|  |         DEBUG_ERROR, | ||||||
|  |         "ERROR: IORT: Failed to add RMR Node. Status = %r\n", | ||||||
|         Status |         Status | ||||||
|         )); |         )); | ||||||
|       goto error_handler; |       goto error_handler; | ||||||
| @@ -2255,9 +2812,9 @@ ACPI_IORT_GENERATOR  IortGenerator = { | |||||||
|     // Generator Description |     // Generator Description | ||||||
|     L"ACPI.STD.IORT.GENERATOR", |     L"ACPI.STD.IORT.GENERATOR", | ||||||
|     // ACPI Table Signature |     // ACPI Table Signature | ||||||
|     EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, |     EFI_ACPI_6_4_IO_REMAPPING_TABLE_SIGNATURE, | ||||||
|     // ACPI Table Revision supported by this Generator |     // ACPI Table Revision supported by this Generator | ||||||
|     EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00, |     EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05, | ||||||
|     // Minimum supported ACPI Table Revision |     // Minimum supported ACPI Table Revision | ||||||
|     EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00, |     EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00, | ||||||
|     // Creator ID |     // Creator ID | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /** @file | /** @file | ||||||
|  |  | ||||||
|   Copyright (c) 2018, ARM Limited. All rights reserved. |   Copyright (c) 2018 - 2022, Arm Limited. All rights reserved. | ||||||
|  |  | ||||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent |   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||||
|  |  | ||||||
| @@ -25,6 +25,9 @@ typedef struct IortNodeIndexer { | |||||||
|   VOID               *Object; |   VOID               *Object; | ||||||
|   /// Node offset from the start of the IORT table |   /// Node offset from the start of the IORT table | ||||||
|   UINT32             Offset; |   UINT32             Offset; | ||||||
|  |  | ||||||
|  |   /// Unique identifier for the Node | ||||||
|  |   UINT32             Identifier; | ||||||
| } IORT_NODE_INDEXER; | } IORT_NODE_INDEXER; | ||||||
|  |  | ||||||
| typedef struct AcpiIortGenerator { | typedef struct AcpiIortGenerator { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user