-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add helper function to generate dsdt aml code for the gpex pci host. Largely copied from arm/virt. Configuration is handled by passing a config struct instead of looked up from memory map. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-id: 20200928104256.9241-3-kraxel@redhat.com
- Loading branch information
Showing
3 changed files
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
#include "qemu/osdep.h" | ||
#include "hw/acpi/aml-build.h" | ||
#include "hw/pci-host/gpex.h" | ||
|
||
void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg) | ||
{ | ||
int nr_pcie_buses = cfg->ecam.size / PCIE_MMCFG_SIZE_MIN; | ||
Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; | ||
int i, slot_no; | ||
|
||
Aml *dev = aml_device("%s", "PCI0"); | ||
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08"))); | ||
aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03"))); | ||
aml_append(dev, aml_name_decl("_SEG", aml_int(0))); | ||
aml_append(dev, aml_name_decl("_BBN", aml_int(0))); | ||
aml_append(dev, aml_name_decl("_UID", aml_int(0))); | ||
aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device"))); | ||
aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | ||
|
||
/* Declare the PCI Routing Table. */ | ||
Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS); | ||
for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) { | ||
for (i = 0; i < PCI_NUM_PINS; i++) { | ||
int gsi = (i + slot_no) % PCI_NUM_PINS; | ||
Aml *pkg = aml_package(4); | ||
aml_append(pkg, aml_int((slot_no << 16) | 0xFFFF)); | ||
aml_append(pkg, aml_int(i)); | ||
aml_append(pkg, aml_name("GSI%d", gsi)); | ||
aml_append(pkg, aml_int(0)); | ||
aml_append(rt_pkg, pkg); | ||
} | ||
} | ||
aml_append(dev, aml_name_decl("_PRT", rt_pkg)); | ||
|
||
/* Create GSI link device */ | ||
for (i = 0; i < PCI_NUM_PINS; i++) { | ||
uint32_t irqs = cfg->irq + i; | ||
Aml *dev_gsi = aml_device("GSI%d", i); | ||
aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F"))); | ||
aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i))); | ||
crs = aml_resource_template(); | ||
aml_append(crs, | ||
aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | ||
AML_EXCLUSIVE, &irqs, 1)); | ||
aml_append(dev_gsi, aml_name_decl("_PRS", crs)); | ||
crs = aml_resource_template(); | ||
aml_append(crs, | ||
aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | ||
AML_EXCLUSIVE, &irqs, 1)); | ||
aml_append(dev_gsi, aml_name_decl("_CRS", crs)); | ||
method = aml_method("_SRS", 1, AML_NOTSERIALIZED); | ||
aml_append(dev_gsi, method); | ||
aml_append(dev, dev_gsi); | ||
} | ||
|
||
method = aml_method("_CBA", 0, AML_NOTSERIALIZED); | ||
aml_append(method, aml_return(aml_int(cfg->ecam.base))); | ||
aml_append(dev, method); | ||
|
||
method = aml_method("_CRS", 0, AML_NOTSERIALIZED); | ||
Aml *rbuf = aml_resource_template(); | ||
aml_append(rbuf, | ||
aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, | ||
0x0000, 0x0000, nr_pcie_buses - 1, 0x0000, | ||
nr_pcie_buses)); | ||
if (cfg->mmio32.size) { | ||
aml_append(rbuf, | ||
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, | ||
AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, | ||
cfg->mmio32.base, | ||
cfg->mmio32.base + cfg->mmio32.size - 1, | ||
0x0000, | ||
cfg->mmio32.size)); | ||
} | ||
if (cfg->pio.size) { | ||
aml_append(rbuf, | ||
aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, | ||
AML_ENTIRE_RANGE, 0x0000, 0x0000, | ||
cfg->pio.size - 1, | ||
cfg->pio.base, | ||
cfg->pio.size)); | ||
} | ||
if (cfg->mmio64.size) { | ||
aml_append(rbuf, | ||
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, | ||
AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, | ||
cfg->mmio64.base, | ||
cfg->mmio64.base + cfg->mmio64.size - 1, | ||
0x0000, | ||
cfg->mmio64.size)); | ||
} | ||
aml_append(method, aml_return(rbuf)); | ||
aml_append(dev, method); | ||
|
||
/* Declare an _OSC (OS Control Handoff) method */ | ||
aml_append(dev, aml_name_decl("SUPP", aml_int(0))); | ||
aml_append(dev, aml_name_decl("CTRL", aml_int(0))); | ||
method = aml_method("_OSC", 4, AML_NOTSERIALIZED); | ||
aml_append(method, | ||
aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); | ||
|
||
/* PCI Firmware Specification 3.0 | ||
* 4.5.1. _OSC Interface for PCI Host Bridge Devices | ||
* The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is | ||
* identified by the Universal Unique IDentifier (UUID) | ||
* 33DB4D5B-1FF7-401C-9657-7441C03DD766 | ||
*/ | ||
UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"); | ||
ifctx = aml_if(aml_equal(aml_arg(0), UUID)); | ||
aml_append(ifctx, | ||
aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); | ||
aml_append(ifctx, | ||
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); | ||
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP"))); | ||
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL"))); | ||
|
||
/* | ||
* Allow OS control for all 5 features: | ||
* PCIeHotplug SHPCHotplug PME AER PCIeCapability. | ||
*/ | ||
aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F), | ||
aml_name("CTRL"))); | ||
|
||
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1)))); | ||
aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08), | ||
aml_name("CDW1"))); | ||
aml_append(ifctx, ifctx1); | ||
|
||
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL")))); | ||
aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10), | ||
aml_name("CDW1"))); | ||
aml_append(ifctx, ifctx1); | ||
|
||
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3"))); | ||
aml_append(ifctx, aml_return(aml_arg(3))); | ||
aml_append(method, ifctx); | ||
|
||
elsectx = aml_else(); | ||
aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4), | ||
aml_name("CDW1"))); | ||
aml_append(elsectx, aml_return(aml_arg(3))); | ||
aml_append(method, elsectx); | ||
aml_append(dev, method); | ||
|
||
method = aml_method("_DSM", 4, AML_NOTSERIALIZED); | ||
|
||
/* PCI Firmware Specification 3.0 | ||
* 4.6.1. _DSM for PCI Express Slot Information | ||
* The UUID in _DSM in this context is | ||
* {E5C937D0-3553-4D7A-9117-EA4D19C3434D} | ||
*/ | ||
UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D"); | ||
ifctx = aml_if(aml_equal(aml_arg(0), UUID)); | ||
ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0))); | ||
uint8_t byte_list[1] = {1}; | ||
buf = aml_buffer(1, byte_list); | ||
aml_append(ifctx1, aml_return(buf)); | ||
aml_append(ifctx, ifctx1); | ||
aml_append(method, ifctx); | ||
|
||
byte_list[0] = 0; | ||
buf = aml_buffer(1, byte_list); | ||
aml_append(method, aml_return(buf)); | ||
aml_append(dev, method); | ||
|
||
Aml *dev_res0 = aml_device("%s", "RES0"); | ||
aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02"))); | ||
crs = aml_resource_template(); | ||
aml_append(crs, | ||
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, | ||
AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, | ||
cfg->ecam.base, | ||
cfg->ecam.base + cfg->ecam.size - 1, | ||
0x0000, | ||
cfg->ecam.size)); | ||
aml_append(dev_res0, aml_name_decl("_CRS", crs)); | ||
aml_append(dev, dev_res0); | ||
aml_append(scope, dev); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters