diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c index 3e22587d4a..a34018151f 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.
+ Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
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 @@ -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 () { - Name (_UID, ]) - Name (_HID, EISAID ("PNP0C0F")) - Name (CRS0, ResourceTemplate () { - Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { ] } - }) - 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, ) - 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) { } - // }) - 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 d1e5465e13..59a0d601a3 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()