diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 49aef4ebd1..96497475d1 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1072,6 +1072,46 @@ static void build_q35_pci0_int(Aml *table) aml_append(table, sb_scope); } +static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg) +{ + Aml *dev; + Aml *resource_template; + + /* DRAM controller */ + dev = aml_device("DRAC"); + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C01"))); + + resource_template = aml_resource_template(); + if (mcfg->base + mcfg->size - 1 >= (1ULL << 32)) { + aml_append(resource_template, + aml_qword_memory(AML_POS_DECODE, + AML_MIN_FIXED, + AML_MAX_FIXED, + AML_NON_CACHEABLE, + AML_READ_WRITE, + 0x0000000000000000, + mcfg->base, + mcfg->base + mcfg->size - 1, + 0x0000000000000000, + mcfg->size)); + } else { + aml_append(resource_template, + aml_dword_memory(AML_POS_DECODE, + AML_MIN_FIXED, + AML_MAX_FIXED, + AML_NON_CACHEABLE, + AML_READ_WRITE, + 0x0000000000000000, + mcfg->base, + mcfg->base + mcfg->size - 1, + 0x0000000000000000, + mcfg->size)); + } + aml_append(dev, aml_name_decl("_CRS", resource_template)); + + return dev; +} + static void build_q35_isa_bridge(Aml *table) { Aml *dev; @@ -1218,6 +1258,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine); X86MachineState *x86ms = X86_MACHINE(machine); AcpiMcfgInfo mcfg; + bool mcfg_valid = !!acpi_get_mcfg(&mcfg); uint32_t nr_mem = machine->ram_slots; int root_bus_limit = 0xFF; PCIBus *bus = NULL; @@ -1256,6 +1297,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(dev, aml_name_decl("_UID", aml_int(0))); aml_append(dev, build_q35_osc_method()); aml_append(sb_scope, dev); + if (mcfg_valid) { + aml_append(sb_scope, build_q35_dram_controller(&mcfg)); + } if (pm->smi_on_cpuhp) { /* reserve SMI block resources, IO ports 0xB2, 0xB3 */ @@ -1386,7 +1430,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, * the PCI0._CRS. Add mmconfig to the set so it will be excluded * too. */ - if (acpi_get_mcfg(&mcfg)) { + if (mcfg_valid) { crs_range_insert(crs_range_set.mem_ranges, mcfg.base, mcfg.base + mcfg.size - 1); }