diff options
Diffstat (limited to 'hw/display')
| -rw-r--r-- | hw/display/apple-gfx.m | 12 | ||||
| -rw-r--r-- | hw/display/artist.c | 1 | ||||
| -rw-r--r-- | hw/display/ati.c | 1 | ||||
| -rw-r--r-- | hw/display/bcm2835_fb.c | 1 | ||||
| -rw-r--r-- | hw/display/exynos4210_fimd.c | 8 | ||||
| -rw-r--r-- | hw/display/framebuffer.c | 6 | ||||
| -rw-r--r-- | hw/display/qxl-render.c | 11 | ||||
| -rw-r--r-- | hw/display/ramfb-standalone.c | 5 | ||||
| -rw-r--r-- | hw/display/ramfb-stubs.c | 2 | ||||
| -rw-r--r-- | hw/display/ramfb.c | 6 | ||||
| -rw-r--r-- | hw/display/sm501.c | 1 | ||||
| -rw-r--r-- | hw/display/trace-events | 2 | ||||
| -rw-r--r-- | hw/display/vga.c | 2 | ||||
| -rw-r--r-- | hw/display/vhost-user-gpu.c | 21 | ||||
| -rw-r--r-- | hw/display/virtio-gpu-base.c | 27 | ||||
| -rw-r--r-- | hw/display/virtio-gpu-udmabuf.c | 8 | ||||
| -rw-r--r-- | hw/display/virtio-gpu-virgl.c | 48 | ||||
| -rw-r--r-- | hw/display/virtio-gpu.c | 28 | ||||
| -rw-r--r-- | hw/display/vmware_vga.c | 2 | ||||
| -rw-r--r-- | hw/display/xenfb.c | 3 | ||||
| -rw-r--r-- | hw/display/xlnx_dp.c | 101 |
21 files changed, 246 insertions, 50 deletions
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m index 2ff1c90..174d56a 100644 --- a/hw/display/apple-gfx.m +++ b/hw/display/apple-gfx.m @@ -69,7 +69,7 @@ struct PGTask_s { mach_vm_address_t address; uint64_t len; /* - * All unique MemoryRegions for which a mapping has been created in in this + * All unique MemoryRegions for which a mapping has been created in this * task, and on which we have thus called memory_region_ref(). There are * usually very few regions of system RAM in total, so we expect this array * to be very short. Therefore, no need for sorting or fancy search @@ -454,7 +454,7 @@ static void set_cursor_glyph(void *opaque) /* ------ DMA (device reading system memory) ------ */ typedef struct AppleGFXReadMemoryJob { - QemuSemaphore sem; + QemuEvent event; hwaddr physical_address; uint64_t length; void *dst; @@ -470,7 +470,7 @@ static void apple_gfx_do_read_memory(void *opaque) job->dst, job->length, MEMTXATTRS_UNSPECIFIED); job->success = (r == MEMTX_OK); - qemu_sem_post(&job->sem); + qemu_event_set(&job->event); } static bool apple_gfx_read_memory(AppleGFXState *s, hwaddr physical_address, @@ -483,11 +483,11 @@ static bool apple_gfx_read_memory(AppleGFXState *s, hwaddr physical_address, trace_apple_gfx_read_memory(physical_address, length, dst); /* Performing DMA requires BQL, so do it in a BH. */ - qemu_sem_init(&job.sem, 0); + qemu_event_init(&job.event, 0); aio_bh_schedule_oneshot(qemu_get_aio_context(), apple_gfx_do_read_memory, &job); - qemu_sem_wait(&job.sem); - qemu_sem_destroy(&job.sem); + qemu_event_wait(&job.event); + qemu_event_destroy(&job.event); return job.success; } diff --git a/hw/display/artist.c b/hw/display/artist.c index 3fafc8a..3c884c9 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -12,6 +12,7 @@ #include "qemu/log.h" #include "qemu/module.h" #include "qemu/units.h" +#include "qemu/bswap.h" #include "qapi/error.h" #include "hw/sysbus.h" #include "hw/loader.h" diff --git a/hw/display/ati.c b/hw/display/ati.c index 7de2773..f7c0006 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -22,6 +22,7 @@ #include "vga-access.h" #include "hw/qdev-properties.h" #include "vga_regs.h" +#include "qemu/bswap.h" #include "qemu/log.h" #include "qemu/module.h" #include "qemu/error-report.h" diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 820e67a..1bb2ee4 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -27,6 +27,7 @@ #include "hw/display/bcm2835_fb.h" #include "hw/hw.h" #include "hw/irq.h" +#include "ui/console.h" #include "framebuffer.h" #include "ui/pixel_ops.h" #include "hw/misc/bcm2835_mbox_defs.h" diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index c61e028..49c180f 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -131,7 +131,6 @@ /* Frame buffer address registers */ #define FIMD_VIDWADD0_START 0x00A0 #define FIMD_VIDWADD0_END 0x00C4 -#define FIMD_VIDWADD0_END 0x00C4 #define FIMD_VIDWADD1_START 0x00D0 #define FIMD_VIDWADD1_END 0x00F4 #define FIMD_VIDWADD2_START 0x0100 @@ -1147,6 +1146,13 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) if (w->mem_section.mr) { memory_region_set_log(w->mem_section.mr, false, DIRTY_MEMORY_VGA); memory_region_unref(w->mem_section.mr); + w->mem_section.mr = NULL; + } + + if (w->fb_len == 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "FIMD: Guest config means framebuffer is zero length\n"); + goto error_return; } w->mem_section = memory_region_find(s->fbmem, fb_start_addr, w->fb_len); diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c index 4485aa3..b4296e8 100644 --- a/hw/display/framebuffer.c +++ b/hw/display/framebuffer.c @@ -95,9 +95,9 @@ void framebuffer_update_display( } first = -1; - addr += i * src_width; - src += i * src_width; - dest += i * dest_row_pitch; + addr += (uint64_t)i * src_width; + src += (uint64_t)i * src_width; + dest += (uint64_t)i * dest_row_pitch; snap = memory_region_snapshot_and_clear_dirty(mem, addr, src_width * rows, DIRTY_MEMORY_VGA); diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index eda6d3d..c6a9ac1 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -222,6 +222,7 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, uint32_t max_chunks = 32; size_t offset = 0; size_t bytes; + QXLPHYSICAL next_chunk_phys = 0; for (;;) { bytes = MIN(size - offset, chunk->data_size); @@ -230,7 +231,15 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, if (offset == size) { return; } - chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id, + next_chunk_phys = chunk->next_chunk; + /* fist time, only get the next chunk's data size */ + chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id, + sizeof(QXLDataChunk)); + if (!chunk) { + return; + } + /* second time, check data size and get data */ + chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id, sizeof(QXLDataChunk) + chunk->data_size); if (!chunk) { return; diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c index 08f2d5d..72b2071 100644 --- a/hw/display/ramfb-standalone.c +++ b/hw/display/ramfb-standalone.c @@ -17,6 +17,7 @@ struct RAMFBStandaloneState { QemuConsole *con; RAMFBState *state; bool migrate; + bool use_legacy_x86_rom; }; static void display_update_wrapper(void *dev) @@ -39,7 +40,7 @@ static void ramfb_realizefn(DeviceState *dev, Error **errp) RAMFBStandaloneState *ramfb = RAMFB(dev); ramfb->con = graphic_console_init(dev, 0, &wrapper_ops, dev); - ramfb->state = ramfb_setup(errp); + ramfb->state = ramfb_setup(ramfb->use_legacy_x86_rom, errp); } static bool migrate_needed(void *opaque) @@ -62,6 +63,8 @@ static const VMStateDescription ramfb_dev_vmstate = { static const Property ramfb_properties[] = { DEFINE_PROP_BOOL("x-migrate", RAMFBStandaloneState, migrate, true), + DEFINE_PROP_BOOL("use-legacy-x86-rom", RAMFBStandaloneState, + use_legacy_x86_rom, false), }; static void ramfb_class_initfn(ObjectClass *klass, const void *data) diff --git a/hw/display/ramfb-stubs.c b/hw/display/ramfb-stubs.c index cf64733..b835513 100644 --- a/hw/display/ramfb-stubs.c +++ b/hw/display/ramfb-stubs.c @@ -8,7 +8,7 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) { } -RAMFBState *ramfb_setup(Error **errp) +RAMFBState *ramfb_setup(bool romfile, Error **errp) { error_setg(errp, "ramfb support not available"); return NULL; diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index 8c0f907..9a17d97 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -135,7 +135,7 @@ const VMStateDescription ramfb_vmstate = { } }; -RAMFBState *ramfb_setup(Error **errp) +RAMFBState *ramfb_setup(bool romfile, Error **errp) { FWCfgState *fw_cfg = fw_cfg_find(); RAMFBState *s; @@ -147,7 +147,9 @@ RAMFBState *ramfb_setup(Error **errp) s = g_new0(RAMFBState, 1); - rom_add_vga("vgabios-ramfb.bin"); + if (romfile) { + rom_add_vga("vgabios-ramfb.bin"); + } fw_cfg_add_file_callback(fw_cfg, "etc/ramfb", NULL, ramfb_fw_cfg_write, s, &s->cfg, sizeof(s->cfg), false); diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 6d2f186..bc091b3 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/module.h" #include "hw/usb/hcd-ohci.h" diff --git a/hw/display/trace-events b/hw/display/trace-events index 52786e6..e323a82 100644 --- a/hw/display/trace-events +++ b/hw/display/trace-events @@ -38,6 +38,8 @@ virtio_gpu_cmd_set_scanout_blob(uint32_t id, uint32_t res, uint32_t w, uint32_t virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d" virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d" virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" PRId64 +virtio_gpu_cmd_res_map_blob(uint32_t res, void *vmr, void *mr) "res 0x%x, vmr %p, mr %p" +virtio_gpu_cmd_res_unmap_blob(uint32_t res, void *mr, bool finish_unmapping) "res 0x%x, mr %p, finish_unmapping %d" virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x" virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x" virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x" diff --git a/hw/display/vga.c b/hw/display/vga.c index 20475eb..90b89cf 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -26,7 +26,7 @@ #include "qemu/units.h" #include "system/reset.h" #include "qapi/error.h" -#include "exec/tswap.h" +#include "qemu/target-info.h" #include "hw/display/vga.h" #include "hw/i386/x86.h" #include "hw/pci/pci.h" diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 06c4e7e..9fc6bbc 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -18,6 +18,7 @@ #include "chardev/char-fe.h" #include "qapi/error.h" #include "migration/blocker.h" +#include "standard-headers/drm/drm_fourcc.h" typedef enum VhostUserGpuRequest { VHOST_USER_GPU_NONE = 0, @@ -249,7 +250,9 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) case VHOST_USER_GPU_DMABUF_SCANOUT: { VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout; int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr); - uint64_t modifier = 0; + uint32_t offset = 0; + uint32_t stride = m->fd_stride; + uint64_t modifier = DRM_FORMAT_MOD_INVALID; QemuDmaBuf *dmabuf; if (m->scanout_id >= g->parent_obj.conf.max_outputs) { @@ -282,10 +285,10 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) } dmabuf = qemu_dmabuf_new(m->width, m->height, - m->fd_stride, 0, 0, + &offset, &stride, 0, 0, m->fd_width, m->fd_height, m->fd_drm_fourcc, modifier, - fd, false, m->fd_flags & + &fd, 1, false, m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); dpy_gl_scanout_dmabuf(con, dmabuf); @@ -513,7 +516,7 @@ vhost_user_gpu_set_config(VirtIODevice *vdev, } } -static void +static int vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val) { VhostUserGPU *g = VHOST_USER_GPU(vdev); @@ -522,18 +525,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val) if (val & VIRTIO_CONFIG_S_DRIVER_OK && vdev->vm_running) { if (!vhost_user_gpu_do_set_socket(g, &err)) { error_report_err(err); - return; + return 0; } vhost_user_backend_start(g->vhost); } else { + int ret; + /* unblock any wait and stop processing */ if (g->vhost_gpu_fd != -1) { vhost_user_gpu_update_blocked(g, true); qemu_chr_fe_deinit(&g->vhost_chr, true); g->vhost_gpu_fd = -1; } - vhost_user_backend_stop(g->vhost); + ret = vhost_user_backend_stop(g->vhost); + if (ret < 0) { + return ret; + } } + return 0; } static bool diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index 9eb806b..7269477 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -19,6 +19,7 @@ #include "qemu/error-report.h" #include "hw/display/edid.h" #include "trace.h" +#include "qapi/qapi-types-virtio.h" void virtio_gpu_base_reset(VirtIOGPUBase *g) @@ -56,6 +57,8 @@ void virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout, struct virtio_gpu_resp_edid *edid) { + size_t output_idx; + VirtIOGPUOutputList *node; qemu_edid_info info = { .width_mm = g->req_state[scanout].width_mm, .height_mm = g->req_state[scanout].height_mm, @@ -64,6 +67,14 @@ virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout, .refresh_rate = g->req_state[scanout].refresh_rate, }; + for (output_idx = 0, node = g->conf.outputs; + output_idx <= scanout && node; output_idx++, node = node->next) { + if (output_idx == scanout && node->value && node->value->name) { + info.name = node->value->name; + break; + } + } + edid->size = cpu_to_le32(sizeof(edid->edid)); qemu_edid_generate(edid->edid, sizeof(edid->edid), &info); } @@ -172,6 +183,8 @@ virtio_gpu_base_device_realize(DeviceState *qdev, VirtIOHandleOutput cursor_cb, Error **errp) { + size_t output_idx; + VirtIOGPUOutputList *node; VirtIODevice *vdev = VIRTIO_DEVICE(qdev); VirtIOGPUBase *g = VIRTIO_GPU_BASE(qdev); int i; @@ -181,6 +194,20 @@ virtio_gpu_base_device_realize(DeviceState *qdev, return false; } + for (output_idx = 0, node = g->conf.outputs; + node; output_idx++, node = node->next) { + if (output_idx == g->conf.max_outputs) { + error_setg(errp, "invalid outputs > %d", g->conf.max_outputs); + return false; + } + if (node->value && node->value->name && + strlen(node->value->name) > EDID_NAME_MAX_LENGTH) { + error_setg(errp, "invalid output name '%s' > %d", + node->value->name, EDID_NAME_MAX_LENGTH); + return false; + } + } + if (virtio_gpu_virgl_enabled(g->conf)) { error_setg(&g->migration_blocker, "virgl is not yet migratable"); if (migrate_add_blocker(&g->migration_blocker, errp) < 0) { diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index 0510577..d804f32 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -25,6 +25,7 @@ #include <linux/memfd.h> #include "qemu/memfd.h" #include "standard-headers/linux/udmabuf.h" +#include "standard-headers/drm/drm_fourcc.h" static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res) { @@ -176,16 +177,19 @@ static VGPUDMABuf struct virtio_gpu_rect *r) { VGPUDMABuf *dmabuf; + uint32_t offset = 0; if (res->dmabuf_fd < 0) { return NULL; } dmabuf = g_new0(VGPUDMABuf, 1); - dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride, + dmabuf->buf = qemu_dmabuf_new(r->width, r->height, + &offset, &fb->stride, r->x, r->y, fb->width, fb->height, qemu_pixman_to_drm_format(fb->format), - 0, res->dmabuf_fd, true, false); + DRM_FORMAT_MOD_INVALID, &res->dmabuf_fd, + 1, true, false); dmabuf->scanout_id = scanout_id; QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next); diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index 145a0b3..07f6355 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -134,6 +134,8 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g, res->mr = mr; + trace_virtio_gpu_cmd_res_map_blob(res->base.resource_id, vmr, mr); + return 0; } @@ -153,6 +155,8 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g, vmr = to_hostmem_region(res->mr); + trace_virtio_gpu_cmd_res_unmap_blob(res->base.resource_id, mr, vmr->finish_unmapping); + /* * Perform async unmapping in 3 steps: * @@ -970,6 +974,15 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, } trace_virtio_gpu_fence_ctrl(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type); +#if VIRGL_VERSION_MAJOR >= 1 + if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX) { + virgl_renderer_context_create_fence(cmd->cmd_hdr.ctx_id, + VIRGL_RENDERER_FENCE_FLAG_MERGEABLE, + cmd->cmd_hdr.ring_idx, + cmd->cmd_hdr.fence_id); + return; + } +#endif virgl_renderer_create_fence(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type); } @@ -983,6 +996,11 @@ static void virgl_write_fence(void *opaque, uint32_t fence) * the guest can end up emitting fences out of order * so we should check all fenced cmds not just the first one. */ +#if VIRGL_VERSION_MAJOR >= 1 + if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX) { + continue; + } +#endif if (cmd->cmd_hdr.fence_id > fence) { continue; } @@ -997,6 +1015,29 @@ static void virgl_write_fence(void *opaque, uint32_t fence) } } +#if VIRGL_VERSION_MAJOR >= 1 +static void virgl_write_context_fence(void *opaque, uint32_t ctx_id, + uint32_t ring_idx, uint64_t fence_id) { + VirtIOGPU *g = opaque; + struct virtio_gpu_ctrl_command *cmd, *tmp; + + QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) { + if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX && + cmd->cmd_hdr.ctx_id == ctx_id && cmd->cmd_hdr.ring_idx == ring_idx && + cmd->cmd_hdr.fence_id <= fence_id) { + trace_virtio_gpu_fence_resp(cmd->cmd_hdr.fence_id); + virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NODATA); + QTAILQ_REMOVE(&g->fenceq, cmd, next); + g_free(cmd); + g->inflight--; + if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { + trace_virtio_gpu_dec_inflight_fences(g->inflight); + } + } + } +} +#endif + static virgl_renderer_gl_context virgl_create_context(void *opaque, int scanout_idx, struct virgl_renderer_gl_ctx_param *params) @@ -1031,11 +1072,18 @@ static int virgl_make_context_current(void *opaque, int scanout_idx, } static struct virgl_renderer_callbacks virtio_gpu_3d_cbs = { +#if VIRGL_VERSION_MAJOR >= 1 + .version = 3, +#else .version = 1, +#endif .write_fence = virgl_write_fence, .create_gl_context = virgl_create_context, .destroy_gl_context = virgl_destroy_context, .make_current = virgl_make_context_current, +#if VIRGL_VERSION_MAJOR >= 1 + .write_context_fence = virgl_write_context_fence, +#endif }; static void virtio_gpu_print_stats(void *opaque) diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 0a1a625..43e88a4 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -242,6 +242,7 @@ static uint32_t calc_image_hostmem(pixman_format_code_t pformat, static void virtio_gpu_resource_create_2d(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd) { + Error *err = NULL; pixman_format_code_t pformat; struct virtio_gpu_simple_resource *res; struct virtio_gpu_resource_create_2d c2d; @@ -293,7 +294,8 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g, c2d.width, c2d.height, c2d.height ? res->hostmem / c2d.height : 0, - &error_warn)) { + &err)) { + warn_report_err(err); goto end; } } @@ -1223,7 +1225,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size, { VirtIOGPU *g = opaque; struct virtio_gpu_simple_resource *res; - int i; + Error *err = NULL; + int i, ret; /* in 2d mode we should never find unprocessed commands here */ assert(QTAILQ_EMPTY(&g->cmdq)); @@ -1246,7 +1249,12 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size, } qemu_put_be32(f, 0); /* end of list */ - return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL); + ret = vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL, + &err); + if (ret < 0) { + error_report_err(err); + } + return ret; } static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g, @@ -1282,9 +1290,10 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, const VMStateField *field) { VirtIOGPU *g = opaque; + Error *err = NULL; struct virtio_gpu_simple_resource *res; uint32_t resource_id, pformat; - int i; + int i, ret; g->hostmem = 0; @@ -1317,7 +1326,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, res->width, res->height, res->height ? res->hostmem / res->height : 0, - &error_warn)) { + &err)) { + warn_report_err(err); g_free(res); return -EINVAL; } @@ -1343,9 +1353,11 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, } /* load & apply scanout state */ - vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1); - - return 0; + ret = vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1, &err); + if (ret < 0) { + error_report_err(err); + } + return ret; } static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size, diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 544bb65..bc1a8ed 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -618,7 +618,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s) uint32_t cmd, colour; int args, len, maxloop = 1024; int x, y, dx, dy, width, height; - struct vmsvga_cursor_definition_s cursor; + QEMU_UNINITIALIZED struct vmsvga_cursor_definition_s cursor; uint32_t cmd_start; len = vmsvga_fifo_length(s); diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 22822fe..164fd0b 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -283,8 +283,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src, scale = surface_height(surface) - 1; break; default: - scale = 0x8000; - break; + g_assert_not_reached(); } xenfb->axis[move->axis] = move->value * scale / 0x7fff; } diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 7c980ee..a248b94 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -435,7 +435,18 @@ static void xlnx_dp_aux_clear_rx_fifo(XlnxDPState *s) static void xlnx_dp_aux_push_rx_fifo(XlnxDPState *s, uint8_t *buf, size_t len) { + size_t avail = fifo8_num_free(&s->rx_fifo); DPRINTF("Push %u data in rx_fifo\n", (unsigned)len); + if (len > avail) { + /* + * Data sheet doesn't specify behaviour here: we choose to ignore + * the excess data. + */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: ignoring %zu bytes pushed to full RX_FIFO\n", + __func__, len - avail); + len = avail; + } fifo8_push_all(&s->rx_fifo, buf, len); } @@ -466,7 +477,18 @@ static void xlnx_dp_aux_clear_tx_fifo(XlnxDPState *s) static void xlnx_dp_aux_push_tx_fifo(XlnxDPState *s, uint8_t *buf, size_t len) { + size_t avail = fifo8_num_free(&s->tx_fifo); DPRINTF("Push %u data in tx_fifo\n", (unsigned)len); + if (len > avail) { + /* + * Data sheet doesn't specify behaviour here: we choose to ignore + * the excess data. + */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: ignoring %zu bytes pushed to full TX_FIFO\n", + __func__, len - avail); + len = avail; + } fifo8_push_all(&s->tx_fifo, buf, len); } @@ -475,8 +497,10 @@ static uint8_t xlnx_dp_aux_pop_tx_fifo(XlnxDPState *s) uint8_t ret; if (fifo8_is_empty(&s->tx_fifo)) { - error_report("%s: TX_FIFO underflow", __func__); - abort(); + /* Data sheet doesn't specify behaviour here: we choose to return 0 */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: attempt to read empty TX_FIFO\n", + __func__); + return 0; } ret = fifo8_pop(&s->tx_fifo); DPRINTF("pop 0x%2.2X from tx_fifo.\n", ret); @@ -641,14 +665,28 @@ static void xlnx_dp_change_graphic_fmt(XlnxDPState *s) case DP_GRAPHIC_BGR888: s->g_plane.format = PIXMAN_b8g8r8; break; + case DP_GRAPHIC_RGBA5551: + case DP_GRAPHIC_RGBA4444: + case DP_GRAPHIC_8BPP: + case DP_GRAPHIC_4BPP: + case DP_GRAPHIC_2BPP: + case DP_GRAPHIC_1BPP: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented graphic format %u", + __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK); + s->g_plane.format = PIXMAN_r8g8b8a8; + break; default: - error_report("%s: unsupported graphic format %u", __func__, - s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK); - abort(); + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid graphic format %u", + __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK); + s->g_plane.format = PIXMAN_r8g8b8a8; + break; } switch (s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK) { case 0: + /* This is DP_NL_VID_CB_Y0_CR_Y1 ??? */ s->v_plane.format = PIXMAN_x8b8g8r8; break; case DP_NL_VID_Y0_CB_Y1_CR: @@ -657,10 +695,39 @@ static void xlnx_dp_change_graphic_fmt(XlnxDPState *s) case DP_NL_VID_RGBA8880: s->v_plane.format = PIXMAN_x8b8g8r8; break; + case DP_NL_VID_CR_Y0_CB_Y1: + case DP_NL_VID_Y0_CR_Y1_CB: + case DP_NL_VID_YV16: + case DP_NL_VID_YV24: + case DP_NL_VID_YV16CL: + case DP_NL_VID_MONO: + case DP_NL_VID_YV16CL2: + case DP_NL_VID_YUV444: + case DP_NL_VID_RGB888: + case DP_NL_VID_RGB888_10BPC: + case DP_NL_VID_YUV444_10BPC: + case DP_NL_VID_YV16CL2_10BPC: + case DP_NL_VID_YV16CL_10BPC: + case DP_NL_VID_YV16_10BPC: + case DP_NL_VID_YV24_10BPC: + case DP_NL_VID_Y_ONLY_10BPC: + case DP_NL_VID_YV16_420: + case DP_NL_VID_YV16CL_420: + case DP_NL_VID_YV16CL2_420: + case DP_NL_VID_YV16_420_10BPC: + case DP_NL_VID_YV16CL_420_10BPC: + case DP_NL_VID_YV16CL2_420_10BPC: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented video format %u", + __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK); + s->v_plane.format = PIXMAN_x8b8g8r8; + break; default: - error_report("%s: unsupported video format %u", __func__, - s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK); - abort(); + qemu_log_mask(LOG_UNIMP, "%s: invalid video format %u", + __func__, + s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK); + s->v_plane.format = PIXMAN_x8b8g8r8; + break; } xlnx_dp_recreate_surface(s); @@ -1267,14 +1334,18 @@ static void xlnx_dp_init(Object *obj) s->aux_bus = aux_bus_init(DEVICE(obj), "aux"); /* - * Initialize DPCD and EDID.. + * Initialize DPCD and EDID. Once we have added the objects as + * child properties of this device, we can drop the reference we + * hold to them, leaving the child-property as the only reference. */ s->dpcd = DPCD(qdev_new("dpcd")); object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd)); + object_unref(s->dpcd); s->edid = I2CDDC(qdev_new("i2c-ddc")); i2c_slave_set_address(I2C_SLAVE(s->edid), 0x50); object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid)); + object_unref(s->edid); fifo8_create(&s->rx_fifo, 16); fifo8_create(&s->tx_fifo, 16); @@ -1302,7 +1373,7 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) DisplaySurface *surface; struct audsettings as; - if (!AUD_register_card("xlnx_dp.audio", &s->aud_card, errp)) { + if (!AUD_backend_check(&s->audio_be, errp)) { return; } @@ -1311,8 +1382,8 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) qdev_realize(DEVICE(s->dpcd), BUS(s->aux_bus), &error_fatal); aux_map_slave(AUX_SLAVE(s->dpcd), 0x0000); - qdev_realize_and_unref(DEVICE(s->edid), BUS(aux_get_i2c_bus(s->aux_bus)), - &error_fatal); + qdev_realize(DEVICE(s->edid), BUS(aux_get_i2c_bus(s->aux_bus)), + &error_fatal); s->console = graphic_console_init(dev, 0, &xlnx_dp_gfx_ops, s); surface = qemu_console_surface(s->console); @@ -1324,13 +1395,13 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; - s->amixer_output_stream = AUD_open_out(&s->aud_card, + s->amixer_output_stream = AUD_open_out(s->audio_be, s->amixer_output_stream, "xlnx_dp.audio.out", s, xlnx_dp_audio_callback, &as); - AUD_set_volume_out(s->amixer_output_stream, 0, 255, 255); + AUD_set_volume_out_lr(s->amixer_output_stream, 0, 255, 255); xlnx_dp_audio_activate(s); s->vblank = ptimer_init(vblank_hit, s, DP_VBLANK_PTIMER_POLICY); ptimer_transaction_begin(s->vblank); @@ -1388,7 +1459,7 @@ static void xlnx_dp_reset(DeviceState *dev) } static const Property xlnx_dp_device_properties[] = { - DEFINE_AUDIO_PROPERTIES(XlnxDPState, aud_card), + DEFINE_AUDIO_PROPERTIES(XlnxDPState, audio_be), }; static void xlnx_dp_class_init(ObjectClass *oc, const void *data) |
