diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-07-08 13:36:19 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-07-08 13:36:19 +0100 |
commit | c8232b39bb18a91cde39b8e0b60e731a4ce782b1 (patch) | |
tree | 8cc13bdc7b677a07edeb762d216e366ca3e0b1eb /hw/i386 | |
parent | 62a3864eb09414d3cee94a2a592ecd414200912f (diff) | |
parent | c4fc82bf1ad088a84ccedf779f6aa928e4fadb5f (diff) |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc,virtio,pci: fixes and updates
Most notably, this includes the TCO support for ICH: the last feature for 2.4
as we are entering the hard freeze.
Bugfixes only from now on.
virtio pci also gained cfg access capability - arguably a bugfix
since virtio spec makes it mandatory, but it's a big patch.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Wed Jul 8 10:40:07 2015 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
* remotes/mst/tags/for_upstream:
tco-test: fix up config accesses and re-enable
virtio fix cfg endian-ness for BE targets
virtio-pci: implement cfg capability
virtio: define virtio_pci_cfg_cap in header.
pcie: Set the "link active" in the link status register
pci_regs.h: import from linux
virtio_net: reuse constants from linux
hw/i386/pc: don't carry FDC from pc_basic_device_init() to pc_cmos_init()
hw/i386/pc: reflect any FDC @ ioport 0x3f0 in the CMOS
hw/i386/pc: factor out pc_cmos_init_floppy()
ich9: implement strap SPKR pin logic
tests: add testcase for TCO watchdog emulation
ich9: add TCO interface emulation
acpi: split out ICH ACPI support
Revert "dataplane: allow virtio-1 devices"
dataplane: fix cross-endian issues
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386')
-rw-r--r-- | hw/i386/pc.c | 129 | ||||
-rw-r--r-- | hw/i386/pc_piix.c | 5 | ||||
-rw-r--r-- | hw/i386/pc_q35.c | 9 |
3 files changed, 103 insertions, 40 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 7959b44b6b..7661ea9cdf 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -293,11 +293,82 @@ static void pc_boot_set(void *opaque, const char *boot_device, Error **errp) set_boot_dev(opaque, boot_device, errp); } +static void pc_cmos_init_floppy(ISADevice *rtc_state, ISADevice *floppy) +{ + int val, nb, i; + FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE }; + + /* floppy type */ + if (floppy) { + for (i = 0; i < 2; i++) { + fd_type[i] = isa_fdc_get_drive_type(floppy, i); + } + } + val = (cmos_get_fd_drive_type(fd_type[0]) << 4) | + cmos_get_fd_drive_type(fd_type[1]); + rtc_set_memory(rtc_state, 0x10, val); + + val = rtc_get_memory(rtc_state, REG_EQUIPMENT_BYTE); + nb = 0; + if (fd_type[0] < FDRIVE_DRV_NONE) { + nb++; + } + if (fd_type[1] < FDRIVE_DRV_NONE) { + nb++; + } + switch (nb) { + case 0: + break; + case 1: + val |= 0x01; /* 1 drive, ready for boot */ + break; + case 2: + val |= 0x41; /* 2 drives, ready for boot */ + break; + } + rtc_set_memory(rtc_state, REG_EQUIPMENT_BYTE, val); +} + typedef struct pc_cmos_init_late_arg { ISADevice *rtc_state; BusState *idebus[2]; } pc_cmos_init_late_arg; +typedef struct check_fdc_state { + ISADevice *floppy; + bool multiple; +} CheckFdcState; + +static int check_fdc(Object *obj, void *opaque) +{ + CheckFdcState *state = opaque; + Object *fdc; + uint32_t iobase; + Error *local_err = NULL; + + fdc = object_dynamic_cast(obj, TYPE_ISA_FDC); + if (!fdc) { + return 0; + } + + iobase = object_property_get_int(obj, "iobase", &local_err); + if (local_err || iobase != 0x3f0) { + error_free(local_err); + return 0; + } + + if (state->floppy) { + state->multiple = true; + } else { + state->floppy = ISA_DEVICE(obj); + } + return 0; +} + +static const char * const fdc_container_path[] = { + "/unattached", "/peripheral", "/peripheral-anon" +}; + static void pc_cmos_init_late(void *opaque) { pc_cmos_init_late_arg *arg = opaque; @@ -306,6 +377,8 @@ static void pc_cmos_init_late(void *opaque) int8_t heads, sectors; int val; int i, trans; + Object *container; + CheckFdcState state = { 0 }; val = 0; if (ide_get_geometry(arg->idebus[0], 0, @@ -335,16 +408,32 @@ static void pc_cmos_init_late(void *opaque) } rtc_set_memory(s, 0x39, val); + /* + * Locate the FDC at IO address 0x3f0, and configure the CMOS registers + * accordingly. + */ + for (i = 0; i < ARRAY_SIZE(fdc_container_path); i++) { + container = container_get(qdev_get_machine(), fdc_container_path[i]); + object_child_foreach(container, check_fdc, &state); + } + + if (state.multiple) { + error_report("warning: multiple floppy disk controllers with " + "iobase=0x3f0 have been found;\n" + "the one being picked for CMOS setup might not reflect " + "your intent"); + } + pc_cmos_init_floppy(s, state.floppy); + qemu_unregister_reset(pc_cmos_init_late, opaque); } void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, MachineState *machine, - ISADevice *floppy, BusState *idebus0, BusState *idebus1, + BusState *idebus0, BusState *idebus1, ISADevice *s) { - int val, nb, i; - FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE }; + int val; static pc_cmos_init_late_arg arg; PCMachineState *pc_machine = PC_MACHINE(machine); Error *local_err = NULL; @@ -401,39 +490,12 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, exit(1); } - /* floppy type */ - if (floppy) { - for (i = 0; i < 2; i++) { - fd_type[i] = isa_fdc_get_drive_type(floppy, i); - } - } - val = (cmos_get_fd_drive_type(fd_type[0]) << 4) | - cmos_get_fd_drive_type(fd_type[1]); - rtc_set_memory(s, 0x10, val); - val = 0; - nb = 0; - if (fd_type[0] < FDRIVE_DRV_NONE) { - nb++; - } - if (fd_type[1] < FDRIVE_DRV_NONE) { - nb++; - } - switch (nb) { - case 0: - break; - case 1: - val |= 0x01; /* 1 drive, ready for boot */ - break; - case 2: - val |= 0x41; /* 2 drives, ready for boot */ - break; - } val |= 0x02; /* FPU is there */ val |= 0x04; /* PS/2 mouse installed */ rtc_set_memory(s, REG_EQUIPMENT_BYTE, val); - /* hard drives */ + /* hard drives and FDC */ arg.rtc_state = s; arg.idebus[0] = idebus0; arg.idebus[1] = idebus1; @@ -1401,7 +1463,6 @@ static const MemoryRegionOps ioportF0_io_ops = { void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, bool create_fdctrl, - ISADevice **floppy, bool no_vmport, uint32 hpet_irqs) { @@ -1497,7 +1558,9 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, fd[i] = drive_get(IF_FLOPPY, 0, i); create_fdctrl |= !!fd[i]; } - *floppy = create_fdctrl ? fdctrl_init_isa(isa_bus, fd) : NULL; + if (create_fdctrl) { + fdctrl_init_isa(isa_bus, fd); + } } void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4c3cb40ce0..8167b122f0 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -94,7 +94,6 @@ static void pc_init1(MachineState *machine) DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; - ISADevice *floppy; MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; @@ -241,7 +240,7 @@ static void pc_init1(MachineState *machine) } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, true, &floppy, + pc_basic_device_init(isa_bus, gsi, &rtc_state, true, (pc_machine->vmport != ON_OFF_AUTO_ON), 0x4); pc_nic_init(isa_bus, pci_bus); @@ -273,7 +272,7 @@ static void pc_init1(MachineState *machine) } pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order, - machine, floppy, idebus[0], idebus[1], rtc_state); + machine, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled()) { pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci"); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 43e6c18777..974aead5a9 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -73,7 +73,6 @@ static void pc_q35_init(MachineState *machine) PCIDevice *lpc; BusState *idebus[MAX_SATA_PORTS]; ISADevice *rtc_state; - ISADevice *floppy; MemoryRegion *pci_memory; MemoryRegion *rom_memory; MemoryRegion *ram_memory; @@ -249,11 +248,11 @@ static void pc_q35_init(MachineState *machine) } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, !mc->no_floppy, &floppy, + pc_basic_device_init(isa_bus, gsi, &rtc_state, !mc->no_floppy, (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104); /* connect pm stuff to lpc */ - ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pc_machine)); + ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pc_machine), !mc->no_tco); /* ahci and SATA device, for q35 1 ahci controller is built-in */ ahci = pci_create_simple_multifunction(host_bus, @@ -278,7 +277,7 @@ static void pc_q35_init(MachineState *machine) 8, NULL, 0); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order, - machine, floppy, idebus[0], idebus[1], rtc_state); + machine, idebus[0], idebus[1], rtc_state); /* the rest devices to which pci devfn is automatically assigned */ pc_vga_init(isa_bus, host_bus); @@ -399,6 +398,7 @@ static void pc_q35_2_4_machine_options(MachineClass *m) m->default_machine_opts = "firmware=bios-256k.bin"; m->default_display = "std"; m->no_floppy = 1; + m->no_tco = 0; m->alias = "q35"; } @@ -410,6 +410,7 @@ static void pc_q35_2_3_machine_options(MachineClass *m) { pc_q35_2_4_machine_options(m); m->no_floppy = 0; + m->no_tco = 1; m->alias = NULL; SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); } |