summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS17
-rw-r--r--Makefile.objs1
-rwxr-xr-xconfigure10
-rw-r--r--hw/display/cirrus_vga_rop.h2
-rw-r--r--hw/dma/rc4030.c162
-rw-r--r--hw/s390x/css.c15
-rw-r--r--target/arm/helper.c26
-rw-r--r--target/arm/translate.c26
-rw-r--r--target/mips/helper.c16
-rw-r--r--target/mips/trace-events5
-rw-r--r--target/mips/translate.c131
-rw-r--r--ui/console.c21
-rw-r--r--ui/vnc.c1
13 files changed, 223 insertions, 210 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index bf1aafb1c5..779c429059 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -600,15 +600,28 @@ S: Maintained
 F: hw/mips/mips_malta.c
 
 Mipssim
-L: qemu-devel@nongnu.org
-S: Orphan
+M: Yongbok Kim <yongbok.kim@imgtec.com>
+S: Odd Fixes
 F: hw/mips/mips_mipssim.c
+F: hw/net/mipsnet.c
 
 R4000
 M: Aurelien Jarno <aurelien@aurel32.net>
 S: Maintained
 F: hw/mips/mips_r4k.c
 
+Fulong 2E
+M: Yongbok Kim <yongbok.kim@imgtec.com>
+S: Odd Fixes
+F: hw/mips/mips_fulong2e.c
+
+Boston
+M: Paul Burton <paul.burton@imgtec.com>
+S: Maintained
+F: hw/core/loader-fit.c
+F: hw/mips/boston.c
+F: hw/pci-host/xilinx-pcie.c
+
 OpenRISC Machines
 -----------------
 or1k-sim
diff --git a/Makefile.objs b/Makefile.objs
index e740500e2d..6167e7b17d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -157,6 +157,7 @@ trace-events-subdirs += audio
 trace-events-subdirs += net
 trace-events-subdirs += target/arm
 trace-events-subdirs += target/i386
+trace-events-subdirs += target/mips
 trace-events-subdirs += target/sparc
 trace-events-subdirs += target/s390x
 trace-events-subdirs += target/ppc
diff --git a/configure b/configure
index b9a30cfd7b..1e0d7a8253 100755
--- a/configure
+++ b/configure
@@ -2888,6 +2888,12 @@ for drv in $audio_drv_list; do
     audio_pt_int="yes"
     ;;
 
+    sdl)
+    if test "$sdl" = "no"; then
+        error_exit "sdl not found or disabled, can not use sdl audio driver"
+    fi
+    ;;
+
     coreaudio)
       libs_softmmu="-framework CoreAudio $libs_softmmu"
     ;;
@@ -2901,8 +2907,8 @@ for drv in $audio_drv_list; do
       libs_softmmu="$oss_lib $libs_softmmu"
     ;;
 
-    sdl|wav)
-    # XXX: Probes for CoreAudio, DirectSound, SDL(?)
+    wav)
+    # XXX: Probes for CoreAudio, DirectSound
     ;;
 
     *)
diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h
index c61a677353..0841b9efa9 100644
--- a/hw/display/cirrus_vga_rop.h
+++ b/hw/display/cirrus_vga_rop.h
@@ -219,7 +219,7 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
     srcpitch += bltwidth;
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x+=2) {
-            ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
+            ROP_OP_TR_16(s, dstaddr - 1, cirrus_src16(s, srcaddr - 1), transp);
             dstaddr -= 2;
             srcaddr -= 2;
         }
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 17c8518fea..0080141905 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -34,8 +34,6 @@
 /********************************************************/
 /* rc4030 emulation                                     */
 
-#define MAX_TL_ENTRIES 512
-
 typedef struct dma_pagetable_entry {
     int32_t frame;
     int32_t owner;
@@ -91,14 +89,8 @@ typedef struct rc4030State
     qemu_irq timer_irq;
     qemu_irq jazz_bus_irq;
 
-    /* biggest translation table */
-    MemoryRegion dma_tt;
-    /* translation table memory region alias, added to system RAM */
-    MemoryRegion dma_tt_alias;
     /* whole DMA memory region, root of DMA address space */
     MemoryRegion dma_mr;
-    /* translation table entry aliases, added to DMA memory region */
-    MemoryRegion dma_mrs[MAX_TL_ENTRIES];
     AddressSpace dma_as;
 
     MemoryRegion iomem_chipset;
@@ -107,8 +99,8 @@ typedef struct rc4030State
 
 static void set_next_tick(rc4030State *s)
 {
-    qemu_irq_lower(s->timer_irq);
     uint32_t tm_hz;
+    qemu_irq_lower(s->timer_irq);
 
     tm_hz = 1000 / (s->itr + 1);
 
@@ -256,96 +248,6 @@ static uint64_t rc4030_read(void *opaque, hwaddr addr, unsigned int size)
     return val;
 }
 
-static void rc4030_dma_as_update_one(rc4030State *s, int index, uint32_t frame)
-{
-    if (index < MAX_TL_ENTRIES) {
-        memory_region_set_enabled(&s->dma_mrs[index], false);
-    }
-
-    if (!frame) {
-        return;
-    }
-
-    if (index >= MAX_TL_ENTRIES) {
-        qemu_log_mask(LOG_UNIMP,
-                      "rc4030: trying to use too high "
-                      "translation table entry %d (max allowed=%d)",
-                      index, MAX_TL_ENTRIES);
-        return;
-    }
-    memory_region_set_alias_offset(&s->dma_mrs[index], frame);
-    memory_region_set_enabled(&s->dma_mrs[index], true);
-}
-
-static void rc4030_dma_tt_write(void *opaque, hwaddr addr, uint64_t data,
-                                unsigned int size)
-{
-    rc4030State *s = opaque;
-
-    /* write memory */
-    memcpy(memory_region_get_ram_ptr(&s->dma_tt) + addr, &data, size);
-
-    /* update dma address space (only if frame field has been written) */
-    if (addr % sizeof(dma_pagetable_entry) == 0) {
-        int index = addr / sizeof(dma_pagetable_entry);
-        memory_region_transaction_begin();
-        rc4030_dma_as_update_one(s, index, (uint32_t)data);
-        memory_region_transaction_commit();
-    }
-}
-
-static const MemoryRegionOps rc4030_dma_tt_ops = {
-    .write = rc4030_dma_tt_write,
-    .impl.min_access_size = 4,
-    .impl.max_access_size = 4,
-};
-
-static void rc4030_dma_tt_update(rc4030State *s, uint32_t new_tl_base,
-                                 uint32_t new_tl_limit)
-{
-    int entries, i;
-    dma_pagetable_entry *dma_tl_contents;
-
-    if (s->dma_tl_limit) {
-        /* write old dma tl table to physical memory */
-        memory_region_del_subregion(get_system_memory(), &s->dma_tt_alias);
-        cpu_physical_memory_write(s->dma_tl_limit & 0x7fffffff,
-                                  memory_region_get_ram_ptr(&s->dma_tt),
-                                  memory_region_size(&s->dma_tt_alias));
-    }
-    object_unparent(OBJECT(&s->dma_tt_alias));
-
-    s->dma_tl_base = new_tl_base;
-    s->dma_tl_limit = new_tl_limit;
-    new_tl_base &= 0x7fffffff;
-
-    if (s->dma_tl_limit) {
-        uint64_t dma_tt_size;
-        if (s->dma_tl_limit <= memory_region_size(&s->dma_tt)) {
-            dma_tt_size = s->dma_tl_limit;
-        } else {
-            dma_tt_size = memory_region_size(&s->dma_tt);
-        }
-        memory_region_init_alias(&s->dma_tt_alias, OBJECT(s),
-                                 "dma-table-alias",
-                                 &s->dma_tt, 0, dma_tt_size);
-        dma_tl_contents = memory_region_get_ram_ptr(&s->dma_tt);
-        cpu_physical_memory_read(new_tl_base, dma_tl_contents, dma_tt_size);
-
-        memory_region_transaction_begin();
-        entries = dma_tt_size / sizeof(dma_pagetable_entry);
-        for (i = 0; i < entries; i++) {
-            rc4030_dma_as_update_one(s, i, dma_tl_contents[i].frame);
-        }
-        memory_region_add_subregion(get_system_memory(), new_tl_base,
-                                    &s->dma_tt_alias);
-        memory_region_transaction_commit();
-    } else {
-        memory_region_init(&s->dma_tt_alias, OBJECT(s),
-                           "dma-table-alias", 0);
-    }
-}
-
 static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
                          unsigned int size)
 {
@@ -362,11 +264,11 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
         break;
     /* DMA transl. table base */
     case 0x0018:
-        rc4030_dma_tt_update(s, val, s->dma_tl_limit);
+        s->dma_tl_base = val;
         break;
     /* DMA transl. table limit */
     case 0x0020:
-        rc4030_dma_tt_update(s, s->dma_tl_base, val);
+        s->dma_tl_limit = val;
         break;
     /* DMA transl. table invalidated */
     case 0x0028:
@@ -460,7 +362,7 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
         break;
     /* Interval timer reload */
     case 0x0228:
-        s->itr = val;
+        s->itr = val & 0x01FF;
         qemu_irq_lower(s->timer_irq);
         set_next_tick(s);
         break;
@@ -586,6 +488,38 @@ static const MemoryRegionOps jazzio_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static IOMMUTLBEntry rc4030_dma_translate(MemoryRegion *iommu, hwaddr addr,
+                                          bool is_write)
+{
+    rc4030State *s = container_of(iommu, rc4030State, dma_mr);
+    IOMMUTLBEntry ret = {
+        .target_as = &address_space_memory,
+        .iova = addr & ~(DMA_PAGESIZE - 1),
+        .translated_addr = 0,
+        .addr_mask = DMA_PAGESIZE - 1,
+        .perm = IOMMU_NONE,
+    };
+    uint64_t i, entry_address;
+    dma_pagetable_entry entry;
+
+    i = addr / DMA_PAGESIZE;
+    if (i < s->dma_tl_limit / sizeof(entry)) {
+        entry_address = (s->dma_tl_base & 0x7fffffff) + i * sizeof(entry);
+        if (address_space_read(ret.target_as, entry_address,
+                               MEMTXATTRS_UNSPECIFIED, (unsigned char *)&entry,
+                               sizeof(entry)) == MEMTX_OK) {
+            ret.translated_addr = entry.frame & ~(DMA_PAGESIZE - 1);
+            ret.perm = IOMMU_RW;
+        }
+    }
+
+    return ret;
+}
+
+static const MemoryRegionIOMMUOps rc4030_dma_ops = {
+    .translate = rc4030_dma_translate,
+};
+
 static void rc4030_reset(DeviceState *dev)
 {
     rc4030State *s = RC4030(dev);
@@ -596,7 +530,6 @@ static void rc4030_reset(DeviceState *dev)
     s->invalid_address_register = 0;
 
     memset(s->dma_regs, 0, sizeof(s->dma_regs));
-    rc4030_dma_tt_update(s, 0, 0);
 
     s->remote_failed_address = s->memory_failed_address = 0;
     s->cache_maint = 0;
@@ -735,7 +668,6 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
 {
     rc4030State *s = RC4030(dev);
     Object *o = OBJECT(dev);
-    int i;
 
     s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                      rc4030_periodic_timer, s);
@@ -745,37 +677,19 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s,
                           "rc4030.jazzio", 0x00001000);
 
-    memory_region_init_rom_device(&s->dma_tt, o,
-                                  &rc4030_dma_tt_ops, s, "dma-table",
-                                  MAX_TL_ENTRIES * sizeof(dma_pagetable_entry),
-                                  NULL);
-    memory_region_init(&s->dma_tt_alias, o, "dma-table-alias", 0);
-    memory_region_init(&s->dma_mr, o, "dma", INT32_MAX);
-    for (i = 0; i < MAX_TL_ENTRIES; ++i) {
-        memory_region_init_alias(&s->dma_mrs[i], o, "dma-alias",
-                                 get_system_memory(), 0, DMA_PAGESIZE);
-        memory_region_set_enabled(&s->dma_mrs[i], false);
-        memory_region_add_subregion(&s->dma_mr, i * DMA_PAGESIZE,
-                                    &s->dma_mrs[i]);
-    }
+    memory_region_init_iommu(&s->dma_mr, o, &rc4030_dma_ops,
+                             "rc4030.dma", UINT32_MAX);
     address_space_init(&s->dma_as, &s->dma_mr, "rc4030-dma");
 }
 
 static void rc4030_unrealize(DeviceState *dev, Error **errp)
 {
     rc4030State *s = RC4030(dev);
-    int i;
 
     timer_free(s->periodic_timer);
 
     address_space_destroy(&s->dma_as);
-    object_unparent(OBJECT(&s->dma_tt));
-    object_unparent(OBJECT(&s->dma_tt_alias));
     object_unparent(OBJECT(&s->dma_mr));
-    for (i = 0; i < MAX_TL_ENTRIES; ++i) {
-        memory_region_del_subregion(&s->dma_mr, &s->dma_mrs[i]);
-        object_unparent(OBJECT(&s->dma_mrs[i]));
-    }
 }
 
 static void rc4030_class_init(ObjectClass *klass, void *class_data)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index e32b2a4d42..37caa98195 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1675,12 +1675,27 @@ void subch_device_save(SubchDev *s, QEMUFile *f)
 
 int subch_device_load(SubchDev *s, QEMUFile *f)
 {
+    SubchDev *old_s;
+    uint16_t old_schid = s->schid;
     int i;
 
     s->cssid = qemu_get_byte(f);
     s->ssid = qemu_get_byte(f);
     s->schid = qemu_get_be16(f);
     s->devno = qemu_get_be16(f);
+    /* Re-assign subch. */
+    if (old_schid != s->schid) {
+        old_s = channel_subsys.css[s->cssid]->sch_set[s->ssid]->sch[old_schid];
+        /*
+         * (old_s != s) means that some other device has its correct
+         * subchannel already assigned (in load).
+         */
+        if (old_s == s) {
+            css_subch_assign(s->cssid, s->ssid, old_schid, s->devno, NULL);
+        }
+        /* It's OK to re-assign without a prior de-assign. */
+        css_subch_assign(s->cssid, s->ssid, s->schid, s->devno, s);
+    }
     s->thinint_active = qemu_get_byte(f);
     /* SCHIB */
     /*     PMCW */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8646a7a119..8cb7a9451c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8548,8 +8548,18 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
     }
 }
 
-void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
-{
+void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
+{
+    /* We're passed bits [11..0] of the instruction; extract
+     * SYSm and the mask bits.
+     * Invalid combinations of SYSm and mask are UNPREDICTABLE;
+     * we choose to treat them as if the mask bits were valid.
+     * NB that the pseudocode 'mask' variable is bits [11..10],
+     * whereas ours is [11..8].
+     */
+    uint32_t mask = extract32(maskreg, 8, 4);
+    uint32_t reg = extract32(maskreg, 0, 8);
+
     if (arm_current_el(env) == 0 && reg > 7) {
         /* only xPSR sub-fields may be written by unprivileged */
         return;
@@ -8558,8 +8568,16 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
     switch (reg) {
     case 0 ... 7: /* xPSR sub-fields */
         /* only APSR is actually writable */
-        if (reg & 4) {
-            xpsr_write(env, val, 0xf8000000); /* APSR */
+        if (!(reg & 4)) {
+            uint32_t apsrmask = 0;
+
+            if (mask & 8) {
+                apsrmask |= 0xf8000000; /* APSR NZCVQ */
+            }
+            if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
+                apsrmask |= 0x000f0000; /* APSR GE[3:0] */
+            }
+            xpsr_write(env, val, apsrmask);
         }
         break;
     case 8: /* MSP */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index b859f10755..e32e38cadd 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10377,6 +10377,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     goto illegal_op;
 
                 if (insn & (1 << 26)) {
+                    if (arm_dc_feature(s, ARM_FEATURE_M)) {
+                        goto illegal_op;
+                    }
                     if (!(insn & (1 << 20))) {
                         /* Hypervisor call (v7) */
                         int imm16 = extract32(insn, 16, 4) << 12
@@ -10400,7 +10403,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     case 0: /* msr cpsr.  */
                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
                             tmp = load_reg(s, rn);
-                            addr = tcg_const_i32(insn & 0xff);
+                            /* the constant is the mask and SYSm fields */
+                            addr = tcg_const_i32(insn & 0xfff);
                             gen_helper_v7m_msr(cpu_env, addr, tmp);
                             tcg_temp_free_i32(addr);
                             tcg_temp_free_i32(tmp);
@@ -10497,7 +10501,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         gen_exception_return(s, tmp);
                         break;
                     case 6: /* MRS */
-                        if (extract32(insn, 5, 1)) {
+                        if (extract32(insn, 5, 1) &&
+                            !arm_dc_feature(s, ARM_FEATURE_M)) {
                             /* MRS (banked) */
                             int sysm = extract32(insn, 16, 4) |
                                 (extract32(insn, 4, 1) << 4);
@@ -10506,6 +10511,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                             break;
                         }
 
+                        if (extract32(insn, 16, 4) != 0xf) {
+                            goto illegal_op;
+                        }
+                        if (!arm_dc_feature(s, ARM_FEATURE_M) &&
+                            extract32(insn, 0, 8) != 0) {
+                            goto illegal_op;
+                        }
+
                         /* mrs cpsr */
                         tmp = tcg_temp_new_i32();
                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
@@ -10518,7 +10531,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         store_reg(s, rd, tmp);
                         break;
                     case 7: /* MRS */
-                        if (extract32(insn, 5, 1)) {
+                        if (extract32(insn, 5, 1) &&
+                            !arm_dc_feature(s, ARM_FEATURE_M)) {
                             /* MRS (banked) */
                             int sysm = extract32(insn, 16, 4) |
                                 (extract32(insn, 4, 1) << 4);
@@ -10532,6 +10546,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
                             goto illegal_op;
                         }
+
+                        if (extract32(insn, 16, 4) != 0xf ||
+                            extract32(insn, 0, 8) != 0) {
+                            goto illegal_op;
+                        }
+
                         tmp = load_cpu_field(spsr);
                         store_reg(s, rd, tmp);
                         break;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index d2e77958fd..e359ca3b44 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -450,10 +450,18 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
     access_type = ACCESS_INT;
     ret = get_physical_address(env, &physical, &prot,
                                address, rw, access_type);
-    qemu_log_mask(CPU_LOG_MMU,
-             "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
-             " prot %d\n",
-             __func__, address, ret, physical, prot);
+    switch (ret) {
+    case TLBRET_MATCH:
+        qemu_log_mask(CPU_LOG_MMU,
+                      "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx
+                      " prot %d\n", __func__, address, physical, prot);
+        break;
+    default:
+        qemu_log_mask(CPU_LOG_MMU,
+                      "%s address=%" VADDR_PRIx " ret %d\n", __func__, address,
+                      ret);
+        break;
+    }
     if (ret == TLBRET_MATCH) {
         tlb_set_page(cs, address & TARGET_PAGE_MASK,
                      physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
diff --git a/target/mips/trace-events b/target/mips/trace-events
new file mode 100644
index 0000000000..43824089b3
--- /dev/null
+++ b/target/mips/trace-events
@@ -0,0 +1,5 @@
+# See docs/tracing.txt for syntax documentation.
+
+# target/mips/translate.c
+mips_translate_c0(const char *instr, const char *rn, int reg, int sel) "%s %s (reg %d sel %d)"
+mips_translate_tr(const char *instr, int rt, int u, int sel, int h) "%s (reg %d u %d sel %d h %d)"
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 8b4a072ecb..3022f349cb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -33,6 +33,7 @@
 #include "sysemu/kvm.h"
 #include "exec/semihost.h"
 
+#include "target/mips/trace.h"
 #include "trace-tcg.h"
 #include "exec/log.h"
 
@@ -4866,13 +4867,11 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
         goto cp0_unimplemented;
     }
-
-    (void)rn; /* avoid a compiler warning */
-    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    trace_mips_translate_c0("mfhc0", rn, reg, sel);
     return;
 
 cp0_unimplemented:
-    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
     tcg_gen_movi_tl(arg, 0);
 }
 
@@ -4941,10 +4940,10 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
         goto cp0_unimplemented;
     }
+    trace_mips_translate_c0("mthc0", rn, reg, sel);
 
-    (void)rn; /* avoid a compiler warning */
 cp0_unimplemented:
-    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
 }
 
 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
@@ -5137,7 +5136,6 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
             rn = "ContextConfig";
             goto cp0_unimplemented;
-//            break;
         case 2:
             CP0_CHECK(ctx->ulri);
             tcg_gen_ld32s_tl(arg, cpu_env,
@@ -5459,19 +5457,19 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
             rn = "TraceControl";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
             rn = "TraceControl2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
             rn = "UserTraceData";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
             rn = "TraceBPC";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -5497,31 +5495,31 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_mfc0_performance1(arg);
             rn = "Performance1";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mfc0_performance2(arg);
             rn = "Performance2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_mfc0_performance3(arg);
             rn = "Performance3";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mfc0_performance4(arg);
             rn = "Performance4";
-//            break;
+            goto cp0_unimplemented;
         case 5:
 //            gen_helper_mfc0_performance5(arg);
             rn = "Performance5";
-//            break;
+            goto cp0_unimplemented;
         case 6:
 //            gen_helper_mfc0_performance6(arg);
             rn = "Performance6";
-//            break;
+            goto cp0_unimplemented;
         case 7:
 //            gen_helper_mfc0_performance7(arg);
             rn = "Performance7";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -5623,12 +5621,11 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
        goto cp0_unimplemented;
     }
-    (void)rn; /* avoid a compiler warning */
-    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    trace_mips_translate_c0("mfc0", rn, reg, sel);
     return;
 
 cp0_unimplemented:
-    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
     gen_mfc0_unimplemented(ctx, arg);
 }
 
@@ -5791,7 +5788,6 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
             rn = "ContextConfig";
             goto cp0_unimplemented;
-//            break;
         case 2:
             CP0_CHECK(ctx->ulri);
             tcg_gen_st_tl(arg, cpu_env,
@@ -6118,13 +6114,13 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             rn = "TraceControl";
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
             rn = "TraceControl2";
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
-//            break;
+            goto cp0_unimplemented;
         case 3:
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
@@ -6132,13 +6128,13 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             rn = "UserTraceData";
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "TraceBPC";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -6163,31 +6159,31 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_mtc0_performance1(arg);
             rn = "Performance1";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mtc0_performance2(arg);
             rn = "Performance2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_mtc0_performance3(arg);
             rn = "Performance3";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mtc0_performance4(arg);
             rn = "Performance4";
-//            break;
+            goto cp0_unimplemented;
         case 5:
 //            gen_helper_mtc0_performance5(arg);
             rn = "Performance5";
-//            break;
+            goto cp0_unimplemented;
         case 6:
 //            gen_helper_mtc0_performance6(arg);
             rn = "Performance6";
-//            break;
+            goto cp0_unimplemented;
         case 7:
 //            gen_helper_mtc0_performance7(arg);
             rn = "Performance7";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -6286,8 +6282,8 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
        goto cp0_unimplemented;
     }
-    (void)rn; /* avoid a compiler warning */
-    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    trace_mips_translate_c0("mtc0", rn, reg, sel);
+
     /* For simplicity assume that all writes can cause interrupts.  */
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
@@ -6296,7 +6292,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     return;
 
 cp0_unimplemented:
-    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
 }
 
 #if defined(TARGET_MIPS64)
@@ -6454,7 +6450,6 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
             rn = "ContextConfig";
             goto cp0_unimplemented;
-//            break;
         case 2:
             CP0_CHECK(ctx->ulri);
             tcg_gen_ld_tl(arg, cpu_env,
@@ -6769,19 +6764,19 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
             rn = "TraceControl";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
             rn = "TraceControl2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
             rn = "UserTraceData";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
             rn = "TraceBPC";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -6806,31 +6801,31 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_dmfc0_performance1(arg);
             rn = "Performance1";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_dmfc0_performance2(arg);
             rn = "Performance2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_dmfc0_performance3(arg);
             rn = "Performance3";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_dmfc0_performance4(arg);
             rn = "Performance4";
-//            break;
+            goto cp0_unimplemented;
         case 5:
 //            gen_helper_dmfc0_performance5(arg);
             rn = "Performance5";
-//            break;
+            goto cp0_unimplemented;
         case 6:
 //            gen_helper_dmfc0_performance6(arg);
             rn = "Performance6";
-//            break;
+            goto cp0_unimplemented;
         case 7:
 //            gen_helper_dmfc0_performance7(arg);
             rn = "Performance7";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -6926,12 +6921,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
         goto cp0_unimplemented;
     }
-    (void)rn; /* avoid a compiler warning */
-    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    trace_mips_translate_c0("dmfc0", rn, reg, sel);
     return;
 
 cp0_unimplemented:
-    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
     gen_mfc0_unimplemented(ctx, arg);
 }
 
@@ -7092,7 +7086,6 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
             rn = "ContextConfig";
             goto cp0_unimplemented;
-//           break;
         case 2:
             CP0_CHECK(ctx->ulri);
             tcg_gen_st_tl(arg, cpu_env,
@@ -7421,25 +7414,25 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "TraceControl";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "TraceControl2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "UserTraceData";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
             /* Stop translation as we may have switched the execution mode */
             ctx->bstate = BS_STOP;
             rn = "TraceBPC";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -7464,31 +7457,31 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 1:
 //            gen_helper_mtc0_performance1(cpu_env, arg);
             rn = "Performance1";
-//            break;
+            goto cp0_unimplemented;
         case 2:
 //            gen_helper_mtc0_performance2(cpu_env, arg);
             rn = "Performance2";
-//            break;
+            goto cp0_unimplemented;
         case 3:
 //            gen_helper_mtc0_performance3(cpu_env, arg);
             rn = "Performance3";
-//            break;
+            goto cp0_unimplemented;
         case 4:
 //            gen_helper_mtc0_performance4(cpu_env, arg);
             rn = "Performance4";
-//            break;
+            goto cp0_unimplemented;
         case 5:
 //            gen_helper_mtc0_performance5(cpu_env, arg);
             rn = "Performance5";
-//            break;
+            goto cp0_unimplemented;
         case 6:
 //            gen_helper_mtc0_performance6(cpu_env, arg);
             rn = "Performance6";
-//            break;
+            goto cp0_unimplemented;
         case 7:
 //            gen_helper_mtc0_performance7(cpu_env, arg);
             rn = "Performance7";
-//            break;
+            goto cp0_unimplemented;
         default:
             goto cp0_unimplemented;
         }
@@ -7587,8 +7580,8 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     default:
         goto cp0_unimplemented;
     }
-    (void)rn; /* avoid a compiler warning */
-    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    trace_mips_translate_c0("dmtc0", rn, reg, sel);
+
     /* For simplicity assume that all writes can cause interrupts.  */
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
@@ -7597,7 +7590,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     return;
 
 cp0_unimplemented:
-    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
 }
 #endif /* TARGET_MIPS64 */
 
@@ -7807,7 +7800,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
     default:
         goto die;
     }
-    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
+    trace_mips_translate_tr("mftr", rt, u, sel, h);
     gen_store_gpr(t0, rd);
     tcg_temp_free(t0);
     return;
@@ -8012,7 +8005,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
     default:
         goto die;
     }
-    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
+    trace_mips_translate_tr("mttr", rd, u, sel, h);
     tcg_temp_free(t0);
     return;
 
@@ -18169,7 +18162,7 @@ static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
 
     check_msa_access(ctx);
 
-    if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
+    if (ctx->hflags & MIPS_HFLAG_BMASK) {
         generate_exception_end(ctx, EXCP_RI);
         return;
     }
diff --git a/ui/console.c b/ui/console.c
index 4c70d8bfda..937c950840 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1575,13 +1575,32 @@ bool dpy_gfx_check_format(QemuConsole *con,
     return true;
 }
 
+/*
+ * Safe DPY refresh for TCG guests. This runs when the TCG vCPUs are
+ * quiescent so we can avoid races between dirty page tracking for
+ * direct frame-buffer access by the guest.
+ *
+ * This is a temporary stopgap until we've fixed the dirty tracking
+ * races in display adapters.
+ */
+static void do_safe_dpy_refresh(CPUState *cpu, run_on_cpu_data opaque)
+{
+    DisplayChangeListener *dcl = opaque.host_ptr;
+    dcl->ops->dpy_refresh(dcl);
+}
+
 static void dpy_refresh(DisplayState *s)
 {
     DisplayChangeListener *dcl;
 
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (dcl->ops->dpy_refresh) {
-            dcl->ops->dpy_refresh(dcl);
+            if (tcg_enabled()) {
+                async_safe_run_on_cpu(first_cpu, do_safe_dpy_refresh,
+                                      RUN_ON_CPU_HOST_PTR(dcl));
+            } else {
+                dcl->ops->dpy_refresh(dcl);
+            }
         }
     }
 }
diff --git a/ui/vnc.c b/ui/vnc.c
index 8bfb1e0685..6e93b883b5 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3677,6 +3677,7 @@ static int vnc_display_listen_addr(VncDisplay *vd,
         qio_channel_set_name(QIO_CHANNEL(sioc), name);
         if (qio_channel_socket_listen_sync(
                 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
+            object_unref(OBJECT(sioc));
             continue;
         }
         listening = true;