From: Pierre Gondois <pierre.gond...@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+tianoc...@kernel.org>
Signed-off-by: Pierre Gondois <pierre.gond...@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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#86283): https://edk2.groups.io/g/devel/message/86283
Mute This Topic: https://groups.io/mt/88837037/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to