public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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

  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