From: "PierreGondois" <pierre.gondois@arm.com>
To: Sami Mujawar <sami.mujawar@arm.com>, devel@edk2.groups.io
Cc: Alexei.Fedorov@arm.com, Matteo.Carlini@arm.com,
Akanksha.Jain2@arm.com, Ben.Adderson@arm.com,
steven.price@arm.com, Lorenzo.Pieralisi@arm.com, nd@arm.com
Subject: Re: [PATCH v5 8/8] DynamicTablesPkg: IORT generator updates for Rev E.d spec
Date: Wed, 13 Jul 2022 14:18:07 +0200 [thread overview]
Message-ID: <b96b8292-723e-7c38-26d2-e088ab42dcdb@arm.com> (raw)
In-Reply-To: <20220712143141.18516-9-sami.mujawar@arm.com>
Hi Sami,
>
> @@ -37,9 +37,11 @@ Requirements:
> - EArmObjSmmuV1SmmuV2
> - EArmObjSmmuV3
> - EArmObjPmcg
> + - EArmObjRmr
> - EArmObjGicItsIdentifierArray
> - EArmObjIdMappingArray
> - - EArmObjGicItsIdentifierArray
I think EArmObjGicItsIdentifierArray should be conserved.
> + - EArmObjSmmuInterruptArray
> + - EArmObjMemoryRangeDescriptor
> */
>
> /** This macro expands to a function that retrieves the ITS
> @@ -96,6 +98,24 @@ GET_OBJECT_LIST (
> 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
> ITS Identifier Array information from the Configuration Manager.
> */
> @@ -174,16 +194,19 @@ GetSizeofItsGroupNodes (
>
> Size = 0;
> while (NodeCount-- != 0) {
> - (*NodeIndexer)->Token = NodeList->Token;
> - (*NodeIndexer)->Object = (VOID *)NodeList;
> - (*NodeIndexer)->Offset = (UINT32)(Size + NodeStartOffset);
> + (*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\n",
> + "IORT: Node Indexer = %p, Token = %p, Object = %p,"
> + " Offset = 0x%x, Identifier = 0x%x\n",
> *NodeIndexer,
> (*NodeIndexer)->Token,
> (*NodeIndexer)->Object,
> - (*NodeIndexer)->Offset
> + (*NodeIndexer)->Offset,
> + (*NodeIndexer)->Identifier
I think all the GetSizeof...Nodes() functions should be merged as one
and take a callback as an argument. This would help factorizing.
For instance for GetSizeofItsGroupNodes():
typedef UINT32 (*GET_NODE_SIZE_CB) (
IN CONST VOID *Node
);
STATIC
UINT64
GetSizeofNodes (
IN UINT32 NodeType,
IN CONST UINT32 NodeStartOffset,
IN CONST CM_ARM_ITS_GROUP_NODE *NodeList,
IN UINT32 NodeCount,
IN GET_NODE_SIZE *GetNodeSizeCb,
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 += GetNodeSizeCb (NodeList);
(*NodeIndexer)++;
NodeList++;
}
return Size;
}
And then:
GetSizeofItsGroupNodes (...)
becomes:
GetSizeofNodes (..., GetItsGroupNodeSize, ...)
(ideally done in a separate patch)
> ));
>
[snip]
> +/** 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) {
I think this should be '!='
> + 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;
> +}
> +
[snip]
> +
> /** Construct the IORT ACPI table.
>
> This function invokes the Configuration Manager protocol interface
> @@ -1632,6 +2078,7 @@ BuildIortTable (
> UINT32 SmmuV1V2NodeCount;
> UINT32 SmmuV3NodeCount;
> UINT32 PmcgNodeCount;
> + UINT32 RmrNodeCount;
>
> UINT32 ItsGroupOffset;
> UINT32 NamedComponentOffset;
> @@ -1639,6 +2086,7 @@ BuildIortTable (
> UINT32 SmmuV1V2Offset;
> UINT32 SmmuV3Offset;
> UINT32 PmcgOffset;
> + UINT32 RmrOffset;
>
> CM_ARM_ITS_GROUP_NODE *ItsGroupNodeList;
> CM_ARM_NAMED_COMPONENT_NODE *NamedComponentNodeList;
> @@ -1646,6 +2094,7 @@ BuildIortTable (
> CM_ARM_SMMUV1_SMMUV2_NODE *SmmuV1V2NodeList;
> CM_ARM_SMMUV3_NODE *SmmuV3NodeList;
> CM_ARM_PMCG_NODE *PmcgNodeList;
> + CM_ARM_RMR_NODE *RmrNodeList;
>
> EFI_ACPI_6_0_IO_REMAPPING_TABLE *Iort;
> IORT_NODE_INDEXER *NodeIndexer;
> @@ -1789,6 +2238,29 @@ BuildIortTable (
> // Add the PMCG node count
> 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
> NodeIndexer = (IORT_NODE_INDEXER *)AllocateZeroPool (
> (sizeof (IORT_NODE_INDEXER) *
> @@ -1998,6 +2470,40 @@ BuildIortTable (
> ));
> }
>
> + // RMR Nodes
> + if ((AcpiTableInfo->AcpiTableRevision >=
> + EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05) &&
> + (RmrNodeCount > 0))
> + {
There are a few checks like this on the revision.
It seems that the 'Identifier' field was added in rev E (=1)
and its size was increased in E.a (=2). So the identifier
field should theoretically be generated for a Revision >= 1.
As we jump from rev D (=0) t5 E.d (=5), maybe we generation
of IORT tables with a revision in between should be prevented.
Regards,
Pierre
next prev parent reply other threads:[~2022-07-13 12:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-12 14:31 [PATCH v5 0/8] IORT Rev E.d specification updates Sami Mujawar
2022-07-12 14:31 ` [PATCH v5 1/8] ShellPkg: Acpiview: Abbreviate field names to preserve alignment Sami Mujawar
2022-07-12 14:31 ` [PATCH v5 2/8] DynamicTablesPkg: Handle error when IdMappingToken is NULL Sami Mujawar
2022-07-12 14:31 ` [PATCH v5 3/8] DynamicTablesPkg: IORT set reference to Id array only if present Sami Mujawar
2022-07-12 14:31 ` [PATCH v5 4/8] DynamicTablesPkg: IORT set reference to interrupt array " Sami Mujawar
2022-07-13 12:08 ` PierreGondois
2022-07-13 16:10 ` PierreGondois
2022-07-12 14:31 ` [PATCH v5 5/8] MdePkg: IORT header update for IORT Rev E.d spec Sami Mujawar
2022-07-13 7:42 ` 回复: [edk2-devel] " gaoliming
2022-07-12 14:31 ` [PATCH v5 6/8] ShellPkg: Acpiview: IORT parser " Sami Mujawar
2022-07-13 12:10 ` PierreGondois
2022-07-13 16:39 ` Sami Mujawar
2022-07-13 16:42 ` Sami Mujawar
2022-07-13 12:22 ` PierreGondois
2022-07-12 14:31 ` [PATCH v5 7/8] DynamicTablesPkg: Update ArmNameSpaceObjects for IORT Rev E.d Sami Mujawar
2022-07-12 14:31 ` [PATCH v5 8/8] DynamicTablesPkg: IORT generator updates for Rev E.d spec Sami Mujawar
2022-07-13 12:18 ` PierreGondois [this message]
2022-07-13 17:07 ` Sami Mujawar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b96b8292-723e-7c38-26d2-e088ab42dcdb@arm.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox