public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
@ 2020-08-24 10:23 Sami Mujawar
  2020-09-10 11:38 ` Sami Mujawar
  2020-09-16  2:43 ` [edk2-devel] " Gao, Zhichao
  0 siblings, 2 replies; 5+ messages in thread
From: Sami Mujawar @ 2020-08-24 10:23 UTC (permalink / raw)
  To: devel
  Cc: Sami Mujawar, ray.ni, zhichao.gao, marc.moisson-franckhauser,
	Guillaume.Letellier, Matteo.Carlini, Ben.Adderson, nd

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Create a new parser for the PCCT Table.

The PCCT Table is used to describe how the OSPM can
communicate with entities outside the platform. It
describes which memory spaces correspond to which
entity as well as a few of the needed information
to handle the communications.

This new PCCT parser dumps the values and names of
the table fields. It also performs some validation
on the table's fields.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---

The changes can be seen at:
https://github.com/samimujawar/edk2/tree/840_pcct_parser_v1

 ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  24 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c       | 494 ++++++++++++++++++++
 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h       |  33 ++
 ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c   |   4 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf |   4 +-
 6 files changed, 558 insertions(+), 5 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index f81ccac7e118378aa185db4b625e5bcd75f78347..051fdf807abb1067a264c136364bb6d145b38dab 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for ACPI parser
 
-  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -671,6 +671,28 @@ ParseAcpiMcfg (
   );
 
 /**
+  This function parses the ACPI PCCT table including its sub-structures
+  of type 0 through 4.
+  When trace is enabled this function parses the PCCT table and
+  traces the ACPI table fields.
+
+  This function also performs validation of the ACPI table fields.
+
+  @param [in] Trace              If TRUE, trace the ACPI fields.
+  @param [in] Ptr                Pointer to the start of the buffer.
+  @param [in] AcpiTableLength    Length of the ACPI table.
+  @param [in] AcpiTableRevision  Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiPcct (
+  IN BOOLEAN Trace,
+  IN UINT8*  Ptr,
+  IN UINT32  AcpiTableLength,
+  IN UINT8   AcpiTableRevision
+  );
+
+/**
   This function parses the ACPI PPTT table.
   When trace is enabled this function parses the PPTT table and
   traces the ACPI table fields.
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
index 4f92596b90a6ee422d8d0959881015ffd3de4da0..19265d0b763f8a810759a2cef09ce2cc2d7bec03 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for ACPI table parser
 
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -11,7 +11,7 @@
 /**
   The maximum number of ACPI table parsers.
 */
-#define MAX_ACPI_TABLE_PARSERS          16
+#define MAX_ACPI_TABLE_PARSERS          17
 
 /** An invalid/NULL signature value.
 */
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
new file mode 100644
index 0000000000000000000000000000000000000000..526cb7b79aa7aa6eee09824600b6c7eac0ab67e2
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
@@ -0,0 +1,494 @@
+/** @file
+  PCCT table parser
+
+  Copyright (c) 2020, Arm Limited.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+    - ACPI 6.3 Specification - January 2019
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+#include "AcpiViewConfig.h"
+#include "PcctParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+STATIC UINT8* PccSubspaceLength;
+STATIC UINT8* PccSubspaceType;
+
+/**
+  This function validates the length coded on 4 bytes of a shared memory range
+
+  @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
+ValidateRangeLength4 (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT32*)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
+    IncrementErrorCount ();
+    Print (
+      L"\nError: Shared memory range length is too short.\n"
+      L"Length is %u when it should be greater than or equal to %u",
+      *(UINT32*)Ptr,
+      MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
+      );
+  }
+}
+
+/**
+  This function validates the length coded on 8 bytes of a shared memory range
+
+  @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
+ValidateRangeLength8 (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT64*)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
+    IncrementErrorCount ();
+    Print (
+      L"\nError: Shared memory range length is too short.\n"
+      L"Length is %u when it should be greater than %u",
+      *(UINT64*)Ptr,
+      MIN_MEMORY_RANGE_LENGTH
+      );
+  }
+}
+
+/**
+  This function validates address space for type 0 structure.
+
+  @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
+ValidatePccType0Gas (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  switch (*(UINT8*)Ptr) {
+#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_IO:
+#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_MEMORY:
+      return;
+    default:
+      IncrementErrorCount ();
+      Print (L"\nError: Invalid address space");
+  }
+}
+
+/**
+  This function validates address space for structures of types other than 0.
+
+  @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
+ValidatePccGas (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  switch (*(UINT8*)Ptr) {
+#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_IO:
+#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE:
+    case EFI_ACPI_6_3_SYSTEM_MEMORY:
+      return;
+    default:
+      IncrementErrorCount ();
+      Print (L"\nError: Invalid address space");
+  }
+}
+
+/**
+  An ACPI_PARSER array describing the ACPI PCCT Table.
+*/
+STATIC CONST ACPI_PARSER PcctParser[] = {
+  PARSE_ACPI_HEADER (&AcpiHdrInfo),
+  {L"Flags", 4, 36, NULL, NULL, NULL, NULL, NULL},
+  {L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the platform communications channel subspace
+  structure header.
+*/
+STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
+  PCC_SUBSPACE_HEADER ()
+  // ... Type Specific Fields ...
+};
+
+/**
+  An ACPI_PARSER array describing the Generic Communications Subspace - Type 0
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL, ValidatePccType0Gas,
+    NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the HW-Reduced Communications Subspace
+  - Type 1
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the HW-Reduced Communications Subspace
+  - Type 2
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Register", 12, 62, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Platform Interrupt Ack Preserve", 8, 74, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Write", 8, 82, L"0x%lx", NULL, NULL,
+    NULL, NULL},
+};
+
+/**
+  An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL, ValidateRangeLength4,
+    NULL},
+  {L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 48, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Reserved", 8, 88, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL, NULL, NULL},
+};
+
+/**
+  This function parses the PCC Subspace type 0.
+
+  @param [in] Ptr     Pointer to the start of Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType0 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 0",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType0Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 1.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType1 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 1",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType1Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 2.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType2 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 2",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType2Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 3.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType3 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 3",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType3Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 4.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType4 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 4",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType3Parser)
+    );
+}
+
+/**
+  This function parses the ACPI PCCT table including its sub-structures
+  of type 0 through 4.
+  When trace is enabled this function parses the PCCT table and
+  traces the ACPI table fields.
+
+  This function also performs validation of the ACPI table fields.
+
+  @param [in] Trace              If TRUE, trace the ACPI fields.
+  @param [in] Ptr                Pointer to the start of the buffer.
+  @param [in] AcpiTableLength    Length of the ACPI table.
+  @param [in] AcpiTableRevision  Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiPcct (
+  IN BOOLEAN Trace,
+  IN UINT8*  Ptr,
+  IN UINT32  AcpiTableLength,
+  IN UINT8   AcpiTableRevision
+  )
+{
+  UINT32 Offset;
+  UINT8* PccSubspacePtr;
+  UINTN  SubspaceCount;
+
+  if (!Trace) {
+    return;
+  }
+
+  Offset = ParseAcpi (
+             TRUE,
+             0,
+             "PCCT",
+             Ptr,
+             AcpiTableLength,
+             PARSER_PARAMS (PcctParser)
+             );
+
+  PccSubspacePtr = Ptr + Offset;
+
+  SubspaceCount = 0;
+  while (Offset < AcpiTableLength) {
+    // Parse common structure header to obtain Type and Length.
+    ParseAcpi (
+      FALSE,
+      0,
+      NULL,
+      PccSubspacePtr,
+      AcpiTableLength - Offset,
+      PARSER_PARAMS (PccSubspaceHeaderParser)
+      );
+
+    // Check if the values used to control the parsing logic have been
+    // successfully read.
+    if ((PccSubspaceType == NULL) ||
+        (PccSubspaceLength == NULL)) {
+      IncrementErrorCount ();
+      Print (
+        L"ERROR: Insufficient remaining table buffer length to read the " \
+          L"structure header. Length = %u.\n",
+        AcpiTableLength - Offset
+        );
+      return;
+    }
+
+    // Validate Structure length
+    if ((*PccSubspaceLength == 0) ||
+        ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) {
+      IncrementErrorCount ();
+      Print (
+        L"ERROR: Invalid Structure length. " \
+          L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
+        *PccSubspaceLength,
+        Offset,
+        AcpiTableLength
+        );
+      return;
+    }
+
+    switch (*PccSubspaceType) {
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC:
+        DumpPccSubspaceType0 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
+        DumpPccSubspaceType1 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
+        DumpPccSubspaceType2 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
+        DumpPccSubspaceType3 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
+        DumpPccSubspaceType4 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      default:
+        IncrementErrorCount ();
+        Print (
+          L"ERROR: Unknown PCC subspace structure:"
+            L" Type = %u, Length = %u\n",
+          PccSubspaceType,
+          *PccSubspaceLength
+          );
+    }
+
+    PccSubspacePtr += *PccSubspaceLength;
+    Offset += *PccSubspaceLength;
+    SubspaceCount++;
+  } // while
+
+  if (SubspaceCount > MAX_PCC_SUBSPACES) {
+    IncrementErrorCount ();
+    Print (L"ERROR: Too many PCC subspaces.");
+  }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..278dc83c5de8860cbb2b1e2b2e277aa7c6c58698
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
@@ -0,0 +1,33 @@
+/** @file
+  Header file for PCCT parser
+
+  Copyright (c) 2020, Arm Limited.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCCT_PARSER_H_
+#define PCCT_PARSER_H_
+
+/**
+  Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
+*/
+#define MIN_MEMORY_RANGE_LENGTH                 8
+
+/**
+  Minimum value for the 'length' field in subspaces of types 3 and 4.
+*/
+#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN      16
+
+/**
+  Maximum number of PCC subspaces.
+*/
+#define MAX_PCC_SUBSPACES                       256
+
+/**
+  Parser for the header of any type of PCC subspace.
+*/
+#define PCC_SUBSPACE_HEADER()                                             \
+  {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL},   \
+  {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL, NULL}
+
+#endif // PCCT_PARSER_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index d2f26ff89f12e596702281c38ab0de3729aa68e4..feb80661cddc420670edb2d8c7a570b0a89272d8 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -1,7 +1,7 @@
 /** @file
   Main file for 'acpiview' Shell command function.
 
-  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -57,6 +57,8 @@ ACPI_TABLE_PARSER ParserList[] = {
   {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
   {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
    ParseAcpiMcfg},
+  {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
+   ParseAcpiPcct},
   {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
    ParseAcpiPptt},
   {RSDP_TABLE_INFO, ParseAcpiRsdp},
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index 91459f9ec632635ee453c5ef46f67445cd9eee0c..efa9c8784a6670e5a4f500e0ae559a4938852f95 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -1,7 +1,7 @@
 ##  @file
 # Provides Shell 'acpiview' command functions
 #
-# Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -37,6 +37,8 @@ [Sources.common]
   Parsers/Madt/MadtParser.c
   Parsers/Madt/MadtParser.h
   Parsers/Mcfg/McfgParser.c
+  Parsers/Pcct/PcctParser.c
+  Parsers/Pcct/PcctParser.h
   Parsers/Pptt/PpttParser.c
   Parsers/Pptt/PpttParser.h
   Parsers/Rsdp/RsdpParser.c
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
  2020-08-24 10:23 [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser Sami Mujawar
@ 2020-09-10 11:38 ` Sami Mujawar
  2020-09-11  1:57   ` Gao, Zhichao
  2020-09-16  2:43 ` [edk2-devel] " Gao, Zhichao
  1 sibling, 1 reply; 5+ messages in thread
From: Sami Mujawar @ 2020-09-10 11:38 UTC (permalink / raw)
  To: zhichao.gao@intel.com, devel@edk2.groups.io
  Cc: ray.ni@intel.com, Sami Mujawar, Marc Moisson-Franckhauser,
	Guillaume Letellier, Matteo Carlini, Ben Adderson, nd

Hi Zhichao,

Would it be possible for you to provide feedback for this patch, please?

Regards,

Sami Mujawar

-----Original Message-----
From: Sami Mujawar <sami.mujawar@arm.com> 
Sent: 24 August 2020 11:23 AM
To: devel@edk2.groups.io
Cc: Sami Mujawar <Sami.Mujawar@arm.com>; ray.ni@intel.com; zhichao.gao@intel.com; Marc Moisson-Franckhauser <Marc.Moisson-Franckhauser@arm.com>; Guillaume Letellier <Guillaume.Letellier@arm.com>; Matteo Carlini <Matteo.Carlini@arm.com>; Ben Adderson <Ben.Adderson@arm.com>; nd <nd@arm.com>
Subject: [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Create a new parser for the PCCT Table.

The PCCT Table is used to describe how the OSPM can
communicate with entities outside the platform. It
describes which memory spaces correspond to which
entity as well as a few of the needed information
to handle the communications.

This new PCCT parser dumps the values and names of
the table fields. It also performs some validation
on the table's fields.

Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---

The changes can be seen at:
https://github.com/samimujawar/edk2/tree/840_pcct_parser_v1

 ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  24 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c       | 494 ++++++++++++++++++++
 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h       |  33 ++
 ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c   |   4 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf |   4 +-
 6 files changed, 558 insertions(+), 5 deletions(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index f81ccac7e118378aa185db4b625e5bcd75f78347..051fdf807abb1067a264c136364bb6d145b38dab 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for ACPI parser
 
-  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -671,6 +671,28 @@ ParseAcpiMcfg (
   );
 
 /**
+  This function parses the ACPI PCCT table including its sub-structures
+  of type 0 through 4.
+  When trace is enabled this function parses the PCCT table and
+  traces the ACPI table fields.
+
+  This function also performs validation of the ACPI table fields.
+
+  @param [in] Trace              If TRUE, trace the ACPI fields.
+  @param [in] Ptr                Pointer to the start of the buffer.
+  @param [in] AcpiTableLength    Length of the ACPI table.
+  @param [in] AcpiTableRevision  Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiPcct (
+  IN BOOLEAN Trace,
+  IN UINT8*  Ptr,
+  IN UINT32  AcpiTableLength,
+  IN UINT8   AcpiTableRevision
+  );
+
+/**
   This function parses the ACPI PPTT table.
   When trace is enabled this function parses the PPTT table and
   traces the ACPI table fields.
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
index 4f92596b90a6ee422d8d0959881015ffd3de4da0..19265d0b763f8a810759a2cef09ce2cc2d7bec03 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for ACPI table parser
 
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -11,7 +11,7 @@
 /**
   The maximum number of ACPI table parsers.
 */
-#define MAX_ACPI_TABLE_PARSERS          16
+#define MAX_ACPI_TABLE_PARSERS          17
 
 /** An invalid/NULL signature value.
 */
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
new file mode 100644
index 0000000000000000000000000000000000000000..526cb7b79aa7aa6eee09824600b6c7eac0ab67e2
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
@@ -0,0 +1,494 @@
+/** @file
+  PCCT table parser
+
+  Copyright (c) 2020, Arm Limited.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+    - ACPI 6.3 Specification - January 2019
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+#include "AcpiViewConfig.h"
+#include "PcctParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+STATIC UINT8* PccSubspaceLength;
+STATIC UINT8* PccSubspaceType;
+
+/**
+  This function validates the length coded on 4 bytes of a shared memory range
+
+  @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
+ValidateRangeLength4 (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT32*)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
+    IncrementErrorCount ();
+    Print (
+      L"\nError: Shared memory range length is too short.\n"
+      L"Length is %u when it should be greater than or equal to %u",
+      *(UINT32*)Ptr,
+      MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
+      );
+  }
+}
+
+/**
+  This function validates the length coded on 8 bytes of a shared memory range
+
+  @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
+ValidateRangeLength8 (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  if (*(UINT64*)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
+    IncrementErrorCount ();
+    Print (
+      L"\nError: Shared memory range length is too short.\n"
+      L"Length is %u when it should be greater than %u",
+      *(UINT64*)Ptr,
+      MIN_MEMORY_RANGE_LENGTH
+      );
+  }
+}
+
+/**
+  This function validates address space for type 0 structure.
+
+  @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
+ValidatePccType0Gas (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  switch (*(UINT8*)Ptr) {
+#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_IO:
+#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_MEMORY:
+      return;
+    default:
+      IncrementErrorCount ();
+      Print (L"\nError: Invalid address space");
+  }
+}
+
+/**
+  This function validates address space for structures of types other than 0.
+
+  @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
+ValidatePccGas (
+  IN UINT8* Ptr,
+  IN VOID*  Context
+  )
+{
+  switch (*(UINT8*)Ptr) {
+#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_SYSTEM_IO:
+#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
+    case EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE:
+    case EFI_ACPI_6_3_SYSTEM_MEMORY:
+      return;
+    default:
+      IncrementErrorCount ();
+      Print (L"\nError: Invalid address space");
+  }
+}
+
+/**
+  An ACPI_PARSER array describing the ACPI PCCT Table.
+*/
+STATIC CONST ACPI_PARSER PcctParser[] = {
+  PARSE_ACPI_HEADER (&AcpiHdrInfo),
+  {L"Flags", 4, 36, NULL, NULL, NULL, NULL, NULL},
+  {L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the platform communications channel subspace
+  structure header.
+*/
+STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
+  PCC_SUBSPACE_HEADER ()
+  // ... Type Specific Fields ...
+};
+
+/**
+  An ACPI_PARSER array describing the Generic Communications Subspace - Type 0
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL, ValidatePccType0Gas,
+    NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the HW-Reduced Communications Subspace
+  - Type 1
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL}
+};
+
+/**
+  An ACPI_PARSER array describing the HW-Reduced Communications Subspace
+  - Type 2
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
+    NULL},
+  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Register", 12, 62, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Platform Interrupt Ack Preserve", 8, 74, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Write", 8, 82, L"0x%lx", NULL, NULL,
+    NULL, NULL},
+};
+
+/**
+  An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
+*/
+STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
+  PCC_SUBSPACE_HEADER (),
+  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
+  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL, ValidateRangeLength4,
+    NULL},
+  {L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Nominal Latency", 4, 48, L"%u", NULL, NULL, NULL, NULL},
+  {L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL, NULL, NULL},
+  {L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Reserved", 8, 88, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL, NULL, NULL},
+  {L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
+    ValidatePccGas, NULL},
+  {L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL, NULL, NULL},
+};
+
+/**
+  This function parses the PCC Subspace type 0.
+
+  @param [in] Ptr     Pointer to the start of Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType0 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 0",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType0Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 1.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType1 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 1",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType1Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 2.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType2 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 2",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType2Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 3.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType3 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 3",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType3Parser)
+    );
+}
+
+/**
+  This function parses the PCC Subspace type 4.
+
+  @param [in] Ptr     Pointer to the start of the Subspace Structure.
+  @param [in] Length  Length of the Subspace Structure.
+**/
+STATIC
+VOID
+DumpPccSubspaceType4 (
+  IN UINT8* Ptr,
+  IN UINT8  Length
+  )
+{
+  ParseAcpi (
+    TRUE,
+    2,
+    "Subspace Type 4",
+    Ptr,
+    Length,
+    PARSER_PARAMS (PccSubspaceType3Parser)
+    );
+}
+
+/**
+  This function parses the ACPI PCCT table including its sub-structures
+  of type 0 through 4.
+  When trace is enabled this function parses the PCCT table and
+  traces the ACPI table fields.
+
+  This function also performs validation of the ACPI table fields.
+
+  @param [in] Trace              If TRUE, trace the ACPI fields.
+  @param [in] Ptr                Pointer to the start of the buffer.
+  @param [in] AcpiTableLength    Length of the ACPI table.
+  @param [in] AcpiTableRevision  Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiPcct (
+  IN BOOLEAN Trace,
+  IN UINT8*  Ptr,
+  IN UINT32  AcpiTableLength,
+  IN UINT8   AcpiTableRevision
+  )
+{
+  UINT32 Offset;
+  UINT8* PccSubspacePtr;
+  UINTN  SubspaceCount;
+
+  if (!Trace) {
+    return;
+  }
+
+  Offset = ParseAcpi (
+             TRUE,
+             0,
+             "PCCT",
+             Ptr,
+             AcpiTableLength,
+             PARSER_PARAMS (PcctParser)
+             );
+
+  PccSubspacePtr = Ptr + Offset;
+
+  SubspaceCount = 0;
+  while (Offset < AcpiTableLength) {
+    // Parse common structure header to obtain Type and Length.
+    ParseAcpi (
+      FALSE,
+      0,
+      NULL,
+      PccSubspacePtr,
+      AcpiTableLength - Offset,
+      PARSER_PARAMS (PccSubspaceHeaderParser)
+      );
+
+    // Check if the values used to control the parsing logic have been
+    // successfully read.
+    if ((PccSubspaceType == NULL) ||
+        (PccSubspaceLength == NULL)) {
+      IncrementErrorCount ();
+      Print (
+        L"ERROR: Insufficient remaining table buffer length to read the " \
+          L"structure header. Length = %u.\n",
+        AcpiTableLength - Offset
+        );
+      return;
+    }
+
+    // Validate Structure length
+    if ((*PccSubspaceLength == 0) ||
+        ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) {
+      IncrementErrorCount ();
+      Print (
+        L"ERROR: Invalid Structure length. " \
+          L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
+        *PccSubspaceLength,
+        Offset,
+        AcpiTableLength
+        );
+      return;
+    }
+
+    switch (*PccSubspaceType) {
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC:
+        DumpPccSubspaceType0 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
+        DumpPccSubspaceType1 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
+        DumpPccSubspaceType2 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
+        DumpPccSubspaceType3 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
+        DumpPccSubspaceType4 (
+          PccSubspacePtr,
+          *PccSubspaceLength
+          );
+        break;
+      default:
+        IncrementErrorCount ();
+        Print (
+          L"ERROR: Unknown PCC subspace structure:"
+            L" Type = %u, Length = %u\n",
+          PccSubspaceType,
+          *PccSubspaceLength
+          );
+    }
+
+    PccSubspacePtr += *PccSubspaceLength;
+    Offset += *PccSubspaceLength;
+    SubspaceCount++;
+  } // while
+
+  if (SubspaceCount > MAX_PCC_SUBSPACES) {
+    IncrementErrorCount ();
+    Print (L"ERROR: Too many PCC subspaces.");
+  }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..278dc83c5de8860cbb2b1e2b2e277aa7c6c58698
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
@@ -0,0 +1,33 @@
+/** @file
+  Header file for PCCT parser
+
+  Copyright (c) 2020, Arm Limited.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCCT_PARSER_H_
+#define PCCT_PARSER_H_
+
+/**
+  Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
+*/
+#define MIN_MEMORY_RANGE_LENGTH                 8
+
+/**
+  Minimum value for the 'length' field in subspaces of types 3 and 4.
+*/
+#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN      16
+
+/**
+  Maximum number of PCC subspaces.
+*/
+#define MAX_PCC_SUBSPACES                       256
+
+/**
+  Parser for the header of any type of PCC subspace.
+*/
+#define PCC_SUBSPACE_HEADER()                                             \
+  {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL},   \
+  {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL, NULL}
+
+#endif // PCCT_PARSER_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index d2f26ff89f12e596702281c38ab0de3729aa68e4..feb80661cddc420670edb2d8c7a570b0a89272d8 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -1,7 +1,7 @@
 /** @file
   Main file for 'acpiview' Shell command function.
 
-  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
+  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -57,6 +57,8 @@ ACPI_TABLE_PARSER ParserList[] = {
   {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
   {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
    ParseAcpiMcfg},
+  {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
+   ParseAcpiPcct},
   {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
    ParseAcpiPptt},
   {RSDP_TABLE_INFO, ParseAcpiRsdp},
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index 91459f9ec632635ee453c5ef46f67445cd9eee0c..efa9c8784a6670e5a4f500e0ae559a4938852f95 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -1,7 +1,7 @@
 ##  @file
 # Provides Shell 'acpiview' command functions
 #
-# Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
+# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -37,6 +37,8 @@ [Sources.common]
   Parsers/Madt/MadtParser.c
   Parsers/Madt/MadtParser.h
   Parsers/Mcfg/McfgParser.c
+  Parsers/Pcct/PcctParser.c
+  Parsers/Pcct/PcctParser.h
   Parsers/Pptt/PpttParser.c
   Parsers/Pptt/PpttParser.h
   Parsers/Rsdp/RsdpParser.c
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
  2020-09-10 11:38 ` Sami Mujawar
@ 2020-09-11  1:57   ` Gao, Zhichao
  0 siblings, 0 replies; 5+ messages in thread
From: Gao, Zhichao @ 2020-09-11  1:57 UTC (permalink / raw)
  To: Sami Mujawar, devel@edk2.groups.io
  Cc: Ni, Ray, Marc Moisson-Franckhauser, Guillaume Letellier,
	Matteo Carlini, Ben Adderson, nd

HI Sami,

Sorry, I almost forget your patches. I would review the two parser related patches this week.

Thanks,
Zhichao

> -----Original Message-----
> From: Sami Mujawar <Sami.Mujawar@arm.com>
> Sent: Thursday, September 10, 2020 7:38 PM
> To: Gao, Zhichao <zhichao.gao@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Sami Mujawar <Sami.Mujawar@arm.com>;
> Marc Moisson-Franckhauser <Marc.Moisson-Franckhauser@arm.com>;
> Guillaume Letellier <Guillaume.Letellier@arm.com>; Matteo Carlini
> <Matteo.Carlini@arm.com>; Ben Adderson <Ben.Adderson@arm.com>; nd
> <nd@arm.com>
> Subject: RE: [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
> 
> Hi Zhichao,
> 
> Would it be possible for you to provide feedback for this patch, please?
> 
> Regards,
> 
> Sami Mujawar
> 
> -----Original Message-----
> From: Sami Mujawar <sami.mujawar@arm.com>
> Sent: 24 August 2020 11:23 AM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <Sami.Mujawar@arm.com>; ray.ni@intel.com;
> zhichao.gao@intel.com; Marc Moisson-Franckhauser <Marc.Moisson-
> Franckhauser@arm.com>; Guillaume Letellier <Guillaume.Letellier@arm.com>;
> Matteo Carlini <Matteo.Carlini@arm.com>; Ben Adderson
> <Ben.Adderson@arm.com>; nd <nd@arm.com>
> Subject: [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
> 
> From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
> 
> Create a new parser for the PCCT Table.
> 
> The PCCT Table is used to describe how the OSPM can communicate with entities
> outside the platform. It describes which memory spaces correspond to which
> entity as well as a few of the needed information to handle the communications.
> 
> This new PCCT parser dumps the values and names of the table fields. It also
> performs some validation on the table's fields.
> 
> Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-
> franckhauser@arm.com>
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
> 
> The changes can be seen at:
> https://github.com/samimujawar/edk2/tree/840_pcct_parser_v1
> 
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  24 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4
> +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c       |
> 494 ++++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h       |
> 33 ++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
> |   4 +-
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.i
> nf |   4 +-
>  6 files changed, 558 insertions(+), 5 deletions(-)
> 
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> index
> f81ccac7e118378aa185db4b625e5bcd75f78347..051fdf807abb1067a264c136364
> bb6d145b38dab 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI parser
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -671,6 +671,28 @@ ParseAcpiMcfg (
>    );
> 
>  /**
> +  This function parses the ACPI PCCT table including its sub-structures
> + of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and  traces
> + the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/**
>    This function parses the ACPI PPTT table.
>    When trace is enabled this function parses the PPTT table and
>    traces the ACPI table fields.
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> index
> 4f92596b90a6ee422d8d0959881015ffd3de4da0..19265d0b763f8a810759a2cef0
> 9ce2cc2d7bec03 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI table parser
> 
> -  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -11,7 +11,7 @@
>  /**
>    The maximum number of ACPI table parsers.
>  */
> -#define MAX_ACPI_TABLE_PARSERS          16
> +#define MAX_ACPI_TABLE_PARSERS          17
> 
>  /** An invalid/NULL signature value.
>  */
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..526cb7b79aa7aa6eee098246
> 00b6c7eac0ab67e2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.c
> @@ -0,0 +1,494 @@
> +/** @file
> +  PCCT table parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Reference(s):
> +    - ACPI 6.3 Specification - January 2019 **/
> +
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiViewConfig.h"
> +#include "PcctParser.h"
> +
> +// Local variables
> +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
> +
> +STATIC UINT8* PccSubspaceLength;
> +STATIC UINT8* PccSubspaceType;
> +
> +/**
> +  This function validates the length coded on 4 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength4 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT32*)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than or equal to %u",
> +      *(UINT32*)Ptr,
> +      MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates the length coded on 8 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength8 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT64*)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than %u",
> +      *(UINT64*)Ptr,
> +      MIN_MEMORY_RANGE_LENGTH
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates address space for type 0 structure.
> +
> +  @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
> +ValidatePccType0Gas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}
> +
> +/**
> +  This function validates address space for structures of types other than 0.
> +
> +  @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
> +ValidatePccGas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE:
> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}
> +
> +/**
> +  An ACPI_PARSER array describing the ACPI PCCT Table.
> +*/
> +STATIC CONST ACPI_PARSER PcctParser[] = {
> +  PARSE_ACPI_HEADER (&AcpiHdrInfo),
> +  {L"Flags", 4, 36, NULL, NULL, NULL, NULL, NULL},
> +  {L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the platform communications channel
> +subspace
> +  structure header.
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
> +  PCC_SUBSPACE_HEADER ()
> +  // ... Type Specific Fields ...
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Generic Communications Subspace -
> +Type 0 */ STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL,
> +NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL, ValidatePccType0Gas,
> +    NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 1
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 2
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 62, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 74, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Write", 8, 82, L"0x%lx", NULL, NULL,
> +    NULL, NULL},
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
> +*/ STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,
> ValidateRangeLength4,
> +    NULL},
> +  {L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 48, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Reserved", 8, 88, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL, NULL, NULL}, };
> +
> +/**
> +  This function parses the PCC Subspace type 0.
> +
> +  @param [in] Ptr     Pointer to the start of Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType0 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 0",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType0Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 1.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType1 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 1",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType1Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 2.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType2 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 2",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType2Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 3.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType3 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 3",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 4.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType4 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 4",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the ACPI PCCT table including its sub-structures
> +  of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and
> +  traces the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT8* PccSubspacePtr;
> +  UINTN  SubspaceCount;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             0,
> +             "PCCT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (PcctParser)
> +             );
> +
> +  PccSubspacePtr = Ptr + Offset;
> +
> +  SubspaceCount = 0;
> +  while (Offset < AcpiTableLength) {
> +    // Parse common structure header to obtain Type and Length.
> +    ParseAcpi (
> +      FALSE,
> +      0,
> +      NULL,
> +      PccSubspacePtr,
> +      AcpiTableLength - Offset,
> +      PARSER_PARAMS (PccSubspaceHeaderParser)
> +      );
> +
> +    // Check if the values used to control the parsing logic have been
> +    // successfully read.
> +    if ((PccSubspaceType == NULL) ||
> +        (PccSubspaceLength == NULL)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Insufficient remaining table buffer length to read the " \
> +          L"structure header. Length = %u.\n",
> +        AcpiTableLength - Offset
> +        );
> +      return;
> +    }
> +
> +    // Validate Structure length
> +    if ((*PccSubspaceLength == 0) ||
> +        ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Invalid Structure length. " \
> +          L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
> +        *PccSubspaceLength,
> +        Offset,
> +        AcpiTableLength
> +        );
> +      return;
> +    }
> +
> +    switch (*PccSubspaceType) {
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC:
> +        DumpPccSubspaceType0 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType1 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType2 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
> +        DumpPccSubspaceType3 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
> +        DumpPccSubspaceType4 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      default:
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Unknown PCC subspace structure:"
> +            L" Type = %u, Length = %u\n",
> +          PccSubspaceType,
> +          *PccSubspaceLength
> +          );
> +    }
> +
> +    PccSubspacePtr += *PccSubspaceLength;
> +    Offset += *PccSubspaceLength;
> +    SubspaceCount++;
> +  } // while
> +
> +  if (SubspaceCount > MAX_PCC_SUBSPACES) {
> +    IncrementErrorCount ();
> +    Print (L"ERROR: Too many PCC subspaces.");
> +  }
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..278dc83c5de8860cbb2b1e2b2
> e277aa7c6c58698
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  Header file for PCCT parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef PCCT_PARSER_H_
> +#define PCCT_PARSER_H_
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
> +*/
> +#define MIN_MEMORY_RANGE_LENGTH                 8
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 3 and 4.
> +*/
> +#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN      16
> +
> +/**
> +  Maximum number of PCC subspaces.
> +*/
> +#define MAX_PCC_SUBSPACES                       256
> +
> +/**
> +  Parser for the header of any type of PCC subspace.
> +*/
> +#define PCC_SUBSPACE_HEADER()                                             \
> +  {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL},   \
> +  {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL,
> +NULL}
> +
> +#endif // PCCT_PARSER_H_
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> index
> d2f26ff89f12e596702281c38ab0de3729aa68e4..feb80661cddc420670edb2d8c7a
> 570b0a89272d8 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Main file for 'acpiview' Shell command function.
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -57,6 +57,8 @@ ACPI_TABLE_PARSER ParserList[] = {
>    {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> ParseAcpiMadt},
> 
> {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BA
> SE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
>     ParseAcpiMcfg},
> +
> {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
> +   ParseAcpiPcct},
> 
> {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGN
> ATURE,
>     ParseAcpiPptt},
>    {RSDP_TABLE_INFO, ParseAcpiRsdp},
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> index
> 91459f9ec632635ee453c5ef46f67445cd9eee0c..efa9c8784a6670e5a4f500e0ae5
> 59a4938852f95 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.inf
> @@ -1,7 +1,7 @@
>  ##  @file
>  # Provides Shell 'acpiview' command functions  # -# Copyright (c) 2016 - 2020,
> ARM Limited. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -37,6 +37,8 @@
> [Sources.common]
>    Parsers/Madt/MadtParser.c
>    Parsers/Madt/MadtParser.h
>    Parsers/Mcfg/McfgParser.c
> +  Parsers/Pcct/PcctParser.c
> +  Parsers/Pcct/PcctParser.h
>    Parsers/Pptt/PpttParser.c
>    Parsers/Pptt/PpttParser.h
>    Parsers/Rsdp/RsdpParser.c
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
  2020-08-24 10:23 [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser Sami Mujawar
  2020-09-10 11:38 ` Sami Mujawar
@ 2020-09-16  2:43 ` Gao, Zhichao
  2020-09-16 14:14   ` Sami Mujawar
  1 sibling, 1 reply; 5+ messages in thread
From: Gao, Zhichao @ 2020-09-16  2:43 UTC (permalink / raw)
  To: devel@edk2.groups.io, sami.mujawar@arm.com
  Cc: Ni, Ray, marc.moisson-franckhauser@arm.com,
	Guillaume.Letellier@arm.com, Matteo.Carlini@arm.com,
	Ben.Adderson@arm.com, nd@arm.com

Hi Sami,

Sorry for the delay review. Please see below.

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sami
> Mujawar
> Sent: Monday, August 24, 2020 6:23 PM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <sami.mujawar@arm.com>; Ni, Ray <ray.ni@intel.com>; Gao,
> Zhichao <zhichao.gao@intel.com>; marc.moisson-franckhauser@arm.com;
> Guillaume.Letellier@arm.com; Matteo.Carlini@arm.com;
> Ben.Adderson@arm.com; nd@arm.com
> Subject: [edk2-devel] [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
> 
> From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
> 
> Create a new parser for the PCCT Table.
> 
> The PCCT Table is used to describe how the OSPM can communicate with entities
> outside the platform. It describes which memory spaces correspond to which
> entity as well as a few of the needed information to handle the communications.
> 
> This new PCCT parser dumps the values and names of the table fields. It also
> performs some validation on the table's fields.
> 
> Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-
> franckhauser@arm.com>
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
> 
> The changes can be seen at:
> https://github.com/samimujawar/edk2/tree/840_pcct_parser_v1
> 
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  24 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4
> +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c       |
> 494 ++++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h       |
> 33 ++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
> |   4 +-
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.i
> nf |   4 +-
>  6 files changed, 558 insertions(+), 5 deletions(-)
> 
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> index
> f81ccac7e118378aa185db4b625e5bcd75f78347..051fdf807abb1067a264c136364
> bb6d145b38dab 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI parser
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -671,6 +671,28 @@ ParseAcpiMcfg (
>    );
> 
>  /**
> +  This function parses the ACPI PCCT table including its sub-structures
> + of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and  traces
> + the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/**
>    This function parses the ACPI PPTT table.
>    When trace is enabled this function parses the PPTT table and
>    traces the ACPI table fields.
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> index
> 4f92596b90a6ee422d8d0959881015ffd3de4da0..19265d0b763f8a810759a2cef0
> 9ce2cc2d7bec03 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI table parser
> 
> -  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -11,7 +11,7 @@
>  /**
>    The maximum number of ACPI table parsers.
>  */
> -#define MAX_ACPI_TABLE_PARSERS          16
> +#define MAX_ACPI_TABLE_PARSERS          17
> 
>  /** An invalid/NULL signature value.
>  */
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..526cb7b79aa7aa6eee098246
> 00b6c7eac0ab67e2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.c
> @@ -0,0 +1,494 @@
> +/** @file
> +  PCCT table parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Reference(s):
> +    - ACPI 6.3 Specification - January 2019 **/
> +
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiViewConfig.h"
> +#include "PcctParser.h"
> +
> +// Local variables
> +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
> +
> +STATIC UINT8* PccSubspaceLength;
> +STATIC UINT8* PccSubspaceType;
> +
> +/**
> +  This function validates the length coded on 4 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength4 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT32*)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than or equal to %u",
> +      *(UINT32*)Ptr,
> +      MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates the length coded on 8 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength8 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT64*)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than %u",
> +      *(UINT64*)Ptr,
> +      MIN_MEMORY_RANGE_LENGTH
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates address space for type 0 structure.
> +
> +  @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
> +ValidatePccType0Gas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))

Why doesn't ARM arch need this check? Is there any doc that descripts this? Just curious.

> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}
> +
> +/**
> +  This function validates address space for structures of types other than 0.
> +
> +  @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
> +ValidatePccGas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE:
> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}

This function is used for subspace type1, 2, 3 and 4. But refer the ACPI 6.3, the field for type4 is optional. If it is not supported, the field would be filled with 0x0 value. So I think we should put the type into consideration.

> +
> +/**
> +  An ACPI_PARSER array describing the ACPI PCCT Table.
> +*/
> +STATIC CONST ACPI_PARSER PcctParser[] = {
> +  PARSE_ACPI_HEADER (&AcpiHdrInfo),
> +  {L"Flags", 4, 36, NULL, NULL, NULL, NULL, NULL},
> +  {L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the platform communications channel
> +subspace
> +  structure header.
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
> +  PCC_SUBSPACE_HEADER ()
> +  // ... Type Specific Fields ...
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Generic Communications Subspace -
> +Type 0 */ STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL,
> +NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL, ValidatePccType0Gas,
> +    NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 1
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 2
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 62, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 74, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Write", 8, 82, L"0x%lx", NULL, NULL,
> +    NULL, NULL},
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
> +*/ STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},

The offset definition in APCI 6.3 Table 14-368 is different. Seems it is a spec mistake.

Others are OK to me.

Thanks,
Zhichao

> +  {L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,
> ValidateRangeLength4,
> +    NULL},
> +  {L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 48, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Reserved", 8, 88, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL, NULL, NULL}, };
> +
> +/**
> +  This function parses the PCC Subspace type 0.
> +
> +  @param [in] Ptr     Pointer to the start of Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType0 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 0",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType0Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 1.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType1 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 1",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType1Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 2.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType2 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 2",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType2Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 3.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType3 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 3",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 4.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType4 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 4",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the ACPI PCCT table including its sub-structures
> +  of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and
> +  traces the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT8* PccSubspacePtr;
> +  UINTN  SubspaceCount;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             0,
> +             "PCCT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (PcctParser)
> +             );
> +
> +  PccSubspacePtr = Ptr + Offset;
> +
> +  SubspaceCount = 0;
> +  while (Offset < AcpiTableLength) {
> +    // Parse common structure header to obtain Type and Length.
> +    ParseAcpi (
> +      FALSE,
> +      0,
> +      NULL,
> +      PccSubspacePtr,
> +      AcpiTableLength - Offset,
> +      PARSER_PARAMS (PccSubspaceHeaderParser)
> +      );
> +
> +    // Check if the values used to control the parsing logic have been
> +    // successfully read.
> +    if ((PccSubspaceType == NULL) ||
> +        (PccSubspaceLength == NULL)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Insufficient remaining table buffer length to read the " \
> +          L"structure header. Length = %u.\n",
> +        AcpiTableLength - Offset
> +        );
> +      return;
> +    }
> +
> +    // Validate Structure length
> +    if ((*PccSubspaceLength == 0) ||
> +        ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Invalid Structure length. " \
> +          L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
> +        *PccSubspaceLength,
> +        Offset,
> +        AcpiTableLength
> +        );
> +      return;
> +    }
> +
> +    switch (*PccSubspaceType) {
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC:
> +        DumpPccSubspaceType0 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType1 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType2 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
> +        DumpPccSubspaceType3 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
> +        DumpPccSubspaceType4 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      default:
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Unknown PCC subspace structure:"
> +            L" Type = %u, Length = %u\n",
> +          PccSubspaceType,
> +          *PccSubspaceLength
> +          );
> +    }
> +
> +    PccSubspacePtr += *PccSubspaceLength;
> +    Offset += *PccSubspaceLength;
> +    SubspaceCount++;
> +  } // while
> +
> +  if (SubspaceCount > MAX_PCC_SUBSPACES) {
> +    IncrementErrorCount ();
> +    Print (L"ERROR: Too many PCC subspaces.");
> +  }
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..278dc83c5de8860cbb2b1e2b2
> e277aa7c6c58698
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  Header file for PCCT parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef PCCT_PARSER_H_
> +#define PCCT_PARSER_H_
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
> +*/
> +#define MIN_MEMORY_RANGE_LENGTH                 8
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 3 and 4.
> +*/
> +#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN      16
> +
> +/**
> +  Maximum number of PCC subspaces.
> +*/
> +#define MAX_PCC_SUBSPACES                       256
> +
> +/**
> +  Parser for the header of any type of PCC subspace.
> +*/
> +#define PCC_SUBSPACE_HEADER()                                             \
> +  {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL},   \
> +  {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL,
> +NULL}
> +
> +#endif // PCCT_PARSER_H_
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> index
> d2f26ff89f12e596702281c38ab0de3729aa68e4..feb80661cddc420670edb2d8c7a
> 570b0a89272d8 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Main file for 'acpiview' Shell command function.
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -57,6 +57,8 @@ ACPI_TABLE_PARSER ParserList[] = {
>    {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> ParseAcpiMadt},
> 
> {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BA
> SE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
>     ParseAcpiMcfg},
> +
> {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
> +   ParseAcpiPcct},
> 
> {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGN
> ATURE,
>     ParseAcpiPptt},
>    {RSDP_TABLE_INFO, ParseAcpiRsdp},
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> index
> 91459f9ec632635ee453c5ef46f67445cd9eee0c..efa9c8784a6670e5a4f500e0ae5
> 59a4938852f95 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.inf
> @@ -1,7 +1,7 @@
>  ##  @file
>  # Provides Shell 'acpiview' command functions  # -# Copyright (c) 2016 - 2020,
> ARM Limited. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -37,6 +37,8 @@
> [Sources.common]
>    Parsers/Madt/MadtParser.c
>    Parsers/Madt/MadtParser.h
>    Parsers/Mcfg/McfgParser.c
> +  Parsers/Pcct/PcctParser.c
> +  Parsers/Pcct/PcctParser.h
>    Parsers/Pptt/PpttParser.c
>    Parsers/Pptt/PpttParser.h
>    Parsers/Rsdp/RsdpParser.c
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
> 
> 
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
  2020-09-16  2:43 ` [edk2-devel] " Gao, Zhichao
@ 2020-09-16 14:14   ` Sami Mujawar
  0 siblings, 0 replies; 5+ messages in thread
From: Sami Mujawar @ 2020-09-16 14:14 UTC (permalink / raw)
  To: devel@edk2.groups.io, zhichao.gao@intel.com
  Cc: Ni, Ray, Marc Moisson-Franckhauser, Guillaume Letellier,
	Matteo Carlini, Ben Adderson, nd

Hi Zhichao,

Thank you for the feedback.

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Gao, Zhichao via groups.io
Sent: 16 September 2020 03:44 AM
To: devel@edk2.groups.io; Sami Mujawar <Sami.Mujawar@arm.com>
Cc: Ni, Ray <ray.ni@intel.com>; Marc Moisson-Franckhauser <Marc.Moisson-Franckhauser@arm.com>; Guillaume Letellier <Guillaume.Letellier@arm.com>; Matteo Carlini <Matteo.Carlini@arm.com>; Ben Adderson <Ben.Adderson@arm.com>; nd <nd@arm.com>
Subject: Re: [edk2-devel] [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser

Hi Sami,

Sorry for the delay review. Please see below.

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sami
> Mujawar
> Sent: Monday, August 24, 2020 6:23 PM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <sami.mujawar@arm.com>; Ni, Ray <ray.ni@intel.com>; Gao,
> Zhichao <zhichao.gao@intel.com>; marc.moisson-franckhauser@arm.com;
> Guillaume.Letellier@arm.com; Matteo.Carlini@arm.com;
> Ben.Adderson@arm.com; nd@arm.com
> Subject: [edk2-devel] [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser
> 
> From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>
> 
> Create a new parser for the PCCT Table.
> 
> The PCCT Table is used to describe how the OSPM can communicate with entities
> outside the platform. It describes which memory spaces correspond to which
> entity as well as a few of the needed information to handle the communications.
> 
> This new PCCT parser dumps the values and names of the table fields. It also
> performs some validation on the table's fields.
> 
> Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-
> franckhauser@arm.com>
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
> 
> The changes can be seen at:
> https://github.com/samimujawar/edk2/tree/840_pcct_parser_v1
> 
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h                    |  24 +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h               |   4
> +-
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c       |
> 494 ++++++++++++++++++++
>  ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h       |
> 33 ++
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
> |   4 +-
> 
> ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.i
> nf |   4 +-
>  6 files changed, 558 insertions(+), 5 deletions(-)
> 
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> index
> f81ccac7e118378aa185db4b625e5bcd75f78347..051fdf807abb1067a264c136364
> bb6d145b38dab 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI parser
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -671,6 +671,28 @@ ParseAcpiMcfg (
>    );
> 
>  /**
> +  This function parses the ACPI PCCT table including its sub-structures
> + of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and  traces
> + the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  );
> +
> +/**
>    This function parses the ACPI PPTT table.
>    When trace is enabled this function parses the PPTT table and
>    traces the ACPI table fields.
> diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> index
> 4f92596b90a6ee422d8d0959881015ffd3de4da0..19265d0b763f8a810759a2cef0
> 9ce2cc2d7bec03 100644
> --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
> @@ -1,7 +1,7 @@
>  /** @file
>    Header file for ACPI table parser
> 
> -  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -11,7 +11,7 @@
>  /**
>    The maximum number of ACPI table parsers.
>  */
> -#define MAX_ACPI_TABLE_PARSERS          16
> +#define MAX_ACPI_TABLE_PARSERS          17
> 
>  /** An invalid/NULL signature value.
>  */
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..526cb7b79aa7aa6eee098246
> 00b6c7eac0ab67e2
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.c
> @@ -0,0 +1,494 @@
> +/** @file
> +  PCCT table parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +  @par Reference(s):
> +    - ACPI 6.3 Specification - January 2019 **/
> +
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include "AcpiParser.h"
> +#include "AcpiView.h"
> +#include "AcpiViewConfig.h"
> +#include "PcctParser.h"
> +
> +// Local variables
> +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
> +
> +STATIC UINT8* PccSubspaceLength;
> +STATIC UINT8* PccSubspaceType;
> +
> +/**
> +  This function validates the length coded on 4 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength4 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT32*)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than or equal to %u",
> +      *(UINT32*)Ptr,
> +      MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates the length coded on 8 bytes of a shared
> +memory range
> +
> +  @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
> +ValidateRangeLength8 (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  if (*(UINT64*)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
> +    IncrementErrorCount ();
> +    Print (
> +      L"\nError: Shared memory range length is too short.\n"
> +      L"Length is %u when it should be greater than %u",
> +      *(UINT64*)Ptr,
> +      MIN_MEMORY_RANGE_LENGTH
> +      );
> +  }
> +}
> +
> +/**
> +  This function validates address space for type 0 structure.
> +
> +  @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
> +ValidatePccType0Gas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))

Why doesn't ARM arch need this check? Is there any doc that descripts this? Just curious.

[SAMI] ARM architecture does not have an I/O address space. The ARM Architecture Reference Manual (https://developer.arm.com/documentation/102105/0101/?search=5eec7399e24a5e02d07b2754) is the best place to get the latest information on Arm Architecture.
The 'Application Note AN 274 Migrating from IA-32 to ARM' (https://developer.arm.com/documentation/dai0274/b?lang=en) may be of interest here. See Section 3.1.1, point 2 for information on I/O address space.
[/SAMI]

> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}
> +
> +/**
> +  This function validates address space for structures of types other than 0.
> +
> +  @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
> +ValidatePccGas (
> +  IN UINT8* Ptr,
> +  IN VOID*  Context
> +  )
> +{
> +  switch (*(UINT8*)Ptr) {
> +#if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_SYSTEM_IO:
> +#endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
> +    case EFI_ACPI_6_3_FUNCTIONAL_FIXED_HARDWARE:
> +    case EFI_ACPI_6_3_SYSTEM_MEMORY:
> +      return;
> +    default:
> +      IncrementErrorCount ();
> +      Print (L"\nError: Invalid address space");
> +  }
> +}

This function is used for subspace type1, 2, 3 and 4. But refer the ACPI 6.3, the field for type4 is optional. If it is not supported, the field would be filled with 0x0 value. So I think we should put the type into consideration.
[SAMI] I think this can be fixed with a few additional checks. I will send out a v2 patch with this changed. [/SAMI]

> +
> +/**
> +  An ACPI_PARSER array describing the ACPI PCCT Table.
> +*/
> +STATIC CONST ACPI_PARSER PcctParser[] = {
> +  PARSE_ACPI_HEADER (&AcpiHdrInfo),
> +  {L"Flags", 4, 36, NULL, NULL, NULL, NULL, NULL},
> +  {L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the platform communications channel
> +subspace
> +  structure header.
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
> +  PCC_SUBSPACE_HEADER ()
> +  // ... Type Specific Fields ...
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Generic Communications Subspace -
> +Type 0 */ STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL,
> +NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL, ValidatePccType0Gas,
> +    NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 1
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL} };
> +
> +/**
> +  An ACPI_PARSER array describing the HW-Reduced Communications
> +Subspace
> +  - Type 2
> +*/
> +STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Memory Range Length", 8, 16, L"0x%lx", NULL, NULL,
> ValidateRangeLength8,
> +    NULL},
> +  {L"Doorbell Register", 12, 24, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 2, 60, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 62, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 74, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Write", 8, 82, L"0x%lx", NULL, NULL,
> +    NULL, NULL},
> +};
> +
> +/**
> +  An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
> +*/ STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
> +  PCC_SUBSPACE_HEADER (),
> +  {L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL},
> +  {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},

The offset definition in APCI 6.3 Table 14-368 is different. Seems it is a spec mistake.
[SAMI] We have reported this to ASWG and there is an ECR to fix this in the spec. [/SAMI]

Others are OK to me.

Thanks,
Zhichao

> +  {L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,
> ValidateRangeLength4,
> +    NULL},
> +  {L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Nominal Latency", 4, 48, L"%u", NULL, NULL, NULL, NULL},
> +  {L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL, NULL,
> +NULL},
> +  {L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,
> +NULL, NULL},
> +  {L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Reserved", 8, 88, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL, NULL,
> +NULL},
> +  {L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL, NULL, NULL},
> +  {L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
> +    ValidatePccGas, NULL},
> +  {L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL, NULL, NULL}, };
> +
> +/**
> +  This function parses the PCC Subspace type 0.
> +
> +  @param [in] Ptr     Pointer to the start of Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType0 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 0",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType0Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 1.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType1 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 1",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType1Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 2.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType2 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 2",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType2Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 3.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType3 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 3",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the PCC Subspace type 4.
> +
> +  @param [in] Ptr     Pointer to the start of the Subspace Structure.
> +  @param [in] Length  Length of the Subspace Structure.
> +**/
> +STATIC
> +VOID
> +DumpPccSubspaceType4 (
> +  IN UINT8* Ptr,
> +  IN UINT8  Length
> +  )
> +{
> +  ParseAcpi (
> +    TRUE,
> +    2,
> +    "Subspace Type 4",
> +    Ptr,
> +    Length,
> +    PARSER_PARAMS (PccSubspaceType3Parser)
> +    );
> +}
> +
> +/**
> +  This function parses the ACPI PCCT table including its sub-structures
> +  of type 0 through 4.
> +  When trace is enabled this function parses the PCCT table and
> +  traces the ACPI table fields.
> +
> +  This function also performs validation of the ACPI table fields.
> +
> +  @param [in] Trace              If TRUE, trace the ACPI fields.
> +  @param [in] Ptr                Pointer to the start of the buffer.
> +  @param [in] AcpiTableLength    Length of the ACPI table.
> +  @param [in] AcpiTableRevision  Revision of the ACPI table.
> +**/
> +VOID
> +EFIAPI
> +ParseAcpiPcct (
> +  IN BOOLEAN Trace,
> +  IN UINT8*  Ptr,
> +  IN UINT32  AcpiTableLength,
> +  IN UINT8   AcpiTableRevision
> +  )
> +{
> +  UINT32 Offset;
> +  UINT8* PccSubspacePtr;
> +  UINTN  SubspaceCount;
> +
> +  if (!Trace) {
> +    return;
> +  }
> +
> +  Offset = ParseAcpi (
> +             TRUE,
> +             0,
> +             "PCCT",
> +             Ptr,
> +             AcpiTableLength,
> +             PARSER_PARAMS (PcctParser)
> +             );
> +
> +  PccSubspacePtr = Ptr + Offset;
> +
> +  SubspaceCount = 0;
> +  while (Offset < AcpiTableLength) {
> +    // Parse common structure header to obtain Type and Length.
> +    ParseAcpi (
> +      FALSE,
> +      0,
> +      NULL,
> +      PccSubspacePtr,
> +      AcpiTableLength - Offset,
> +      PARSER_PARAMS (PccSubspaceHeaderParser)
> +      );
> +
> +    // Check if the values used to control the parsing logic have been
> +    // successfully read.
> +    if ((PccSubspaceType == NULL) ||
> +        (PccSubspaceLength == NULL)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Insufficient remaining table buffer length to read the " \
> +          L"structure header. Length = %u.\n",
> +        AcpiTableLength - Offset
> +        );
> +      return;
> +    }
> +
> +    // Validate Structure length
> +    if ((*PccSubspaceLength == 0) ||
> +        ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) {
> +      IncrementErrorCount ();
> +      Print (
> +        L"ERROR: Invalid Structure length. " \
> +          L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
> +        *PccSubspaceLength,
> +        Offset,
> +        AcpiTableLength
> +        );
> +      return;
> +    }
> +
> +    switch (*PccSubspaceType) {
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_GENERIC:
> +        DumpPccSubspaceType0 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType1 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case
> EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
> +        DumpPccSubspaceType2 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
> +        DumpPccSubspaceType3 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      case EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
> +        DumpPccSubspaceType4 (
> +          PccSubspacePtr,
> +          *PccSubspaceLength
> +          );
> +        break;
> +      default:
> +        IncrementErrorCount ();
> +        Print (
> +          L"ERROR: Unknown PCC subspace structure:"
> +            L" Type = %u, Length = %u\n",
> +          PccSubspaceType,
> +          *PccSubspaceLength
> +          );
> +    }
> +
> +    PccSubspacePtr += *PccSubspaceLength;
> +    Offset += *PccSubspaceLength;
> +    SubspaceCount++;
> +  } // while
> +
> +  if (SubspaceCount > MAX_PCC_SUBSPACES) {
> +    IncrementErrorCount ();
> +    Print (L"ERROR: Too many PCC subspaces.");
> +  }
> +}
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..278dc83c5de8860cbb2b1e2b2
> e277aa7c6c58698
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctPars
> +++ er.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  Header file for PCCT parser
> +
> +  Copyright (c) 2020, Arm Limited.
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef PCCT_PARSER_H_
> +#define PCCT_PARSER_H_
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
> +*/
> +#define MIN_MEMORY_RANGE_LENGTH                 8
> +
> +/**
> +  Minimum value for the 'length' field in subspaces of types 3 and 4.
> +*/
> +#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN      16
> +
> +/**
> +  Maximum number of PCC subspaces.
> +*/
> +#define MAX_PCC_SUBSPACES                       256
> +
> +/**
> +  Parser for the header of any type of PCC subspace.
> +*/
> +#define PCC_SUBSPACE_HEADER()                                             \
> +  {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL},   \
> +  {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL,
> +NULL}
> +
> +#endif // PCCT_PARSER_H_
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> index
> d2f26ff89f12e596702281c38ab0de3729aa68e4..feb80661cddc420670edb2d8c7a
> 570b0a89272d8 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.c
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Main file for 'acpiview' Shell command function.
> 
> -  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>    SPDX-License-Identifier: BSD-2-Clause-Patent  **/
> 
> @@ -57,6 +57,8 @@ ACPI_TABLE_PARSER ParserList[] = {
>    {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> ParseAcpiMadt},
> 
> {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BA
> SE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
>     ParseAcpiMcfg},
> +
> {EFI_ACPI_6_2_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
> +   ParseAcpiPcct},
> 
> {EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGN
> ATURE,
>     ParseAcpiPptt},
>    {RSDP_TABLE_INFO, ParseAcpiRsdp},
> diff --git
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> index
> 91459f9ec632635ee453c5ef46f67445cd9eee0c..efa9c8784a6670e5a4f500e0ae5
> 59a4938852f95 100644
> ---
> a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLi
> b.inf
> +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewComm
> +++ andLib.inf
> @@ -1,7 +1,7 @@
>  ##  @file
>  # Provides Shell 'acpiview' command functions  # -# Copyright (c) 2016 - 2020,
> ARM Limited. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -37,6 +37,8 @@
> [Sources.common]
>    Parsers/Madt/MadtParser.c
>    Parsers/Madt/MadtParser.h
>    Parsers/Mcfg/McfgParser.c
> +  Parsers/Pcct/PcctParser.c
> +  Parsers/Pcct/PcctParser.h
>    Parsers/Pptt/PpttParser.c
>    Parsers/Pptt/PpttParser.h
>    Parsers/Rsdp/RsdpParser.c
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
> 
> 
> 







^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-09-16 14:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-24 10:23 [PATCH v1 1/1] ShellPkg/AcpiView: PCCT Parser Sami Mujawar
2020-09-10 11:38 ` Sami Mujawar
2020-09-11  1:57   ` Gao, Zhichao
2020-09-16  2:43 ` [edk2-devel] " Gao, Zhichao
2020-09-16 14:14   ` Sami Mujawar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox