From patchwork Mon May 13 20:01:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 243525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9C7922C00A8 for ; Tue, 14 May 2013 06:26:54 +1000 (EST) Received: from localhost ([::1]:58663 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ubz16-0003b7-Ha for incoming@patchwork.ozlabs.org; Mon, 13 May 2013 16:06:40 -0400 Received: from eggs.gnu.org ([208.118.235.92]:34553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UbywA-0005NN-QW for qemu-devel@nongnu.org; Mon, 13 May 2013 16:01:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ubyw6-0008Ff-71 for qemu-devel@nongnu.org; Mon, 13 May 2013 16:01:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40685) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ubyw5-0008FX-Ri for qemu-devel@nongnu.org; Mon, 13 May 2013 16:01:30 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r4DK1QKu026813 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 13 May 2013 16:01:28 -0400 Received: from redhat.com (vpn-202-66.tlv.redhat.com [10.35.202.66]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id r4DK1MVn008134; Mon, 13 May 2013 16:01:24 -0400 Date: Mon, 13 May 2013 23:01:25 +0300 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org, Anthony Liguori , lersek@redhat.com, seabios@seabios.org Message-ID: <94d1bc6d9a1780d85773c02306ca469f30bd8c93.1368474222.git.mst@redhat.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH RFC 10/13] i386: generate pc guest info X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This fills in guest info table with misc information of interest to the guest. Will be used by ACPI table generation code. Signed-off-by: Michael S. Tsirkin --- hw/acpi/ich9.c | 7 ++++- hw/acpi/piix4.c | 44 +++++++++++++++++++++++++- hw/i386/Makefile.objs | 2 ++ hw/i386/pc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-- hw/i386/pc_piix.c | 26 +++++++++++++-- hw/i386/pc_q35.c | 14 +++++++-- hw/isa/lpc_ich9.c | 11 +++++-- hw/mips/mips_malta.c | 2 +- hw/pci-host/q35.c | 5 +++ include/hw/acpi/ich9.h | 2 +- include/hw/i386/ich9.h | 3 +- include/hw/i386/pc.h | 53 +++++++++++++++++++++++++++++-- include/hw/pci-host/q35.h | 2 ++ include/qemu/typedefs.h | 1 + 14 files changed, 233 insertions(+), 19 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 4a17f32..764e27f 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -203,7 +203,7 @@ static void pm_powerdown_req(Notifier *n, void *opaque) } void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, - qemu_irq sci_irq) + qemu_irq sci_irq, PcGuestInfo *guest_info) { memory_region_init(&pm->io, "ich9-pm", ICH9_PMIO_SIZE); memory_region_set_enabled(&pm->io, false); @@ -219,6 +219,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, ICH9_PMIO_GPE0_LEN); memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe); + guest_info->gpe0_blk = PC_GUEST_PORT_ACPI_PM_BASE + ICH9_PMIO_GPE0_STS; + guest_info->gpe0_blk_len = ICH9_PMIO_GPE0_LEN; + guest_info->fix_rtc = true; + guest_info->platform_timer = false; + memory_region_init_io(&pm->io_smi, &ich9_smi_ops, pm, "apci-smi", 8); memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index e6525ac..19a26f5 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -94,6 +94,8 @@ typedef struct PIIX4PMState { CPUStatus gpe_cpu; Notifier cpu_added_notifier; + + PcGuestInfo *guest_info; } PIIX4PMState; static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, @@ -380,6 +382,27 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(&s->ar); } +static void piix4_update_guest_info(PIIX4PMState *s) +{ + PCIDevice *dev = &s->dev; + BusState *bus = qdev_get_parent_bus(&dev->qdev); + BusChild *kid, *next; + + memset(s->guest_info->slot_hotplug_enable, 0xff, + DIV_ROUND_UP(PCI_SLOT_MAX, BITS_PER_BYTE)); + + QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) { + DeviceState *qdev = kid->child; + PCIDevice *pdev = PCI_DEVICE(qdev); + PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev); + int slot = PCI_SLOT(pdev->devfn); + + if (pc->no_hotplug) { + clear_bit(slot, s->guest_info->slot_hotplug_enable); + } + } +} + static void piix4_pm_machine_ready(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); @@ -391,6 +414,9 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) pci_conf[0x67] = (isa_is_ioport_assigned(0x3f8) ? 0x08 : 0) | (isa_is_ioport_assigned(0x2f8) ? 0x90 : 0); + if (s->guest_info) { + piix4_update_guest_info(s); + } } static int piix4_pm_initfn(PCIDevice *dev) @@ -447,7 +473,8 @@ static int piix4_pm_initfn(PCIDevice *dev) i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq, qemu_irq smi_irq, - int kvm_enabled, FWCfgState *fw_cfg) + int kvm_enabled, FWCfgState *fw_cfg, + PcGuestInfo *guest_info) { PCIDevice *dev; PIIX4PMState *s; @@ -470,6 +497,21 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); } + if (guest_info) { + s->guest_info = guest_info; + + guest_info->s3_disabled = s->disable_s3; + guest_info->s4_disabled = s->disable_s4; + guest_info->s4_val = s->s4_val; + + guest_info->acpi_enable_cmd = ACPI_ENABLE; + guest_info->acpi_disable_cmd = ACPI_DISABLE; + guest_info->gpe0_blk = GPE_BASE; + guest_info->gpe0_blk_len = GPE_LEN; + guest_info->fix_rtc = false; + guest_info->platform_timer = true; + } + return s->smb.smbus; } diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 71be2da..e783050 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -5,6 +5,8 @@ obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o obj-y += kvmvapic.o obj-y += bios-linker-loader.o +hw/i386/pc_piix.o: hw/i386/pc_piix.c hw/i386/acpi-dsdt.hex +hw/i386/pc_q35.o: hw/i386/pc_q35.c hw/i386/q35-acpi-dsdt.hex iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \ ; then echo "$(2)"; else echo "$(3)"; fi ;) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 338a672..203c683 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -976,6 +976,74 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } } +static void pc_set_cpu_guest_info(CPUState *cpu, void *arg) +{ + PcGuestInfo *guest_info = arg; + CPUClass *klass = CPU_GET_CLASS(cpu); + uint64_t apic_id = klass->get_arch_id(cpu); + int j; + + assert(apic_id <= MAX_CPUMASK_BITS); + assert(apic_id < guest_info->apic_id_limit); + + set_bit(apic_id, guest_info->found_cpus); + + for (j = 0; j < guest_info->numa_nodes; j++) { + assert(cpu->cpu_index < max_cpus); + if (test_bit(cpu->cpu_index, node_cpumask[j])) { + guest_info->node_cpu[apic_id] = cpu_to_le64(j); + break; + } + } +} + +typedef struct PcGuestInfoState { + PcGuestInfo info; + Notifier machine_done; +} PcGuestInfoState; + +static +void pc_guest_info_machine_done(Notifier *notifier, void *data) +{ + PcGuestInfoState *guest_info_state = container_of(notifier, + PcGuestInfoState, + machine_done); +} + +PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, + ram_addr_t above_4g_mem_size) +{ + PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); + PcGuestInfo *guest_info = &guest_info_state->info; + + guest_info->ram_size = below_4g_mem_size + above_4g_mem_size; + guest_info->apic_id_limit = pc_apic_id_limit(max_cpus); + guest_info->apic_xrupt_override = kvm_allows_irq0_override(); + guest_info->numa_nodes = nb_numa_nodes; + guest_info->node_mem = g_memdup(node_mem, guest_info->numa_nodes * + sizeof *guest_info->node_mem); + guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit * + sizeof *guest_info->node_mem); + + memset(&guest_info->found_cpus, 0, sizeof guest_info->found_cpus); + qemu_for_each_cpu(pc_set_cpu_guest_info, guest_info); + + guest_info->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS; + if (sizeof(hwaddr) == 4) { + guest_info->pci_info.w64.begin = 0; + guest_info->pci_info.w64.end = 0; + } else { + guest_info->pci_info.w64.begin = 0x100000000ULL + above_4g_mem_size; + guest_info->pci_info.w64.end = guest_info->pci_info.w64.begin + + (0x1ULL << 62); + assert(range_valid(&guest_info->pci_info.w64)); + } + + guest_info_state->machine_done.notify = pc_guest_info_machine_done; + qemu_add_machine_init_done_notifier(&guest_info_state->machine_done); + return guest_info; +} + void pc_acpi_init(const char *default_dsdt) { char *filename; @@ -1017,7 +1085,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, ram_addr_t below_4g_mem_size, ram_addr_t above_4g_mem_size, MemoryRegion *rom_memory, - MemoryRegion **ram_memory) + MemoryRegion **ram_memory, + PcGuestInfo *guest_info) { int linux_boot, i; MemoryRegion *ram, *option_rom_mr; @@ -1069,6 +1138,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, for (i = 0; i < nb_option_roms; i++) { rom_add_option(option_rom[i].name, option_rom[i].bootindex); } + guest_info->fw_cfg = fw_cfg; return fw_cfg; } @@ -1123,7 +1193,8 @@ static const MemoryRegionOps ioportF0_io_ops = { void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, - bool no_vmport) + bool no_vmport, + PcGuestInfo *guest_info) { int i; DriveInfo *fd[MAX_FD]; @@ -1149,7 +1220,10 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT * when the HPET wants to take over. Thus we have to disable the latter. */ - if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { + guest_info->has_hpet = !no_hpet && + (!kvm_irqchip_in_kernel() || kvm_has_pit_state2()); + + if (guest_info->has_hpet) { hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); if (hpet) { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 207115c..cd2038a 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -50,6 +50,8 @@ # include #endif +#include "hw/i386/acpi-dsdt.hex" + #define MAX_IDE_BUS 2 static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; @@ -90,6 +92,7 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *rom_memory; DeviceState *icc_bridge; FWCfgState *fw_cfg = NULL; + PcGuestInfo *guest_info; icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); object_property_add_child(qdev_get_machine(), "icc-bridge", @@ -119,12 +122,26 @@ static void pc_init1(MemoryRegion *system_memory, rom_memory = system_memory; } + guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size); + + guest_info->dsdt_code = AcpiDsdtAmlCode; + guest_info->dsdt_size = sizeof AcpiDsdtAmlCode; + + /* Set PCI window size the way seabios has always done it. */ + /* TODO: consider just starting at below_4g_mem_size */ + if (ram_size <= 0x80000000) + guest_info->pci_info.w32.begin = 0x80000000; + else if (ram_size <= 0xc0000000) + guest_info->pci_info.w32.begin = 0xc0000000; + else + guest_info->pci_info.w32.begin = 0xe0000000; + /* allocate ram and load rom/bios */ if (!xen_enabled()) { fw_cfg = pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size, - rom_memory, &ram_memory); + rom_memory, &ram_memory, guest_info); } gsi_state = g_malloc0(sizeof(*gsi_state)); @@ -179,7 +196,8 @@ static void pc_init1(MemoryRegion *system_memory, } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); + pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled(), + guest_info); pc_nic_init(isa_bus, pci_bus); @@ -218,7 +236,9 @@ static void pc_init1(MemoryRegion *system_memory, /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, gsi[9], *smi_irq, - kvm_enabled(), fw_cfg); + kvm_enabled(), fw_cfg, + guest_info); + guest_info->sci_int = 9; smbus_eeprom_init(smbus, 8, NULL, 0); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4160e2b..9fd8143 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,6 +43,8 @@ #include "hw/usb.h" #include "hw/cpu/icc_bus.h" +#include "hw/i386/q35-acpi-dsdt.hex" + /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 @@ -77,6 +79,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) ICH9LPCState *ich9_lpc; PCIDevice *ahci; DeviceState *icc_bridge; + PcGuestInfo *guest_info; icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); object_property_add_child(qdev_get_machine(), "icc-bridge", @@ -105,11 +108,15 @@ static void pc_q35_init(QEMUMachineInitArgs *args) rom_memory = get_system_memory(); } + guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size); + guest_info->dsdt_code = Q35AcpiDsdtAmlCode; + guest_info->dsdt_size = sizeof Q35AcpiDsdtAmlCode; + /* allocate ram and load rom/bios */ if (!xen_enabled()) { pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size, - rom_memory, &ram_memory); + rom_memory, &ram_memory, guest_info); } /* irq lines */ @@ -131,6 +138,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) q35_host->mch.address_space_io = get_system_io();; q35_host->mch.below_4g_mem_size = below_4g_mem_size; q35_host->mch.above_4g_mem_size = above_4g_mem_size; + q35_host->mch.guest_info = guest_info; /* pci */ qdev_init_nofail(DEVICE(q35_host)); host_bus = q35_host->host.pci.bus; @@ -169,10 +177,10 @@ static void pc_q35_init(QEMUMachineInitArgs *args) pc_register_ferr_irq(gsi[13]); /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false); + pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false, guest_info); /* connect pm stuff to lpc */ - ich9_lpc_pm_init(lpc); + ich9_lpc_pm_init(lpc, guest_info); /* ahci and SATA device, for q35 1 ahci controller is built-in */ ahci = pci_create_simple_multifunction(host_bus, diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 667e882..a742fcb 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -312,6 +312,13 @@ PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin) return route; } +void ich9_lpc_set_guest_info(PcGuestInfo *guest_info) +{ + guest_info->sci_int = 9; + guest_info->acpi_enable_cmd = ICH9_APM_ACPI_ENABLE; + guest_info->acpi_disable_cmd = ICH9_APM_ACPI_DISABLE; +} + static int ich9_lpc_sci_irq(ICH9LPCState *lpc) { switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] & @@ -356,13 +363,13 @@ static void ich9_set_sci(void *opaque, int irq_num, int level) } } -void ich9_lpc_pm_init(PCIDevice *lpc_pci) +void ich9_lpc_pm_init(PCIDevice *lpc_pci, PcGuestInfo *guest_info) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci); qemu_irq *sci_irq; sci_irq = qemu_allocate_irqs(ich9_set_sci, lpc, 1); - ich9_pm_init(lpc_pci, &lpc->pm, sci_irq[0]); + ich9_pm_init(lpc_pci, &lpc->pm, sci_irq[0], guest_info); ich9_lpc_reset(&lpc->d.qdev); } diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 9d521cc..6ac08e1 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -965,7 +965,7 @@ void mips_malta_init(QEMUMachineInitArgs *args) pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci"); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, - isa_get_irq(NULL, 9), NULL, 0, NULL); + isa_get_irq(NULL, 9), NULL, 0, NULL, NULL); /* TODO: Populate SPD eeprom data. */ smbus_eeprom_init(smbus, 8, NULL, 0); pit = pit_init(isa_bus, 0x40, 0, NULL); diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 8467f86..857f16c 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -243,6 +243,11 @@ static int mch_init(PCIDevice *d) hwaddr pci_hole64_size; MCHPCIState *mch = MCH_PCI_DEVICE(d); + mch->guest_info->mcfg_base = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT; + /* Leave enough space for the biggest MCFG BAR */ + mch->guest_info->pci_info.w32.begin = mch->guest_info->mcfg_base + + MCH_HOST_BRIDGE_PCIEXBAR_MAX; + /* setup pci memory regions */ memory_region_init_alias(&mch->pci_hole, "pci-hole", mch->pci_address_space, diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index b1fe71f..66ab31a 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -45,7 +45,7 @@ typedef struct ICH9LPCPMRegs { } ICH9LPCPMRegs; void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, - qemu_irq sci_irq); + qemu_irq sci_irq, PcGuestInfo *guest_info); void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base); extern const VMStateDescription vmstate_ich9_pm; diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index c5f637b..7428452 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -15,10 +15,11 @@ #include "hw/acpi/ich9.h" #include "hw/pci/pci_bus.h" +void ich9_lpc_set_guest_info(PcGuestInfo *guest_info); void ich9_lpc_set_irq(void *opaque, int irq_num, int level); int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx); PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin); -void ich9_lpc_pm_init(PCIDevice *pci_lpc); +void ich9_lpc_pm_init(PCIDevice *pci_lpc, PcGuestInfo *guest_info); PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus); i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 1c2baaf..f8d0871 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -10,8 +10,48 @@ #include "exec/memory.h" #include "hw/i386/ioapic.h" +#include "qemu/range.h" +#include "qemu/bitmap.h" +#include "sysemu/sysemu.h" +#include "hw/pci/pci.h" + /* PC-style peripherals (also used by other machines). */ +typedef struct PcPciInfo { + Range w32; + Range w64; +} PcPciInfo; + +/* Matches the value hard-coded in BIOS */ +#define PC_GUEST_PORT_ACPI_PM_BASE 0xb000 + +struct PcGuestInfo { + PcPciInfo pci_info; + hwaddr ram_size; + unsigned apic_id_limit; + bool apic_xrupt_override; + bool has_hpet; + uint64_t numa_nodes; + uint64_t *node_mem; + uint64_t *node_cpu; + DECLARE_BITMAP(found_cpus, MAX_CPUMASK_BITS + 1); + bool s3_disabled; + bool s4_disabled; + uint8_t s4_val; + DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX); + uint16_t sci_int; + uint8_t acpi_enable_cmd; + uint8_t acpi_disable_cmd; + uint32_t gpe0_blk; + uint32_t gpe0_blk_len; + bool fix_rtc; + bool platform_timer; + uint64_t mcfg_base; + const unsigned char *dsdt_code; + unsigned dsdt_size; + FWCfgState *fw_cfg; +}; + /* parallel.c */ static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr) { @@ -81,6 +121,10 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); + +PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, + ram_addr_t above_4g_mem_size); + FWCfgState *pc_memory_init(MemoryRegion *system_memory, const char *kernel_filename, const char *kernel_cmdline, @@ -88,13 +132,15 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, ram_addr_t below_4g_mem_size, ram_addr_t above_4g_mem_size, MemoryRegion *rom_memory, - MemoryRegion **ram_memory); + MemoryRegion **ram_memory, + PcGuestInfo *guest_info); qemu_irq *pc_allocate_cpu_irq(void); DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, - bool no_vmport); + bool no_vmport, + PcGuestInfo *guest_info); void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd); void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, @@ -112,7 +158,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq, qemu_irq smi_irq, - int kvm_enabled, FWCfgState *fw_cfg); + int kvm_enabled, FWCfgState *fw_cfg, + PcGuestInfo *guest_info); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); /* hpet.c */ diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index e182c82..b083831 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -55,6 +55,7 @@ typedef struct MCHPCIState { uint8_t smm_enabled; ram_addr_t below_4g_mem_size; ram_addr_t above_4g_mem_size; + PcGuestInfo *guest_info; } MCHPCIState; typedef struct Q35PCIHost { @@ -81,6 +82,7 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_PCIEXBAR 0x60 /* 64bit register */ #define MCH_HOST_BRIDGE_PCIEXBAR_SIZE 8 /* 64bit register */ #define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000 +#define MCH_HOST_BRIDGE_PCIEXBAR_MAX (0x10000000) /* 256M */ #define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28) #define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26)) #define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25)) diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index afe4ec7..ec0d0d1 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -62,5 +62,6 @@ typedef struct VirtIODevice VirtIODevice; typedef struct QEMUSGList QEMUSGList; typedef struct SHPCDevice SHPCDevice; typedef struct FWCfgState FWCfgState; +typedef struct PcGuestInfo PcGuestInfo; #endif /* QEMU_TYPEDEFS_H */