summaryrefslogtreecommitdiffstats
path: root/hw/i386
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-07-08 13:36:19 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-07-08 13:36:19 +0100
commitc8232b39bb18a91cde39b8e0b60e731a4ce782b1 (patch)
tree8cc13bdc7b677a07edeb762d216e366ca3e0b1eb /hw/i386
parent62a3864eb09414d3cee94a2a592ecd414200912f (diff)
parentc4fc82bf1ad088a84ccedf779f6aa928e4fadb5f (diff)
downloadhqemu-c8232b39bb18a91cde39b8e0b60e731a4ce782b1.zip
hqemu-c8232b39bb18a91cde39b8e0b60e731a4ce782b1.tar.gz
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.c129
-rw-r--r--hw/i386/pc_piix.c5
-rw-r--r--hw/i386/pc_q35.c9
3 files changed, 103 insertions, 40 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 7959b44..7661ea9 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 4c3cb40..8167b12 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 43e6c18..974aead 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);
}
OpenPOWER on IntegriCloud