[edk2-devel] [PATCH v2 4/8] ShellPkg: Acpiview: IORT parser update for IORT Rev E.b spec

Sami Mujawar posted 8 patches 4 years, 7 months ago
There is a newer version of this series
[edk2-devel] [PATCH v2 4/8] ShellPkg: Acpiview: IORT parser update for IORT Rev E.b spec
Posted by Sami Mujawar 4 years, 7 months ago
Bugzilla: 3458 - Add support IORT Rev E.b specification updates
          (https://bugzilla.tianocore.org/show_bug.cgi?id=3458)

The IO Remapping Table, Platform Design Document, Revision E.b,
Feb 2021 (https://developer.arm.com/documentation/den0049/)
introduces the following updates, collectively including the
updates and errata fixes to Rev E and Rev E.a:
  - increments the IORT table revision to 3.
  - 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.

Therefore, update the IORT parser to:
  - parse the Identifier field.
  - parse Reserved Memory Range node.
  - parse Memory Range Descriptors.
  - add validations to check that the physical range base
    and size of the Memory Range Descriptor is 64KB aligned.
  - add validation to check that the ID mapping count is
    set to 1.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---

Notes:
    v2:
     - No code change since v1. Re-sending with v2 series.    [SAMI]

 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c | 196 +++++++++++++++++++-
 1 file changed, 191 insertions(+), 5 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
index fcecaff5134256497bda87241f339076897c3ece..1507dd3a4d79e61024b0c5526e21ffdacb782251 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
@@ -5,10 +5,12 @@
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Reference(s):
-  - IO Remapping Table, Platform Design Document, Revision D, March 2018
+    - IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021
+      (https://developer.arm.com/documentation/den0049/)
 
   @par Glossary:
     - Ref  - Reference
+    - Desc - Descriptor
 **/
 
 #include <IndustryStandard/IoRemappingTable.h>
@@ -36,6 +38,9 @@ STATIC CONST UINT32* PmuInterruptOffset;
 
 STATIC CONST UINT32* ItsCount;
 
+STATIC CONST UINT32* RmrMemDescCount;
+STATIC CONST UINT32* RmrMemDescOffset;
+
 /**
   This function validates the ID Mapping array count for the ITS node.
 
@@ -100,6 +105,72 @@ ValidateItsIdArrayReference (
   }
 }
 
+/**
+  This function validates that the address or length is 64K aligned.
+
+  @param [in] Ptr     Pointer to the start of the field data.
+  @param [in] Context Pointer to context specific information e.g. this
+                      could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+Validate64KAlignment (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  UINT64 Address;
+  Address = *(UINT64*)Ptr;
+  if ((Address & (SIZE_64KB - 1)) != 0) {
+    IncrementErrorCount ();
+    Print (L"\nERROR: Value must be 64K aligned.");
+  }
+}
+
+/**
+  This function validates that the RMR memory range descriptor count.
+
+  @param [in] Ptr     Pointer to the start of the field data.
+  @param [in] Context Pointer to context specific information e.g. this
+                      could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateRmrMemDescCount (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT32*)Ptr == 0) {
+    IncrementErrorCount ();
+    Print (L"\nERROR: Memory Range Descriptor count must be >=1.");
+  }
+}
+
+/**
+  This function validates the ID Mapping array count for the Reserved
+  Memory Range (RMR) node.
+
+  @param [in] Ptr     Pointer to the start of the field data.
+  @param [in] Context Pointer to context specific information e.g. this
+                      could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateRmrIdMappingCount (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT32*)Ptr != 1) {
+    IncrementErrorCount ();
+    Print (L"\nERROR: IORT ID Mapping count must be set to 1.");
+  }
+}
+
 /**
   Helper Macro for populating the IORT Node header in the ACPI_PARSER array.
 
@@ -113,7 +184,7 @@ ValidateItsIdArrayReference (
   { L"Type", 1, 0, L"%d", NULL, (VOID**)&IortNodeType, NULL, NULL },     \
   { L"Length", 2, 1, L"%d", NULL, (VOID**)&IortNodeLength, NULL, NULL }, \
   { L"Revision", 1, 3, L"%d", NULL, NULL, NULL, NULL },                  \
-  { L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },                \
+  { L"Identifier", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },              \
   { L"Number of ID mappings", 4, 8, L"%d", NULL,                         \
     (VOID**)&IortIdMappingCount, ValidateIdMappingCount, NULL },         \
   { L"Reference to ID Array", 4, 12, L"0x%x", NULL,                      \
@@ -253,6 +324,29 @@ STATIC CONST ACPI_PARSER IortNodePmcgParser[] = {
   {L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}
 };
 
+/**
+  An ACPI_PARSER array describing the IORT RMR node.
+**/
+STATIC CONST ACPI_PARSER IortNodeRmrParser[] = {
+  PARSE_IORT_NODE_HEADER (ValidateRmrIdMappingCount, NULL),
+  {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Memory Range Desc count", 4, 20, L"%d", NULL,
+   (VOID**)&RmrMemDescCount, ValidateRmrMemDescCount, NULL},
+  {L"Memory Range Desc Ref", 4, 24, L"0x%x", NULL,
+   (VOID**)&RmrMemDescOffset, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the IORT RMR Memory Range Descriptor.
+**/
+STATIC CONST ACPI_PARSER IortNodeRmrMemRangeDescParser[] = {
+  {L"Physical Range offset", 8, 0, L"0x%lx", NULL, NULL, Validate64KAlignment,
+   NULL},
+  {L"Physical Range length", 8, 8, L"0x%lx", NULL, NULL, Validate64KAlignment,
+   NULL},
+  {L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
 /**
   This function parses the IORT Node Id Mapping array.
 
@@ -601,9 +695,93 @@ DumpIortNodePmcg (
     );
 }
 
+/**
+  This function parses the IORT RMR Node Memory Range Descriptor array.
+
+  @param [in] Ptr         Pointer to the start of the Memory Range Descriptor
+                          array.
+  @param [in] Length      Length of the buffer.
+  @param [in] DescCount   Memory Range Descriptor count.
+**/
+STATIC
+VOID
+DumpIortNodeRmrMemRangeDesc (
+  IN UINT8* Ptr,
+  IN UINT32 Length,
+  IN UINT32 DescCount
+  )
+{
+  UINT32 Index;
+  UINT32 Offset;
+  CHAR8  Buffer[40];  // Used for AsciiName param of ParseAcpi
+
+  Index = 0;
+  Offset = 0;
+
+  while ((Index < DescCount) &&
+         (Offset < Length)) {
+    AsciiSPrint (
+      Buffer,
+      sizeof (Buffer),
+      "Mem range Descriptor [%d]",
+      Index
+      );
+    Offset += ParseAcpi (
+                TRUE,
+                4,
+                Buffer,
+                Ptr + Offset,
+                Length - Offset,
+                PARSER_PARAMS (IortNodeRmrMemRangeDescParser)
+                );
+    Index++;
+  }
+}
+
+/**
+  This function parses the IORT RMR node.
+
+  @param [in] Ptr            Pointer to the start of the buffer.
+  @param [in] Length         Length of the buffer.
+  @param [in] MappingCount   The ID Mapping count.
+  @param [in] MappingOffset  The offset of the ID Mapping array
+                             from the start of the IORT table.
+**/
+STATIC
+VOID
+DumpIortNodeRmr (
+  IN UINT8* Ptr,
+  IN UINT16 Length,
+  IN UINT32 MappingCount,
+  IN UINT32 MappingOffset
+)
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "RMR Node",
+    Ptr,
+    Length,
+    PARSER_PARAMS (IortNodeRmrParser)
+    );
+
+  DumpIortNodeIdMappings (
+    Ptr + MappingOffset,
+    Length - MappingOffset,
+    MappingCount
+    );
+
+  DumpIortNodeRmrMemRangeDesc (
+    Ptr + (*RmrMemDescOffset),
+    Length - (*RmrMemDescOffset),
+    *RmrMemDescCount
+    );
+}
+
 /**
   This function parses the ACPI IORT table.
-  When trace is enabled this function parses the IORT table and traces the ACPI fields.
+  When trace is enabled this function parses the IORT table and traces the ACPI
+  fields.
 
   This function also parses the following nodes:
     - ITS Group
@@ -612,6 +790,7 @@ DumpIortNodePmcg (
     - SMMUv1/2
     - SMMUv3
     - PMCG
+    - RMR
 
   This function also performs validation of the ACPI table fields.
 
@@ -753,9 +932,16 @@ ParseAcpiIort (
           *IortNodeLength,
           *IortIdMappingCount,
           *IortIdMappingOffset
-        );
+          );
+        break;
+      case EFI_ACPI_IORT_TYPE_RMR:
+        DumpIortNodeRmr (
+          NodePtr,
+          *IortNodeLength,
+          *IortIdMappingCount,
+          *IortIdMappingOffset
+          );
         break;
-
       default:
         IncrementErrorCount ();
         Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#76658): https://edk2.groups.io/g/devel/message/76658
Mute This Topic: https://groups.io/mt/83600720/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] [PATCH v2 4/8] ShellPkg: Acpiview: IORT parser update for IORT Rev E.b spec
Posted by Gao, Zhichao 4 years, 7 months ago
Reviewed-by: Zhichao Gao <zhichao.gao@intel.com>

Thanks,
Zhichao

> -----Original Message-----
> From: Sami Mujawar <sami.mujawar@arm.com>
> Sent: Thursday, June 17, 2021 5:56 PM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <sami.mujawar@arm.com>; Alexei.Fedorov@arm.com;
> steven.price@arm.com; Lorenzo.Pieralisi@arm.com;
> Matteo.Carlini@arm.com; Ben.Adderson@arm.com; Ni, Ray
> <ray.ni@intel.com>; Gao, Zhichao <zhichao.gao@intel.com>; nd@arm.com
> Subject: [PATCH v2 4/8] ShellPkg: Acpiview: IORT parser update for IORT Rev
> E.b spec
> 
> Bugzilla: 3458 - Add support IORT Rev E.b specification updates
>           (https://bugzilla.tianocore.org/show_bug.cgi?id=3458)
> 
> The IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021
> (https://developer.arm.com/documentation/den0049/)
> introduces the following updates, collectively including the updates and
> errata fixes to Rev E and Rev E.a:
>   - increments the IORT table revision to 3.
>   - 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.
> 
> Therefore, update the IORT parser to:
>   - parse the Identifier field.
>   - parse Reserved Memory Range node.
>   - parse Memory Range Descriptors.
>   - add validations to check that the physical range base
>     and size of the Memory Range Descriptor is 64KB aligned.
>   - add validation to check that the ID mapping count is
>     set to 1.
> 
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
> 
> Notes:
>     v2:
>      - No code change since v1. Re-sending with v2 series.    [SAMI]
> 
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c |
> 196 +++++++++++++++++++-
>  1 file changed, 191 insertions(+), 5 deletions(-)
> 
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
> index
> fcecaff5134256497bda87241f339076897c3ece..1507dd3a4d79e61024b0c5526e
> 21ffdacb782251 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortPars
> +++ er.c
> @@ -5,10 +5,12 @@
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>    @par Reference(s):
> -  - IO Remapping Table, Platform Design Document, Revision D, March 2018
> +    - IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021
> +      (https://developer.arm.com/documentation/den0049/)
> 
>    @par Glossary:
>      - Ref  - Reference
> +    - Desc - Descriptor
>  **/
> 
>  #include <IndustryStandard/IoRemappingTable.h>
> @@ -36,6 +38,9 @@ STATIC CONST UINT32* PmuInterruptOffset;
> 
>  STATIC CONST UINT32* ItsCount;
> 
> +STATIC CONST UINT32* RmrMemDescCount;
> +STATIC CONST UINT32* RmrMemDescOffset;
> +
>  /**
>    This function validates the ID Mapping array count for the ITS node.
> 
> @@ -100,6 +105,72 @@ ValidateItsIdArrayReference (
>    }
>  }
> 
> +/**
> +  This function validates that the address or length is 64K aligned.
> +
> +  @param [in] Ptr     Pointer to the start of the field data.
> +  @param [in] Context Pointer to context specific information e.g. this
> +                      could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +Validate64KAlignment (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  UINT64 Address;
> +  Address = *(UINT64*)Ptr;
> +  if ((Address & (SIZE_64KB - 1)) != 0) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: Value must be 64K aligned.");
> +  }
> +}
> +
> +/**
> +  This function validates that the RMR memory range descriptor count.
> +
> +  @param [in] Ptr     Pointer to the start of the field data.
> +  @param [in] Context Pointer to context specific information e.g. this
> +                      could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +ValidateRmrMemDescCount (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT32*)Ptr == 0) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: Memory Range Descriptor count must be >=1.");
> +  }
> +}
> +
> +/**
> +  This function validates the ID Mapping array count for the Reserved
> +  Memory Range (RMR) node.
> +
> +  @param [in] Ptr     Pointer to the start of the field data.
> +  @param [in] Context Pointer to context specific information e.g. this
> +                      could be a pointer to the ACPI table header.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +ValidateRmrIdMappingCount (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT32*)Ptr != 1) {
> +    IncrementErrorCount ();
> +    Print (L"\nERROR: IORT ID Mapping count must be set to 1.");
> +  }
> +}
> +
>  /**
>    Helper Macro for populating the IORT Node header in the ACPI_PARSER
> array.
> 
> @@ -113,7 +184,7 @@ ValidateItsIdArrayReference (
>    { L"Type", 1, 0, L"%d", NULL, (VOID**)&IortNodeType, NULL, NULL },     \
>    { L"Length", 2, 1, L"%d", NULL, (VOID**)&IortNodeLength, NULL, NULL }, \
>    { L"Revision", 1, 3, L"%d", NULL, NULL, NULL, NULL },                  \
> -  { L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },                \
> +  { L"Identifier", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },              \
>    { L"Number of ID mappings", 4, 8, L"%d", NULL,                         \
>      (VOID**)&IortIdMappingCount, ValidateIdMappingCount, NULL },         \
>    { L"Reference to ID Array", 4, 12, L"0x%x", NULL,                      \
> @@ -253,6 +324,29 @@ STATIC CONST ACPI_PARSER IortNodePmcgParser[]
> = {
>    {L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}  };
> 
> +/**
> +  An ACPI_PARSER array describing the IORT RMR node.
> +**/
> +STATIC CONST ACPI_PARSER IortNodeRmrParser[] = {
> +  PARSE_IORT_NODE_HEADER (ValidateRmrIdMappingCount, NULL),
> +  {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Desc count", 4, 20, L"%d", NULL,
> +   (VOID**)&RmrMemDescCount, ValidateRmrMemDescCount, NULL},
> +  {L"Memory Range Desc Ref", 4, 24, L"0x%x", NULL,
> +   (VOID**)&RmrMemDescOffset, NULL, NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the IORT RMR Memory Range Descriptor.
> +**/
> +STATIC CONST ACPI_PARSER IortNodeRmrMemRangeDescParser[] = {
> +  {L"Physical Range offset", 8, 0, L"0x%lx", NULL, NULL,
> Validate64KAlignment,
> +   NULL},
> +  {L"Physical Range length", 8, 8, L"0x%lx", NULL, NULL,
> Validate64KAlignment,
> +   NULL},
> +  {L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL} };
> +
>  /**
>    This function parses the IORT Node Id Mapping array.
> 
> @@ -601,9 +695,93 @@ DumpIortNodePmcg (
>      );
>  }
> 
> +/**
> +  This function parses the IORT RMR Node Memory Range Descriptor array.
> +
> +  @param [in] Ptr         Pointer to the start of the Memory Range Descriptor
> +                          array.
> +  @param [in] Length      Length of the buffer.
> +  @param [in] DescCount   Memory Range Descriptor count.
> +**/
> +STATIC
> +VOID
> +DumpIortNodeRmrMemRangeDesc (
> +  IN UINT8* Ptr,
> +  IN UINT32 Length,
> +  IN UINT32 DescCount
> +  )
> +{
> +  UINT32 Index;
> +  UINT32 Offset;
> +  CHAR8  Buffer[40];  // Used for AsciiName param of ParseAcpi
> +
> +  Index = 0;
> +  Offset = 0;
> +
> +  while ((Index < DescCount) &&
> +         (Offset < Length)) {
> +    AsciiSPrint (
> +      Buffer,
> +      sizeof (Buffer),
> +      "Mem range Descriptor [%d]",
> +      Index
> +      );
> +    Offset += ParseAcpi (
> +                TRUE,
> +                4,
> +                Buffer,
> +                Ptr + Offset,
> +                Length - Offset,
> +                PARSER_PARAMS (IortNodeRmrMemRangeDescParser)
> +                );
> +    Index++;
> +  }
> +}
> +
> +/**
> +  This function parses the IORT RMR node.
> +
> +  @param [in] Ptr            Pointer to the start of the buffer.
> +  @param [in] Length         Length of the buffer.
> +  @param [in] MappingCount   The ID Mapping count.
> +  @param [in] MappingOffset  The offset of the ID Mapping array
> +                             from the start of the IORT table.
> +**/
> +STATIC
> +VOID
> +DumpIortNodeRmr (
> +  IN UINT8* Ptr,
> +  IN UINT16 Length,
> +  IN UINT32 MappingCount,
> +  IN UINT32 MappingOffset
> +)
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "RMR Node",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (IortNodeRmrParser)
> +    );
> +
> +  DumpIortNodeIdMappings (
> +    Ptr + MappingOffset,
> +    Length - MappingOffset,
> +    MappingCount
> +    );
> +
> +  DumpIortNodeRmrMemRangeDesc (
> +    Ptr + (*RmrMemDescOffset),
> +    Length - (*RmrMemDescOffset),
> +    *RmrMemDescCount
> +    );
> +}
> +
>  /**
>    This function parses the ACPI IORT table.
> -  When trace is enabled this function parses the IORT table and traces the
> ACPI fields.
> +  When trace is enabled this function parses the IORT table and traces
> + the ACPI  fields.
> 
>    This function also parses the following nodes:
>      - ITS Group
> @@ -612,6 +790,7 @@ DumpIortNodePmcg (
>      - SMMUv1/2
>      - SMMUv3
>      - PMCG
> +    - RMR
> 
>    This function also performs validation of the ACPI table fields.
> 
> @@ -753,9 +932,16 @@ ParseAcpiIort (
>            *IortNodeLength,
>            *IortIdMappingCount,
>            *IortIdMappingOffset
> -        );
> +          );
> +        break;
> +      case EFI_ACPI_IORT_TYPE_RMR:
> +        DumpIortNodeRmr (
> +          NodePtr,
> +          *IortNodeLength,
> +          *IortIdMappingCount,
> +          *IortIdMappingOffset
> +          );
>          break;
> -
>        default:
>          IncrementErrorCount ();
>          Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#77166): https://edk2.groups.io/g/devel/message/77166
Mute This Topic: https://groups.io/mt/83600720/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-