diff options
| -rw-r--r-- | .travis.yml | 8 | ||||
| -rwxr-xr-x | configure | 2 | ||||
| -rw-r--r-- | cpus-common.c | 10 | ||||
| -rw-r--r-- | hw/display/cg3.c | 14 | ||||
| -rw-r--r-- | hw/display/cirrus_vga.c | 119 | ||||
| -rw-r--r-- | hw/display/dpcd.c | 20 | ||||
| -rw-r--r-- | hw/display/exynos4210_fimd.c | 46 | ||||
| -rw-r--r-- | hw/display/omap_dss.c | 2 | ||||
| -rw-r--r-- | hw/display/pxa2xx_lcd.c | 26 | ||||
| -rw-r--r-- | hw/display/sm501.c | 311 | ||||
| -rw-r--r-- | hw/display/trace-events | 10 | ||||
| -rw-r--r-- | hw/display/vmware_vga.c | 18 | ||||
| -rw-r--r-- | hw/display/xlnx_dp.c | 14 | ||||
| -rw-r--r-- | include/hw/display/edid.h | 1 | ||||
| -rw-r--r-- | linux-user/syscall.c | 19 | ||||
| -rw-r--r-- | tests/Makefile.include | 44 | ||||
| -rw-r--r-- | tests/docker/Makefile.include | 4 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/debian-arm64-test-cross.docker | 13 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/debian11.docker | 18 | ||||
| -rw-r--r-- | tests/tcg/aarch64/Makefile.softmmu-target | 2 | ||||
| -rwxr-xr-x | tests/tcg/configure.sh | 4 | ||||
| -rw-r--r-- | tests/tcg/multiarch/Makefile.target | 2 | ||||
| -rw-r--r-- | tests/tcg/multiarch/gdbstub/sha1.py | 4 | ||||
| -rw-r--r-- | tests/tcg/multiarch/threadcount.c | 64 | ||||
| -rw-r--r-- | tests/vm/Makefile.include | 1 | ||||
| -rw-r--r-- | tests/vm/basevm.py | 16 |
26 files changed, 472 insertions, 320 deletions
diff --git a/.travis.yml b/.travis.yml index 1ec8a7b465..564be50a3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -205,14 +205,15 @@ jobs: # Test with Clang for compile portability (Travis uses clang-5.0) - name: "Clang (user)" env: - - CONFIG="--disable-system" + - CONFIG="--disable-system --host-cc=clang --cxx=clang++" - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-default" compiler: clang - name: "Clang (main-softmmu)" env: - - CONFIG="--target-list=${MAIN_SOFTMMU_TARGETS} " + - CONFIG="--target-list=${MAIN_SOFTMMU_TARGETS} + --host-cc=clang --cxx=clang++" - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-sanitize" compiler: clang before_script: @@ -222,7 +223,8 @@ jobs: - name: "Clang (other-softmmu)" env: - - CONFIG="--disable-user --target-list-exclude=${MAIN_SOFTMMU_TARGETS}" + - CONFIG="--disable-user --target-list-exclude=${MAIN_SOFTMMU_TARGETS} + --host-cc=clang --cxx=clang++" - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-default" compiler: clang diff --git a/configure b/configure index b969dee675..af2ba83f0e 100755 --- a/configure +++ b/configure @@ -941,7 +941,7 @@ done # Check for ancillary tools used in testing genisoimage= -for binary in genisoimage +for binary in genisoimage mkisofs do if has $binary then diff --git a/cpus-common.c b/cpus-common.c index 55d5df8923..70a9d12981 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -61,13 +61,15 @@ static bool cpu_index_auto_assigned; static int cpu_get_free_index(void) { CPUState *some_cpu; - int cpu_index = 0; + int max_cpu_index = 0; cpu_index_auto_assigned = true; CPU_FOREACH(some_cpu) { - cpu_index++; + if (some_cpu->cpu_index >= max_cpu_index) { + max_cpu_index = some_cpu->cpu_index + 1; + } } - return cpu_index; + return max_cpu_index; } void cpu_list_add(CPUState *cpu) @@ -90,8 +92,6 @@ void cpu_list_remove(CPUState *cpu) return; } - assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus))); - QTAILQ_REMOVE_RCU(&cpus, cpu, node); cpu->cpu_index = UNASSIGNED_CPU_INDEX; } diff --git a/hw/display/cg3.c b/hw/display/cg3.c index f7f1c199ce..7cbe6e56ff 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -35,6 +35,7 @@ #include "hw/qdev-properties.h" #include "qemu/log.h" #include "qemu/module.h" +#include "trace.h" /* Change to 1 to enable debugging */ #define DEBUG_CG3 0 @@ -63,12 +64,6 @@ #define CG3_VRAM_SIZE 0x100000 #define CG3_VRAM_OFFSET 0x800000 -#define DPRINTF(fmt, ...) do { \ - if (DEBUG_CG3) { \ - printf("CG3: " fmt , ## __VA_ARGS__); \ - } \ -} while (0) - #define TYPE_CG3 "cgthree" #define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3) @@ -195,7 +190,8 @@ static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size) val = 0; break; } - DPRINTF("read %02x from reg %" HWADDR_PRIx "\n", val, addr); + trace_cg3_read(addr, val, size); + return val; } @@ -206,9 +202,7 @@ static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val, uint8_t regval; int i; - DPRINTF("write %" PRIx64 " to reg %" HWADDR_PRIx " size %d\n", - val, addr, size); - + trace_cg3_write(addr, val, size); switch (addr) { case CG3_REG_BT458_ADDR: s->dac_index = val; diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 1f29731ffe..92c197cdde 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -35,6 +35,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/units.h" +#include "qemu/log.h" #include "sysemu/reset.h" #include "qapi/error.h" #include "trace.h" @@ -52,7 +53,6 @@ */ //#define DEBUG_CIRRUS -//#define DEBUG_BITBLT /*************************************** * @@ -905,9 +905,8 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) static int cirrus_bitblt_videotocpu(CirrusVGAState * s) { /* XXX */ -#ifdef DEBUG_BITBLT - printf("cirrus: bitblt (video to cpu) is not implemented yet\n"); -#endif + qemu_log_mask(LOG_UNIMP, + "cirrus: bitblt (video to cpu) is not implemented\n"); return 0; } @@ -950,19 +949,16 @@ static void cirrus_bitblt_start(CirrusVGAState * s) s->cirrus_blt_dstaddr &= s->cirrus_addr_mask; s->cirrus_blt_srcaddr &= s->cirrus_addr_mask; -#ifdef DEBUG_BITBLT - printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n", - blt_rop, - s->cirrus_blt_mode, - s->cirrus_blt_modeext, - s->cirrus_blt_width, - s->cirrus_blt_height, - s->cirrus_blt_dstpitch, - s->cirrus_blt_srcpitch, - s->cirrus_blt_dstaddr, - s->cirrus_blt_srcaddr, - s->vga.gr[0x2f]); -#endif + trace_vga_cirrus_bitblt_start(blt_rop, + s->cirrus_blt_mode, + s->cirrus_blt_modeext, + s->cirrus_blt_width, + s->cirrus_blt_height, + s->cirrus_blt_dstpitch, + s->cirrus_blt_srcpitch, + s->cirrus_blt_dstaddr, + s->cirrus_blt_srcaddr, + s->vga.gr[0x2f]); switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: @@ -978,9 +974,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) s->cirrus_blt_pixelwidth = 4; break; default: -#ifdef DEBUG_BITBLT - printf("cirrus: bitblt - pixel width is unknown\n"); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: bitblt - pixel width is unknown\n"); goto bitblt_ignore; } s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK; @@ -989,9 +984,8 @@ static void cirrus_bitblt_start(CirrusVGAState * s) cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { -#ifdef DEBUG_BITBLT - printf("cirrus: bitblt - memory-to-memory copy is requested\n"); -#endif + qemu_log_mask(LOG_UNIMP, + "cirrus: bitblt - memory-to-memory copy requested\n"); goto bitblt_ignore; } @@ -1038,7 +1032,9 @@ static void cirrus_bitblt_start(CirrusVGAState * s) } else { if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { if (s->cirrus_blt_pixelwidth > 2) { - printf("src transparent without colorexpand must be 8bpp or 16bpp\n"); + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: src transparent without colorexpand " + "must be 8bpp or 16bpp\n"); goto bitblt_ignore; } if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { @@ -1136,10 +1132,9 @@ static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s) ret = 16; break; /* XGA HiColor */ default: -#ifdef DEBUG_CIRRUS - printf("cirrus: invalid DAC value %x in 16bpp\n", - (s->cirrus_hidden_dac_data & 0xf)); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: invalid DAC value 0x%x in 16bpp\n", + (s->cirrus_hidden_dac_data & 0xf)); ret = 15; /* XXX */ break; } @@ -1308,11 +1303,9 @@ static int cirrus_vga_read_sr(CirrusVGAState * s) #endif return s->vga.sr[s->vga.sr_index]; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: inport sr_index %02x\n", s->vga.sr_index); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: inport sr_index 0x%02x\n", s->vga.sr_index); return 0xff; - break; } } @@ -1401,10 +1394,9 @@ static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val) cirrus_update_memory_access(s); break; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: outport sr_index %02x, sr_value %02x\n", - s->vga.sr_index, val); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: outport sr_index 0x%02x, sr_value 0x%02x\n", + s->vga.sr_index, val); break; } } @@ -1502,9 +1494,8 @@ static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index) if (reg_index < 0x3a) { return s->vga.gr[reg_index]; } else { -#ifdef DEBUG_CIRRUS - printf("cirrus: inport gr_index %02x\n", reg_index); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: inport gr_index 0x%02x\n", reg_index); return 0xff; } } @@ -1512,9 +1503,7 @@ static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index) static void cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) { -#if defined(DEBUG_BITBLT) && 0 - printf("gr%02x: %02x\n", reg_index, reg_value); -#endif + trace_vga_cirrus_write_gr(reg_index, reg_value); switch (reg_index) { case 0x00: // Standard VGA, BGCOLOR 0x000000ff s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; @@ -1593,10 +1582,9 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) cirrus_write_bitblt(s, reg_value); break; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index, - reg_value); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: outport gr_index 0x%02x, gr_value 0x%02x\n", + reg_index, reg_value); break; } } @@ -1651,9 +1639,8 @@ static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index) return s->vga.ar_index & 0x3f; break; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: inport cr_index %02x\n", reg_index); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: inport cr_index 0x%02x\n", reg_index); return 0xff; } } @@ -1724,10 +1711,9 @@ static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value) break; case 0x25: // Part Status default: -#ifdef DEBUG_CIRRUS - printf("cirrus: outport cr_index %02x, cr_value %02x\n", - s->vga.cr_index, reg_value); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: outport cr_index 0x%02x, cr_value 0x%02x\n", + s->vga.cr_index, reg_value); break; } } @@ -1837,9 +1823,8 @@ static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address) value = cirrus_vga_read_gr(s, 0x31); break; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: mmio read - address 0x%04x\n", address); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: mmio read - address 0x%04x\n", address); break; } @@ -1949,10 +1934,9 @@ static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, cirrus_vga_write_gr(s, 0x31, value); break; default: -#ifdef DEBUG_CIRRUS - printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", - address, value); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", + address, value); break; } } @@ -2050,9 +2034,8 @@ static uint64_t cirrus_vga_mem_read(void *opaque, } } else { val = 0xff; -#ifdef DEBUG_CIRRUS - printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: mem_readb 0x" TARGET_FMT_plx "\n", addr); } return val; } @@ -2115,10 +2098,9 @@ static void cirrus_vga_mem_write(void *opaque, cirrus_mmio_blt_write(s, addr & 0xff, mem_value); } } else { -#ifdef DEBUG_CIRRUS - printf("cirrus: mem_writeb " TARGET_FMT_plx " value 0x%02" PRIu64 "\n", addr, - mem_value); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "cirrus: mem_writeb 0x" TARGET_FMT_plx " " + "value 0x%02" PRIu64 "\n", addr, mem_value); } } @@ -2414,6 +2396,9 @@ static uint64_t cirrus_linear_bitblt_read(void *opaque, /* XXX handle bitblt */ (void)s; + qemu_log_mask(LOG_UNIMP, + "cirrus: linear bitblt is not implemented\n"); + return 0xff; } diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c index 170545c605..64463654a1 100644 --- a/hw/display/dpcd.c +++ b/hw/display/dpcd.c @@ -1,5 +1,5 @@ /* - * dpcd.c + * Xilinx Display Port Control Data * * Copyright (C) 2015 : GreenSocs Ltd * http://www.greensocs.com/ , email: info@greensocs.com @@ -32,16 +32,7 @@ #include "hw/misc/auxbus.h" #include "migration/vmstate.h" #include "hw/display/dpcd.h" - -#ifndef DEBUG_DPCD -#define DEBUG_DPCD 0 -#endif - -#define DPRINTF(fmt, ...) do { \ - if (DEBUG_DPCD) { \ - qemu_log("dpcd: " fmt, ## __VA_ARGS__); \ - } \ -} while (0) +#include "trace.h" #define DPCD_READABLE_AREA 0x600 @@ -70,8 +61,8 @@ static uint64_t dpcd_read(void *opaque, hwaddr offset, unsigned size) offset); ret = 0; } + trace_dpcd_read(offset, ret); - DPRINTF("read 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", ret, offset); return ret; } @@ -80,8 +71,7 @@ static void dpcd_write(void *opaque, hwaddr offset, uint64_t value, { DPCDState *e = DPCD(opaque); - DPRINTF("write 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", (uint8_t)value, offset); - + trace_dpcd_write(offset, value); if (offset < DPCD_READABLE_AREA) { e->dpcd_info[offset] = value; } else { @@ -137,7 +127,7 @@ static void dpcd_init(Object *obj) { DPCDState *s = DPCD(obj); - memory_region_init_io(&s->iomem, obj, &aux_ops, s, TYPE_DPCD, 0x7FFFF); + memory_region_init_io(&s->iomem, obj, &aux_ops, s, TYPE_DPCD, 0x80000); aux_init_mmio(AUX_SLAVE(obj), &s->iomem); } diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index 1c0266ce9f..4b7286b7c9 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -31,6 +31,7 @@ #include "ui/pixel_ops.h" #include "qemu/bswap.h" #include "qemu/module.h" +#include "qemu/log.h" /* Debug messages configuration */ #define EXYNOS4210_FIMD_DEBUG 0 @@ -39,20 +40,15 @@ #if EXYNOS4210_FIMD_DEBUG == 0 #define DPRINT_L1(fmt, args...) do { } while (0) #define DPRINT_L2(fmt, args...) do { } while (0) - #define DPRINT_ERROR(fmt, args...) do { } while (0) #elif EXYNOS4210_FIMD_DEBUG == 1 #define DPRINT_L1(fmt, args...) \ do {fprintf(stderr, "QEMU FIMD: "fmt, ## args); } while (0) #define DPRINT_L2(fmt, args...) do { } while (0) - #define DPRINT_ERROR(fmt, args...) \ - do {fprintf(stderr, "QEMU FIMD ERROR: "fmt, ## args); } while (0) #else #define DPRINT_L1(fmt, args...) \ do {fprintf(stderr, "QEMU FIMD: "fmt, ## args); } while (0) #define DPRINT_L2(fmt, args...) \ do {fprintf(stderr, "QEMU FIMD: "fmt, ## args); } while (0) - #define DPRINT_ERROR(fmt, args...) \ - do {fprintf(stderr, "QEMU FIMD ERROR: "fmt, ## args); } while (0) #endif #if EXYNOS4210_FIMD_MODE_TRACE == 0 @@ -1108,7 +1104,7 @@ static inline int fimd_get_buffer_id(Exynos4210fimdWindow *w) case FIMD_WINCON_BUF2_STAT: return 2; default: - DPRINT_ERROR("Non-existent buffer index\n"); + qemu_log_mask(LOG_GUEST_ERROR, "FIMD: Non-existent buffer index\n"); return 0; } } @@ -1160,20 +1156,24 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) if (int128_get64(w->mem_section.size) != w->fb_len || !memory_region_is_ram(w->mem_section.mr)) { - DPRINT_ERROR("Failed to find window %u framebuffer region\n", win); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: Failed to find window %u framebuffer region\n", + win); goto error_return; } w->host_fb_addr = cpu_physical_memory_map(fb_start_addr, &fb_mapped_len, false); if (!w->host_fb_addr) { - DPRINT_ERROR("Failed to map window %u framebuffer\n", win); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: Failed to map window %u framebuffer\n", win); goto error_return; } if (fb_mapped_len != w->fb_len) { - DPRINT_ERROR("Window %u mapped framebuffer length is less then " - "expected\n", win); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: Window %u mapped framebuffer length is less than " + "expected\n", win); cpu_physical_memory_unmap(w->host_fb_addr, fb_mapped_len, 0, 0); goto error_return; } @@ -1490,7 +1490,9 @@ static void exynos4210_fimd_write(void *opaque, hwaddr offset, break; case 3: if (w != 1 && w != 2) { - DPRINT_ERROR("Bad write offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: Bad write offset 0x%08"HWADDR_PRIx"\n", + offset); return; } s->window[w].osdsize = val; @@ -1624,7 +1626,9 @@ static void exynos4210_fimd_write(void *opaque, hwaddr offset, break; case FIMD_VIDW0ADD0_B2 ... FIMD_VIDW4ADD0_B2: if (offset & 0x0004) { - DPRINT_ERROR("bad write offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad write offset 0x%08"HWADDR_PRIx"\n", + offset); break; } w = (offset - FIMD_VIDW0ADD0_B2) >> 3; @@ -1638,14 +1642,18 @@ static void exynos4210_fimd_write(void *opaque, hwaddr offset, break; case FIMD_SHD_ADD0_START ... FIMD_SHD_ADD0_END: if (offset & 0x0004) { - DPRINT_ERROR("bad write offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad write offset 0x%08"HWADDR_PRIx"\n", + offset); break; } s->window[(offset - FIMD_SHD_ADD0_START) >> 3].shadow_buf_start = val; break; case FIMD_SHD_ADD1_START ... FIMD_SHD_ADD1_END: if (offset & 0x0004) { - DPRINT_ERROR("bad write offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad write offset 0x%08"HWADDR_PRIx"\n", + offset); break; } s->window[(offset - FIMD_SHD_ADD1_START) >> 3].shadow_buf_end = val; @@ -1665,7 +1673,8 @@ static void exynos4210_fimd_write(void *opaque, hwaddr offset, s->window[w].palette[i] = val; break; default: - DPRINT_ERROR("bad write offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad write offset 0x%08"HWADDR_PRIx"\n", offset); break; } } @@ -1715,7 +1724,9 @@ static uint64_t exynos4210_fimd_read(void *opaque, hwaddr offset, break; case 3: if (w != 1 && w != 2) { - DPRINT_ERROR("bad read offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad read offset 0x%08"HWADDR_PRIx"\n", + offset); return 0xBAADBAAD; } ret = s->window[w].osdsize; @@ -1809,7 +1820,8 @@ static uint64_t exynos4210_fimd_read(void *opaque, hwaddr offset, return s->window[w].palette[i]; } - DPRINT_ERROR("bad read offset 0x%08x\n", offset); + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: bad read offset 0x%08"HWADDR_PRIx"\n", offset); return 0xBAADBAAD; } diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c index 32dc0d6aa7..21fde58a26 100644 --- a/hw/display/omap_dss.c +++ b/hw/display/omap_dss.c @@ -619,7 +619,7 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s) if (s->rfbi.control & (1 << 1)) { /* BYPASS */ /* TODO: in non-Bypass mode we probably need to just assert the * DRQ and wait for DMA to write the pixels. */ - fprintf(stderr, "%s: Bypass mode unimplemented\n", __func__); + qemu_log_mask(LOG_UNIMP, "%s: Bypass mode unimplemented\n", __func__); return; } diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c index d5f2e82a4e..ff90104b80 100644 --- a/hw/display/pxa2xx_lcd.c +++ b/hw/display/pxa2xx_lcd.c @@ -426,9 +426,10 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, if ((s->control[0] & LCCR0_ENB) && !(value & LCCR0_ENB)) s->status[0] |= LCSR0_QD; - if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT)) - printf("%s: internal frame buffer unsupported\n", __func__); - + if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT)) { + qemu_log_mask(LOG_UNIMP, + "%s: internal frame buffer unsupported\n", __func__); + } if ((s->control[3] & LCCR3_API) && (value & LCCR0_ENB) && !(value & LCCR0_LCDT)) s->status[0] |= LCSR0_ABC; @@ -462,9 +463,9 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, break; case OVL1C1: - if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) - printf("%s: Overlay 1 not supported\n", __func__); - + if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) { + qemu_log_mask(LOG_UNIMP, "%s: Overlay 1 not supported\n", __func__); + } s->ovl1c[0] = value & 0x80ffffff; s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS); break; @@ -474,9 +475,9 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, break; case OVL2C1: - if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) - printf("%s: Overlay 2 not supported\n", __func__); - + if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) { + qemu_log_mask(LOG_UNIMP, "%s: Overlay 2 not supported\n", __func__); + } s->ovl2c[0] = value & 0x80ffffff; s->dma_ch[2].up = !!(value & OVLC1_EN); s->dma_ch[3].up = !!(value & OVLC1_EN); @@ -488,9 +489,10 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, break; case CCR: - if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) - printf("%s: Hardware cursor unimplemented\n", __func__); - + if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) { + qemu_log_mask(LOG_UNIMP, + "%s: Hardware cursor unimplemented\n", __func__); + } s->ccr = value & 0x81ffffe7; s->dma_ch[5].up = !!(value & CCR_CEN); break; diff --git a/hw/display/sm501.c b/hw/display/sm501.c index acc692531a..edd8d24a76 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -2,7 +2,7 @@ * QEMU SM501 Device * * Copyright (c) 2008 Shin-ichiro KAWASAKI - * Copyright (c) 2016 BALATON Zoltan + * Copyright (c) 2016-2020 BALATON Zoltan * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,23 +40,6 @@ #include "ui/pixel_ops.h" #include "qemu/bswap.h" -/* - * Status: 2010/05/07 - * - Minimum implementation for Linux console : mmio regs and CRT layer. - * - 2D graphics acceleration partially supported : only fill rectangle. - * - * Status: 2016/12/04 - * - Misc fixes: endianness, hardware cursor - * - Panel support - * - * TODO: - * - Touch panel support - * - USB support - * - UART support - * - More 2D graphics engine support - * - Performance tuning - */ - /*#define DEBUG_SM501*/ /*#define DEBUG_BITBLT*/ @@ -699,139 +682,176 @@ static inline void hwc_invalidate(SM501State *s, int crt) static void sm501_2d_operation(SM501State *s) { - /* obtain operation parameters */ - int operation = (s->twoD_control >> 16) & 0x1f; - int rtl = s->twoD_control & 0x8000000; - int src_x = (s->twoD_source >> 16) & 0x01FFF; - int src_y = s->twoD_source & 0xFFFF; - int dst_x = (s->twoD_destination >> 16) & 0x01FFF; - int dst_y = s->twoD_destination & 0xFFFF; - int operation_width = (s->twoD_dimension >> 16) & 0x1FFF; - int operation_height = s->twoD_dimension & 0xFFFF; - uint32_t color = s->twoD_foreground; - int format_flags = (s->twoD_stretch >> 20) & 0x3; - int addressing = (s->twoD_stretch >> 16) & 0xF; + int cmd = (s->twoD_control >> 16) & 0x1F; + int rtl = s->twoD_control & BIT(27); + int format = (s->twoD_stretch >> 20) & 0x3; int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */ /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; int rop = s->twoD_control & 0xFF; - uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; + unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF; + unsigned int dst_y = s->twoD_destination & 0xFFFF; + unsigned int width = (s->twoD_dimension >> 16) & 0x1FFF; + unsigned int height = s->twoD_dimension & 0xFFFF; uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF; - - /* get frame buffer info */ - uint8_t *src = s->local_mem + src_base; - uint8_t *dst = s->local_mem + dst_base; - int src_width = s->twoD_pitch & 0x1FFF; - int dst_width = (s->twoD_pitch >> 16) & 0x1FFF; + unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); - if (addressing != 0x0) { - printf("%s: only XY addressing is supported.\n", __func__); - abort(); + if ((s->twoD_stretch >> 16) & 0xF) { + qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n"); + return; } - if (rop_mode == 0) { - if (rop != 0xcc) { - /* Anything other than plain copies are not supported */ - qemu_log_mask(LOG_UNIMP, "sm501: rop3 mode with rop %x is not " - "supported.\n", rop); - } - } else { - if (rop2_source_is_pattern && rop != 0x5) { - /* For pattern source, we support only inverse dest */ - qemu_log_mask(LOG_UNIMP, "sm501: rop2 source being the pattern and " - "rop %x is not supported.\n", rop); - } else { - if (rop != 0x5 && rop != 0xc) { - /* Anything other than plain copies or inverse dest is not - * supported */ - qemu_log_mask(LOG_UNIMP, "sm501: rop mode %x is not " - "supported.\n", rop); - } - } + if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) { + qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); + return; } - if ((s->twoD_source_base & 0x08000000) || - (s->twoD_destination_base & 0x08000000)) { - printf("%s: only local memory is supported.\n", __func__); - abort(); + if (!dst_pitch) { + qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero dest pitch.\n"); + return; + } + + if (!width || !height) { + qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero size 2D op.\n"); + return; } - switch (operation) { - case 0x00: /* copy area */ -#define COPY_AREA(_bpp, _pixel_type, rtl) { \ - int y, x, index_d, index_s; \ - for (y = 0; y < operation_height; y++) { \ - for (x = 0; x < operation_width; x++) { \ - _pixel_type val; \ - \ - if (rtl) { \ - index_s = ((src_y - y) * src_width + src_x - x) * _bpp; \ - index_d = ((dst_y - y) * dst_width + dst_x - x) * _bpp; \ - } else { \ - index_s = ((src_y + y) * src_width + src_x + x) * _bpp; \ - index_d = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ - } \ - if (rop_mode == 1 && rop == 5) { \ - /* Invert dest */ \ - val = ~*(_pixel_type *)&dst[index_d]; \ - } else { \ - val = *(_pixel_type *)&src[index_s]; \ - } \ - *(_pixel_type *)&dst[index_d] = val; \ - } \ - } \ + if (rtl) { + dst_x -= width - 1; + dst_y -= height - 1; } - switch (format_flags) { - case 0: - COPY_AREA(1, uint8_t, rtl); - break; - case 1: - COPY_AREA(2, uint16_t, rtl); - break; - case 2: - COPY_AREA(4, uint32_t, rtl); - break; + + if (dst_base >= get_local_mem_size(s) || dst_base + + (dst_x + width + (dst_y + height) * (dst_pitch + width)) * + (1 << format) >= get_local_mem_size(s)) { + qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n"); + return; + } + + switch (cmd) { + case 0: /* BitBlt */ + { + static uint32_t tmp_buf[16384]; + unsigned int src_x = (s->twoD_source >> 16) & 0x01FFF; + unsigned int src_y = s->twoD_source & 0xFFFF; + uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; + unsigned int src_pitch = s->twoD_pitch & 0x1FFF; + + if (!src_pitch) { + qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero src pitch.\n"); + return; + } + + if (rtl) { + src_x -= width - 1; + src_y -= height - 1; } - break; - case 0x01: /* fill rectangle */ -#define FILL_RECT(_bpp, _pixel_type) { \ - int y, x; \ - for (y = 0; y < operation_height; y++) { \ - for (x = 0; x < operation_width; x++) { \ - int index = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ - *(_pixel_type *)&dst[index] = (_pixel_type)color; \ - } \ - } \ + if (src_base >= get_local_mem_size(s) || src_base + + (src_x + width + (src_y + height) * (src_pitch + width)) * + (1 << format) >= get_local_mem_size(s)) { + qemu_log_mask(LOG_GUEST_ERROR, + "sm501: 2D op src is outside vram.\n"); + return; + } + + if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) { + /* Invert dest, is there a way to do this with pixman? */ + unsigned int x, y, i; + uint8_t *d = s->local_mem + dst_base; + + for (y = 0; y < height; y++) { + i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format); + for (x = 0; x < width; x++, i += (1 << format)) { + switch (format) { + case 0: + d[i] = ~d[i]; + break; + case 1: + *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i]; + break; + case 2: + *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i]; + break; + } + } + } + } else { + /* Do copy src for unimplemented ops, better than unpainted area */ + if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) || + (!rop_mode && rop != 0xcc)) { + qemu_log_mask(LOG_UNIMP, + "sm501: rop%d op %x%s not implemented\n", + (rop_mode ? 2 : 3), rop, + (rop2_source_is_pattern ? + " with pattern source" : "")); + } + /* Check for overlaps, this could be made more exact */ + uint32_t sb, se, db, de; + sb = src_base + src_x + src_y * (width + src_pitch); + se = sb + width + height * (width + src_pitch); + db = dst_base + dst_x + dst_y * (width + dst_pitch); + de = db + width + height * (width + dst_pitch); + if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) { + /* regions may overlap: copy via temporary */ + int free_buf = 0, llb = width * (1 << format); + int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t)); + uint32_t *tmp = tmp_buf; + + if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) { + tmp = g_malloc(tmp_stride * sizeof(uint32_t) * height); + free_buf = 1; + } + pixman_blt((uint32_t *)&s->local_mem[src_base], tmp, + src_pitch * (1 << format) / sizeof(uint32_t), + tmp_stride, 8 * (1 << format), 8 * (1 << format), + src_x, src_y, 0, 0, width, height); + pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base], + tmp_stride, + dst_pitch * (1 << format) / sizeof(uint32_t), + 8 * (1 << format), 8 * (1 << format), + 0, 0, dst_x, dst_y, width, height); + if (free_buf) { + g_free(tmp); + } + } else { + pixman_blt((uint32_t *)&s->local_mem[src_base], + (uint32_t *)&s->local_mem[dst_base], + src_pitch * (1 << format) / sizeof(uint32_t), + dst_pitch * (1 << format) / sizeof(uint32_t), + 8 * (1 << format), 8 * (1 << format), + src_x, src_y, dst_x, dst_y, width, height); + } + } + break; } + case 1: /* Rectangle Fill */ + { + uint32_t color = s->twoD_foreground; - switch (format_flags) { - case 0: - FILL_RECT(1, uint8_t); - break; - case 1: - color = cpu_to_le16(color); - FILL_RECT(2, uint16_t); - break; - case 2: + if (format == 2) { color = cpu_to_le32(color); - FILL_RECT(4, uint32_t); - break; + } else if (format == 1) { + color = cpu_to_le16(color); } - break; - default: - printf("non-implemented SM501 2D operation. %d\n", operation); - abort(); + pixman_fill((uint32_t *)&s->local_mem[dst_base], + dst_pitch * (1 << format) / sizeof(uint32_t), + 8 * (1 << format), dst_x, dst_y, width, height, color); break; } + default: + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", + cmd); + return; + } if (dst_base >= get_fb_addr(s, crt) && dst_base <= get_fb_addr(s, crt) + fb_len) { - int dst_len = MIN(fb_len, ((dst_y + operation_height - 1) * dst_width + - dst_x + operation_width) * (1 << format_flags)); + int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch + + dst_x + width) * (1 << format)); if (dst_len) { memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len); } @@ -892,9 +912,8 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, break; default: - printf("sm501 system config : not implemented register read." - " addr=%x\n", (int)addr); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" + "register read. addr=%" HWADDR_PRIx "\n", addr); } return ret; @@ -948,15 +967,15 @@ static void sm501_system_config_write(void *opaque, hwaddr addr, break; case SM501_ENDIAN_CONTROL: if (value & 0x00000001) { - printf("sm501 system config : big endian mode not implemented.\n"); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: system config big endian mode not" + " implemented.\n"); } break; default: - printf("sm501 system config : not implemented register write." - " addr=%x, val=%x\n", (int)addr, (uint32_t)value); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" + "register write. addr=%" HWADDR_PRIx + ", val=%" PRIx64 "\n", addr, value); } } @@ -1207,9 +1226,8 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr, break; default: - printf("sm501 disp ctrl : not implemented register read." - " addr=%x\n", (int)addr); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " + "read. addr=%" HWADDR_PRIx "\n", addr); } return ret; @@ -1345,9 +1363,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr, break; default: - printf("sm501 disp ctrl : not implemented register write." - " addr=%x, val=%x\n", (int)addr, (unsigned)value); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " + "write. addr=%" HWADDR_PRIx + ", val=%" PRIx64 "\n", addr, value); } } @@ -1433,9 +1451,8 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr, ret = 0; /* Should return interrupt status */ break; default: - printf("sm501 disp ctrl : not implemented register read." - " addr=%x\n", (int)addr); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " + "read. addr=%" HWADDR_PRIx "\n", addr); } return ret; @@ -1520,9 +1537,9 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr, /* ignored, writing 0 should clear interrupt status */ break; default: - printf("sm501 2d engine : not implemented register write." - " addr=%x, val=%x\n", (int)addr, (unsigned)value); - abort(); + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2d engine register " + "write. addr=%" HWADDR_PRIx + ", val=%" PRIx64 "\n", addr, value); } } @@ -1670,9 +1687,9 @@ static void sm501_update_display(void *opaque) draw_line = draw_line32_funcs[dst_depth_index]; break; default: - printf("sm501 update display : invalid control register value.\n"); - abort(); - break; + qemu_log_mask(LOG_GUEST_ERROR, "sm501: update display" + "invalid control register value.\n"); + return; } /* set up to draw hardware cursor */ diff --git a/hw/display/trace-events b/hw/display/trace-events index e6e22bef88..72d4c9812c 100644 --- a/hw/display/trace-events +++ b/hw/display/trace-events @@ -133,6 +133,8 @@ vga_vbe_write(uint32_t index, uint32_t val) "index 0x%x, val 0x%x" vga_cirrus_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" vga_cirrus_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x" +vga_cirrus_write_gr(uint8_t index, uint8_t val) "GR addr 0x%02x, val 0x%02x" +vga_cirrus_bitblt_start(uint8_t blt_rop, uint8_t blt_mode, uint8_t blt_modeext, int blt_width, int blt_height, int blt_dstpitch, int blt_srcpitch, uint32_t blt_dstaddr, uint32_t blt_srcaddr, uint8_t gr_val) "rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08"PRIx32" saddr=0x%08"PRIx32" writemask=0x%02x" # sii9022.c sii9022_read_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x" @@ -151,3 +153,11 @@ artist_vram_write(unsigned int size, uint64_t addr, uint64_t val) "%u 0x%"PRIx64 artist_fill_window(unsigned int start_x, unsigned int start_y, unsigned int width, unsigned int height, uint32_t op, uint32_t ctlpln) "start=%ux%u length=%ux%u op=0x%08x ctlpln=0x%08x" artist_block_move(unsigned int start_x, unsigned int start_y, unsigned int dest_x, unsigned int dest_y, unsigned int width, unsigned int height) "source %ux%u -> dest %ux%u size %ux%u" artist_draw_line(unsigned int start_x, unsigned int start_y, unsigned int end_x, unsigned int end_y) "%ux%u %ux%u" + +# cg3.c +cg3_read(uint32_t addr, uint32_t val, unsigned size) "read addr:0x%06"PRIx32" val:0x%08"PRIx32" size:%u" +cg3_write(uint32_t addr, uint32_t val, unsigned size) "write addr:0x%06"PRIx32" val:0x%08"PRIx32" size:%u" + +# dpcd.c +dpcd_read(uint32_t addr, uint8_t val) "read addr:0x%"PRIx32" val:0x%02x" +dpcd_write(uint32_t addr, uint8_t val) "write addr:0x%"PRIx32" val:0x%02x" diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 58ea82e3e5..2579f6b218 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -26,6 +26,7 @@ #include "qemu/module.h" #include "qemu/units.h" #include "qapi/error.h" +#include "qemu/log.h" #include "hw/loader.h" #include "trace.h" #include "ui/vnc.h" @@ -953,7 +954,8 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) ret = s->scratch[s->index - SVGA_SCRATCH_BASE]; break; } - printf("%s: Bad register %02x\n", __func__, s->index); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad register %02x\n", __func__, s->index); ret = 0; break; } @@ -1002,7 +1004,8 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->new_width = value; s->invalidated = 1; } else { - printf("%s: Bad width: %i\n", __func__, value); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad width: %i\n", __func__, value); } break; @@ -1011,13 +1014,15 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->new_height = value; s->invalidated = 1; } else { - printf("%s: Bad height: %i\n", __func__, value); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad height: %i\n", __func__, value); } break; case SVGA_REG_BITS_PER_PIXEL: if (value != 32) { - printf("%s: Bad bits per pixel: %i bits\n", __func__, value); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad bits per pixel: %i bits\n", __func__, value); s->config = 0; s->invalidated = 1; } @@ -1082,7 +1087,8 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->scratch[s->index - SVGA_SCRATCH_BASE] = value; break; } - printf("%s: Bad register %02x\n", __func__, s->index); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad register %02x\n", __func__, s->index); } } @@ -1300,7 +1306,7 @@ static void pci_vmsvga_realize(PCIDevice *dev, Error **errp) dev->config[PCI_LATENCY_TIMER] = 0x40; dev->config[PCI_INTERRUPT_LINE] = 0xff; /* End */ - memory_region_init_io(&s->io_bar, NULL, &vmsvga_io_ops, &s->chip, + memory_region_init_io(&s->io_bar, OBJECT(dev), &vmsvga_io_ops, &s->chip, "vmsvga-io", 0x10); memory_region_set_flush_coalesced(&s->io_bar); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 3e5fb44e06..8d940cd8d1 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1,5 +1,5 @@ /* - * xlnx_dp.c + * Xilinx Display Port * * Copyright (C) 2015 : GreenSocs Ltd * http://www.greensocs.com/ , email: info@greensocs.com @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/module.h" #include "hw/display/xlnx_dp.h" @@ -465,7 +466,7 @@ static uint8_t xlnx_dp_aux_pop_tx_fifo(XlnxDPState *s) uint8_t ret; if (fifo8_is_empty(&s->tx_fifo)) { - DPRINTF("tx_fifo underflow..\n"); + error_report("%s: TX_FIFO underflow", __func__); abort(); } ret = fifo8_pop(&s->tx_fifo); @@ -525,6 +526,7 @@ static void xlnx_dp_aux_set_command(XlnxDPState *s, uint32_t value) qemu_log_mask(LOG_UNIMP, "xlnx_dp: Write i2c status not implemented\n"); break; default: + error_report("%s: invalid command: %u", __func__, cmd); abort(); } @@ -631,8 +633,8 @@ static void xlnx_dp_change_graphic_fmt(XlnxDPState *s) s->g_plane.format = PIXMAN_b8g8r8; break; default: - DPRINTF("error: unsupported graphic format %u.\n", - s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK); + error_report("%s: unsupported graphic format %u", __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK); abort(); } @@ -647,8 +649,8 @@ static void xlnx_dp_change_graphic_fmt(XlnxDPState *s) s->v_plane.format = PIXMAN_x8b8g8r8; break; default: - DPRINTF("error: unsupported video format %u.\n", - s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK); + error_report("%s: unsupported video format %u", __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK); abort(); } diff --git a/include/hw/display/edid.h b/include/hw/display/edid.h index ff99dc0a05..23371ee82c 100644 --- a/include/hw/display/edid.h +++ b/include/hw/display/edid.h @@ -2,6 +2,7 @@ #define EDID_H #include "qom/object.h" +#include "hw/qdev-properties.h" typedef struct qemu_edid_info { const char *vendor; /* http://www.uefi.org/pnp_id_list */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 05f03919ff..7f6700c54e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7635,30 +7635,33 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return -TARGET_ERESTARTSYS; } - cpu_list_lock(); + pthread_mutex_lock(&clone_lock); if (CPU_NEXT(first_cpu)) { - TaskState *ts; + TaskState *ts = cpu->opaque; - /* Remove the CPU from the list. */ - QTAILQ_REMOVE_RCU(&cpus, cpu, node); + object_property_set_bool(OBJECT(cpu), false, "realized", NULL); + object_unref(OBJECT(cpu)); + /* + * At this point the CPU should be unrealized and removed + * from cpu lists. We can clean-up the rest of the thread + * data without the lock held. + */ - cpu_list_unlock(); + pthread_mutex_unlock(&clone_lock); - ts = cpu->opaque; if (ts->child_tidptr) { put_user_u32(0, ts->child_tidptr); do_sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, NULL, NULL, 0); } thread_cpu = NULL; - object_unref(OBJECT(cpu)); g_free(ts); rcu_unregister_thread(); pthread_exit(NULL); } - cpu_list_unlock(); + pthread_mutex_unlock(&clone_lock); preexit_cleanup(cpu_env, arg1); _exit(arg1); return 0; /* avoid warning */ diff --git a/tests/Makefile.include b/tests/Makefile.include index 03a74b60f6..a00ccc94b8 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -687,11 +687,26 @@ test-softfloat = $(call quiet-command, \ (cat $2.out && exit 1;), \ "FLOAT TEST", $2) -# Conversion Routines: +# Conversion Routines: Float to Float +# FIXME: f32_to_f128 (broken), f64_to_f128 (broken) +# FIXME: f128_to_f32(broken), f128_to_f64 (broken) +# FIXME: f128_to_extF80 (broken) +check-softfloat-conv-f2f: $(FP_TEST_BIN) + $(call test-softfloat, \ + f16_to_f32 f16_to_f64 \ + f16_to_extF80 f16_to_f128 \ + f32_to_f16 f32_to_f64 \ + f32_to_extF80 \ + f64_to_f16 f64_to_f32 \ + extF80_to_f16 extF80_to_f32 \ + extF80_to_f64 extF80_to_f128 \ + f128_to_f16, \ + float-to-float) + +# Conversion Routines: Int and Uint to Float # FIXME: i32_to_extF80 (broken), i64_to_extF80 (broken) -# ui32_to_f128 (not implemented), extF80_roundToInt (broken) -# -check-softfloat-conv: $(FP_TEST_BIN) +# ui32_to_f128 (not implemented) +check-softfloat-conv-to-float: $(FP_TEST_BIN) $(call test-softfloat, \ i32_to_f16 i64_to_f16 \ i32_to_f32 i64_to_f32 \ @@ -701,7 +716,12 @@ check-softfloat-conv: $(FP_TEST_BIN) ui32_to_f16 ui64_to_f16 \ ui32_to_f32 ui64_to_f32 \ ui32_to_f64 ui64_to_f64 \ + ui32_to_extF80 ui64_to_extF80 \ ui64_to_f128, uint-to-float) + +# Conversion Routines: Float to integers +# FIXME: extF80_roundToInt (broken) +check-softfloat-conv-to-int: $(FP_TEST_BIN) $(call test-softfloat, \ f16_to_i32 f16_to_i32_r_minMag \ f32_to_i32 f32_to_i32_r_minMag \ @@ -718,10 +738,12 @@ check-softfloat-conv: $(FP_TEST_BIN) f16_to_ui32 f16_to_ui32_r_minMag \ f32_to_ui32 f32_to_ui32_r_minMag \ f64_to_ui32 f64_to_ui32_r_minMag \ + extF80_to_ui32 extF80_to_ui32_r_minMag \ f128_to_ui32 f128_to_ui32_r_minMag \ f16_to_ui64 f16_to_ui64_r_minMag \ f32_to_ui64 f32_to_ui64_r_minMag \ f64_to_ui64 f64_to_ui64_r_minMag \ + extF80_to_ui64 extF80_to_ui64_r_minMag \ f128_to_ui64 f128_to_ui64_r_minMag, \ float-to-uint) $(call test-softfloat, \ @@ -729,9 +751,14 @@ check-softfloat-conv: $(FP_TEST_BIN) f64_roundToInt f128_roundToInt, \ round-to-integer) +.PHONY: check-softfloat-conv +check-softfloat-conv: check-softfloat-conv-f2f +check-softfloat-conv: check-softfloat-conv-to-float +check-softfloat-conv: check-softfloat-conv-to-int + # Generic rule for all float operations # -# Some patterns are overidden due to broken or missing tests. +# Some patterns are overridden due to broken or missing tests. # Hopefully these can be removed over time. check-softfloat-%: $(FP_TEST_BIN) @@ -741,13 +768,6 @@ check-softfloat-%: $(FP_TEST_BIN) SF_COMPARE_OPS=eq eq_signaling le le_quiet lt_quiet SF_COMPARE_RULES=$(patsubst %,check-softfloat-%, $(SF_COMPARE_OPS)) -# FIXME: extF80_le_quiet (broken) -check-softfloat-le_quiet: $(FP_TEST_BIN) - $(call test-softfloat, \ - f16_le_quiet f32_le_quiet f64_le_quiet \ - f128_le_quiet, \ - le_quiet) - # FIXME: extF80_lt_quiet (broken) check-softfloat-lt_quiet: $(FP_TEST_BIN) $(call test-softfloat, \ diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 43a8678688..ed46bd98eb 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -7,7 +7,7 @@ HOST_ARCH = $(if $(ARCH),$(ARCH),$(shell uname -m)) DOCKER_SUFFIX := .docker DOCKER_FILES_DIR := $(SRC_PATH)/tests/docker/dockerfiles # we don't run tests on intermediate images (used as base by another image) -DOCKER_PARTIAL_IMAGES := debian9 debian10 +DOCKER_PARTIAL_IMAGES := debian9 debian10 debian11 DOCKER_PARTIAL_IMAGES += debian9-mxe debian-bootstrap DOCKER_IMAGES := $(sort $(notdir $(basename $(wildcard $(DOCKER_FILES_DIR)/*.docker)))) DOCKER_TARGETS := $(patsubst %,docker-image-%,$(DOCKER_IMAGES)) @@ -131,9 +131,11 @@ docker-image-travis: NOUSER=1 # Specialist build images, sometimes very limited tools docker-image-tricore-cross: docker-image-debian9 +docker-image-debian-arm64-test-cross: docker-image-debian11 # These images may be good enough for building tests but not for test builds DOCKER_PARTIAL_IMAGES += debian-alpha-cross +DOCKER_PARTIAL_IMAGES += debian-arm64-test-cross DOCKER_PARTIAL_IMAGES += debian-hppa-cross DOCKER_PARTIAL_IMAGES += debian-m68k-cross debian-mips64-cross DOCKER_PARTIAL_IMAGES += debian-powerpc-cross debian-ppc64-cross diff --git a/tests/docker/dockerfiles/debian-arm64-test-cross.docker b/tests/docker/dockerfiles/debian-arm64-test-cross.docker new file mode 100644 index 0000000000..a44e76d942 --- /dev/null +++ b/tests/docker/dockerfiles/debian-arm64-test-cross.docker @@ -0,0 +1,13 @@ +# +# Docker arm64 cross-compiler target (tests only) +# +# This docker target builds on the debian Bullseye base image. +# +FROM qemu:debian11 + +# Add the foreign architecture we want and install dependencies +RUN dpkg --add-architecture arm64 +RUN apt update && \ + DEBIAN_FRONTEND=noninteractive eatmydata \ + apt install -y --no-install-recommends \ + crossbuild-essential-arm64 gcc-10-aarch64-linux-gnu diff --git a/tests/docker/dockerfiles/debian11.docker b/tests/docker/dockerfiles/debian11.docker new file mode 100644 index 0000000000..5adfd62d55 --- /dev/null +++ b/tests/docker/dockerfiles/debian11.docker @@ -0,0 +1,18 @@ +# +# Docker multiarch cross-compiler target +# +# This docker target uses the current development version of Debian as +# a base for cross compilers for building test binaries. We won't +# attempt to build QEMU on it yet given it is still in development. +# +# On its own you can't build much but the docker-foo-cross targets +# build on top of the base debian image. +# +FROM debian:bullseye-slim + +# Duplicate deb line as deb-src +RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list + +# Install common build utilities +RUN apt update && \ + DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target index 71f72cfbe3..1057a8ac49 100644 --- a/tests/tcg/aarch64/Makefile.softmmu-target +++ b/tests/tcg/aarch64/Makefile.softmmu-target @@ -61,7 +61,7 @@ run-memory-replay: memory-replay run-memory-record $(QEMU_OPTS) memory, \ "$< on $(TARGET_NAME)") -EXTRA_TESTS+=memory-record memory-replay +EXTRA_RUNS+=run-memory-replay ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_3),) pauth-3: CFLAGS += -march=armv8.3-a diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index eaaaff6233..2326f97856 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -97,8 +97,8 @@ for target in $target_list; do case $target in aarch64-*) # We don't have any bigendian build tools so we only use this for AArch64 - container_image=debian-arm64-cross - container_cross_cc=aarch64-linux-gnu-gcc + container_image=debian-arm64-test-cross + container_cross_cc=aarch64-linux-gnu-gcc-10 ;; alpha-*) container_image=debian-alpha-cross diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target index 51fb75ecfd..cb49cc9ccb 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -28,6 +28,8 @@ run-float_%: float_% testthread: LDFLAGS+=-lpthread +threadcount: LDFLAGS+=-lpthread + # We define the runner for test-mmap after the individual # architectures have defined their supported pages sizes. If no # additional page sizes are defined we only run the default test. diff --git a/tests/tcg/multiarch/gdbstub/sha1.py b/tests/tcg/multiarch/gdbstub/sha1.py index 734553b98b..2bfde49633 100644 --- a/tests/tcg/multiarch/gdbstub/sha1.py +++ b/tests/tcg/multiarch/gdbstub/sha1.py @@ -65,6 +65,10 @@ except (gdb.error, AttributeError): print("SKIPPING (not connected)", file=sys.stderr) exit(0) +if gdb.parse_and_eval('$pc') == 0: + print("SKIP: PC not set") + exit(0) + try: # These are not very useful in scripts gdb.execute("set pagination off") diff --git a/tests/tcg/multiarch/threadcount.c b/tests/tcg/multiarch/threadcount.c new file mode 100644 index 0000000000..545a1c8146 --- /dev/null +++ b/tests/tcg/multiarch/threadcount.c @@ -0,0 +1,64 @@ +/* + * Thread Exerciser + * + * Unlike testthread which is mainly concerned about testing thread + * semantics this test is used to exercise the thread creation and + * accounting. A version of this test found a problem with clashing + * cpu_indexes which caused a break in plugin handling. + * + * Based on the original test case by Nikolay Igotti. + * + * Copyright (c) 2020 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> + +int max_threads = 10; + +typedef struct { + int delay; +} ThreadArg; + +static void *thread_fn(void* varg) +{ + ThreadArg *arg = varg; + usleep(arg->delay); + free(arg); + return NULL; +} + +int main(int argc, char **argv) +{ + int i; + pthread_t *threads; + + if (argc > 1) { + max_threads = atoi(argv[1]); + } + threads = calloc(sizeof(pthread_t), max_threads); + + for (i = 0; i < max_threads; i++) { + ThreadArg *arg = calloc(sizeof(ThreadArg), 1); + arg->delay = i * 100; + pthread_create(threads + i, NULL, thread_fn, arg); + } + + printf("Created %d threads\n", max_threads); + + /* sleep until roughly half the threads have "finished" */ + usleep(max_threads * 50); + + for (i = 0; i < max_threads; i++) { + pthread_join(threads[i], NULL); + } + + printf("Done\n"); + + return 0; +} diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 1bf9693d19..74ab522c55 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -56,6 +56,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(call quiet-command, \ $(PYTHON) $< \ $(if $(V)$(DEBUG), --debug) \ + $(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \ --image "$@" \ --force \ --build-image $@, \ diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 756ccf7aca..a2d4054d72 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -61,8 +61,9 @@ class BaseVM(object): # 4 is arbitrary, but greater than 2, # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 - def __init__(self, debug=False, vcpus=None): + def __init__(self, debug=False, vcpus=None, genisoimage=None): self._guest = None + self._genisoimage = genisoimage self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", dir=".")) @@ -381,12 +382,12 @@ class BaseVM(object): udata.writelines(["apt:\n", " proxy: %s" % proxy]) udata.close() - subprocess.check_call(["genisoimage", "-output", "cloud-init.iso", + subprocess.check_call([self._genisoimage, "-output", "cloud-init.iso", "-volid", "cidata", "-joliet", "-rock", "user-data", "meta-data"], - cwd=cidir, - stdin=self._devnull, stdout=self._stdout, - stderr=self._stdout) + cwd=cidir, + stdin=self._devnull, stdout=self._stdout, + stderr=self._stdout) return os.path.join(cidir, "cloud-init.iso") @@ -424,6 +425,8 @@ def parse_args(vmcls): help="Interactively run command") parser.add_option("--snapshot", "-s", action="store_true", help="run tests with a snapshot") + parser.add_option("--genisoimage", default="genisoimage", + help="iso imaging tool") parser.disable_interspersed_args() return parser.parse_args() @@ -435,7 +438,8 @@ def main(vmcls): return 1 logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) - vm = vmcls(debug=args.debug, vcpus=args.jobs) + vm = vmcls(debug=args.debug, vcpus=args.jobs, + genisoimage=args.genisoimage) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image, |