[edk2-devel] [PATCH v5 2/9] DynamicTablesPkg: FdtHwInfoParserLib: Parse Pmu info

PierreGondois pierre.gondois at arm.com
Tue Feb 1 17:22:45 UTC 2022


From: Pierre Gondois <Pierre.Gondois at 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 at 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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#86305): https://edk2.groups.io/g/devel/message/86305
Mute This Topic: https://groups.io/mt/88838055/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list