We can have more than one PCI Express bus. So instead of having static description in DSDT we create SSDT table for each existing PCIe bus.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiew...@linaro.org> --- Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 2 + .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 37 +- .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.h | 23 + .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 87 ++- .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.c | 576 ++++++++++++++++++++ Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl | 302 ---------- .../Drivers/SbsaQemuAcpiDxe/SsdtTemplate.asl | 82 +++ 7 files changed, 790 insertions(+), 319 deletions(-) diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc index e246db8b0a23..b012eaa34147 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc @@ -173,6 +173,8 @@ [LibraryClasses.common] ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf + AcpiHelperLib|DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLib.inf + AmlLib|DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf index 727c8e82d16e..6de1073e6ac2 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf @@ -18,18 +18,25 @@ [Defines] [Sources] SbsaQemuAcpiDxe.c + SbsaQemuAcpiDxe.h + SbsaQemuAcpiPcie.c + SbsaQemuAcpiPcie.h + SsdtTemplate.asl [Packages] ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec ArmVirtPkg/ArmVirtPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec EmbeddedPkg/EmbeddedPkg.dec MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec Silicon/Qemu/SbsaQemu/SbsaQemu.dec [LibraryClasses] + AcpiHelperLib AcpiLib + AmlLib ArmLib BaseMemoryLib BaseLib @@ -37,6 +44,7 @@ [LibraryClasses] DxeServicesLib HardwareInfoLib PcdLib + PciLib PrintLib UefiDriverEntryPoint UefiLib @@ -54,14 +62,39 @@ [Pcd] gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSmmuBase [Depex] - gEfiAcpiTableProtocolGuid ## CONSUMES + # We want all PCIe buses to be scanned first + gEfiPciIoProtocolGuid ## CONSUMES [Guids] gEdkiiPlatformHasAcpiGuid [Protocols] gEfiAcpiSdtProtocolGuid - gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiAcpiTableProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + + +[Pcd] + gArmTokenSpaceGuid.PcdPciBusMin + gArmTokenSpaceGuid.PcdPciBusMax + gArmTokenSpaceGuid.PcdPciIoBase + gArmTokenSpaceGuid.PcdPciIoSize + gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPciIoLimit + + gArmTokenSpaceGuid.PcdPciMmio32Base + gArmTokenSpaceGuid.PcdPciMmio32Size + gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPciMmio32Limit + + gArmTokenSpaceGuid.PcdPciMmio64Base + gArmTokenSpaceGuid.PcdPciMmio64Size + gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPciMmio64Limit + + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPciExpressBarSize + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdPciExpressBarLimit [FixedPcd] gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.h b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.h new file mode 100644 index 000000000000..56cc6f1381da --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.h @@ -0,0 +1,23 @@ +/** @file +* This file is an ACPI driver for the Qemu SBSA platform. +* +* Copyright (c) 2024, Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#ifndef SBSAQEMU_ACPI_PCIE_H +#define SBSAQEMU_ACPI_PCIE_H + +#pragma pack(1) + +/* AML bytecode generated from SsdtTemplate.asl */ +extern CHAR8 ssdttemplate_aml_code[]; + +EFI_STATUS +AddPcieHostBridges ( + AML_OBJECT_NODE_HANDLE ScopeNode + ); + +#endif diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c index 30239e7dca0d..f3d5dc9e9ba7 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c @@ -6,28 +6,27 @@ * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ -#include <IndustryStandard/Acpi.h> -#include <IndustryStandard/AcpiAml.h> #include <IndustryStandard/IoRemappingTable.h> #include <IndustryStandard/SbsaQemuAcpi.h> #include <IndustryStandard/SbsaQemuPlatformVersion.h> + #include <Library/AcpiLib.h> +#include <Library/AmlLib/AmlLib.h> #include <Library/ArmLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/MemoryAllocationLib.h> -#include <Library/PcdLib.h> -#include <Library/PrintLib.h> #include <Library/HardwareInfoLib.h> +#include <Library/PrintLib.h> #include <Library/UefiBootServicesTableLib.h> -#include <Library/UefiDriverEntryPoint.h> -#include <Library/UefiLib.h> + #include <Protocol/AcpiTable.h> +#include <Protocol/PciRootBridgeIo.h> + #include "SbsaQemuAcpiDxe.h" +#include "SbsaQemuAcpiPcie.h" #pragma pack(1) - static UINTN GicItsBase; #pragma pack () @@ -36,7 +35,7 @@ static UINTN GicItsBase; * A Function to Compute the ACPI Table Checksum */ VOID -AcpiPlatformChecksum ( +AcpiTableChecksum ( IN UINT8 *Buffer, IN UINTN Size ) @@ -189,7 +188,7 @@ AddIortTable ( CopyMem (New, &Rc, sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE)); New += sizeof (SBSA_EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -314,7 +313,7 @@ AddMadtTable ( New += sizeof (EFI_ACPI_6_5_GIC_ITS_STRUCTURE); } - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -467,7 +466,7 @@ AddSsdtTable ( } // Perform Checksum - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -572,7 +571,7 @@ AddPpttTable ( } // Perform Checksum - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -667,7 +666,7 @@ AddGtdtTable ( New += sizeof (EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE); // Perform Checksum - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -752,7 +751,7 @@ AddSratTable ( } // Perform Checksum - AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize); + AcpiTableChecksum ((UINT8*) PageAddress, TableSize); Status = AcpiTable->InstallAcpiTable ( AcpiTable, @@ -832,6 +831,58 @@ DisableXhciOnOlderPlatVer ( return Status; } +/** Adds the SSDT ACPI table with PCIe nodes. + + @param AcpiTable The ACPI Table. + + @return EFI_SUCCESS on success, or an error code. + +**/ +STATIC +EFI_STATUS +AddSsdtPcieTable ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable + ) +{ + EFI_STATUS Status; + UINTN TableHandle; + EFI_ACPI_DESCRIPTION_HEADER *Table; + AML_ROOT_NODE_HANDLE RootNode; + AML_OBJECT_NODE_HANDLE ScopeNode; + + Status = AmlCodeGenDefinitionBlock ("SSDT", "LINARO", "SBSAQEMU", 0x1, &RootNode); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT: AmlCodeGenDefinitionBlock failed." + " Status = %r\n", + Status + )); + } + + AmlCodeGenScope ("_SB_", RootNode, &ScopeNode); + + AddPcieHostBridges(ScopeNode); + + // Serialize the tree. + Status = AmlSerializeDefinitionBlock ( + RootNode, + &Table + ); + + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + Table, + Table->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to install SSDT table\n")); + } + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI @@ -895,5 +946,11 @@ InitializeSbsaQemuAcpiDxe ( DEBUG ((DEBUG_ERROR, "Failed to handle XHCI enablement\n")); } + Status = AddSsdtPcieTable (AcpiTable); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to add SSDT table\n")); + } + + return EFI_SUCCESS; } diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.c new file mode 100644 index 000000000000..f5595b8a1baa --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.c @@ -0,0 +1,576 @@ +/** @file +* This file is an ACPI driver for the Qemu SBSA platform. +* +* Copyright (c) 2024, Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <Library/AcpiHelperLib.h> +#include <Library/AmlLib/AmlLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PciHostBridgeLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <Protocol/PciRootBridgeIo.h> + +#include "SbsaQemuAcpiPcie.h" + +#pragma pack(1) + +/** Adds the _OSC method to the PCIe node. + + @param PciNode PCIe device node. + + @return EFI_SUCCESS on success, or an error code. + +**/ +STATIC +EFI_STATUS +AddOscMethod ( + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *SsdtPcieOscTemplate; + AML_ROOT_NODE_HANDLE OscTemplateRoot; + AML_OBJECT_NODE_HANDLE OscNode; + AML_OBJECT_NODE_HANDLE ClonedOscNode; + + ASSERT (PciNode != NULL); + + /* Parse the Ssdt Pci Osc Template. */ + SsdtPcieOscTemplate = (EFI_ACPI_DESCRIPTION_HEADER *) + ssdttemplate_aml_code; + + Status = AmlParseDefinitionBlock ( + SsdtPcieOscTemplate, + &OscTemplateRoot + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI-OSC: Failed to parse SSDT PCI OSC Template." + " Status = %r\n", + Status + )); + return Status; + } + + Status = AmlFindNode (OscTemplateRoot, "\\_OSC", &OscNode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "AmlFindNode: %r\n", Status)); + return Status; + } + + Status = AmlCloneTree (OscNode, &ClonedOscNode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "AmlCloneTree: %r\n", Status)); + return Status; + } + + Status = AmlAttachNode (PciNode, ClonedOscNode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "AmlAttachNode: %r\n", Status)); + // Free the cloned node. + AmlDeleteTree (ClonedOscNode); + return Status; + } + + return Status; +} + +/** Creates a PCI Interrupt Link Device. + + @param PciDeviceHandle PCIe device node. + @param Uid UID of the Link Device. + @param LinkName Name of the Device. + @param Irq IRQ number. + +**/ +STATIC +VOID +GenPciLinkDevice ( + AML_OBJECT_NODE_HANDLE PciDeviceHandle, + UINT32 Uid, + CONST CHAR8 *LinkName, + UINT32 Irq + ) +{ + EFI_STATUS Status; + UINT32 EisaId; + AML_OBJECT_NODE_HANDLE GsiNode; + + AmlCodeGenDevice (LinkName, PciDeviceHandle, &GsiNode); + + Status = AmlGetEisaIdFromString ("PNP0C0F", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return; + } + + AmlCodeGenNameInteger ("_HID", EisaId, GsiNode, NULL); + AmlCodeGenNameInteger ("_UID", Uid, GsiNode, NULL); + + AML_OBJECT_NODE_HANDLE Prs; + + AmlCodeGenNameResourceTemplate ("_PRS", GsiNode, &Prs); + AmlCodeGenRdInterrupt (FALSE, FALSE, FALSE, FALSE, &Irq, 1, Prs, NULL); + AmlCodeGenMethodRetNameString ("_CRS", "_PRS", 0, TRUE, 0, GsiNode, NULL); + AmlCodeGenMethodRetNameString ("_SRS", NULL, 1, FALSE, 0, GsiNode, NULL); + AmlCodeGenMethodRetNameString ("_DIS", NULL, 0, FALSE, 0, GsiNode, NULL); +} + +/** Creates a _PRT package. + + @param PciDeviceHandle PCIe device node. + +**/ +STATIC +VOID +GenPrtEntries ( + AML_OBJECT_NODE_HANDLE PciDeviceHandle + ) +{ + AML_OBJECT_NODE_HANDLE PrtNode; + + AmlCodeGenNamePackage ("_PRT", PciDeviceHandle, &PrtNode); + + AmlAddPrtEntry (0x0000FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0000FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0000FFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x0000FFFF, 0, "GSI3", 0, PrtNode); + + AmlAddPrtEntry (0x0001FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0001FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0001FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0001FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x0002FFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x0002FFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x0002FFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x0002FFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x0003FFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x0003FFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x0003FFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x0003FFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x0004FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0004FFFF, 0, "GSI1", 1, PrtNode); + + AmlAddPrtEntry (0x0004FFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x0004FFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x0005FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0005FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0005FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0005FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x0006FFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x0006FFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x0006FFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x0006FFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x0007FFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x0007FFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x0007FFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x0007FFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x0008FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0008FFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x0008FFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x0008FFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x0009FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0009FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0009FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0009FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x000AFFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x000AFFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x000AFFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x000AFFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x000BFFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x000BFFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x000BFFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x000BFFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x000CFFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x000CFFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x000CFFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x000CFFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x000DFFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x000DFFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x000DFFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x000DFFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x000EFFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x000EFFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x000EFFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x000EFFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x000FFFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x000FFFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x000FFFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x000FFFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x0010FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0010FFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x0010FFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x0010FFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x0011FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0011FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0011FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0011FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x0012FFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x0012FFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x0012FFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x0012FFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x0013FFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x0013FFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x0013FFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x0013FFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x0014FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0014FFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x0014FFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x0014FFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x0015FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0015FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0015FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0015FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x0016FFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x0016FFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x0016FFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x0016FFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x0017FFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x0017FFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x0017FFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x0017FFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x0018FFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x0018FFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x0018FFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x0018FFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x0019FFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x0019FFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x0019FFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x0019FFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x001AFFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x001AFFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x001AFFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x001AFFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x001BFFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x001BFFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x001BFFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x001BFFFF, 0, "GSI2", 3, PrtNode); + + AmlAddPrtEntry (0x001CFFFF, 0, "GSI0", 0, PrtNode); + AmlAddPrtEntry (0x001CFFFF, 0, "GSI1", 1, PrtNode); + AmlAddPrtEntry (0x001CFFFF, 0, "GSI2", 2, PrtNode); + AmlAddPrtEntry (0x001CFFFF, 0, "GSI3", 3, PrtNode); + + AmlAddPrtEntry (0x001DFFFF, 0, "GSI1", 0, PrtNode); + AmlAddPrtEntry (0x001DFFFF, 0, "GSI2", 1, PrtNode); + AmlAddPrtEntry (0x001DFFFF, 0, "GSI3", 2, PrtNode); + AmlAddPrtEntry (0x001DFFFF, 0, "GSI0", 3, PrtNode); + + AmlAddPrtEntry (0x001EFFFF, 0, "GSI2", 0, PrtNode); + AmlAddPrtEntry (0x001EFFFF, 0, "GSI3", 1, PrtNode); + AmlAddPrtEntry (0x001EFFFF, 0, "GSI0", 2, PrtNode); + AmlAddPrtEntry (0x001EFFFF, 0, "GSI1", 3, PrtNode); + + AmlAddPrtEntry (0x001FFFFF, 0, "GSI3", 0, PrtNode); + AmlAddPrtEntry (0x001FFFFF, 0, "GSI0", 1, PrtNode); + AmlAddPrtEntry (0x001FFFFF, 0, "GSI1", 2, PrtNode); + AmlAddPrtEntry (0x001FFFFF, 0, "GSI2", 3, PrtNode); +} + +EFI_STATUS +PciGetProtocolAndResource ( + IN EFI_HANDLE Handle, + OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **IoDev, + OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors + ) +{ + EFI_STATUS Status; + + // + // Get inferface from protocol + // + Status = gBS->HandleProtocol ( + Handle, + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **)IoDev + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Call Configuration() to get address space descriptors + // + Status = (*IoDev)->Configuration (*IoDev, (VOID **)Descriptors); + if (Status == EFI_UNSUPPORTED) { + *Descriptors = NULL; + return EFI_SUCCESS; + } else { + return Status; + } +} + +EFI_STATUS +AddPcieHostBridges ( + AML_OBJECT_NODE_HANDLE ScopeNode + ) +{ + UINTN HandleBufSize; + EFI_HANDLE *HandleBuf; + UINTN HandleCount; + EFI_STATUS Status; + UINTN Index; + + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + AML_OBJECT_NODE_HANDLE PciNode; + AML_OBJECT_NODE_HANDLE ResNode; + AML_OBJECT_NODE_HANDLE RbufRt; + AML_OBJECT_NODE_HANDLE ResRt; + UINT64 PcieDeviceStatus; + UINT32 EisaId; + CHAR8 DeviceName[5]; + + HandleBufSize = sizeof (EFI_HANDLE); + HandleBuf = (EFI_HANDLE *)AllocateZeroPool (HandleBufSize); + if (HandleBuf == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleBufSize, + HandleBuf + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf); + if (HandleBuf == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->LocateHandle ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleBufSize, + HandleBuf + ); + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to locate PciRootBridge\n")); + return EFI_OUT_OF_RESOURCES; + } + + HandleCount = HandleBufSize / sizeof (EFI_HANDLE); + + for (Index = 0; Index < HandleCount; Index++) { + AsciiSPrint (DeviceName, sizeof (DeviceName), "PCI%x", Index); + AmlCodeGenDevice (DeviceName, ScopeNode, &PciNode); + Status = AmlGetEisaIdFromString ("PNP0A08", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + AmlCodeGenNameInteger ("_HID", EisaId, PciNode, NULL); + Status = AmlGetEisaIdFromString ("PNP0A03", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + AmlCodeGenNameInteger ("_CID", EisaId, PciNode, NULL); + AmlCodeGenNameInteger ("_SEG", 0, PciNode, NULL); + AmlCodeGenNameInteger ("_CCA", 1, PciNode, NULL); + AmlCodeGenNameString ("_UID", DeviceName, PciNode, NULL); + + GenPciLinkDevice (PciNode, 0, "GSI0", 0x23); + GenPciLinkDevice (PciNode, 0, "GSI1", 0x24); + GenPciLinkDevice (PciNode, 0, "GSI2", 0x25); + GenPciLinkDevice (PciNode, 0, "GSI3", 0x26); + + GenPrtEntries (PciNode); + AmlCodeGenNameResourceTemplate ("RBUF", PciNode, &RbufRt); + AmlCodeGenMethodRetInteger ("_CBA", PcdGet64 (PcdPciExpressBaseAddress), 0, FALSE, 0, PciNode, NULL); + + Status = PciGetProtocolAndResource ( + HandleBuf[Index], + &IoDev, + &Descriptors + ); + + while ((*Descriptors).Desc != ACPI_END_TAG_DESCRIPTOR) { + if (((*Descriptors).ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) && + ((*Descriptors).AddrSpaceGranularity == 0x20)) + { + AmlCodeGenRdDWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + 1, + TRUE, + 0, + (*Descriptors).AddrRangeMin, + (*Descriptors).AddrRangeMax, + 0, + (*Descriptors).AddrRangeMax - (*Descriptors).AddrRangeMin + 1, + 0, + NULL, + 0, + TRUE, + RbufRt, + NULL + ); + } + + if (((*Descriptors).ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) && + ((*Descriptors).AddrSpaceGranularity == 0x40)) + { + AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + 0, + (*Descriptors).AddrRangeMin, + (*Descriptors).AddrRangeMax, + 0, + (*Descriptors).AddrRangeMax - (*Descriptors).AddrRangeMin + 1, + 0, + NULL, + 0, + TRUE, + RbufRt, + NULL + ); + } + + if ((*Descriptors).ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { + AmlCodeGenRdDWordIo ( + FALSE, + TRUE, + TRUE, + TRUE, + 3, + 0, + (*Descriptors).AddrRangeMin, + (*Descriptors).AddrRangeMax, + 0, + (*Descriptors).AddrRangeMax - (*Descriptors).AddrRangeMin + 1, + 0, + NULL, + FALSE, + TRUE, + RbufRt, + NULL + ); + } + + if ((*Descriptors).ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { + AmlCodeGenNameInteger ("_BBN", (*Descriptors).AddrRangeMin, PciNode, NULL); + AmlCodeGenRdWordBusNumber ( + FALSE, + TRUE, + TRUE, + TRUE, + 0, + (*Descriptors).AddrRangeMin, + (*Descriptors).AddrRangeMax, + 0, + (*Descriptors).AddrRangeMax - (*Descriptors).AddrRangeMin + 1, + 0, + NULL, + RbufRt, + NULL + ); + } + + (Descriptors)++; + } + + DEBUG ((DEBUG_INFO, "\n")); + + AmlCodeGenMethodRetNameString ("_CRS", "RBUF", 0, TRUE, 0, PciNode, NULL); + PcieDeviceStatus = 0xF; // STATUS_PRESENT | STATUS_ENABLED | STATUS_SHOWN_IN_UI | STATUS_FUNCTIONING; + AmlCodeGenMethodRetInteger ("_STA", PcieDeviceStatus, 0, TRUE, 0, PciNode, NULL); + + AmlCodeGenNameInteger ("SUPP", 0, PciNode, NULL); + AmlCodeGenNameInteger ("CTRL", 0, PciNode, NULL); + + AddOscMethod (PciNode); + + if (Index == 0) { + // first node + AmlCodeGenDevice ("RES0", PciNode, &ResNode); + Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT (0); + return Status; + } + + AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL); + + AmlCodeGenNameResourceTemplate ("_CRS", ResNode, &ResRt); + AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, + TRUE, + 0, + PcdGet64 (PcdPciExpressBaseAddress), // Range Minimum + PcdGet64 (PcdPciExpressBarLimit), // Range Maximum + 0x0000000000000000, // Translation Offset + PcdGet64 (PcdPciExpressBarSize), // Length + // Bridge->Mem.Base, + // Bridge->Mem.Limit, + // FixedPcdGet32 (PcdPciMmio32Translation), + // Bridge->Mem.Limit - Bridge->Mem.Base + 1, + 0, + NULL /* ResourceSource */, + 0 /* MemoryRangeType */, + TRUE /* IsTypeStatic */, + ResRt, + NULL + ); + } + } + + return EFI_SUCCESS; +} diff --git a/Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl b/Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl index c134fb66e860..1c8d4fe4f647 100644 --- a/Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl +++ b/Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl @@ -181,307 +181,5 @@ DefinitionBlock ("DsdtTable.aml", "DSDT", } // USB0_RHUB_HUB1 } // USB0_RHUB } // USB0 - - Device (PCI0) - { - Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge - Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge - Name (_SEG, Zero) // PCI Segment Group number - Name (_BBN, Zero) // PCI Base Bus Number - Name (_UID, "PCI0") - Name (_CCA, One) // Initially mark the PCI coherent (for JunoR1) - - Method (_STA) { - Return (0xF) - } - - Method (_CBA, 0, NotSerialized) { - return (FixedPcdGet32 (PcdPciExpressBaseAddress)) - } - - LINK_DEVICE(0, GSI0, 0x23) - LINK_DEVICE(1, GSI1, 0x24) - LINK_DEVICE(2, GSI2, 0x25) - LINK_DEVICE(3, GSI3, 0x26) - - Name (_PRT, Package () // _PRT: PCI Routing Table - { - PRT_ENTRY(0x0000FFFF, 0, GSI0), - PRT_ENTRY(0x0000FFFF, 0, GSI1), - PRT_ENTRY(0x0000FFFF, 0, GSI2), - PRT_ENTRY(0x0000FFFF, 0, GSI3), - - PRT_ENTRY(0x0001FFFF, 0, GSI1), - PRT_ENTRY(0x0001FFFF, 1, GSI2), - PRT_ENTRY(0x0001FFFF, 2, GSI3), - PRT_ENTRY(0x0001FFFF, 3, GSI0), - - PRT_ENTRY(0x0002FFFF, 0, GSI2), - PRT_ENTRY(0x0002FFFF, 1, GSI3), - PRT_ENTRY(0x0002FFFF, 2, GSI0), - PRT_ENTRY(0x0002FFFF, 3, GSI1), - - PRT_ENTRY(0x0003FFFF, 0, GSI3), - PRT_ENTRY(0x0003FFFF, 1, GSI0), - PRT_ENTRY(0x0003FFFF, 2, GSI1), - PRT_ENTRY(0x0003FFFF, 3, GSI2), - - PRT_ENTRY(0x0004FFFF, 0, GSI0), - PRT_ENTRY(0x0004FFFF, 1, GSI1), - PRT_ENTRY(0x0004FFFF, 2, GSI2), - PRT_ENTRY(0x0004FFFF, 3, GSI3), - - PRT_ENTRY(0x0005FFFF, 0, GSI1), - PRT_ENTRY(0x0005FFFF, 1, GSI2), - PRT_ENTRY(0x0005FFFF, 2, GSI3), - PRT_ENTRY(0x0005FFFF, 3, GSI0), - - PRT_ENTRY(0x0006FFFF, 0, GSI2), - PRT_ENTRY(0x0006FFFF, 1, GSI3), - PRT_ENTRY(0x0006FFFF, 2, GSI0), - PRT_ENTRY(0x0006FFFF, 3, GSI1), - - PRT_ENTRY(0x0007FFFF, 0, GSI3), - PRT_ENTRY(0x0007FFFF, 1, GSI0), - PRT_ENTRY(0x0007FFFF, 2, GSI1), - PRT_ENTRY(0x0007FFFF, 3, GSI2), - - PRT_ENTRY(0x0008FFFF, 0, GSI0), - PRT_ENTRY(0x0008FFFF, 1, GSI1), - PRT_ENTRY(0x0008FFFF, 2, GSI2), - PRT_ENTRY(0x0008FFFF, 3, GSI3), - - PRT_ENTRY(0x0009FFFF, 0, GSI1), - PRT_ENTRY(0x0009FFFF, 1, GSI2), - PRT_ENTRY(0x0009FFFF, 2, GSI3), - PRT_ENTRY(0x0009FFFF, 3, GSI0), - - PRT_ENTRY(0x000AFFFF, 0, GSI2), - PRT_ENTRY(0x000AFFFF, 1, GSI3), - PRT_ENTRY(0x000AFFFF, 2, GSI0), - PRT_ENTRY(0x000AFFFF, 3, GSI1), - - PRT_ENTRY(0x000BFFFF, 0, GSI3), - PRT_ENTRY(0x000BFFFF, 1, GSI0), - PRT_ENTRY(0x000BFFFF, 2, GSI1), - PRT_ENTRY(0x000BFFFF, 3, GSI2), - - PRT_ENTRY(0x000CFFFF, 0, GSI0), - PRT_ENTRY(0x000CFFFF, 1, GSI1), - PRT_ENTRY(0x000CFFFF, 2, GSI2), - PRT_ENTRY(0x000CFFFF, 3, GSI3), - - PRT_ENTRY(0x000DFFFF, 0, GSI1), - PRT_ENTRY(0x000DFFFF, 1, GSI2), - PRT_ENTRY(0x000DFFFF, 2, GSI3), - PRT_ENTRY(0x000DFFFF, 3, GSI0), - - PRT_ENTRY(0x000EFFFF, 0, GSI2), - PRT_ENTRY(0x000EFFFF, 1, GSI3), - PRT_ENTRY(0x000EFFFF, 2, GSI0), - PRT_ENTRY(0x000EFFFF, 3, GSI1), - - PRT_ENTRY(0x000FFFFF, 0, GSI3), - PRT_ENTRY(0x000FFFFF, 1, GSI0), - PRT_ENTRY(0x000FFFFF, 2, GSI1), - PRT_ENTRY(0x000FFFFF, 3, GSI2), - - PRT_ENTRY(0x0010FFFF, 0, GSI0), - PRT_ENTRY(0x0010FFFF, 1, GSI1), - PRT_ENTRY(0x0010FFFF, 2, GSI2), - PRT_ENTRY(0x0010FFFF, 3, GSI3), - - PRT_ENTRY(0x0011FFFF, 0, GSI1), - PRT_ENTRY(0x0011FFFF, 1, GSI2), - PRT_ENTRY(0x0011FFFF, 2, GSI3), - PRT_ENTRY(0x0011FFFF, 3, GSI0), - - PRT_ENTRY(0x0012FFFF, 0, GSI2), - PRT_ENTRY(0x0012FFFF, 1, GSI3), - PRT_ENTRY(0x0012FFFF, 2, GSI0), - PRT_ENTRY(0x0012FFFF, 3, GSI1), - - PRT_ENTRY(0x0013FFFF, 0, GSI3), - PRT_ENTRY(0x0013FFFF, 1, GSI0), - PRT_ENTRY(0x0013FFFF, 2, GSI1), - PRT_ENTRY(0x0013FFFF, 3, GSI2), - - PRT_ENTRY(0x0014FFFF, 0, GSI0), - PRT_ENTRY(0x0014FFFF, 1, GSI1), - PRT_ENTRY(0x0014FFFF, 2, GSI2), - PRT_ENTRY(0x0014FFFF, 3, GSI3), - - PRT_ENTRY(0x0015FFFF, 0, GSI1), - PRT_ENTRY(0x0015FFFF, 1, GSI2), - PRT_ENTRY(0x0015FFFF, 2, GSI3), - PRT_ENTRY(0x0015FFFF, 3, GSI0), - - PRT_ENTRY(0x0016FFFF, 0, GSI2), - PRT_ENTRY(0x0016FFFF, 1, GSI3), - PRT_ENTRY(0x0016FFFF, 2, GSI0), - PRT_ENTRY(0x0016FFFF, 3, GSI1), - - PRT_ENTRY(0x0017FFFF, 0, GSI3), - PRT_ENTRY(0x0017FFFF, 1, GSI0), - PRT_ENTRY(0x0017FFFF, 2, GSI1), - PRT_ENTRY(0x0017FFFF, 3, GSI2), - - PRT_ENTRY(0x0018FFFF, 0, GSI0), - PRT_ENTRY(0x0018FFFF, 1, GSI1), - PRT_ENTRY(0x0018FFFF, 2, GSI2), - PRT_ENTRY(0x0018FFFF, 3, GSI3), - - PRT_ENTRY(0x0019FFFF, 0, GSI1), - PRT_ENTRY(0x0019FFFF, 1, GSI2), - PRT_ENTRY(0x0019FFFF, 2, GSI3), - PRT_ENTRY(0x0019FFFF, 3, GSI0), - - PRT_ENTRY(0x001AFFFF, 0, GSI2), - PRT_ENTRY(0x001AFFFF, 1, GSI3), - PRT_ENTRY(0x001AFFFF, 2, GSI0), - PRT_ENTRY(0x001AFFFF, 3, GSI1), - - PRT_ENTRY(0x001BFFFF, 0, GSI3), - PRT_ENTRY(0x001BFFFF, 1, GSI0), - PRT_ENTRY(0x001BFFFF, 2, GSI1), - PRT_ENTRY(0x001BFFFF, 3, GSI2), - - PRT_ENTRY(0x001CFFFF, 0, GSI0), - PRT_ENTRY(0x001CFFFF, 1, GSI1), - PRT_ENTRY(0x001CFFFF, 2, GSI2), - PRT_ENTRY(0x001CFFFF, 3, GSI3), - - PRT_ENTRY(0x001DFFFF, 0, GSI1), - PRT_ENTRY(0x001DFFFF, 1, GSI2), - PRT_ENTRY(0x001DFFFF, 2, GSI3), - PRT_ENTRY(0x001DFFFF, 3, GSI0), - - PRT_ENTRY(0x001EFFFF, 0, GSI2), - PRT_ENTRY(0x001EFFFF, 1, GSI3), - PRT_ENTRY(0x001EFFFF, 2, GSI0), - PRT_ENTRY(0x001EFFFF, 3, GSI1), - - PRT_ENTRY(0x001FFFFF, 0, GSI3), - PRT_ENTRY(0x001FFFFF, 1, GSI0), - PRT_ENTRY(0x001FFFFF, 2, GSI1), - PRT_ENTRY(0x001FFFFF, 3, GSI2), - }) - - // Root complex resources - Name (_CRS, ResourceTemplate () { - WordBusNumber ( // Bus numbers assigned to this root - ResourceProducer, - MinFixed, MaxFixed, PosDecode, - 0, // AddressGranularity - FixedPcdGet32 (PcdPciBusMin), // AddressMinimum - Minimum Bus Number - FixedPcdGet32 (PcdPciBusMax), // AddressMaximum - Maximum Bus Number - 0, // AddressTranslation - Set to 0 - 256 // RangeLength - Number of Busses - ) - - DWordMemory ( // 32-bit BAR Windows - ResourceProducer, PosDecode, - MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x00000000, // Granularity - FixedPcdGet32 (PcdPciMmio32Base), // Min Base Address - FixedPcdGet32 (PcdPciMmio32Limit), // Max Base Address - FixedPcdGet32 (PcdPciMmio32Translation), // Translate - FixedPcdGet32 (PcdPciMmio32Size) // Length - ) - - QWordMemory ( // 64-bit BAR Windows - ResourceProducer, PosDecode, - MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x00000000, // Granularity - FixedPcdGet64 (PcdPciMmio64Base), // Min Base Address - FixedPcdGet64 (PcdPciMmio64Limit), // Max Base Address - FixedPcdGet64 (PcdPciMmio64Translation), // Translate - FixedPcdGet64 (PcdPciMmio64Size) // Length - ) - - DWordIo ( // IO window - ResourceProducer, - MinFixed, - MaxFixed, - PosDecode, - EntireRange, - 0x00000000, // Granularity - FixedPcdGet32 (PcdPciIoBase), // Min Base Address - FixedPcdGet32 (PcdPciIoLimit), // Max Base Address - FixedPcdGet32 (PcdPciIoTranslation), // Translate - FixedPcdGet32 (PcdPciIoSize), // Length - ,,,TypeTranslation - ) - }) // Name(_CRS) - - Device (RES0) - { - Name (_HID, "PNP0C02" /* PNP Motherboard Resources */) // _HID: Hardware ID - Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings - { - QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, - 0x0000000000000000, // Granularity - FixedPcdGet64 (PcdPciExpressBaseAddress), // Range Minimum - FixedPcdGet64 (PcdPciExpressBarLimit), // Range Maximum - 0x0000000000000000, // Translation Offset - FixedPcdGet64 (PcdPciExpressBarSize), // Length - ,, , AddressRangeMemory, TypeStatic) - }) - Method (_STA) { - Return (0xF) - } - } - - // OS Control Handoff - Name (SUPP, Zero) // PCI _OSC Support Field value - Name (CTRL, Zero) // PCI _OSC Control Field value - - /* - * See [1] 6.2.10, [2] 4.5 - */ - Method (_OSC,4) { - // Check for proper UUID - If (Arg0 == ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")) { - // Create DWord-adressable fields from the Capabilities Buffer - CreateDWordField (Arg3,0,CDW1) - CreateDWordField (Arg3,4,CDW2) - CreateDWordField (Arg3,8,CDW3) - - // Save Capabilities DWord2 & 3 - Store (CDW2,SUPP) - Store (CDW3,CTRL) - - // Only allow native hot plug control if OS supports: - // * ASPM - // * Clock PM - // * MSI/MSI-X - If ((SUPP & 0x16) != 0x16) { - CTRL &= 0x1E // Mask bit 0 (and undefined bits) - } - - // Always allow native PME, AER (no dependencies) - - // Never allow SHPC (no SHPC controller in this system) - CTRL &= 0x1D - - If (Arg1 != One) { // Unknown revision - CDW1 |= 0x08 - } - - If (CDW3 != CTRL) { // Capabilities bits were masked - CDW1 |= 0x10 - } - - // Update DWORD3 in the buffer - Store (CTRL,CDW3) - Return (Arg3) - } Else { - CDW1 |= 4 // Unrecognized UUID - Return (Arg3) - } - } // End _OSC - } } // Scope (_SB) } diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SsdtTemplate.asl b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SsdtTemplate.asl new file mode 100644 index 000000000000..2fcdb607d173 --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SsdtTemplate.asl @@ -0,0 +1,82 @@ +/** @file +* Differentiated System Description Table Fields (DSDT). +* +* Copyright (c) 2024, Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <IndustryStandard/Acpi63.h> +#include <IndustryStandard/SbsaQemuAcpi.h> + +#define LINK_DEVICE(Uid, LinkName, Irq) \ + Device (LinkName) { \ + Name (_HID, EISAID("PNP0C0F")) \ + Name (_UID, Uid) \ + Name (_PRS, ResourceTemplate() { \ + Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { Irq } \ + }) \ + Method (_CRS, 0) { Return (_PRS) } \ + Method (_SRS, 1) { } \ + Method (_DIS) { } \ + } + +#define PRT_ENTRY(Address, Pin, Link) \ + Package (4) { \ + Address, Pin, Link, Zero \ + } + +DefinitionBlock ("Dsdt.aml", "DSDT", + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION, + "LINARO", "SBSAQEMU", FixedPcdGet32 (PcdAcpiDefaultOemRevision)) { + /* + * See [1] 6.2.10, [2] 4.5 + */ + Name (SUPP, Zero) // PCI _OSC Support Field value + Name (CTRL, Zero) // PCI _OSC Control Field value + Method (_OSC, 4, Serialized) { + // + // OS Control Handoff + // + + // Check for proper UUID + If (Arg0 == ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")) { + // Create DWord-adressable fields from the Capabilities Buffer + CreateDWordField (Arg3,0,CDW1) + CreateDWordField (Arg3,4,CDW2) + CreateDWordField (Arg3,8,CDW3) + + // Save Capabilities DWord2 & 3 + Store (CDW2,SUPP) + Store (CDW3,CTRL) + + // Only allow native hot plug control if OS supports: + // * ASPM + // * Clock PM + // * MSI/MSI-X + If ((SUPP & 0x16) != 0x16) { + CTRL |= 0x1E // Mask bit 0 (and undefined bits) + } + + // Always allow native PME, AER (no dependencies) + + // Never allow SHPC (no SHPC controller in this system) + CTRL &= 0x1D + + If (Arg1 != One) { // Unknown revision + CDW1 |= 0x08 + } + + If (CDW3 != CTRL) { // Capabilities bits were masked + CDW1 |= 0x10 + } + + // Update DWORD3 in the buffer + Store (CTRL,CDW3) + Return (Arg3) + } Else { + CDW1 |= 4 // Unrecognized UUID + Return (Arg3) + } + } // End _OSC +} -- 2.44.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118290): https://edk2.groups.io/g/devel/message/118290 Mute This Topic: https://groups.io/mt/105728626/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-