diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-12-20 11:20:25 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-12-20 11:20:25 +0000 |
commit | 48008198270e3ebcc9394401d676c54ed5ac139c (patch) | |
tree | 5dd154ecc44a6c49bcd3d6276336422e14790fe1 /hw/i386/pc.c | |
parent | 31b2bd89b915d527ff907e8f3c151585e0c45d4f (diff) | |
parent | e2328a11bda7a4d087200c524333adafb8beb7d7 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* More uses of RCU_READ_LOCK_GUARD (Dave, myself)
* QOM doc improvments (Greg)
* Cleanups from the Meson conversion (Marc-André)
* Support for multiple -accel options (myself)
* Many x86 machine cleanup (Philippe, myself)
* tests/migration-test cleanup (Juan)
* PC machine removal and next round of deprecation (Thomas)
* kernel-doc integration (Peter, myself)
# gpg: Signature made Wed 18 Dec 2019 01:35:02 GMT
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream: (87 commits)
vga: cleanup mapping of VRAM for non-PCI VGA
hw/display: Remove "rombar" hack from vga-pci and vmware_vga
hw/pci: Remove the "command_serr_enable" property
hw/audio: Remove the "use_broken_id" hack from the AC97 device
hw/i386: Remove the deprecated machines 0.12 up to 0.15
hw/pci-host: Add Kconfig entry to select the IGD Passthrough Host Bridge
hw/pci-host/i440fx: Extract the IGD passthrough host bridge device
hw/pci-host/i440fx: Use definitions instead of magic values
hw/pci-host/i440fx: Use size_t to iterate over ARRAY_SIZE()
hw/pci-host/i440fx: Extract PCII440FXState to "hw/pci-host/i440fx.h"
hw/pci-host/i440fx: Correct the header description
Fix some comment spelling errors.
target/i386: remove unused pci-assign codes
WHPX: refactor load library
migration: check length directly to make sure the range is aligned
memory: include MemoryListener documentation and some missing function parameters
docs: add memory API reference
memory.h: Silence kernel-doc complaints
docs: Create bitops.rst as example of kernel-docs
bitops.h: Silence kernel-doc complaints
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386/pc.c')
-rw-r--r-- | hw/i386/pc.c | 291 |
1 files changed, 7 insertions, 284 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 58867f987d..42014b06de 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -44,6 +44,7 @@ #include "migration/vmstate.h" #include "multiboot.h" #include "hw/rtc/mc146818rtc.h" +#include "hw/intc/i8259.h" #include "hw/dma/i8257.h" #include "hw/timer/i8254.h" #include "hw/input/i8042.h" @@ -90,18 +91,7 @@ #include "config-devices.h" #include "e820_memory_layout.h" #include "fw_cfg.h" - -/* debug PC/ISA interrupts */ -//#define DEBUG_IRQ - -#ifdef DEBUG_IRQ -#define DPRINTF(fmt, ...) \ - do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) -#endif - -struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; +#include "trace.h" GlobalProperty pc_compat_4_2[] = {}; const size_t pc_compat_4_2_len = G_N_ELEMENTS(pc_compat_4_2); @@ -347,17 +337,6 @@ GlobalProperty pc_compat_1_4[] = { }; const size_t pc_compat_1_4_len = G_N_ELEMENTS(pc_compat_1_4); -void gsi_handler(void *opaque, int n, int level) -{ - GSIState *s = opaque; - - DPRINTF("pc: %s GSI %d\n", level ? "raising" : "lowering", n); - if (n < ISA_NUM_IRQS) { - qemu_set_irq(s->i8259_irq[n], level); - } - qemu_set_irq(s->ioapic_irq[n], level); -} - GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) { GSIState *s; @@ -365,10 +344,8 @@ GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) s = g_new0(GSIState, 1); if (kvm_ioapic_in_kernel()) { kvm_pc_setup_irq_routing(pci_enabled); - *irqs = qemu_allocate_irqs(kvm_pc_gsi_handler, s, GSI_NUM_PINS); - } else { - *irqs = qemu_allocate_irqs(gsi_handler, s, GSI_NUM_PINS); } + *irqs = qemu_allocate_irqs(gsi_handler, s, GSI_NUM_PINS); return s; } @@ -397,55 +374,6 @@ static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size) return 0xffffffffffffffffULL; } -/* TSC handling */ -uint64_t cpu_get_tsc(CPUX86State *env) -{ - return cpu_get_ticks(); -} - -/* IRQ handling */ -int cpu_get_pic_interrupt(CPUX86State *env) -{ - X86CPU *cpu = env_archcpu(env); - int intno; - - if (!kvm_irqchip_in_kernel()) { - intno = apic_get_interrupt(cpu->apic_state); - if (intno >= 0) { - return intno; - } - /* read the irq from the PIC */ - if (!apic_accept_pic_intr(cpu->apic_state)) { - return -1; - } - } - - intno = pic_read_irq(isa_pic); - return intno; -} - -static void pic_irq_request(void *opaque, int irq, int level) -{ - CPUState *cs = first_cpu; - X86CPU *cpu = X86_CPU(cs); - - DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq); - if (cpu->apic_state && !kvm_irqchip_in_kernel()) { - CPU_FOREACH(cs) { - cpu = X86_CPU(cs); - if (apic_accept_pic_intr(cpu->apic_state)) { - apic_deliver_pic_intr(cpu->apic_state, level); - } - } - } else { - if (level) { - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } - } -} - /* PC cmos mappings */ #define REG_EQUIPMENT_BYTE 0x14 @@ -745,124 +673,6 @@ void pc_cmos_init(PCMachineState *pcms, qemu_register_reset(pc_cmos_init_late, &arg); } -#define TYPE_PORT92 "port92" -#define PORT92(obj) OBJECT_CHECK(Port92State, (obj), TYPE_PORT92) - -/* port 92 stuff: could be split off */ -typedef struct Port92State { - ISADevice parent_obj; - - MemoryRegion io; - uint8_t outport; - qemu_irq a20_out; -} Port92State; - -static void port92_write(void *opaque, hwaddr addr, uint64_t val, - unsigned size) -{ - Port92State *s = opaque; - int oldval = s->outport; - - DPRINTF("port92: write 0x%02" PRIx64 "\n", val); - s->outport = val; - qemu_set_irq(s->a20_out, (val >> 1) & 1); - if ((val & 1) && !(oldval & 1)) { - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); - } -} - -static uint64_t port92_read(void *opaque, hwaddr addr, - unsigned size) -{ - Port92State *s = opaque; - uint32_t ret; - - ret = s->outport; - DPRINTF("port92: read 0x%02x\n", ret); - return ret; -} - -static void port92_init(ISADevice *dev, qemu_irq a20_out) -{ - qdev_connect_gpio_out_named(DEVICE(dev), PORT92_A20_LINE, 0, a20_out); -} - -static const VMStateDescription vmstate_port92_isa = { - .name = "port92", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT8(outport, Port92State), - VMSTATE_END_OF_LIST() - } -}; - -static void port92_reset(DeviceState *d) -{ - Port92State *s = PORT92(d); - - s->outport &= ~1; -} - -static const MemoryRegionOps port92_ops = { - .read = port92_read, - .write = port92_write, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static void port92_initfn(Object *obj) -{ - Port92State *s = PORT92(obj); - - memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1); - - s->outport = 0; - - qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1); -} - -static void port92_realizefn(DeviceState *dev, Error **errp) -{ - ISADevice *isadev = ISA_DEVICE(dev); - Port92State *s = PORT92(dev); - - isa_register_ioport(isadev, &s->io, 0x92); -} - -static void port92_class_initfn(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = port92_realizefn; - dc->reset = port92_reset; - dc->vmsd = &vmstate_port92_isa; - /* - * Reason: unlike ordinary ISA devices, this one needs additional - * wiring: its A20 output line needs to be wired up by - * port92_init(). - */ - dc->user_creatable = false; -} - -static const TypeInfo port92_info = { - .name = TYPE_PORT92, - .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(Port92State), - .instance_init = port92_initfn, - .class_init = port92_class_initfn, -}; - -static void port92_register_types(void) -{ - type_register_static(&port92_info); -} - -type_init(port92_register_types) - static void handle_a20_line_change(void *opaque, int irq, int level) { X86CPU *cpu = opaque; @@ -889,16 +699,6 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd) nb_ne2k++; } -DeviceState *cpu_get_current_apic(void) -{ - if (current_cpu) { - X86CPU *cpu = X86_CPU(current_cpu); - return cpu->apic_state; - } else { - return NULL; - } -} - void pc_acpi_smi_interrupt(void *opaque, int irq, int level) { X86CPU *cpu = opaque; @@ -1294,11 +1094,6 @@ uint64_t pc_pci_hole64_start(void) return ROUND_UP(hole64_start, 1 * GiB); } -qemu_irq pc_allocate_cpu_irq(void) -{ - return qemu_allocate_irq(pic_irq_request, NULL, 0); -} - DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) { DeviceState *dev = NULL; @@ -1365,11 +1160,12 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl, bool no_vmport) qdev_prop_set_ptr(dev, "ps2_mouse", i8042); qdev_init_nofail(dev); } - port92 = isa_create_simple(isa_bus, "port92"); + port92 = isa_create_simple(isa_bus, TYPE_PORT92); a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); i8042_setup_a20_line(i8042, a20_line[0]); - port92_init(port92, a20_line[1]); + qdev_connect_gpio_out_named(DEVICE(port92), + PORT92_A20_LINE, 0, a20_line[1]); g_free(a20_line); } @@ -1475,7 +1271,7 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs) } else if (xen_enabled()) { i8259 = xen_interrupt_controller_init(); } else { - i8259 = i8259_init(isa_bus, pc_allocate_cpu_irq()); + i8259 = i8259_init(isa_bus, x86_allocate_cpu_irq()); } for (size_t i = 0; i < ISA_NUM_IRQS; i++) { @@ -1485,30 +1281,6 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs) g_free(i8259); } -void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) -{ - DeviceState *dev; - SysBusDevice *d; - unsigned int i; - - if (kvm_ioapic_in_kernel()) { - dev = qdev_create(NULL, TYPE_KVM_IOAPIC); - } else { - dev = qdev_create(NULL, TYPE_IOAPIC); - } - if (parent_name) { - object_property_add_child(object_resolve_path(parent_name, NULL), - "ioapic", OBJECT(dev), NULL); - } - qdev_init_nofail(dev); - d = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS); - - for (i = 0; i < IOAPIC_NUM_PINS; i++) { - gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); - } -} - static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -2032,48 +1804,6 @@ static void pc_machine_set_vmport(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &pcms->vmport, errp); } -bool pc_machine_is_smm_enabled(PCMachineState *pcms) -{ - bool smm_available = false; - - if (pcms->smm == ON_OFF_AUTO_OFF) { - return false; - } - - if (tcg_enabled() || qtest_enabled()) { - smm_available = true; - } else if (kvm_enabled()) { - smm_available = kvm_has_smm(); - } - - if (smm_available) { - return true; - } - - if (pcms->smm == ON_OFF_AUTO_ON) { - error_report("System Management Mode not supported by this hypervisor."); - exit(1); - } - return false; -} - -static void pc_machine_get_smm(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - PCMachineState *pcms = PC_MACHINE(obj); - OnOffAuto smm = pcms->smm; - - visit_type_OnOffAuto(v, name, &smm, errp); -} - -static void pc_machine_set_smm(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - PCMachineState *pcms = PC_MACHINE(obj); - - visit_type_OnOffAuto(v, name, &pcms->smm, errp); -} - static bool pc_machine_get_smbus(Object *obj, Error **errp) { PCMachineState *pcms = PC_MACHINE(obj); @@ -2120,7 +1850,6 @@ static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); - pcms->smm = ON_OFF_AUTO_AUTO; #ifdef CONFIG_VMPORT pcms->vmport = ON_OFF_AUTO_AUTO; #else @@ -2227,12 +1956,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pc_machine_get_device_memory_region_size, NULL, NULL, NULL, &error_abort); - object_class_property_add(oc, PC_MACHINE_SMM, "OnOffAuto", - pc_machine_get_smm, pc_machine_set_smm, - NULL, NULL, &error_abort); - object_class_property_set_description(oc, PC_MACHINE_SMM, - "Enable SMM (pc & q35)", &error_abort); - object_class_property_add(oc, PC_MACHINE_VMPORT, "OnOffAuto", pc_machine_get_vmport, pc_machine_set_vmport, NULL, NULL, &error_abort); |