public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v5 0/9] Add ACPI support for Kvmtool
@ 2022-02-01 17:22 PierreGondois
  2022-02-01 17:22 ` [PATCH v5 1/9] DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID PierreGondois
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3742
V1: https://edk2.groups.io/g/devel/message/76990
V2:
- New patch: "DynamicTablesPkg: Print specifier macro for
  CM_OBJECT_ID" [Laszlo]
- Only add AcpiView for ArmVirtKvmTool instead of all ArmVirt
  platforms. This is done using a 'ACPIVIEW_ENABLE' switch.
  [Laszlo]
- Only generate ACPI tables for AARCH64. [Laszlo]
- Various modifications (error handling, patch organization,
  coding style, etc). [Laszlo]
V3:
- To fix bugs reported by Linux (signaled by Ard):
  - Add patch to parse and populate PMU information.
  - Add patch to strictly comply to the first model at ACPI
    6.4 s6.2.13 to describe PCI legacy interrupts using _PRT.
  - Add address size limit to IORT PCI root complex.
V4:
- Describe PCI legacy interrupts using GSI and remove link
  device generation. [Pierre]
- Add more description in ASSERT macros. [Ard]
V5:
- Update DSDT revision to 2. [Rebecca]

The changes can be seen at:
https://github.com/PierreARM/edk2/tree/1456_Add_ACPI_support_for_Kvmtool_v5
The results of the CI can be seen at:
https://github.com/tianocore/edk2/pull/2476

The patch depends on the KvmTool patch at:
https://lists.cs.columbia.edu/pipermail/kvmarm/2022-January/051865.html

Kvmtool dynamically generates a device tree describing the platform
to boot on. Using the patch-sets listed below, the DynamicTables
framework generates ACPI tables describing a similar platform.

This patch-set:
 - adds a ConfigurationManager and make use of the DynamicTablesPkg
   in for Kvmtool for AARCH64, allowing to generate ACPI tables
 - adds the acpiview command line utility to the ArmVirtPkg
   platform that request if via the ACPIVIEW_ENABLE macro
 - update ArmVirtPkg.ci.yaml to add new words and use the
   DynamicTablesPkg
 - adds a print specifier macro for the CM_OBJECT_ID type

With this patchset, KvmTool on AARCH64 will use ACPI tables instead
of a Device Tree (cf PcdForceNoAcpi Pcd).

Pierre Gondois (5):
  DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID
  DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info
  DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI
  DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation
  ArmVirtPkg: Add cspell exceptions

Sami Mujawar (4):
  ArmVirtPkg/Kvmtool: Add DSDT ACPI table
  ArmVirtPkg/Kvmtool: Add Configuration Manager
  ArmVirtPkg/Kvmtool: Enable ACPI support
  ArmVirtPkg/Kvmtool: Enable Acpiview

 ArmVirtPkg/ArmVirt.dsc.inc                    |    5 +-
 ArmVirtPkg/ArmVirtKvmTool.dsc                 |   22 +-
 ArmVirtPkg/ArmVirtKvmTool.fdf                 |   15 +-
 ArmVirtPkg/ArmVirtPkg.ci.yaml                 |    6 +-
 .../KvmtoolCfgMgrDxe/AslTables/Dsdt.asl       |   21 +
 .../KvmtoolCfgMgrDxe/ConfigurationManager.c   | 1065 +++++++++++++++++
 .../KvmtoolCfgMgrDxe/ConfigurationManager.h   |  125 ++
 .../ConfigurationManagerDxe.inf               |   54 +
 .../Include/ConfigurationManagerObject.h      |    7 +-
 .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.c    |  239 +---
 .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.h    |   64 +-
 .../Common/AmlLib/CodeGen/AmlCodeGen.c        |   89 +-
 .../FdtHwInfoParserLib/Gic/ArmGicCParser.c    |  132 +-
 .../FdtHwInfoParserLib/Gic/ArmGicCParser.h    |    8 +-
 14 files changed, 1518 insertions(+), 334 deletions(-)
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf

-- 
2.25.1


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

* [PATCH v5 1/9] DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 2/9] DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info PierreGondois
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

Add a macro that specifies the format for printing CM_OBJECT_ID.
This allows to print the CM_OBJECT_ID is a consistent way in the
output logs.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v2:
    - New patch, requested by Laszlo.

 DynamicTablesPkg/Include/ConfigurationManagerObject.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
index 60d825a2b253..74ad25d5d94a 100644
--- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h
+++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
@@ -1,6 +1,6 @@
 /** @file
 
-  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+  Copyright (c) 2017 - 2022, ARM Limited. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -84,6 +84,11 @@ Object ID's in the ARM Namespace:
 */
 typedef UINT32 CM_OBJECT_ID;
 
+//
+// Helper macro to format a CM_OBJECT_ID.
+//
+#define FMT_CM_OBJECT_ID  "0x%lx"
+
 /** A mask for Object ID
 */
 #define OBJECT_ID_MASK  0xFF
-- 
2.25.1


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

* [PATCH v5 2/9] DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
  2022-02-01 17:22 ` [PATCH v5 1/9] DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 3/9] DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI PierreGondois
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

Parse the Pmu interrupts if a pmu compatible node is present,
and populate the MADT GicC structure accordingly.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v3:
     - New patch. [Pierre]
    v4:
     - Add more information in ASSERT () checks. [Ard]

 .../FdtHwInfoParserLib/Gic/ArmGicCParser.c    | 132 +++++++++++++++++-
 .../FdtHwInfoParserLib/Gic/ArmGicCParser.h    |   8 +-
 2 files changed, 136 insertions(+), 4 deletions(-)

diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
index b4e6729a4ab2..fb01aa0d19e2 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
@@ -1,13 +1,14 @@
 /** @file
   Arm Gic cpu parser.
 
-  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Reference(s):
   - linux/Documentation/devicetree/bindings/arm/cpus.yaml
   - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
   - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
+  - linux/Documentation/devicetree/bindings/arm/pmu.yaml
 **/
 
 #include "FdtHwInfoParser.h"
@@ -34,6 +35,21 @@ STATIC CONST COMPATIBILITY_INFO  CpuCompatibleInfo = {
   CpuCompatibleStr
 };
 
+/** Pmu compatible strings.
+
+  Any other "compatible" value is not supported by this module.
+*/
+STATIC CONST COMPATIBILITY_STR  PmuCompatibleStr[] = {
+  { "arm,armv8-pmuv3" }
+};
+
+/** COMPATIBILITY_INFO structure for the PmuCompatibleStr.
+*/
+CONST COMPATIBILITY_INFO  PmuCompatibleInfo = {
+  ARRAY_SIZE (PmuCompatibleStr),
+  PmuCompatibleStr
+};
+
 /** Parse a "cpu" node.
 
   @param [in]  Fdt              Pointer to a Flattened Device Tree (Fdt).
@@ -639,6 +655,111 @@ GicCv3IntcNodeParser (
   return EFI_SUCCESS;
 }
 
+/** Parse a Pmu compatible node, extracting Pmu information.
+
+  This function modifies a CM_OBJ_DESCRIPTOR object.
+  The following CM_ARM_GICC_INFO fields are patched:
+    - PerformanceInterruptGsiv;
+
+  @param [in]       Fdt              Pointer to a Flattened Device Tree (Fdt).
+  @param [in]       GicIntcNode      Offset of a Gic compatible
+                                     interrupt-controller node.
+  @param [in, out]  GicCCmObjDesc    The CM_ARM_GICC_INFO to patch.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GicCPmuNodeParser (
+  IN      CONST VOID               *Fdt,
+  IN            INT32              GicIntcNode,
+  IN  OUT       CM_OBJ_DESCRIPTOR  *GicCCmObjDesc
+  )
+{
+  EFI_STATUS        Status;
+  INT32             IntCells;
+  INT32             PmuNode;
+  UINT32            PmuNodeCount;
+  UINT32            PmuIrq;
+  UINT32            Index;
+  CM_ARM_GICC_INFO  *GicCInfo;
+  CONST UINT8       *Data;
+  INT32             DataSize;
+
+  if (GicCCmObjDesc == NULL) {
+    ASSERT (GicCCmObjDesc != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data;
+  PmuNode  = 0;
+
+  // Count the number of pmu nodes.
+  Status = FdtCountCompatNodeInBranch (
+             Fdt,
+             0,
+             &PmuCompatibleInfo,
+             &PmuNodeCount
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  if (PmuNodeCount == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = FdtGetNextCompatNodeInBranch (
+             Fdt,
+             0,
+             &PmuCompatibleInfo,
+             &PmuNode
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    if (Status == EFI_NOT_FOUND) {
+      // Should have found the node.
+      Status = EFI_ABORTED;
+    }
+  }
+
+  // Get the number of cells used to encode an interrupt.
+  Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Data = fdt_getprop (Fdt, PmuNode, "interrupts", &DataSize);
+  if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) {
+    // If error or not 1 interrupt.
+    ASSERT (Data != NULL);
+    ASSERT (DataSize == (IntCells * sizeof (UINT32)));
+    return EFI_ABORTED;
+  }
+
+  PmuIrq = FdtGetInterruptId ((CONST UINT32 *)Data);
+
+  // Only supports PPI 23 for now.
+  // According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. A non BSA
+  // compliant system may assign a different IRQ for the PMU, however this
+  // is not implemented for now.
+  if (PmuIrq != BSA_PMU_IRQ) {
+    ASSERT (PmuIrq == BSA_PMU_IRQ);
+    return EFI_ABORTED;
+  }
+
+  for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
+    GicCInfo[Index].PerformanceInterruptGsiv = PmuIrq;
+  }
+
+  return EFI_SUCCESS;
+}
+
 /** CM_ARM_GICC_INFO parser function.
 
   This parser expects FdtBranch to be the "\cpus" node node.
@@ -649,7 +770,7 @@ GicCv3IntcNodeParser (
     UINT32  AcpiProcessorUid;                 // {Populated}
     UINT32  Flags;                            // {Populated}
     UINT32  ParkingProtocolVersion;           // {default = 0}
-    UINT32  PerformanceInterruptGsiv;         // {default = 0}
+    UINT32  PerformanceInterruptGsiv;         // {Populated}
     UINT64  ParkedAddress;                    // {default = 0}
     UINT64  PhysicalBaseAddress;              // {Populated}
     UINT64  GICV;                             // {Populated}
@@ -764,6 +885,13 @@ ArmGicCInfoParser (
     goto exit_handler;
   }
 
+  // Parse the Pmu Interrupt.
+  Status = GicCPmuNodeParser (Fdt, IntcNode, NewCmObjDesc);
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+    ASSERT_EFI_ERROR (Status);
+    goto exit_handler;
+  }
+
   // Add all the CmObjs to the Configuration Manager.
   Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL);
   if (EFI_ERROR (Status)) {
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
index 2a0f966bf0c2..fd980484a28d 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
@@ -1,7 +1,7 @@
 /** @file
   Arm Gic cpu parser.
 
-  Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Reference(s):
@@ -12,6 +12,10 @@
 #ifndef ARM_GICC_PARSER_H_
 #define ARM_GICC_PARSER_H_
 
+/* According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23.
+*/
+#define BSA_PMU_IRQ  23
+
 /** CM_ARM_GICC_INFO parser function.
 
   This parser expects FdtBranch to be the "\cpus" node node.
@@ -22,7 +26,7 @@
     UINT32  AcpiProcessorUid;                 // {Populated}
     UINT32  Flags;                            // {Populated}
     UINT32  ParkingProtocolVersion;           // {default = 0}
-    UINT32  PerformanceInterruptGsiv;         // {default = 0}
+    UINT32  PerformanceInterruptGsiv;         // {Populated}
     UINT64  ParkedAddress;                    // {default = 0}
     UINT64  PhysicalBaseAddress;              // {Populated}
     UINT64  GICV;                             // {Populated}
-- 
2.25.1


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

* [PATCH v5 3/9] DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
  2022-02-01 17:22 ` [PATCH v5 1/9] DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID PierreGondois
  2022-02-01 17:22 ` [PATCH v5 2/9] DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 4/9] DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation PierreGondois
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

In ACPI 6.4, s6.2.13, _PRT objects describing PCI legacy interrupts
can be defined following 2 models.
In the first model, _PRT entries reference link devices. Link devices
then describe interrupts. This allows to dynamically modify
interrupts through _SRS and _PRS objects and to choose exactly the
interrupt type (level/edge triggered, active high/low).
In the second model, interrupt numbers are described in the _PRT entry.
The interrupt type is then assumed by the OS.

AmlAddPrtEntry() currently only handles the first model. Make
changes to also handle the second model.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v4:
     - New patch (to handle GSI description in _PRT). [Pierre]

 .../Common/AmlLib/CodeGen/AmlCodeGen.c        | 89 ++++++++++++-------
 1 file changed, 55 insertions(+), 34 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index d245848ce3fa..2d55db97c7bf 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -1,7 +1,7 @@
 /** @file
   AML Code Generation.
 
-  Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
+  Copyright (c) 2020 - 2022, Arm Limited. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
@@ -881,6 +881,9 @@ AmlCodeGenNameResourceTemplate (
                // interrupt, so let it to index 0.
     }
 
+  The 2 models described in ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)" can
+  be generated by this function. The example above matches the first model.
+
   The package is added at the tail of the list of the input _PRT node
   name:
     Name (_PRT, Package () {
@@ -901,8 +904,10 @@ AmlCodeGenNameResourceTemplate (
   @param [in]  Pin            PCI pin number of the device (0-INTA ... 3-INTD).
                               Must be between 0-3.
   @param [in]  LinkName       Link Name, i.e. device in the AML NameSpace
-                              describing the interrupt used.
-                              The input string is copied.
+                              describing the interrupt used. The input string
+                              is copied.
+                              If NULL, generate 0 in the 'Source' field (cf.
+                              second model, using GSIV).
   @param [in]  SourceIndex    Source index or GSIV.
   @param [in]  PrtNameNode    Prt Named node to add the object to ....
 
@@ -930,7 +935,6 @@ AmlAddPrtEntry (
   AML_DATA_NODE  *DataNode;
 
   if ((Pin > 3)                 ||
-      (LinkName == NULL)        ||
       (PrtNameNode == NULL)     ||
       (AmlGetNodeType ((AML_NODE_HANDLE)PrtNameNode) != EAmlNodeObject) ||
       (!AmlNodeHasOpCode (PrtNameNode, AML_NAME_OP, 0))                 ||
@@ -999,41 +1003,58 @@ AmlAddPrtEntry (
 
   NewElementNode = NULL;
 
-  Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    goto error_handler;
-  }
+  if (LinkName != NULL) {
+    Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
 
-  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    goto error_handler;
-  }
+    Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
 
-  Status = AmlCreateDataNode (
-             EAmlNodeDataTypeNameString,
-             (UINT8 *)AmlNameString,
-             AmlNameStringSize,
-             &DataNode
-             );
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    goto error_handler;
-  }
+    Status = AmlCreateDataNode (
+               EAmlNodeDataTypeNameString,
+               (UINT8 *)AmlNameString,
+               AmlNameStringSize,
+               &DataNode
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
 
-  // AmlNameString will be freed before returning.
+    // AmlNameString will be freed be fore returning.
 
-  Status = AmlVarListAddTail (
-             (AML_NODE_HANDLE)PackageNode,
-             (AML_NODE_HANDLE)DataNode
-             );
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    goto error_handler;
-  }
+    Status = AmlVarListAddTail (
+               (AML_NODE_HANDLE)PackageNode,
+               (AML_NODE_HANDLE)DataNode
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
+
+    DataNode = NULL;
+  } else {
+    Status = AmlCodeGenInteger (0, &NewElementNode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
 
-  DataNode = NULL;
+    Status = AmlVarListAddTail (
+               (AML_NODE_HANDLE)PackageNode,
+               (AML_NODE_HANDLE)NewElementNode
+               );
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      goto error_handler;
+    }
+  }
 
   Status = AmlCodeGenInteger (SourceIndex, &NewElementNode);
   if (EFI_ERROR (Status)) {
-- 
2.25.1


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

* [PATCH v5 4/9] DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (2 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 3/9] DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 5/9] ArmVirtPkg: Add cspell exceptions PierreGondois
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

In ACPI 6.4, s6.2.13, _PRT objects describing PCI legacy interrupts
can be defined following 2 models.
In the first model, _PRT entries reference link devices. Link devices
then describe interrupts. This allows to dynamically modify
interrupts through _SRS and _PRS objects and to choose exactly the
interrupt type (level/edge triggered, active high/low).
In the second model, interrupt numbder are described in the _PRT entry.
The interrupt type is then assumed by the OS.

The Arm BSA, sE.6 "Legacy interrupts" states that PCI legacy
interrupts must be converted to SPIs, and programmed level-sensitive,
active high. Thus any OS must configure interrupts as such and there
is no need to specify the interrupt type.
Plus it is not possible to dynamically configure PCI interrupts.

Thus remove the link device generation and use the second model
for _PRT.

Suggested-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v4:
     - New patch. [Ard]

 .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.c    | 239 +-----------------
 .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.h    |  64 +----
 2 files changed, 15 insertions(+), 288 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c
index 3e22587d4a25..a34018151f2d 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c
@@ -1,7 +1,7 @@
 /** @file
   SSDT Pcie Table Generator.
 
-  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -12,6 +12,7 @@
    - s6.1.1 "_ADR (Address)"
   - linux kernel code
   - Arm Base Boot Requirements v1.0
+  - Arm Base System Architecture v1.0
 **/
 
 #include <Library/AcpiLib.h>
@@ -279,171 +280,6 @@ GeneratePciDeviceInfo (
   return Status;
 }
 
-/** Generate a Link device.
-
-  The Link device is added at the beginning of the ASL Pci device definition.
-
-  Each Link device represents a Pci legacy interrupt (INTA-...-INTD).
-
-  ASL code:
-  Device (<Link Name>) {
-    Name (_UID, <Uid>])
-    Name (_HID, EISAID ("PNP0C0F"))
-    Name (CRS0, ResourceTemplate () {
-      Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { <Irq>] }
-      })
-    Method (_CRS, 0) {
-      Return CRS0
-      })
-    Method (_DIS) { }
-  }
-
-  The list of objects to define is available at:
-  PCI Firmware Specification - Revision 3.3,
-  s3.5. "Device State at Firmware/Operating System Handoff"
-
-  The _PRS and _SRS are not supported, cf Arm Base Boot Requirements v1.0:
-  "The _PRS (Possible Resource Settings) and _SRS (Set Resource Settings)
-  are not supported."
-
-  @param [in]       Irq         Interrupt controller interrupt.
-  @param [in]       IrqFlags    Interrupt flags.
-  @param [in]       LinkIndex   Legacy Pci interrupt index.
-                                Must be between 0-INTA and 3-INTD.
-  @param [in, out]  PciNode     Pci node to amend.
-
-  @retval EFI_SUCCESS            Success.
-  @retval EFI_INVALID_PARAMETER  Invalid parameter.
-  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-GenerateLinkDevice (
-  IN      UINT32                  Irq,
-  IN      UINT32                  IrqFlags,
-  IN      UINT32                  LinkIndex,
-  IN  OUT AML_OBJECT_NODE_HANDLE  PciNode
-  )
-{
-  EFI_STATUS              Status;
-  CHAR8                   AslName[AML_NAME_SEG_SIZE + 1];
-  AML_OBJECT_NODE_HANDLE  LinkNode;
-  AML_OBJECT_NODE_HANDLE  CrsNode;
-  UINT32                  EisaId;
-
-  ASSERT (LinkIndex < 4);
-  ASSERT (PciNode != NULL);
-
-  CopyMem (AslName, "LNKx", AML_NAME_SEG_SIZE + 1);
-  AslName[AML_NAME_SEG_SIZE - 1] = 'A' + LinkIndex;
-
-  // ASL: Device (LNKx) {}
-  Status = AmlCodeGenDevice (AslName, NULL, &LinkNode);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  Status = AmlAttachNode (PciNode, LinkNode);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    // Failed to add.
-    AmlDeleteTree ((AML_NODE_HANDLE)LinkNode);
-    return Status;
-  }
-
-  // ASL: Name (_UID, <Uid>)
-  Status = AmlCodeGenNameInteger ("_UID", LinkIndex, LinkNode, NULL);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  // ASL: Name (_HID, EISAID ("PNP0C0F"))
-  Status = AmlGetEisaIdFromString ("PNP0C0F", &EisaId);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  Status = AmlCodeGenNameInteger ("_HID", EisaId, LinkNode, NULL);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  // ASL:
-  // Name (CRS0, ResourceTemplate () {
-  //   Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { <Irq> }
-  // })
-  Status = AmlCodeGenNameResourceTemplate ("CRS0", LinkNode, &CrsNode);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  Status = AmlCodeGenRdInterrupt (
-             FALSE,
-             (IrqFlags & BIT0) != 0,
-             (IrqFlags & BIT1) != 0,
-             FALSE,
-             &Irq,
-             1,
-             CrsNode,
-             NULL
-             );
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  // ASL:
-  // Method (_CRS, 0) {
-  //   Return (CRS0)
-  // }
-  Status = AmlCodeGenMethodRetNameString (
-             "_CRS",
-             "CRS0",
-             0,
-             FALSE,
-             0,
-             LinkNode,
-             NULL
-             );
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  // ASL:Method (_DIS, 1) {}
-  // Not possible to disable interrupts.
-  Status = AmlCodeGenMethodRetNameString (
-             "_DIS",
-             NULL,
-             0,
-             FALSE,
-             0,
-             LinkNode,
-             NULL
-             );
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
-  // _STA:
-  // ACPI 6.4, s6.3.7 "_STA (Device Status)":
-  // If a device object describes a device that is not on an enumerable bus
-  // and the device object does not have an _STA object, then OSPM assumes
-  // that the device is present, enabled, shown in the UI, and functioning.
-
-  // _MAT:
-  // Not supported. Mainly used for processors.
-
-  return Status;
-}
-
 /** Generate Pci slots devices.
 
   PCI Firmware Specification - Revision 3.3,
@@ -556,14 +392,10 @@ GeneratePrt (
 {
   EFI_STATUS                     Status;
   INT32                          Index;
-  UINT32                         IrqTableIndex;
   AML_OBJECT_NODE_HANDLE         PrtNode;
-  CHAR8                          AslName[AML_NAME_SEG_SIZE + 1];
   CM_ARM_OBJ_REF                 *RefInfo;
   UINT32                         RefCount;
   CM_ARM_PCI_INTERRUPT_MAP_INFO  *IrqMapInfo;
-  UINT32                         IrqFlags;
-  UINT32                         PrevIrqFlags;
 
   ASSERT (Generator != NULL);
   ASSERT (CfgMgrProtocol != NULL);
@@ -585,13 +417,6 @@ GeneratePrt (
     return Status;
   }
 
-  // Initialized IrqTable.
-  Status = MappingTableInitialize (&Generator->IrqTable, RefCount);
-  if (EFI_ERROR (Status)) {
-    ASSERT (0);
-    return Status;
-  }
-
   // Initialized DeviceTable.
   Status = MappingTableInitialize (&Generator->DeviceTable, RefCount);
   if (EFI_ERROR (Status)) {
@@ -606,8 +431,6 @@ GeneratePrt (
     goto exit_handler;
   }
 
-  CopyMem (AslName, "LNKx", AML_NAME_SEG_SIZE + 1);
-
   for (Index = 0; Index < RefCount; Index++) {
     // Get CM_ARM_PCI_INTERRUPT_MAP_INFO structures one by one.
     Status = GetEArmObjPciInterruptMapInfo (
@@ -621,25 +444,15 @@ GeneratePrt (
       goto exit_handler;
     }
 
-    // Add the interrupt in the IrqTable and get the link name.
-    IrqTableIndex = MappingTableAdd (
-                      &Generator->IrqTable,
-                      IrqMapInfo->IntcInterrupt.Interrupt
-                      );
-    if (IrqTableIndex >= MAX_PCI_LEGACY_INTERRUPT) {
-      ASSERT (0);
-      Status = EFI_INVALID_PARAMETER;
-      goto exit_handler;
-    }
-
-    AslName[AML_NAME_SEG_SIZE - 1] = 'A' + IrqTableIndex;
-
-    // Check that the interrupts flags are identical for all interrupts.
-    PrevIrqFlags = IrqFlags;
-    IrqFlags     = IrqMapInfo->IntcInterrupt.Flags;
-    if ((Index > 0) && (PrevIrqFlags != IrqFlags)) {
-      ASSERT (0);
+    // Check that the interrupts flags are SPIs, level high.
+    // Cf. Arm BSA v1.0, sE.6 "Legacy interrupts"
+    if ((Index > 0)   &&
+        (IrqMapInfo->IntcInterrupt.Interrupt >= 32)   &&
+        (IrqMapInfo->IntcInterrupt.Interrupt < 1020)  &&
+        ((IrqMapInfo->IntcInterrupt.Flags & 0x3) != BIT0))
+    {
       Status = EFI_INVALID_PARAMETER;
+      ASSERT_EFI_ERROR (Status);
       goto exit_handler;
     }
 
@@ -662,8 +475,8 @@ GeneratePrt (
     Status = AmlAddPrtEntry (
                (IrqMapInfo->PciDevice << 16) | 0xFFFF,
                IrqMapInfo->PciInterrupt,
-               AslName,
-               0,
+               NULL,
+               IrqMapInfo->IntcInterrupt.Interrupt,
                PrtNode
                );
     if (EFI_ERROR (Status)) {
@@ -672,24 +485,10 @@ GeneratePrt (
     }
   } // for
 
-  // Generate the LNKx devices now that we know all the interrupts used.
-  for (Index = 0; Index < Generator->IrqTable.LastIndex; Index++) {
-    Status = GenerateLinkDevice (
-               Generator->IrqTable.Table[Index],
-               IrqFlags,
-               Index,
-               PciNode
-               );
-    if (EFI_ERROR (Status)) {
-      ASSERT (0);
-      goto exit_handler;
-    }
-  } // for
-
-  // Attach the _PRT entry now, after the LNKx devices.
+  // Attach the _PRT entry.
   Status = AmlAttachNode (PciNode, PrtNode);
   if (EFI_ERROR (Status)) {
-    ASSERT (0);
+    ASSERT_EFI_ERROR (Status);
     goto exit_handler;
   }
 
@@ -705,7 +504,6 @@ GeneratePrt (
 exit_handler:
   MappingTableFree (&Generator->DeviceTable);
 exit_handler0:
-  MappingTableFree (&Generator->IrqTable);
   if (PrtNode != NULL) {
     AmlDeleteTree (PrtNode);
   }
@@ -1382,15 +1180,6 @@ ACPI_PCI_GENERATOR  SsdtPcieGenerator = {
 
   // Private fields are defined from here.
 
-  // IrqTable
-  {
-    // Table
-    NULL,
-    // LastIndex
-    0,
-    // MaxIndex
-    0
-  },
   // DeviceTable
   {
     // Table
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h
index d1e5465e1346..59a0d601a36d 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h
@@ -33,12 +33,6 @@
 */
 #define MAX_PCI_ROOT_COMPLEXES_SUPPORTED  16
 
-/** Maximum number of Pci legacy interrupts.
-
-  Currently 4 for INTA-INTB-INTC-INTD.
-*/
-#define MAX_PCI_LEGACY_INTERRUPT  4
-
 // _SB scope of the AML namespace.
 #define SB_SCOPE  "\\_SB_"
 
@@ -73,64 +67,8 @@ typedef struct AcpiPcieGenerator {
 
   // Private fields are defined from here.
 
-  /** A structure used to handle the Address and Interrupt Map referencing.
-
-    A CM_ARM_PCI_CONFIG_SPACE_INFO structure references two CM_ARM_OBJ_REF:
-     - one for the address mapping, referencing
-       CM_ARM_PCI_ADDRESS_MAP_INFO structures.
-     - one for the interrupt mapping, referencing
-       CM_ARM_PCI_INTERRUPT_MAP_INFO structures.
-
-    Example:
-    (Pci0)
-    CM_ARM_PCI_CONFIG_SPACE_INFO
-                |
-                +----------------------------------------
-                |                                       |
-                v                                       v
-          CM_ARM_OBJ_REF                          CM_ARM_OBJ_REF
-      (List of references to                  (List of references to
-         address mappings)                        interrupt mappings)
-                |                                       |
-                v                                       v
-    CM_ARM_PCI_ADDRESS_MAP_INFO[0..N]      CM_ARM_PCI_INTERRUPT_MAP_INFO[0..M]
-    (A list of address mappings)           (A list of interrupt mappings)
-
-    The CM_ARM_PCI_INTERRUPT_MAP_INFO objects cannot be handled individually.
-    Device's Pci legacy interrupts that are mapped to the same CPU interrupt
-    are grouped under a Link device.
-    For instance, the following mapping:
-     - [INTA of device 0] mapped on [GIC irq 168]
-     - [INTB of device 1] mapped on [GIC irq 168]
-    will be represented in an SSDT table as:
-     - [INTA of device 0] mapped on [Link device A]
-     - [INTB of device 1] mapped on [Link device A]
-     - [Link device A] mapped on [GIC irq 168]
-
-    Counting the number of Cpu interrupts used and grouping them in Link
-    devices is done through this IRQ_TABLE.
-
-    ASL code:
-    Scope (_SB) {
-      Device (LNKA) {
-        [...]
-        Name (_PRS, ResourceTemplate () {
-          Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { 168 }
-        })
-      }
-
-      Device (PCI0) {
-        Name (_PRT, Package () {
-          Package (0x0FFFF, 0, LNKA, 0)  // INTA of device 0 <-> LNKA
-          Package (0x1FFFF, 1, LNKA, 0)  // INTB of device 1 <-> LNKA
-          })
-        }
-    }
-  */
-  MAPPING_TABLE    IrqTable;
-
   /// Table to map: Index <-> Pci device
-  MAPPING_TABLE    DeviceTable;
+  MAPPING_TABLE           DeviceTable;
 } ACPI_PCI_GENERATOR;
 
 #pragma pack()
-- 
2.25.1


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

* [PATCH v5 5/9] ArmVirtPkg: Add cspell exceptions
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (3 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 4/9] DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 6/9] ArmVirtPkg/Kvmtool: Add DSDT ACPI table PierreGondois
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Pierre Gondois <Pierre.Gondois@arm.com>

The cpsell tool checks for unknown words in the upstream CI.
Add some new words to the list of exceptions.

Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v2:
    - Adding 'acpiview'. Since the patch change, Laszlo's
      Reviewed-by is not added. [Pierre]

 ArmVirtPkg/ArmVirtPkg.ci.yaml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ArmVirtPkg/ArmVirtPkg.ci.yaml b/ArmVirtPkg/ArmVirtPkg.ci.yaml
index 67b0e9594f3e..d5d63ddd4fd7 100644
--- a/ArmVirtPkg/ArmVirtPkg.ci.yaml
+++ b/ArmVirtPkg/ArmVirtPkg.ci.yaml
@@ -6,7 +6,7 @@
 #
 # Copyright (c) Microsoft Corporation
 # Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2020 - 2022, ARM Limited. All rights reserved.<BR>
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 ##
@@ -48,6 +48,7 @@
             "MdePkg/MdePkg.dec",
             "MdeModulePkg/MdeModulePkg.dec",
             "ArmVirtPkg/ArmVirtPkg.dec",
+            "DynamicTablesPkg/DynamicTablesPkg.dec",
             "NetworkPkg/NetworkPkg.dec",
             "ArmPkg/ArmPkg.dec",
             "OvmfPkg/OvmfPkg.dec",
@@ -98,6 +99,9 @@
         "AuditOnly": False,           # Fails right now with over 270 errors
         "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
         "ExtendWords": [
+            "acpiview",
+            "armltd",
+            "ssdts",
             "setjump",
             "plong",
             "lparam",
-- 
2.25.1


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

* [PATCH v5 6/9] ArmVirtPkg/Kvmtool: Add DSDT ACPI table
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (4 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 5/9] ArmVirtPkg: Add cspell exceptions PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 7/9] ArmVirtPkg/Kvmtool: Add Configuration Manager PierreGondois
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Sami Mujawar <sami.mujawar@arm.com>

Most ACPI tables for Kvmtool firmware are dynamically
generated. The AML code is also generated at runtime
for most components in appropriate SSDTs.

Although there may not be much to describe in the DSDT,
the DSDT table is mandatory.

Therefore, add an empty stub for DSDT.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
     - Coding style modifications. [Laszlo]
    v5:
     - Update DSDT table revision to 2. [Rebecca]

 .../KvmtoolCfgMgrDxe/AslTables/Dsdt.asl       | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl

diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl b/ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl
new file mode 100644
index 000000000000..13d1e1d8d6bd
--- /dev/null
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl
@@ -0,0 +1,21 @@
+/** @file
+  Differentiated System Description Table Fields (DSDT)
+
+  Copyright (c) 2021 - 2022, ARM Ltd. All rights reserved.<BR>
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock ("DsdtTable.aml", "DSDT", 2, "ARMLTD", "ARM-KVMT", 1) {
+  Scope (_SB) {
+    //
+    // Most ACPI tables for Kvmtool firmware are
+    // dynamically generated. The AML code is also
+    // generated at runtime for most components in
+    // appropriate SSDTs.
+    // Although there may not be much to describe
+    // in the DSDT, the DSDT table is mandatory.
+    // Therefore, add an empty stub for DSDT.
+    //
+  } // Scope (_SB)
+}
-- 
2.25.1


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

* [PATCH v5 7/9] ArmVirtPkg/Kvmtool: Add Configuration Manager
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (5 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 6/9] ArmVirtPkg/Kvmtool: Add DSDT ACPI table PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 8/9] ArmVirtPkg/Kvmtool: Enable ACPI support PierreGondois
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Sami Mujawar <sami.mujawar@arm.com>

Add Configuration Manager to enable ACPI tables for Kvmtool
firmware. The Configuration Manager for Kvmtool uses the DT
Hardware Information Parser module (FdtHwInfoParser) to parse
the DT provided by Kvmtool. The FdtHwInfoParser parses the DT
and invokes the callback function HW_INFO_ADD_OBJECT to add
the Configuration Manager objects to the Platform Information
repository.

The information for some Configuration Manager objects may not
be available in the DT. Such objects are initialised locally
by the Configuration Manager.

Support for the following ACPI tables is provided:
 - DBG2
 - DSDT (Empty stub)
 - FADT
 - GTDT
 - MADT
 - SPCR
 - SSDT (Cpu Hierarchy)
 - SSDT (Pcie bus)

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - Only keep AARCH64 as a valid architecture. [Laszlo]
    - Move modifications to ArmVirtKvmTool.dsc to the next
      patch. [Laszlo]
    - Various coding style/error handling/ASSERT corrections.
      [Laszlo]
    - Remove dependency to PcdForceNoAcpi and rely on DEPEX
      to load the module. [Laszlo]
    - Not possible to make 'struct PlatformRepositoryInfo'
      an unamed struct since this is a redifinition.
      [Laszlo/Pierre]
    - Define 'FMT_CM_OBJECT_ID' print formatter in an earlier
      patch and use it in this patch. [Laszlo/Pierre]
    
    v3:
    - Add address size limit for IORT PCI root complex. [Pierre]

 .../KvmtoolCfgMgrDxe/ConfigurationManager.c   | 1065 +++++++++++++++++
 .../KvmtoolCfgMgrDxe/ConfigurationManager.h   |  125 ++
 .../ConfigurationManagerDxe.inf               |   54 +
 3 files changed, 1244 insertions(+)
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
 create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf

diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
new file mode 100644
index 000000000000..e8c1b13c8f2c
--- /dev/null
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
@@ -0,0 +1,1065 @@
+/** @file
+  Configuration Manager Dxe
+
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DynamicPlatRepoLib.h>
+#include <Library/HobLib.h>
+#include <Library/HwInfoParserLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TableHelperLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "ConfigurationManager.h"
+
+//
+// The platform configuration repository information.
+//
+STATIC
+EDKII_PLATFORM_REPOSITORY_INFO  mKvmtoolPlatRepositoryInfo = {
+  //
+  // Configuration Manager information
+  //
+  { CONFIGURATION_MANAGER_REVISION, CFG_MGR_OEM_ID },
+
+  //
+  // ACPI Table List
+  //
+  {
+    //
+    // FADT Table
+    //
+    {
+      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
+      NULL
+    },
+    //
+    // GTDT Table
+    //
+    {
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
+      NULL
+    },
+    //
+    // MADT Table
+    //
+    {
+      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
+      NULL
+    },
+    //
+    // SPCR Table
+    //
+    {
+      EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+      EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
+      NULL
+    },
+    //
+    // DSDT Table
+    //
+    {
+      EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
+      (EFI_ACPI_DESCRIPTION_HEADER *)dsdt_aml_code
+    },
+    //
+    // SSDT Cpu Hierarchy Table
+    //
+    {
+      EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology),
+      NULL
+    },
+    //
+    // DBG2 Table
+    //
+    {
+      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
+      NULL
+    },
+    //
+    // PCI MCFG Table
+    //
+    {
+      EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg),
+      NULL
+    },
+    //
+    // SSDT table describing the PCI root complex
+    //
+    {
+      EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+      0, // Unused
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress),
+      NULL
+    },
+    //
+    // IORT Table
+    //
+    {
+      EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE,
+      EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
+      NULL
+    },
+  },
+
+  //
+  // Power management profile information
+  //
+  { EFI_ACPI_6_3_PM_PROFILE_ENTERPRISE_SERVER },    // PowerManagement Profile
+
+  //
+  // ITS group node
+  //
+  {
+    //
+    // Reference token for this Iort node
+    //
+    REFERENCE_TOKEN (ItsGroupInfo),
+    //
+    // The number of ITS identifiers in the ITS node.
+    //
+    1,
+    //
+    // Reference token for the ITS identifier array
+    //
+    REFERENCE_TOKEN (ItsIdentifierArray)
+  },
+
+  //
+  // ITS identifier array
+  //
+  {
+    { 0 },                            // The ITS Identifier
+  },
+
+  //
+  // Root Complex node info
+  //
+  {
+    //
+    // Reference token for this Iort node
+    //
+    REFERENCE_TOKEN (RootComplexInfo),
+    //
+    // Number of ID mappings
+    //
+    1,
+    //
+    // Reference token for the ID mapping array
+    //
+    REFERENCE_TOKEN (DeviceIdMapping[0]),
+    //
+    // Memory access properties : Cache coherent attributes
+    //
+    EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+    //
+    // Memory access properties : Allocation hints
+    //
+    0,
+    //
+    // Memory access properties : Memory access flags
+    //
+    0,
+    //
+    // ATS attributes
+    //
+    EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
+    //
+    // PCI segment number
+    //
+    0,
+    ///
+    /// Memory address size limit
+    ///
+    MEMORY_ADDRESS_SIZE_LIMIT
+  },
+
+  //
+  // Array of Device ID mappings
+  //
+  {
+    //
+    // Device ID mapping for Root complex node
+    // RootComplex -> ITS Group
+    //
+    {
+      //
+      // Input base
+      //
+      0x0,
+      //
+      // Number of input IDs
+      //
+      0x0000FFFF,
+      //
+      // Output Base
+      //
+      0x0,
+      //
+      // Output reference
+      //
+      REFERENCE_TOKEN (ItsGroupInfo),
+      //
+      // Flags
+      //
+      0
+    },
+  },
+};
+
+/**
+  A helper function for returning the Configuration Manager Objects.
+
+  @param [in]       CmObjectId     The Configuration Manager Object ID.
+  @param [in]       Object         Pointer to the Object(s).
+  @param [in]       ObjectSize     Total size of the Object(s).
+  @param [in]       ObjectCount    Number of Objects.
+  @param [in, out]  CmObjectDesc   Pointer to the Configuration Manager Object
+                                   descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObject (
+  IN  CONST CM_OBJECT_ID                CmObjectId,
+  IN        VOID                        *Object,
+  IN  CONST UINTN                       ObjectSize,
+  IN  CONST UINTN                       ObjectCount,
+  IN  OUT   CM_OBJ_DESCRIPTOR   *CONST  CmObjectDesc
+  )
+{
+  CmObjectDesc->ObjectId = CmObjectId;
+  CmObjectDesc->Size     = ObjectSize;
+  CmObjectDesc->Data     = Object;
+  CmObjectDesc->Count    = ObjectCount;
+  DEBUG ((
+    DEBUG_INFO,
+    "INFO: CmObjectId = " FMT_CM_OBJECT_ID ", "
+                                           "Ptr = 0x%p, Size = %lu, Count = %lu\n",
+    CmObjectId,
+    CmObjectDesc->Data,
+    CmObjectDesc->Size,
+    CmObjectDesc->Count
+    ));
+  return EFI_SUCCESS;
+}
+
+/**
+  A helper function for returning the Configuration Manager Objects that
+  match the token.
+
+  @param [in]  This               Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId         The Configuration Manager Object ID.
+  @param [in]  Object             Pointer to the Object(s).
+  @param [in]  ObjectSize         Total size of the Object(s).
+  @param [in]  ObjectCount        Number of Objects.
+  @param [in]  Token              A token identifying the object.
+  @param [in]  HandlerProc        A handler function to search the object
+                                  referenced by the token.
+  @param [in, out]  CmObjectDesc  Pointer to the Configuration Manager Object
+                                  descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObjectRefByToken (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN        VOID                                          *Object,
+  IN  CONST UINTN                                         ObjectSize,
+  IN  CONST UINTN                                         ObjectCount,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  CONST CM_OBJECT_HANDLER_PROC                        HandlerProc,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObjectDesc
+  )
+{
+  EFI_STATUS  Status;
+
+  CmObjectDesc->ObjectId = CmObjectId;
+  if (Token == CM_NULL_TOKEN) {
+    CmObjectDesc->Size  = ObjectSize;
+    CmObjectDesc->Data  = Object;
+    CmObjectDesc->Count = ObjectCount;
+    Status              = EFI_SUCCESS;
+  } else {
+    Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc);
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "INFO: Token = 0x%p, CmObjectId = " FMT_CM_OBJECT_ID ", "
+                                                         "Ptr = 0x%p, Size = %lu, Count = %lu\n",
+    (VOID *)Token,
+    CmObjectId,
+    CmObjectDesc->Data,
+    CmObjectDesc->Size,
+    CmObjectDesc->Count
+    ));
+  return Status;
+}
+
+/**
+  Return an ITS identifier array.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId  The Configuration Manager Object ID.
+  @param [in]  Token       A token for identifying the object
+  @param [out] CmObject    Pointer to the Configuration Manager Object
+                           descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetItsIdentifierArray (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  OUT       CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray) {
+    return EFI_NOT_FOUND;
+  }
+
+  CmObject->ObjectId = CmObjectId;
+  CmObject->Size     = sizeof (PlatformRepo->ItsIdentifierArray);
+  CmObject->Data     = (VOID *)&PlatformRepo->ItsIdentifierArray;
+  CmObject->Count    = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
+  return EFI_SUCCESS;
+}
+
+/**
+  Return a device Id mapping array.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId  The Configuration Manager Object ID.
+  @param [in]  Token       A token for identifying the object
+  @param [out] CmObject    Pointer to the Configuration Manager Object
+                           descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetDeviceIdMappingArray (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  OUT       CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0]) {
+    return EFI_NOT_FOUND;
+  }
+
+  CmObject->ObjectId = CmObjectId;
+  CmObject->Size     = sizeof (CM_ARM_ID_MAPPING);
+  CmObject->Data     = (VOID *)Token;
+  CmObject->Count    = 1;
+  return EFI_SUCCESS;
+}
+
+/**
+  Function pointer called by the parser to add information.
+
+  Callback function that the parser can use to add new
+  CmObj. This function must copy the CmObj data and not rely on
+  the parser preserving the CmObj memory.
+  This function is responsible of the Token allocation.
+
+  @param  [in]  ParserHandle  A handle to the parser instance.
+  @param  [in]  Context       A pointer to the caller's context provided in
+                              HwInfoParserInit ().
+  @param  [in]  CmObjDesc     CM_OBJ_DESCRIPTOR containing the CmObj(s) to add.
+  @param  [out] Token         If provided and success, contain the token
+                              generated for the CmObj.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HwInfoAdd (
+  IN        HW_INFO_PARSER_HANDLE  ParserHandle,
+  IN        VOID                   *Context,
+  IN  CONST CM_OBJ_DESCRIPTOR      *CmObjDesc,
+  OUT       CM_OBJECT_TOKEN        *Token OPTIONAL
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((ParserHandle == NULL)  ||
+      (Context == NULL)       ||
+      (CmObjDesc == NULL))
+  {
+    ASSERT (ParserHandle != NULL);
+    ASSERT (Context != NULL);
+    ASSERT (CmObjDesc != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = (EDKII_PLATFORM_REPOSITORY_INFO *)Context;
+
+  DEBUG_CODE_BEGIN ();
+  //
+  // Print the received objects.
+  //
+  ParseCmObjDesc (CmObjDesc);
+  DEBUG_CODE_END ();
+
+  Status = DynPlatRepoAddObject (
+             PlatformRepo->DynamicPlatformRepo,
+             CmObjDesc,
+             Token
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+/**
+  Cleanup the platform configuration repository.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+
+  @retval EFI_SUCCESS             Success
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CleanupPlatformRepository (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if (This == NULL) {
+    ASSERT (This != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  //
+  // Shutdown the dynamic repo and free all objects.
+  //
+  Status = DynamicPlatRepoShutdown (PlatformRepo->DynamicPlatformRepo);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Shutdown parser.
+  //
+  Status = HwInfoParserShutdown (PlatformRepo->FdtParserHandle);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+/**
+  Initialize the platform configuration repository.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+
+  @retval EFI_SUCCESS             Success
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES    An allocation has failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InitializePlatformRepository (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  VOID                            *Hob;
+
+  if (This == NULL) {
+    ASSERT (This != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Hob = GetFirstGuidHob (&gFdtHobGuid);
+  if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64))) {
+    ASSERT (FALSE);
+    ASSERT (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64));
+    return EFI_NOT_FOUND;
+  }
+
+  PlatformRepo          = This->PlatRepoInfo;
+  PlatformRepo->FdtBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob);
+
+  //
+  // Initialise the dynamic platform repository.
+  //
+  Status = DynamicPlatRepoInit (&PlatformRepo->DynamicPlatformRepo);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Initialise the FDT parser
+  //
+  Status = HwInfoParserInit (
+             PlatformRepo->FdtBase,
+             PlatformRepo,
+             HwInfoAdd,
+             &PlatformRepo->FdtParserHandle
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto ErrorHandler;
+  }
+
+  Status = HwInfoParse (PlatformRepo->FdtParserHandle);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto ErrorHandler;
+  }
+
+  Status = DynamicPlatRepoFinalise (PlatformRepo->DynamicPlatformRepo);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    goto ErrorHandler;
+  }
+
+  return EFI_SUCCESS;
+
+ErrorHandler:
+  CleanupPlatformRepository (This);
+  return Status;
+}
+
+/**
+  Return a standard namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, out] CmObject    Pointer to the Configuration Manager Object
+                               descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetStandardNameSpaceObject (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  UINTN                           AcpiTableCount;
+  CM_OBJ_DESCRIPTOR               CmObjDesc;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status       = EFI_NOT_FOUND;
+  PlatformRepo = This->PlatRepoInfo;
+
+  switch (GET_CM_OBJECT_ID (CmObjectId)) {
+    case EStdObjCfgMgrInfo:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->CmInfo,
+                 sizeof (PlatformRepo->CmInfo),
+                 1,
+                 CmObject
+                 );
+      break;
+
+    case EStdObjAcpiTableList:
+      AcpiTableCount = ARRAY_SIZE (PlatformRepo->CmAcpiTableList);
+
+      //
+      // Get Pci config space information.
+      //
+      Status = DynamicPlatRepoGetObject (
+                 PlatformRepo->DynamicPlatformRepo,
+                 CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo),
+                 CM_NULL_TOKEN,
+                 &CmObjDesc
+                 );
+      if (Status == EFI_NOT_FOUND) {
+        //
+        // The last 3 tables are for PCIe. If PCIe information is not
+        // present, Kvmtool was launched without the PCIe option.
+        // Therefore, reduce the table count by 3.
+        //
+        AcpiTableCount -= 3;
+      } else if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return Status;
+      }
+
+      //
+      // Get the Gic version.
+      //
+      Status = DynamicPlatRepoGetObject (
+                 PlatformRepo->DynamicPlatformRepo,
+                 CREATE_CM_ARM_OBJECT_ID (EArmObjGicDInfo),
+                 CM_NULL_TOKEN,
+                 &CmObjDesc
+                 );
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return Status;
+      }
+
+      if (((CM_ARM_GICD_INFO *)CmObjDesc.Data)->GicVersion < 3) {
+        //
+        // IORT is only required for GicV3/4
+        //
+        AcpiTableCount -= 1;
+      }
+
+      Status = HandleCmObject (
+                 CmObjectId,
+                 PlatformRepo->CmAcpiTableList,
+                 (sizeof (PlatformRepo->CmAcpiTableList[0]) * AcpiTableCount),
+                 AcpiTableCount,
+                 CmObject
+                 );
+      break;
+
+    default:
+      Status = EFI_NOT_FOUND;
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
+        CmObjectId,
+        Status
+        ));
+      break;
+  }
+
+  return Status;
+}
+
+/**
+  Return an ARM namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, out] CmObject    Pointer to the Configuration Manager Object
+                               descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetArmNameSpaceObject (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EFI_STATUS                      Status;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status       = EFI_NOT_FOUND;
+  PlatformRepo = This->PlatRepoInfo;
+
+  //
+  // First check among the static objects.
+  //
+  switch (GET_CM_OBJECT_ID (CmObjectId)) {
+    case EArmObjPowerManagementProfileInfo:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->PmProfileInfo,
+                 sizeof (PlatformRepo->PmProfileInfo),
+                 1,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjItsGroup:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->ItsGroupInfo,
+                 sizeof (PlatformRepo->ItsGroupInfo),
+                 1,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjGicItsIdentifierArray:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->ItsIdentifierArray,
+                 sizeof (PlatformRepo->ItsIdentifierArray),
+                 ARRAY_SIZE (PlatformRepo->ItsIdentifierArray),
+                 Token,
+                 GetItsIdentifierArray,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjRootComplex:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 &PlatformRepo->RootComplexInfo,
+                 sizeof (PlatformRepo->RootComplexInfo),
+                 1,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjIdMappingArray:
+      Status = HandleCmObjectRefByToken (
+                 This,
+                 CmObjectId,
+                 PlatformRepo->DeviceIdMapping,
+                 sizeof (PlatformRepo->DeviceIdMapping),
+                 ARRAY_SIZE (PlatformRepo->DeviceIdMapping),
+                 Token,
+                 GetDeviceIdMappingArray,
+                 CmObject
+                 );
+      break;
+
+    default:
+      //
+      // No match found among the static objects.
+      // Check the dynamic objects.
+      //
+      Status = DynamicPlatRepoGetObject (
+                 PlatformRepo->DynamicPlatformRepo,
+                 CmObjectId,
+                 Token,
+                 CmObject
+                 );
+      break;
+  } // switch
+
+  if (Status == EFI_NOT_FOUND) {
+    DEBUG ((
+      DEBUG_INFO,
+      "INFO: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
+      CmObjectId,
+      Status
+      ));
+  } else {
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+/**
+  Return an OEM namespace object.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, out] CmObject    Pointer to the Configuration Manager Object
+                               descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetOemNameSpaceObject (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (GET_CM_OBJECT_ID (CmObjectId)) {
+    default:
+      Status = EFI_NOT_FOUND;
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
+        CmObjectId,
+        Status
+        ));
+      break;
+  }
+
+  return Status;
+}
+
+/**
+  The GetObject function defines the interface implemented by the
+  Configuration Manager Protocol for returning the Configuration
+  Manager Objects.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in, out] CmObject    Pointer to the Configuration Manager Object
+                               descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+ArmKvmtoolPlatformGetObject (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EFI_STATUS  Status;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (GET_CM_NAMESPACE_ID (CmObjectId)) {
+    case EObjNameSpaceStandard:
+      Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject);
+      break;
+    case EObjNameSpaceArm:
+      Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject);
+      break;
+    case EObjNameSpaceOem:
+      Status = GetOemNameSpaceObject (This, CmObjectId, Token, CmObject);
+      break;
+    default:
+      Status = EFI_INVALID_PARAMETER;
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: Unknown Namespace CmObjectId " FMT_CM_OBJECT_ID ". "
+                                                                "Status = %r\n",
+        CmObjectId,
+        Status
+        ));
+      break;
+  }
+
+  return Status;
+}
+
+/**
+  The SetObject function defines the interface implemented by the
+  Configuration Manager Protocol for updating the Configuration
+  Manager Objects.
+
+  @param [in]      This        Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId  The Configuration Manager Object ID.
+  @param [in]      Token       An optional token identifying the object. If
+                               unused this must be CM_NULL_TOKEN.
+  @param [in]      CmObject    Pointer to the Configuration Manager Object
+                               descriptor describing the Object.
+
+  @retval EFI_UNSUPPORTED  This operation is not supported.
+**/
+EFI_STATUS
+EFIAPI
+ArmKvmtoolPlatformSetObject (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token OPTIONAL,
+  IN        CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+//
+// A structure describing the configuration manager protocol interface.
+//
+STATIC
+CONST
+EDKII_CONFIGURATION_MANAGER_PROTOCOL  mKvmtoolPlatformConfigManagerProtocol = {
+  CREATE_REVISION (1,          0),
+  ArmKvmtoolPlatformGetObject,
+  ArmKvmtoolPlatformSetObject,
+  &mKvmtoolPlatRepositoryInfo
+};
+
+/**
+  Entrypoint of Configuration Manager Dxe.
+
+  @param  ImageHandle
+  @param  SystemTable
+
+  @retval EFI_SUCCESS
+  @retval EFI_LOAD_ERROR
+  @retval EFI_OUT_OF_RESOURCES
+**/
+EFI_STATUS
+EFIAPI
+ConfigurationManagerDxeInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gEdkiiConfigurationManagerProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  (VOID *)&mKvmtoolPlatformConfigManagerProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to get Install Configuration Manager Protocol." \
+      " Status = %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  Status = InitializePlatformRepository (
+             &mKvmtoolPlatformConfigManagerProtocol
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to initialize the Platform Configuration Repository." \
+      " Status = %r\n",
+      Status
+      ));
+    goto ErrorHandler;
+  }
+
+  return Status;
+
+ErrorHandler:
+  gBS->UninstallProtocolInterface (
+         &ImageHandle,
+         &gEdkiiConfigurationManagerProtocolGuid,
+         (VOID *)&mKvmtoolPlatformConfigManagerProtocol
+         );
+  return Status;
+}
+
+/**
+  Unload function for this image.
+
+  @param ImageHandle   Handle for the image of this driver.
+
+  @retval EFI_SUCCESS  Driver unloaded successfully.
+  @retval other        Driver can not unloaded.
+**/
+EFI_STATUS
+EFIAPI
+ConfigurationManagerDxeUnloadImage (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  return CleanupPlatformRepository (&mKvmtoolPlatformConfigManagerProtocol);
+}
diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
new file mode 100644
index 000000000000..3373948bc4eb
--- /dev/null
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
@@ -0,0 +1,125 @@
+/** @file
+
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+**/
+
+#ifndef CONFIGURATION_MANAGER_H_
+#define CONFIGURATION_MANAGER_H_
+
+///
+/// C array containing the compiled AML template.
+/// This symbol is defined in the auto generated C file
+/// containing the AML bytecode array.
+///
+extern CHAR8  dsdt_aml_code[];
+
+///
+/// The configuration manager version.
+///
+#define CONFIGURATION_MANAGER_REVISION  CREATE_REVISION (1, 0)
+
+///
+/// The OEM ID
+///
+#define CFG_MGR_OEM_ID  { 'A', 'R', 'M', 'L', 'T', 'D' }
+
+///
+/// Memory address size limit. Assume the whole address space.
+///
+#define MEMORY_ADDRESS_SIZE_LIMIT  64
+
+/** A function that prepares Configuration Manager Objects for returning.
+
+  @param [in]  This        Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId  The Configuration Manager Object ID.
+  @param [in]  Token       A token for identifying the object.
+  @param [out] CmObject    Pointer to the Configuration Manager Object
+                           descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+typedef EFI_STATUS (*CM_OBJECT_HANDLER_PROC) (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  );
+
+///
+/// A helper macro for mapping a reference token.
+///
+#define REFERENCE_TOKEN(Field)                                     \
+          (CM_OBJECT_TOKEN)((UINT8*)&mKvmtoolPlatRepositoryInfo +  \
+           OFFSET_OF (EDKII_PLATFORM_REPOSITORY_INFO, Field))
+
+///
+/// The number of ACPI tables to install
+///
+#define PLAT_ACPI_TABLE_COUNT  10
+
+///
+/// A structure describing the platform configuration
+/// manager repository information
+///
+typedef struct PlatformRepositoryInfo {
+  ///
+  /// Configuration Manager Information.
+  ///
+  CM_STD_OBJ_CONFIGURATION_MANAGER_INFO    CmInfo;
+
+  ///
+  /// List of ACPI tables
+  ///
+  CM_STD_OBJ_ACPI_TABLE_INFO               CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+
+  ///
+  /// Power management profile information
+  ///
+  CM_ARM_POWER_MANAGEMENT_PROFILE_INFO     PmProfileInfo;
+
+  ///
+  /// ITS Group node
+  ///
+  CM_ARM_ITS_GROUP_NODE                    ItsGroupInfo;
+
+  ///
+  /// ITS Identifier array
+  ///
+  CM_ARM_ITS_IDENTIFIER                    ItsIdentifierArray[1];
+
+  ///
+  /// PCI Root complex node
+  ///
+  CM_ARM_ROOT_COMPLEX_NODE                 RootComplexInfo;
+
+  ///
+  /// Array of DeviceID mapping
+  ///
+  CM_ARM_ID_MAPPING                        DeviceIdMapping[1];
+
+  ///
+  /// Dynamic platform repository.
+  /// CmObj created by parsing the Kvmtool device tree are stored here.
+  ///
+  DYNAMIC_PLATFORM_REPOSITORY_INFO         *DynamicPlatformRepo;
+
+  ///
+  /// Base address of the FDT.
+  ///
+  VOID                                     *FdtBase;
+
+  ///
+  /// A handle to the FDT HwInfoParser.
+  ///
+  HW_INFO_PARSER_HANDLE                    FdtParserHandle;
+} EDKII_PLATFORM_REPOSITORY_INFO;
+
+#endif // CONFIGURATION_MANAGER_H_
diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
new file mode 100644
index 000000000000..a333966a8c96
--- /dev/null
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
@@ -0,0 +1,54 @@
+## @file
+#  Configuration Manager Dxe
+#
+#  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ConfigurationManagerDxe
+  FILE_GUID                      = 3C80D366-510C-4154-BB3A-E12439AD337C
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ConfigurationManagerDxeInitialize
+  UNLOAD_IMAGE                   = ConfigurationManagerDxeUnloadImage
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  AslTables/Dsdt.asl
+  ConfigurationManager.c
+  ConfigurationManager.h
+  ConfigurationManagerDxe.inf
+
+[Packages]
+  ArmVirtPkg/ArmVirtPkg.dec
+  DynamicTablesPkg/DynamicTablesPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  DynamicPlatRepoLib
+  HobLib
+  HwInfoParserLib
+  PrintLib
+  TableHelperLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEdkiiConfigurationManagerProtocolGuid
+
+[Guids]
+  gFdtHobGuid
+
+[Depex]
+  gEdkiiPlatformHasAcpiGuid
-- 
2.25.1


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

* [PATCH v5 8/9] ArmVirtPkg/Kvmtool: Enable ACPI support
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (6 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 7/9] ArmVirtPkg/Kvmtool: Add Configuration Manager PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 17:22 ` [PATCH v5 9/9] ArmVirtPkg/Kvmtool: Enable Acpiview PierreGondois
  2022-02-01 18:04 ` [PATCH v5 0/9] Add ACPI support for Kvmtool Ard Biesheuvel
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Sami Mujawar <sami.mujawar@arm.com>

A Configuration Manager that uses the Dynamic Tables framework
to generate ACPI tables for Kvmtool Guests has been provided.
This Configuration Manager uses the FdtHwInfoParser module to
parse the Kvmtool Device Tree and generate the required
Configuration Manager objects for generating the ACPI tables.

Therefore, enable ACPI table generation for Kvmtool.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3742
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
---

Notes:
    v2:
    - Remove Pcds that are redefined to their default value,
      and modules already included in ArmVirtPkg/ArmVirt.dsc.inc
      [Laszlo]
    - Use guards as '!if $(ARCH) == AARCH64' to conditionnaly
      generate ACPI tables. This allows to prevent the 32bits
      ARM/ACPI combination without restricting the DynamicTablesPkg
      to AARCH64. This means that KvmTool on ARM will use the DT.
      Not adding Laszlo's Acked-by since this is not exactly what
      was suggested. [Laszlo/Pierre]

 ArmVirtPkg/ArmVirtKvmTool.dsc | 17 ++++++++++++++---
 ArmVirtPkg/ArmVirtKvmTool.fdf | 15 ++++++++++++++-
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index 4a54d13735e9..4b6090ab6075 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -29,6 +29,10 @@ [Defines]
 
 !include ArmVirtPkg/ArmVirt.dsc.inc
 
+!if $(ARCH) == AARCH64
+!include DynamicTablesPkg/DynamicTables.dsc.inc
+!endif
+
 !include MdePkg/MdeLibs.dsc.inc
 
 [LibraryClasses.common]
@@ -71,6 +75,9 @@ [LibraryClasses.common]
   PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf
   SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
 
+  HwInfoParserLib|DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
+  DynamicPlatRepoLib|DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf
+
 [LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
   PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
   PlatformHookLib|ArmVirtPkg/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
@@ -195,9 +202,6 @@ [PcdsDynamicDefault.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
   gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
 
-  ## Force DTB
-  gArmVirtTokenSpaceGuid.PcdForceNoAcpi|TRUE
-
   # Setup Flash storage variables
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x40000
@@ -353,3 +357,10 @@ [Components.common]
   }
   OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
   OvmfPkg/Virtio10Dxe/Virtio10.inf
+
+!if $(ARCH) == AARCH64
+  #
+  # ACPI Support
+  #
+  ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
+!endif
diff --git a/ArmVirtPkg/ArmVirtKvmTool.fdf b/ArmVirtPkg/ArmVirtKvmTool.fdf
index 14a5fce43a09..9e006e83ee5c 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.fdf
+++ b/ArmVirtPkg/ArmVirtKvmTool.fdf
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.
+#  Copyright (c) 2018 - 2022, ARM Limited. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -201,6 +201,19 @@ [FV.FvMain]
   INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
   INF OvmfPkg/Virtio10Dxe/Virtio10.inf
 
+!if $(ARCH) == AARCH64
+  #
+  # ACPI Support
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  #
+  # Dynamic Table fdf
+  #
+  !include DynamicTablesPkg/DynamicTables.fdf.inc
+
+  INF ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
+!endif
+
   #
   # TianoCore logo (splash screen)
   #
-- 
2.25.1


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

* [PATCH v5 9/9] ArmVirtPkg/Kvmtool: Enable Acpiview
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (7 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 8/9] ArmVirtPkg/Kvmtool: Enable ACPI support PierreGondois
@ 2022-02-01 17:22 ` PierreGondois
  2022-02-01 18:04 ` [PATCH v5 0/9] Add ACPI support for Kvmtool Ard Biesheuvel
  9 siblings, 0 replies; 11+ messages in thread
From: PierreGondois @ 2022-02-01 17:22 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Sami Mujawar, Rebecca Cran, Pierre Gondois

From: Sami Mujawar <sami.mujawar@arm.com>

Acpiview is a command line tool allowing to display, dump, or check
installed ACPI tables. Add a 'ACPIVIEW_ENABLE' switch to enable it
on an ArmVirt platform.

The switch is set for the ArmVirtKvmTool platform.

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    v2:
    - Only add AcpiView for ArmVirtKvmTool instead of all
      ArmVirt platforms. This is done using a
      'ACPIVIEW_ENABLE' switch. [Laszlo]

 ArmVirtPkg/ArmVirt.dsc.inc    | 5 ++++-
 ArmVirtPkg/ArmVirtKvmTool.dsc | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 4db8ad5a7999..ba711deac025 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+#  Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
 #  Copyright (c) 2014, Linaro Limited. All rights reserved.
 #  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
 #  Copyright (c) Microsoft Corporation.
@@ -397,6 +397,9 @@ [Components.common]
       NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
       NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
       NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+!if $(ACPIVIEW_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+!endif
       NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
       NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
 !if $(NETWORK_IP6_ENABLE) == TRUE
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index 4b6090ab6075..a1bf4b9be87b 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -1,7 +1,7 @@
 #  @file
 #  Workspace file for KVMTool virtual platform.
 #
-#  Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.
+#  Copyright (c) 2018 - 2022, ARM Limited. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -27,6 +27,9 @@ [Defines]
   SKUID_IDENTIFIER               = DEFAULT
   FLASH_DEFINITION               = ArmVirtPkg/ArmVirtKvmTool.fdf
 
+[Defines.AARCH64]
+  DEFINE ACPIVIEW_ENABLE         = TRUE
+
 !include ArmVirtPkg/ArmVirt.dsc.inc
 
 !if $(ARCH) == AARCH64
-- 
2.25.1


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

* Re: [PATCH v5 0/9] Add ACPI support for Kvmtool
  2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
                   ` (8 preceding siblings ...)
  2022-02-01 17:22 ` [PATCH v5 9/9] ArmVirtPkg/Kvmtool: Enable Acpiview PierreGondois
@ 2022-02-01 18:04 ` Ard Biesheuvel
  9 siblings, 0 replies; 11+ messages in thread
From: Ard Biesheuvel @ 2022-02-01 18:04 UTC (permalink / raw)
  To: Pierre; +Cc: edk2-devel-groups-io, Ard Biesheuvel, Sami Mujawar, Rebecca Cran

On Tue, 1 Feb 2022 at 18:23, <Pierre.Gondois@arm.com> wrote:
>
> From: Pierre Gondois <Pierre.Gondois@arm.com>
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3742
> V1: https://edk2.groups.io/g/devel/message/76990
> V2:
> - New patch: "DynamicTablesPkg: Print specifier macro for
>   CM_OBJECT_ID" [Laszlo]
> - Only add AcpiView for ArmVirtKvmTool instead of all ArmVirt
>   platforms. This is done using a 'ACPIVIEW_ENABLE' switch.
>   [Laszlo]
> - Only generate ACPI tables for AARCH64. [Laszlo]
> - Various modifications (error handling, patch organization,
>   coding style, etc). [Laszlo]
> V3:
> - To fix bugs reported by Linux (signaled by Ard):
>   - Add patch to parse and populate PMU information.
>   - Add patch to strictly comply to the first model at ACPI
>     6.4 s6.2.13 to describe PCI legacy interrupts using _PRT.
>   - Add address size limit to IORT PCI root complex.
> V4:
> - Describe PCI legacy interrupts using GSI and remove link
>   device generation. [Pierre]
> - Add more description in ASSERT macros. [Ard]
> V5:
> - Update DSDT revision to 2. [Rebecca]
>
> The changes can be seen at:
> https://github.com/PierreARM/edk2/tree/1456_Add_ACPI_support_for_Kvmtool_v5
> The results of the CI can be seen at:
> https://github.com/tianocore/edk2/pull/2476
>

Merged as #2477

Thanks!

Btw, my patch 'ArmVirtPkg/ArmVirtMemoryInitPeiLib: avoid redundant
cache invalidation' reduces the startup time of the firmware
substantially when running on an actual KVM host.


> The patch depends on the KvmTool patch at:
> https://lists.cs.columbia.edu/pipermail/kvmarm/2022-January/051865.html
>
> Kvmtool dynamically generates a device tree describing the platform
> to boot on. Using the patch-sets listed below, the DynamicTables
> framework generates ACPI tables describing a similar platform.
>
> This patch-set:
>  - adds a ConfigurationManager and make use of the DynamicTablesPkg
>    in for Kvmtool for AARCH64, allowing to generate ACPI tables
>  - adds the acpiview command line utility to the ArmVirtPkg
>    platform that request if via the ACPIVIEW_ENABLE macro
>  - update ArmVirtPkg.ci.yaml to add new words and use the
>    DynamicTablesPkg
>  - adds a print specifier macro for the CM_OBJECT_ID type
>
> With this patchset, KvmTool on AARCH64 will use ACPI tables instead
> of a Device Tree (cf PcdForceNoAcpi Pcd).
>
> Pierre Gondois (5):
>   DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID
>   DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info
>   DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI
>   DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation
>   ArmVirtPkg: Add cspell exceptions
>
> Sami Mujawar (4):
>   ArmVirtPkg/Kvmtool: Add DSDT ACPI table
>   ArmVirtPkg/Kvmtool: Add Configuration Manager
>   ArmVirtPkg/Kvmtool: Enable ACPI support
>   ArmVirtPkg/Kvmtool: Enable Acpiview
>
>  ArmVirtPkg/ArmVirt.dsc.inc                    |    5 +-
>  ArmVirtPkg/ArmVirtKvmTool.dsc                 |   22 +-
>  ArmVirtPkg/ArmVirtKvmTool.fdf                 |   15 +-
>  ArmVirtPkg/ArmVirtPkg.ci.yaml                 |    6 +-
>  .../KvmtoolCfgMgrDxe/AslTables/Dsdt.asl       |   21 +
>  .../KvmtoolCfgMgrDxe/ConfigurationManager.c   | 1065 +++++++++++++++++
>  .../KvmtoolCfgMgrDxe/ConfigurationManager.h   |  125 ++
>  .../ConfigurationManagerDxe.inf               |   54 +
>  .../Include/ConfigurationManagerObject.h      |    7 +-
>  .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.c    |  239 +---
>  .../AcpiSsdtPcieLibArm/SsdtPcieGenerator.h    |   64 +-
>  .../Common/AmlLib/CodeGen/AmlCodeGen.c        |   89 +-
>  .../FdtHwInfoParserLib/Gic/ArmGicCParser.c    |  132 +-
>  .../FdtHwInfoParserLib/Gic/ArmGicCParser.h    |    8 +-
>  14 files changed, 1518 insertions(+), 334 deletions(-)
>  create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/AslTables/Dsdt.asl
>  create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
>  create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
>  create mode 100644 ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManagerDxe.inf
>
> --
> 2.25.1
>

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

end of thread, other threads:[~2022-02-01 18:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-01 17:22 [PATCH v5 0/9] Add ACPI support for Kvmtool PierreGondois
2022-02-01 17:22 ` [PATCH v5 1/9] DynamicTablesPkg: Print specifier macro for CM_OBJECT_ID PierreGondois
2022-02-01 17:22 ` [PATCH v5 2/9] DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info PierreGondois
2022-02-01 17:22 ` [PATCH v5 3/9] DynamicTablesPkg: AmlLib: AmlAddPrtEntry() to handle GSI PierreGondois
2022-02-01 17:22 ` [PATCH v5 4/9] DynamicTablesPkg: AcpiSsdtPcieLibArm: Remove link device generation PierreGondois
2022-02-01 17:22 ` [PATCH v5 5/9] ArmVirtPkg: Add cspell exceptions PierreGondois
2022-02-01 17:22 ` [PATCH v5 6/9] ArmVirtPkg/Kvmtool: Add DSDT ACPI table PierreGondois
2022-02-01 17:22 ` [PATCH v5 7/9] ArmVirtPkg/Kvmtool: Add Configuration Manager PierreGondois
2022-02-01 17:22 ` [PATCH v5 8/9] ArmVirtPkg/Kvmtool: Enable ACPI support PierreGondois
2022-02-01 17:22 ` [PATCH v5 9/9] ArmVirtPkg/Kvmtool: Enable Acpiview PierreGondois
2022-02-01 18:04 ` [PATCH v5 0/9] Add ACPI support for Kvmtool Ard Biesheuvel

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