diff options
97 files changed, 837 insertions, 515 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 743a92666a..ef6c01084b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1274,6 +1274,7 @@ Machine core M: Eduardo Habkost <ehabkost@redhat.com> M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> S: Supported +F: hw/core/cpu.c F: hw/core/machine-qmp-cmds.c F: hw/core/machine.c F: hw/core/null-machine.c @@ -1281,10 +1282,9 @@ F: hw/core/numa.c F: hw/cpu/cluster.c F: qapi/machine.json F: qapi/machine-target.json -F: qom/cpu.c F: include/hw/boards.h +F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h -F: include/qom/cpu.h F: include/sysemu/numa.h T: git https://github.com/ehabkost/qemu.git machine-next @@ -2048,12 +2048,10 @@ F: hw/core/qdev* F: include/hw/qdev* F: include/monitor/qdev.h F: include/qom/ -X: include/qom/cpu.h F: qapi/qom.json F: qapi/qdev.json F: qdev-monitor.c F: qom/ -X: qom/cpu.c F: tests/check-qom-interface.c F: tests/check-qom-proplist.c F: tests/test-qdev-global-props.c @@ -84,8 +84,7 @@ endif include $(SRC_PATH)/rules.mak -# notempy and lor are defined in rules.mak -CONFIG_TOOLS := $(call notempty,$(TOOLS)) +# lor is defined in rules.mak CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS)) # Create QEMU_PKGVERSION and FULL_VERSION strings @@ -681,7 +680,7 @@ clean: recurse-clean ! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \ -exec rm {} + rm -f $(edk2-decompressed) - rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga$(EXESUF) TAGS cscope.* *.pod *~ */*~ + rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) TAGS cscope.* *.pod *~ */*~ rm -f fsdev/*.pod scsi/*.pod rm -f qemu-img-cmds.h rm -f ui/shader/*-vert.h ui/shader/*-frag.h @@ -809,7 +808,7 @@ ifdef CONFIG_POSIX $(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7" $(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7" $(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7" -ifneq ($(TOOLS),) +ifeq ($(CONFIG_TOOLS),y) $(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1" $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8" $(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8" @@ -845,7 +844,7 @@ install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstated $(if $(INSTALL_BLOBS),$(edk2-decompressed)) \ recurse-install ifneq ($(TOOLS),) - $(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir)) + $(call install-prog,$(TOOLS),$(DESTDIR)$(bindir)) endif ifneq ($(CONFIG_MODULES),) $(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)" diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c index 4bf00b8496..f6d8c8fb6f 100644 --- a/accel/tcg/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/replay.h" #include "sysemu/sysemu.h" diff --git a/arch_init.c b/arch_init.c index 74b0708634..0a1531124c 100644 --- a/arch_init.c +++ b/arch_init.c @@ -106,14 +106,3 @@ int xen_available(void) return 0; #endif } - - -TargetInfo *qmp_query_target(Error **errp) -{ - TargetInfo *info = g_malloc0(sizeof(*info)); - - info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1, - &error_abort); - - return info; -} diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 7ca5d97af3..03f03407b0 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener, void *opaque); static int tcp_chr_read_poll(void *opaque); -static void tcp_chr_disconnect(Chardev *chr); +static void tcp_chr_disconnect_locked(Chardev *chr); /* Called with chr_write_lock held. */ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) @@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) if (ret < 0 && errno != EAGAIN) { if (tcp_chr_read_poll(chr) <= 0) { - tcp_chr_disconnect(chr); + tcp_chr_disconnect_locked(chr); return len; } /* else let the read handler finish it properly */ } @@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s) /* NB may be called even if tcp_chr_connect has not been * reached, due to TLS or telnet initialization failure, * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED + * This must be called with chr->chr_write_lock held. */ -static void tcp_chr_disconnect(Chardev *chr) +static void tcp_chr_disconnect_locked(Chardev *chr) { SocketChardev *s = SOCKET_CHARDEV(chr); bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED; @@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr) } } +static void tcp_chr_disconnect(Chardev *chr) +{ + qemu_mutex_lock(&chr->chr_write_lock); + tcp_chr_disconnect_locked(chr); + qemu_mutex_unlock(&chr->chr_write_lock); +} + static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { Chardev *chr = CHARDEV(opaque); @@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque) Chardev *chr = CHARDEV(opaque); SocketChardev *s = SOCKET_CHARDEV(opaque); + qemu_mutex_lock(&chr->chr_write_lock); g_source_unref(s->reconnect_timer); s->reconnect_timer = NULL; + qemu_mutex_unlock(&chr->chr_write_lock); if (chr->be_open) { return false; @@ -6129,7 +6129,7 @@ if [ "$guest_agent" != "no" ]; then if [ "$softmmu" = no -a "$want_tools" = no ] ; then guest_agent=no elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then - tools="qemu-ga $tools" + tools="qemu-ga\$(EXESUF) $tools" guest_agent=yes elif [ "$guest_agent" != yes ]; then guest_agent=no @@ -6614,6 +6614,9 @@ fi if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi +if test "$want_tools" = "yes" ; then + echo "CONFIG_TOOLS=y" >> $config_host_mak +fi if test "$slirp" != "no"; then echo "CONFIG_SLIRP=y" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak @@ -7360,11 +7363,6 @@ if test "$sparse" = "yes" ; then echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak fi -if test "$cross_prefix" != ""; then - echo "AUTOCONF_HOST := --host=${cross_prefix%-}" >> $config_host_mak -else - echo "AUTOCONF_HOST := " >> $config_host_mak -fi echo "LDFLAGS=$LDFLAGS" >> $config_host_mak echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak diff --git a/cpus-common.c b/cpus-common.c index 023cfebfa3..af3385a296 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "exec/cpu-common.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/cpus.h" static QemuMutex qemu_cpu_list_lock; diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json index ff8c2ce5f2..8ffb7856d2 100644 --- a/docs/interop/firmware.json +++ b/docs/interop/firmware.json @@ -13,7 +13,7 @@ # = Firmware ## -{ 'include' : 'common.json' } +{ 'include' : 'machine.json' } { 'include' : 'block-core.json' } ## @@ -939,7 +939,7 @@ void cpu_exec_unrealizefn(CPUState *cpu) Property cpu_common_props[] = { #ifndef CONFIG_USER_ONLY /* Create a memory property for softmmu CPU object, - * so users can wire up its memory. (This can't go in qom/cpu.c + * so users can wire up its memory. (This can't go in hw/core/cpu.c * because that file is compiled only once for both user-mode * and system builds.) The default if no link is set up is to use * the system address space. diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index a83567e6aa..6e8293aac9 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "hw/acpi/cpu_hotplug.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/i386/pc.h" #include "qemu/error-report.h" diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 2ca52bf045..2034dd749e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -31,7 +31,7 @@ #include "hw/pci/pci.h" #include "migration/vmstate.h" #include "qemu/timer.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" #include "hw/acpi/acpi.h" diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 1c907d2a7d..5742c3df87 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -44,7 +44,7 @@ #include "hw/xen/xen.h" #include "migration/qemu-file-types.h" #include "migration/vmstate.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "trace.h" #define GPE_BASE 0xafe0 diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 956ebe32c8..245817d23e 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -20,7 +20,7 @@ #include "exec/address-spaces.h" #include "trace.h" #include "exec/target_page.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/qdev-properties.h" #include "qapi/error.h" #include "qemu/jhash.h" diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index fa9afd2b7e..a8b2d97fe9 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -30,7 +30,7 @@ #include "qapi/error.h" #include "qemu/bitmap.h" #include "trace.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "target/arm/cpu.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index b49f880a0c..fd0550d1d9 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -8,6 +8,7 @@ common-obj-y += irq.o common-obj-y += hotplug.o common-obj-$(CONFIG_SOFTMMU) += nmi.o common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o +common-obj-y += cpu.o common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o common-obj-$(CONFIG_XILINX_AXI) += stream.o diff --git a/qom/cpu.c b/hw/core/cpu.c index aeb34f8c67..0035845511 100644 --- a/qom/cpu.c +++ b/hw/core/cpu.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/hw_accel.h" #include "qemu/notify.h" #include "qemu/log.h" diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index 06d8d6466e..4b1fc86a06 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -31,7 +31,7 @@ */ #include "qemu/osdep.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/sysbus.h" #include "sysemu/dma.h" #include "sysemu/reset.h" diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 526fbd5ced..15cf7c62e3 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -249,6 +249,16 @@ CurrentMachineParams *qmp_query_current_machine(Error **errp) return params; } +TargetInfo *qmp_query_target(Error **errp) +{ + TargetInfo *info = g_malloc0(sizeof(*info)); + + info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1, + &error_abort); + + return info; +} + HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index 30b1991b52..1aa0a9a01a 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -16,7 +16,7 @@ #include "hw/boards.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" static void machine_none_init(MachineState *mch) { diff --git a/hw/core/numa.c b/hw/core/numa.c index 7a63ddc4c6..4f7e4628a0 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -34,7 +34,7 @@ #include "qapi/opts-visitor.h" #include "qapi/qapi-visit-machine.h" #include "sysemu/qtest.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/mem/pc-dimm.h" #include "migration/vmstate.h" #include "hw/boards.h" diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c index cd1e165faf..6872a3a00a 100644 --- a/hw/cpu/a9mpcore.c +++ b/hw/cpu/a9mpcore.c @@ -14,7 +14,7 @@ #include "hw/cpu/a9mpcore.h" #include "hw/irq.h" #include "hw/qdev-properties.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" static void a9mp_priv_set_irq(void *opaque, int irq, int level) { diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c index 74d8d43c00..349a883261 100644 --- a/hw/cpu/cluster.c +++ b/hw/cpu/cluster.c @@ -21,7 +21,7 @@ #include "qemu/osdep.h" #include "hw/cpu/cluster.h" #include "hw/qdev-properties.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qapi/error.h" #include "qemu/module.h" #include "qemu/cutils.h" diff --git a/hw/display/ati.c b/hw/display/ati.c index 35f49a591b..8f940eee22 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -50,6 +50,7 @@ static void ati_vga_switch_mode(ATIVGAState *s) s->mode = EXT_MODE; if (s->regs.crtc_gen_cntl & CRTC2_EN) { /* CRT controller enabled, use CRTC values */ + /* FIXME Should these be the same as VGA CRTC regs? */ uint32_t offs = s->regs.crtc_offset & 0x07ffffff; int stride = (s->regs.crtc_pitch & 0x7ff) * 8; int bpp = 0; @@ -89,7 +90,9 @@ static void ati_vga_switch_mode(ATIVGAState *s) DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs); vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED); - s->vga.big_endian_fb = false; + s->vga.big_endian_fb = (s->regs.config_cntl & APER_0_ENDIAN || + s->regs.config_cntl & APER_1_ENDIAN ? + true : false); /* reset VBE regs then set up mode */ s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h; s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v; @@ -101,16 +104,23 @@ static void ati_vga_switch_mode(ATIVGAState *s) (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0)); /* now set offset and stride after enable as that resets these */ if (stride) { + int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE); + vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH); vbe_ioport_write_data(&s->vga, 0, stride); - if (offs % stride == 0) { - vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET); - vbe_ioport_write_data(&s->vga, 0, offs / stride); - } else { - /* FIXME what to do with this? */ - error_report("VGA offset is not multiple of pitch, " - "expect bad picture"); + stride *= bypp; + if (offs % stride) { + DPRINTF("CRTC offset is not multiple of pitch\n"); + vbe_ioport_write_index(&s->vga, 0, + VBE_DISPI_INDEX_X_OFFSET); + vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp); } + vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET); + vbe_ioport_write_data(&s->vga, 0, offs / stride); + DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n", + s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET], + s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET], + s->vga.vbe_start_addr); } } } else { @@ -132,9 +142,8 @@ static void ati_cursor_define(ATIVGAState *s) return; /* Do not update cursor if locked or rendered by guest */ } /* FIXME handle cur_hv_offs correctly */ - src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) + - s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) - - (s->regs.cur_hv_offs & 0xffff) * 16; + src = s->vga.vram_ptr + s->regs.cur_offset - + (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16; for (i = 0; i < 64; i++) { for (j = 0; j < 8; j++, idx++) { data[idx] = src[i * 16 + j]; @@ -190,8 +199,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y) return; } /* FIXME handle cur_hv_offs correctly */ - src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) + - s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16; + src = s->vga.vram_ptr + s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16; dp = &dp[vga->hw_cursor_x]; h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8; for (i = 0; i < 8; i++) { @@ -207,7 +215,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y) } } else { color = (xbits & BIT(7) ? s->regs.cur_color1 : - s->regs.cur_color0) << 8 | 0xff; + s->regs.cur_color0) | 0xff000000; } if (vga->hw_cursor_x + i * 8 + j >= h) { return; /* end of screen, don't span to next line */ @@ -235,6 +243,21 @@ static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base) return data; } +static void ati_vga_update_irq(ATIVGAState *s) +{ + pci_set_irq(&s->dev, !!(s->regs.gen_int_status & s->regs.gen_int_cntl)); +} + +static void ati_vga_vblank_irq(void *opaque) +{ + ATIVGAState *s = opaque; + + timer_mod(&s->vblank_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 60); + s->regs.gen_int_status |= CRTC_VBLANK_INT; + ati_vga_update_irq(s); +} + static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs, unsigned int size) { @@ -275,6 +298,12 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) addr - (BIOS_0_SCRATCH + i * 4), size); break; } + case GEN_INT_CNTL: + val = s->regs.gen_int_cntl; + break; + case GEN_INT_STATUS: + val = s->regs.gen_int_status; + break; case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: val = ati_reg_read_offs(s->regs.crtc_gen_cntl, addr - CRTC_GEN_CNTL, size); @@ -304,9 +333,27 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) case PALETTE_DATA: val = vga_ioport_read(&s->vga, VGA_PEL_D); break; + case CNFG_CNTL: + val = s->regs.config_cntl; + break; case CNFG_MEMSIZE: val = s->vga.vram_size; break; + case CONFIG_APER_0_BASE: + case CONFIG_APER_1_BASE: + val = pci_default_read_config(&s->dev, + PCI_BASE_ADDRESS_0, size) & 0xfffffff0; + break; + case CONFIG_APER_SIZE: + val = s->vga.vram_size; + break; + case CONFIG_REG_1_BASE: + val = pci_default_read_config(&s->dev, + PCI_BASE_ADDRESS_2, size) & 0xfffffff0; + break; + case CONFIG_REG_APER_SIZE: + val = memory_region_size(&s->mm); + break; case MC_STATUS: val = 5; break; @@ -486,6 +533,21 @@ static void ati_mm_write(void *opaque, hwaddr addr, addr - (BIOS_0_SCRATCH + i * 4), data, size); break; } + case GEN_INT_CNTL: + s->regs.gen_int_cntl = data; + if (data & CRTC_VBLANK_INT) { + ati_vga_vblank_irq(s); + } else { + timer_del(&s->vblank_timer); + ati_vga_update_irq(s); + } + break; + case GEN_INT_STATUS: + data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ? + 0x000f040fUL : 0xfc080effUL); + s->regs.gen_int_status &= ~data; + ati_vga_update_irq(s); + break; case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: { uint32_t val = s->regs.crtc_gen_cntl; @@ -549,12 +611,15 @@ static void ati_mm_write(void *opaque, hwaddr addr, addr - GPIO_MONID, data, size); /* * Rage128p accesses DDC used to get EDID via these bits. - * Only touch i2c when write overlaps 3rd byte because some - * drivers access this reg via multiple partial writes and - * without this spurious bits would be sent. + * Because some drivers access this via multiple byte writes + * we have to be careful when we send bits to avoid spurious + * changes in bitbang_i2c state. So only do it when mask is set + * and either the enable bits are changed or output bits changed + * while enabled. */ if ((s->regs.gpio_monid & BIT(25)) && - addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) { + ((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) || + (addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) { s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1); } } @@ -580,6 +645,9 @@ static void ati_mm_write(void *opaque, hwaddr addr, data >>= 8; vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff); break; + case CNFG_CNTL: + s->regs.config_cntl = data; + break; case CRTC_H_TOTAL_DISP: s->regs.crtc_h_total_disp = data & 0x07ff07ff; break; @@ -870,12 +938,19 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm); + + /* most interrupts are not yet emulated but MacOS needs at least VBlank */ + dev->config[PCI_INTERRUPT_PIN] = 1; + timer_init_ns(&s->vblank_timer, QEMU_CLOCK_VIRTUAL, ati_vga_vblank_irq, s); } static void ati_vga_reset(DeviceState *dev) { ATIVGAState *s = ATI_VGA(dev); + timer_del(&s->vblank_timer); + ati_vga_update_irq(s); + /* reset vga */ vga_common_reset(&s->vga); s->mode = VGA_MODE; @@ -885,6 +960,7 @@ static void ati_vga_exit(PCIDevice *dev) { ATIVGAState *s = ATI_VGA(dev); + timer_del(&s->vblank_timer); graphic_console_close(s->vga.con); } diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c index 88b3a11315..0ebbd36f14 100644 --- a/hw/display/ati_dbg.c +++ b/hw/display/ati_dbg.c @@ -16,6 +16,7 @@ static struct ati_regdesc ati_reg_names[] = { {"BUS_CNTL", 0x0030}, {"BUS_CNTL1", 0x0034}, {"GEN_INT_CNTL", 0x0040}, + {"GEN_INT_STATUS", 0x0044}, {"CRTC_GEN_CNTL", 0x0050}, {"CRTC_EXT_CNTL", 0x0054}, {"DAC_CNTL", 0x0058}, @@ -23,11 +24,20 @@ static struct ati_regdesc ati_reg_names[] = { {"GPIO_DVI_DDC", 0x0064}, {"GPIO_MONID", 0x0068}, {"I2C_CNTL_1", 0x0094}, + {"AMCGPIO_MASK_MIR", 0x009c}, + {"AMCGPIO_A_MIR", 0x00a0}, + {"AMCGPIO_Y_MIR", 0x00a4}, + {"AMCGPIO_EN_MIR", 0x00a8}, {"PALETTE_INDEX", 0x00b0}, {"PALETTE_DATA", 0x00b4}, {"CNFG_CNTL", 0x00e0}, {"GEN_RESET_CNTL", 0x00f0}, {"CNFG_MEMSIZE", 0x00f8}, + {"CONFIG_APER_0_BASE", 0x0100}, + {"CONFIG_APER_1_BASE", 0x0104}, + {"CONFIG_APER_SIZE", 0x0108}, + {"CONFIG_REG_1_BASE", 0x010c}, + {"CONFIG_REG_APER_SIZE", 0x0110}, {"MEM_CNTL", 0x0140}, {"MC_FB_LOCATION", 0x0148}, {"MC_AGP_LOCATION", 0x014C}, diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h index 31a1927b3e..2a16708e4f 100644 --- a/hw/display/ati_int.h +++ b/hw/display/ati_int.h @@ -9,6 +9,7 @@ #ifndef ATI_INT_H #define ATI_INT_H +#include "qemu/timer.h" #include "hw/pci/pci.h" #include "hw/i2c/bitbang_i2c.h" #include "vga_int.h" @@ -33,12 +34,15 @@ typedef struct ATIVGARegs { uint32_t mm_index; uint32_t bios_scratch[8]; + uint32_t gen_int_cntl; + uint32_t gen_int_status; uint32_t crtc_gen_cntl; uint32_t crtc_ext_cntl; uint32_t dac_cntl; uint32_t gpio_vga_ddc; uint32_t gpio_dvi_ddc; uint32_t gpio_monid; + uint32_t config_cntl; uint32_t crtc_h_total_disp; uint32_t crtc_h_sync_strt_wid; uint32_t crtc_v_total_disp; @@ -88,6 +92,7 @@ typedef struct ATIVGAState { uint16_t cursor_size; uint32_t cursor_offset; QEMUCursor *cursor; + QEMUTimer vblank_timer; bitbang_i2c_interface bbi2c; MemoryRegion io; MemoryRegion mm; diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h index d7155c93d5..ebd37ee30d 100644 --- a/hw/display/ati_regs.h +++ b/hw/display/ati_regs.h @@ -34,6 +34,7 @@ #define BUS_CNTL 0x0030 #define BUS_CNTL1 0x0034 #define GEN_INT_CNTL 0x0040 +#define GEN_INT_STATUS 0x0044 #define CRTC_GEN_CNTL 0x0050 #define CRTC_EXT_CNTL 0x0054 #define DAC_CNTL 0x0058 @@ -41,11 +42,20 @@ #define GPIO_DVI_DDC 0x0064 #define GPIO_MONID 0x0068 #define I2C_CNTL_1 0x0094 +#define AMCGPIO_MASK_MIR 0x009c +#define AMCGPIO_A_MIR 0x00a0 +#define AMCGPIO_Y_MIR 0x00a4 +#define AMCGPIO_EN_MIR 0x00a8 #define PALETTE_INDEX 0x00b0 #define PALETTE_DATA 0x00b4 #define CNFG_CNTL 0x00e0 #define GEN_RESET_CNTL 0x00f0 #define CNFG_MEMSIZE 0x00f8 +#define CONFIG_APER_0_BASE 0x0100 +#define CONFIG_APER_1_BASE 0x0104 +#define CONFIG_APER_SIZE 0x0108 +#define CONFIG_REG_1_BASE 0x010c +#define CONFIG_REG_APER_SIZE 0x0110 #define MEM_CNTL 0x0140 #define MC_FB_LOCATION 0x0148 #define MC_AGP_LOCATION 0x014C @@ -307,7 +317,14 @@ #define XPLL_FB_DIV_MASK 0x0000FF00 #define X_MPLL_REF_DIV_MASK 0x000000FF +/* GEN_INT_CNTL) */ +#define CRTC_VBLANK_INT 0x00000001 +#define CRTC_VLINE_INT 0x00000002 +#define CRTC_VSYNC_INT 0x00000004 + /* Config control values (CONFIG_CNTL) */ +#define APER_0_ENDIAN 0x00000003 +#define APER_1_ENDIAN 0x0000000c #define CFG_VGA_IO_DIS 0x00000400 /* CRTC control values (CRTC_GEN_CNTL) */ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5b0ec1b89e..034e413fd0 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -27,7 +27,7 @@ #include "qemu/bitmap.h" #include "qemu/error-report.h" #include "hw/pci/pci.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "target/i386/cpu.h" #include "hw/misc/pvpanic.h" #include "hw/timer/hpet.h" diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 697c33606a..c14ed86439 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -76,7 +76,7 @@ #include "qapi/error.h" #include "qapi/qapi-visit-common.h" #include "qapi/visitor.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/nmi.h" #include "hw/usb.h" #include "hw/i386/intel_iommu.h" diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 7af591daac..1d7da7baa2 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -23,7 +23,7 @@ #include "hw/sysbus.h" #include "gic_internal.h" #include "qapi/error.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/log.h" #include "qemu/module.h" #include "trace.h" diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 8f5f4c8e94..f0c551d43f 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index eec9eb31c1..17c292e306 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -49,7 +49,7 @@ #include "exec/address-spaces.h" #include "sysemu/runstate.h" #include "sysemu/sysemu.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/nvram/fw_cfg.h" #include "qemu/cutils.h" diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c index 8ab18967b5..dd99cc7acf 100644 --- a/hw/misc/imx6_src.c +++ b/hw/misc/imx6_src.c @@ -16,7 +16,7 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "arm-powerctl.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef DEBUG_IMX6_SRC #define DEBUG_IMX6_SRC 0 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 64fc2255cc..baedadf20b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -49,7 +49,7 @@ #include "mmu-hash64.h" #include "mmu-book3s-v3.h" #include "cpu-models.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "hw/boards.h" #include "hw/ppc/ppc.h" diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index 75f1867174..4c634c83b1 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -31,7 +31,7 @@ #include "qemu/bitops.h" #include "qemu/log.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef A9_GTIMER_ERR_DEBUG #define A9_GTIMER_ERR_DEBUG 0 diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 983e61847e..9f63abef10 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -29,7 +29,7 @@ #include "qapi/error.h" #include "qemu/main-loop.h" #include "qemu/module.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define PTIMER_POLICY \ (PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | \ diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 9ca7b87a80..56ab2f457f 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1838,6 +1838,9 @@ static int ehci_state_fetchqtd(EHCIQueue *q) ehci_set_state(q->ehci, q->async, EST_EXECUTING); break; } + } else if (q->dev == NULL) { + ehci_trace_guest_bug(q->ehci, "no device attached to queue"); + ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); } else { p = ehci_alloc_packet(q); p->qtdaddr = q->qtdaddr; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index f698224c8a..f578264948 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -2543,6 +2543,9 @@ static void xhci_process_commands(XHCIState *xhci) case CR_GET_PORT_BANDWIDTH: event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter); break; + case CR_NOOP: + event.ccode = CC_SUCCESS; + break; case CR_VENDOR_NEC_FIRMWARE_REVISION: if (xhci->nec_quirks) { event.type = 48; /* NEC reply */ diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index fc9fe0c00f..e0f5ca6f81 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -819,8 +819,8 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, USBPacket *p, uint8_t ep) { /* Input interrupt endpoint, buffered packet input */ - struct buf_packet *intp; - int status, len; + struct buf_packet *intp, *intp_to_free; + int status, len, sum; if (!dev->endpoint[EP2I(ep)].interrupt_started && !dev->endpoint[EP2I(ep)].interrupt_error) { @@ -839,9 +839,17 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; } - intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); + /* check for completed interrupt message (with all fragments) */ + sum = 0; + QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { + sum += intp->len; + if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || + sum >= p->iov.size) + break; + } + if (intp == NULL) { - DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep); + DPRINTF2("interrupt-token-in ep %02X, no intp, buffered %d\n", ep, sum); /* Check interrupt_error for stream errors */ status = dev->endpoint[EP2I(ep)].interrupt_error; dev->endpoint[EP2I(ep)].interrupt_error = 0; @@ -852,18 +860,42 @@ static void usbredir_handle_interrupt_in_data(USBRedirDevice *dev, } return; } - DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep, - intp->status, intp->len); - status = intp->status; - len = intp->len; - if (len > p->iov.size) { - ERROR("received int data is larger then packet ep %02X\n", ep); - len = p->iov.size; - status = usb_redir_babble; + /* copy of completed interrupt message */ + sum = 0; + status = usb_redir_success; + intp_to_free = NULL; + QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { + if (intp_to_free) { + bufp_free(dev, intp_to_free, ep); + } + DPRINTF("interrupt-token-in ep %02X fragment status %d len %d\n", ep, + intp->status, intp->len); + + sum += intp->len; + len = intp->len; + if (status == usb_redir_success) { + status = intp->status; + } + if (sum > p->iov.size) { + ERROR("received int data is larger then packet ep %02X\n", ep); + len -= (sum - p->iov.size); + sum = p->iov.size; + status = usb_redir_babble; + } + + usb_packet_copy(p, intp->data, len); + + intp_to_free = intp; + if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || + sum >= p->iov.size) + break; + } + if (intp_to_free) { + bufp_free(dev, intp_to_free, ep); } - usb_packet_copy(p, intp->data, len); - bufp_free(dev, intp, ep); + DPRINTF("interrupt-token-in ep %02X summary status %d len %d\n", ep, + status, sum); usbredir_handle_status(dev, p, status); } @@ -1499,6 +1531,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev) for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) { dev->endpoint[i].bulk_receiving_enabled = 0; } + + if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { + return; + } + for (i = 0; i < dev->interface_info.interface_count; i++) { quirks = usb_get_quirks(dev->device_info.vendor_id, dev->device_info.product_id, @@ -2036,22 +2073,17 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id, } if (ep & USB_DIR_IN) { - bool q_was_empty; - if (dev->endpoint[EP2I(ep)].interrupt_started == 0) { DPRINTF("received int packet while not started ep %02X\n", ep); free(data); return; } - q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq); - /* bufp_alloc also adds the packet to the ep queue */ bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data); - if (q_was_empty) { - usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0); - } + /* insufficient data solved with USB_RET_NAK */ + usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0); } else { /* * We report output interrupt packets as completed directly upon diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 536ea58f81..8323094648 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -22,7 +22,7 @@ #include "exec/cpu-common.h" #include "exec/memory.h" #include "qemu/thread.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/rcu.h" #define EXCP_INTERRUPT 0x10000 /* async interruption */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 57a9a4ffd9..189709b6de 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -32,7 +32,7 @@ #include "exec/hwaddr.h" #endif #include "exec/memattrs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "cpu-param.h" diff --git a/include/exec/log.h b/include/exec/log.h index de067f173b..e2cfd436e6 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -2,7 +2,7 @@ #define QEMU_EXEC_LOG_H #include "qemu/log.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "disas/disas.h" /* cpu_dump_state() logging functions: */ diff --git a/include/hw/boards.h b/include/hw/boards.h index 60d69217b4..ced86109ec 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -9,7 +9,7 @@ #include "qapi/qapi-types-machine.h" #include "qemu/module.h" #include "qom/object.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /** * memory_region_allocate_system_memory - Allocate a board's main memory diff --git a/include/qom/cpu.h b/include/hw/core/cpu.h index 77fca95a40..77fca95a40 100644 --- a/include/qom/cpu.h +++ b/include/hw/core/cpu.h diff --git a/include/hw/ppc/openpic.h b/include/hw/ppc/openpic.h index ec16897bfb..db0d29e6c2 100644 --- a/include/hw/ppc/openpic.h +++ b/include/hw/ppc/openpic.h @@ -2,7 +2,7 @@ #define OPENPIC_H #include "hw/sysbus.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define MAX_CPU 32 #define MAX_MSI 8 diff --git a/include/qemu/module.h b/include/qemu/module.h index db3065381d..65ba596e46 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -65,6 +65,6 @@ void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); -void module_load_one(const char *prefix, const char *lib_name); +bool module_load_one(const char *prefix, const char *lib_name); #endif diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index d2ddfb5ad0..0ec2372477 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -11,7 +11,7 @@ #ifndef QEMU_HW_ACCEL_H #define QEMU_HW_ACCEL_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "sysemu/hax.h" #include "sysemu/kvm.h" #include "sysemu/whpx.h" diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c8ea412f62..909bcd77cf 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -15,7 +15,7 @@ #define QEMU_KVM_H #include "qemu/queue.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "exec/memattrs.h" #ifdef NEED_CPU_H @@ -136,6 +136,7 @@ static gpointer qio_task_thread_worker(gpointer opaque) qio_task_thread_result, task, NULL); g_source_attach(task->thread->completion, task->thread->context); + g_source_unref(task->thread->completion); trace_qio_task_thread_source_attach(task, task->thread->completion); qemu_cond_signal(&task->thread_cond); @@ -217,7 +217,6 @@ struct FlatRange { bool romd_mode; bool readonly; bool nonvolatile; - int has_coalesced_range; }; #define FOR_EACH_FLAT_RANGE(var, view) \ @@ -654,7 +653,6 @@ static void render_memory_region(FlatView *view, fr.romd_mode = mr->romd_mode; fr.readonly = readonly; fr.nonvolatile = nonvolatile; - fr.has_coalesced_range = 0; /* Render the region itself into any gaps left by the current view. */ for (i = 0; i < view->nr && int128_nz(remain); ++i) { @@ -855,46 +853,55 @@ static void address_space_update_ioeventfds(AddressSpace *as) flatview_unref(view); } -static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as) +/* + * Notify the memory listeners about the coalesced IO change events of + * range `cmr'. Only the part that has intersection of the specified + * FlatRange will be sent. + */ +static void flat_range_coalesced_io_notify(FlatRange *fr, AddressSpace *as, + CoalescedMemoryRange *cmr, bool add) { - if (!fr->has_coalesced_range) { + AddrRange tmp; + + tmp = addrrange_shift(cmr->addr, + int128_sub(fr->addr.start, + int128_make64(fr->offset_in_region))); + if (!addrrange_intersects(tmp, fr->addr)) { return; } + tmp = addrrange_intersection(tmp, fr->addr); - if (--fr->has_coalesced_range > 0) { - return; + if (add) { + MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add, + int128_get64(tmp.start), + int128_get64(tmp.size)); + } else { + MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del, + int128_get64(tmp.start), + int128_get64(tmp.size)); } +} - MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del, - int128_get64(fr->addr.start), - int128_get64(fr->addr.size)); +static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as) +{ + CoalescedMemoryRange *cmr; + + QTAILQ_FOREACH(cmr, &fr->mr->coalesced, link) { + flat_range_coalesced_io_notify(fr, as, cmr, false); + } } static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as) { MemoryRegion *mr = fr->mr; CoalescedMemoryRange *cmr; - AddrRange tmp; if (QTAILQ_EMPTY(&mr->coalesced)) { return; } - if (fr->has_coalesced_range++) { - return; - } - QTAILQ_FOREACH(cmr, &mr->coalesced, link) { - tmp = addrrange_shift(cmr->addr, - int128_sub(fr->addr.start, - int128_make64(fr->offset_in_region))); - if (!addrrange_intersects(tmp, fr->addr)) { - continue; - } - tmp = addrrange_intersection(tmp, fr->addr); - MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add, - int128_get64(tmp.start), - int128_get64(tmp.size)); + flat_range_coalesced_io_notify(fr, as, cmr, true); } } @@ -2236,27 +2243,26 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp qemu_ram_resize(mr->ram_block, newsize, errp); } -static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as) +/* + * Call proper memory listeners about the change on the newly + * added/removed CoalescedMemoryRange. + */ +static void memory_region_update_coalesced_range(MemoryRegion *mr, + CoalescedMemoryRange *cmr, + bool add) { + AddressSpace *as; FlatView *view; FlatRange *fr; - view = address_space_get_flatview(as); - FOR_EACH_FLAT_RANGE(fr, view) { - if (fr->mr == mr) { - flat_range_coalesced_io_del(fr, as); - flat_range_coalesced_io_add(fr, as); - } - } - flatview_unref(view); -} - -static void memory_region_update_coalesced_range(MemoryRegion *mr) -{ - AddressSpace *as; - QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { - memory_region_update_coalesced_range_as(mr, as); + view = address_space_get_flatview(as); + FOR_EACH_FLAT_RANGE(fr, view) { + if (fr->mr == mr) { + flat_range_coalesced_io_notify(fr, as, cmr, add); + } + } + flatview_unref(view); } } @@ -2274,14 +2280,17 @@ void memory_region_add_coalescing(MemoryRegion *mr, cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size)); QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link); - memory_region_update_coalesced_range(mr); + memory_region_update_coalesced_range(mr, cmr, true); memory_region_set_flush_coalesced(mr); } void memory_region_clear_coalescing(MemoryRegion *mr) { CoalescedMemoryRange *cmr; - bool updated = false; + + if (QTAILQ_EMPTY(&mr->coalesced)) { + return; + } qemu_flush_coalesced_mmio_buffer(); mr->flush_coalesced_mmio = false; @@ -2289,12 +2298,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr) while (!QTAILQ_EMPTY(&mr->coalesced)) { cmr = QTAILQ_FIRST(&mr->coalesced); QTAILQ_REMOVE(&mr->coalesced, cmr, link); + memory_region_update_coalesced_range(mr, cmr, false); g_free(cmr); - updated = true; - } - - if (updated) { - memory_region_update_coalesced_range(mr); } } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index e4d4043a3b..b2551c16d1 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -25,7 +25,6 @@ #include "qemu/timer.h" #include "qemu/sockets.h" #include "monitor/monitor-internal.h" -#include "monitor/qdev.h" #include "qapi/error.h" #include "qapi/clone-visitor.h" #include "qapi/opts-visitor.h" @@ -35,7 +34,6 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" -#include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-rocker.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-commands-tpm.h" @@ -2167,23 +2165,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict) } } -void hmp_device_add(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - - qmp_device_add((QDict *)qdict, NULL, &err); - hmp_handle_error(mon, &err); -} - -void hmp_device_del(Monitor *mon, const QDict *qdict) -{ - const char *id = qdict_get_str(qdict, "id"); - Error *err = NULL; - - qmp_device_del(id, &err); - hmp_handle_error(mon, &err); -} - void hmp_netdev_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; diff --git a/monitor/qmp.c b/monitor/qmp.c index e1b196217d..9d9e5d8b27 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -97,7 +97,7 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rsp) } /* - * Emit QMP response @rsp with ID @id to @mon. + * Emit QMP response @rsp to @mon. * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP. * Nothing is emitted then. */ diff --git a/qapi/common.json b/qapi/common.json index 3d4e8de1e0..7b9cbcd97b 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -144,28 +144,3 @@ ## { 'enum': 'PCIELinkWidth', 'data': [ '1', '2', '4', '8', '12', '16', '32' ] } - -## -# @SysEmuTarget: -# -# The comprehensive enumeration of QEMU system emulation ("softmmu") -# targets. Run "./configure --help" in the project root directory, and -# look for the *-softmmu targets near the "--target-list" option. The -# individual target constants are not documented here, for the time -# being. -# -# Notes: The resulting QMP strings can be appended to the "qemu-system-" -# prefix to produce the corresponding QEMU executable name. This -# is true even for "qemu-system-x86_64". -# -# ppcemb: dropped in 3.1 -# -# Since: 3.0 -## -{ 'enum' : 'SysEmuTarget', - 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', - 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', - 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', - 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', - 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', - 'x86_64', 'xtensa', 'xtensaeb' ] } diff --git a/qapi/machine.json b/qapi/machine.json index 6db8a7e2ec..de5c742d72 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -7,7 +7,30 @@ # = Machines ## -{ 'include': 'common.json' } +## +# @SysEmuTarget: +# +# The comprehensive enumeration of QEMU system emulation ("softmmu") +# targets. Run "./configure --help" in the project root directory, and +# look for the *-softmmu targets near the "--target-list" option. The +# individual target constants are not documented here, for the time +# being. +# +# Notes: The resulting QMP strings can be appended to the "qemu-system-" +# prefix to produce the corresponding QEMU executable name. This +# is true even for "qemu-system-x86_64". +# +# ppcemb: dropped in 3.1 +# +# Since: 3.0 +## +{ 'enum' : 'SysEmuTarget', + 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', + 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', + 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', + 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', + 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', + 'x86_64', 'xtensa', 'xtensaeb' ] } ## # @CpuInfoArch: @@ -369,6 +392,29 @@ { 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' } ## +# @TargetInfo: +# +# Information describing the QEMU target. +# +# @arch: the target architecture +# +# Since: 1.2.0 +## +{ 'struct': 'TargetInfo', + 'data': { 'arch': 'SysEmuTarget' } } + +## +# @query-target: +# +# Return information about the target for this QEMU +# +# Returns: TargetInfo +# +# Since: 1.2.0 +## +{ 'command': 'query-target', 'returns': 'TargetInfo' } + +## # @NumaOptionsType: # # @node: NUMA nodes configuration diff --git a/qapi/misc.json b/qapi/misc.json index a7fba7230c..6bd11f50e6 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1342,29 +1342,6 @@ { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] } ## -# @TargetInfo: -# -# Information describing the QEMU target. -# -# @arch: the target architecture -# -# Since: 1.2.0 -## -{ 'struct': 'TargetInfo', - 'data': { 'arch': 'SysEmuTarget' } } - -## -# @query-target: -# -# Return information about the target for this QEMU -# -# Returns: TargetInfo -# -# Since: 1.2.0 -## -{ 'command': 'query-target', 'returns': 'TargetInfo' } - -## # @AcpiTableOptions: # # Specify an ACPI table on the command line to load. diff --git a/qapi/ui.json b/qapi/ui.json index 59e412139a..e04525d8b4 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1025,7 +1025,8 @@ # ## { 'enum': 'GrabToggleKeys', - 'data': [ 'ctrl-ctrl', 'alt-alt', 'meta-meta', 'scrolllock', 'ctrl-scrolllock' ] } + 'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock', + 'ctrl-scrolllock' ] } ## # @DisplayGTK: diff --git a/qdev-monitor.c b/qdev-monitor.c index a0003bf2a9..8fe5c2cad2 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "monitor/hmp.h" #include "monitor/monitor.h" #include "monitor/qdev.h" #include "sysemu/arch_init.h" @@ -844,6 +845,23 @@ void qmp_device_del(const char *id, Error **errp) } } +void hmp_device_add(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + + qmp_device_add((QDict *)qdict, NULL, &err); + hmp_handle_error(mon, &err); +} + +void hmp_device_del(Monitor *mon, const QDict *qdict) +{ + const char *id = qdict_get_str(qdict, "id"); + Error *err = NULL; + + qmp_device_del(id, &err); + hmp_handle_error(mon, &err); +} + BlockBackend *blk_by_qdev_id(const char *id, Error **errp) { DeviceState *dev; diff --git a/qemu-options.hx b/qemu-options.hx index a308e5f5aa..ea0638e92d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1436,12 +1436,15 @@ STEXI ETEXI DEF("usb", 0, QEMU_OPTION_usb, - "-usb enable the USB driver (if it is not used by default yet)\n", + "-usb enable on-board USB host controller (if not enabled by default)\n", QEMU_ARCH_ALL) STEXI @item -usb @findex -usb -Enable the USB driver (if it is not used by default yet). +Enable USB emulation on machine types with an on-board USB host controller (if +not enabled by default). Note that on-board USB host controllers may not +support USB 3.0. In this case @option{-device qemu-xhci} can be used instead +on machines with PCI. ETEXI DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice, diff --git a/qom/Makefile.objs b/qom/Makefile.objs index aae478fc21..f9d77350ac 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,5 +1,4 @@ qom-obj-y = object.o container.o qom-qobject.o qom-obj-y += object_interfaces.o -common-obj-y = cpu.o common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o @@ -661,6 +661,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words) qtest_send_prefix(chr); qtest_sendf(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + } else if (strcmp(words[0], "module_load") == 0) { + g_assert(words[1] && words[2]); + + qtest_send_prefix(chr); + if (module_load_one(words[1], words[2])) { + qtest_sendf(chr, "OK\n"); + } else { + qtest_sendf(chr, "FAIL\n"); + } } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) { int64_t ns; int ret; diff --git a/scripts/minikconf.py b/scripts/minikconf.py index 3109a81db7..40ae1989e1 100644 --- a/scripts/minikconf.py +++ b/scripts/minikconf.py @@ -702,8 +702,8 @@ if __name__ == '__main__': config = data.compute_config() for key in sorted(config.keys()): - if key not in external_vars: - print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n'))) + if key not in external_vars and config[key]: + print ('CONFIG_%s=y' % key) deps = open(argv[2], 'w') for fname in data.previously_included: diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h index bae4945344..6f0a0adb9e 100644 --- a/target/alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_ALPHA_CPU_QOM_H #define QEMU_ALPHA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_ALPHA_CPU "alpha-cpu" diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h index 2049fa9612..7f5b244bde 100644 --- a/target/arm/cpu-qom.h +++ b/target/arm/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_ARM_CPU_QOM_H #define QEMU_ARM_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" struct arm_boot_info; diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h index 7556e9f97e..308c1f95bd 100644 --- a/target/cris/cpu-qom.h +++ b/target/cris/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_CRIS_CPU_QOM_H #define QEMU_CRIS_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_CRIS_CPU "cris-cpu" diff --git a/target/hppa/cpu-qom.h b/target/hppa/cpu-qom.h index 9084e4701d..6367dc4793 100644 --- a/target/hppa/cpu-qom.h +++ b/target/hppa/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_HPPA_CPU_QOM_H #define QEMU_HPPA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_HPPA_CPU "hppa-cpu" diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 89241c31e7..462747baf8 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -22,7 +22,7 @@ #include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef CONFIG_USER_ONLY static void eval_interrupt(HPPACPU *cpu) diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index b12c5b5054..5a465db0dd 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "trace.h" #ifdef CONFIG_USER_ONLY diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index 1a52f02a4c..0efab2fc67 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_I386_CPU_QOM_H #define QEMU_I386_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "qemu/notify.h" #ifdef TARGET_X86_64 diff --git a/target/lm32/cpu-qom.h b/target/lm32/cpu-qom.h index b423d2564b..dc9ac9ac9f 100644 --- a/target/lm32/cpu-qom.h +++ b/target/lm32/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_LM32_CPU_QOM_H #define QEMU_LM32_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_LM32_CPU "lm32-cpu" diff --git a/target/m68k/cpu-qom.h b/target/m68k/cpu-qom.h index 0c157251a2..b56da8a213 100644 --- a/target/m68k/cpu-qom.h +++ b/target/m68k/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_M68K_CPU_QOM_H #define QEMU_M68K_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_M68K_CPU "m68k-cpu" diff --git a/target/microblaze/cpu-qom.h b/target/microblaze/cpu-qom.h index 1a61db77d0..49b07cc697 100644 --- a/target/microblaze/cpu-qom.h +++ b/target/microblaze/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_MICROBLAZE_CPU_QOM_H #define QEMU_MICROBLAZE_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_MICROBLAZE_CPU "microblaze-cpu" diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h index ee58606afe..a430c0fe4b 100644 --- a/target/mips/cpu-qom.h +++ b/target/mips/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_MIPS_CPU_QOM_H #define QEMU_MIPS_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_MIPS64 #define TYPE_MIPS_CPU "mips64-cpu" diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h index 91ef2dc25e..01dca548e5 100644 --- a/target/moxie/cpu.h +++ b/target/moxie/cpu.h @@ -46,7 +46,7 @@ typedef struct CPUMoxieState { struct {} end_reset_fields; } CPUMoxieState; -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_MOXIE_CPU "moxie-cpu" diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h index 5d44b76389..361b06ffeb 100644 --- a/target/nios2/cpu.h +++ b/target/nios2/cpu.h @@ -22,7 +22,7 @@ #define NIOS2_CPU_H #include "exec/cpu-defs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" typedef struct CPUNios2State CPUNios2State; #if !defined(CONFIG_USER_ONLY) diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 61ade1d4f0..561f0f7fad 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -21,7 +21,7 @@ #define OPENRISC_CPU_H #include "exec/cpu-defs.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl. */ struct OpenRISCCPU; diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 5769fb78a9..7ffdb0a706 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_PPC_CPU_QOM_H #define QEMU_PPC_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_PPC64 #define TYPE_POWERPC_CPU "powerpc64-cpu" diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 240b31e2eb..18d91d0920 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -20,7 +20,7 @@ #ifndef RISCV_CPU_H #define RISCV_CPU_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #include "exec/cpu-defs.h" #include "fpu/softfloat-types.h" diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h index b46217dc31..b809ec8418 100644 --- a/target/s390x/cpu-qom.h +++ b/target/s390x/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_S390_CPU_QOM_H #define QEMU_S390_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_S390_CPU "s390x-cpu" diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h index 174a99e561..88bd01a616 100644 --- a/target/s390x/cpu_models.h +++ b/target/s390x/cpu_models.h @@ -15,7 +15,7 @@ #include "cpu_features.h" #include "gen-features.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /* static CPU definition */ struct S390CPUDef { diff --git a/target/sh4/cpu-qom.h b/target/sh4/cpu-qom.h index 0f9fb4dd31..0c56d055ba 100644 --- a/target/sh4/cpu-qom.h +++ b/target/sh4/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_SUPERH_CPU_QOM_H #define QEMU_SUPERH_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_SUPERH_CPU "superh-cpu" diff --git a/target/sparc/cpu-qom.h b/target/sparc/cpu-qom.h index af6d57a9e0..7442e2768e 100644 --- a/target/sparc/cpu-qom.h +++ b/target/sparc/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_SPARC_CPU_QOM_H #define QEMU_SPARC_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifdef TARGET_SPARC64 #define TYPE_SPARC_CPU "sparc64-cpu" diff --git a/target/tilegx/cpu.h b/target/tilegx/cpu.h index 6fcec06a9b..9cbec247d2 100644 --- a/target/tilegx/cpu.h +++ b/target/tilegx/cpu.h @@ -94,7 +94,7 @@ typedef struct CPUTLGState { struct {} end_reset_fields; } CPUTLGState; -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_TILEGX_CPU "tilegx-cpu" diff --git a/target/tricore/cpu-qom.h b/target/tricore/cpu-qom.h index 93c9d77fe3..7c1e130b4e 100644 --- a/target/tricore/cpu-qom.h +++ b/target/tricore/cpu-qom.h @@ -18,7 +18,7 @@ #ifndef QEMU_TRICORE_CPU_QOM_H #define QEMU_TRICORE_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_TRICORE_CPU "tricore-cpu" diff --git a/target/tricore/helper.h b/target/tricore/helper.h index b64780c37d..78176aa17a 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -153,3 +153,4 @@ DEF_HELPER_2(psw_write, void, env, i32) DEF_HELPER_1(psw_read, i32, env) /* Exceptions */ DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32) +DEF_HELPER_2(qemu_excp, noreturn, env, i32) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 9476d10d00..32c2bc1699 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -107,6 +107,13 @@ static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class, raise_exception_sync_internal(env, class, tin, pc, 0); } +void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp) +{ + CPUState *cs = env_cpu(env); + cs->exception_index = excp; + cpu_loop_exit(cs); +} + /* Addressing mode helper */ static uint16_t reverse16(uint16_t val) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index dc2a65f3f9..4f10407477 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -30,6 +30,7 @@ #include "exec/helper-gen.h" #include "tricore-opcodes.h" +#include "exec/translator.h" #include "exec/log.h" /* @@ -64,25 +65,16 @@ static const char *regnames_d[] = { }; typedef struct DisasContext { - struct TranslationBlock *tb; - target_ulong pc, saved_pc, next_pc; + DisasContextBase base; + CPUTriCoreState *env; + target_ulong pc_succ_insn; uint32_t opcode; - int singlestep_enabled; /* Routine used to access memory */ int mem_idx; uint32_t hflags, saved_hflags; - int bstate; } DisasContext; enum { - - BS_NONE = 0, - BS_STOP = 1, - BS_BRANCH = 2, - BS_EXCP = 3, -}; - -enum { MODE_LL = 0, MODE_LU = 1, MODE_UL = 2, @@ -378,13 +370,13 @@ static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea) These makros also specify in which ISA version the csfr was introduced. */ #define R(ADDRESS, REG, FEATURE) \ case ADDRESS: \ - if (tricore_feature(env, FEATURE)) { \ + if (tricore_feature(ctx->env, FEATURE)) { \ tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \ } \ break; #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) -static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) +static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset) { /* since we're caching PSW make this a special case */ if (offset == 0xfe04) { @@ -403,7 +395,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) since no execption occurs */ #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \ case ADDRESS: \ - if (tricore_feature(env, FEATURE)) { \ + if (tricore_feature(ctx->env, FEATURE)) { \ tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \ } \ break; @@ -412,7 +404,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset) watchdog device, we handle endinit protected registers like all-access registers for now. */ #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE) -static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1, +static inline void gen_mtcr(DisasContext *ctx, TCGv r1, int32_t offset) { if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { @@ -1102,7 +1094,7 @@ gen_maddrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) static inline void gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, - uint32_t up_shift, CPUTriCoreState *env) + uint32_t up_shift) { TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); @@ -1263,7 +1255,7 @@ gen_m16adds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, static inline void gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, - TCGv arg3, uint32_t n, CPUTriCoreState *env) + TCGv arg3, uint32_t n) { TCGv_i64 t1 = tcg_temp_new_i64(); TCGv_i64 t2 = tcg_temp_new_i64(); @@ -1961,7 +1953,7 @@ gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n) static inline void gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, - uint32_t up_shift, CPUTriCoreState *env) + uint32_t up_shift) { TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); @@ -2116,7 +2108,7 @@ gen_m16subs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, static inline void gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, - TCGv arg3, uint32_t n, CPUTriCoreState *env) + TCGv arg3, uint32_t n) { TCGv_i64 t1 = tcg_temp_new_i64(); TCGv_i64 t2 = tcg_temp_new_i64(); @@ -3162,11 +3154,11 @@ static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1) } static inline void -gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) +gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2) { TCGv_i64 ret = tcg_temp_new_i64(); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { gen_helper_dvinit_b_13(ret, cpu_env, r1, r2); } else { gen_helper_dvinit_b_131(ret, cpu_env, r1, r2); @@ -3177,11 +3169,11 @@ gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) } static inline void -gen_dvinit_h(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2) +gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2) { TCGv_i64 ret = tcg_temp_new_i64(); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { gen_helper_dvinit_h_13(ret, cpu_env, r1, r2); } else { gen_helper_dvinit_h_131(ret, cpu_env, r1, r2); @@ -3230,12 +3222,12 @@ static inline void gen_save_pc(target_ulong pc) static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) { - if (unlikely(ctx->singlestep_enabled)) { + if (unlikely(ctx->base.singlestep_enabled)) { return false; } #ifndef CONFIG_USER_ONLY - return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); + return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); #else return true; #endif @@ -3246,10 +3238,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(n); gen_save_pc(dest); - tcg_gen_exit_tb(ctx->tb, n); + tcg_gen_exit_tb(ctx->base.tb, n); } else { gen_save_pc(dest); - if (ctx->singlestep_enabled) { + if (ctx->base.singlestep_enabled) { /* raise exception debug */ } tcg_gen_exit_tb(NULL, 0); @@ -3261,24 +3253,33 @@ static void generate_trap(DisasContext *ctx, int class, int tin) TCGv_i32 classtemp = tcg_const_i32(class); TCGv_i32 tintemp = tcg_const_i32(tin); - gen_save_pc(ctx->pc); + gen_save_pc(ctx->base.pc_next); gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp); - ctx->bstate = BS_EXCP; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(classtemp); tcg_temp_free(tintemp); } +static void generate_qemu_excp(DisasContext *ctx, int excp) +{ + TCGv_i32 tmp = tcg_const_i32(excp); + gen_save_pc(ctx->base.pc_next); + gen_helper_qemu_excp(cpu_env, tmp); + ctx->base.is_jmp = DISAS_NORETURN; + tcg_temp_free(tmp); +} + static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1, TCGv r2, int16_t address) { TCGLabel *jumpLabel = gen_new_label(); tcg_gen_brcond_tl(cond, r1, r2, jumpLabel); - gen_goto_tb(ctx, 1, ctx->next_pc); + gen_goto_tb(ctx, 1, ctx->pc_succ_insn); gen_set_label(jumpLabel); - gen_goto_tb(ctx, 0, ctx->pc + address * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2); } static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1, @@ -3295,9 +3296,9 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset) tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1); - gen_goto_tb(ctx, 1, ctx->pc + offset); + gen_goto_tb(ctx, 1, ctx->base.pc_next + offset); gen_set_label(l1); - gen_goto_tb(ctx, 0, ctx->next_pc); + gen_goto_tb(ctx, 0, ctx->pc_succ_insn); } static void gen_fcall_save_ctx(DisasContext *ctx) @@ -3306,7 +3307,7 @@ static void gen_fcall_save_ctx(DisasContext *ctx) tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4); tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL); - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); tcg_gen_mov_tl(cpu_gpr_a[10], temp); tcg_temp_free(temp); @@ -3321,7 +3322,7 @@ static void gen_fret(DisasContext *ctx) tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4); tcg_gen_mov_tl(cpu_PC, temp); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(temp); } @@ -3336,12 +3337,12 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, /* SB-format jumps */ case OPC1_16_SB_J: case OPC1_32_B_J: - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_32_B_CALL: case OPC1_16_SB_CALL: - gen_helper_1arg(call, ctx->next_pc); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_helper_1arg(call, ctx->pc_succ_insn); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_16_SB_JZ: gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset); @@ -3433,26 +3434,26 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, break; /* B-format */ case OPC1_32_B_CALLA: - gen_helper_1arg(call, ctx->next_pc); + gen_helper_1arg(call, ctx->pc_succ_insn); gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_FCALL: gen_fcall_save_ctx(ctx); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; case OPC1_32_B_FCALLA: gen_fcall_save_ctx(ctx); gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_JLA: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); /* fall through */ case OPC1_32_B_JA: gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); break; case OPC1_32_B_JL: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); break; /* BOL format */ case OPCM_32_BRC_EQ_NEQ: @@ -3551,7 +3552,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, gen_loop(ctx, r2, offset * 2); } else { /* OPC2_32_BRR_LOOPU */ - gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2); } break; case OPCM_32_BRR_JNE: @@ -3585,7 +3586,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; } @@ -3593,7 +3594,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, * Functions for decoding instructions */ -static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1) +static void decode_src_opc(DisasContext *ctx, int op1) { int r1; int32_t const4; @@ -3655,7 +3656,7 @@ static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1) tcg_gen_movi_tl(cpu_gpr_a[r1], const4); break; case OPC1_16_SRC_MOV_E: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { tcg_gen_movi_tl(cpu_gpr_d[r1], const4); tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31); } else { @@ -3919,7 +3920,7 @@ static void decode_sro_opc(DisasContext *ctx, int op1) } } -static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sr_system(DisasContext *ctx) { uint32_t op2; op2 = MASK_OP_SR_OP2(ctx->opcode); @@ -3933,7 +3934,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) case OPC2_16_SR_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; break; case OPC2_16_SR_DEBUG: /* raise EXCP_DEBUG */ @@ -3946,7 +3947,7 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sr_accu(DisasContext *ctx) { uint32_t op2; uint32_t r1; @@ -3990,7 +3991,7 @@ static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_16Bit_opc(DisasContext *ctx) { int op1; int r1, r2; @@ -4021,7 +4022,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_16_SRC_MOV_E: case OPC1_16_SRC_SH: case OPC1_16_SRC_SHA: - decode_src_opc(env, ctx, op1); + decode_src_opc(ctx, op1); break; /* SRR-format */ case OPC1_16_SRR_ADD: @@ -4106,7 +4107,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; case OPC1_16_SBC_JEQ2: case OPC1_16_SBC_JNE2: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { address = MASK_OP_SBC_DISP4(ctx->opcode); const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode); gen_compute_branch(ctx, op1, 0, 0, const16, address); @@ -4124,7 +4125,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) /* SBR-format */ case OPC1_16_SBR_JEQ2: case OPC1_16_SBR_JNE2: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { r1 = MASK_OP_SBR_S2(ctx->opcode); address = MASK_OP_SBR_DISP4(ctx->opcode); gen_compute_branch(ctx, op1, r1, 0, 0, address); @@ -4204,10 +4205,10 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* SR-format */ case OPCM_16_SR_SYSTEM: - decode_sr_system(env, ctx); + decode_sr_system(ctx); break; case OPCM_16_SR_ACCU: - decode_sr_accu(env, ctx); + decode_sr_accu(ctx); break; case OPC1_16_SR_JI: r1 = MASK_OP_SR_S1D(ctx->opcode); @@ -4227,7 +4228,7 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) */ /* ABS-format */ -static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldw(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4262,7 +4263,7 @@ static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldb(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4295,7 +4296,7 @@ static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldst_swap(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4322,7 +4323,7 @@ static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_ldst_context(DisasContext *ctx) { uint32_t op2; int32_t off18; @@ -4348,7 +4349,7 @@ static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_store(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4382,7 +4383,7 @@ static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_abs_storeb_h(DisasContext *ctx) { int32_t op2; int32_t r1; @@ -4410,7 +4411,7 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx) /* Bit-format */ -static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_andacc(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4451,7 +4452,7 @@ static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_logical_t(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4485,7 +4486,7 @@ static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4508,7 +4509,7 @@ static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_logical_t2(DisasContext *ctx) { uint32_t op2; @@ -4544,7 +4545,7 @@ static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_orand(DisasContext *ctx) { uint32_t op2; @@ -4585,7 +4586,7 @@ static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_sh_logic1(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4626,7 +4627,7 @@ static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx) +static void decode_bit_sh_logic2(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -4670,8 +4671,7 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx) /* BO-format */ -static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -4705,13 +4705,13 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, break; case OPC2_32_BO_CACHEI_WI_SHORTOFF: case OPC2_32_BO_CACHEI_W_SHORTOFF: - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC2_32_BO_CACHEI_W_POSTINC: case OPC2_32_BO_CACHEI_WI_POSTINC: - if (tricore_feature(env, TRICORE_FEATURE_131)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) { tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -4719,7 +4719,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, break; case OPC2_32_BO_CACHEI_W_PREINC: case OPC2_32_BO_CACHEI_WI_PREINC: - if (tricore_feature(env, TRICORE_FEATURE_131)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) { tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -4830,8 +4830,7 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, } } -static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -4941,8 +4940,7 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5076,8 +5074,7 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env, } } -static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5195,8 +5192,7 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5288,8 +5284,7 @@ static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env, tcg_temp_free(temp2); } -static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env, - DisasContext *ctx) +static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx) { uint32_t op2; uint32_t off10; @@ -5351,7 +5346,7 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env, tcg_temp_free(temp3); } -static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) +static void decode_bol_opc(DisasContext *ctx, int32_t op1) { int r1, r2; int32_t address; @@ -5378,7 +5373,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address); break; case OPC1_32_BOL_ST_A_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -5388,42 +5383,42 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL); break; case OPC1_32_BOL_LD_B_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_BU_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_H_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_LD_HU_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_ST_B_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_BOL_ST_H_LONGOFF: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -5435,7 +5430,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1) } /* RC format */ -static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_logical_shift(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5502,7 +5497,7 @@ static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_accumulator(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5702,7 +5697,7 @@ static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_serviceroutine(DisasContext *ctx) { uint32_t op2; uint32_t const9; @@ -5722,7 +5717,7 @@ static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rc_mul(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5760,7 +5755,7 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx) } /* RCPW format */ -static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcpw_insert(DisasContext *ctx) { uint32_t op2; int r1, r2; @@ -5799,7 +5794,7 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx) /* RCRW format */ -static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcrw_insert(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5844,7 +5839,7 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx) /* RCR format */ -static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_cond_select(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5888,7 +5883,7 @@ static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_madd(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -5943,7 +5938,7 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rcr_msub(DisasContext *ctx) { uint32_t op2; int r1, r3, r4; @@ -6000,7 +5995,7 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx) /* RLC format */ -static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, +static void decode_rlc_opc(DisasContext *ctx, uint32_t op1) { int32_t const16; @@ -6022,13 +6017,13 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, break; case OPC1_32_RLC_MFCR: const16 = MASK_OP_RLC_CONST16(ctx->opcode); - gen_mfcr(env, cpu_gpr_d[r2], const16); + gen_mfcr(ctx, cpu_gpr_d[r2], const16); break; case OPC1_32_RLC_MOV: tcg_gen_movi_tl(cpu_gpr_d[r2], const16); break; case OPC1_32_RLC_MOV_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { CHECK_REG_PAIR(r2); tcg_gen_movi_tl(cpu_gpr_d[r2], const16); tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15); @@ -6048,7 +6043,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, break; case OPC1_32_RLC_MTCR: const16 = MASK_OP_RLC_CONST16(ctx->opcode); - gen_mtcr(env, ctx, cpu_gpr_d[r1], const16); + gen_mtcr(ctx, cpu_gpr_d[r1], const16); break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); @@ -6056,7 +6051,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx, } /* RR format */ -static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_accumulator(DisasContext *ctx) { uint32_t op2; int r3, r2, r1; @@ -6254,7 +6249,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]); break; case OPC2_32_RR_MOV_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { temp = tcg_temp_new(); CHECK_REG_PAIR(r3); @@ -6268,7 +6263,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) } break; case OPC2_32_RR_MOVS_64: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { CHECK_REG_PAIR(r3); tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]); tcg_gen_sari_tl(cpu_gpr_d[r3 + 1], cpu_gpr_d[r2], 31); @@ -6398,7 +6393,7 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_logical_shift(DisasContext *ctx) { uint32_t op2; int r3, r2, r1; @@ -6476,7 +6471,7 @@ static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } -static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_address(DisasContext *ctx) { uint32_t op2, n; int r1, r2, r3; @@ -6544,7 +6539,7 @@ static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_idirect(DisasContext *ctx) { uint32_t op2; int r1; @@ -6557,11 +6552,11 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_JLI: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_CALLI: - gen_helper_1arg(call, ctx->next_pc); + gen_helper_1arg(call, ctx->pc_succ_insn); tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_FCALLI: @@ -6572,10 +6567,10 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx) generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; } -static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr_divide(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6597,7 +6592,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) break; case OPC2_32_RR_DVINIT_B: CHECK_REG_PAIR(r3); - gen_dvinit_b(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], + gen_dvinit_b(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); break; case OPC2_32_RR_DVINIT_BU: @@ -6608,7 +6603,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8); /* reset av */ tcg_gen_movi_tl(cpu_PSW_AV, 0); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */ tcg_gen_abs_tl(temp, temp3); tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]); @@ -6630,7 +6625,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) break; case OPC2_32_RR_DVINIT_H: CHECK_REG_PAIR(r3); - gen_dvinit_h(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], + gen_dvinit_h(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); break; case OPC2_32_RR_DVINIT_HU: @@ -6641,7 +6636,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16); /* reset av */ tcg_gen_movi_tl(cpu_PSW_AV, 0); - if (!tricore_feature(env, TRICORE_FEATURE_131)) { + if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) { /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */ tcg_gen_abs_tl(temp, temp3); tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]); @@ -6704,14 +6699,14 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; case OPC2_32_RR_CRC32: - if (tricore_feature(env, TRICORE_FEATURE_161)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_161)) { gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC2_32_RR_DIV: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6719,7 +6714,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) } break; case OPC2_32_RR_DIV_U: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6762,7 +6757,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx) } /* RR1 Format */ -static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr1_mul(DisasContext *ctx) { uint32_t op2; @@ -6876,7 +6871,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(n); } -static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr1_mulq(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6948,7 +6943,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx) } /* RR2 format */ -static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rr2_mul(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -6985,7 +6980,7 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx) } /* RRPW format */ -static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrpw_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3; @@ -7039,7 +7034,7 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* RRR format */ -static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr_cond_select(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -7085,7 +7080,7 @@ static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr_divide(DisasContext *ctx) { uint32_t op2; @@ -7165,7 +7160,7 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) } /* RRR2 format */ -static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr2_madd(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4; @@ -7217,7 +7212,7 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr2_msub(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4; @@ -7269,7 +7264,7 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx) } /* RRR1 format */ -static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_madd(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7415,7 +7410,7 @@ static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_maddq_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7434,19 +7429,19 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) switch (op2) { case OPC2_32_RRR1_MADD_Q_32: gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - cpu_gpr_d[r2], n, 32, env); + cpu_gpr_d[r2], n, 32); break; case OPC2_32_RRR1_MADD_Q_64: CHECK_REG_PAIR(r4); CHECK_REG_PAIR(r3); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_L: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MADD_Q_64_L: CHECK_REG_PAIR(r4); @@ -7454,12 +7449,12 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_U: tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MADD_Q_64_U: CHECK_REG_PAIR(r4); @@ -7467,7 +7462,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MADD_Q_32_LL: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]); @@ -7595,7 +7590,7 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp2); } -static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_maddsu_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7753,7 +7748,7 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msub(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7899,7 +7894,7 @@ static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msubq_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -7918,19 +7913,19 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) switch (op2) { case OPC2_32_RRR1_MSUB_Q_32: gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - cpu_gpr_d[r2], n, 32, env); + cpu_gpr_d[r2], n, 32); break; case OPC2_32_RRR1_MSUB_Q_64: CHECK_REG_PAIR(r4); CHECK_REG_PAIR(r3); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_L: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MSUB_Q_64_L: CHECK_REG_PAIR(r4); @@ -7938,12 +7933,12 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_U: tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1], - temp, n, 16, env); + temp, n, 16); break; case OPC2_32_RRR1_MSUB_Q_64_U: CHECK_REG_PAIR(r4); @@ -7951,7 +7946,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16); gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, - n, env); + n); break; case OPC2_32_RRR1_MSUB_Q_32_LL: tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]); @@ -8079,7 +8074,7 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp2); } -static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrr1_msubad_h(DisasContext *ctx) { uint32_t op2; uint32_t r1, r2, r3, r4, n; @@ -8238,7 +8233,7 @@ static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx) } /* RRRR format */ -static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrrr_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -8295,7 +8290,7 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* RRRW format */ -static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) +static void decode_rrrw_extract_insert(DisasContext *ctx) { uint32_t op2; int r1, r2, r3, r4; @@ -8356,7 +8351,7 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) } /* SYS Format*/ -static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) +static void decode_sys_interrupts(DisasContext *ctx) { uint32_t op2; uint32_t r1; @@ -8391,7 +8386,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) case OPC2_32_SYS_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; break; case OPC2_32_SYS_RFM: if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { @@ -8404,7 +8399,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) gen_helper_rfm(cpu_env); gen_set_label(l1); tcg_gen_exit_tb(NULL, 0); - ctx->bstate = BS_BRANCH; + ctx->base.is_jmp = DISAS_NORETURN; tcg_temp_free(tmp); } else { /* generate privilege trap */ @@ -8417,7 +8412,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) gen_helper_svlcx(cpu_env); break; case OPC2_32_SYS_RESTORE: - if (tricore_feature(env, TRICORE_FEATURE_16)) { + if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) { if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM || (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) { tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1); @@ -8443,7 +8438,7 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) +static void decode_32Bit_opc(DisasContext *ctx) { int op1; int32_t r1, r2, r3; @@ -8462,22 +8457,22 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) switch (op1) { /* ABS-format */ case OPCM_32_ABS_LDW: - decode_abs_ldw(env, ctx); + decode_abs_ldw(ctx); break; case OPCM_32_ABS_LDB: - decode_abs_ldb(env, ctx); + decode_abs_ldb(ctx); break; case OPCM_32_ABS_LDMST_SWAP: - decode_abs_ldst_swap(env, ctx); + decode_abs_ldst_swap(ctx); break; case OPCM_32_ABS_LDST_CONTEXT: - decode_abs_ldst_context(env, ctx); + decode_abs_ldst_context(ctx); break; case OPCM_32_ABS_STORE: - decode_abs_store(env, ctx); + decode_abs_store(ctx); break; case OPCM_32_ABS_STOREB_H: - decode_abs_storeb_h(env, ctx); + decode_abs_storeb_h(ctx); break; case OPC1_32_ABS_STOREQ: address = MASK_OP_ABS_OFF18(ctx->opcode); @@ -8537,44 +8532,44 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* Bit-format */ case OPCM_32_BIT_ANDACC: - decode_bit_andacc(env, ctx); + decode_bit_andacc(ctx); break; case OPCM_32_BIT_LOGICAL_T1: - decode_bit_logical_t(env, ctx); + decode_bit_logical_t(ctx); break; case OPCM_32_BIT_INSERT: - decode_bit_insert(env, ctx); + decode_bit_insert(ctx); break; case OPCM_32_BIT_LOGICAL_T2: - decode_bit_logical_t2(env, ctx); + decode_bit_logical_t2(ctx); break; case OPCM_32_BIT_ORAND: - decode_bit_orand(env, ctx); + decode_bit_orand(ctx); break; case OPCM_32_BIT_SH_LOGIC1: - decode_bit_sh_logic1(env, ctx); + decode_bit_sh_logic1(ctx); break; case OPCM_32_BIT_SH_LOGIC2: - decode_bit_sh_logic2(env, ctx); + decode_bit_sh_logic2(ctx); break; /* BO Format */ case OPCM_32_BO_ADDRMODE_POST_PRE_BASE: - decode_bo_addrmode_post_pre_base(env, ctx); + decode_bo_addrmode_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR: - decode_bo_addrmode_bitreverse_circular(env, ctx); + decode_bo_addrmode_bitreverse_circular(ctx); break; case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE: - decode_bo_addrmode_ld_post_pre_base(env, ctx); + decode_bo_addrmode_ld_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR: - decode_bo_addrmode_ld_bitreverse_circular(env, ctx); + decode_bo_addrmode_ld_bitreverse_circular(ctx); break; case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE: - decode_bo_addrmode_stctx_post_pre_base(env, ctx); + decode_bo_addrmode_stctx_post_pre_base(ctx); break; case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR: - decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx); + decode_bo_addrmode_ldmst_bitreverse_circular(ctx); break; /* BOL-format */ case OPC1_32_BOL_LD_A_LONGOFF: @@ -8588,7 +8583,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_32_BOL_LD_HU_LONGOFF: case OPC1_32_BOL_ST_B_LONGOFF: case OPC1_32_BOL_ST_H_LONGOFF: - decode_bol_opc(env, ctx, op1); + decode_bol_opc(ctx, op1); break; /* BRC Format */ case OPCM_32_BRC_EQ_NEQ: @@ -8621,20 +8616,20 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RC Format */ case OPCM_32_RC_LOGICAL_SHIFT: - decode_rc_logical_shift(env, ctx); + decode_rc_logical_shift(ctx); break; case OPCM_32_RC_ACCUMULATOR: - decode_rc_accumulator(env, ctx); + decode_rc_accumulator(ctx); break; case OPCM_32_RC_SERVICEROUTINE: - decode_rc_serviceroutine(env, ctx); + decode_rc_serviceroutine(ctx); break; case OPCM_32_RC_MUL: - decode_rc_mul(env, ctx); + decode_rc_mul(ctx); break; /* RCPW Format */ case OPCM_32_RCPW_MASK_INSERT: - decode_rcpw_insert(env, ctx); + decode_rcpw_insert(ctx); break; /* RCRR Format */ case OPC1_32_RCRR_INSERT: @@ -8659,17 +8654,17 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RCRW Format */ case OPCM_32_RCRW_MASK_INSERT: - decode_rcrw_insert(env, ctx); + decode_rcrw_insert(ctx); break; /* RCR Format */ case OPCM_32_RCR_COND_SELECT: - decode_rcr_cond_select(env, ctx); + decode_rcr_cond_select(ctx); break; case OPCM_32_RCR_MADD: - decode_rcr_madd(env, ctx); + decode_rcr_madd(ctx); break; case OPCM_32_RCR_MSUB: - decode_rcr_msub(env, ctx); + decode_rcr_msub(ctx); break; /* RLC Format */ case OPC1_32_RLC_ADDI: @@ -8682,38 +8677,38 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPC1_32_RLC_MOV_H: case OPC1_32_RLC_MOVH_A: case OPC1_32_RLC_MTCR: - decode_rlc_opc(env, ctx, op1); + decode_rlc_opc(ctx, op1); break; /* RR Format */ case OPCM_32_RR_ACCUMULATOR: - decode_rr_accumulator(env, ctx); + decode_rr_accumulator(ctx); break; case OPCM_32_RR_LOGICAL_SHIFT: - decode_rr_logical_shift(env, ctx); + decode_rr_logical_shift(ctx); break; case OPCM_32_RR_ADDRESS: - decode_rr_address(env, ctx); + decode_rr_address(ctx); break; case OPCM_32_RR_IDIRECT: - decode_rr_idirect(env, ctx); + decode_rr_idirect(ctx); break; case OPCM_32_RR_DIVIDE: - decode_rr_divide(env, ctx); + decode_rr_divide(ctx); break; /* RR1 Format */ case OPCM_32_RR1_MUL: - decode_rr1_mul(env, ctx); + decode_rr1_mul(ctx); break; case OPCM_32_RR1_MULQ: - decode_rr1_mulq(env, ctx); + decode_rr1_mulq(ctx); break; /* RR2 format */ case OPCM_32_RR2_MUL: - decode_rr2_mul(env, ctx); + decode_rr2_mul(ctx); break; /* RRPW format */ case OPCM_32_RRPW_EXTRACT_INSERT: - decode_rrpw_extract_insert(env, ctx); + decode_rrpw_extract_insert(ctx); break; case OPC1_32_RRPW_DEXTR: r1 = MASK_OP_RRPW_S1(ctx->opcode); @@ -8732,48 +8727,48 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; /* RRR Format */ case OPCM_32_RRR_COND_SELECT: - decode_rrr_cond_select(env, ctx); + decode_rrr_cond_select(ctx); break; case OPCM_32_RRR_DIVIDE: - decode_rrr_divide(env, ctx); + decode_rrr_divide(ctx); break; /* RRR2 Format */ case OPCM_32_RRR2_MADD: - decode_rrr2_madd(env, ctx); + decode_rrr2_madd(ctx); break; case OPCM_32_RRR2_MSUB: - decode_rrr2_msub(env, ctx); + decode_rrr2_msub(ctx); break; /* RRR1 format */ case OPCM_32_RRR1_MADD: - decode_rrr1_madd(env, ctx); + decode_rrr1_madd(ctx); break; case OPCM_32_RRR1_MADDQ_H: - decode_rrr1_maddq_h(env, ctx); + decode_rrr1_maddq_h(ctx); break; case OPCM_32_RRR1_MADDSU_H: - decode_rrr1_maddsu_h(env, ctx); + decode_rrr1_maddsu_h(ctx); break; case OPCM_32_RRR1_MSUB_H: - decode_rrr1_msub(env, ctx); + decode_rrr1_msub(ctx); break; case OPCM_32_RRR1_MSUB_Q: - decode_rrr1_msubq_h(env, ctx); + decode_rrr1_msubq_h(ctx); break; case OPCM_32_RRR1_MSUBAD_H: - decode_rrr1_msubad_h(env, ctx); + decode_rrr1_msubad_h(ctx); break; /* RRRR format */ case OPCM_32_RRRR_EXTRACT_INSERT: - decode_rrrr_extract_insert(env, ctx); + decode_rrrr_extract_insert(ctx); break; /* RRRW format */ case OPCM_32_RRRW_EXTRACT_INSERT: - decode_rrrw_extract_insert(env, ctx); + decode_rrrw_extract_insert(ctx); break; /* SYS format */ case OPCM_32_SYS_INTERRUPTS: - decode_sys_interrupts(env, ctx); + decode_sys_interrupts(ctx); break; case OPC1_32_SYS_RSTV: tcg_gen_movi_tl(cpu_PSW_V, 0); @@ -8786,70 +8781,130 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) } } -static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch) +static bool tricore_insn_is_16bit(uint32_t insn) { - /* 16-Bit Instruction */ - if ((ctx->opcode & 0x1) == 0) { - ctx->next_pc = ctx->pc + 2; - decode_16Bit_opc(env, ctx); - /* 32-Bit Instruction */ - } else { - ctx->next_pc = ctx->pc + 4; - decode_32Bit_opc(env, ctx); - } + return (insn & 0x1) == 0; } -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +static void tricore_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs) { + DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUTriCoreState *env = cs->env_ptr; - DisasContext ctx; - target_ulong pc_start; - int num_insns = 0; - - pc_start = tb->pc; - ctx.pc = pc_start; - ctx.saved_pc = -1; - ctx.tb = tb; - ctx.singlestep_enabled = cs->singlestep_enabled; - ctx.bstate = BS_NONE; - ctx.mem_idx = cpu_mmu_index(env, false); - ctx.hflags = (uint32_t)tb->flags; - - tcg_clear_temp_count(); - gen_tb_start(tb); - while (ctx.bstate == BS_NONE) { - tcg_gen_insn_start(ctx.pc); - num_insns++; - - ctx.opcode = cpu_ldl_code(env, ctx.pc); - decode_opc(env, &ctx, 0); - - if (num_insns >= max_insns || tcg_op_buf_full()) { - gen_save_pc(ctx.next_pc); - tcg_gen_exit_tb(NULL, 0); - break; - } - ctx.pc = ctx.next_pc; + ctx->mem_idx = cpu_mmu_index(env, false); + ctx->hflags = (uint32_t)ctx->base.tb->flags; +} + +static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu) +{ +} + +static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + tcg_gen_insn_start(ctx->base.pc_next); +} + +static bool tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, + const CPUBreakpoint *bp) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + generate_qemu_excp(ctx, EXCP_DEBUG); + /* + * The address covered by the breakpoint must be included in + * [tb->pc, tb->pc + tb->size) in order to for it to be + * properly cleared -- thus we increment the PC here so that + * the logic setting tb->size below does the right thing. + */ + ctx->base.pc_next += 4; + return true; +} + +static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx) +{ + /* + * Return true if the insn at ctx->base.pc_next might cross a page boundary. + * (False positives are OK, false negatives are not.) + * Our caller ensures we are only called if dc->base.pc_next is less than + * 4 bytes from the page boundary, so we cross the page if the first + * 16 bits indicate that this is a 32 bit insn. + */ + uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next); + + return !tricore_insn_is_16bit(insn); +} + + +static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + CPUTriCoreState *env = cpu->env_ptr; + uint16_t insn_lo; + bool is_16bit; + + insn_lo = cpu_lduw_code(env, ctx->base.pc_next); + is_16bit = tricore_insn_is_16bit(insn_lo); + if (is_16bit) { + ctx->opcode = insn_lo; + ctx->pc_succ_insn = ctx->base.pc_next + 2; + decode_16Bit_opc(ctx); + } else { + uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2); + ctx->opcode = insn_hi << 16 | insn_lo; + ctx->pc_succ_insn = ctx->base.pc_next + 4; + decode_32Bit_opc(ctx); } + ctx->base.pc_next = ctx->pc_succ_insn; - gen_tb_end(tb, num_insns); - tb->size = ctx.pc - pc_start; - tb->icount = num_insns; + if (ctx->base.is_jmp == DISAS_NEXT) { + target_ulong page_start; - if (tcg_check_temp_count()) { - printf("LEAK at %08x\n", env->PC); + page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE + || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3 + && insn_crosses_page(env, ctx))) { + ctx->base.is_jmp = DISAS_TOO_MANY; + } } +} -#ifdef DEBUG_DISAS - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) - && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); - qemu_log("IN: %s\n", lookup_symbol(pc_start)); - log_target_disas(cs, pc_start, ctx.pc - pc_start); - qemu_log("\n"); - qemu_log_unlock(); +static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + switch (ctx->base.is_jmp) { + case DISAS_TOO_MANY: + gen_goto_tb(ctx, 0, ctx->base.pc_next); + break; + case DISAS_NORETURN: + break; + default: + g_assert_not_reached(); } -#endif +} + +static void tricore_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) +{ + qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); + log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); +} + +static const TranslatorOps tricore_tr_ops = { + .init_disas_context = tricore_tr_init_disas_context, + .tb_start = tricore_tr_tb_start, + .insn_start = tricore_tr_insn_start, + .breakpoint_check = tricore_tr_breakpoint_check, + .translate_insn = tricore_tr_translate_insn, + .tb_stop = tricore_tr_tb_stop, + .disas_log = tricore_tr_disas_log, +}; + + +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +{ + DisasContext ctx; + translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns); } void diff --git a/target/unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h index bc68e78045..7dd04515cb 100644 --- a/target/unicore32/cpu-qom.h +++ b/target/unicore32/cpu-qom.h @@ -11,7 +11,7 @@ #ifndef QEMU_UC32_CPU_QOM_H #define QEMU_UC32_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_UNICORE32_CPU "unicore32-cpu" diff --git a/target/xtensa/cpu-qom.h b/target/xtensa/cpu-qom.h index 403bd95721..9ac54241bd 100644 --- a/target/xtensa/cpu-qom.h +++ b/target/xtensa/cpu-qom.h @@ -29,7 +29,7 @@ #ifndef QEMU_XTENSA_CPU_QOM_H #define QEMU_XTENSA_CPU_QOM_H -#include "qom/cpu.h" +#include "hw/core/cpu.h" #define TYPE_XTENSA_CPU "xtensa-cpu" diff --git a/tests/Makefile.include b/tests/Makefile.include index 6f02dfcc01..39bed753b3 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -149,6 +149,7 @@ check-block-$(call land,$(CONFIG_POSIX),$(CONFIG_SOFTMMU)) += tests/check-block. check-qtest-generic-y += tests/qmp-test$(EXESUF) check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF) +check-qtest-generic-$(CONFIG_MODULES) += tests/modules-test$(EXESUF) check-qtest-generic-y += tests/device-introspect-test$(EXESUF) check-qtest-generic-y += tests/cdrom-test$(EXESUF) diff --git a/tests/libqtest.c b/tests/libqtest.c index eb971d0d11..2713b86cf7 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -811,6 +811,12 @@ bool qtest_get_irq(QTestState *s, int num) return s->irq_level[num]; } +void qtest_module_load(QTestState *s, const char *prefix, const char *libname) +{ + qtest_sendf(s, "module_load %s %s\n", prefix, libname); + qtest_rsp(s, 0); +} + static int64_t qtest_clock_rsp(QTestState *s) { gchar **words; diff --git a/tests/libqtest.h b/tests/libqtest.h index 7833148358..07ea35867c 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -262,6 +262,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); +void qtest_module_load(QTestState *s, const char *prefix, const char *libname); + /** * qtest_get_irq: * @s: #QTestState instance to operate on. diff --git a/tests/modules-test.c b/tests/modules-test.c new file mode 100644 index 0000000000..3aef0e5a19 --- /dev/null +++ b/tests/modules-test.c @@ -0,0 +1,71 @@ +#include "qemu/osdep.h" +#include "libqtest.h" + +static void test_modules_load(const void *data) +{ + QTestState *qts; + const char **args = data; + + qts = qtest_init(NULL); + qtest_module_load(qts, args[0], args[1]); + qtest_quit(qts); +} + +int main(int argc, char *argv[]) +{ + const char *modules[] = { +#ifdef CONFIG_CURL + "block-", "curl", +#endif +#ifdef CONFIG_GLUSTERFS + "block-", "gluster", +#endif +#ifdef CONFIG_LIBISCSI + "block-", "iscsi", +#endif +#ifdef CONFIG_LIBNFS + "block-", "nfs", +#endif +#ifdef CONFIG_LIBSSH + "block-", "ssh", +#endif +#ifdef CONFIG_RBD + "block-", "rbd", +#endif +#ifdef CONFIG_AUDIO_ALSA + "audio-", "alsa", +#endif +#ifdef CONFIG_AUDIO_OSS + "audio-", "oss", +#endif +#ifdef CONFIG_AUDIO_PA + "audio-", "pa", +#endif +#ifdef CONFIG_AUDIO_SDL + "audio-", "sdl", +#endif +#ifdef CONFIG_CURSES + "ui-", "curses", +#endif +#if defined(CONFIG_GTK) && defined(CONFIG_VTE) + "ui-", "gtk", +#endif +#ifdef CONFIG_SDL + "ui-", "sdl", +#endif +#if defined(CONFIG_SPICE) && defined(CONFIG_GIO) + "ui-", "spice-app", +#endif + }; + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; i < G_N_ELEMENTS(modules); i += 2) { + char *testname = g_strdup_printf("/module/load/%s", modules[i + 1]); + qtest_add_data_func(testname, modules + i, test_modules_load); + g_free(testname); + } + + return g_test_run(); +} diff --git a/trace-events b/trace-events index aeea3c2bdb..823a4ae64e 100644 --- a/trace-events +++ b/trace-events @@ -129,7 +129,7 @@ vcpu guest_cpu_enter(void) # Targets: all vcpu guest_cpu_exit(void) -# qom/cpu.c +# hw/core/cpu.c # Reset the state of a virtual (guest) CPU # diff --git a/trace/control-vcpu.h b/trace/control-vcpu.h index a8f1035c2e..0f98ebe7b5 100644 --- a/trace/control-vcpu.h +++ b/trace/control-vcpu.h @@ -12,7 +12,7 @@ #include "control.h" #include "event-internal.h" -#include "qom/cpu.h" +#include "hw/core/cpu.h" /** * trace_event_get_vcpu_state: diff --git a/ui/cocoa.m b/ui/cocoa.m index f023d5166f..f12e21df6e 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -40,7 +40,7 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include <Carbon/Carbon.h> -#include "qom/cpu.h" +#include "hw/core/cpu.h" #ifndef MAC_OS_X_VERSION_10_5 #define MAC_OS_X_VERSION_10_5 1050 diff --git a/ui/curses.c b/ui/curses.c index a6e260eb96..ec281125ac 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -225,6 +225,8 @@ static wint_t console_getch(enum maybe_keycode *maybe_keycode) case ERR: ret = -1; break; + default: + abort(); } return ret; } diff --git a/ui/input-linux.c b/ui/input-linux.c index 59456fe765..a7b280b25b 100644 --- a/ui/input-linux.c +++ b/ui/input-linux.c @@ -113,6 +113,10 @@ static bool input_linux_check_toggle(InputLinux *il) return il->keydown[KEY_LEFTALT] && il->keydown[KEY_RIGHTALT]; + case GRAB_TOGGLE_KEYS_SHIFT_SHIFT: + return il->keydown[KEY_LEFTSHIFT] && + il->keydown[KEY_RIGHTSHIFT]; + case GRAB_TOGGLE_KEYS_META_META: return il->keydown[KEY_LEFTMETA] && il->keydown[KEY_RIGHTMETA]; diff --git a/util/module.c b/util/module.c index 142db7e911..e9fe3e5422 100644 --- a/util/module.c +++ b/util/module.c @@ -156,8 +156,10 @@ out: } #endif -void module_load_one(const char *prefix, const char *lib_name) +bool module_load_one(const char *prefix, const char *lib_name) { + bool success = false; + #ifdef CONFIG_MODULES char *fname = NULL; char *exec_dir; @@ -170,7 +172,7 @@ void module_load_one(const char *prefix, const char *lib_name) if (!g_module_supported()) { fprintf(stderr, "Module is not supported by system.\n"); - return; + return false; } if (!loaded_modules) { @@ -179,11 +181,10 @@ void module_load_one(const char *prefix, const char *lib_name) module_name = g_strdup_printf("%s%s", prefix, lib_name); - if (g_hash_table_lookup(loaded_modules, module_name)) { + if (!g_hash_table_add(loaded_modules, module_name)) { g_free(module_name); - return; + return true; } - g_hash_table_insert(loaded_modules, module_name, module_name); exec_dir = qemu_get_exec_dir(); search_dir = getenv("QEMU_MODULE_DIR"); @@ -206,13 +207,19 @@ void module_load_one(const char *prefix, const char *lib_name) fname = NULL; /* Try loading until loaded a module file */ if (!ret) { + success = true; break; } } + if (!success) { + g_hash_table_remove(loaded_modules, module_name); + } + for (i = 0; i < n_dirs; i++) { g_free(dirs[i]); } #endif + return success; } |