* [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses
@ 2024-05-28 10:31 Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 1/3] SbsaQemu: scan for PCIe buses Marcin Juszkiewicz
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Marcin Juszkiewicz @ 2024-05-28 10:31 UTC (permalink / raw)
To: devel
Cc: Leif Lindholm, Ard Biesheuvel, Graeme Gregory, Ray Ni,
Marcin Juszkiewicz
QEMU allows to have NUMA setup where each node has own cpus, memory and
i/o. We already handle cpus and memory. This patchset adds support for
having multiple PCI Express buses.
SbsaQemu assumed that there is only bus 0. First patch does PCIe bus
scan to find all host bridges (bus 0 one and additional 'pxb-pcie'
ones).
Second patch moves description of PCIe from DSDT to SSDT (one per each
PCIe bus). So Operating System will know about all of them.
Third patch moves generation of MCFG table to C. It is preparation to
move PCIe Pcds from being fixed to dynamic ones.
There are some booting issues with assigning resources for cards:
pci 0000:00:03.0: BAR 15: no space for [mem size 0x00200000 64bit pref]
pci 0000:00:03.0: BAR 15: failed to assign [mem size 0x00200000 64bit pref]
pci 0000:00:01.0: BAR 6: no space for [mem size 0x00040000 pref]
pci 0000:00:01.0: BAR 6: failed to assign [mem size 0x00040000 pref]
pci 0000:00:03.0: BAR 13: no space for [io size 0x1000]
pci 0000:00:03.0: BAR 13: failed to assign [io size 0x1000]
Boot log (Linux + lspci + ACPI tables dump):
https://people.linaro.org/~marcin.juszkiewicz/sbsa-ref/boot-linux-with-numa-multiple-pcie-buses.txt
I am wondering where I made mistakes in handling PCIe buses.
Thanks go to Leif for pointing me to use of Aml to generate SSDT tables.
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Graeme Gregory <graeme@xora.org.uk>
Cc: Ray Ni <ray.ni@intel.com>
To: devel@edk2.groups.io
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
Changes in v2:
- Dropped [WIP] status
- Link to v1: https://openfw.io/edk2-devel/20240425-review-multiple-pcie-0425-v1-0-68fdfd781f9e@linaro.org/
---
Marcin Juszkiewicz (3):
SbsaQemu: scan for PCIe buses
SbsaQemu: describe PCIe buses in SSDT tables
SbsaQemu: generate MCFG table
Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 2 +
Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf | 1 -
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 37 +-
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.h | 23 +
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 170 +++++-
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiPcie.c | 576 ++++++++++++++++++++
.../SbsaQemuPciHostBridgeLib.c | 185 ++++---
Silicon/Qemu/SbsaQemu/AcpiTables/Dsdt.asl | 302 ----------
Silicon/Qemu/SbsaQemu/AcpiTables/Mcfg.aslc | 43 --
.../Drivers/SbsaQemuAcpiDxe/SsdtTemplate.asl | 82 +++
10 files changed, 982 insertions(+), 439 deletions(-)
---
base-commit: 4bbd0ed440322e49edffdebe15e12aa76916d1b0
change-id: 20240425-review-multiple-pcie-0425-54ce3817fd3f
Best regards,
--
Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119300): https://edk2.groups.io/g/devel/message/119300
Mute This Topic: https://groups.io/mt/106345969/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH edk2-platforms v2 1/3] SbsaQemu: scan for PCIe buses
2024-05-28 10:31 [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Marcin Juszkiewicz
@ 2024-05-28 10:31 ` Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 2/3] SbsaQemu: describe PCIe buses in SSDT tables Marcin Juszkiewicz
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Marcin Juszkiewicz @ 2024-05-28 10:31 UTC (permalink / raw)
To: devel
Cc: Leif Lindholm, Ard Biesheuvel, Graeme Gregory, Ray Ni,
Marcin Juszkiewicz
SbsaQemu assumes that there is only one PCI Express bus. But there can
be multiple PCIe buses as NUMA systems can get 'pxb-pcie' HostBridge
devices added.
Let scan for all PCIe buses and report them back so EDK2 will be able to
find all expansions.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
.../SbsaQemuPciHostBridgeLib.c | 185 ++++++++++++--------
1 file changed, 109 insertions(+), 76 deletions(-)
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuPciHostBridgeLib/SbsaQemuPciHostBridgeLib.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuPciHostBridgeLib/SbsaQemuPciHostBridgeLib.c
index 9739c7500def..1c4ed1c74e52 100644
--- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuPciHostBridgeLib/SbsaQemuPciHostBridgeLib.c
+++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuPciHostBridgeLib/SbsaQemuPciHostBridgeLib.c
@@ -6,10 +6,14 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+#include <limits.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <PiDxe.h>
@@ -52,76 +56,49 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
L"Mem", L"I/O", L"Bus"
};
-STATIC PCI_ROOT_BRIDGE mRootBridge = {
- /* UINT32 Segment; Segment number */
- 0,
-
- /* UINT64 Supports; Supported attributes */
- EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
- EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16,
-
- /* UINT64 Attributes; Initial attributes */
- EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
- EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16,
-
- /* BOOLEAN DmaAbove4G; DMA above 4GB memory */
- TRUE,
-
- /* BOOLEAN NoExtendedConfigSpace; When FALSE, the root bridge supports
- Extended (4096-byte) Configuration Space. When TRUE, the root bridge
- supports 256-byte Configuration Space only. */
- FALSE,
-
- /* BOOLEAN ResourceAssigned; Resource assignment status of the root bridge.
- Set to TRUE if Bus/IO/MMIO resources for root bridge have been assigned */
- FALSE,
-
- /* UINT64 AllocationAttributes; Allocation attributes. */
- EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
- EFI_PCI_HOST_BRIDGE_MEM64_DECODE, /* as Mmio64Size > 0 */
-
- {
- /* PCI_ROOT_BRIDGE_APERTURE Bus; Bus aperture which can be used by the
- * root bridge. */
- FixedPcdGet32 (PcdPciBusMin),
- FixedPcdGet32 (PcdPciBusMax)
- },
-
- /* PCI_ROOT_BRIDGE_APERTURE Io; IO aperture which can be used by the root
- bridge */
- {
- FixedPcdGet64 (PcdPciIoBase),
- FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
- },
-
- /* PCI_ROOT_BRIDGE_APERTURE Mem; MMIO aperture below 4GB which can be used by
- the root bridge
- (gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation as 0x0) */
- {
- FixedPcdGet32 (PcdPciMmio32Base),
- FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1,
- },
-
- /* PCI_ROOT_BRIDGE_APERTURE MemAbove4G; MMIO aperture above 4GB which can be
- used by the root bridge.
- (gEfiMdePkgTokenSpaceGuid.PcdPciMmio64Translation as 0x0) */
- {
- FixedPcdGet64 (PcdPciMmio64Base),
- FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
- },
-
- /* PCI_ROOT_BRIDGE_APERTURE PMem; Prefetchable MMIO aperture below 4GB which
- can be used by the root bridge.
- In our case, there are no separate ranges for prefetchable and
- non-prefetchable BARs */
- { MAX_UINT64, 0 },
-
- /* PCI_ROOT_BRIDGE_APERTURE PMemAbove4G; Prefetchable MMIO aperture above 4GB
- which can be used by the root bridge. */
- { MAX_UINT64, 0 },
- /* EFI_DEVICE_PATH_PROTOCOL *DevicePath; Device path. */
- (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath,
-};
+EFI_STATUS
+EFIAPI
+PciHostBridgeUtilityInitRootBridge (
+ IN UINTN RootBusNumber,
+ OUT PCI_ROOT_BRIDGE *RootBus
+ )
+{
+ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
+ UINTN MaxSubBusNumber = 255;
+
+ DevicePath = AllocateCopyPool (
+ sizeof mEfiPciRootBridgeDevicePath,
+ &mEfiPciRootBridgeDevicePath
+ );
+ if (DevicePath == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __func__, EFI_OUT_OF_RESOURCES));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DevicePath->AcpiDevicePath.UID = RootBusNumber;
+
+ RootBus->Segment = 0;
+ RootBus->Supports = 0;
+ RootBus->Attributes = 0;
+ RootBus->DmaAbove4G = TRUE;
+ RootBus->AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE, /* as Mmio64Size > 0 */
+ RootBus->Bus.Base = RootBusNumber;
+ RootBus->Bus.Limit = MaxSubBusNumber;
+ RootBus->Io.Base = PcdGet64 (PcdPciIoBase);
+ RootBus->Io.Limit = PcdGet64 (PcdPciIoBase) + PcdGet64 (PcdPciIoSize) - 1;
+ RootBus->Mem.Base = PcdGet32 (PcdPciMmio32Base);
+ RootBus->Mem.Limit = PcdGet32 (PcdPciMmio32Base) + PcdGet32 (PcdPciMmio32Size) - 1;
+ RootBus->MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
+ RootBus->MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) + PcdGet64 (PcdPciMmio64Size) - 1;
+ RootBus->PMem.Base = MAX_UINT64;
+ RootBus->PMem.Limit = 0;
+ RootBus->PMemAbove4G.Base = MAX_UINT64;
+ RootBus->PMemAbove4G.Limit = 0;
+ RootBus->NoExtendedConfigSpace = FALSE;
+ RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+
+ return EFI_SUCCESS;
+}
/**
Return all the root bridge instances in an array.
@@ -135,11 +112,67 @@ STATIC PCI_ROOT_BRIDGE mRootBridge = {
PCI_ROOT_BRIDGE *
EFIAPI
PciHostBridgeGetRootBridges (
- UINTN *Count
+ UINTN *Count
)
{
- *Count = 1;
- return &mRootBridge;
+ PCI_ROOT_BRIDGE *Bridges;
+ int BusId, BusMin = 0, BusMax = 255, Index = 0;
+ int AvailableBusses[255] = { INT_MAX }; // INT_MAX as "there is no bus"
+
+ *Count = 0;
+
+ //
+ // Scan all root buses. If function 0 of any device on a bus returns a
+ // VendorId register value different from all-bits-one, then that bus is
+ // alive.
+ //
+ for (BusId = BusMin; BusId <= BusMax; ++BusId) {
+ UINTN Device;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
+ if (PciRead16 (
+ PCI_LIB_ADDRESS (
+ BusId,
+ Device,
+ 0,
+ PCI_VENDOR_ID_OFFSET
+ )
+ ) != MAX_UINT16)
+ {
+ break;
+ }
+ }
+
+ if (Device <= PCI_MAX_DEVICE) {
+ DEBUG ((DEBUG_ERROR, "%a: found bus: 0x%02x\n", __func__, BusId));
+ AvailableBusses[Index++] = BusId;
+ *Count += 1;
+ }
+ }
+
+ //
+ // Allocate the "main" root bridge, and any extra root bridges.
+ //
+ Bridges = AllocateZeroPool (*Count * sizeof *Bridges);
+ if (Bridges == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __func__, EFI_OUT_OF_RESOURCES));
+ return NULL;
+ }
+
+ for (Index = 0; Index < *Count; Index++) {
+ if (AvailableBusses[Index] == INT_MAX) {
+ break;
+ }
+
+ PciHostBridgeUtilityInitRootBridge (AvailableBusses[Index], &Bridges[Index]);
+
+ // limit previous RootBridge bus range
+ if (Index > 0) {
+ Bridges[Index - 1].Bus.Limit = AvailableBusses[Index] - 1;
+ }
+ }
+
+ return Bridges;
}
/**
@@ -152,11 +185,11 @@ PciHostBridgeGetRootBridges (
VOID
EFIAPI
PciHostBridgeFreeRootBridges (
- PCI_ROOT_BRIDGE *Bridges,
- UINTN Count
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
)
{
- ASSERT (Count == 1);
+ FreePool (Bridges);
}
/**
--
2.45.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119301): https://edk2.groups.io/g/devel/message/119301
Mute This Topic: https://groups.io/mt/106345970/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH edk2-platforms v2 2/3] SbsaQemu: describe PCIe buses in SSDT tables
2024-05-28 10:31 [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 1/3] SbsaQemu: scan for PCIe buses Marcin Juszkiewicz
@ 2024-05-28 10:31 ` Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 3/3] SbsaQemu: generate MCFG table Marcin Juszkiewicz
2024-05-28 14:31 ` [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Ard Biesheuvel
3 siblings, 0 replies; 7+ messages in thread
From: Marcin Juszkiewicz @ 2024-05-28 10:31 UTC (permalink / raw)
To: devel
Cc: Leif Lindholm, Ard Biesheuvel, Graeme Gregory, Ray Ni,
Marcin Juszkiewicz
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.juszkiewicz@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.45.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119302): https://edk2.groups.io/g/devel/message/119302
Mute This Topic: https://groups.io/mt/106345971/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH edk2-platforms v2 3/3] SbsaQemu: generate MCFG table
2024-05-28 10:31 [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 1/3] SbsaQemu: scan for PCIe buses Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 2/3] SbsaQemu: describe PCIe buses in SSDT tables Marcin Juszkiewicz
@ 2024-05-28 10:31 ` Marcin Juszkiewicz
2024-05-28 14:31 ` [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Ard Biesheuvel
3 siblings, 0 replies; 7+ messages in thread
From: Marcin Juszkiewicz @ 2024-05-28 10:31 UTC (permalink / raw)
To: devel
Cc: Leif Lindholm, Ard Biesheuvel, Graeme Gregory, Ray Ni,
Marcin Juszkiewicz
We want to have dynaminc PCI Express variables. Which forces us to
generate MCFG from C code.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf | 1 -
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 83 ++++++++++++++++++++
Silicon/Qemu/SbsaQemu/AcpiTables/Mcfg.aslc | 43 ----------
3 files changed, 83 insertions(+), 44 deletions(-)
diff --git a/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf b/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf
index 8d4905362edc..37abf2f4c512 100644
--- a/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf
+++ b/Silicon/Qemu/SbsaQemu/AcpiTables/AcpiTables.inf
@@ -19,7 +19,6 @@ [Sources]
Dbg2.aslc
Dsdt.asl
Fadt.aslc
- Mcfg.aslc
Spcr.aslc
[Packages]
diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
index f3d5dc9e9ba7..6c7913eead81 100644
--- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
+++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
@@ -7,6 +7,7 @@
*
**/
#include <IndustryStandard/IoRemappingTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
#include <IndustryStandard/SbsaQemuAcpi.h>
#include <IndustryStandard/SbsaQemuPlatformVersion.h>
@@ -883,6 +884,83 @@ AddSsdtPcieTable (
return EFI_SUCCESS;
}
+/** Adds the MCFG ACPI table.
+
+ @param AcpiTable The ACPI Table.
+ @param PcieCfgData PCIe configuration data.
+ @param NumPcieSegments Number of PCIe segments.
+
+ @return EFI_SUCCESS on success, or an error code.
+
+**/
+STATIC
+EFI_STATUS
+AddMcfgTable (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN TableHandle;
+ UINT32 TableSize;
+ EFI_PHYSICAL_ADDRESS PageAddress;
+ UINT8 *New;
+
+ EFI_ACPI_DESCRIPTION_HEADER Header =
+ SBSAQEMU_ACPI_HEADER (
+ EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_DESCRIPTION_HEADER,
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION
+ );
+
+ TableSize = sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
+ sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE);
+
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIReclaimMemory,
+ EFI_SIZE_TO_PAGES (TableSize),
+ &PageAddress
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to allocate pages for MCFG table\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ New = (UINT8 *)(UINTN)PageAddress;
+ ZeroMem (New, TableSize);
+
+ // Add the ACPI Description table header
+ CopyMem (New, &Header, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
+ ((EFI_ACPI_DESCRIPTION_HEADER *)New)->Length = TableSize;
+ New += sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER);
+
+ EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *CfgPtr;
+
+ CfgPtr = (VOID *)New;
+
+ CfgPtr->BaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+ CfgPtr->PciSegmentGroupNumber = 0;
+ CfgPtr->StartBusNumber = PcdGet32 (PcdPciBusMin);
+ CfgPtr->EndBusNumber = PcdGet32 (PcdPciBusMax);
+
+ New += sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE);
+
+ // Perform Checksum
+ AcpiTableChecksum ((UINT8 *)PageAddress, TableSize);
+
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ (EFI_ACPI_COMMON_HEADER *)PageAddress,
+ TableSize,
+ &TableHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to install MCFG table\n"));
+ }
+
+ return Status;
+}
+
EFI_STATUS
EFIAPI
@@ -951,6 +1029,11 @@ InitializeSbsaQemuAcpiDxe (
DEBUG ((DEBUG_ERROR, "Failed to add SSDT table\n"));
}
+ Status = AddMcfgTable (AcpiTable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to add MCFG table\n"));
+ }
+
return EFI_SUCCESS;
}
diff --git a/Silicon/Qemu/SbsaQemu/AcpiTables/Mcfg.aslc b/Silicon/Qemu/SbsaQemu/AcpiTables/Mcfg.aslc
deleted file mode 100644
index 289f4ad4ea3a..000000000000
--- a/Silicon/Qemu/SbsaQemu/AcpiTables/Mcfg.aslc
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @file
-* ACPI Memory mapped configuration space base address Description Table (MCFG).
-*
-* Copyright (c) 2020, Linaro Limited. All rights reserved.
-*
-* SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
-#include <IndustryStandard/SbsaQemuAcpi.h>
-
-#pragma pack(push, 1)
-
-typedef struct {
- EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER Header;
- EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Structure[1];
-} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE;
-
-EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE Mcfg = {
- {
- SBSAQEMU_ACPI_HEADER (
- EFI_ACPI_6_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE,
- EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION),
- EFI_ACPI_RESERVED_QWORD
- },
- {
- {
- FixedPcdGet32 (PcdPciExpressBaseAddress),
- 0,
- FixedPcdGet32 (PcdPciBusMin),
- FixedPcdGet32 (PcdPciBusMax),
- EFI_ACPI_RESERVED_DWORD
- }
- }
-};
-
-#pragma pack(pop)
-
-// Reference the table being generated to prevent the optimizer
-// from removing the data structure from the executable
-VOID* CONST ReferenceAcpiTable = &Mcfg;
--
2.45.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119303): https://edk2.groups.io/g/devel/message/119303
Mute This Topic: https://groups.io/mt/106345972/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses
2024-05-28 10:31 [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Marcin Juszkiewicz
` (2 preceding siblings ...)
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 3/3] SbsaQemu: generate MCFG table Marcin Juszkiewicz
@ 2024-05-28 14:31 ` Ard Biesheuvel
2024-06-04 7:23 ` Marcin Juszkiewicz
3 siblings, 1 reply; 7+ messages in thread
From: Ard Biesheuvel @ 2024-05-28 14:31 UTC (permalink / raw)
To: devel, marcin.juszkiewicz; +Cc: Leif Lindholm, Graeme Gregory, Ray Ni
On Tue, 28 May 2024 at 12:31, Marcin Juszkiewicz
<marcin.juszkiewicz@linaro.org> wrote:
>
> QEMU allows to have NUMA setup where each node has own cpus, memory and
> i/o. We already handle cpus and memory. This patchset adds support for
> having multiple PCI Express buses.
>
> SbsaQemu assumed that there is only bus 0. First patch does PCIe bus
> scan to find all host bridges (bus 0 one and additional 'pxb-pcie'
> ones).
>
> Second patch moves description of PCIe from DSDT to SSDT (one per each
> PCIe bus). So Operating System will know about all of them.
>
> Third patch moves generation of MCFG table to C. It is preparation to
> move PCIe Pcds from being fixed to dynamic ones.
>
> There are some booting issues with assigning resources for cards:
>
> pci 0000:00:03.0: BAR 15: no space for [mem size 0x00200000 64bit pref]
> pci 0000:00:03.0: BAR 15: failed to assign [mem size 0x00200000 64bit pref]
> pci 0000:00:01.0: BAR 6: no space for [mem size 0x00040000 pref]
> pci 0000:00:01.0: BAR 6: failed to assign [mem size 0x00040000 pref]
> pci 0000:00:03.0: BAR 13: no space for [io size 0x1000]
> pci 0000:00:03.0: BAR 13: failed to assign [io size 0x1000]
>
> Boot log (Linux + lspci + ACPI tables dump):
> https://people.linaro.org/~marcin.juszkiewicz/sbsa-ref/boot-linux-with-numa-multiple-pcie-buses.txt
>
> I am wondering where I made mistakes in handling PCIe buses.
>
I would expect each host bridge to have its own separate resource
windows for config space, buses and MMIO regions.
So each host bridge gets a different segment number, and each segment
is associated with a different ECAM region. That also means the bus
range can start at 0x0 for each segment, as they are completely
disjoint.
This is a more accurate representation of the physical topology, given
that each host bridge has its own link to the CPU side interconnect,
and so things like peer-to-peer DMA between endpoints does not
generally work unless the endpoints share a segment, especially in the
presence of SMMUs.
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119308): https://edk2.groups.io/g/devel/message/119308
Mute This Topic: https://groups.io/mt/106345969/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses
2024-05-28 14:31 ` [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Ard Biesheuvel
@ 2024-06-04 7:23 ` Marcin Juszkiewicz
2024-06-04 12:06 ` Gerd Hoffmann
0 siblings, 1 reply; 7+ messages in thread
From: Marcin Juszkiewicz @ 2024-06-04 7:23 UTC (permalink / raw)
To: Ard Biesheuvel, devel; +Cc: Leif Lindholm, Graeme Gregory, Ray Ni
W dniu 28.05.2024 o 16:31, Ard Biesheuvel pisze:
> I would expect each host bridge to have its own separate resource
> windows for config space, buses and MMIO regions.
>
> So each host bridge gets a different segment number, and each segment
> is associated with a different ECAM region. That also means the bus
> range can start at 0x0 for each segment, as they are completely
> disjoint.
>
> This is a more accurate representation of the physical topology, given
> that each host bridge has its own link to the CPU side interconnect,
> and so things like peer-to-peer DMA between endpoints does not
> generally work unless the endpoints share a segment, especially in the
> presence of SMMUs.
OK. I have to admit that I never checked how physical NUMA system
handles PCI Express. The code in patches was done by comparing with
other QEMU targets.
To make PCIe in a way you describe we probably need to go to QEMU devel
ML and discuss how it can be done there. Or I did not got deep enough
into PCIe world to notice how to make it happen with current implementation.
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119442): https://edk2.groups.io/g/devel/message/119442
Mute This Topic: https://groups.io/mt/106345969/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses
2024-06-04 7:23 ` Marcin Juszkiewicz
@ 2024-06-04 12:06 ` Gerd Hoffmann
0 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2024-06-04 12:06 UTC (permalink / raw)
To: devel, marcin.juszkiewicz
Cc: Ard Biesheuvel, Leif Lindholm, Graeme Gregory, Ray Ni
On Tue, Jun 04, 2024 at 09:23:30AM GMT, Marcin Juszkiewicz wrote:
> W dniu 28.05.2024 o 16:31, Ard Biesheuvel pisze:
> > I would expect each host bridge to have its own separate resource
> > windows for config space, buses and MMIO regions.
That isn't how qemu pxb-pcie host bridge works on x86 though. It does
*not* create a separate pci domain and resources such as bus numbers are
shared.
> OK. I have to admit that I never checked how physical NUMA system handles
> PCI Express. The code in patches was done by comparing with other QEMU
> targets.
It's probably not that easy. On x86 initialization works like this:
(1) the firmware sets up bridge windows and pci bars.
(2) qemu generates acpi tables with matching _CRS ranges.
(3) the firmware downloads and installs the acpi tables.
On arm qemu does the resource allocation for the root bridge windows and
communicates them to the firmware via FDT, so stealing ideas from x86
probably isn't going to work very well.
I think one option would be to have the firmware split the ranges it
got and distribute them across the root bridges, program the root
windows accordingly, generate acpi tables accordingly.
Going for a separate pci domain with separate ecam and separate bus
namespace and separate mmio ressources should be possible too, but that
most likely will need a bunch of changes on the qemu side.
HTH & take care,
Gerd
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119445): https://edk2.groups.io/g/devel/message/119445
Mute This Topic: https://groups.io/mt/106345969/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-06-04 12:07 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-28 10:31 [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 1/3] SbsaQemu: scan for PCIe buses Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 2/3] SbsaQemu: describe PCIe buses in SSDT tables Marcin Juszkiewicz
2024-05-28 10:31 ` [edk2-devel] [PATCH edk2-platforms v2 3/3] SbsaQemu: generate MCFG table Marcin Juszkiewicz
2024-05-28 14:31 ` [edk2-devel] [PATCH edk2-platforms v2 0/3] SbsaQemu: support multiple PCI Express buses Ard Biesheuvel
2024-06-04 7:23 ` Marcin Juszkiewicz
2024-06-04 12:06 ` Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox