mirror of https://github.com/xemu-project/xemu.git
pc: acpi: piix4: move PCI0._PRT() into SSDT
PCI routing table for expander buses is build with help of build_prt() using AML API. And it's almost the same as PRT for PCI0 bus except of power-management device. So make existing build_prt() build PRT table for PCI0 bus as well. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
06989b8861
commit
196e213783
|
@ -623,6 +623,23 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
|
||||||
qobject_decref(bsel);
|
qobject_decref(bsel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build_prt_entry:
|
||||||
|
* @link_name: link name for PCI route entry
|
||||||
|
*
|
||||||
|
* build AML package containing a PCI route entry for @link_name
|
||||||
|
*/
|
||||||
|
static Aml *build_prt_entry(const char *link_name)
|
||||||
|
{
|
||||||
|
Aml *a_zero = aml_int(0);
|
||||||
|
Aml *pkg = aml_package(4);
|
||||||
|
aml_append(pkg, a_zero);
|
||||||
|
aml_append(pkg, a_zero);
|
||||||
|
aml_append(pkg, aml_name("%s", link_name));
|
||||||
|
aml_append(pkg, a_zero);
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize_route - Initialize the interrupt routing rule
|
* initialize_route - Initialize the interrupt routing rule
|
||||||
* through a specific LINK:
|
* through a specific LINK:
|
||||||
|
@ -633,12 +650,8 @@ static Aml *initialize_route(Aml *route, const char *link_name,
|
||||||
Aml *lnk_idx, int idx)
|
Aml *lnk_idx, int idx)
|
||||||
{
|
{
|
||||||
Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
|
Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
|
||||||
Aml *pkg = aml_package(4);
|
Aml *pkg = build_prt_entry(link_name);
|
||||||
|
|
||||||
aml_append(pkg, aml_int(0));
|
|
||||||
aml_append(pkg, aml_int(0));
|
|
||||||
aml_append(pkg, aml_name("%s", link_name));
|
|
||||||
aml_append(pkg, aml_int(0));
|
|
||||||
aml_append(if_ctx, aml_store(pkg, route));
|
aml_append(if_ctx, aml_store(pkg, route));
|
||||||
|
|
||||||
return if_ctx;
|
return if_ctx;
|
||||||
|
@ -654,7 +667,7 @@ static Aml *initialize_route(Aml *route, const char *link_name,
|
||||||
* The hash function is (slot + pin) & 3 -> "LNK[D|A|B|C]".
|
* The hash function is (slot + pin) & 3 -> "LNK[D|A|B|C]".
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static Aml *build_prt(void)
|
static Aml *build_prt(bool is_pci0_prt)
|
||||||
{
|
{
|
||||||
Aml *method, *while_ctx, *pin, *res;
|
Aml *method, *while_ctx, *pin, *res;
|
||||||
|
|
||||||
|
@ -681,7 +694,29 @@ static Aml *build_prt(void)
|
||||||
|
|
||||||
/* route[2] = "LNK[D|A|B|C]", selection based on pin % 3 */
|
/* route[2] = "LNK[D|A|B|C]", selection based on pin % 3 */
|
||||||
aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
|
aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
|
||||||
aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
|
if (is_pci0_prt) {
|
||||||
|
Aml *if_device_1, *if_pin_4, *else_pin_4;
|
||||||
|
|
||||||
|
/* device 1 is the power-management device, needs SCI */
|
||||||
|
if_device_1 = aml_if(aml_equal(lnk_idx, aml_int(1)));
|
||||||
|
{
|
||||||
|
if_pin_4 = aml_if(aml_equal(pin, aml_int(4)));
|
||||||
|
{
|
||||||
|
aml_append(if_pin_4,
|
||||||
|
aml_store(build_prt_entry("LNKS"), route));
|
||||||
|
}
|
||||||
|
aml_append(if_device_1, if_pin_4);
|
||||||
|
else_pin_4 = aml_else();
|
||||||
|
{
|
||||||
|
aml_append(else_pin_4,
|
||||||
|
aml_store(build_prt_entry("LNKA"), route));
|
||||||
|
}
|
||||||
|
aml_append(if_device_1, else_pin_4);
|
||||||
|
}
|
||||||
|
aml_append(while_ctx, if_device_1);
|
||||||
|
} else {
|
||||||
|
aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
|
||||||
|
}
|
||||||
aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
|
aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
|
||||||
aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
|
aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
|
||||||
|
|
||||||
|
@ -1474,6 +1509,10 @@ static void build_piix4_pci0_int(Aml *table)
|
||||||
Aml *method;
|
Aml *method;
|
||||||
uint32_t irqs;
|
uint32_t irqs;
|
||||||
Aml *sb_scope = aml_scope("_SB");
|
Aml *sb_scope = aml_scope("_SB");
|
||||||
|
Aml *pci0_scope = aml_scope("PCI0");
|
||||||
|
|
||||||
|
aml_append(pci0_scope, build_prt(true));
|
||||||
|
aml_append(sb_scope, pci0_scope);
|
||||||
|
|
||||||
field = aml_field("PCI0.ISA.P40C", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
|
field = aml_field("PCI0.ISA.P40C", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
|
||||||
aml_append(field, aml_named_field("PRQ0", 8));
|
aml_append(field, aml_named_field("PRQ0", 8));
|
||||||
|
@ -1698,7 +1737,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||||
aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
|
aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aml_append(dev, build_prt());
|
aml_append(dev, build_prt(false));
|
||||||
crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent),
|
crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent),
|
||||||
io_ranges, mem_ranges);
|
io_ranges, mem_ranges);
|
||||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||||
|
|
|
@ -78,64 +78,4 @@ DefinitionBlock (
|
||||||
/* Hotplug notification method supplied by SSDT */
|
/* Hotplug notification method supplied by SSDT */
|
||||||
External(\_SB.PCI0.PCNT, MethodObj)
|
External(\_SB.PCI0.PCNT, MethodObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
* PCI IRQs
|
|
||||||
****************************************************************/
|
|
||||||
|
|
||||||
Scope(\_SB) {
|
|
||||||
Scope(PCI0) {
|
|
||||||
Method (_PRT, 0) {
|
|
||||||
Store(Package(128) {}, Local0)
|
|
||||||
Store(Zero, Local1)
|
|
||||||
While(LLess(Local1, 128)) {
|
|
||||||
// slot = pin >> 2
|
|
||||||
Store(ShiftRight(Local1, 2), Local2)
|
|
||||||
|
|
||||||
// lnk = (slot + pin) & 3
|
|
||||||
Store(And(Add(Local1, Local2), 3), Local3)
|
|
||||||
If (LEqual(Local3, 0)) {
|
|
||||||
Store(Package(4) { Zero, Zero, LNKD, Zero }, Local4)
|
|
||||||
}
|
|
||||||
If (LEqual(Local3, 1)) {
|
|
||||||
// device 1 is the power-management device, needs SCI
|
|
||||||
If (LEqual(Local1, 4)) {
|
|
||||||
Store(Package(4) { Zero, Zero, LNKS, Zero }, Local4)
|
|
||||||
} Else {
|
|
||||||
Store(Package(4) { Zero, Zero, LNKA, Zero }, Local4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
If (LEqual(Local3, 2)) {
|
|
||||||
Store(Package(4) { Zero, Zero, LNKB, Zero }, Local4)
|
|
||||||
}
|
|
||||||
If (LEqual(Local3, 3)) {
|
|
||||||
Store(Package(4) { Zero, Zero, LNKC, Zero }, Local4)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete the interrupt routing entry:
|
|
||||||
// Package(4) { 0x[slot]FFFF, [pin], [link], 0) }
|
|
||||||
|
|
||||||
Store(Or(ShiftLeft(Local2, 16), 0xFFFF), Index(Local4, 0))
|
|
||||||
Store(And(Local1, 3), Index(Local4, 1))
|
|
||||||
Store(Local4, Index(Local0, Local1))
|
|
||||||
|
|
||||||
Increment(Local1)
|
|
||||||
}
|
|
||||||
|
|
||||||
Return(Local0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
External(PRQ0, FieldUnitObj)
|
|
||||||
External(PRQ1, FieldUnitObj)
|
|
||||||
External(PRQ2, FieldUnitObj)
|
|
||||||
External(PRQ3, FieldUnitObj)
|
|
||||||
External(LNKA, DeviceObj)
|
|
||||||
External(LNKB, DeviceObj)
|
|
||||||
External(LNKC, DeviceObj)
|
|
||||||
External(LNKD, DeviceObj)
|
|
||||||
External(LNKS, DeviceObj)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue