diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-05-18 16:37:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-05-18 16:37:09 +0100 |
commit | a28c9c8c9fc42484efe1bf5a77affe842e54e38b (patch) | |
tree | f0975d07b7c1062416c7c8555c8c9cb1ad1d7ac2 | |
parent | debe78ce14bf8f8940c2bdf3ef387505e9e035a9 (diff) | |
parent | 3fcf15df0073a76d37e2816597771d4c9763e413 (diff) |
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200518-pull-request' into staging
vga: ati-vga bugfix, ramfb cleanups and fixes.
# gpg: Signature made Mon 18 May 2020 16:12:11 BST
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/vga-20200518-pull-request:
ramfb: fix size calculation
ramfb: add sanity checks to ramfb_create_display_surface
ramfb: don't update RAMFBState on errors
ramfb: drop leftover debug message
Revert "hw/display/ramfb: lock guest resolution after it's set"
Revert "hw/display/ramfb: initialize fw-config space with xres/ yres"
hw/display: Include local 'framebuffer.h'
ati-vga: Do not allow unaligned access via index register
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/display/artist.c | 2 | ||||
-rw-r--r-- | hw/display/ati.c | 2 | ||||
-rw-r--r-- | hw/display/next-fb.c | 2 | ||||
-rw-r--r-- | hw/display/ramfb-standalone.c | 12 | ||||
-rw-r--r-- | hw/display/ramfb.c | 79 | ||||
-rw-r--r-- | hw/vfio/display.c | 4 | ||||
-rw-r--r-- | include/hw/display/ramfb.h | 2 | ||||
-rw-r--r-- | stubs/ramfb.c | 2 |
8 files changed, 38 insertions, 67 deletions
diff --git a/hw/display/artist.c b/hw/display/artist.c index 7e2a4556bd..6261bfe65b 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -21,7 +21,7 @@ #include "migration/vmstate.h" #include "ui/console.h" #include "trace.h" -#include "hw/display/framebuffer.h" +#include "framebuffer.h" #define TYPE_ARTIST "artist" #define ARTIST(obj) OBJECT_CHECK(ARTISTState, (obj), TYPE_ARTIST) diff --git a/hw/display/ati.c b/hw/display/ati.c index 58ec8291d4..065f197678 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -511,7 +511,7 @@ static void ati_mm_write(void *opaque, hwaddr addr, } switch (addr) { case MM_INDEX: - s->regs.mm_index = data; + s->regs.mm_index = data & ~3; break; case MM_DATA ... MM_DATA + 3: /* indexed access to regs or memory */ diff --git a/hw/display/next-fb.c b/hw/display/next-fb.c index 2b726a10f8..b0513a8fba 100644 --- a/hw/display/next-fb.c +++ b/hw/display/next-fb.c @@ -27,7 +27,7 @@ #include "hw/hw.h" #include "hw/boards.h" #include "hw/loader.h" -#include "hw/display/framebuffer.h" +#include "framebuffer.h" #include "ui/pixel_ops.h" #include "hw/m68k/next-cube.h" diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c index d76a9d0fe2..b18db97eeb 100644 --- a/hw/display/ramfb-standalone.c +++ b/hw/display/ramfb-standalone.c @@ -3,7 +3,6 @@ #include "qemu/module.h" #include "hw/loader.h" #include "hw/qdev-properties.h" -#include "hw/isa/isa.h" #include "hw/display/ramfb.h" #include "ui/console.h" @@ -13,8 +12,6 @@ typedef struct RAMFBStandaloneState { SysBusDevice parent_obj; QemuConsole *con; RAMFBState *state; - uint32_t xres; - uint32_t yres; } RAMFBStandaloneState; static void display_update_wrapper(void *dev) @@ -37,22 +34,15 @@ 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(dev, errp); + ramfb->state = ramfb_setup(errp); } -static Property ramfb_properties[] = { - DEFINE_PROP_UINT32("xres", RAMFBStandaloneState, xres, 0), - DEFINE_PROP_UINT32("yres", RAMFBStandaloneState, yres, 0), - DEFINE_PROP_END_OF_LIST(), -}; - static void ramfb_class_initfn(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); dc->realize = ramfb_realizefn; - device_class_set_props(dc, ramfb_properties); dc->desc = "ram framebuffer standalone device"; dc->user_creatable = true; } diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index 7ba07c80f6..79b9754a58 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -13,9 +13,9 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qemu/option.h" #include "hw/loader.h" #include "hw/display/ramfb.h" +#include "hw/display/bochs-vbe.h" /* for limits */ #include "ui/console.h" #include "sysemu/reset.h" @@ -31,9 +31,7 @@ struct QEMU_PACKED RAMFBCfg { struct RAMFBState { DisplaySurface *ds; uint32_t width, height; - uint32_t starting_width, starting_height; struct RAMFBCfg cfg; - bool locked; }; static void ramfb_unmap_display_surface(pixman_image_t *image, void *unused) @@ -46,25 +44,31 @@ static void ramfb_unmap_display_surface(pixman_image_t *image, void *unused) static DisplaySurface *ramfb_create_display_surface(int width, int height, pixman_format_code_t format, - int linesize, uint64_t addr) + hwaddr stride, hwaddr addr) { DisplaySurface *surface; - hwaddr size; + hwaddr size, mapsize, linesize; void *data; - if (linesize == 0) { - linesize = width * PIXMAN_FORMAT_BPP(format) / 8; + if (width < 16 || width > VBE_DISPI_MAX_XRES || + height < 16 || height > VBE_DISPI_MAX_YRES || + format == 0 /* unknown format */) + return NULL; + + linesize = width * PIXMAN_FORMAT_BPP(format) / 8; + if (stride == 0) { + stride = linesize; } - size = (hwaddr)linesize * height; - data = cpu_physical_memory_map(addr, &size, false); - if (size != (hwaddr)linesize * height) { - cpu_physical_memory_unmap(data, size, 0, 0); + mapsize = size = stride * (height - 1) + linesize; + data = cpu_physical_memory_map(addr, &mapsize, false); + if (size != mapsize) { + cpu_physical_memory_unmap(data, mapsize, 0, 0); return NULL; } surface = qemu_create_displaysurface_from(width, height, - format, linesize, data); + format, stride, data); pixman_image_set_destroy_function(surface->image, ramfb_unmap_display_surface, NULL); @@ -74,27 +78,26 @@ static DisplaySurface *ramfb_create_display_surface(int width, int height, static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len) { RAMFBState *s = dev; + DisplaySurface *surface; uint32_t fourcc, format, width, height; hwaddr stride, addr; - width = be32_to_cpu(s->cfg.width); - height = be32_to_cpu(s->cfg.height); - stride = be32_to_cpu(s->cfg.stride); - fourcc = be32_to_cpu(s->cfg.fourcc); - addr = be64_to_cpu(s->cfg.addr); - format = qemu_drm_format_to_pixman(fourcc); - - fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__, - width, height, addr); - if (s->locked) { - fprintf(stderr, "%s: resolution locked, change rejected\n", __func__); + width = be32_to_cpu(s->cfg.width); + height = be32_to_cpu(s->cfg.height); + stride = be32_to_cpu(s->cfg.stride); + fourcc = be32_to_cpu(s->cfg.fourcc); + addr = be64_to_cpu(s->cfg.addr); + format = qemu_drm_format_to_pixman(fourcc); + + surface = ramfb_create_display_surface(width, height, + format, stride, addr); + if (!surface) { return; } - s->locked = true; + s->width = width; s->height = height; - s->ds = ramfb_create_display_surface(s->width, s->height, - format, stride, addr); + s->ds = surface; } void ramfb_display_update(QemuConsole *con, RAMFBState *s) @@ -112,16 +115,7 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) dpy_gfx_update_full(con); } -static void ramfb_reset(void *opaque) -{ - RAMFBState *s = (RAMFBState *)opaque; - s->locked = false; - memset(&s->cfg, 0, sizeof(s->cfg)); - s->cfg.width = s->starting_width; - s->cfg.height = s->starting_height; -} - -RAMFBState *ramfb_setup(DeviceState* dev, Error **errp) +RAMFBState *ramfb_setup(Error **errp) { FWCfgState *fw_cfg = fw_cfg_find(); RAMFBState *s; @@ -133,22 +127,9 @@ RAMFBState *ramfb_setup(DeviceState* dev, Error **errp) s = g_new0(RAMFBState, 1); - const char *s_fb_width = qemu_opt_get(dev->opts, "xres"); - const char *s_fb_height = qemu_opt_get(dev->opts, "yres"); - if (s_fb_width) { - s->cfg.width = atoi(s_fb_width); - s->starting_width = s->cfg.width; - } - if (s_fb_height) { - s->cfg.height = atoi(s_fb_height); - s->starting_height = s->cfg.height; - } - s->locked = false; - 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); - qemu_register_reset(ramfb_reset, s); return s; } diff --git a/hw/vfio/display.c b/hw/vfio/display.c index f4977c66e1..a57a22674d 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -353,7 +353,7 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp) &vfio_display_dmabuf_ops, vdev); if (vdev->enable_ramfb) { - vdev->dpy->ramfb = ramfb_setup(DEVICE(vdev), errp); + vdev->dpy->ramfb = ramfb_setup(errp); } vfio_display_edid_init(vdev); return 0; @@ -479,7 +479,7 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp) &vfio_display_region_ops, vdev); if (vdev->enable_ramfb) { - vdev->dpy->ramfb = ramfb_setup(DEVICE(vdev), errp); + vdev->dpy->ramfb = ramfb_setup(errp); } return 0; } diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h index f6c2de93b2..b33a2c467b 100644 --- a/include/hw/display/ramfb.h +++ b/include/hw/display/ramfb.h @@ -4,7 +4,7 @@ /* ramfb.c */ typedef struct RAMFBState RAMFBState; void ramfb_display_update(QemuConsole *con, RAMFBState *s); -RAMFBState *ramfb_setup(DeviceState *dev, Error **errp); +RAMFBState *ramfb_setup(Error **errp); /* ramfb-standalone.c */ #define TYPE_RAMFB_DEVICE "ramfb" diff --git a/stubs/ramfb.c b/stubs/ramfb.c index 0799093a5d..48143f3354 100644 --- a/stubs/ramfb.c +++ b/stubs/ramfb.c @@ -6,7 +6,7 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) { } -RAMFBState *ramfb_setup(DeviceState* dev, Error **errp) +RAMFBState *ramfb_setup(Error **errp) { error_setg(errp, "ramfb support not available"); return NULL; |