From 6fc97fafce05eee76479ca6d289241772d21b370 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 4 Mar 2012 08:21:39 +0100 Subject: target-mips: Fix some helper functions (VR54xx multiplication) Commits b5dc7732e1cc2fb549e48b7b5d664f2c79628e2e and be24bb4f3007c3e07cbf1934f7e781493d876ab7 optimized the code and removed the correct setting of t0. Fix this. gcc-4.7 detected this bug because parameter arg1 was unused but set in set_HIT0_LO and set_HI_LOT0. Cc: Aurelien Jarno Signed-off-by: Stefan Weil Signed-off-by: Aurelien Jarno --- target-mips/op_helper.c | 75 +++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 66037acec..e5bc93e22 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -192,115 +192,98 @@ static inline uint64_t get_HILO (void) return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0]; } -static inline void set_HIT0_LO (target_ulong arg1, uint64_t HILO) +static inline target_ulong set_HIT0_LO(uint64_t HILO) { + target_ulong tmp; env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); - arg1 = env->active_tc.HI[0] = (int32_t)(HILO >> 32); + tmp = env->active_tc.HI[0] = (int32_t)(HILO >> 32); + return tmp; } -static inline void set_HI_LOT0 (target_ulong arg1, uint64_t HILO) +static inline target_ulong set_HI_LOT0(uint64_t HILO) { - arg1 = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); + target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); env->active_tc.HI[0] = (int32_t)(HILO >> 32); + return tmp; } /* Multiplication variants of the vr54xx. */ target_ulong helper_muls (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HI_LOT0(0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); } target_ulong helper_mulsu (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HI_LOT0(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); } target_ulong helper_macc (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, ((int64_t)get_HILO()) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HI_LOT0((int64_t)get_HILO() + (int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2); } target_ulong helper_macchi (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, ((int64_t)get_HILO()) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HIT0_LO((int64_t)get_HILO() + (int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2); } target_ulong helper_maccu (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HI_LOT0((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); } target_ulong helper_macchiu (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HIT0_LO((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); } target_ulong helper_msac (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, ((int64_t)get_HILO()) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HI_LOT0((int64_t)get_HILO() - (int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2); } target_ulong helper_msachi (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, ((int64_t)get_HILO()) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HIT0_LO((int64_t)get_HILO() - (int64_t)(int32_t)arg1 * + (int64_t)(int32_t)arg2); } target_ulong helper_msacu (target_ulong arg1, target_ulong arg2) { - set_HI_LOT0(arg1, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HI_LOT0((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); } target_ulong helper_msachiu (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HIT0_LO((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 * + (uint64_t)(uint32_t)arg2); } target_ulong helper_mulhi (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); - - return arg1; + return set_HIT0_LO((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); } target_ulong helper_mulhiu (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); - - return arg1; + return set_HIT0_LO((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); } target_ulong helper_mulshi (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2)); - - return arg1; + return set_HIT0_LO(0 - (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); } target_ulong helper_mulshiu (target_ulong arg1, target_ulong arg2) { - set_HIT0_LO(arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2)); - - return arg1; + return set_HIT0_LO(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); } #ifdef TARGET_MIPS64 -- cgit v1.2.3 From 26efaca377e004b79ff50a6e936d029a0c095b8b Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Thu, 23 Aug 2012 13:49:02 -0500 Subject: monitor: don't try to initialize json parser when monitor is HMP Reported-by: Michael Roth Signed-off-by: Anthony Liguori --- monitor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index b18858205..b17b1bb84 100644 --- a/monitor.c +++ b/monitor.c @@ -4946,13 +4946,13 @@ void monitor_init(CharDriverState *chr, int flags) qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, monitor_control_event, mon); qemu_chr_fe_set_echo(chr, true); + + json_message_parser_init(&mon->mc->parser, handle_qmp_command); } else { qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event, mon); } - json_message_parser_init(&mon->mc->parser, handle_qmp_command); - QLIST_INSERT_HEAD(&mon_list, mon, entry); if (!default_mon || (flags & MONITOR_IS_DEFAULT)) default_mon = mon; -- cgit v1.2.3 From da5a44e8b0b727681fc33e8d94832d1cae48a788 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Aug 2012 23:09:46 +0200 Subject: qom: object_delete should unparent the object first object_deinit is only called when the reference count goes to zero, and yet tries to do an object_unparent. Now, object_unparent either does nothing or it will decrease the reference count. Because we know the reference count is zero, the object_unparent call in object_deinit is useless. Instead, we need to disconnect the object from its parent just before we remove the last reference apart from the parent's. This happens in object_delete. Once we do this, all calls to object_unparent peppered through QEMU can go away. Signed-off-by: Paolo Bonzini Signed-off-by: Anthony Liguori --- hw/acpi_piix4.c | 1 - hw/qdev.c | 2 -- hw/shpc.c | 1 - hw/xen_platform.c | 3 --- qom/object.c | 5 ++--- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 0aace60f2..72d6e5c90 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -305,7 +305,6 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) if (pc->no_hotplug) { slot_free = false; } else { - object_unparent(OBJECT(dev)); qdev_free(qdev); } } diff --git a/hw/qdev.c b/hw/qdev.c index b5b74b913..b5a52ac50 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -159,7 +159,6 @@ int qdev_init(DeviceState *dev) rc = dc->init(dev); if (rc < 0) { - object_unparent(OBJECT(dev)); qdev_free(dev); return rc; } @@ -243,7 +242,6 @@ void qbus_reset_all_fn(void *opaque) int qdev_simple_unplug_cb(DeviceState *dev) { /* just zap it */ - object_unparent(OBJECT(dev)); qdev_free(dev); return 0; } diff --git a/hw/shpc.c b/hw/shpc.c index 6b9884d54..a5baf246f 100644 --- a/hw/shpc.c +++ b/hw/shpc.c @@ -253,7 +253,6 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) ++devfn) { PCIDevice *affected_dev = shpc->sec_bus->devices[devfn]; if (affected_dev) { - object_unparent(OBJECT(affected_dev)); qdev_free(&affected_dev->qdev); } } diff --git a/hw/xen_platform.c b/hw/xen_platform.c index c1fe984f0..0d6c2ff8c 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -87,9 +87,6 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o) { if (pci_get_word(d->config + PCI_CLASS_DEVICE) == PCI_CLASS_NETWORK_ETHERNET) { - /* Until qdev_free includes a call to object_unparent, we call it here - */ - object_unparent(&d->qdev.parent_obj); qdev_free(&d->qdev); } } diff --git a/qom/object.c b/qom/object.c index a552be258..e3e924263 100644 --- a/qom/object.c +++ b/qom/object.c @@ -373,8 +373,6 @@ static void object_deinit(Object *obj, TypeImpl *type) if (type_has_parent(type)) { object_deinit(obj, type_get_parent(type)); } - - object_unparent(obj); } void object_finalize(void *data) @@ -411,8 +409,9 @@ Object *object_new(const char *typename) void object_delete(Object *obj) { + object_unparent(obj); + g_assert(obj->ref == 1); object_unref(obj); - g_assert(obj->ref == 0); g_free(obj); } -- cgit v1.2.3 From 98609cd8fcf755c0ba7049d751353b8b2e243b65 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Aug 2012 23:09:47 +0200 Subject: ivshmem: fix memory_region_del_eventfd assertion failure We do not register ioeventfds unless the IVSHMEM_IOEVENTFD feature is set. The same feature must be checked before releasing the eventfds. Regression introduced by commit 563027c (ivshmem: use EventNotifier and memory API, 2012-07-05). Reported-by: Cam Macdonnell Tested-by: Cam Macdonnell Signed-off-by: Paolo Bonzini Signed-off-by: Anthony Liguori --- hw/ivshmem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index b4d65a6db..47f2a1683 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -366,6 +366,10 @@ static void close_guest_eventfds(IVShmemState *s, int posn) { int i, guest_curr_max; + if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { + return; + } + guest_curr_max = s->peers[posn].nb_eventfds; memory_region_transaction_begin(); -- cgit v1.2.3 From 145c7c880ff520a9348cc2401ba291330b9606fe Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:38 -0600 Subject: fix some debug printf format strings These are normally ifdefed out and don't matter. But if you enable them, they ought to be correct. Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- hw/cirrus_vga.c | 4 ++-- hw/i8259.c | 3 ++- hw/ide/cmd646.c | 5 +++-- hw/ide/via.c | 5 +++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index e8dcc6b88..909899dd5 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2055,8 +2055,8 @@ static void cirrus_vga_mem_write(void *opaque, } } else { #ifdef DEBUG_CIRRUS - printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr, - mem_value); + printf("cirrus: mem_writeb " TARGET_FMT_plx " value %" PRIx64 "\n", + addr, mem_value); #endif } } diff --git a/hw/i8259.c b/hw/i8259.c index 53daf7865..65876662a 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -355,7 +355,8 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, ret = s->imr; } } - DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret); + DPRINTF("read: addr=0x%02" TARGET_PRIxPHYS " val=0x%02x\n", + addr, ret); return ret; } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index e0b944349..dd2855e19 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -154,7 +154,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE - printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); + printf("bmdma: readb 0x%02" TARGET_PRIxPHYS " : 0x%02x\n", addr, val); #endif return val; } @@ -170,7 +170,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE - printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); + printf("bmdma: writeb 0x%02" TARGET_PRIxPHYS " : 0x%02" PRIx64 "\n", + addr, val); #endif switch(addr & 3) { case 0: diff --git a/hw/ide/via.c b/hw/ide/via.c index b20e4f094..948a46938 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -55,7 +55,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE - printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); + printf("bmdma: readb 0x%02" TARGET_PRIxPHYS " : 0x%02x\n", addr, val); #endif return val; } @@ -70,7 +70,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE - printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); + printf("bmdma: writeb 0x%02" TARGET_PRIxPHYS " : 0x%02" PRIx64 "\n", + addr, val); #endif switch (addr & 3) { case 0: -- cgit v1.2.3 From 5c73b757e3aa80dc84352b2ede0d8bdea5419f6d Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:39 -0600 Subject: target-i386/translate.c: mov to/from crN/drN: ignore mod bits > This instruction is always treated as a register-to-register (MOD = 11) > instruction, regardless of the encoding of the MOD field in the MODR/M > byte. Also, Microport UNIX System V/386 v 2.1 (ca 1987) runs fine on real Intel 386 and 486 CPU's (at least), but does not run in qemu without this patch. Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- target-i386/translate.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 7ab2ccb19..eb0cabcf1 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7551,8 +7551,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = cpu_ldub_code(cpu_single_env, s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) @@ -7594,8 +7597,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = cpu_ldub_code(cpu_single_env, s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) -- cgit v1.2.3 From 7764ae9671f1cd74227cf4404431dd5213799ef0 Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:40 -0600 Subject: vl: fix -hdachs/-hda argument order parsing issues Without this patch, the -hdachs argument had to occur either BEFORE the corresponding "-hda" option, or AFTER the plain disk image name (if neither -hda nor -drive is used). Otherwise it would effectively be ignored. Option -hdachs still has no effect on -drive, but that seems best. Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- vl.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/vl.c b/vl.c index 7c577fa54..febfd62c3 100644 --- a/vl.c +++ b/vl.c @@ -2352,8 +2352,9 @@ int main(int argc, char **argv, char **envp) char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */ DisplayState *ds; DisplayChangeListener *dcl; - int cyls, heads, secs, translation; - QemuOpts *hda_opts = NULL, *opts, *machine_opts; + char hdachs_params[512]; /* save -hdachs to apply to later -hda */ + QemuOpts *hda_opts = NULL; /* save -hda to be modified by later -hdachs */ + QemuOpts *opts, *machine_opts; QemuOptsList *olist; int optind; const char *optarg; @@ -2408,8 +2409,7 @@ int main(int argc, char **argv, char **envp) cpu_model = NULL; ram_size = 0; snapshot = 0; - cyls = heads = secs = 0; - translation = BIOS_ATA_TRANSLATION_AUTO; + snprintf(hdachs_params, sizeof(hdachs_params), "%s", HD_OPTS); for (i = 0; i < MAX_NODES; i++) { node_mem[i] = 0; @@ -2457,7 +2457,7 @@ int main(int argc, char **argv, char **envp) if (optind >= argc) break; if (argv[optind][0] != '-') { - hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS); + hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], hdachs_params); } else { const QEMUOption *popt; @@ -2475,21 +2475,8 @@ int main(int argc, char **argv, char **envp) cpu_model = optarg; break; case QEMU_OPTION_hda: - { - char buf[256]; - if (cyls == 0) - snprintf(buf, sizeof(buf), "%s", HD_OPTS); - else - snprintf(buf, sizeof(buf), - "%s,cyls=%d,heads=%d,secs=%d%s", - HD_OPTS , cyls, heads, secs, - translation == BIOS_ATA_TRANSLATION_LBA ? - ",trans=lba" : - translation == BIOS_ATA_TRANSLATION_NONE ? - ",trans=none" : ""); - drive_add(IF_DEFAULT, 0, optarg, buf); - break; - } + hda_opts = drive_add(IF_DEFAULT, 0, optarg, hdachs_params); + break; case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: case QEMU_OPTION_hdd: @@ -2523,7 +2510,10 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_hdachs: { + int cyls, heads, secs, translation; const char *p; + cyls = heads = secs = 0; + translation = BIOS_ATA_TRANSLATION_AUTO; p = optarg; cyls = strtol(p, (char **)&p, 0); if (cyls < 1 || cyls > 16383) @@ -2555,7 +2545,14 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "qemu: invalid physical CHS format\n"); exit(1); } - if (hda_opts != NULL) { + snprintf(hdachs_params, sizeof(hdachs_params), + "%s,cyls=%d,heads=%d,secs=%d%s", + HD_OPTS , cyls, heads, secs, + translation == BIOS_ATA_TRANSLATION_LBA ? + ",trans=lba" : + translation == BIOS_ATA_TRANSLATION_NONE ? + ",trans=none" : ""); + if (hda_opts != NULL) { char num[16]; snprintf(num, sizeof(num), "%d", cyls); qemu_opt_set(hda_opts, "cyls", num); -- cgit v1.2.3 From 39dda260628e5f2a3fd2ce2ec8a71f3d5ca309a9 Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:41 -0600 Subject: qemu-options.hx: mention retrace= VGA option The feature was added in commit cb5a7aa8c32141bb Sep 2008. My description is based on "Better VGA retrace emulation (needed for some DOS games/demos)" from http://www.boblycat.org/~malc/code/patches/qemu/index.html Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- qemu-options.hx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 3c411c427..3e8085d46 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -945,7 +945,7 @@ DEF("vga", HAS_ARG, QEMU_OPTION_vga, "-vga [std|cirrus|vmware|qxl|xenfb|none]\n" " select video card type\n", QEMU_ARCH_ALL) STEXI -@item -vga @var{type} +@item -vga @var{type}[,@var{prop}=@var{value}[,...]] @findex -vga Select type of VGA card to emulate. Valid values for @var{type} are @table @option @@ -970,6 +970,12 @@ Recommended choice when using the spice protocol. @item none Disable VGA card. @end table +Valid optional properties are +@table @option +@item retrace=dumb|precise +Select dumb (default) or precise VGA retrace logic, useful for some +DOS games/demos. +@end table ETEXI DEF("full-screen", 0, QEMU_OPTION_full_screen, -- cgit v1.2.3 From 482f7bf86b43af9f6903c52726fedf82b28bf953 Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:42 -0600 Subject: vga: add some optional CGA compatibility hacks This patch adds some optional compatibility hacks (default disabled) to allow Microport UNIX to function under qemu. I've tried to structure it to be easy to add more hacks for other old CGA programs, if anyone ever needs them. Microport UNIX System V/386 v 2.1 (ca 1987) tries to program the CGA registers directly with neither the assistance of BIOS, nor with proper handling of EGA/VGA-only registers. Note that it didn't work on real VGA hardware, either (although in that case, the most obvious problems seemed to be out-of-range hsync and/or vsync signalling, rather than the issues in this patch). Eventually real MDA and/or CGA support might provide an alternative to this patch, although a hybrid approach like this patch might still be useful in marginal cases. Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- hw/pc.h | 4 ++++ hw/vga.c | 36 ++++++++++++++++++++++++++++-------- qemu-options.hx | 19 +++++++++++++++++++ vl.c | 23 +++++++++++++++++++++++ 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index e4db0715b..37e2f8758 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -176,6 +176,10 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; +#define VGA_CGA_HACK_PALETTE_BLANKING (1<<0) +#define VGA_CGA_HACK_FONT_HEIGHT (1<<1) +extern int vga_cga_hacks; + static inline DeviceState *isa_vga_init(ISABus *bus) { ISADevice *dev; diff --git a/hw/vga.c b/hw/vga.c index f82ced8e6..a65fc26ab 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -547,14 +547,31 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("vga: write CR%x = 0x%02x\n", s->cr_index, val); #endif /* handle CR0-7 protection */ - if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) && - s->cr_index <= VGA_CRTC_OVERFLOW) { - /* can always write bit 4 of CR7 */ - if (s->cr_index == VGA_CRTC_OVERFLOW) { - s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | - (val & 0x10); + if (s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) { + if (s->cr_index <= VGA_CRTC_OVERFLOW) { + /* can always write bit 4 of CR7 */ + if (s->cr_index == VGA_CRTC_OVERFLOW) { + s->cr[VGA_CRTC_OVERFLOW] = + (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | (val & 0x10); + } + return; + } else if ((vga_cga_hacks & VGA_CGA_HACK_FONT_HEIGHT) && + !(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { + /* extra CGA compatibility hacks (not in standard VGA) */ + if (s->cr_index == VGA_CRTC_MAX_SCAN && + val == 7 && + (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { + return; + } else if (s->cr_index == VGA_CRTC_CURSOR_START && + val == 6 && + (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { + val = 0xd; + } else if (s->cr_index == VGA_CRTC_CURSOR_END && + val == 7 && + (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { + val = 0xe; + } } - return; } s->cr[s->cr_index] = val; @@ -1886,7 +1903,10 @@ static void vga_update_display(void *opaque) /* nothing to do */ } else { full_update = 0; - if (!(s->ar_index & 0x20)) { + if (!(s->ar_index & 0x20) && + /* extra CGA compatibility hacks (not in standard VGA */ + (!(vga_cga_hacks & VGA_CGA_HACK_PALETTE_BLANKING) || + (s->ar_index != 0 && s->ar_flip_flop))) { graphic_mode = GMODE_BLANK; } else { graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE; diff --git a/qemu-options.hx b/qemu-options.hx index 3e8085d46..0682338e9 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -975,6 +975,25 @@ Valid optional properties are @item retrace=dumb|precise Select dumb (default) or precise VGA retrace logic, useful for some DOS games/demos. +@item cga_hacks=@var{hack1}[+@var{hack2},[...]] +Enable various extra CGA compatibility hacks for programs that are +trying to directly set CGA modes without BIOS assistance nor +real knowledge of EGA/VGA. These might only work with -vga std. +Valid hacks are +@table @option +@item palette_blanking +Wait to blank the screen until palette registers seem to actually be +modified, instead of blanking it as soon as the palette address bit (0x10) +of the attribute address register (0x3c0) is cleared. +@item font_height +Ignore attempts to change the VGA font height (index 9), +cursor start (index 10), and cursor end (index 11) of the CRTC control +registers (0x3d5) if trying to set them to the default for CGA fonts +instead of VGA fonts. +@item all +Enable all CGA hacks. More CGA hacks may be added in future versions +of qemu. +@end table @end table ETEXI diff --git a/vl.c b/vl.c index febfd62c3..16d04a2ee 100644 --- a/vl.c +++ b/vl.c @@ -179,6 +179,7 @@ int main(int argc, char **argv) static const char *data_dir; const char *bios_name = NULL; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; +int vga_cga_hacks = 0; DisplayType display_type = DT_DEFAULT; int display_remote = 0; const char* keyboard_layout = NULL; @@ -1748,6 +1749,28 @@ static void select_vgahw (const char *p) else if (strstart(opts, "precise", &nextopt)) vga_retrace_method = VGA_RETRACE_PRECISE; else goto invalid_vga; + } else if (strstart(opts, ",cga_hacks=", &nextopt)) { + opts = nextopt; + while (*opts) { + if (strstart(opts, "all", &nextopt)) { + opts = nextopt; + vga_cga_hacks |= ~0; + } else if (strstart(opts, "palette_blanking", &nextopt)) { + opts = nextopt; + vga_cga_hacks |= VGA_CGA_HACK_PALETTE_BLANKING; + } else if (strstart(opts, "font_height", &nextopt)) { + opts = nextopt; + vga_cga_hacks |= VGA_CGA_HACK_FONT_HEIGHT; + } else { + break; + } + + if (*opts == '+') { + opts++; + } else { + break; + } + } } else goto invalid_vga; opts = nextopt; } -- cgit v1.2.3 From f278d4947fff814dcde2ef2acad36d172ff8be35 Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:43 -0600 Subject: i8259: add -no-spurious-interrupt-hack option This patch provides a way to optionally suppress spurious interrupts, as a workaround for systems described below: Some old operating systems do not handle spurious interrupts well, and qemu tends to generate them significantly more often than real hardware. Examples: - Microport UNIX System V/386 v 2.1 (ca 1987) (The main problem I'm fixing: Without this patch, it panics sporadically when accessing the hard disk.) - AT&T UNIX System V/386 Release 4.0 Version 2.1a (ca 1991) See screenshot in "QEMU Official OS Support List": http://www.claunia.com/qemu/objectManager.php?sClass=application&iId=9 (I don't have this system to test.) - A report about OS/2 boot lockup from 2004 by Hampa Hug: http://lists.nongnu.org/archive/html/qemu-devel/2004-09/msg00367.html (My patch was partially inspired by his.) Also: http://lists.nongnu.org/archive/html/qemu-devel/2005-06/msg00243.html (I don't have this system to test.) Signed-off-by: Matthew Ogilvie Signed-off-by: malc --- cpu-exec.c | 14 +++++++++----- hw/i8259.c | 18 ++++++++++++++++++ qemu-options.hx | 12 ++++++++++++ sysemu.h | 1 + vl.c | 4 ++++ 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 134b3c4fc..625fbb0e0 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -329,11 +329,15 @@ int cpu_exec(CPUArchState *env) 0); env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); - qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); - do_interrupt_x86_hardirq(env, intno, 1); - /* ensure that no TB jump will be modified as - the program flow was changed */ - next_tb = 0; + if (intno >= 0) { + qemu_log_mask(CPU_LOG_TB_IN_ASM, + "Servicing hardware INT=0x%02x\n", + intno); + do_interrupt_x86_hardirq(env, intno, 1); + /* ensure that no TB jump will be modified as + the program flow was changed */ + next_tb = 0; + } #if !defined(CONFIG_USER_ONLY) } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && (env->eflags & IF_MASK) && diff --git a/hw/i8259.c b/hw/i8259.c index 65876662a..7ecb7e1de 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -26,6 +26,7 @@ #include "isa.h" #include "monitor.h" #include "qemu-timer.h" +#include "sysemu.h" #include "i8259_internal.h" /* debug PIC */ @@ -193,6 +194,20 @@ int pic_read_irq(DeviceState *d) pic_intack(slave_pic, irq2); } else { /* spurious IRQ on slave controller */ + if (no_spurious_interrupt_hack) { + /* Pretend it was delivered and acknowledged. If + * it was spurious due to slave_pic->imr, then + * as soon as the mask is cleared, the slave will + * re-trigger IRQ2 on the master. If it is spurious for + * some other reason, make sure we don't keep trying + * to half-process the same spurious interrupt over + * and over again. + */ + s->irr &= ~(1<last_irr &= ~(1<isr &= ~(1<irq_base + irq2; @@ -202,6 +217,9 @@ int pic_read_irq(DeviceState *d) pic_intack(s, irq); } else { /* spurious IRQ on host controller */ + if (no_spurious_interrupt_hack) { + return -1; + } irq = 7; intno = s->irq_base + irq; } diff --git a/qemu-options.hx b/qemu-options.hx index 0682338e9..2a6d82955 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1189,6 +1189,18 @@ Windows 2000 is installed, you no longer need this option (this option slows down the IDE transfers). ETEXI +DEF("no-spurious-interrupt-hack", 0, QEMU_OPTION_no_spurious_interrupt_hack, + "-no-spurious-interrupt-hack disable delivery of spurious interrupts\n", + QEMU_ARCH_I386) +STEXI +@item -no-spurious-interrupt-hack +@findex -no-spurious-interrupt-hack +Use it as a workaround for operating systems that drive PICs in a way that +can generate spurious interrupts, but the OS doesn't handle spurious +interrupts gracefully. (e.g. late 80s/early 90s versions of ATT UNIX +and derivatives) +ETEXI + HXCOMM Deprecated by -rtc DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, "", QEMU_ARCH_I386) diff --git a/sysemu.h b/sysemu.h index 65552acee..0170109e1 100644 --- a/sysemu.h +++ b/sysemu.h @@ -117,6 +117,7 @@ extern int graphic_depth; extern DisplayType display_type; extern const char *keyboard_layout; extern int win2k_install_hack; +extern int no_spurious_interrupt_hack; extern int alt_grab; extern int ctrl_grab; extern int usb_enabled; diff --git a/vl.c b/vl.c index 16d04a2ee..6de41c124 100644 --- a/vl.c +++ b/vl.c @@ -204,6 +204,7 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; int win2k_install_hack = 0; +int no_spurious_interrupt_hack = 0; int usb_enabled = 0; int singlestep = 0; int smp_cpus = 1; @@ -3046,6 +3047,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_win2k_hack: win2k_install_hack = 1; break; + case QEMU_OPTION_no_spurious_interrupt_hack: + no_spurious_interrupt_hack = 1; + break; case QEMU_OPTION_rtc_td_hack: { static GlobalProperty slew_lost_ticks[] = { { -- cgit v1.2.3 From 9716ef3b1b48ebbb4b6515fb4685a5db96ce41d9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 26 Aug 2012 14:40:02 +0100 Subject: tcg/arm: Fix broken CONFIG_TCG_PASS_AREG0 code The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers was broken in that it did not respect the ABI requirement that 64 bit values were passed in even-odd register pairs. The simplest way to fix this is to implement some new utility functions for marshalling function arguments into the correct registers and stack, so that the code which sets up the address and data arguments does not need to care whether there has been a preceding env argument. Signed-off-by: Peter Maydell Signed-off-by: Blue Swirl --- tcg/arm/tcg-target.c | 237 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 144 insertions(+), 93 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 4d59a6385..cf0ca3d0b 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -176,6 +176,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) so don't use these. */ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1); +#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64) + /* If we're passing env to the helper as r0 and need a regpair + * for the address then r2 will be overwritten as we're setting + * up the args to the helper. + */ + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2); +#endif #endif break; case 'L': @@ -197,6 +204,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) use these. */ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1); +#if defined(CONFIG_SOFTMMU) && \ + defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64) + /* Avoid clashes with registers being used for helper args */ + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2); + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3); +#endif break; /* qemu_st64 data_reg2 */ case 'S': @@ -210,6 +223,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) #ifdef CONFIG_SOFTMMU /* r2 is still needed to load data_reg, so don't use it. */ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2); +#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64) + /* Avoid clashes with registers being used for helper args */ + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3); +#endif #endif break; @@ -388,6 +405,14 @@ static inline void tcg_out_dat_reg(TCGContext *s, (rn << 16) | (rd << 12) | shift | rm); } +static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm) +{ + /* Simple reg-reg move, optimising out the 'do nothing' case */ + if (rd != rm) { + tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0)); + } +} + static inline void tcg_out_dat_reg2(TCGContext *s, int cond, int opc0, int opc1, int rd0, int rd1, int rn0, int rn1, int rm0, int rm1, int shift) @@ -966,6 +991,90 @@ static void *qemu_st_helpers[4] = { __stq_mmu, }; #endif + +/* Helper routines for marshalling helper function arguments into + * the correct registers and stack. + * argreg is where we want to put this argument, arg is the argument itself. + * Return value is the updated argreg ready for the next call. + * Note that argreg 0..3 is real registers, 4+ on stack. + * When we reach the first stacked argument, we allocate space for it + * and the following stacked arguments using "str r8, [sp, #-0x10]!". + * Following arguments are filled in with "str r8, [sp, #0xNN]". + * For more than 4 stacked arguments we'd need to know how much + * space to allocate when we pushed the first stacked argument. + * We don't need this, so don't implement it (and will assert if you try it.) + * + * We provide routines for arguments which are: immediate, 32 bit + * value in register, 16 and 8 bit values in register (which must be zero + * extended before use) and 64 bit value in a lo:hi register pair. + */ +#define DEFINE_TCG_OUT_ARG(NAME, ARGPARAM) \ + static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGPARAM) \ + { \ + if (argreg < 4) { \ + TCG_OUT_ARG_GET_ARG(argreg); \ + } else if (argreg == 4) { \ + TCG_OUT_ARG_GET_ARG(TCG_REG_R8); \ + tcg_out32(s, (COND_AL << 28) | 0x052d8010); \ + } else { \ + assert(argreg < 8); \ + TCG_OUT_ARG_GET_ARG(TCG_REG_R8); \ + tcg_out32(s, (COND_AL << 28) | 0x058d8000 | (argreg - 4) * 4); \ + } \ + return argreg + 1; \ + } + +#define TCG_OUT_ARG_GET_ARG(A) tcg_out_dat_imm(s, COND_AL, ARITH_MOV, A, 0, arg) +DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t arg) +#undef TCG_OUT_ARG_GET_ARG +#define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext8u(s, COND_AL, A, arg) +DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg arg) +#undef TCG_OUT_ARG_GET_ARG +#define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext16u(s, COND_AL, A, arg) +DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg arg) +#undef TCG_OUT_ARG_GET_ARG + +/* We don't use the macro for this one to avoid an unnecessary reg-reg + * move when storing to the stack. + */ +static TCGReg tcg_out_arg_reg32(TCGContext *s, TCGReg argreg, TCGReg arg) +{ + if (argreg < 4) { + tcg_out_mov_reg(s, COND_AL, argreg, arg); + } else if (argreg == 4) { + /* str arg, [sp, #-0x10]! */ + tcg_out32(s, (COND_AL << 28) | 0x052d0010 | (arg << 12)); + } else { + assert(argreg < 8); + /* str arg, [sp, #0xNN] */ + tcg_out32(s, (COND_AL << 28) | 0x058d0000 | + (arg << 12) | (argreg - 4) * 4); + } + return argreg + 1; +} + +static inline TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg, + TCGReg arglo, TCGReg arghi) +{ + /* 64 bit arguments must go in even/odd register pairs + * and in 8-aligned stack slots. + */ + if (argreg & 1) { + argreg++; + } + argreg = tcg_out_arg_reg32(s, argreg, arglo); + argreg = tcg_out_arg_reg32(s, argreg, arghi); + return argreg; +} + +static inline void tcg_out_arg_stacktidy(TCGContext *s, TCGReg argreg) +{ + /* Output any necessary post-call cleanup of the stack */ + if (argreg > 4) { + tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10); + } +} + #endif #define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS) @@ -975,6 +1084,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) int addr_reg, data_reg, data_reg2, bswap; #ifdef CONFIG_SOFTMMU int mem_index, s_bits; + TCGReg argreg; # if TARGET_LONG_BITS == 64 int addr_reg2; # endif @@ -1088,31 +1198,22 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) tcg_out_b_noaddr(s, COND_EQ); /* TODO: move this code to where the constants pool will be */ - if (addr_reg != TCG_REG_R0) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0)); - } -# if TARGET_LONG_BITS == 32 - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R1, 0, mem_index); -# else - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0)); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); -# endif + /* Note that this code relies on the constraints we set in arm_op_defs[] + * to ensure that later arguments are not passed to us in registers we + * trash by moving the earlier arguments into them. + */ + argreg = TCG_REG_R0; #ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 bit */ - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[2], 0, - tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0)); - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[1], 0, - tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0)); - - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[0], 0, TCG_AREG0, - SHIFT_IMM_LSL(0)); + argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0); #endif +#if TARGET_LONG_BITS == 64 + argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2); +#else + argreg = tcg_out_arg_reg32(s, argreg, addr_reg); +#endif + argreg = tcg_out_arg_imm32(s, argreg, mem_index); tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]); + tcg_out_arg_stacktidy(s, argreg); switch (opc) { case 0 | 4: @@ -1211,6 +1312,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) int addr_reg, data_reg, data_reg2, bswap; #ifdef CONFIG_SOFTMMU int mem_index, s_bits; + TCGReg argreg; # if TARGET_LONG_BITS == 64 int addr_reg2; # endif @@ -1314,89 +1416,38 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) tcg_out_b_noaddr(s, COND_EQ); /* TODO: move this code to where the constants pool will be */ - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0)); -# if TARGET_LONG_BITS == 32 - switch (opc) { - case 0: - tcg_out_ext8u(s, COND_AL, TCG_REG_R1, data_reg); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); - break; - case 1: - tcg_out_ext16u(s, COND_AL, TCG_REG_R1, data_reg); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); - break; - case 2: - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0)); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); - break; - case 3: - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index); - tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */ - if (data_reg != TCG_REG_R2) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0)); - } - if (data_reg2 != TCG_REG_R3) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0)); - } - break; - } -# else - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0)); + /* Note that this code relies on the constraints we set in arm_op_defs[] + * to ensure that later arguments are not passed to us in registers we + * trash by moving the earlier arguments into them. + */ + argreg = TCG_REG_R0; +#ifdef CONFIG_TCG_PASS_AREG0 + argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0); +#endif +#if TARGET_LONG_BITS == 64 + argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2); +#else + argreg = tcg_out_arg_reg32(s, argreg, addr_reg); +#endif + switch (opc) { case 0: - tcg_out_ext8u(s, COND_AL, TCG_REG_R2, data_reg); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index); + argreg = tcg_out_arg_reg8(s, argreg, data_reg); break; case 1: - tcg_out_ext16u(s, COND_AL, TCG_REG_R2, data_reg); - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index); + argreg = tcg_out_arg_reg16(s, argreg, data_reg); break; case 2: - if (data_reg != TCG_REG_R2) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0)); - } - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index); + argreg = tcg_out_arg_reg32(s, argreg, data_reg); break; case 3: - tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index); - tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */ - if (data_reg != TCG_REG_R2) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0)); - } - if (data_reg2 != TCG_REG_R3) { - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0)); - } + argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2); break; } -# endif - -#ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 bit */ - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[3], 0, - tcg_target_call_iarg_regs[2], SHIFT_IMM_LSL(0)); - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[2], 0, - tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0)); - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[1], 0, - tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0)); - tcg_out_dat_reg(s, COND_AL, ARITH_MOV, - tcg_target_call_iarg_regs[0], 0, TCG_AREG0, - SHIFT_IMM_LSL(0)); -#endif + argreg = tcg_out_arg_imm32(s, argreg, mem_index); tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]); - if (opc == 3) - tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10); + tcg_out_arg_stacktidy(s, argreg); reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr); #else /* !CONFIG_SOFTMMU */ -- cgit v1.2.3 From 18d445b443a5fa06a7c2819a170623b970afb3fb Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sat, 25 Aug 2012 23:59:58 +0200 Subject: tcg/ia64: fix prologue/epilogue Prologue and epilogue code has been broken in cea5f9a28. Signed-off-by: Aurelien Jarno --- tcg/ia64/tcg-target.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index e02dacc84..b3c7db0f9 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -107,7 +107,7 @@ enum { }; static const int tcg_target_reg_alloc_order[] = { - TCG_REG_R34, + TCG_REG_R33, TCG_REG_R35, TCG_REG_R36, TCG_REG_R37, @@ -2314,13 +2314,13 @@ static void tcg_target_qemu_prologue(TCGContext *s) s->code_ptr += 16; /* skip GP */ /* prologue */ - tcg_out_bundle(s, mII, + tcg_out_bundle(s, miI, tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34, - TCG_REG_R33, 32, 24, 0), + TCG_REG_R34, 32, 24, 0), + tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, + TCG_AREG0, 0, TCG_REG_R32), tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, - TCG_REG_B6, TCG_REG_R33, 0), - tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, - TCG_REG_R32, TCG_REG_B0)); + TCG_REG_B6, TCG_REG_R33, 0)); /* ??? If GUEST_BASE < 0x200000, we could load the register via an ADDL in the M slot of the next bundle. */ @@ -2334,10 +2334,10 @@ static void tcg_target_qemu_prologue(TCGContext *s) } tcg_out_bundle(s, miB, - tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, - TCG_AREG0, 0, TCG_REG_R32), tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R12, -frame_size, TCG_REG_R12), + tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, + TCG_REG_R32, TCG_REG_B0), tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6)); /* epilogue */ @@ -2351,7 +2351,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_out_bundle(s, miB, tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), tcg_opc_i26(TCG_REG_P0, OPC_MOV_I_I26, - TCG_REG_PFS, TCG_REG_R33), + TCG_REG_PFS, TCG_REG_R34), tcg_opc_b4 (TCG_REG_P0, OPC_BR_RET_SPTK_MANY_B4, TCG_REG_B0)); } @@ -2403,7 +2403,7 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* stack pointer */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R32); /* return address */ - tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33); /* PFS */ + tcg_regset_set_reg(s->reserved_regs, TCG_REG_R34); /* PFS */ /* The following 3 are not in use, are call-saved, but *not* saved by the prologue. Therefore we cannot use them without modifying -- cgit v1.2.3 From d03c98d80ffb7c561d9e6874580f52fe7ecc8c6c Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 26 Aug 2012 00:45:27 +0200 Subject: tcg/ia64: fix and optimize ld/st slow path Store slow path has been broken in e141ab52d: - the arguments are shifted before the last one (mem_index) is written. - the shift is done for both slow and fast paths. Fix that. Also optimize a bit by bundling the move together. This still can be optimized, but it's better to wait for a decision to be taken on the arguments order. Signed-off-by: Aurelien Jarno --- tcg/ia64/tcg-target.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index b3c7db0f9..dc588dbea 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -1532,12 +1532,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) } #ifdef CONFIG_TCG_PASS_AREG0 /* XXX/FIXME: suboptimal */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); + tcg_out_bundle(s, mII, + tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58, + mem_index, TCG_REG_R0), + tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, + TCG_REG_R57, 0, TCG_REG_R56), + tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, + TCG_REG_R56, 0, TCG_AREG0)); #endif if (!bswap || s_bits == 0) { tcg_out_bundle(s, miB, @@ -1659,15 +1660,21 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) #ifdef CONFIG_TCG_PASS_AREG0 /* XXX/FIXME: suboptimal */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], - tcg_target_call_iarg_regs[2]); - tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); -#endif + tcg_out_bundle(s, mII, + tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R59, + mem_index, TCG_REG_R0), + tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, + TCG_REG_R58, 0, TCG_REG_R57), + tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, + TCG_REG_R57, 0, TCG_REG_R56)); + tcg_out_bundle(s, miB, + tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc], + data_reg, TCG_REG_R3), + tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4, + TCG_REG_R56, 0, TCG_AREG0), + tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5, + TCG_REG_B0, TCG_REG_B6)); +#else tcg_out_bundle(s, miB, tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc], data_reg, TCG_REG_R3), @@ -1675,6 +1682,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) mem_index, TCG_REG_R0), tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5, TCG_REG_B0, TCG_REG_B6)); +#endif } #else /* !CONFIG_SOFTMMU */ -- cgit v1.2.3 From 42644cee08f85202f5d3e8babf6503487849353a Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 21 May 2012 21:56:19 +0200 Subject: linux-user: arg_table need not have global scope Declare arg_table to be "static const", and adjust the two users to also be const. Signed-off-by: Jim Meyering Signed-off-by: Riku Voipio --- linux-user/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 7dea08487..b1c228a24 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3222,7 +3222,7 @@ struct qemu_argument { const char *help; }; -struct qemu_argument arg_table[] = { +static const struct qemu_argument arg_table[] = { {"h", "", false, handle_arg_help, "", "print this help"}, {"g", "QEMU_GDB", true, handle_arg_gdb, @@ -3264,7 +3264,7 @@ struct qemu_argument arg_table[] = { static void usage(void) { - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; int maxarglen; int maxenvlen; @@ -3330,7 +3330,7 @@ static int parse_args(int argc, char **argv) { const char *r; int optind; - struct qemu_argument *arginfo; + const struct qemu_argument *arginfo; for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (arginfo->env == NULL) { -- cgit v1.2.3 From 333858b77c2b4f7636257808a77822c58bdd80fe Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Tue, 21 Aug 2012 02:13:12 +0400 Subject: linux-user: fix emulation of getdents In case when TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64, the last byte of the target dirent structure (aka d_type byte) was never copied from the host dirent structure, thus breaking everything that relies on valid d_type value, e.g. glob(3). Reviewed-by: Peter Maydell Signed-off-by: Dmitry V. Levin Signed-off-by: Riku Voipio --- linux-user/syscall.c | 11 +++++------ linux-user/syscall_defs.h | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 11743065e..6257a04d0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7025,15 +7025,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, tde = target_dirp; while (len > 0) { reclen = de->d_reclen; - treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long))); + tnamelen = reclen - offsetof(struct linux_dirent, d_name); + assert(tnamelen >= 0); + treclen = tnamelen + offsetof(struct target_dirent, d_name); + assert(count1 + treclen <= count); tde->d_reclen = tswap16(treclen); tde->d_ino = tswapal(de->d_ino); tde->d_off = tswapal(de->d_off); - tnamelen = treclen - (2 * sizeof(abi_long) + 2); - if (tnamelen > 256) - tnamelen = 256; - /* XXX: may not be correct */ - pstrcpy(tde->d_name, tnamelen, de->d_name); + memcpy(tde->d_name, de->d_name, tnamelen); de = (struct linux_dirent *)((char *)de + reclen); len -= reclen; tde = (struct target_dirent *)((char *)tde + treclen); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 2cfda5afd..a98cbf7b8 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -255,10 +255,10 @@ struct kernel_statfs { }; struct target_dirent { - abi_long d_ino; - abi_long d_off; - unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ + abi_long d_ino; + abi_long d_off; + unsigned short d_reclen; + char d_name[]; }; struct target_dirent64 { -- cgit v1.2.3 From 097b8cb840a31ec526cc58778bd8cbab0d2beaaa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 20 Aug 2012 11:36:32 +0100 Subject: linux-user: Clarify "Unable to reserve guest address space" error Now that we default to reserving nearly 4GB of RAM for the guest address space when running a 32 bit linux-user guest on 64 bit hosts, users are much more likely to run into it. Reword the message to be more informative about what failed and provide suggestions for how to fix things. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-user/main.c b/linux-user/main.c index b1c228a24..1a1c661ee 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3519,7 +3519,10 @@ int main(int argc, char **argv, char **envp) guest_base = init_guest_space(guest_base, reserved_va, 0, have_guest_base); if (guest_base == (unsigned long)-1) { - fprintf(stderr, "Unable to reserve guest address space\n"); + fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address " + "space for use as guest address space (check your virtual " + "memory ulimit setting or reserve less using -R option)\n", + reserved_va); exit(1); } -- cgit v1.2.3 From d22d7289877ecd3ef86570f6f6d0574da40711dc Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 27 Aug 2012 09:50:38 +0100 Subject: Fix operands of RECIP2.S and RECIP2.PS Read the second input operand of RECIP2.S and RECIP2.PS from FT rather than FD. RECIP2.D is already correct. Signed-off-by: Richard Sandiford Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index d643676e5..2589f63b3 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -6805,7 +6805,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i32 fp1 = tcg_temp_new_i32(); gen_load_fpr32(fp0, fs); - gen_load_fpr32(fp1, fd); + gen_load_fpr32(fp1, ft); gen_helper_float_recip2_s(fp0, fp0, fp1); tcg_temp_free_i32(fp1); gen_store_fpr32(fp0, fd); @@ -7543,7 +7543,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i64 fp1 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); - gen_load_fpr64(ctx, fp1, fd); + gen_load_fpr64(ctx, fp1, ft); gen_helper_float_recip2_ps(fp0, fp0, fp1); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp0, fd); -- cgit v1.2.3 From 13d24f49720a3e7b35a21222ef182c8513f139db Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 27 Aug 2012 09:53:29 +0100 Subject: Fix order of CVT.PS.S operands The FS input to CVT.PS.S is the high half and FT is the low half. tcg_gen_concat_i32_i64 takes the low half first, so the operands were in the wrong order. Signed-off-by: Richard Sandiford Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2589f63b3..d8129864e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -6900,7 +6900,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, gen_load_fpr32(fp32_0, fs); gen_load_fpr32(fp32_1, ft); - tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1); + tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); tcg_temp_free_i32(fp32_1); tcg_temp_free_i32(fp32_0); gen_store_fpr64(ctx, fp64, fd); -- cgit v1.2.3 From 05168674505153a641c7bfddb691d2eda11d13d1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 30 Mar 2012 13:16:36 -0400 Subject: target-mips: Streamline indexed cp1 memory addressing. We've already eliminated both base and index being zero. Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index d8129864e..f740a0832 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7742,8 +7742,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, } else if (index == 0) { gen_load_gpr(t0, base); } else { - gen_load_gpr(t0, index); - gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); + gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ -- cgit v1.2.3 From b3167288367f79754b74ad933146e37938ebff13 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 30 Mar 2012 13:16:37 -0400 Subject: mips-linux-user: Always support rdhwr. The kernel will emulate this instruction if it's not supported natively. This insn is used for TLS, among other things, and so is required by modern glibc. Signed-off-by: Richard Henderson Cc: Riku Voipio Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target-mips/translate.c b/target-mips/translate.c index f740a0832..35624e9da 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -8111,7 +8111,11 @@ gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd) { TCGv t0; +#if !defined(CONFIG_USER_ONLY) + /* The Linux kernel will emulate rdhwr if it's not supported natively. + Therefore only check the ISA in system mode. */ check_insn(env, ctx, ISA_MIPS32R2); +#endif t0 = tcg_temp_new(); switch (rd) { -- cgit v1.2.3 From 4f213879f3cc695644cfd8bf603495e7316c78f6 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 27 Aug 2012 18:33:12 +0400 Subject: Revert "i8259: add -no-spurious-interrupt-hack option" This reverts commit f278d4947fff814dcde2ef2acad36d172ff8be35. Signed-off-by: malc --- cpu-exec.c | 14 +++++--------- hw/i8259.c | 18 ------------------ qemu-options.hx | 12 ------------ sysemu.h | 1 - vl.c | 4 ---- 5 files changed, 5 insertions(+), 44 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 625fbb0e0..134b3c4fc 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -329,15 +329,11 @@ int cpu_exec(CPUArchState *env) 0); env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); - if (intno >= 0) { - qemu_log_mask(CPU_LOG_TB_IN_ASM, - "Servicing hardware INT=0x%02x\n", - intno); - do_interrupt_x86_hardirq(env, intno, 1); - /* ensure that no TB jump will be modified as - the program flow was changed */ - next_tb = 0; - } + qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); + do_interrupt_x86_hardirq(env, intno, 1); + /* ensure that no TB jump will be modified as + the program flow was changed */ + next_tb = 0; #if !defined(CONFIG_USER_ONLY) } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && (env->eflags & IF_MASK) && diff --git a/hw/i8259.c b/hw/i8259.c index 7ecb7e1de..65876662a 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -26,7 +26,6 @@ #include "isa.h" #include "monitor.h" #include "qemu-timer.h" -#include "sysemu.h" #include "i8259_internal.h" /* debug PIC */ @@ -194,20 +193,6 @@ int pic_read_irq(DeviceState *d) pic_intack(slave_pic, irq2); } else { /* spurious IRQ on slave controller */ - if (no_spurious_interrupt_hack) { - /* Pretend it was delivered and acknowledged. If - * it was spurious due to slave_pic->imr, then - * as soon as the mask is cleared, the slave will - * re-trigger IRQ2 on the master. If it is spurious for - * some other reason, make sure we don't keep trying - * to half-process the same spurious interrupt over - * and over again. - */ - s->irr &= ~(1<last_irr &= ~(1<isr &= ~(1<irq_base + irq2; @@ -217,9 +202,6 @@ int pic_read_irq(DeviceState *d) pic_intack(s, irq); } else { /* spurious IRQ on host controller */ - if (no_spurious_interrupt_hack) { - return -1; - } irq = 7; intno = s->irq_base + irq; } diff --git a/qemu-options.hx b/qemu-options.hx index 2a6d82955..0682338e9 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1189,18 +1189,6 @@ Windows 2000 is installed, you no longer need this option (this option slows down the IDE transfers). ETEXI -DEF("no-spurious-interrupt-hack", 0, QEMU_OPTION_no_spurious_interrupt_hack, - "-no-spurious-interrupt-hack disable delivery of spurious interrupts\n", - QEMU_ARCH_I386) -STEXI -@item -no-spurious-interrupt-hack -@findex -no-spurious-interrupt-hack -Use it as a workaround for operating systems that drive PICs in a way that -can generate spurious interrupts, but the OS doesn't handle spurious -interrupts gracefully. (e.g. late 80s/early 90s versions of ATT UNIX -and derivatives) -ETEXI - HXCOMM Deprecated by -rtc DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, "", QEMU_ARCH_I386) diff --git a/sysemu.h b/sysemu.h index 0170109e1..65552acee 100644 --- a/sysemu.h +++ b/sysemu.h @@ -117,7 +117,6 @@ extern int graphic_depth; extern DisplayType display_type; extern const char *keyboard_layout; extern int win2k_install_hack; -extern int no_spurious_interrupt_hack; extern int alt_grab; extern int ctrl_grab; extern int usb_enabled; diff --git a/vl.c b/vl.c index 6de41c124..16d04a2ee 100644 --- a/vl.c +++ b/vl.c @@ -204,7 +204,6 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; int win2k_install_hack = 0; -int no_spurious_interrupt_hack = 0; int usb_enabled = 0; int singlestep = 0; int smp_cpus = 1; @@ -3047,9 +3046,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_win2k_hack: win2k_install_hack = 1; break; - case QEMU_OPTION_no_spurious_interrupt_hack: - no_spurious_interrupt_hack = 1; - break; case QEMU_OPTION_rtc_td_hack: { static GlobalProperty slew_lost_ticks[] = { { -- cgit v1.2.3 From df8002103c3e262dc40d7b5e0eb2171ba28b1d63 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 27 Aug 2012 18:33:20 +0400 Subject: Revert "vga: add some optional CGA compatibility hacks" This reverts commit 482f7bf86b43af9f6903c52726fedf82b28bf953. Signed-off-by: malc --- hw/pc.h | 4 ---- hw/vga.c | 36 ++++++++---------------------------- qemu-options.hx | 19 ------------------- vl.c | 23 ----------------------- 4 files changed, 8 insertions(+), 74 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index 37e2f8758..e4db0715b 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -176,10 +176,6 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; -#define VGA_CGA_HACK_PALETTE_BLANKING (1<<0) -#define VGA_CGA_HACK_FONT_HEIGHT (1<<1) -extern int vga_cga_hacks; - static inline DeviceState *isa_vga_init(ISABus *bus) { ISADevice *dev; diff --git a/hw/vga.c b/hw/vga.c index a65fc26ab..f82ced8e6 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -547,31 +547,14 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("vga: write CR%x = 0x%02x\n", s->cr_index, val); #endif /* handle CR0-7 protection */ - if (s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) { - if (s->cr_index <= VGA_CRTC_OVERFLOW) { - /* can always write bit 4 of CR7 */ - if (s->cr_index == VGA_CRTC_OVERFLOW) { - s->cr[VGA_CRTC_OVERFLOW] = - (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | (val & 0x10); - } - return; - } else if ((vga_cga_hacks & VGA_CGA_HACK_FONT_HEIGHT) && - !(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { - /* extra CGA compatibility hacks (not in standard VGA) */ - if (s->cr_index == VGA_CRTC_MAX_SCAN && - val == 7 && - (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { - return; - } else if (s->cr_index == VGA_CRTC_CURSOR_START && - val == 6 && - (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { - val = 0xd; - } else if (s->cr_index == VGA_CRTC_CURSOR_END && - val == 7 && - (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) { - val = 0xe; - } + if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) && + s->cr_index <= VGA_CRTC_OVERFLOW) { + /* can always write bit 4 of CR7 */ + if (s->cr_index == VGA_CRTC_OVERFLOW) { + s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | + (val & 0x10); } + return; } s->cr[s->cr_index] = val; @@ -1903,10 +1886,7 @@ static void vga_update_display(void *opaque) /* nothing to do */ } else { full_update = 0; - if (!(s->ar_index & 0x20) && - /* extra CGA compatibility hacks (not in standard VGA */ - (!(vga_cga_hacks & VGA_CGA_HACK_PALETTE_BLANKING) || - (s->ar_index != 0 && s->ar_flip_flop))) { + if (!(s->ar_index & 0x20)) { graphic_mode = GMODE_BLANK; } else { graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE; diff --git a/qemu-options.hx b/qemu-options.hx index 0682338e9..3e8085d46 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -975,25 +975,6 @@ Valid optional properties are @item retrace=dumb|precise Select dumb (default) or precise VGA retrace logic, useful for some DOS games/demos. -@item cga_hacks=@var{hack1}[+@var{hack2},[...]] -Enable various extra CGA compatibility hacks for programs that are -trying to directly set CGA modes without BIOS assistance nor -real knowledge of EGA/VGA. These might only work with -vga std. -Valid hacks are -@table @option -@item palette_blanking -Wait to blank the screen until palette registers seem to actually be -modified, instead of blanking it as soon as the palette address bit (0x10) -of the attribute address register (0x3c0) is cleared. -@item font_height -Ignore attempts to change the VGA font height (index 9), -cursor start (index 10), and cursor end (index 11) of the CRTC control -registers (0x3d5) if trying to set them to the default for CGA fonts -instead of VGA fonts. -@item all -Enable all CGA hacks. More CGA hacks may be added in future versions -of qemu. -@end table @end table ETEXI diff --git a/vl.c b/vl.c index 16d04a2ee..febfd62c3 100644 --- a/vl.c +++ b/vl.c @@ -179,7 +179,6 @@ int main(int argc, char **argv) static const char *data_dir; const char *bios_name = NULL; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; -int vga_cga_hacks = 0; DisplayType display_type = DT_DEFAULT; int display_remote = 0; const char* keyboard_layout = NULL; @@ -1749,28 +1748,6 @@ static void select_vgahw (const char *p) else if (strstart(opts, "precise", &nextopt)) vga_retrace_method = VGA_RETRACE_PRECISE; else goto invalid_vga; - } else if (strstart(opts, ",cga_hacks=", &nextopt)) { - opts = nextopt; - while (*opts) { - if (strstart(opts, "all", &nextopt)) { - opts = nextopt; - vga_cga_hacks |= ~0; - } else if (strstart(opts, "palette_blanking", &nextopt)) { - opts = nextopt; - vga_cga_hacks |= VGA_CGA_HACK_PALETTE_BLANKING; - } else if (strstart(opts, "font_height", &nextopt)) { - opts = nextopt; - vga_cga_hacks |= VGA_CGA_HACK_FONT_HEIGHT; - } else { - break; - } - - if (*opts == '+') { - opts++; - } else { - break; - } - } } else goto invalid_vga; opts = nextopt; } -- cgit v1.2.3 From e4558dcae8b9fcb2bcc312f1d04071b34adf0781 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 27 Aug 2012 18:33:21 +0400 Subject: Revert "qemu-options.hx: mention retrace= VGA option" This reverts commit 39dda260628e5f2a3fd2ce2ec8a71f3d5ca309a9. Signed-off-by: malc --- qemu-options.hx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 3e8085d46..3c411c427 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -945,7 +945,7 @@ DEF("vga", HAS_ARG, QEMU_OPTION_vga, "-vga [std|cirrus|vmware|qxl|xenfb|none]\n" " select video card type\n", QEMU_ARCH_ALL) STEXI -@item -vga @var{type}[,@var{prop}=@var{value}[,...]] +@item -vga @var{type} @findex -vga Select type of VGA card to emulate. Valid values for @var{type} are @table @option @@ -970,12 +970,6 @@ Recommended choice when using the spice protocol. @item none Disable VGA card. @end table -Valid optional properties are -@table @option -@item retrace=dumb|precise -Select dumb (default) or precise VGA retrace logic, useful for some -DOS games/demos. -@end table ETEXI DEF("full-screen", 0, QEMU_OPTION_full_screen, -- cgit v1.2.3 From 9f227bc3583ea082be7a79c14a5ffdade5844753 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 27 Aug 2012 18:33:22 +0400 Subject: Revert "vl: fix -hdachs/-hda argument order parsing issues" This reverts commit 7764ae9671f1cd74227cf4404431dd5213799ef0. Signed-off-by: malc --- vl.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/vl.c b/vl.c index febfd62c3..7c577fa54 100644 --- a/vl.c +++ b/vl.c @@ -2352,9 +2352,8 @@ int main(int argc, char **argv, char **envp) char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */ DisplayState *ds; DisplayChangeListener *dcl; - char hdachs_params[512]; /* save -hdachs to apply to later -hda */ - QemuOpts *hda_opts = NULL; /* save -hda to be modified by later -hdachs */ - QemuOpts *opts, *machine_opts; + int cyls, heads, secs, translation; + QemuOpts *hda_opts = NULL, *opts, *machine_opts; QemuOptsList *olist; int optind; const char *optarg; @@ -2409,7 +2408,8 @@ int main(int argc, char **argv, char **envp) cpu_model = NULL; ram_size = 0; snapshot = 0; - snprintf(hdachs_params, sizeof(hdachs_params), "%s", HD_OPTS); + cyls = heads = secs = 0; + translation = BIOS_ATA_TRANSLATION_AUTO; for (i = 0; i < MAX_NODES; i++) { node_mem[i] = 0; @@ -2457,7 +2457,7 @@ int main(int argc, char **argv, char **envp) if (optind >= argc) break; if (argv[optind][0] != '-') { - hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], hdachs_params); + hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS); } else { const QEMUOption *popt; @@ -2475,8 +2475,21 @@ int main(int argc, char **argv, char **envp) cpu_model = optarg; break; case QEMU_OPTION_hda: - hda_opts = drive_add(IF_DEFAULT, 0, optarg, hdachs_params); - break; + { + char buf[256]; + if (cyls == 0) + snprintf(buf, sizeof(buf), "%s", HD_OPTS); + else + snprintf(buf, sizeof(buf), + "%s,cyls=%d,heads=%d,secs=%d%s", + HD_OPTS , cyls, heads, secs, + translation == BIOS_ATA_TRANSLATION_LBA ? + ",trans=lba" : + translation == BIOS_ATA_TRANSLATION_NONE ? + ",trans=none" : ""); + drive_add(IF_DEFAULT, 0, optarg, buf); + break; + } case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: case QEMU_OPTION_hdd: @@ -2510,10 +2523,7 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_hdachs: { - int cyls, heads, secs, translation; const char *p; - cyls = heads = secs = 0; - translation = BIOS_ATA_TRANSLATION_AUTO; p = optarg; cyls = strtol(p, (char **)&p, 0); if (cyls < 1 || cyls > 16383) @@ -2545,14 +2555,7 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "qemu: invalid physical CHS format\n"); exit(1); } - snprintf(hdachs_params, sizeof(hdachs_params), - "%s,cyls=%d,heads=%d,secs=%d%s", - HD_OPTS , cyls, heads, secs, - translation == BIOS_ATA_TRANSLATION_LBA ? - ",trans=lba" : - translation == BIOS_ATA_TRANSLATION_NONE ? - ",trans=none" : ""); - if (hda_opts != NULL) { + if (hda_opts != NULL) { char num[16]; snprintf(num, sizeof(num), "%d", cyls); qemu_opt_set(hda_opts, "cyls", num); -- cgit v1.2.3 From 08406b035edc35fff4e3e14af3ec6f8f3a17a587 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 27 Aug 2012 18:33:24 +0400 Subject: Revert "fix some debug printf format strings" This reverts commit 145c7c880ff520a9348cc2401ba291330b9606fe. Signed-off-by: malc --- hw/cirrus_vga.c | 4 ++-- hw/i8259.c | 3 +-- hw/ide/cmd646.c | 5 ++--- hw/ide/via.c | 5 ++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 909899dd5..e8dcc6b88 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2055,8 +2055,8 @@ static void cirrus_vga_mem_write(void *opaque, } } else { #ifdef DEBUG_CIRRUS - printf("cirrus: mem_writeb " TARGET_FMT_plx " value %" PRIx64 "\n", - addr, mem_value); + printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr, + mem_value); #endif } } diff --git a/hw/i8259.c b/hw/i8259.c index 65876662a..53daf7865 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -355,8 +355,7 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, ret = s->imr; } } - DPRINTF("read: addr=0x%02" TARGET_PRIxPHYS " val=0x%02x\n", - addr, ret); + DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret); return ret; } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index dd2855e19..e0b944349 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -154,7 +154,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE - printf("bmdma: readb 0x%02" TARGET_PRIxPHYS " : 0x%02x\n", addr, val); + printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); #endif return val; } @@ -170,8 +170,7 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE - printf("bmdma: writeb 0x%02" TARGET_PRIxPHYS " : 0x%02" PRIx64 "\n", - addr, val); + printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch(addr & 3) { case 0: diff --git a/hw/ide/via.c b/hw/ide/via.c index 948a46938..b20e4f094 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -55,7 +55,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE - printf("bmdma: readb 0x%02" TARGET_PRIxPHYS " : 0x%02x\n", addr, val); + printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); #endif return val; } @@ -70,8 +70,7 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE - printf("bmdma: writeb 0x%02" TARGET_PRIxPHYS " : 0x%02" PRIx64 "\n", - addr, val); + printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch (addr & 3) { case 0: -- cgit v1.2.3 From 2e15497c5b8d0d172dece0cf56e2d2e977a6b679 Mon Sep 17 00:00:00 2001 From: Eric Johnson Date: Sat, 17 Sep 2011 17:05:32 -0700 Subject: target-mips: add privilege level check to several Cop0 instructions The MIPS Architecture Verification Programs (AVPs) check privileged instructions for the required privilege level. These changes are needed to pass the AVP suite. Signed-off-by: Eric Johnson Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/target-mips/translate.c b/target-mips/translate.c index 35624e9da..0cff905db 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -5933,6 +5933,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, { const char *opn = "ldst"; + check_cp0_enabled(ctx); switch (opc) { case OPC_MFC0: if (rt == 0) { @@ -10121,6 +10122,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, #ifndef CONFIG_USER_ONLY case MFC0: case MFC0 + 32: + check_cp0_enabled(ctx); if (rt == 0) { /* Treat as NOP. */ break; @@ -10129,6 +10131,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, break; case MTC0: case MTC0 + 32: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10225,10 +10228,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, case 0x05: switch (minor) { case RDPGPR: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS32R2); gen_load_srsgpr(rt, rs); break; case WRPGPR: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS32R2); gen_store_srsgpr(rt, rs); break; @@ -10269,6 +10274,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, case 0x1d: switch (minor) { case DI: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10281,6 +10287,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, } break; case EI: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10761,6 +10768,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, minor = (ctx->opcode >> 12) & 0xf; switch (minor) { case CACHE: + check_cp0_enabled(ctx); /* Treat as no-op. */ break; case LWC2: @@ -12211,6 +12219,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); /* Treat as NOP. */ break; -- cgit v1.2.3 From 36c6711bbe79642b0102416a9dd4243505e874a6 Mon Sep 17 00:00:00 2001 From: Eric Johnson Date: Sat, 17 Sep 2011 17:28:16 -0700 Subject: target-mips: allow microMIPS SWP and SDP to have RD equal to BASE The microMIPS SWP and SDP instructions do not modify GPRs. So their behavior is well defined when RD equals BASE. The MIPS Architecture Verification Programs (AVPs) check that they work as expected. This is required for AVPs to pass. Signed-off-by: Eric Johnson Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 0cff905db..b29341953 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -10031,7 +10031,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, const char *opn = "ldst_pair"; TCGv t0, t1; - if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) { + if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) { generate_exception(ctx, EXCP_RI); return; } @@ -10043,6 +10043,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, switch (opc) { case LWP: + if (rd == base) { + generate_exception(ctx, EXCP_RI); + return; + } save_cpu_state(ctx, 0); op_ld_lw(t1, t0, ctx); gen_store_gpr(t1, rd); @@ -10064,6 +10068,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, break; #ifdef TARGET_MIPS64 case LDP: + if (rd == base) { + generate_exception(ctx, EXCP_RI); + return; + } save_cpu_state(ctx, 0); op_ld_ld(t1, t0, ctx); gen_store_gpr(t1, rd); -- cgit v1.2.3 From fb6541571e0dc74655f0bfb0534c95d759a7bdb4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 24 Aug 2012 12:36:41 +0200 Subject: megasas: Add 'hba_serial' property Add a 'hba_serial' property to the megasas driver. Originally it would be using a pointer value which would break migration. Reported-by: Stefan Weil Cc: Paolo Bonzini Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini --- hw/megasas.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/megasas.c b/hw/megasas.c index c35a15db4..c728aea69 100644 --- a/hw/megasas.c +++ b/hw/megasas.c @@ -38,6 +38,7 @@ #define MEGASAS_MAX_SECTORS 0xFFFF /* No real limit */ #define MEGASAS_MAX_ARRAYS 128 +#define MEGASAS_HBA_SERIAL "QEMU123456" #define NAA_LOCALLY_ASSIGNED_ID 0x3ULL #define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400 @@ -93,6 +94,7 @@ typedef struct MegasasState { int boot_event; uint64_t sas_addr; + char *hba_serial; uint64_t reply_queue_pa; void *reply_queue; @@ -698,8 +700,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) } memcpy(info.product_name, "MegaRAID SAS 8708EM2", 20); - snprintf(info.serial_number, 32, "QEMU%08lx", - (unsigned long)s & 0xFFFFFFFF); + snprintf(info.serial_number, 32, "%s", s->hba_serial); snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_VERSION); memcpy(info.image_component[0].name, "APP", 3); memcpy(info.image_component[0].version, MEGASAS_VERSION "-QEMU", 9); @@ -2132,6 +2133,9 @@ static int megasas_scsi_init(PCIDevice *dev) s->sas_addr |= (PCI_SLOT(dev->devfn) << 8); s->sas_addr |= PCI_FUNC(dev->devfn); } + if (!s->hba_serial) { + s->hba_serial = g_strdup(MEGASAS_HBA_SERIAL); + } if (s->fw_sge >= MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE) { s->fw_sge = MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE; } else if (s->fw_sge >= 128 - MFI_PASS_FRAME_SIZE) { @@ -2166,6 +2170,7 @@ static Property megasas_properties[] = { MEGASAS_DEFAULT_SGE), DEFINE_PROP_UINT32("max_cmds", MegasasState, fw_cmds, MEGASAS_DEFAULT_FRAMES), + DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial), DEFINE_PROP_HEX64("sas_address", MegasasState, sas_addr, 0), #ifdef USE_MSIX DEFINE_PROP_BIT("use_msix", MegasasState, flags, -- cgit v1.2.3 From 9ea73f8b10531de4b1173835c819b7c35b7160c6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 2 Aug 2012 15:43:39 +0200 Subject: esp: support 24-bit DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SeaBIOS will issue requests for more than 64k when loading a CD-ROM image into memory. Support the TCHI register from the AMD PCscsi spec. Acked-by: Hervé Poussineau Signed-off-by: Paolo Bonzini --- hw/esp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 52c46e615..84a4e74e2 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -87,7 +87,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) target = s->wregs[ESP_WBUSID] & BUSID_DID; if (s->dma) { - dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8); + dmalen = s->rregs[ESP_TCLO]; + dmalen |= s->rregs[ESP_TCMID] << 8; + dmalen |= s->rregs[ESP_TCHI] << 16; s->dma_memory_read(s->dma_opaque, buf, dmalen); } else { dmalen = s->ti_size; @@ -226,6 +228,7 @@ static void esp_dma_done(ESPState *s) s->rregs[ESP_RFLAGS] = 0; s->rregs[ESP_TCLO] = 0; s->rregs[ESP_TCMID] = 0; + s->rregs[ESP_TCHI] = 0; esp_raise_irq(s); } @@ -328,7 +331,9 @@ static void handle_ti(ESPState *s) return; } - dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8); + dmalen = s->rregs[ESP_TCLO]; + dmalen |= s->rregs[ESP_TCMID] << 8; + dmalen |= s->rregs[ESP_TCHI] << 16; if (dmalen==0) { dmalen=0x10000; } @@ -429,6 +434,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) switch (saddr) { case ESP_TCLO: case ESP_TCMID: + case ESP_TCHI: s->rregs[ESP_RSTAT] &= ~STAT_TC; break; case ESP_FIFO: @@ -448,6 +454,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) /* Reload DMA counter. */ s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO]; s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID]; + s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI]; } else { s->dma = 0; } @@ -530,13 +537,12 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) case ESP_WBUSID ... ESP_WSYNO: break; case ESP_CFG1: + case ESP_CFG2: case ESP_CFG3: + case ESP_RES3: case ESP_RES4: s->rregs[saddr] = val; break; case ESP_WCCF ... ESP_WTEST: break; - case ESP_CFG2 ... ESP_RES4: - s->rregs[saddr] = val; - break; default: trace_esp_error_invalid_write(val, saddr); return; -- cgit v1.2.3 From 0f1da449ec65403bc5c028eb9618d0ee598a3615 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 28 Aug 2012 12:46:18 +0200 Subject: scsi: more fixes to properties for passthrough devices Commit 0384783 (scsi-block: remove properties that are not relevant for passthrough, 2012-07-09) removed one property that should have been left there, "bootindex". It also did not touch scsi-generic, while it should have. Fix both problems. Reported-by: Alexandre DERUMIER Signed-off-by: Paolo Bonzini --- hw/scsi-disk.c | 1 + hw/scsi-generic.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 409f760ef..21b862dad 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -2421,6 +2421,7 @@ static TypeInfo scsi_cd_info = { #ifdef __linux__ static Property scsi_block_properties[] = { DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs), + DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 8d5106061..a5eb663ec 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -479,7 +479,8 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, } static Property scsi_generic_properties[] = { - DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf), + DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs), + DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1), DEFINE_PROP_END_OF_LIST(), }; -- cgit v1.2.3 From 135b9088780d7d8e5eae027b4fba6b33562f7006 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Fri, 17 Aug 2012 12:36:20 +1000 Subject: iscsi: Set number of blocks to 0 for blank CDROM devices The number of blocks of the device is used to compute the device size in bdrv_getlength()/iscsi_getlength(). For MMC devices, the ReturnedLogicalBlockAddress in the READCAPACITY10 has a special meaning when it is 0. In this case it does not mean that LBA 0 is the last accessible LBA, and thus the device has 1 readable block, but instead it means that the disc is blank and there are no readable blocks. This change ensures that when the iSCSI LUN is loaded with a blank DVD-R disk or similar that bdrv_getlength() will return the correct size of the device as 0 bytes. Signed-off-by: Ronnie Sahlberg --- block/iscsi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/iscsi.c b/block/iscsi.c index 4828b8392..0b96165ec 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -721,7 +721,12 @@ iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status, } itask->iscsilun->block_size = rc10->block_size; - itask->iscsilun->num_blocks = rc10->lba + 1; + if (rc10->lba == 0) { + /* blank disk loaded */ + itask->iscsilun->num_blocks = 0; + } else { + itask->iscsilun->num_blocks = rc10->lba + 1; + } itask->bs->total_sectors = itask->iscsilun->num_blocks * itask->iscsilun->block_size / BDRV_SECTOR_SIZE ; -- cgit v1.2.3 From 13ef70f64e9e4d7583fbd9918d8ea76194023d37 Mon Sep 17 00:00:00 2001 From: "munkyu.im" Date: Tue, 28 Aug 2012 16:42:06 +0900 Subject: audio/winwave: previous audio buffer should be flushed Winwave audio backend has problem with pausing and restart audio out. Unlike other backends, Winwave pausing API does not flush audio buffer. As a result, the previous audio data are played in front of user expected sound when user restart audio. So changes it to waveOutReset() Signed-off-by: Munkyu Im Signed-off-by: malc --- audio/winwaveaudio.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c index 663abb9b5..72babbf18 100644 --- a/audio/winwaveaudio.c +++ b/audio/winwaveaudio.c @@ -349,21 +349,15 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...) else { hw->poll_mode = 0; } - if (wave->paused) { - mr = waveOutRestart (wave->hwo); - if (mr != MMSYSERR_NOERROR) { - winwave_logerr (mr, "waveOutRestart"); - } - wave->paused = 0; - } + wave->paused = 0; } return 0; case VOICE_DISABLE: if (!wave->paused) { - mr = waveOutPause (wave->hwo); + mr = waveOutReset (wave->hwo); if (mr != MMSYSERR_NOERROR) { - winwave_logerr (mr, "waveOutPause"); + winwave_logerr (mr, "waveOutReset"); } else { wave->paused = 1; -- cgit v1.2.3 From 54cddd21b04013d5741a92d6828dea3bdb821482 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 26 Aug 2012 16:12:03 +0200 Subject: target-ppc: fix altivec instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Altivec instructions are not working anymore in PowerPC emulation, following commit d15f74fb, which inverted two registers in the call to helper. Fix that. Reviewed-by: Peter Maydell Reviewed-by: Andreas Färber Acked-by: Blue Swirl Signed-off-by: Aurelien Jarno --- target-ppc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 91eb7a062..ac915ccad 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6530,7 +6530,7 @@ static void glue(gen_, name)(DisasContext *ctx) \ ra = gen_avr_ptr(rA(ctx->opcode)); \ rb = gen_avr_ptr(rB(ctx->opcode)); \ rd = gen_avr_ptr(rD(ctx->opcode)); \ - gen_helper_##name(rd, cpu_env, ra, rb); \ + gen_helper_##name(cpu_env, rd, ra, rb); \ tcg_temp_free_ptr(ra); \ tcg_temp_free_ptr(rb); \ tcg_temp_free_ptr(rd); \ -- cgit v1.2.3 From ce6760404851f410d63519084329d54dc216ff93 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Tue, 28 Aug 2012 14:47:51 +0200 Subject: Update OpenBIOS PPC image Update OpenBIOS PPC image to SVN r1063 to fix issues introduced by commit 9e56edcf. The code change in this revision only affects PPC, so OpenBIOS SPARC images are not updated. Signed-off-by: Aurelien Jarno --- pc-bios/README | 2 +- pc-bios/openbios-ppc | Bin 729876 -> 729908 bytes roms/openbios | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index fc07ebc21..303713099 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -12,7 +12,7 @@ 1275-1994 (referred to as Open Firmware) compliant firmware. The included images for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32 and Sparc64 are built from OpenBIOS SVN revision - 1062. + 1063. - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc index 1c3753d3e..5311eca69 100644 Binary files a/pc-bios/openbios-ppc and b/pc-bios/openbios-ppc differ diff --git a/roms/openbios b/roms/openbios index d1d2787f8..f095c8581 160000 --- a/roms/openbios +++ b/roms/openbios @@ -1 +1 @@ -Subproject commit d1d2787f87167edf487a60e61b9168514d5a7434 +Subproject commit f095c858136896d236931357b8d597f407286f71 -- cgit v1.2.3 From 18fec301cd2a38f72a5eeba2656a0c5b4fa69fb7 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 27 Aug 2012 22:13:27 +0200 Subject: tcg/mips: fix broken CONFIG_TCG_PASS_AREG0 code The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers was broken in that it did not respect the ABI requirement that 64 bit values were passed in even-odd register pairs. The simplest way to fix this is to implement some new utility functions for marshalling function arguments into the correct registers and stack, so that the code which sets up the address and data arguments does not need to care whether there has been a preceding env argument. Based on commit 9716ef3b for ARM by Peter Maydell. Signed-off-by: Aurelien Jarno Reviewed-by: Peter Maydell --- tcg/mips/tcg-target.c | 158 +++++++++++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 59 deletions(-) diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 393ba07f2..1006e2800 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -217,6 +217,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_set(ct->u.regs, 0xffffffff); #if defined(CONFIG_SOFTMMU) tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); +# if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64) + tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2); +# endif #endif break; case 'S': /* qemu_st constraint */ @@ -224,10 +227,14 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_set(ct->u.regs, 0xffffffff); tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); #if defined(CONFIG_SOFTMMU) -# if TARGET_LONG_BITS == 64 +# if (defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 32) || \ + (!defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64) tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1); # endif tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2); +# if defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64 + tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3); +# endif #endif break; case 'I': @@ -382,7 +389,10 @@ static inline void tcg_out_nop(TCGContext *s) static inline void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { - tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO); + /* Simple reg-reg move, optimising out the 'do nothing' case */ + if (ret != arg) { + tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO); + } } static inline void tcg_out_movi(TCGContext *s, TCGType type, @@ -503,6 +513,67 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) } } +/* Helper routines for marshalling helper function arguments into + * the correct registers and stack. + * arg_num is where we want to put this argument, and is updated to be ready + * for the next call. arg is the argument itself. Note that arg_num 0..3 is + * real registers, 4+ on stack. + * + * We provide routines for arguments which are: immediate, 32 bit + * value in register, 16 and 8 bit values in register (which must be zero + * extended before use) and 64 bit value in a lo:hi register pair. + */ +#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM) \ + static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM) \ + { \ + if (*arg_num < 4) { \ + DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \ + } else { \ + DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT); \ + tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num)); \ + } \ + (*arg_num)++; \ +} +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG +#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \ + tcg_out_movi(s, TCG_TYPE_I32, A, arg); +DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg) +#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG + +/* We don't use the macro for this one to avoid an unnecessary reg-reg + move when storing to the stack. */ +static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num, + TCGReg arg) +{ + if (*arg_num < 4) { + tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg); + } else { + tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num)); + } + (*arg_num)++; +} + +static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num, + TCGReg arg_low, TCGReg arg_high) +{ + (*arg_num) = (*arg_num + 1) & ~1; + +#if defined(TCG_TARGET_WORDS_BIGENDIAN) + tcg_out_call_iarg_reg32(s, arg_num, arg_high); + tcg_out_call_iarg_reg32(s, arg_num, arg_low); +#else + tcg_out_call_iarg_reg32(s, arg_num, arg_low); + tcg_out_call_iarg_reg32(s, arg_num, arg_high); +#endif +} + static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1, int arg2, int label_index) { @@ -792,18 +863,18 @@ static void *qemu_st_helpers[4] = { static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) { - int addr_regl, addr_reg1, addr_meml; + int addr_regl, addr_meml; int data_regl, data_regh, data_reg1, data_reg2; int mem_index, s_bits; #if defined(CONFIG_SOFTMMU) void *label1_ptr, *label2_ptr; - int sp_args; + int arg_num; #endif #if TARGET_LONG_BITS == 64 # if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr; # endif - int addr_regh, addr_reg2, addr_memh; + int addr_regh, addr_memh; #endif data_regl = *args++; if (opc == 3) @@ -831,18 +902,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, } #if TARGET_LONG_BITS == 64 # if defined(TCG_TARGET_WORDS_BIGENDIAN) - addr_reg1 = addr_regh; - addr_reg2 = addr_regl; addr_memh = 0; addr_meml = 4; # else - addr_reg1 = addr_regl; - addr_reg2 = addr_regh; addr_memh = 4; addr_meml = 0; # endif #else - addr_reg1 = addr_regl; addr_meml = 0; #endif @@ -875,22 +941,17 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, # endif /* slow path */ - sp_args = TCG_REG_A0; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1); + arg_num = 0; +# ifdef CONFIG_TCG_PASS_AREG0 + tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0); +# endif # if TARGET_LONG_BITS == 64 - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh); +# else + tcg_out_call_iarg_reg32(s, &arg_num, addr_regl); # endif - tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index); + tcg_out_call_iarg_imm32(s, &arg_num, mem_index); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]); -#ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); -#endif tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0); tcg_out_nop(s); @@ -991,18 +1052,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) { - int addr_regl, addr_reg1, addr_meml; + int addr_regl, addr_meml; int data_regl, data_regh, data_reg1, data_reg2; int mem_index, s_bits; #if defined(CONFIG_SOFTMMU) uint8_t *label1_ptr, *label2_ptr; - int sp_args; + int arg_num; #endif #if TARGET_LONG_BITS == 64 # if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr; # endif - int addr_regh, addr_reg2, addr_memh; + int addr_regh, addr_memh; #endif data_regl = *args++; @@ -1024,18 +1085,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, #if TARGET_LONG_BITS == 64 addr_regh = *args++; # if defined(TCG_TARGET_WORDS_BIGENDIAN) - addr_reg1 = addr_regh; - addr_reg2 = addr_regl; addr_memh = 0; addr_meml = 4; # else - addr_reg1 = addr_regl; - addr_reg2 = addr_regh; addr_memh = 4; addr_meml = 0; # endif #else - addr_reg1 = addr_regl; addr_meml = 0; #endif mem_index = *args; @@ -1070,49 +1126,33 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, # endif /* slow path */ - sp_args = TCG_REG_A0; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1); + arg_num = 0; +# ifdef CONFIG_TCG_PASS_AREG0 + tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0); +# endif # if TARGET_LONG_BITS == 64 - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh); +# else + tcg_out_call_iarg_reg32(s, &arg_num, addr_regl); # endif switch(opc) { case 0: - tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff); + tcg_out_call_iarg_reg8(s, &arg_num, data_regl); break; case 1: - tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff); + tcg_out_call_iarg_reg16(s, &arg_num, data_regl); break; case 2: - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1); + tcg_out_call_iarg_reg32(s, &arg_num, data_regl); break; case 3: - sp_args = (sp_args + 1) & ~1; - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1); - tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2); + tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh); break; default: tcg_abort(); } - if (sp_args > TCG_REG_A3) { - /* Push mem_index on the stack */ - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index); - tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16); - } else { - tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index); - } - + tcg_out_call_iarg_imm32(s, &arg_num, mem_index); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]); -#ifdef CONFIG_TCG_PASS_AREG0 - /* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */ - tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], - tcg_target_call_iarg_regs[2]); - tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2], - tcg_target_call_iarg_regs[1]); - tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1], - tcg_target_call_iarg_regs[0]); - tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], - TCG_AREG0); -#endif tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0); tcg_out_nop(s); -- cgit v1.2.3 From 998a74bcda7f3297813732ddc2f28ffe5a12e37a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 29 Aug 2012 08:52:37 +0100 Subject: hw/arm_gic.c: Define .class_size in arm_gic_info TypeInfo Add the missing .class_size definition to the arm_gic_info TypeInfo. This fixes the memory corruption and possible segfault that otherwise results when the class struct is allocated at too small a size and the class init function writes off the end of it. Reported-by: Adam Lackorzynski Signed-off-by: Peter Maydell Signed-off-by: Anthony Liguori --- hw/arm_gic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/arm_gic.c b/hw/arm_gic.c index 186ac66f0..55871fad1 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -703,6 +703,7 @@ static TypeInfo arm_gic_info = { .parent = TYPE_ARM_GIC_COMMON, .instance_size = sizeof(gic_state), .class_init = arm_gic_class_init, + .class_size = sizeof(ARMGICClass), }; static void arm_gic_register_types(void) -- cgit v1.2.3 From 7e7de876ae9bdb1b994dee148c6dc009ce94c48e Mon Sep 17 00:00:00 2001 From: Cam Macdonell Date: Mon, 27 Aug 2012 12:12:19 -0600 Subject: ivshmem: remove redundant ioeventfd configuration setup_ioeventfds() is unnecessary and actually causes a segfault when used ioeventfd=on is used on the command-line. Since ioeventfds are handled within the memory API, it can be removed. Signed-off-by: Cam Macdonell Signed-off-by: Anthony Liguori --- hw/ivshmem.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 47f2a1683..62fe53ae2 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -385,17 +385,6 @@ static void close_guest_eventfds(IVShmemState *s, int posn) s->peers[posn].nb_eventfds = 0; } -static void setup_ioeventfds(IVShmemState *s) { - - int i, j; - - for (i = 0; i <= s->max_peer; i++) { - for (j = 0; j < s->peers[i].nb_eventfds; j++) { - ivshmem_add_eventfd(s, i, j); - } - } -} - /* this function increase the dynamic storage need to store data about other * guests */ static void increase_dynamic_storage(IVShmemState *s, int new_min_size) { @@ -696,10 +685,6 @@ static int pci_ivshmem_init(PCIDevice *dev) memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); - if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { - setup_ioeventfds(s); - } - /* region for registers*/ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem_mmio); -- cgit v1.2.3 From 7e2a62d82a3f1397acd67685c3008046eba8344b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 26 Aug 2012 10:12:47 +0200 Subject: memory: Fix copy&paste mistake in memory_region_iorange_write The last argument of find_portio is "write", so this must be true here. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori --- memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memory.c b/memory.c index 643871baf..d528d1f7f 100644 --- a/memory.c +++ b/memory.c @@ -426,7 +426,7 @@ static void memory_region_iorange_write(IORange *iorange, if (mrp) { mrp->write(mr->opaque, offset, data); } else if (width == 2) { - mrp = find_portio(mr, offset - mrio->offset, 1, false); + mrp = find_portio(mr, offset - mrio->offset, 1, true); assert(mrp); mrp->write(mr->opaque, offset, data & 0xff); mrp->write(mr->opaque, offset + 1, data >> 8); -- cgit v1.2.3 From 4bdb1a3059d7d3a931de0748a2eec39a0ab41b4e Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Fri, 24 Aug 2012 07:03:03 +0200 Subject: qemu-ga: Fix null pointer passed to unlink in failure branch Clang reports this warning: Null pointer passed as an argument to a 'nonnull' parameter Reviewed-by: Luiz Capitulino Signed-off-by: Stefan Weil Signed-off-by: Anthony Liguori --- qemu-ga.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qemu-ga.c b/qemu-ga.c index 26671fee3..762307988 100644 --- a/qemu-ga.c +++ b/qemu-ga.c @@ -438,7 +438,9 @@ static void become_daemon(const char *pidfile) return; fail: - unlink(pidfile); + if (pidfile) { + unlink(pidfile); + } g_critical("failed to daemonize"); exit(EXIT_FAILURE); #endif -- cgit v1.2.3 From 4d09d37c6aa9a02b44b1fdb6268820fab92499bd Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 7 Aug 2012 15:52:03 +0300 Subject: reset PMBA and PMREGMISC PIIX4 registers. The bug causes Windows + OVMF hang after reboot since OVMF checks PMREGMISC to see if IO space is enabled and skip configuration if it is. Reviewed-by: Laszlo Ersek Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori --- hw/acpi_piix4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 72d6e5c90..c56220b36 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -352,6 +352,9 @@ static void piix4_reset(void *opaque) pci_conf[0x5a] = 0; pci_conf[0x5b] = 0; + pci_conf[0x40] = 0x01; /* PM io base read only bit */ + pci_conf[0x80] = 0; + if (s->kvm_enabled) { /* Mark SMM as already inited (until KVM supports SMM). */ pci_conf[0x5B] = 0x02; @@ -391,8 +394,6 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x09] = 0x00; pci_conf[0x3d] = 0x01; // interrupt pin 1 - pci_conf[0x40] = 0x01; /* PM io base read only bit */ - /* APM */ apm_init(&s->apm, apm_ctrl_changed, s); -- cgit v1.2.3 From ef8621b1a3b199c348606c0a11a77d8e8bf135f1 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Wed, 29 Aug 2012 09:32:41 -0500 Subject: target-i386: disable pv eoi to fix migration across QEMU versions We have a problem with how we handle migration with KVM paravirt features. We unconditionally enable paravirt features regardless of whether we know how to migrate them. We also don't tie paravirt features to specific machine types so an old QEMU on a new kernel would expose features that never existed. The 1.2 cycle is over and as things stand, migration is broken. Michael has another series that adds support for migrating PV EOI and attempts to make it work correctly for different machine types. After speaking with Michael on IRC, we agreed to take this patch plus 1 & 4 from his series. This makes sure QEMU can migrate PV EOI if it's enabled, but does not enable it by default. This also means that we won't unconditionally enable new features for guests future proofing us from this happening again in the future. Signed-off-by: Anthony Liguori --- target-i386/cpu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 120a2e3d3..f3cac49fd 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -33,6 +33,7 @@ #include "hyperv.h" #include "hw/hw.h" +#include /* feature flags taken from "Intel Processor Identification and the CPUID * Instruction" and AMD's "CPUID Specification". In cases of disagreement @@ -887,7 +888,17 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) memcpy(x86_cpu_def, def, sizeof(*def)); } - plus_kvm_features = ~0; /* not supported bits will be filtered out later */ +#if defined(CONFIG_KVM) + plus_kvm_features = (1 << KVM_FEATURE_CLOCKSOURCE) | + (1 << KVM_FEATURE_NOP_IO_DELAY) | + (1 << KVM_FEATURE_MMU_OP) | + (1 << KVM_FEATURE_CLOCKSOURCE2) | + (1 << KVM_FEATURE_ASYNC_PF) | + (1 << KVM_FEATURE_STEAL_TIME) | + (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT); +#else + plus_kvm_features = 0; +#endif add_flagname_to_bitmaps("hypervisor", &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, -- cgit v1.2.3 From 651682dcf54c4f2e07904bd822a97895900f6d8a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 28 Aug 2012 20:43:42 +0300 Subject: linux-headers: update to 3.6-rc3 Update linux-headers to version present in Linux 3.6-rc3. Header asm-x96_64/kvm_para.h update is needed for the new PV EOI feature. Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori --- linux-headers/asm-s390/kvm.h | 2 +- linux-headers/asm-s390/kvm_para.h | 2 +- linux-headers/asm-x86/kvm.h | 1 + linux-headers/asm-x86/kvm_para.h | 7 +++++++ linux-headers/linux/kvm.h | 3 +++ 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h index bdcbe0f8d..d25da598e 100644 --- a/linux-headers/asm-s390/kvm.h +++ b/linux-headers/asm-s390/kvm.h @@ -1,7 +1,7 @@ #ifndef __LINUX_KVM_S390_H #define __LINUX_KVM_S390_H /* - * asm-s390/kvm.h - KVM s390 specific structures and definitions + * KVM s390 specific structures and definitions * * Copyright IBM Corp. 2008 * diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h index 8e2dd6706..870051f64 100644 --- a/linux-headers/asm-s390/kvm_para.h +++ b/linux-headers/asm-s390/kvm_para.h @@ -1,5 +1,5 @@ /* - * asm-s390/kvm_para.h - definition for paravirtual devices on s390 + * definition for paravirtual devices on s390 * * Copyright IBM Corp. 2008 * diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index e7d1c194d..246617efd 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -12,6 +12,7 @@ /* Select x86 specific features in */ #define __KVM_HAVE_PIT #define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_DEVICE_ASSIGNMENT #define __KVM_HAVE_MSI #define __KVM_HAVE_USER_NMI diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index f2ac46a2a..a1c3d72ac 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -22,6 +22,7 @@ #define KVM_FEATURE_CLOCKSOURCE2 3 #define KVM_FEATURE_ASYNC_PF 4 #define KVM_FEATURE_STEAL_TIME 5 +#define KVM_FEATURE_PV_EOI 6 /* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. @@ -37,6 +38,7 @@ #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 #define MSR_KVM_STEAL_TIME 0x4b564d03 +#define MSR_KVM_PV_EOI_EN 0x4b564d04 struct kvm_steal_time { __u64 steal; @@ -89,5 +91,10 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_EOI_BIT 0 +#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT) +#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK +#define KVM_PV_EOI_DISABLED 0x0 + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 5a9d4e350..4b9e575dd 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -617,6 +617,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_SIGNAL_MSI 77 #define KVM_CAP_PPC_GET_SMMU_INFO 78 #define KVM_CAP_S390_COW 79 +#define KVM_CAP_PPC_ALLOC_HTAB 80 #ifdef KVM_CAP_IRQ_ROUTING @@ -828,6 +829,8 @@ struct kvm_s390_ucas_mapping { #define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi) /* Available with KVM_CAP_PPC_GET_SMMU_INFO */ #define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) +/* Available with KVM_CAP_PPC_ALLOC_HTAB */ +#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) /* * ioctls for vcpu fds -- cgit v1.2.3 From bc9a839d569d4d8532c5c097bf1f4583226e3aa0 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 28 Aug 2012 20:43:56 +0300 Subject: kvm: get/set PV EOI MSR Support get/set of new PV EOI MSR, for migration. Add an optional section for MSR value - send it out in case MSR was changed from the default value (0). Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori --- target-i386/cpu.h | 1 + target-i386/kvm.c | 13 +++++++++++++ target-i386/machine.c | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 60f9e972b..0677502dc 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -699,6 +699,7 @@ typedef struct CPUX86State { uint64_t system_time_msr; uint64_t wall_clock_msr; uint64_t async_pf_en_msr; + uint64_t pv_eoi_en_msr; uint64_t tsc; uint64_t tsc_deadline; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 696b14a04..ffc294ec3 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -63,6 +63,7 @@ static bool has_msr_star; static bool has_msr_hsave_pa; static bool has_msr_tsc_deadline; static bool has_msr_async_pf_en; +static bool has_msr_pv_eoi_en; static bool has_msr_misc_enable; static int lm_capable_kernel; @@ -455,6 +456,8 @@ int kvm_arch_init_vcpu(CPUX86State *env) has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); + has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI); + cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); for (i = 0; i <= limit; i++) { @@ -1017,6 +1020,10 @@ static int kvm_put_msrs(CPUX86State *env, int level) kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr); } + if (has_msr_pv_eoi_en) { + kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN, + env->pv_eoi_en_msr); + } if (hyperv_hypercall_available()) { kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0); kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0); @@ -1259,6 +1266,9 @@ static int kvm_get_msrs(CPUX86State *env) if (has_msr_async_pf_en) { msrs[n++].index = MSR_KVM_ASYNC_PF_EN; } + if (has_msr_pv_eoi_en) { + msrs[n++].index = MSR_KVM_PV_EOI_EN; + } if (env->mcg_cap) { msrs[n++].index = MSR_MCG_STATUS; @@ -1338,6 +1348,9 @@ static int kvm_get_msrs(CPUX86State *env) case MSR_KVM_ASYNC_PF_EN: env->async_pf_en_msr = msrs[i].data; break; + case MSR_KVM_PV_EOI_EN: + env->pv_eoi_en_msr = msrs[i].data; + break; } } diff --git a/target-i386/machine.c b/target-i386/machine.c index a8be058d2..477150887 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -279,6 +279,13 @@ static bool async_pf_msr_needed(void *opaque) return cpu->async_pf_en_msr != 0; } +static bool pv_eoi_msr_needed(void *opaque) +{ + CPUX86State *cpu = opaque; + + return cpu->pv_eoi_en_msr != 0; +} + static const VMStateDescription vmstate_async_pf_msr = { .name = "cpu/async_pf_msr", .version_id = 1, @@ -290,6 +297,17 @@ static const VMStateDescription vmstate_async_pf_msr = { } }; +static const VMStateDescription vmstate_pv_eoi_msr = { + .name = "cpu/async_pv_eoi_msr", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(pv_eoi_en_msr, CPUX86State), + VMSTATE_END_OF_LIST() + } +}; + static bool fpop_ip_dp_needed(void *opaque) { CPUX86State *env = opaque; @@ -453,6 +471,9 @@ static const VMStateDescription vmstate_cpu = { { .vmsd = &vmstate_async_pf_msr, .needed = async_pf_msr_needed, + } , { + .vmsd = &vmstate_pv_eoi_msr, + .needed = pv_eoi_msr_needed, } , { .vmsd = &vmstate_fpop_ip_dp, .needed = fpop_ip_dp_needed, -- cgit v1.2.3 From 3cac001e5ae3c0ceb33e0a1978a48cb5e2482ab2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 29 Aug 2012 19:40:56 +0300 Subject: msix: make [un]use vectors on reset/load optional The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function. Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly. This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did. Tested-by: Cam Macdonell Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori --- hw/msix.c | 13 +++++++++++-- hw/virtio-pci.c | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/msix.c b/hw/msix.c index aea340b7c..d81209413 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -336,6 +336,15 @@ static void msix_free_irq_entries(PCIDevice *dev) } } +static void msix_clear_all_vectors(PCIDevice *dev) +{ + int vector; + + for (vector = 0; vector < dev->msix_entries_nr; ++vector) { + msix_clr_pending(dev, vector); + } +} + /* Clean up resources for the device. */ void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar) { @@ -390,7 +399,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f) return; } - msix_free_irq_entries(dev); + msix_clear_all_vectors(dev); qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE); qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8); msix_update_function_masked(dev); @@ -436,7 +445,7 @@ void msix_reset(PCIDevice *dev) if (!msix_present(dev)) { return; } - msix_free_irq_entries(dev); + msix_clear_all_vectors(dev); dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &= ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET]; memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 2a3d86f17..b3f0710f3 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f) if (ret) { return ret; } + msix_unuse_all_vectors(&proxy->pci_dev); msix_load(&proxy->pci_dev, f); if (msix_present(&proxy->pci_dev)) { qemu_get_be16s(f, &proxy->vdev->config_vector); @@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d) VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev); virtio_pci_stop_ioeventfd(proxy); virtio_reset(proxy->vdev); + msix_unuse_all_vectors(&proxy->pci_dev); proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } -- cgit v1.2.3 From 5bb0b62e750c24886e90d1399eb9f03c68404001 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 29 Aug 2012 20:39:25 +0200 Subject: scsi-disk: Fix typo (uint32 -> uint32_t) Cc: Paolo Bonzini Signed-off-by: Stefan Weil Signed-off-by: Anthony Liguori --- hw/scsi-disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 21b862dad..1585683bc 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1461,7 +1461,7 @@ static void scsi_unmap_complete(void *opaque, int ret) SCSIDiskReq *r = data->r; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint64_t sector_num; - uint32 nb_sectors; + uint32_t nb_sectors; r->req.aiocb = NULL; if (ret < 0) { -- cgit v1.2.3 From c9a238e7005bc6c94c7367b2976402ee5adec0de Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Thu, 30 Aug 2012 07:45:28 -0500 Subject: Update version for 1.2.0-rc2 Signed-off-by: Anthony Liguori --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 069199b82..99f6a00b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.91 +1.1.92 -- cgit v1.2.3 From b834b5081d6266cc0789454905f3b7d622d4d096 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 30 Aug 2012 22:28:31 +0200 Subject: w32: Fix broken build Commit ef8621b1a3b199c348606c0a11a77d8e8bf135f1 added an include file which is not available for MinGW compilations. Signed-off-by: Stefan Weil Signed-off-by: Anthony Liguori --- target-i386/cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index f3cac49fd..423e00905 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -33,7 +33,9 @@ #include "hyperv.h" #include "hw/hw.h" +#if defined(CONFIG_KVM) #include +#endif /* feature flags taken from "Intel Processor Identification and the CPUID * Instruction" and AMD's "CPUID Specification". In cases of disagreement -- cgit v1.2.3