From 9220eeed62e06e115c83e6ffed24907c24c99197 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sat, 29 Jun 2013 15:10:48 +0000 Subject: [PATCH 01/27] aes: Remove unused code (NDEBUG, u16) The current code includes assert.h very early (from qemu-common.h), so the definition of NDEBUG was without any effect. In the initial version from 2004, NDEBUG was used to disable the assertions. Those assertions are not in time critical code, so it is no longer reasonable to disable them and the definition of NDEBUG can be removed. Type u16 is also unused and therefore does not need a type definition. Signed-off-by: Stefan Weil Signed-off-by: Michael Tokarev --- util/aes.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/util/aes.c b/util/aes.c index 91e97fa6e7..4b4d88e7e6 100644 --- a/util/aes.c +++ b/util/aes.c @@ -30,12 +30,7 @@ #include "qemu-common.h" #include "qemu/aes.h" -#ifndef NDEBUG -#define NDEBUG -#endif - typedef uint32_t u32; -typedef uint16_t u16; typedef uint8_t u8; /* This controls loop-unrolling in aes_core.c */ From d9cd4007d5c7e877a006392eeafb2291f06d6685 Mon Sep 17 00:00:00 2001 From: Liu Ping Fan Date: Sun, 21 Jul 2013 08:43:00 +0000 Subject: [PATCH 02/27] timer: make timers_state static Signed-off-by: Liu Ping Fan Reviewed-by: Jan Kiszka Signed-off-by: Michael Tokarev --- cpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index ca6b886592..0f65e763f2 100644 --- a/cpus.c +++ b/cpus.c @@ -112,7 +112,7 @@ typedef struct TimersState { int64_t dummy; } TimersState; -TimersState timers_state; +static TimersState timers_state; /* Return the virtual CPU time, based on the instruction counter. */ int64_t cpu_get_icount(void) From 80cba1b71eb9a75404d1effddec8ffa9f0d6d6fb Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 16 Jun 2013 12:14:36 +0200 Subject: [PATCH 03/27] hw/9pfs: Fix potential memory leak and avoid reuse of freed memory The leak was reported by cppcheck. Function proxy_init also calls g_free for ctx->fs_root. Avoid reuse of this memory by setting ctx->fs_root to NULL. Signed-off-by: Stefan Weil Reviewed-by: M. Mohan Kumar Signed-off-by: Michael Tokarev --- hw/9pfs/virtio-9p-proxy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index 8ba2959dbb..5f44bb758b 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -1153,10 +1153,12 @@ static int proxy_init(FsContext *ctx) sock_id = atoi(ctx->fs_root); if (sock_id < 0) { fprintf(stderr, "socket descriptor not initialized\n"); + g_free(proxy); return -1; } } g_free(ctx->fs_root); + ctx->fs_root = NULL; proxy->in_iovec.iov_base = g_malloc(PROXY_MAX_IO_SZ + PROXY_HDR_SZ); proxy->in_iovec.iov_len = PROXY_MAX_IO_SZ + PROXY_HDR_SZ; From 0dd60ae2f4efd2966e8d6cb7db653d5d17a68c62 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 21 Jul 2013 16:43:14 +0200 Subject: [PATCH 04/27] exec: Remove env from list of poisoned names The global variable env was removed some time ago, so this name may be used without any restriction now. Signed-off-by: Stefan Weil Signed-off-by: Michael Tokarev --- include/exec/poison.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/exec/poison.h b/include/exec/poison.h index 2341a75041..a4b1eca24f 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -36,7 +36,6 @@ #pragma GCC poison TARGET_PAGE_ALIGN #pragma GCC poison CPUArchState -#pragma GCC poison env #pragma GCC poison lduw_phys #pragma GCC poison ldl_phys From f6019e5fada012f7f396c89968f2c242f92f40df Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Tue, 23 Jul 2013 06:46:49 +0200 Subject: [PATCH 05/27] watchdog: Remove break after exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was dead code. Signed-off-by: Stefan Weil Reviewed-by: Andreas Färber Signed-off-by: Michael Tokarev --- hw/watchdog/watchdog.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index cb4e1f9e47..387962ec4a 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -128,7 +128,6 @@ void watchdog_perform_action(void) case WDT_POWEROFF: /* same as 'quit' command in monitor */ watchdog_mon_event("poweroff"); exit(0); - break; case WDT_PAUSE: /* same as 'stop' command in monitor */ watchdog_mon_event("pause"); From 04dd125942b11136a8c96d36591ad043b8653a7b Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Fri, 12 Jul 2013 18:48:39 +0200 Subject: [PATCH 06/27] PPC: dbdma: macio: Fix format specifiers (build regression) Fix a number of warnings for 32 bit builds (tested on MingW and Linux): CC hw/ide/macio.o qemu/hw/ide/macio.c: In function 'pmac_ide_atapi_transfer_cb': qemu/hw/ide/macio.c:134:9: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' [-Werror=format] qemu/hw/ide/macio.c: In function 'pmac_ide_transfer_cb': qemu/hw/ide/macio.c:215:5: error: format '%ld' expects argument of type 'long int', but argument 5 has type 'int64_t' [-Werror=format] qemu/hw/ide/macio.c:222:9: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' [-Werror=format] qemu/hw/ide/macio.c:264:9: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'hwaddr' [-Werror=format] cc1: all warnings being treated as errors make: *** [hw/ide/macio.o] Error 1 Signed-off-by: Stefan Weil Acked-by: Alexander Graf Signed-off-by: Michael Tokarev --- hw/ide/macio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 38ad92423d..ef4ba2b2c5 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -131,7 +131,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) int sector_num = (s->lba << 2) + (s->io_buffer_index >> 9); int nsector = io->len >> 9; - MACIO_DPRINTF("precopying unaligned %d bytes to %#lx\n", + MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n", unaligned, io->addr + io->len - unaligned); bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); @@ -212,14 +212,15 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) s->nsector -= n; } - MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d sector_num: %ld\n", + MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d " + "sector_num: %" PRId64 "\n", io->remainder_len, io->len, s->nsector, sector_num); if (io->remainder_len && io->len) { /* guest wants the rest of its previous transfer */ int remainder_len = MIN(io->remainder_len, io->len); uint8_t *p = &io->remainder[0x200 - remainder_len]; - MACIO_DPRINTF("copying remainder %d bytes at %#lx\n", + MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\n", remainder_len, io->addr); switch (s->dma_cmd) { @@ -261,7 +262,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) if (unaligned) { int nsector = io->len >> 9; - MACIO_DPRINTF("precopying unaligned %d bytes to %#lx\n", + MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n", unaligned, io->addr + io->len - unaligned); switch (s->dma_cmd) { From 6064be7912ab262f0abd85ad042fafd435ad6651 Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Tue, 23 Jul 2013 19:00:10 +0200 Subject: [PATCH 07/27] linux-user: correct argument number for sys_mremap and sys_splice sys_mremap missed 5th argument (new_address), which caused examples that remap to a specific address to fail. sys_splice missed 5th and 6th argument which caused different examples to fail. This change has an effect on MIPS target only. Signed-off-by: Petar Jovanovic Reviewed-by: Peter Maydell Signed-off-by: Michael Tokarev --- linux-user/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 5309117034..03859bcc23 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1920,7 +1920,7 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_sched_get_priority_min, 1) MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */ MIPS_SYS(sys_nanosleep, 2) - MIPS_SYS(sys_mremap , 4) + MIPS_SYS(sys_mremap , 5) MIPS_SYS(sys_accept , 3) MIPS_SYS(sys_bind , 3) MIPS_SYS(sys_connect , 3) /* 4170 */ @@ -2057,7 +2057,7 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_pselect6, 6) MIPS_SYS(sys_ppoll, 5) MIPS_SYS(sys_unshare, 1) - MIPS_SYS(sys_splice, 4) + MIPS_SYS(sys_splice, 6) MIPS_SYS(sys_sync_file_range, 7) /* 4305 */ MIPS_SYS(sys_tee, 4) MIPS_SYS(sys_vmsplice, 4) From 52f350227f737b649f09e56ed32eaf1265605611 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 24 Jul 2013 19:48:56 +0200 Subject: [PATCH 08/27] misc: Fix new typos in comments and strings All these typos were found by codespell. sould -> should emperical -> empirical intialization -> initialization successfuly -> successfully gaurantee -> guarantee Fix also another error (before before) in the same context. Signed-off-by: Stefan Weil Reviewed-by: Peter Maydell Signed-off-by: Michael Tokarev --- block/vhdx.h | 2 +- docs/rdma.txt | 2 +- hw/virtio/virtio-balloon.c | 4 ++-- hw/xen/xen_pt.c | 3 ++- migration-rdma.c | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/block/vhdx.h b/block/vhdx.h index c3b64c6ff6..fb687ed2d6 100644 --- a/block/vhdx.h +++ b/block/vhdx.h @@ -168,7 +168,7 @@ typedef struct QEMU_PACKED VHDXLogEntryHeader { vhdx_header. If not found in vhdx_header, it is invalid */ uint64_t flushed_file_offset; /* see spec for full details - this - sould be vhdx file size in bytes */ + should be vhdx file size in bytes */ uint64_t last_file_offset; /* size in bytes that all allocated file structures fit into */ } VHDXLogEntryHeader; diff --git a/docs/rdma.txt b/docs/rdma.txt index 45d1c8aab8..8d1e003f92 100644 --- a/docs/rdma.txt +++ b/docs/rdma.txt @@ -199,7 +199,7 @@ Version #1 requires that all server implementations of the protocol must check this field and register all requests found in the array of commands located in the data portion and return an equal number of results in the response. The maximum number of repeats is hard-coded to 4096. This is a conservative -limit based on the maximum size of a SEND message along with emperical +limit based on the maximum size of a SEND message along with empirical observations on the maximum future benefit of simultaneous page registrations. The 'type' field has 12 different command values: diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 3fa72a97b9..337cfa517a 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -53,8 +53,8 @@ static const char *balloon_stat_names[] = { /* * reset_stats - Mark all items in the stats array as unset * - * This function needs to be called at device intialization and before - * before updating to a set of newly-generated stats. This will ensure that no + * This function needs to be called at device initialization and before + * updating to a set of newly-generated stats. This will ensure that no * stale values stick around in case the guest reports a subset of the supported * statistics. */ diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index d7ee7745c8..d15a7290cc 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -756,7 +756,8 @@ static int xen_pt_initfn(PCIDevice *d) out: memory_listener_register(&s->memory_listener, &address_space_memory); memory_listener_register(&s->io_listener, &address_space_io); - XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n", + XEN_PT_LOG(d, + "Real physical device %02x:%02x.%d registered successfully!\n", s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function); return 0; diff --git a/migration-rdma.c b/migration-rdma.c index d044830ed8..4828738560 100644 --- a/migration-rdma.c +++ b/migration-rdma.c @@ -2494,7 +2494,7 @@ static int qemu_rdma_close(void *opaque) * @size == 0 : * A 'hint' or 'advice' that means that we wish to speculatively * and asynchronously unregister this memory. In this case, there is no - * gaurantee that the unregister will actually happen, for example, + * guarantee that the unregister will actually happen, for example, * if the memory is being actively transmitted. Additionally, the memory * may be re-registered at any future time if a write within the same * chunk was requested again, even if you attempted to unregister it @@ -2570,7 +2570,7 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque, qemu_rdma_signal_unregister(rdma, index, chunk, 0); /* - * TODO: Synchronous, gauranteed unregistration (should not occur during + * TODO: Synchronous, guaranteed unregistration (should not occur during * fast-path). Otherwise, unregisters will process on the next call to * qemu_rdma_drain_cq() if (size < 0) { From b031f413b9e68899032f04fc05fd0a6b62039b2b Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Sat, 20 Jul 2013 16:53:09 +0530 Subject: [PATCH 09/27] qemu-options: mention C-a h in the -nographic doc Otherwise, a new user will be wondering how to switch between the console and monitor. Cc: Anthony Liguori Cc: Stefan Hajnoczi Cc: Markus Armbruster Cc: Marcelo Tosatti Cc: Peter Maydell Signed-off-by: Ramkumar Ramachandra Signed-off-by: Michael Tokarev --- qemu-options.hx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 2dbfd42a8c..25ecb55da4 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -844,7 +844,8 @@ you can totally disable graphical output so that QEMU is a simple command line application. The emulated serial port is redirected on the console and muxed with the monitor (unless redirected elsewhere explicitly). Therefore, you can still use QEMU to debug a Linux kernel -with a serial console. +with a serial console. Use @key{C-a h} for help on switching between +the console and monitor. ETEXI DEF("curses", 0, QEMU_OPTION_curses, From dfc6f86567c58bc4dd02f4db098fc4c2221e85b5 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 25 Jul 2013 18:21:28 +0200 Subject: [PATCH 10/27] misc: Use g_assert_not_reached for code which is expected to be unreachable The macro g_assert_not_reached is a better self documenting replacement for assert(0) or assert(false). Signed-off-by: Stefan Weil Signed-off-by: Michael Tokarev --- blockdev.c | 2 +- hw/net/vmxnet3.c | 16 ++++++++-------- hw/net/vmxnet_tx_pkt.c | 2 +- hw/usb/hcd-ehci.c | 8 ++++---- net/eth.c | 2 +- qdev-monitor.c | 4 ++-- target-arm/helper.c | 2 +- tests/test-qmp-input-visitor.c | 2 +- tests/test-qmp-output-visitor.c | 4 ++-- tests/test-visitor-serialization.c | 8 ++++---- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/blockdev.c b/blockdev.c index 4534864802..7879e8593d 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1029,7 +1029,7 @@ static void abort_prepare(BlkTransactionState *common, Error **errp) static void abort_commit(BlkTransactionState *common) { - assert(false); /* this action never succeeds */ + g_assert_not_reached(); /* this action never succeeds */ } static const BdrvActionOps actions[] = { diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index b39ff08f28..0f3c58c8e4 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -528,7 +528,7 @@ vmxnet3_setup_tx_offloads(VMXNET3State *s) break; default: - assert(false); + g_assert_not_reached(); return false; } @@ -575,7 +575,7 @@ vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx, stats->ucastBytesTxOK += tot_len; break; default: - assert(false); + g_assert_not_reached(); } if (s->offload_mode == VMXNET3_OM_TSO) { @@ -599,7 +599,7 @@ vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx, break; default: - assert(false); + g_assert_not_reached(); } } @@ -634,7 +634,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s, stats->ucastBytesRxOK += tot_len; break; default: - assert(false); + g_assert_not_reached(); } if (tot_len > s->mtu) { @@ -643,7 +643,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s, } break; default: - assert(false); + g_assert_not_reached(); } } @@ -1106,7 +1106,7 @@ vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size) { if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR, VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) { - assert(false); + g_assert_not_reached(); } VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size); @@ -1651,7 +1651,7 @@ vmxnet3_io_bar1_write(void *opaque, case VMXNET3_REG_ICR: VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d", val, size); - assert(false); + g_assert_not_reached(); break; /* Event Cause Register */ @@ -1801,7 +1801,7 @@ vmxnet3_rx_filter_may_indicate(VMXNET3State *s, const void *data, break; default: - assert(false); + g_assert_not_reached(); } return true; diff --git a/hw/net/vmxnet_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c index fc01e4da3c..f7344c4cb3 100644 --- a/hw/net/vmxnet_tx_pkt.c +++ b/hw/net/vmxnet_tx_pkt.c @@ -287,7 +287,7 @@ void vmxnet_tx_pkt_build_vheader(struct VmxnetTxPkt *pkt, bool tso_enable, break; default: - assert(false); + g_assert_not_reached(); } if (csum_enable) { diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 67e4b24273..010a0d0d32 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1357,7 +1357,7 @@ static void ehci_execute_complete(EHCIQueue *q) default: /* should not be triggerable */ fprintf(stderr, "USB invalid response %d\n", p->packet.status); - assert(0); + g_assert_not_reached(); break; } @@ -2142,7 +2142,7 @@ static void ehci_advance_state(EHCIState *ehci, int async) default: fprintf(stderr, "Bad state!\n"); again = -1; - assert(0); + g_assert_not_reached(); break; } @@ -2206,7 +2206,7 @@ static void ehci_advance_async_state(EHCIState *ehci) /* this should only be due to a developer mistake */ fprintf(stderr, "ehci: Bad asynchronous state %d. " "Resetting to active\n", ehci->astate); - assert(0); + g_assert_not_reached(); } } @@ -2256,7 +2256,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci) /* this should only be due to a developer mistake */ fprintf(stderr, "ehci: Bad periodic state %d. " "Resetting to active\n", ehci->pstate); - assert(0); + g_assert_not_reached(); } } diff --git a/net/eth.c b/net/eth.c index 1d7494d5e5..7c61132cbb 100644 --- a/net/eth.c +++ b/net/eth.c @@ -73,7 +73,7 @@ eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto) } /* Unsupported offload */ - assert(false); + g_assert_not_reached(); return VIRTIO_NET_HDR_GSO_NONE | ecn_state; } diff --git a/qdev-monitor.c b/qdev-monitor.c index e54dbc2c5d..e5adf6c9d0 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -360,7 +360,7 @@ static BusState *qbus_find(const char *path) /* find device */ if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) { - assert(0); + g_assert_not_reached(); elem[0] = len = 0; } pos += len; @@ -397,7 +397,7 @@ static BusState *qbus_find(const char *path) /* find bus */ if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) { - assert(0); + g_assert_not_reached(); elem[0] = len = 0; } pos += len; diff --git a/target-arm/helper.c b/target-arm/helper.c index b0c3ca1fbe..4968391b83 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1653,7 +1653,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, "was %s, now %s\n", r2->cp, 32 + 32 * is64, r2->crn, r2->crm, r2->opc1, r2->opc2, oldreg->name, r2->name); - assert(0); + g_assert_not_reached(); } } g_hash_table_insert(cpu->cp_regs, key, r2); diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index 2741eef3fa..0beb8fbfd2 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -394,7 +394,7 @@ static void test_native_list_integer_helper(TestInputVisitorData *data, break; } default: - g_assert(false); + g_assert_not_reached(); } g_string_free(gstr_union, true); diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index b2fa9a74f6..e073d833bf 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -559,7 +559,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue) break; } default: - g_assert(false); + g_assert_not_reached(); } } @@ -645,7 +645,7 @@ static void check_native_list(QObject *qobj, } break; default: - g_assert(false); + g_assert_not_reached(); } QDECREF(qlist); } diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index ee7916b806..9aaa5872e5 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -136,7 +136,7 @@ static void visit_primitive_type(Visitor *v, void **native, Error **errp) visit_type_int64(v, &pt->value.s64, NULL, errp); break; case PTYPE_EOL: - g_assert(false); + g_assert_not_reached(); } } @@ -181,7 +181,7 @@ static void visit_primitive_list(Visitor *v, void **native, Error **errp) visit_type_uint64List(v, &pl->value.u64_integers, NULL, errp); break; default: - g_assert(false); + g_assert_not_reached(); } } @@ -500,7 +500,7 @@ static void test_primitive_lists(gconstpointer opaque) break; } default: - g_assert(0); + g_assert_not_reached(); } } @@ -656,7 +656,7 @@ static void test_primitive_lists(gconstpointer opaque) break; } default: - g_assert(0); + g_assert_not_reached(); } i++; } while (cur_head); From 6c86f405efd6532b58ad1b607cc9f11e856ef5ca Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 25 Jul 2013 22:10:31 +0200 Subject: [PATCH 11/27] target-mips: Remove assignment to a variable which is never used This assignment causes a compiler warning for compilations with the compiler option -Wunused-but-set-variable (which is included with -Wextra). Removing it allows using -Wextra for QEMU code without suppressing too many extra warnings. Signed-off-by: Stefan Weil Signed-off-by: Michael Tokarev --- target-mips/op_helper.c | 1 - 1 file changed, 1 deletion(-) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 5cf1c3f04b..b828375714 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1735,7 +1735,6 @@ target_ulong helper_evpe(CPUMIPSState *env) void helper_fork(target_ulong arg1, target_ulong arg2) { // arg1 = rt, arg2 = rs - arg1 = 0; // TODO: store to TC register } From 4877866ee4fbd760c943577bb6d1eba489fb6c6e Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Thu, 23 May 2013 19:37:53 +0200 Subject: [PATCH 12/27] target-mips: fix multiplication in mipsdsp_rndq15_mul_q15_q15 Multiplication of Q15 fractional halfword vectors was incorrect in the previous implementation of mipsdsp_rndq15_mul_q15_q15. It failed to take element signs into account. This change fixes it, and it adds a test case for it. The change also removes unnecessary cast in the function mipsdsp_mul_q15_q15_overflowflag21(). Signed-off-by: Petar Jovanovic Reviewed-by: Richard Henderson Signed-off-by: Aurelien Jarno --- target-mips/dsp_helper.c | 4 ++-- tests/tcg/mips/mips32-dsp/mulq_rs_ph.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index 4116de93c3..c718a786e1 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -390,7 +390,7 @@ static inline int32_t mipsdsp_mul_q15_q15_overflowflag21(uint16_t a, uint16_t b, temp = 0x7FFFFFFF; set_DSPControl_overflow_flag(1, 21, env); } else { - temp = ((int32_t)(int16_t)a * (int32_t)(int16_t)b) << 1; + temp = ((int16_t)a * (int16_t)b) << 1; } return temp; @@ -622,7 +622,7 @@ static inline int16_t mipsdsp_rndq15_mul_q15_q15(uint16_t a, uint16_t b, temp = 0x7FFF0000; set_DSPControl_overflow_flag(1, 21, env); } else { - temp = (a * b) << 1; + temp = ((int16_t)a * (int16_t)b) << 1; temp = temp + 0x00008000; } diff --git a/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c index c7206039ea..370c2a8018 100644 --- a/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c +++ b/tests/tcg/mips/mips32-dsp/mulq_rs_ph.c @@ -12,7 +12,24 @@ int main() resultdsp = 1; __asm - ("mulq_rs.ph %0, %2, %3\n\t" + ("wrdsp $0\n\t" + "mulq_rs.ph %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 21) & 0x01; + assert(rd == result); + assert(dsp == resultdsp); + + rs = 0x80011234; + rt = 0x80024321; + result = 0x7FFD098C; + resultdsp = 0; + + __asm + ("wrdsp $0\n\t" + "mulq_rs.ph %0, %2, %3\n\t" "rddsp %1\n\t" : "=r"(rd), "=r"(dsp) : "r"(rs), "r"(rt) From 240ce26a0533a6e5ee472789fbfbd9f7f939197e Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 24 Jun 2013 17:45:39 +0100 Subject: [PATCH 13/27] target-mips: fix branch in likely delay slot tcg assert When a branch delay slot contains another branch instruction, the code generated raises an exception, however since is_branch==1, handle_delay_slot() doesn't get called immediately. This means ctx->bstate isn't set to BS_BRANCH, and the decoder continues decoding until a non-branch instruction is found. If the first branch was a branch likely instruction then each instruction after it generates code for the unlikely case, to go to the next tb starting after the delay slot. This results in multiple goto_tb tcg ops being generated with the same exit number. When debug is enabled this hits: tcg-op.h:2589: tcg_gen_goto_tb: Assertion `(tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0' failed. This is fixed by removing is_branch entirely, and calling handle_delay_slot() if (ctx.hflags & MIPS_HFLAG_BMASK) was set prior to the current instruction being decoded. This still prevents handle_delay_slot() being called immediately after a branch but allows it to still be called after a branch within a delay slot. Signed-off-by: James Hogan Signed-off-by: Yongbok Kim Signed-off-by: Aurelien Jarno --- target-mips/translate.c | 62 +++++++++++------------------------------ 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 877f8dfe88..c1d57a791e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -9571,8 +9571,7 @@ static void decode_i64_mips16 (DisasContext *ctx, } #endif -static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx, - int *is_branch) +static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx) { int extend = cpu_lduw_code(env, ctx->pc + 2); int op, rx, ry, funct, sa; @@ -9763,8 +9762,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx, return 4; } -static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, - int *is_branch) +static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx) { int rx, ry; int sa; @@ -9807,7 +9805,6 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS; gen_compute_branch(ctx, op, 4, rx, ry, offset); n_bytes = 4; - *is_branch = 1; break; case M16_OPC_BEQZ: gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1); @@ -10046,9 +10043,6 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, } gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0); - if (!nd) { - *is_branch = 1; - } } break; case RR_SDBBP: @@ -10193,7 +10187,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, } break; case M16_OPC_EXTEND: - decode_extended_mips16_opc(env, ctx, is_branch); + decode_extended_mips16_opc(env, ctx); n_bytes = 4; break; #if defined(TARGET_MIPS64) @@ -10802,7 +10796,7 @@ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist, } -static void gen_pool16c_insn(DisasContext *ctx, int *is_branch) +static void gen_pool16c_insn(DisasContext *ctx) { int rd = mmreg((ctx->opcode >> 3) & 0x7); int rs = mmreg(ctx->opcode & 0x7); @@ -10864,7 +10858,6 @@ static void gen_pool16c_insn(DisasContext *ctx, int *is_branch) gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0); } - *is_branch = 1; break; case JRC16 + 0: case JRC16 + 1: @@ -10889,7 +10882,6 @@ static void gen_pool16c_insn(DisasContext *ctx, int *is_branch) gen_compute_branch(ctx, opc, 2, reg, 31, 0); } - *is_branch = 1; break; case MFHI16 + 0: case MFHI16 + 1: @@ -11020,8 +11012,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, tcg_temp_free(t1); } -static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, - int *is_branch) +static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) { int extension = (ctx->opcode >> 6) & 0x3f; int minor = (ctx->opcode >> 12) & 0xf; @@ -11147,12 +11138,10 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, case JALR: case JALR_HB: gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0); - *is_branch = 1; break; case JALRS: case JALRS_HB: gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0); - *is_branch = 1; break; default: goto pool32axf_invalid; @@ -11551,7 +11540,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) } static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, - uint16_t insn_hw1, int *is_branch) + uint16_t insn_hw1) { int32_t offset; uint16_t insn; @@ -11685,7 +11674,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); return; case POOL32AXF: - gen_pool32axf(env, ctx, rt, rs, is_branch); + gen_pool32axf(env, ctx, rt, rs); break; case 0x07: generate_exception(ctx, EXCP_BREAK); @@ -12048,7 +12037,6 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, mips32_op = OPC_BGTZ; do_branch: gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1); - *is_branch = 1; break; /* Traps */ @@ -12109,7 +12097,6 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, do_cp1branch: gen_compute_branch1(ctx, mips32_op, (ctx->opcode >> 18) & 0x7, imm << 1); - *is_branch = 1; break; case BPOSGE64: case BPOSGE32: @@ -12216,30 +12203,24 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, case JALX32: offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset); - *is_branch = 1; break; case JALS32: offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1; gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset); - *is_branch = 1; break; case BEQ32: gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1); - *is_branch = 1; break; case BNE32: gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1); - *is_branch = 1; break; case J32: gen_compute_branch(ctx, OPC_J, 4, rt, rs, (int32_t)(ctx->opcode & 0x3FFFFFF) << 1); - *is_branch = 1; break; case JAL32: gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, (int32_t)(ctx->opcode & 0x3FFFFFF) << 1); - *is_branch = 1; break; /* Floating point (COP1) */ case LWC132: @@ -12309,7 +12290,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, } } -static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) +static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx) { uint32_t op; @@ -12442,7 +12423,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_b } break; case POOL16C: - gen_pool16c_insn(ctx, is_branch); + gen_pool16c_insn(ctx); break; case LWGP16: { @@ -12582,14 +12563,12 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_b case B16: gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, SIMM(ctx->opcode, 0, 10) << 1); - *is_branch = 1; break; case BNEZ16: case BEQZ16: gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2, mmreg(uMIPS_RD(ctx->opcode)), 0, SIMM(ctx->opcode, 0, 7) << 1); - *is_branch = 1; break; case LI16: { @@ -12610,7 +12589,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_b generate_exception(ctx, EXCP_RI); break; default: - decode_micromips32_opc (env, ctx, op, is_branch); + decode_micromips32_opc (env, ctx, op); return 4; } @@ -14346,7 +14325,7 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, /* End MIPSDSP functions. */ -static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) +static void decode_opc (CPUMIPSState *env, DisasContext *ctx) { int32_t offset; int rs, rt, rd, sa; @@ -14460,7 +14439,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) break; case OPC_JR ... OPC_JALR: gen_compute_branch(ctx, op1, 4, rs, rd, sa); - *is_branch = 1; break; case OPC_TGE ... OPC_TEQ: /* Traps */ case OPC_TNE: @@ -15227,7 +15205,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */ case OPC_BLTZAL ... OPC_BGEZALL: gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2); - *is_branch = 1; break; case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ case OPC_TNEI: @@ -15243,7 +15220,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) #endif check_dsp(ctx); gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2); - *is_branch = 1; break; default: /* Invalid */ MIPS_INVAL("regimm"); @@ -15355,12 +15331,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_J ... OPC_JAL: /* Jump */ offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, op, 4, rs, rt, offset); - *is_branch = 1; break; case OPC_BEQ ... OPC_BGTZ: /* Branch */ case OPC_BEQL ... OPC_BGTZL: gen_compute_branch(ctx, op, 4, rs, rt, imm << 2); - *is_branch = 1; break; case OPC_LB ... OPC_LWR: /* Load and stores */ case OPC_LL: @@ -15420,7 +15394,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_BC1: gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), (rt >> 2) & 0x7, imm << 2); - *is_branch = 1; break; case OPC_S_FMT: case OPC_D_FMT: @@ -15527,7 +15500,6 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, op, 4, rs, rt, offset); - *is_branch = 1; break; case OPC_MDMX: check_insn(ctx, ASE_MDMX); @@ -15553,7 +15525,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, int num_insns; int max_insns; int insn_bytes; - int is_branch; + int is_delay; if (search_pc) qemu_log("search pc %d\n", search_pc); @@ -15611,23 +15583,23 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); - is_branch = 0; + is_delay = ctx.hflags & MIPS_HFLAG_BMASK; if (!(ctx.hflags & MIPS_HFLAG_M16)) { ctx.opcode = cpu_ldl_code(env, ctx.pc); insn_bytes = 4; - decode_opc(env, &ctx, &is_branch); + decode_opc(env, &ctx); } else if (ctx.insn_flags & ASE_MICROMIPS) { ctx.opcode = cpu_lduw_code(env, ctx.pc); - insn_bytes = decode_micromips_opc(env, &ctx, &is_branch); + insn_bytes = decode_micromips_opc(env, &ctx); } else if (ctx.insn_flags & ASE_MIPS16) { ctx.opcode = cpu_lduw_code(env, ctx.pc); - insn_bytes = decode_mips16_opc(env, &ctx, &is_branch); + insn_bytes = decode_mips16_opc(env, &ctx); } else { generate_exception(&ctx, EXCP_RI); ctx.bstate = BS_STOP; break; } - if (!is_branch) { + if (is_delay) { handle_delay_slot(&ctx, insn_bytes); } ctx.pc += insn_bytes; From cba5cb67becd66f8eae4177c4f95756f3f9bb77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 27 Jul 2013 22:19:54 +0200 Subject: [PATCH 14/27] mips_malta: QOM cast cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index dad58c0ed2..e932fdc77d 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -79,8 +79,12 @@ typedef struct { SerialState *uart; } MaltaFPGAState; +#define TYPE_MIPS_MALTA "mips-malta" +#define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA) + typedef struct { - SysBusDevice busdev; + SysBusDevice parent_obj; + qemu_irq *i8259; } MaltaState; @@ -808,8 +812,8 @@ void mips_malta_init(QEMUMachineInitArgs *args) int fl_sectors = bios_size >> 16; int be; - DeviceState *dev = qdev_create(NULL, "mips-malta"); - MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev); + DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA); + MaltaState *s = MIPS_MALTA(dev); qdev_init_nofail(dev); @@ -1004,7 +1008,7 @@ static void mips_malta_class_init(ObjectClass *klass, void *data) } static const TypeInfo mips_malta_device = { - .name = "mips-malta", + .name = TYPE_MIPS_MALTA, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MaltaState), .class_init = mips_malta_class_init, From a2b8813d62fa5a35adc1a7bf58de5b2ffb754f5d Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:43 +0100 Subject: [PATCH 15/27] mips_malta: fix BIOS endianness swapping If the target is little endian (mipsel) then the BIOS image endianness is swapped so that the big endian BIOS binaries commonly produced can be loaded correctly. When using the -bios argument the BIOS is loaded using load_image_targphys, however this doesn't perform the load to target memory immediately. Instead it loads the BIOS file into a struct Rom which will later be written to target memory upon reset. However the endianness conversion was being performed before this, on init, and operating on the target memory which at this point is blank & will later be overwritten by the (big endian) BIOS image. Correct this by operating on the data referenced by struct Rom rather than the target memory when the -bios argument is used. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index e932fdc77d..05d9bf512f 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -920,8 +920,11 @@ void mips_malta_init(QEMUMachineInitArgs *args) a neat trick which allows bi-endian firmware. */ #ifndef TARGET_WORDS_BIGENDIAN { - uint32_t *addr = memory_region_get_ram_ptr(bios); - uint32_t *end = addr + bios_size; + uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS); + if (!addr) { + addr = memory_region_get_ram_ptr(bios); + } + end = (void *)addr + bios_size; while (addr < end) { bswap32s(addr); addr++; From a427338b222b43197c2776cbc996936df0302f51 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:44 +0100 Subject: [PATCH 16/27] mips_malta: correct reading MIPS revision at 0x1fc00010 Rather than modifying the BIOS code at its original location, copy it for the 0x1fc00000 region & modify the copy. This means the original ROM code is correctly readable at 0x1e000010 whilst the MIPS revision is readable at 0x1fc00010. Additionally the code previously operated on target memory which would later be overwritten by the BIOS image upon CPU reset if the -bios argument was used to specify the BIOS image. This led to the written MIPS revision being lost. Copying using rom_copy when -bios is used fixes this issue. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 05d9bf512f..2edc8e16f5 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -793,7 +793,7 @@ void mips_malta_init(QEMUMachineInitArgs *args) pflash_t *fl; MemoryRegion *system_memory = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); - MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); + MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1); target_long bios_size = FLASH_SIZE; int64_t kernel_entry; PCIBus *pci_bus; @@ -933,14 +933,23 @@ void mips_malta_init(QEMUMachineInitArgs *args) #endif } - /* Map the BIOS at a 2nd physical location, as on the real board. */ - memory_region_init_alias(bios_alias, NULL, "bios.1fc", bios, 0, BIOS_SIZE); - memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias); + /* + * Map the BIOS at a 2nd physical location, as on the real board. + * Copy it so that we can patch in the MIPS revision, which cannot be + * handled by an overlapping region as the resulting ROM code subpage + * regions are not executable. + */ + memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE); + if (!rom_copy(memory_region_get_ram_ptr(bios_copy), + FLASH_ADDRESS, bios_size)) { + memcpy(memory_region_get_ram_ptr(bios_copy), + memory_region_get_ram_ptr(bios), bios_size); + } + memory_region_set_readonly(bios_copy, true); + memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy); - /* Board ID = 0x420 (Malta Board with CoreLV) - XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should - map to the board ID. */ - stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420); + /* Board ID = 0x420 (Malta Board with CoreLV) */ + stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420); /* Init internal devices */ cpu_mips_irq_init_cpu(env); From 02bccc7796fec8b39dca9affc8bff8edebe0a867 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:45 +0100 Subject: [PATCH 17/27] mips_malta: generate SPD EEPROM data at runtime The SPD EEPROM specifies the amount of memory present in the system and thus its correct contents can only be known at runtime. Calculating parts of the data on init allows the data to accurately reflect the amount of target memory present and allow YAMON to boot with an arbitrary amount of SDRAM. Where possible the SPD data will favor indicating 2 banks of SDRAM rather than 1. For example the default 128MB of target memory will be represented as 2x64MB banks rather than 1x128MB bank. This allows versions of MIPS BIOS code (such as YAMON 2.22 and older) to boot despite a bug preventing them from handling a single bank of SDRAM with the Galileo GT64120 system controller emulated by QEMU. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 60 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2edc8e16f5..e06e19d2df 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -47,6 +47,7 @@ #include "sysemu/blockdev.h" #include "exec/address-spaces.h" #include "hw/sysbus.h" /* SysBusDevice */ +#include "qemu/host-utils.h" //#define DEBUG_BOARD_INIT @@ -150,10 +151,10 @@ typedef struct _eeprom24c0x_t eeprom24c0x_t; static eeprom24c0x_t eeprom = { .contents = { - /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00, + /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00, /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01, - /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00, - /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40, + /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00, + /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF, /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00, /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -169,6 +170,56 @@ static eeprom24c0x_t eeprom = { }, }; +static void eeprom_generate(eeprom24c0x_t *eeprom, ram_addr_t ram_size) +{ + enum { SDR = 0x4, DDR2 = 0x8 } type; + uint8_t *spd = eeprom->contents; + uint8_t nbanks = 0; + uint16_t density = 0; + int i; + + /* work in terms of MB */ + ram_size >>= 20; + + while ((ram_size >= 4) && (nbanks <= 2)) { + int sz_log2 = MIN(31 - clz32(ram_size), 14); + nbanks++; + density |= 1 << (sz_log2 - 2); + ram_size -= 1 << sz_log2; + } + + /* split to 2 banks if possible */ + if ((nbanks == 1) && (density > 1)) { + nbanks++; + density >>= 1; + } + + if (density & 0xff00) { + density = (density & 0xe0) | ((density >> 8) & 0x1f); + type = DDR2; + } else if (!(density & 0x1f)) { + type = DDR2; + } else { + type = SDR; + } + + if (ram_size) { + fprintf(stderr, "Warning: SPD cannot represent final %dMB" + " of SDRAM\n", (int)ram_size); + } + + /* fill in SPD memory information */ + spd[2] = type; + spd[5] = nbanks; + spd[31] = density; + + /* checksum */ + spd[63] = 0; + for (i = 0; i < 63; i++) { + spd[63] += spd[i]; + } +} + static uint8_t eeprom24c0x_read(void) { logout("%u: scl = %u, sda = %u, data = 0x%02x\n", @@ -862,6 +913,9 @@ void mips_malta_init(QEMUMachineInitArgs *args) vmstate_register_ram_global(ram); memory_region_add_subregion(system_memory, 0, ram); + /* generate SPD EEPROM data */ + eeprom_generate(&eeprom, ram_size); + #ifdef TARGET_WORDS_BIGENDIAN be = 1; #else From 1817f56a834f55311af20d1c004b259c16fb1515 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:46 +0100 Subject: [PATCH 18/27] mips_malta: cap BIOS endian swap length at 0x3e0000 bytes This preserves the final sector of the pflash which is used by YAMON to hold environment variables. If the endianness of the environment data is swapped then YAMON will fail to load environment variables from pflash. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index e06e19d2df..a740f614f7 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -978,7 +978,7 @@ void mips_malta_init(QEMUMachineInitArgs *args) if (!addr) { addr = memory_region_get_ram_ptr(bios); } - end = (void *)addr + bios_size; + end = (void *)addr + MIN(bios_size, 0x3e0000); while (addr < end) { bswap32s(addr); addr++; From 35c648078aa493c3b976840eb7cf2e53ab5b7a2d Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:47 +0100 Subject: [PATCH 19/27] mips_malta: generate SMBUS EEPROM data The malta contains 2 EEPROMs, one containing SPD data for the SDRAM and another containing board information such as serial number and MAC address. These are both exposed via the PIIX4 SMBUS. Generating this data and providing it to smbus_eeprom_init will allow YAMON to read a serial number for the board and prevent it from warning that the EEPROM data is invalid. We already have the contents of the SPD EEPROM which are exposed via FPGA I2C accesses, this is provided as part of the SMBUS EEPROM data too for consistency. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 133 ++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 46 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index a740f614f7..28c351d83d 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -149,7 +149,7 @@ struct _eeprom24c0x_t { typedef struct _eeprom24c0x_t eeprom24c0x_t; -static eeprom24c0x_t eeprom = { +static eeprom24c0x_t spd_eeprom = { .contents = { /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00, /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01, @@ -170,10 +170,10 @@ static eeprom24c0x_t eeprom = { }, }; -static void eeprom_generate(eeprom24c0x_t *eeprom, ram_addr_t ram_size) +static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size) { enum { SDR = 0x4, DDR2 = 0x8 } type; - uint8_t *spd = eeprom->contents; + uint8_t *spd = spd_eeprom.contents; uint8_t nbanks = 0; uint16_t density = 0; int i; @@ -218,71 +218,109 @@ static void eeprom_generate(eeprom24c0x_t *eeprom, ram_addr_t ram_size) for (i = 0; i < 63; i++) { spd[63] += spd[i]; } + + /* copy for SMBUS */ + memcpy(eeprom, spd, sizeof(spd_eeprom.contents)); } -static uint8_t eeprom24c0x_read(void) +static void generate_eeprom_serial(uint8_t *eeprom) +{ + int i, pos = 0; + uint8_t mac[6] = { 0x00 }; + uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 }; + + /* version */ + eeprom[pos++] = 0x01; + + /* count */ + eeprom[pos++] = 0x02; + + /* MAC address */ + eeprom[pos++] = 0x01; /* MAC */ + eeprom[pos++] = 0x06; /* length */ + memcpy(&eeprom[pos], mac, sizeof(mac)); + pos += sizeof(mac); + + /* serial number */ + eeprom[pos++] = 0x02; /* serial */ + eeprom[pos++] = 0x05; /* length */ + memcpy(&eeprom[pos], sn, sizeof(sn)); + pos += sizeof(sn); + + /* checksum */ + eeprom[pos] = 0; + for (i = 0; i < pos; i++) { + eeprom[pos] += eeprom[i]; + } +} + +static uint8_t eeprom24c0x_read(eeprom24c0x_t *eeprom) { logout("%u: scl = %u, sda = %u, data = 0x%02x\n", - eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data); - return eeprom.sda; + eeprom->tick, eeprom->scl, eeprom->sda, eeprom->data); + return eeprom->sda; } -static void eeprom24c0x_write(int scl, int sda) +static void eeprom24c0x_write(eeprom24c0x_t *eeprom, int scl, int sda) { - if (eeprom.scl && scl && (eeprom.sda != sda)) { + if (eeprom->scl && scl && (eeprom->sda != sda)) { logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n", - eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start"); + eeprom->tick, eeprom->scl, scl, eeprom->sda, sda, + sda ? "stop" : "start"); if (!sda) { - eeprom.tick = 1; - eeprom.command = 0; + eeprom->tick = 1; + eeprom->command = 0; } - } else if (eeprom.tick == 0 && !eeprom.ack) { + } else if (eeprom->tick == 0 && !eeprom->ack) { /* Waiting for start. */ logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n", - eeprom.tick, eeprom.scl, scl, eeprom.sda, sda); - } else if (!eeprom.scl && scl) { + eeprom->tick, eeprom->scl, scl, eeprom->sda, sda); + } else if (!eeprom->scl && scl) { logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n", - eeprom.tick, eeprom.scl, scl, eeprom.sda, sda); - if (eeprom.ack) { + eeprom->tick, eeprom->scl, scl, eeprom->sda, sda); + if (eeprom->ack) { logout("\ti2c ack bit = 0\n"); sda = 0; - eeprom.ack = 0; - } else if (eeprom.sda == sda) { + eeprom->ack = 0; + } else if (eeprom->sda == sda) { uint8_t bit = (sda != 0); logout("\ti2c bit = %d\n", bit); - if (eeprom.tick < 9) { - eeprom.command <<= 1; - eeprom.command += bit; - eeprom.tick++; - if (eeprom.tick == 9) { - logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write"); - eeprom.ack = 1; + if (eeprom->tick < 9) { + eeprom->command <<= 1; + eeprom->command += bit; + eeprom->tick++; + if (eeprom->tick == 9) { + logout("\tcommand 0x%04x, %s\n", eeprom->command, + bit ? "read" : "write"); + eeprom->ack = 1; } - } else if (eeprom.tick < 17) { - if (eeprom.command & 1) { - sda = ((eeprom.data & 0x80) != 0); + } else if (eeprom->tick < 17) { + if (eeprom->command & 1) { + sda = ((eeprom->data & 0x80) != 0); } - eeprom.address <<= 1; - eeprom.address += bit; - eeprom.tick++; - eeprom.data <<= 1; - if (eeprom.tick == 17) { - eeprom.data = eeprom.contents[eeprom.address]; - logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data); - eeprom.ack = 1; - eeprom.tick = 0; + eeprom->address <<= 1; + eeprom->address += bit; + eeprom->tick++; + eeprom->data <<= 1; + if (eeprom->tick == 17) { + eeprom->data = eeprom->contents[eeprom->address]; + logout("\taddress 0x%04x, data 0x%02x\n", + eeprom->address, eeprom->data); + eeprom->ack = 1; + eeprom->tick = 0; } - } else if (eeprom.tick >= 17) { + } else if (eeprom->tick >= 17) { sda = 0; } } else { logout("\tsda changed with raising scl\n"); } } else { - logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda); + logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom->tick, eeprom->scl, + scl, eeprom->sda, sda); } - eeprom.scl = scl; - eeprom.sda = sda; + eeprom->scl = scl; + eeprom->sda = sda; } static uint64_t malta_fpga_read(void *opaque, hwaddr addr, @@ -345,7 +383,7 @@ static uint64_t malta_fpga_read(void *opaque, hwaddr addr, /* I2CINP Register */ case 0x00b00: - val = ((s->i2cin & ~1) | eeprom24c0x_read()); + val = ((s->i2cin & ~1) | eeprom24c0x_read(&spd_eeprom)); break; /* I2COE Register */ @@ -441,7 +479,7 @@ static void malta_fpga_write(void *opaque, hwaddr addr, /* I2COUT Register */ case 0x00b10: - eeprom24c0x_write(val & 0x02, val & 0x01); + eeprom24c0x_write(&spd_eeprom, val & 0x02, val & 0x01); s->i2cout = val; break; @@ -846,6 +884,8 @@ void mips_malta_init(QEMUMachineInitArgs *args) MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1); target_long bios_size = FLASH_SIZE; + const size_t smbus_eeprom_size = 8 * 256; + uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size); int64_t kernel_entry; PCIBus *pci_bus; ISABus *isa_bus; @@ -914,7 +954,8 @@ void mips_malta_init(QEMUMachineInitArgs *args) memory_region_add_subregion(system_memory, 0, ram); /* generate SPD EEPROM data */ - eeprom_generate(&eeprom, ram_size); + generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size); + generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]); #ifdef TARGET_WORDS_BIGENDIAN be = 1; @@ -1035,8 +1076,8 @@ void mips_malta_init(QEMUMachineInitArgs *args) pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci"); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(NULL, 9), NULL, 0, NULL); - /* TODO: Populate SPD eeprom data. */ - smbus_eeprom_init(smbus, 8, NULL, 0); + smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size); + g_free(smbus_eeprom_buf); pit = pit_init(isa_bus, 0x40, 0, NULL); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); From ea0a4f34418c9f2cad9722bb27acd6349148fac0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Jun 2013 08:30:48 +0100 Subject: [PATCH 20/27] pflash_cfi01: duplicate status byte from bits 23:16 for 32bit reads The firmware commonly used with MIPS Malta boards (YAMON) reads the status of the pflash with a 32bit memory access. On real hardware this results in the status byte being mirrored in the upper 16 bits of the read value. For example if the status byte is represented by SS then the hardware reads 0x00SS00SS. The YAMON firmware compares the status against 32bit values expecting the mirrored value and fails without it. Signed-off-by: Paul Burton Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/block/pflash_cfi01.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 2bcd7318bc..29738598ac 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -192,6 +192,9 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset, case 0xe8: /* Write block */ /* Status register read */ ret = pfl->status; + if (width > 2) { + ret |= pfl->status << 16; + } DPRINTF("%s: status %x\n", __func__, ret); break; case 0x90: From 05b3274b6bedb68ff78b76c642e17e97f3181c2f Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 27 Jun 2013 08:35:27 +0100 Subject: [PATCH 21/27] hw/mips: align initrd to 64KB to avoid kernel error The Linux kernel can be configured to use 64KB pages, but it also requires initrd to be page aligned. Therefore, to be safe, align the initrd to 64KB using a new INITRD_PAGE_MASK rather than TARGET_PAGE_MASK. Signed-off-by: James Hogan Signed-off-by: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_fulong2e.c | 2 +- hw/mips/mips_malta.c | 2 +- hw/mips/mips_mipssim.c | 2 +- hw/mips/mips_r4k.c | 2 +- include/hw/mips/mips.h | 3 +++ 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index a7e9dcf4bf..99014415ca 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -126,7 +126,7 @@ static int64_t load_kernel (CPUMIPSState *env) if (loaderparams.initrd_filename) { initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { - initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; + initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 28c351d83d..2dc66f7748 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -792,7 +792,7 @@ static int64_t load_kernel (void) if (loaderparams.initrd_filename) { initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { - initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; + initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c index e8802c128e..fea1a15916 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mips_mipssim.c @@ -83,7 +83,7 @@ static int64_t load_kernel(void) if (loaderparams.initrd_filename) { initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { - initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; + initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; if (initrd_offset + initrd_size > loaderparams.ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 4bc2e3fa7a..7af08b8d0f 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -102,7 +102,7 @@ static int64_t load_kernel(void) if (loaderparams.initrd_filename) { initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { - initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; + initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h index 291e85f6b9..2a7a9c9f42 100644 --- a/include/hw/mips/mips.h +++ b/include/hw/mips/mips.h @@ -2,6 +2,9 @@ #define HW_MIPS_H /* Definitions for mips board emulation. */ +/* Kernels can be configured with 64KB pages */ +#define INITRD_PAGE_MASK (~((1 << 16) - 1)) + #include "exec/memory.h" /* gt64xxx.c */ From d36c231f4b7386bd8230aa17d362b925aa419b2f Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Mon, 1 Jul 2013 01:54:47 +0200 Subject: [PATCH 22/27] target-mips: fix mipsdsp_trunc16_sat16_round This change corrects rounding and saturation of Q31 fractional value in mipsdsp_trunc16_sat16_round(). Overflow detection was incorrect for the corner case for PRECRQ_RS.PH, and this test case is also part of the change. Signed-off-by: Petar Jovanovic Signed-off-by: Aurelien Jarno --- target-mips/dsp_helper.c | 16 ++++++++++----- tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c | 24 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index c718a786e1..93f5d9e023 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -648,16 +648,22 @@ static inline int32_t mipsdsp_sat16_mul_q15_q15(uint16_t a, uint16_t b, static inline uint16_t mipsdsp_trunc16_sat16_round(int32_t a, CPUMIPSState *env) { - int64_t temp; + uint16_t temp; - temp = (int32_t)a + 0x00008000; - if (a > (int)0x7fff8000) { - temp = 0x7FFFFFFF; + /* + * The value 0x00008000 will be added to the input Q31 value, and the code + * needs to check if the addition causes an overflow. Since a positive value + * is added, overflow can happen in one direction only. + */ + if (a > 0x7FFF7FFF) { + temp = 0x7FFF; set_DSPControl_overflow_flag(1, 22, env); + } else { + temp = ((a + 0x8000) >> 16) & 0xFFFF; } - return (temp >> 16) & 0xFFFF; + return temp; } static inline uint8_t mipsdsp_sat8_reduce_precision(uint16_t a, diff --git a/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c b/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c index 3535b37a58..da6845bf24 100644 --- a/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c +++ b/tests/tcg/mips/mips32-dsp/precrq_rs_ph_w.c @@ -12,18 +12,34 @@ int main() result = 0x12348765; __asm - ("precrq_rs.ph.w %0, %1, %2\n\t" + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %1, %2\n\t" : "=r"(rd) : "r"(rs), "r"(rt) ); assert(result == rd); - rs = 0x7fffC678; + rs = 0x7FFFC678; rt = 0x865432A0; - result = 0x7fff8654; + result = 0x7FFF8654; __asm - ("precrq_rs.ph.w %0, %2, %3\n\t" + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %2, %3\n\t" + "rddsp %1\n\t" + : "=r"(rd), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + assert(((dsp >> 22) & 0x01) == 1); + assert(result == rd); + + rs = 0xBEEFFEED; + rt = 0x7FFF8000; + result = 0xBEF07FFF; + + __asm + ("wrdsp $0\n\t" + "precrq_rs.ph.w %0, %2, %3\n\t" "rddsp %1\n\t" : "=r"(rd), "=r"(dsp) : "r"(rs), "r"(rt) From d2e46d59cac7d8259bf80abcddfebde87014d610 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 25 Jul 2013 22:10:31 +0200 Subject: [PATCH 23/27] target-mips: Remove assignment to a variable which is never used This assignment causes a compiler warning for compilations with the compiler option -Wunused-but-set-variable (which is included with -Wextra). Removing it allows using -Wextra for QEMU code without suppressing too many extra warnings. Signed-off-by: Stefan Weil Signed-off-by: Aurelien Jarno --- target-mips/op_helper.c | 1 - 1 file changed, 1 deletion(-) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 5cf1c3f04b..b828375714 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1735,7 +1735,6 @@ target_ulong helper_evpe(CPUMIPSState *env) void helper_fork(target_ulong arg1, target_ulong arg2) { // arg1 = rt, arg2 = rs - arg1 = 0; // TODO: store to TC register } From b0932e0617c65ae1cb0362416ec0ef32766abf5d Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Tue, 23 Jul 2013 19:00:10 +0200 Subject: [PATCH 24/27] linux-user: correct argument number for sys_mremap and sys_splice sys_mremap missed 5th argument (new_address), which caused examples that remap to a specific address to fail. sys_splice missed 5th and 6th argument which caused different examples to fail. This change has an effect on MIPS target only. Signed-off-by: Petar Jovanovic Signed-off-by: Aurelien Jarno --- linux-user/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 5309117034..03859bcc23 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1920,7 +1920,7 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_sched_get_priority_min, 1) MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */ MIPS_SYS(sys_nanosleep, 2) - MIPS_SYS(sys_mremap , 4) + MIPS_SYS(sys_mremap , 5) MIPS_SYS(sys_accept , 3) MIPS_SYS(sys_bind , 3) MIPS_SYS(sys_connect , 3) /* 4170 */ @@ -2057,7 +2057,7 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_pselect6, 6) MIPS_SYS(sys_ppoll, 5) MIPS_SYS(sys_unshare, 1) - MIPS_SYS(sys_splice, 4) + MIPS_SYS(sys_splice, 6) MIPS_SYS(sys_sync_file_range, 7) /* 4305 */ MIPS_SYS(sys_tee, 4) MIPS_SYS(sys_vmsplice, 4) From f05d4d94d6bb0e240e6cfda65972fd86601f9f0d Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 29 Jul 2013 07:00:29 +0200 Subject: [PATCH 25/27] mips_malta: fix copy of the 0x1fc00000 region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy the whole 0x1fe000000 region into 0x1fc00000, independently of the loaded BIOS size. This fix the MIPS make check tests. Reported-by: Andreas Färber Tested-by: Andreas Färber Cc: Paul Burton Cc: Leon Alrae Signed-off-by: Aurelien Jarno --- hw/mips/mips_malta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2dc66f7748..1589b59194 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1036,9 +1036,9 @@ void mips_malta_init(QEMUMachineInitArgs *args) */ memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE); if (!rom_copy(memory_region_get_ram_ptr(bios_copy), - FLASH_ADDRESS, bios_size)) { + FLASH_ADDRESS, BIOS_SIZE)) { memcpy(memory_region_get_ram_ptr(bios_copy), - memory_region_get_ram_ptr(bios), bios_size); + memory_region_get_ram_ptr(bios), BIOS_SIZE); } memory_region_set_readonly(bios_copy, true); memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy); From b6a9f4682e62c686995cc1a1fe2ef4a57a92020b Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Mon, 29 Jul 2013 04:06:12 +0200 Subject: [PATCH 26/27] target-mips: fix mipsdsp_mul_q31_q31 Multiplication of two fractional word elements is not correct when sign extension/promotion is needed. This change fixes it by adding correct casts from unsigned to signed values. In addition, the tests (dpaq_sa_l_w.c and dpsq_sa_l_w.c) have been extended to trigger the current issue. Signed-off-by: Petar Jovanovic Signed-off-by: Aurelien Jarno --- target-mips/dsp_helper.c | 2 +- tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c | 64 +++++++++++++++++++++---- tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c | 4 +- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index 93f5d9e023..b088a25017 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -583,7 +583,7 @@ static inline int64_t mipsdsp_mul_q31_q31(int32_t ac, uint32_t a, uint32_t b, temp = (0x01ull << 63) - 1; set_DSPControl_overflow_flag(1, 16 + ac, env); } else { - temp = ((uint64_t)a * (uint64_t)b) << 1; + temp = ((int64_t)(int32_t)a * (int32_t)b) << 1; } return temp; diff --git a/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c index ce864844d9..cbf900713f 100644 --- a/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c +++ b/tests/tcg/mips/mips32-dsp/dpaq_sa_l_w.c @@ -14,7 +14,7 @@ int main() resultdsp = 0x01; __asm ("mthi %0, $ac1\n\t" - "mtlo %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" "dpaq_sa.l.w $ac1, %3, %4\n\t" "mfhi %0, $ac1\n\t" "mflo %1, $ac1\n\t" @@ -27,8 +27,8 @@ int main() assert(ach == resulth); assert(acl == resultl); - ach = 0x12; - acl = 0x48; + ach = 0x00000012; + acl = 0x00000048; rs = 0x80000000; rt = 0x80000000; @@ -37,7 +37,7 @@ int main() resultdsp = 0x01; __asm ("mthi %0, $ac1\n\t" - "mtlo %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" "dpaq_sa.l.w $ac1, %3, %4\n\t" "mfhi %0, $ac1\n\t" "mflo %1, $ac1\n\t" @@ -51,16 +51,64 @@ int main() assert(acl == resultl); ach = 0x741532A0; - acl = 0xfceabb08; + acl = 0xFCEABB08; rs = 0x80000000; rt = 0x80000000; - resulth = 0x7fffffff; - resultl = 0xffffffff; + resulth = 0x7FFFFFFF; + resultl = 0xFFFFFFFF; resultdsp = 0x01; __asm ("mthi %0, $ac1\n\t" - "mtlo %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0; + acl = 0; + rs = 0xC0000000; + rt = 0x7FFFFFFF; + + resulth = 0xC0000000; + resultl = 0x80000000; + resultdsp = 0; + __asm + ("wrdsp $0\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" + "dpaq_sa.l.w $ac1, %3, %4\n\t" + "mfhi %0, $ac1\n\t" + "mflo %1, $ac1\n\t" + "rddsp %2\n\t" + : "+r"(ach), "+r"(acl), "=r"(dsp) + : "r"(rs), "r"(rt) + ); + dsp = (dsp >> 17) & 0x01; + assert(dsp == resultdsp); + assert(ach == resulth); + assert(acl == resultl); + + ach = 0x20000000; + acl = 0; + rs = 0xE0000000; + rt = 0x7FFFFFFF; + + resulth = 0; + resultl = 0x40000000; + resultdsp = 0; + __asm + ("wrdsp $0\n\t" + "mthi %0, $ac1\n\t" + "mtlo %1, $ac1\n\t" "dpaq_sa.l.w $ac1, %3, %4\n\t" "mfhi %0, $ac1\n\t" "mflo %1, $ac1\n\t" diff --git a/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c index b7b73fdb66..eda3b14e2b 100644 --- a/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c +++ b/tests/tcg/mips/mips32-dsp/dpsq_sa_l_w.c @@ -9,8 +9,8 @@ int main() rs = 0xBC0123AD; rt = 0x01643721; - resulth = 0xfdf4cbe0; - resultl = 0xd138776b; + resulth = 0x00BD3A22; + resultl = 0xD138776B; resultdsp = 0x00; __asm ("mthi %0, $ac1\n\t" From f53ec6999287bfdc4f0dfdb6427baa1853f8952a Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Mon, 15 Jul 2013 23:49:57 +0200 Subject: [PATCH 27/27] w32, w64: Add build rule for installer The new rules in Makefile allow building installers for QEMU on Windows using NSIS, a package which is also available for Linux distributions (so cross builds are possible). The rules for NSIS are in qemu.nsi which also uses two new images. Signed-off-by: Stefan Weil --- Makefile | 55 ++++++++++ pc-bios/qemu-nsis.bmp | Bin 0 -> 154542 bytes pc-bios/qemu-nsis.ico | Bin 0 -> 4846 bytes qemu.nsi | 250 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 pc-bios/qemu-nsis.bmp create mode 100644 pc-bios/qemu-nsis.ico create mode 100644 qemu.nsi diff --git a/Makefile b/Makefile index c06bfaba20..29f10436f8 100644 --- a/Makefile +++ b/Makefile @@ -437,6 +437,61 @@ qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \ qemu-img.texi qemu-nbd.texi qemu-options.texi \ qemu-monitor.texi qemu-img-cmds.texi +ifdef CONFIG_WIN32 + +INSTALLER = qemu-setup-$(VERSION)$(EXESUF) + +nsisflags = -V2 -NOCD + +ifneq ($(wildcard $(SRC_PATH)/dll),) +ifeq ($(ARCH),x86_64) +# 64 bit executables +DLL_PATH = $(SRC_PATH)/dll/w64 +nsisflags += -DW64 +else +# 32 bit executables +DLL_PATH = $(SRC_PATH)/dll/w32 +endif +endif + +.PHONY: installer +installer: $(INSTALLER) + +INSTDIR=/tmp/qemu-nsis + +$(INSTALLER): $(SRC_PATH)/qemu.nsi + make install prefix=${INSTDIR} +ifdef SIGNCODE + (cd ${INSTDIR}; \ + for i in *.exe; do \ + $(SIGNCODE) $${i}; \ + done \ + ) +endif # SIGNCODE + (cd ${INSTDIR}; \ + for i in qemu-system-*.exe; do \ + arch=$${i%.exe}; \ + arch=$${arch#qemu-system-}; \ + echo Section \"$$arch\" Section_$$arch; \ + echo SetOutPath \"\$$INSTDIR\"; \ + echo File \"\$${BINDIR}\\$$i\"; \ + echo SectionEnd; \ + done \ + ) >${INSTDIR}/system-emulations.nsh + makensis $(nsisflags) \ + $(if $(BUILD_DOCS),-DCONFIG_DOCUMENTATION="y") \ + $(if $(CONFIG_GTK),-DCONFIG_GTK="y") \ + -DBINDIR="${INSTDIR}" \ + $(if $(DLL_PATH),-DDLLDIR="$(DLL_PATH)") \ + -DSRCDIR="$(SRC_PATH)" \ + -DOUTFILE="$(INSTALLER)" \ + $(SRC_PATH)/qemu.nsi + rm -r ${INSTDIR} +ifdef SIGNCODE + $(SIGNCODE) $(INSTALLER) +endif # SIGNCODE +endif # CONFIG_WIN + # Add a dependency on the generated files, so that they are always # rebuilt before other object files ifneq ($(filter-out %clean,$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail)) diff --git a/pc-bios/qemu-nsis.bmp b/pc-bios/qemu-nsis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ae82cd2697ab688137c1758c724c2e2597cf8121 GIT binary patch literal 154542 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 literal 0 HcmV?d00001 diff --git a/pc-bios/qemu-nsis.ico b/pc-bios/qemu-nsis.ico new file mode 100644 index 0000000000000000000000000000000000000000..1d0128cd4c37f9c845f19c499febd61f85af5961 GIT binary patch literal 4846 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 X6&Oj5#*Cyur7}_?l4W8%9QXeKCmz*e literal 0 HcmV?d00001 diff --git a/qemu.nsi b/qemu.nsi new file mode 100644 index 0000000000..1d57455956 --- /dev/null +++ b/qemu.nsi @@ -0,0 +1,250 @@ +;!/usr/bin/makensis + +; This NSIS script creates an installer for QEMU on Windows. + +; Copyright (C) 2006-2012 Stefan Weil +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 2 of the License, or +; (at your option) version 3 or any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . + +; NSIS_WIN32_MAKENSIS + +!define PRODUCT "QEMU" +!define URL "http://www.qemu.org/" + +!define UNINST_EXE "$INSTDIR\qemu-uninstall.exe" +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" + +!ifndef BINDIR +!define BINDIR nsis.tmp +!endif +!ifndef SRCDIR +!define SRCDIR . +!endif +!ifndef OUTFILE +!define OUTFILE "qemu-setup.exe" +!endif + +; Optionally install documentation. +!ifndef CONFIG_DOCUMENTATION +!define CONFIG_DOCUMENTATION +!endif + +; Use maximum compression. +SetCompressor /SOLID lzma + +!include "MUI2.nsh" + +; The name of the installer. +Name "QEMU" + +; The file to write +OutFile "${OUTFILE}" + +; The default installation directory. +!ifdef W64 +InstallDir $PROGRAMFILES64\qemu +!else +InstallDir $PROGRAMFILES\qemu +!endif + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\qemu" "Install_Dir" + +; Request administrator privileges for Windows Vista. +RequestExecutionLevel admin + +;-------------------------------- +; Interface Settings. +;!define MUI_HEADERIMAGE "qemu-nsis.bmp" +; !define MUI_SPECIALBITMAP "qemu.bmp" +!define MUI_ICON "${SRCDIR}\pc-bios\qemu-nsis.ico" +!define MUI_UNICON "${SRCDIR}\pc-bios\qemu-nsis.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "${SRCDIR}\pc-bios\qemu-nsis.bmp" +; !define MUI_HEADERIMAGE_BITMAP "qemu-install.bmp" +; !define MUI_HEADERIMAGE_UNBITMAP "qemu-uninstall.bmp" +; !define MUI_COMPONENTSPAGE_SMALLDESC +; !define MUI_WELCOMEPAGE_TEXT "Insert text here.$\r$\n$\r$\n$\r$\n$_CLICK" + +;-------------------------------- +; Pages. + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "${SRCDIR}\COPYING" +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!define MUI_FINISHPAGE_LINK "Visit the QEMU Wiki online!" +!define MUI_FINISHPAGE_LINK_LOCATION "${URL}" +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +; Languages. + +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "German" + +;-------------------------------- + +; The stuff to install. +Section "${PRODUCT} (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath "$INSTDIR" + + File "${SRCDIR}\Changelog" + File "${SRCDIR}\COPYING" + File "${SRCDIR}\COPYING.LIB" + File "${SRCDIR}\README" + File "${SRCDIR}\VERSION" + + File "${BINDIR}\*.bmp" + File "${BINDIR}\*.bin" + File "${BINDIR}\*.dtb" + File "${BINDIR}\*.rom" + File "${BINDIR}\openbios-*" + + File /r "${BINDIR}\keymaps" +!ifdef CONFIG_GTK + File /r "${BINDIR}\share" +!endif + +!ifdef W64 + SetRegView 64 +!endif + + ; Write the installation path into the registry + WriteRegStr HKLM SOFTWARE\${PRODUCT} "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "QEMU" + WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"${UNINST_EXE}"' + WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 1 + WriteUninstaller "qemu-uninstall.exe" +SectionEnd + +Section "Tools" SectionTools + SetOutPath "$INSTDIR" + File "${BINDIR}\qemu-img.exe" + File "${BINDIR}\qemu-io.exe" +SectionEnd + +SectionGroup "System Emulations" SectionSystem + +!include "${BINDIR}\system-emulations.nsh" + +SectionGroupEnd + +!ifdef DLLDIR +Section "Libraries (DLL)" SectionDll + SetOutPath "$INSTDIR" + File "${DLLDIR}\*.dll" +SectionEnd +!endif + +!ifdef CONFIG_DOCUMENTATION +Section "Documentation" SectionDoc + SetOutPath "$INSTDIR" + File "${BINDIR}\qemu-doc.html" + File "${BINDIR}\qemu-tech.html" + CreateDirectory "$SMPROGRAMS\${PRODUCT}" + CreateShortCut "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" "$INSTDIR\qemu-doc.html" "" "$INSTDIR\qemu-doc.html" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT}\Technical Documentation.lnk" "$INSTDIR\qemu-tech.html" "" "$INSTDIR\qemu-tech.html" 0 +SectionEnd +!endif + +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" SectionMenu + CreateDirectory "$SMPROGRAMS\${PRODUCT}" + CreateShortCut "$SMPROGRAMS\${PRODUCT}\Uninstall.lnk" "${UNINST_EXE}" "" "${UNINST_EXE}" 0 +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + ; Remove registry keys +!ifdef W64 + SetRegView 64 +!endif + DeleteRegKey HKLM "${UNINST_KEY}" + DeleteRegKey HKLM SOFTWARE\${PRODUCT} + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" + Delete "$SMPROGRAMS\${PRODUCT}\Technical Documentation.lnk" + Delete "$SMPROGRAMS\${PRODUCT}\Uninstall.lnk" + RMDir "$SMPROGRAMS\${PRODUCT}" + + ; Remove files and directories used + Delete "$INSTDIR\Changelog" + Delete "$INSTDIR\COPYING" + Delete "$INSTDIR\COPYING.LIB" + Delete "$INSTDIR\README" + Delete "$INSTDIR\VERSION" + Delete "$INSTDIR\*.bmp" + Delete "$INSTDIR\*.bin" + Delete "$INSTDIR\*.dll" + Delete "$INSTDIR\*.dtb" + Delete "$INSTDIR\*.rom" + Delete "$INSTDIR\openbios-*" + Delete "$INSTDIR\qemu-img.exe" + Delete "$INSTDIR\qemu-io.exe" + Delete "$INSTDIR\qemu.exe" + Delete "$INSTDIR\qemu-system-*.exe" + Delete "$INSTDIR\qemu-doc.html" + Delete "$INSTDIR\qemu-tech.html" + RMDir /r "$INSTDIR\keymaps" + RMDir /r "$INSTDIR\share" + ; Remove generated files + Delete "$INSTDIR\stderr.txt" + Delete "$INSTDIR\stdout.txt" + ; Remove uninstaller + Delete "${UNINST_EXE}" + RMDir "$INSTDIR" +SectionEnd + +;-------------------------------- + +; Descriptions (mouse-over). +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SectionSystem} "System emulation." + !insertmacro MUI_DESCRIPTION_TEXT ${Section_alpha} "Alpha system emulation." + !insertmacro MUI_DESCRIPTION_TEXT ${Section_alphaw} "Alpha system emulation (GUI)." + !insertmacro MUI_DESCRIPTION_TEXT ${Section_i386} "PC i386 system emulation." + !insertmacro MUI_DESCRIPTION_TEXT ${Section_i386w} "PC i386 system emulation (GUI)." + !insertmacro MUI_DESCRIPTION_TEXT ${SectionTools} "Tools." +!ifdef DLLDIR + !insertmacro MUI_DESCRIPTION_TEXT ${SectionDll} "Runtime Libraries (DLL)." +!endif +!ifdef CONFIG_DOCUMENTATION + !insertmacro MUI_DESCRIPTION_TEXT ${SectionDoc} "Documentation." +!endif + !insertmacro MUI_DESCRIPTION_TEXT ${SectionMenu} "Menu entries." +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +;-------------------------------- +; Functions. + +Function .onInit + !insertmacro MUI_LANGDLL_DISPLAY +FunctionEnd