mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 22:33:36 +08:00
hw/loongarch: Improve acpi dsdt table
Cleanup the previous pci information in acpi dsdt table. And using the common acpi_dsdt_add_gpex function to build the gpex and pci information. Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> Acked-by: Song Gao <gaosong@loongson.cn> Message-Id: <20220908094623.73051-10-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
parent
c3da26f314
commit
1895b96792
@ -30,6 +30,7 @@
|
||||
#include "qom/qom-qobject.h"
|
||||
|
||||
#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/pci-host/gpex.h"
|
||||
|
||||
#define ACPI_BUILD_ALIGN_SIZE 0x1000
|
||||
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
||||
@ -206,108 +207,6 @@ struct AcpiBuildState {
|
||||
MemoryRegion *linker_mr;
|
||||
} AcpiBuildState;
|
||||
|
||||
static void build_gpex_pci0_int(Aml *table)
|
||||
{
|
||||
Aml *sb_scope = aml_scope("_SB");
|
||||
Aml *pci0_scope = aml_scope("PCI0");
|
||||
Aml *prt_pkg = aml_varpackage(128);
|
||||
int slot, pin;
|
||||
|
||||
for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
|
||||
for (pin = 0; pin < PCI_NUM_PINS; pin++) {
|
||||
Aml *pkg = aml_package(4);
|
||||
aml_append(pkg, aml_int((slot << 16) | 0xFFFF));
|
||||
aml_append(pkg, aml_int(pin));
|
||||
aml_append(pkg, aml_int(0));
|
||||
aml_append(pkg, aml_int(80 + (slot + pin) % 4));
|
||||
aml_append(prt_pkg, pkg);
|
||||
}
|
||||
}
|
||||
aml_append(pci0_scope, aml_name_decl("_PRT", prt_pkg));
|
||||
aml_append(sb_scope, pci0_scope);
|
||||
aml_append(table, sb_scope);
|
||||
}
|
||||
|
||||
static void build_dbg_aml(Aml *table)
|
||||
{
|
||||
Aml *field;
|
||||
Aml *method;
|
||||
Aml *while_ctx;
|
||||
Aml *scope = aml_scope("\\");
|
||||
Aml *buf = aml_local(0);
|
||||
Aml *len = aml_local(1);
|
||||
Aml *idx = aml_local(2);
|
||||
|
||||
aml_append(scope,
|
||||
aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01));
|
||||
field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("DBGB", 8));
|
||||
aml_append(scope, field);
|
||||
|
||||
method = aml_method("DBUG", 1, AML_NOTSERIALIZED);
|
||||
|
||||
aml_append(method, aml_to_hexstring(aml_arg(0), buf));
|
||||
aml_append(method, aml_to_buffer(buf, buf));
|
||||
aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len));
|
||||
aml_append(method, aml_store(aml_int(0), idx));
|
||||
|
||||
while_ctx = aml_while(aml_lless(idx, len));
|
||||
aml_append(while_ctx,
|
||||
aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB")));
|
||||
aml_append(while_ctx, aml_increment(idx));
|
||||
aml_append(method, while_ctx);
|
||||
aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB")));
|
||||
aml_append(scope, method);
|
||||
aml_append(table, scope);
|
||||
}
|
||||
|
||||
static Aml *build_osc_method(void)
|
||||
{
|
||||
Aml *if_ctx;
|
||||
Aml *if_ctx2;
|
||||
Aml *else_ctx;
|
||||
Aml *method;
|
||||
Aml *a_cwd1 = aml_name("CDW1");
|
||||
Aml *a_ctrl = aml_local(0);
|
||||
|
||||
method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
|
||||
aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
|
||||
|
||||
if_ctx = aml_if(aml_equal(
|
||||
aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
|
||||
aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
|
||||
aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
|
||||
aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
|
||||
|
||||
/*
|
||||
* Always allow native PME, AER (no dependencies)
|
||||
* Allow SHPC (PCI bridges can have SHPC controller)
|
||||
*/
|
||||
aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
|
||||
|
||||
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
|
||||
/* Unknown revision */
|
||||
aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
|
||||
aml_append(if_ctx, if_ctx2);
|
||||
|
||||
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
|
||||
/* Capabilities bits were masked */
|
||||
aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
|
||||
aml_append(if_ctx, if_ctx2);
|
||||
|
||||
/* Update DWORD3 in the buffer */
|
||||
aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
|
||||
aml_append(method, if_ctx);
|
||||
|
||||
else_ctx = aml_else();
|
||||
/* Unrecognized UUID */
|
||||
aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
|
||||
aml_append(method, else_ctx);
|
||||
|
||||
aml_append(method, aml_return(aml_arg(3)));
|
||||
return method;
|
||||
}
|
||||
|
||||
static void build_uart_device_aml(Aml *table)
|
||||
{
|
||||
Aml *dev;
|
||||
@ -360,57 +259,37 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
|
||||
}
|
||||
}
|
||||
|
||||
static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
|
||||
{
|
||||
struct GPEXConfig cfg = {
|
||||
.mmio64.base = VIRT_PCI_MEM_BASE,
|
||||
.mmio64.size = VIRT_PCI_MEM_SIZE,
|
||||
.pio.base = VIRT_PCI_IO_BASE,
|
||||
.pio.size = VIRT_PCI_IO_SIZE,
|
||||
.ecam.base = VIRT_PCI_CFG_BASE,
|
||||
.ecam.size = VIRT_PCI_CFG_SIZE,
|
||||
.irq = PCH_PIC_IRQ_OFFSET + VIRT_DEVICE_IRQS,
|
||||
.bus = lams->pci_bus,
|
||||
};
|
||||
|
||||
acpi_dsdt_add_gpex(scope, &cfg);
|
||||
}
|
||||
|
||||
/* build DSDT */
|
||||
static void
|
||||
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
{
|
||||
Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg;
|
||||
int root_bus_limit = 0x7F;
|
||||
Aml *dsdt, *scope, *pkg;
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
dsdt = init_aml_allocator();
|
||||
|
||||
build_dbg_aml(dsdt);
|
||||
|
||||
sb_scope = aml_scope("_SB");
|
||||
dev = aml_device("PCI0");
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
|
||||
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
|
||||
aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(1)));
|
||||
aml_append(dev, build_osc_method());
|
||||
aml_append(sb_scope, dev);
|
||||
aml_append(dsdt, sb_scope);
|
||||
|
||||
build_gpex_pci0_int(dsdt);
|
||||
build_uart_device_aml(dsdt);
|
||||
build_pci_device_aml(dsdt, lams);
|
||||
build_la_ged_aml(dsdt, machine);
|
||||
|
||||
scope = aml_scope("\\_SB.PCI0");
|
||||
/* Build PCI0._CRS */
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
|
||||
0x0000, 0x0, root_bus_limit,
|
||||
0x0000, root_bus_limit + 1));
|
||||
aml_append(crs,
|
||||
aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_POS_DECODE, AML_ENTIRE_RANGE,
|
||||
0x0000, 0x0000, 0xFFFF, 0x18000000, 0x10000));
|
||||
aml_append(crs,
|
||||
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_CACHEABLE, AML_READ_WRITE,
|
||||
0, VIRT_PCI_MEM_BASE,
|
||||
VIRT_PCI_MEM_BASE + VIRT_PCI_MEM_SIZE - 1,
|
||||
0, VIRT_PCI_MEM_BASE));
|
||||
aml_append(scope, aml_name_decl("_CRS", crs));
|
||||
aml_append(dsdt, scope);
|
||||
|
||||
/* System State Package */
|
||||
scope = aml_scope("\\");
|
||||
pkg = aml_package(4);
|
||||
|
@ -387,6 +387,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
|
||||
d = SYS_BUS_DEVICE(gpex_dev);
|
||||
sysbus_realize_and_unref(d, &error_fatal);
|
||||
pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
|
||||
lams->pci_bus = pci_bus;
|
||||
|
||||
/* Map only part size_ecam bytes of ECAM space */
|
||||
ecam_alias = g_new0(MemoryRegion, 1);
|
||||
|
@ -50,6 +50,7 @@ struct LoongArchMachineState {
|
||||
DeviceState *acpi_ged;
|
||||
int fdt_size;
|
||||
DeviceState *platform_bus_dev;
|
||||
PCIBus *pci_bus;
|
||||
};
|
||||
|
||||
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
|
Loading…
Reference in New Issue
Block a user