diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/apic.c | 42 | ||||
| -rw-r--r-- | hw/cirrus_vga.c | 1 | ||||
| -rw-r--r-- | hw/hpet.c | 2 | ||||
| -rw-r--r-- | hw/i2c.h | 5 | ||||
| -rw-r--r-- | hw/ide/core.c | 2 | ||||
| -rw-r--r-- | hw/isa-bus.c | 12 | ||||
| -rw-r--r-- | hw/isa.h | 1 | ||||
| -rw-r--r-- | hw/kvmclock.c | 125 | ||||
| -rw-r--r-- | hw/kvmclock.h | 14 | ||||
| -rw-r--r-- | hw/mainstone.c | 34 | ||||
| -rw-r--r-- | hw/mainstone.h | 38 | ||||
| -rw-r--r-- | hw/max7310.c | 26 | ||||
| -rw-r--r-- | hw/mips_malta.c | 6 | ||||
| -rw-r--r-- | hw/mst_fpga.c | 130 | ||||
| -rw-r--r-- | hw/pc.c | 30 | ||||
| -rw-r--r-- | hw/pc.h | 10 | ||||
| -rw-r--r-- | hw/pc_piix.c | 32 | ||||
| -rw-r--r-- | hw/pci.c | 20 | ||||
| -rw-r--r-- | hw/pci.h | 4 | ||||
| -rw-r--r-- | hw/pxa2xx.c | 53 | ||||
| -rw-r--r-- | hw/qdev.c | 14 | ||||
| -rw-r--r-- | hw/qdev.h | 1 | ||||
| -rw-r--r-- | hw/scsi-disk.c | 2 | ||||
| -rw-r--r-- | hw/sysbus.c | 32 | ||||
| -rw-r--r-- | hw/sysbus.h | 9 | ||||
| -rw-r--r-- | hw/tc6393xb.c | 3 | ||||
| -rw-r--r-- | hw/tosa.c | 4 | ||||
| -rw-r--r-- | hw/vga.c | 31 | ||||
| -rw-r--r-- | hw/vhost.c | 2 | ||||
| -rw-r--r-- | hw/virtio-blk.c | 2 | ||||
| -rw-r--r-- | hw/vmmouse.c | 62 | ||||
| -rw-r--r-- | hw/vmport.c | 43 | ||||
| -rw-r--r-- | hw/vmware_vga.c | 5 | ||||
| -rw-r--r-- | hw/vmware_vga.h | 12 | ||||
| -rw-r--r-- | hw/watchdog.c | 2 | ||||
| -rw-r--r-- | hw/zaurus.c | 20 |
36 files changed, 579 insertions, 252 deletions
diff --git a/hw/apic.c b/hw/apic.c index 2f8376a307..218d1bb6da 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -372,19 +372,36 @@ static int apic_get_arb_pri(APICState *s) return 0; } -/* signal the CPU if an irq is pending */ -static void apic_update_irq(APICState *s) + +/* + * <0 - low prio interrupt, + * 0 - no interrupt, + * >0 - interrupt number + */ +static int apic_irq_pending(APICState *s) { int irrv, ppr; - if (!(s->spurious_vec & APIC_SV_ENABLE)) - return; irrv = get_highest_priority_int(s->irr); - if (irrv < 0) - return; + if (irrv < 0) { + return 0; + } ppr = apic_get_ppr(s); - if (ppr && (irrv & 0xf0) <= (ppr & 0xf0)) + if (ppr && (irrv & 0xf0) <= (ppr & 0xf0)) { + return -1; + } + + return irrv; +} + +/* signal the CPU if an irq is pending */ +static void apic_update_irq(APICState *s) +{ + if (!(s->spurious_vec & APIC_SV_ENABLE)) { return; - cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); + } + if (apic_irq_pending(s) > 0) { + cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); + } } void apic_reset_irq_delivered(void) @@ -590,12 +607,13 @@ int apic_get_interrupt(DeviceState *d) if (!(s->spurious_vec & APIC_SV_ENABLE)) return -1; - /* XXX: spurious IRQ handling */ - intno = get_highest_priority_int(s->irr); - if (intno < 0) + intno = apic_irq_pending(s); + + if (intno == 0) { return -1; - if (s->tpr && intno <= s->tpr) + } else if (intno < 0) { return s->spurious_vec & 0xff; + } reset_bit(s->irr, intno); set_bit(s->isr, intno); apic_update_irq(s); diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 5f45b5dee7..2724f7b480 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -31,7 +31,6 @@ #include "pci.h" #include "console.h" #include "vga_int.h" -#include "kvm.h" #include "loader.h" /* diff --git a/hw/hpet.c b/hw/hpet.c index 8fb6811a2c..82a9a21978 100644 --- a/hw/hpet.c +++ b/hw/hpet.c @@ -74,8 +74,6 @@ typedef struct HPETState { uint8_t hpet_id; /* instance id */ } HPETState; -struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; - static uint32_t hpet_in_legacy_mode(HPETState *s) { return s->config & HPET_CFG_LEGACY; diff --git a/hw/i2c.h b/hw/i2c.h index 83fd91714a..5514402029 100644 --- a/hw/i2c.h +++ b/hw/i2c.h @@ -59,11 +59,6 @@ void i2c_register_slave(I2CSlaveInfo *type); DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr); -/* max7310.c */ -void max7310_reset(i2c_slave *i2c); -qemu_irq *max7310_gpio_in_get(i2c_slave *i2c); -void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler); - /* wm8750.c */ void wm8750_data_req_set(DeviceState *dev, void (*data_req)(void *, int, int), void *opaque); diff --git a/hw/ide/core.c b/hw/ide/core.c index dd63664c0d..9c91a49767 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -465,7 +465,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) s->bus->dma->ops->set_unit(s->bus->dma, s->unit); s->bus->dma->ops->add_status(s->bus->dma, op); bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + vm_stop(VMSTOP_DISKFULL); } else { if (op & BM_STATUS_DMA_RETRY) { dma_buf_commit(s, 0); diff --git a/hw/isa-bus.c b/hw/isa-bus.c index 0cb1afbf2e..6f349a574a 100644 --- a/hw/isa-bus.c +++ b/hw/isa-bus.c @@ -146,6 +146,18 @@ ISADevice *isa_create(const char *name) return DO_UPCAST(ISADevice, qdev, dev); } +ISADevice *isa_try_create(const char *name) +{ + DeviceState *dev; + + if (!isabus) { + hw_error("Tried to create isa device %s with no isa bus present.", + name); + } + dev = qdev_try_create(&isabus->qbus, name); + return DO_UPCAST(ISADevice, qdev, dev); +} + ISADevice *isa_create_simple(const char *name) { ISADevice *dev; diff --git a/hw/isa.h b/hw/isa.h index 19aa94c9fd..e26abfa063 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -32,6 +32,7 @@ void isa_init_ioport(ISADevice *dev, uint16_t ioport); void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length); void isa_qdev_register(ISADeviceInfo *info); ISADevice *isa_create(const char *name); +ISADevice *isa_try_create(const char *name); ISADevice *isa_create_simple(const char *name); extern target_phys_addr_t isa_mem_base; diff --git a/hw/kvmclock.c b/hw/kvmclock.c new file mode 100644 index 0000000000..b6ceddfba6 --- /dev/null +++ b/hw/kvmclock.c @@ -0,0 +1,125 @@ +/* + * QEMU KVM support, paravirtual clock device + * + * Copyright (C) 2011 Siemens AG + * + * Authors: + * Jan Kiszka <jan.kiszka@siemens.com> + * + * This work is licensed under the terms of the GNU GPL version 2. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "sysemu.h" +#include "sysbus.h" +#include "kvm.h" +#include "kvmclock.h" + +#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ADJUST_CLOCK) + +#include <linux/kvm.h> +#include <linux/kvm_para.h> + +typedef struct KVMClockState { + SysBusDevice busdev; + uint64_t clock; + bool clock_valid; +} KVMClockState; + +static void kvmclock_pre_save(void *opaque) +{ + KVMClockState *s = opaque; + struct kvm_clock_data data; + int ret; + + if (s->clock_valid) { + return; + } + ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); + if (ret < 0) { + fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); + data.clock = 0; + } + s->clock = data.clock; + /* + * If the VM is stopped, declare the clock state valid to avoid re-reading + * it on next vmsave (which would return a different value). Will be reset + * when the VM is continued. + */ + s->clock_valid = !vm_running; +} + +static int kvmclock_post_load(void *opaque, int version_id) +{ + KVMClockState *s = opaque; + struct kvm_clock_data data; + + data.clock = s->clock; + data.flags = 0; + return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); +} + +static void kvmclock_vm_state_change(void *opaque, int running, int reason) +{ + KVMClockState *s = opaque; + + if (running) { + s->clock_valid = false; + } +} + +static int kvmclock_init(SysBusDevice *dev) +{ + KVMClockState *s = FROM_SYSBUS(KVMClockState, dev); + + qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s); + return 0; +} + +static const VMStateDescription kvmclock_vmsd = { + .name = "kvmclock", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = kvmclock_pre_save, + .post_load = kvmclock_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT64(clock, KVMClockState), + VMSTATE_END_OF_LIST() + } +}; + +static SysBusDeviceInfo kvmclock_info = { + .qdev.name = "kvmclock", + .qdev.size = sizeof(KVMClockState), + .qdev.vmsd = &kvmclock_vmsd, + .qdev.no_user = 1, + .init = kvmclock_init, +}; + +/* Note: Must be called after VCPU initialization. */ +void kvmclock_create(void) +{ + if (kvm_enabled() && + first_cpu->cpuid_kvm_features & (1ULL << KVM_FEATURE_CLOCKSOURCE)) { + sysbus_create_simple("kvmclock", -1, NULL); + } +} + +static void kvmclock_register_device(void) +{ + if (kvm_enabled()) { + sysbus_register_withprop(&kvmclock_info); + } +} + +device_init(kvmclock_register_device); + +#else /* !(CONFIG_KVM_PARA && KVM_CAP_ADJUST_CLOCK) */ + +void kvmclock_create(void) +{ +} +#endif /* !(CONFIG_KVM_PARA && KVM_CAP_ADJUST_CLOCK) */ diff --git a/hw/kvmclock.h b/hw/kvmclock.h new file mode 100644 index 0000000000..7a83cbe8f6 --- /dev/null +++ b/hw/kvmclock.h @@ -0,0 +1,14 @@ +/* + * QEMU KVM support, paravirtual clock device + * + * Copyright (C) 2011 Siemens AG + * + * Authors: + * Jan Kiszka <jan.kiszka@siemens.com> + * + * This work is licensed under the terms of the GNU GPL version 2. + * See the COPYING file in the top-level directory. + * + */ + +void kvmclock_create(void); diff --git a/hw/mainstone.c b/hw/mainstone.c index 58e3f8670d..aec8d34b4f 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -14,10 +14,32 @@ #include "net.h" #include "devices.h" #include "boards.h" -#include "mainstone.h" #include "sysemu.h" #include "flash.h" #include "blockdev.h" +#include "sysbus.h" + +/* Device addresses */ +#define MST_FPGA_PHYS 0x08000000 +#define MST_ETH_PHYS 0x10000300 +#define MST_FLASH_0 0x00000000 +#define MST_FLASH_1 0x04000000 + +/* IRQ definitions */ +#define MMC_IRQ 0 +#define USIM_IRQ 1 +#define USBC_IRQ 2 +#define ETHERNET_IRQ 3 +#define AC97_IRQ 4 +#define PEN_IRQ 5 +#define MSINS_IRQ 6 +#define EXBRD_IRQ 7 +#define S0_CD_IRQ 9 +#define S0_STSCHG_IRQ 10 +#define S0_IRQ 11 +#define S1_CD_IRQ 13 +#define S1_STSCHG_IRQ 14 +#define S1_IRQ 15 static struct keymap map[0xE0] = { [0 ... 0xDF] = { -1, -1 }, @@ -77,7 +99,7 @@ static void mainstone_common_init(ram_addr_t ram_size, uint32_t sector_len = 256 * 1024; target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 }; PXA2xxState *cpu; - qemu_irq *mst_irq; + DeviceState *mst_irq; DriveInfo *dinfo; int i; int be; @@ -117,16 +139,18 @@ static void mainstone_common_init(ram_addr_t ram_size, } } - mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0); + mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS, + cpu->pic[PXA2XX_PIC_GPIO_0]); /* setup keypad */ printf("map addr %p\n", &map); pxa27x_register_keypad(cpu->kp, map, 0xe0); /* MMC/SD host */ - pxa2xx_mmci_handlers(cpu->mmc, NULL, mst_irq[MMC_IRQ]); + pxa2xx_mmci_handlers(cpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ)); - smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]); + smc91c111_init(&nd_table[0], MST_ETH_PHYS, + qdev_get_gpio_in(mst_irq, ETHERNET_IRQ)); mainstone_binfo.kernel_filename = kernel_filename; mainstone_binfo.kernel_cmdline = kernel_cmdline; diff --git a/hw/mainstone.h b/hw/mainstone.h deleted file mode 100644 index 9618c0632a..0000000000 --- a/hw/mainstone.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * PXA270-based Intel Mainstone platforms. - * - * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or - * <akuster@mvista.com> - * - * This code is licensed under the GNU GPL v2. - */ - -#ifndef __MAINSTONE_H__ -#define __MAINSTONE_H__ - -/* Device addresses */ -#define MST_FPGA_PHYS 0x08000000 -#define MST_ETH_PHYS 0x10000300 -#define MST_FLASH_0 0x00000000 -#define MST_FLASH_1 0x04000000 - -/* IRQ definitions */ -#define MMC_IRQ 0 -#define USIM_IRQ 1 -#define USBC_IRQ 2 -#define ETHERNET_IRQ 3 -#define AC97_IRQ 4 -#define PEN_IRQ 5 -#define MSINS_IRQ 6 -#define EXBRD_IRQ 7 -#define S0_CD_IRQ 9 -#define S0_STSCHG_IRQ 10 -#define S0_IRQ 11 -#define S1_CD_IRQ 13 -#define S1_STSCHG_IRQ 14 -#define S1_IRQ 15 - -extern qemu_irq -*mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq); - -#endif /* __MAINSTONE_H__ */ diff --git a/hw/max7310.c b/hw/max7310.c index c302eb6aa4..c1bdb2ee0c 100644 --- a/hw/max7310.c +++ b/hw/max7310.c @@ -23,9 +23,9 @@ typedef struct { qemu_irq *gpio_in; } MAX7310State; -void max7310_reset(i2c_slave *i2c) +static void max7310_reset(DeviceState *dev) { - MAX7310State *s = (MAX7310State *) i2c; + MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, I2C_SLAVE_FROM_QDEV(dev)); s->level &= s->direction; s->direction = 0xff; s->polarity = 0xf0; @@ -179,33 +179,17 @@ static int max7310_init(i2c_slave *i2c) { MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c); - s->gpio_in = qemu_allocate_irqs(max7310_gpio_set, s, - ARRAY_SIZE(s->handler)); - - max7310_reset(&s->i2c); + qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8); + qdev_init_gpio_out(&i2c->qdev, s->handler, 8); return 0; } -qemu_irq *max7310_gpio_in_get(i2c_slave *i2c) -{ - MAX7310State *s = (MAX7310State *) i2c; - return s->gpio_in; -} - -void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler) -{ - MAX7310State *s = (MAX7310State *) i2c; - if (line >= ARRAY_SIZE(s->handler) || line < 0) - hw_error("bad GPIO line"); - - s->handler[line] = handler; -} - static I2CSlaveInfo max7310_info = { .qdev.name = "max7310", .qdev.size = sizeof(MAX7310State), .qdev.vmsd = &vmstate_max7310, + .qdev.reset = max7310_reset, .init = max7310_init, .event = max7310_event, .recv = max7310_rx, diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 2d3f242cc8..930c51c74d 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -957,7 +957,11 @@ void mips_malta_init (ram_addr_t ram_size, if (cirrus_vga_enabled) { pci_cirrus_vga_init(pci_bus); } else if (vmsvga_enabled) { - pci_vmsvga_init(pci_bus); + if (!pci_vmsvga_init(pci_bus)) { + fprintf(stderr, "Warning: vmware_vga not available," + " using standard VGA instead\n"); + pci_vga_init(pci_bus); + } } else if (std_vga_enabled) { pci_vga_init(pci_bus); } diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c index 5252fc5e1c..afed2acd44 100644 --- a/hw/mst_fpga.c +++ b/hw/mst_fpga.c @@ -8,8 +8,7 @@ * This code is licensed under the GNU GPL v2. */ #include "hw.h" -#include "pxa.h" -#include "mainstone.h" +#include "sysbus.h" /* Mainstone FPGA for extern irqs */ #define FPGA_GPIO_PIN 0 @@ -28,8 +27,9 @@ #define MST_PCMCIA1 0xe4 typedef struct mst_irq_state{ - qemu_irq *parent; - qemu_irq *pins; + SysBusDevice busdev; + + qemu_irq parent; uint32_t prev_level; uint32_t leddat1; @@ -47,33 +47,21 @@ typedef struct mst_irq_state{ }mst_irq_state; static void -mst_fpga_update_gpio(mst_irq_state *s) -{ - uint32_t level, diff; - int bit; - level = s->prev_level ^ s->intsetclr; - - for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; - qemu_set_irq(s->pins[bit], (level >> bit) & 1 ); - } - s->prev_level = level; -} - -static void mst_fpga_set_irq(void *opaque, int irq, int level) { mst_irq_state *s = (mst_irq_state *)opaque; + uint32_t oldint = s->intsetclr; if (level) s->prev_level |= 1u << irq; else s->prev_level &= ~(1u << irq); - if(s->intmskena & (1u << irq)) { - s->intsetclr = 1u << irq; - qemu_set_irq(s->parent[0], level); - } + if ((s->intmskena & (1u << irq)) && level) + s->intsetclr |= 1u << irq; + + if (oldint != (s->intsetclr & s->intmskena)) + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); } @@ -109,7 +97,7 @@ mst_fpga_readb(void *opaque, target_phys_addr_t addr) return s->pcmcia1; default: printf("Mainstone - mst_fpga_readb: Bad register offset " - REG_FMT " \n", addr); + "0x" TARGET_FMT_plx " \n", addr); } return 0; } @@ -147,10 +135,11 @@ mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) break; case MST_INTMSKENA: /* Mask interupt */ s->intmskena = (value & 0xFEEFF); - mst_fpga_update_gpio(s); + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); break; case MST_INTSETCLR: /* clear or set interrupt */ s->intsetclr = (value & 0xFEEFF); + qemu_set_irq(s->parent, s->intsetclr); break; case MST_PCMCIA0: s->pcmcia0 = value; @@ -160,7 +149,7 @@ mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) break; default: printf("Mainstone - mst_fpga_writeb: Bad register offset " - REG_FMT " \n", addr); + "0x" TARGET_FMT_plx " \n", addr); } } @@ -175,66 +164,67 @@ static CPUWriteMemoryFunc * const mst_fpga_writefn[] = { mst_fpga_writeb, }; -static void -mst_fpga_save(QEMUFile *f, void *opaque) -{ - struct mst_irq_state *s = (mst_irq_state *) opaque; - - qemu_put_be32s(f, &s->prev_level); - qemu_put_be32s(f, &s->leddat1); - qemu_put_be32s(f, &s->leddat2); - qemu_put_be32s(f, &s->ledctrl); - qemu_put_be32s(f, &s->gpswr); - qemu_put_be32s(f, &s->mscwr1); - qemu_put_be32s(f, &s->mscwr2); - qemu_put_be32s(f, &s->mscwr3); - qemu_put_be32s(f, &s->mscrd); - qemu_put_be32s(f, &s->intmskena); - qemu_put_be32s(f, &s->intsetclr); - qemu_put_be32s(f, &s->pcmcia0); - qemu_put_be32s(f, &s->pcmcia1); -} -static int -mst_fpga_load(QEMUFile *f, void *opaque, int version_id) +static int mst_fpga_post_load(void *opaque, int version_id) { mst_irq_state *s = (mst_irq_state *) opaque; - qemu_get_be32s(f, &s->prev_level); - qemu_get_be32s(f, &s->leddat1); - qemu_get_be32s(f, &s->leddat2); - qemu_get_be32s(f, &s->ledctrl); - qemu_get_be32s(f, &s->gpswr); - qemu_get_be32s(f, &s->mscwr1); - qemu_get_be32s(f, &s->mscwr2); - qemu_get_be32s(f, &s->mscwr3); - qemu_get_be32s(f, &s->mscrd); - qemu_get_be32s(f, &s->intmskena); - qemu_get_be32s(f, &s->intsetclr); - qemu_get_be32s(f, &s->pcmcia0); - qemu_get_be32s(f, &s->pcmcia1); + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); return 0; } -qemu_irq *mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq) +static int mst_fpga_init(SysBusDevice *dev) { mst_irq_state *s; int iomemtype; - qemu_irq *qi; - s = (mst_irq_state *) - qemu_mallocz(sizeof(mst_irq_state)); + s = FROM_SYSBUS(mst_irq_state, dev); - s->parent = &cpu->pic[irq]; + sysbus_init_irq(dev, &s->parent); /* alloc the external 16 irqs */ - qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS); - s->pins = qi; + qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS); iomemtype = cpu_register_io_memory(mst_fpga_readfn, mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00100000, iomemtype); - register_savevm(NULL, "mainstone_fpga", 0, 0, mst_fpga_save, - mst_fpga_load, s); - return qi; + sysbus_init_mmio(dev, 0x00100000, iomemtype); + return 0; +} + +static VMStateDescription vmstate_mst_fpga_regs = { + .name = "mainstone_fpga", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = mst_fpga_post_load, + .fields = (VMStateField []) { + VMSTATE_UINT32(prev_level, mst_irq_state), + VMSTATE_UINT32(leddat1, mst_irq_state), + VMSTATE_UINT32(leddat2, mst_irq_state), + VMSTATE_UINT32(ledctrl, mst_irq_state), + VMSTATE_UINT32(gpswr, mst_irq_state), + VMSTATE_UINT32(mscwr1, mst_irq_state), + VMSTATE_UINT32(mscwr2, mst_irq_state), + VMSTATE_UINT32(mscwr3, mst_irq_state), + VMSTATE_UINT32(mscrd, mst_irq_state), + VMSTATE_UINT32(intmskena, mst_irq_state), + VMSTATE_UINT32(intsetclr, mst_irq_state), + VMSTATE_UINT32(pcmcia0, mst_irq_state), + VMSTATE_UINT32(pcmcia1, mst_irq_state), + VMSTATE_END_OF_LIST(), + }, +}; + +static SysBusDeviceInfo mst_fpga_info = { + .init = mst_fpga_init, + .qdev.name = "mainstone-fpga", + .qdev.desc = "Mainstone II FPGA", + .qdev.size = sizeof(mst_irq_state), + .qdev.vmsd = &vmstate_mst_fpga_regs, +}; + +static void mst_fpga_register(void) +{ + sysbus_register_withprop(&mst_fpga_info); } +device_init(mst_fpga_register); diff --git a/hw/pc.c b/hw/pc.c index 4dfdc0be53..56bf1d63f0 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -84,6 +84,7 @@ struct e820_table { } __attribute((__packed__, __aligned__(4))); static struct e820_table e820_table; +struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; void isa_irq_handler(void *opaque, int n, int level) { @@ -1053,10 +1054,15 @@ void pc_vga_init(PCIBus *pci_bus) isa_cirrus_vga_init(); } } else if (vmsvga_enabled) { - if (pci_bus) - pci_vmsvga_init(pci_bus); - else + if (pci_bus) { + if (!pci_vmsvga_init(pci_bus)) { + fprintf(stderr, "Warning: vmware_vga not available," + " using standard VGA instead\n"); + pci_vga_init(pci_bus); + } + } else { fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__); + } #ifdef CONFIG_SPICE } else if (qxl_enabled) { if (pci_bus) @@ -1091,7 +1097,7 @@ void pc_basic_device_init(qemu_irq *isa_irq, PITState *pit; qemu_irq rtc_irq = NULL; qemu_irq *a20_line; - ISADevice *i8042, *port92; + ISADevice *i8042, *port92, *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -1099,12 +1105,14 @@ void pc_basic_device_init(qemu_irq *isa_irq, register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); if (!no_hpet) { - DeviceState *hpet = sysbus_create_simple("hpet", HPET_BASE, NULL); + DeviceState *hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); - for (i = 0; i < 24; i++) { - sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]); + if (hpet) { + for (i = 0; i < 24; i++) { + sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]); + } + rtc_irq = qdev_get_gpio_in(hpet, 0); } - rtc_irq = qdev_get_gpio_in(hpet, 0); } *rtc_state = rtc_init(2000, rtc_irq); @@ -1128,7 +1136,11 @@ void pc_basic_device_init(qemu_irq *isa_irq, a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); i8042 = isa_create_simple("i8042"); i8042_setup_a20_line(i8042, &a20_line[0]); - vmmouse_init(i8042); + vmport_init(); + vmmouse = isa_try_create("vmmouse"); + if (vmmouse) { + qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042); + } port92 = isa_create_simple("port92"); port92_init(port92, &a20_line[1]); diff --git a/hw/pc.h b/hw/pc.h index a048768d21..d5d2f42f96 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -65,11 +65,13 @@ void hpet_pit_disable(void); void hpet_pit_enable(void); /* vmport.c */ -void vmport_init(void); +static inline void vmport_init(void) +{ + isa_create_simple("vmport"); +} void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque); - -/* vmmouse.c */ -void *vmmouse_init(void *m); +void vmmouse_get_data(uint32_t *data); +void vmmouse_set_data(const uint32_t *data); /* pckbd.c */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 7b744730f7..291845478d 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -32,6 +32,7 @@ #include "boards.h" #include "ide.h" #include "kvm.h" +#include "kvmclock.h" #include "sysemu.h" #include "sysbus.h" #include "arch_init.h" @@ -66,7 +67,8 @@ static void pc_init1(ram_addr_t ram_size, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, - int pci_enabled) + int pci_enabled, + int kvmclock_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; @@ -86,7 +88,9 @@ static void pc_init1(ram_addr_t ram_size, pc_cpus_init(cpu_model); - vmport_init(); + if (kvmclock_enabled) { + kvmclock_create(); + } /* allocate ram and load rom/bios */ pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, @@ -195,7 +199,19 @@ static void pc_init_pci(ram_addr_t ram_size, { pc_init1(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 1); + initrd_filename, cpu_model, 1, 1); +} + +static void pc_init_pci_no_kvmclock(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + pc_init1(ram_size, boot_device, + kernel_filename, kernel_cmdline, + initrd_filename, cpu_model, 1, 0); } static void pc_init_isa(ram_addr_t ram_size, @@ -209,7 +225,7 @@ static void pc_init_isa(ram_addr_t ram_size, cpu_model = "486"; pc_init1(ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 0); + initrd_filename, cpu_model, 0, 1); } static QEMUMachine pc_machine = { @@ -224,7 +240,7 @@ static QEMUMachine pc_machine = { static QEMUMachine pc_machine_v0_13 = { .name = "pc-0.13", .desc = "Standard PC", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -251,7 +267,7 @@ static QEMUMachine pc_machine_v0_13 = { static QEMUMachine pc_machine_v0_12 = { .name = "pc-0.12", .desc = "Standard PC", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -282,7 +298,7 @@ static QEMUMachine pc_machine_v0_12 = { static QEMUMachine pc_machine_v0_11 = { .name = "pc-0.11", .desc = "Standard PC, qemu 0.11", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -321,7 +337,7 @@ static QEMUMachine pc_machine_v0_11 = { static QEMUMachine pc_machine_v0_10 = { .name = "pc-0.10", .desc = "Standard PC, qemu 0.10", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { diff --git a/hw/pci.c b/hw/pci.c index d5bbba975b..5e6e216487 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1708,6 +1708,21 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, return DO_UPCAST(PCIDevice, qdev, dev); } +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, + bool multifunction, + const char *name) +{ + DeviceState *dev; + + dev = qdev_try_create(&bus->qbus, name); + if (!dev) { + return NULL; + } + qdev_prop_set_uint32(dev, "addr", devfn); + qdev_prop_set_bit(dev, "multifunction", multifunction); + return DO_UPCAST(PCIDevice, qdev, dev); +} + PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name) @@ -1727,6 +1742,11 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) return pci_create_simple_multifunction(bus, devfn, false, name); } +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name) +{ + return pci_try_create_multifunction(bus, devfn, false, name); +} + static int pci_find_space(PCIDevice *pdev, uint8_t size) { int config_size = pci_config_size(pdev); diff --git a/hw/pci.h b/hw/pci.h index 0d2753f27e..113e556e2d 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -453,8 +453,12 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name); +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, + bool multifunction, + const char *name); PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name); static inline int pci_is_express(const PCIDevice *d) { diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index d966846f94..9ebbce60d7 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -1262,10 +1262,12 @@ typedef struct { } PXA2xxI2CSlaveState; struct PXA2xxI2CState { + SysBusDevice busdev; PXA2xxI2CSlaveState *slave; i2c_bus *bus; qemu_irq irq; - target_phys_addr_t offset; + uint32_t offset; + uint32_t region_size; uint16_t control; uint16_t status; @@ -1499,27 +1501,42 @@ static I2CSlaveInfo pxa2xx_i2c_slave_info = { PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base, qemu_irq irq, uint32_t region_size) { - int iomemtype; DeviceState *dev; - PXA2xxI2CState *s = qemu_mallocz(sizeof(PXA2xxI2CState)); + SysBusDevice *i2c_dev; + PXA2xxI2CState *s; + + i2c_dev = sysbus_from_qdev(qdev_create(NULL, "pxa2xx_i2c")); + qdev_prop_set_uint32(&i2c_dev->qdev, "size", region_size + 1); + qdev_prop_set_uint32(&i2c_dev->qdev, "offset", + base - (base & (~region_size) & TARGET_PAGE_MASK)); + + qdev_init_nofail(&i2c_dev->qdev); + + sysbus_mmio_map(i2c_dev, 0, base & ~region_size); + sysbus_connect_irq(i2c_dev, 0, irq); + s = FROM_SYSBUS(PXA2xxI2CState, i2c_dev); /* FIXME: Should the slave device really be on a separate bus? */ dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0); s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE_FROM_QDEV(dev)); s->slave->host = s; - s->irq = irq; - s->bus = i2c_init_bus(NULL, "i2c"); - s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK); + return s; +} + +static int pxa2xx_i2c_initfn(SysBusDevice *dev) +{ + PXA2xxI2CState *s = FROM_SYSBUS(PXA2xxI2CState, dev); + int iomemtype; + + s->bus = i2c_init_bus(&dev->qdev, "i2c"); iomemtype = cpu_register_io_memory(pxa2xx_i2c_readfn, pxa2xx_i2c_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base & ~region_size, - region_size + 1, iomemtype); - - vmstate_register(NULL, base, &vmstate_pxa2xx_i2c, s); + sysbus_init_mmio(dev, s->region_size, iomemtype); + sysbus_init_irq(dev, &s->irq); - return s; + return 0; } i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s) @@ -1527,6 +1544,19 @@ i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s) return s->bus; } +static SysBusDeviceInfo pxa2xx_i2c_info = { + .init = pxa2xx_i2c_initfn, + .qdev.name = "pxa2xx_i2c", + .qdev.desc = "PXA2xx I2C Bus Controller", + .qdev.size = sizeof(PXA2xxI2CState), + .qdev.vmsd = &vmstate_pxa2xx_i2c, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000), + DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0), + DEFINE_PROP_END_OF_LIST(), + }, +}; + /* PXA Inter-IC Sound Controller */ static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s) { @@ -2287,6 +2317,7 @@ static void pxa2xx_register_devices(void) { i2c_register_slave(&pxa2xx_i2c_slave_info); sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init); + sysbus_register_withprop(&pxa2xx_i2c_info); } device_init(pxa2xx_register_devices) diff --git a/hw/qdev.c b/hw/qdev.c index c7fec44a83..1aa1ea0e26 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -106,6 +106,18 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) initialize the actual device emulation. */ DeviceState *qdev_create(BusState *bus, const char *name) { + DeviceState *dev; + + dev = qdev_try_create(bus, name); + if (!dev) { + hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name); + } + + return dev; +} + +DeviceState *qdev_try_create(BusState *bus, const char *name) +{ DeviceInfo *info; if (!bus) { @@ -114,7 +126,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) info = qdev_find_info(bus->info, name); if (!info) { - hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name); + return NULL; } return qdev_create_from_info(bus, info); diff --git a/hw/qdev.h b/hw/qdev.h index 9808f85119..8a13ec95cc 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -122,6 +122,7 @@ typedef struct GlobalProperty { /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); +DeviceState *qdev_try_create(BusState *bus, const char *name); int qdev_device_help(QemuOpts *opts); DeviceState *qdev_device_add(QemuOpts *opts); int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 488eedd2cd..b05e6547df 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -239,7 +239,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) r->status |= SCSI_REQ_STATUS_RETRY | type; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + vm_stop(VMSTOP_DISKFULL); } else { if (type == SCSI_REQ_STATUS_RETRY_READ) { r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0); diff --git a/hw/sysbus.c b/hw/sysbus.c index 1583bd8589..acad72abe4 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -173,11 +173,43 @@ DeviceState *sysbus_create_varargs(const char *name, return dev; } +DeviceState *sysbus_try_create_varargs(const char *name, + target_phys_addr_t addr, ...) +{ + DeviceState *dev; + SysBusDevice *s; + va_list va; + qemu_irq irq; + int n; + + dev = qdev_try_create(NULL, name); + if (!dev) { + return NULL; + } + s = sysbus_from_qdev(dev); + qdev_init_nofail(dev); + if (addr != (target_phys_addr_t)-1) { + sysbus_mmio_map(s, 0, addr); + } + va_start(va, addr); + n = 0; + while (1) { + irq = va_arg(va, qemu_irq); + if (!irq) { + break; + } + sysbus_connect_irq(s, n, irq); + n++; + } + return dev; +} + static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) { SysBusDevice *s = sysbus_from_qdev(dev); int i; + monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq); for (i = 0; i < s->num_mmio; i++) { monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", indent, "", s->mmio[i].addr, s->mmio[i].size); diff --git a/hw/sysbus.h b/hw/sysbus.h index e9eb618a72..4e8cb16d42 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -57,6 +57,8 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr); /* Legacy helper function for creating devices. */ DeviceState *sysbus_create_varargs(const char *name, target_phys_addr_t addr, ...); +DeviceState *sysbus_try_create_varargs(const char *name, + target_phys_addr_t addr, ...); static inline DeviceState *sysbus_create_simple(const char *name, target_phys_addr_t addr, qemu_irq irq) @@ -64,4 +66,11 @@ static inline DeviceState *sysbus_create_simple(const char *name, return sysbus_create_varargs(name, addr, irq, NULL); } +static inline DeviceState *sysbus_try_create_simple(const char *name, + target_phys_addr_t addr, + qemu_irq irq) +{ + return sysbus_try_create_varargs(name, addr, irq, NULL); +} + #endif /* !HW_SYSBUS_H */ diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index c3fbe4e205..ed49e944df 100644 --- a/hw/tc6393xb.c +++ b/hw/tc6393xb.c @@ -8,7 +8,6 @@ * This code is licensed under the GNU GPL v2. */ #include "hw.h" -#include "pxa.h" #include "devices.h" #include "flash.h" #include "console.h" @@ -381,7 +380,7 @@ static void tc6393xb_nand_writeb(TC6393xbState *s, target_phys_addr_t addr, uint case NAND_DATA + 2: case NAND_DATA + 3: nand_setio(s->flash, value); - s->nand.isr &= 1; + s->nand.isr |= 1; tc6393xb_nand_irq(s); return; case NAND_MODE: diff --git a/hw/tosa.c b/hw/tosa.c index 0bfab1634a..b8b6c4f390 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -25,6 +25,7 @@ #define TOSA_RAM 0x04000000 #define TOSA_ROM 0x00800000 +#define TOSA_GPIO_USB_IN (5) #define TOSA_GPIO_nSD_DETECT (9) #define TOSA_GPIO_ON_RESET (19) #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ @@ -115,6 +116,9 @@ static void tosa_gpio_setup(PXA2xxState *cpu, qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio)); + + /* UDC Vbus */ + qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN)); } static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value) diff --git a/hw/vga.c b/hw/vga.c index e2151a2458..c22b8af833 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -28,7 +28,6 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" -#include "kvm.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -1573,34 +1572,36 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) void vga_dirty_log_start(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_start(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_start(isa_mem_base + 0xa0000, 0x8000); - kvm_log_start(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } void vga_dirty_log_stop(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_stop(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_stop(isa_mem_base + 0xa0000, 0x8000); - kvm_log_stop(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } diff --git a/hw/vhost.c b/hw/vhost.c index 38cc3b365b..0ca3507f44 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -607,6 +607,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) hdev->client.set_memory = vhost_client_set_memory; hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; hdev->client.migration_log = vhost_client_migration_log; + hdev->client.log_start = NULL; + hdev->client.log_stop = NULL; hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); hdev->log = NULL; hdev->log_size = 0; diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index ffac5a4d8f..b14fb995e8 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -78,7 +78,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, req->next = s->rq; s->rq = req; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + vm_stop(VMSTOP_DISKFULL); } else { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); diff --git a/hw/vmmouse.c b/hw/vmmouse.c index 209711942f..ab8dbd6ccb 100644 --- a/hw/vmmouse.c +++ b/hw/vmmouse.c @@ -25,6 +25,7 @@ #include "console.h" #include "ps2.h" #include "pc.h" +#include "qdev.h" /* debug only vmmouse */ //#define DEBUG_VMMOUSE @@ -52,6 +53,7 @@ typedef struct _VMMouseState { + ISADevice dev; uint32_t queue[VMMOUSE_QUEUE_SIZE]; int32_t queue_size; uint16_t nb_queue; @@ -176,30 +178,6 @@ static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size) memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue); } -static void vmmouse_get_data(uint32_t *data) -{ - CPUState *env = cpu_single_env; - - data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX]; - data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX]; - data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI]; - - DPRINTF("get_data = {%x, %x, %x, %x, %x, %x}\n", - data[0], data[1], data[2], data[3], data[4], data[5]); -} - -static void vmmouse_set_data(const uint32_t *data) -{ - CPUState *env = cpu_single_env; - - DPRINTF("set_data = {%x, %x, %x, %x, %x, %x}\n", - data[0], data[1], data[2], data[3], data[4], data[5]); - - env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1]; - env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3]; - env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; -} - static uint32_t vmmouse_ioport_read(void *opaque, uint32_t addr) { VMMouseState *s = opaque; @@ -270,22 +248,42 @@ static const VMStateDescription vmstate_vmmouse = { } }; -void *vmmouse_init(void *m) +static void vmmouse_reset(DeviceState *d) { - VMMouseState *s = NULL; - - DPRINTF("vmmouse_init\n"); - - s = qemu_mallocz(sizeof(VMMouseState)); + VMMouseState *s = container_of(d, VMMouseState, dev.qdev); s->status = 0xffff; - s->ps2_mouse = m; s->queue_size = VMMOUSE_QUEUE_SIZE; +} + +static int vmmouse_initfn(ISADevice *dev) +{ + VMMouseState *s = DO_UPCAST(VMMouseState, dev, dev); + + DPRINTF("vmmouse_init\n"); vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s); vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s); vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s); vmstate_register(NULL, 0, &vmstate_vmmouse, s); - return s; + return 0; +} + +static ISADeviceInfo vmmouse_info = { + .init = vmmouse_initfn, + .qdev.name = "vmmouse", + .qdev.size = sizeof(VMMouseState), + .qdev.no_user = 1, + .qdev.reset = vmmouse_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void vmmouse_dev_register(void) +{ + isa_qdev_register(&vmmouse_info); } +device_init(vmmouse_dev_register) diff --git a/hw/vmport.c b/hw/vmport.c index 6c9d7c9651..292d78ffb4 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -26,6 +26,7 @@ #include "pc.h" #include "sysemu.h" #include "kvm.h" +#include "qdev.h" //#define VMPORT_DEBUG @@ -37,6 +38,7 @@ typedef struct _VMPortState { + ISADevice dev; IOPortReadFunc *func[VMPORT_ENTRIES]; void *opaque[VMPORT_ENTRIES]; } VMPortState; @@ -100,12 +102,47 @@ static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr) return ram_size; } -void vmport_init(void) +/* vmmouse helpers */ +void vmmouse_get_data(uint32_t *data) { - register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &port_state); - register_ioport_write(0x5658, 1, 4, vmport_ioport_write, &port_state); + CPUState *env = cpu_single_env; + + data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX]; + data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX]; + data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI]; +} + +void vmmouse_set_data(const uint32_t *data) +{ + CPUState *env = cpu_single_env; + + env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1]; + env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3]; + env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; +} + +static int vmport_initfn(ISADevice *dev) +{ + VMPortState *s = DO_UPCAST(VMPortState, dev, dev); + register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &s); + register_ioport_write(0x5658, 1, 4, vmport_ioport_write, &s); + isa_init_ioport(dev, 0x5658); /* Register some generic port commands */ vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL); vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL); + return 0; +} + +static ISADeviceInfo vmport_info = { + .qdev.name = "vmport", + .qdev.size = sizeof(VMPortState), + .qdev.no_user = 1, + .init = vmport_initfn, +}; + +static void vmport_dev_register(void) +{ + isa_qdev_register(&vmport_info); } +device_init(vmport_dev_register) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 6c59053308..4656767964 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1309,11 +1309,6 @@ static int pci_vmsvga_initfn(PCIDevice *dev) return 0; } -void pci_vmsvga_init(PCIBus *bus) -{ - pci_create_simple(bus, -1, "vmware-svga"); -} - static PCIDeviceInfo vmsvga_info = { .qdev.name = "vmware-svga", .qdev.size = sizeof(struct pci_vmsvga_state_s), diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h index 2e0813c81b..5132573a56 100644 --- a/hw/vmware_vga.h +++ b/hw/vmware_vga.h @@ -4,6 +4,16 @@ #include "qemu-common.h" /* vmware_vga.c */ -void pci_vmsvga_init(PCIBus *bus); +static inline bool pci_vmsvga_init(PCIBus *bus) +{ + PCIDevice *dev; + + dev = pci_try_create(bus, -1, "vmware-svga"); + if (!dev || qdev_init(&dev->qdev) < 0) { + return false; + } else { + return true; + } +} #endif diff --git a/hw/watchdog.c b/hw/watchdog.c index e9dd56e229..1c900a1189 100644 --- a/hw/watchdog.c +++ b/hw/watchdog.c @@ -132,7 +132,7 @@ void watchdog_perform_action(void) case WDT_PAUSE: /* same as 'stop' command in monitor */ watchdog_mon_event("pause"); - vm_stop(0); + vm_stop(VMSTOP_WATCHDOG); break; case WDT_DEBUG: diff --git a/hw/zaurus.c b/hw/zaurus.c index fca11a5333..c24aeb5763 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -16,7 +16,6 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "hw.h" -#include "pxa.h" #include "sharpsl.h" #include "sysbus.h" @@ -181,17 +180,34 @@ static int scoop_init(SysBusDevice *dev) return 0; } +static int scoop_post_load(void *opaque, int version_id) +{ + ScoopInfo *s = (ScoopInfo *) opaque; + int i; + uint32_t level; + + level = s->gpio_level & s->gpio_dir; + + for (i = 0; i < 16; i++) { + qemu_set_irq(s->handler[i], (level >> i) & 1); + } + + s->prev_level = level; + + return 0; +} + static bool is_version_0 (void *opaque, int version_id) { return version_id == 0; } - static const VMStateDescription vmstate_scoop_regs = { .name = "scoop", .version_id = 1, .minimum_version_id = 0, .minimum_version_id_old = 0, + .post_load = scoop_post_load, .fields = (VMStateField []) { VMSTATE_UINT16(status, ScoopInfo), VMSTATE_UINT16(power, ScoopInfo), |