diff options
Diffstat (limited to 'hw/display')
-rw-r--r-- | hw/display/Makefile.objs | 4 | ||||
-rw-r--r-- | hw/display/bcm2835_fb.c | 2 | ||||
-rw-r--r-- | hw/display/bochs-display.c | 13 | ||||
-rw-r--r-- | hw/display/cg3.c | 2 | ||||
-rw-r--r-- | hw/display/cirrus_vga.c | 143 | ||||
-rw-r--r-- | hw/display/cirrus_vga_internal.h | 103 | ||||
-rw-r--r-- | hw/display/cirrus_vga_isa.c | 98 | ||||
-rw-r--r-- | hw/display/edid-generate.c | 10 | ||||
-rw-r--r-- | hw/display/qxl.c | 47 | ||||
-rw-r--r-- | hw/display/qxl.h | 1 | ||||
-rw-r--r-- | hw/display/tcx.c | 2 | ||||
-rw-r--r-- | hw/display/vga-pci.c | 8 | ||||
-rw-r--r-- | hw/display/vga_int.h | 1 |
13 files changed, 277 insertions, 157 deletions
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index 780a76b9f0..97acd5b6cb 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -5,6 +5,7 @@ common-obj-$(CONFIG_FW_CFG_DMA) += ramfb-standalone.o common-obj-$(CONFIG_ADS7846) += ads7846.o common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o +common-obj-$(call land,$(CONFIG_VGA_CIRRUS),$(CONFIG_VGA_ISA))+=cirrus_vga_isa.o common-obj-$(CONFIG_G364FB) += g364fb.o common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o common-obj-$(CONFIG_PL110) += pl110.o @@ -14,11 +15,12 @@ common-obj-$(CONFIG_SSD0323) += ssd0323.o common-obj-$(CONFIG_XEN) += xenfb.o common-obj-$(CONFIG_VGA_PCI) += vga-pci.o -common-obj-$(CONFIG_VGA_PCI) += bochs-display.o common-obj-$(CONFIG_VGA_PCI) += edid-region.o common-obj-$(CONFIG_VGA_ISA) += vga-isa.o common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o +common-obj-$(CONFIG_BOCHS_DISPLAY) += bochs-display.o +common-obj-$(CONFIG_BOCHS_DISPLAY) += edid-region.o common-obj-$(CONFIG_BLIZZARD) += blizzard.o common-obj-$(CONFIG_EXYNOS4) += exynos4210_fimd.o diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index d534d00a65..599863e4e1 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -190,7 +190,7 @@ static void fb_update_display(void *opaque) } if (s->invalidate) { - hwaddr base = s->config.base + xoff + yoff * src_width; + hwaddr base = s->config.base + xoff + (hwaddr)yoff * src_width; framebuffer_update_memory_section(&s->fbsection, s->dma_mr, base, s->config.yres, src_width); diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index 09d8944a1b..3d439eb240 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -9,6 +9,7 @@ #include "hw/hw.h" #include "hw/pci/pci.h" #include "hw/display/bochs-vbe.h" +#include "hw/display/edid.h" #include "qapi/error.h" @@ -35,9 +36,13 @@ typedef struct BochsDisplayState { MemoryRegion mmio; MemoryRegion vbe; MemoryRegion qext; + MemoryRegion edid; /* device config */ uint64_t vgamem; + bool enable_edid; + qemu_edid_info edid_info; + uint8_t edid_blob[256]; /* device registers */ uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; @@ -283,6 +288,12 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp) pci_register_bar(&s->pci, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); pci_register_bar(&s->pci, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); + if (s->enable_edid) { + qemu_edid_generate(s->edid_blob, sizeof(s->edid_blob), &s->edid_info); + qemu_edid_region_io(&s->edid, obj, s->edid_blob, sizeof(s->edid_blob)); + memory_region_add_subregion(&s->mmio, 0, &s->edid); + } + if (pci_bus_is_express(pci_get_bus(dev))) { dev->cap_present |= QEMU_PCI_CAP_EXPRESS; ret = pcie_endpoint_cap_init(dev, 0x80); @@ -325,6 +336,8 @@ static void bochs_display_exit(PCIDevice *dev) static Property bochs_display_properties[] = { DEFINE_PROP_SIZE("vgamem", BochsDisplayState, vgamem, 16 * MiB), + DEFINE_PROP_BOOL("edid", BochsDisplayState, enable_edid, false), + DEFINE_EDID_PROPERTIES(BochsDisplayState, edid_info), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/display/cg3.c b/hw/display/cg3.c index 1c199ab369..e50d97e48c 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -307,7 +307,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp) ret = load_image_mr(fcode_filename, &s->rom); g_free(fcode_filename); if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) { - error_report("cg3: could not load prom '%s'", CG3_ROM_FILE); + warn_report("cg3: could not load prom '%s'", CG3_ROM_FILE); } } diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 04c87c8e8d..d9b854d74d 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -33,8 +33,8 @@ #include "hw/hw.h" #include "hw/pci/pci.h" #include "ui/pixel_ops.h" -#include "vga_int.h" #include "hw/loader.h" +#include "cirrus_vga_internal.h" /* * TODO: @@ -52,16 +52,6 @@ * ***************************************/ -// ID -#define CIRRUS_ID_CLGD5422 (0x23<<2) -#define CIRRUS_ID_CLGD5426 (0x24<<2) -#define CIRRUS_ID_CLGD5424 (0x25<<2) -#define CIRRUS_ID_CLGD5428 (0x26<<2) -#define CIRRUS_ID_CLGD5430 (0x28<<2) -#define CIRRUS_ID_CLGD5434 (0x2A<<2) -#define CIRRUS_ID_CLGD5436 (0x2B<<2) -#define CIRRUS_ID_CLGD5446 (0x2E<<2) - // sequencer 0x07 #define CIRRUS_SR7_BPP_VGA 0x00 #define CIRRUS_SR7_BPP_SVGA 0x01 @@ -176,65 +166,10 @@ #define CIRRUS_PNPMMIO_SIZE 0x1000 -struct CirrusVGAState; -typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, - uint32_t dstaddr, uint32_t srcaddr, - int dstpitch, int srcpitch, - int bltwidth, int bltheight); typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, uint32_t dstaddr, int dst_pitch, int width, int height); -typedef struct CirrusVGAState { - VGACommonState vga; - - MemoryRegion cirrus_vga_io; - MemoryRegion cirrus_linear_io; - MemoryRegion cirrus_linear_bitblt_io; - MemoryRegion cirrus_mmio_io; - MemoryRegion pci_bar; - bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ - MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ - MemoryRegion low_mem; /* always mapped, overridden by: */ - MemoryRegion cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ - uint32_t cirrus_addr_mask; - uint32_t linear_mmio_mask; - uint8_t cirrus_shadow_gr0; - uint8_t cirrus_shadow_gr1; - uint8_t cirrus_hidden_dac_lockindex; - uint8_t cirrus_hidden_dac_data; - uint32_t cirrus_bank_base[2]; - uint32_t cirrus_bank_limit[2]; - uint8_t cirrus_hidden_palette[48]; - bool enable_blitter; - int cirrus_blt_pixelwidth; - int cirrus_blt_width; - int cirrus_blt_height; - int cirrus_blt_dstpitch; - int cirrus_blt_srcpitch; - uint32_t cirrus_blt_fgcol; - uint32_t cirrus_blt_bgcol; - uint32_t cirrus_blt_dstaddr; - uint32_t cirrus_blt_srcaddr; - uint8_t cirrus_blt_mode; - uint8_t cirrus_blt_modeext; - cirrus_bitblt_rop_t cirrus_rop; -#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */ - uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE]; - uint8_t *cirrus_srcptr; - uint8_t *cirrus_srcptr_end; - uint32_t cirrus_srccounter; - /* hwcursor display state */ - int last_hw_cursor_size; - int last_hw_cursor_x; - int last_hw_cursor_y; - int last_hw_cursor_y_start; - int last_hw_cursor_y_end; - int real_vram_size; /* XXX: suppress that */ - int device_id; - int bustype; -} CirrusVGAState; - typedef struct PCICirrusVGAState { PCIDevice dev; CirrusVGAState cirrus_vga; @@ -244,16 +179,6 @@ typedef struct PCICirrusVGAState { #define PCI_CIRRUS_VGA(obj) \ OBJECT_CHECK(PCICirrusVGAState, (obj), TYPE_PCI_CIRRUS_VGA) -#define TYPE_ISA_CIRRUS_VGA "isa-cirrus-vga" -#define ISA_CIRRUS_VGA(obj) \ - OBJECT_CHECK(ISACirrusVGAState, (obj), TYPE_ISA_CIRRUS_VGA) - -typedef struct ISACirrusVGAState { - ISADevice parent_obj; - - CirrusVGAState cirrus_vga; -} ISACirrusVGAState; - static uint8_t rop_to_index[256]; /*************************************** @@ -2829,7 +2754,7 @@ static int cirrus_post_load(void *opaque, int version_id) return 0; } -static const VMStateDescription vmstate_cirrus_vga = { +const VMStateDescription vmstate_cirrus_vga = { .name = "cirrus_vga", .version_id = 2, .minimum_version_id = 1, @@ -2932,10 +2857,9 @@ static const MemoryRegionOps cirrus_vga_io_ops = { }, }; -static void cirrus_init_common(CirrusVGAState *s, Object *owner, - int device_id, int is_pci, - MemoryRegion *system_memory, - MemoryRegion *system_io) +void cirrus_init_common(CirrusVGAState *s, Object *owner, + int device_id, int is_pci, + MemoryRegion *system_memory, MemoryRegion *system_io) { int i; static int inited; @@ -3031,62 +2955,6 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner, /*************************************** * - * ISA bus support - * - ***************************************/ - -static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) -{ - ISADevice *isadev = ISA_DEVICE(dev); - ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); - VGACommonState *s = &d->cirrus_vga.vga; - - /* follow real hardware, cirrus card emulated has 4 MB video memory. - Also accept 8 MB/16 MB for backward compatibility. */ - if (s->vram_size_mb != 4 && s->vram_size_mb != 8 && - s->vram_size_mb != 16) { - error_setg(errp, "Invalid cirrus_vga ram size '%u'", - s->vram_size_mb); - return; - } - s->global_vmstate = true; - vga_common_init(s, OBJECT(dev)); - cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, - isa_address_space(isadev), - isa_address_space_io(isadev)); - s->con = graphic_console_init(dev, 0, s->hw_ops, s); - rom_add_vga(VGABIOS_CIRRUS_FILENAME); - /* XXX ISA-LFB support */ - /* FIXME not qdev yet */ -} - -static Property isa_cirrus_vga_properties[] = { - DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, - cirrus_vga.vga.vram_size_mb, 4), - DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, - cirrus_vga.enable_blitter, true), - DEFINE_PROP_END_OF_LIST(), -}; - -static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->vmsd = &vmstate_cirrus_vga; - dc->realize = isa_cirrus_vga_realizefn; - dc->props = isa_cirrus_vga_properties; - set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); -} - -static const TypeInfo isa_cirrus_vga_info = { - .name = TYPE_ISA_CIRRUS_VGA, - .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(ISACirrusVGAState), - .class_init = isa_cirrus_vga_class_init, -}; - -/*************************************** - * * PCI bus support * ***************************************/ @@ -3171,7 +3039,6 @@ static const TypeInfo cirrus_vga_info = { static void cirrus_vga_register_types(void) { - type_register_static(&isa_cirrus_vga_info); type_register_static(&cirrus_vga_info); } diff --git a/hw/display/cirrus_vga_internal.h b/hw/display/cirrus_vga_internal.h new file mode 100644 index 0000000000..a78ebbd920 --- /dev/null +++ b/hw/display/cirrus_vga_internal.h @@ -0,0 +1,103 @@ +/* + * QEMU Cirrus CLGD 54xx VGA Emulator, ISA bus support + * + * Copyright (c) 2004 Fabrice Bellard + * Copyright (c) 2004 Makoto Suzuki (suzu) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef CIRRUS_VGA_INTERNAL_H +#define CIRRUS_VGA_INTERNAL_H + +#include "vga_int.h" + +/* IDs */ +#define CIRRUS_ID_CLGD5422 (0x23 << 2) +#define CIRRUS_ID_CLGD5426 (0x24 << 2) +#define CIRRUS_ID_CLGD5424 (0x25 << 2) +#define CIRRUS_ID_CLGD5428 (0x26 << 2) +#define CIRRUS_ID_CLGD5430 (0x28 << 2) +#define CIRRUS_ID_CLGD5434 (0x2A << 2) +#define CIRRUS_ID_CLGD5436 (0x2B << 2) +#define CIRRUS_ID_CLGD5446 (0x2E << 2) + +extern const VMStateDescription vmstate_cirrus_vga; + +struct CirrusVGAState; +typedef void (*cirrus_bitblt_rop_t)(struct CirrusVGAState *s, + uint32_t dstaddr, uint32_t srcaddr, + int dstpitch, int srcpitch, + int bltwidth, int bltheight); + +typedef struct CirrusVGAState { + VGACommonState vga; + + MemoryRegion cirrus_vga_io; + MemoryRegion cirrus_linear_io; + MemoryRegion cirrus_linear_bitblt_io; + MemoryRegion cirrus_mmio_io; + MemoryRegion pci_bar; + bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ + MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ + MemoryRegion low_mem; /* always mapped, overridden by: */ + MemoryRegion cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ + uint32_t cirrus_addr_mask; + uint32_t linear_mmio_mask; + uint8_t cirrus_shadow_gr0; + uint8_t cirrus_shadow_gr1; + uint8_t cirrus_hidden_dac_lockindex; + uint8_t cirrus_hidden_dac_data; + uint32_t cirrus_bank_base[2]; + uint32_t cirrus_bank_limit[2]; + uint8_t cirrus_hidden_palette[48]; + bool enable_blitter; + int cirrus_blt_pixelwidth; + int cirrus_blt_width; + int cirrus_blt_height; + int cirrus_blt_dstpitch; + int cirrus_blt_srcpitch; + uint32_t cirrus_blt_fgcol; + uint32_t cirrus_blt_bgcol; + uint32_t cirrus_blt_dstaddr; + uint32_t cirrus_blt_srcaddr; + uint8_t cirrus_blt_mode; + uint8_t cirrus_blt_modeext; + cirrus_bitblt_rop_t cirrus_rop; +#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */ + uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE]; + uint8_t *cirrus_srcptr; + uint8_t *cirrus_srcptr_end; + uint32_t cirrus_srccounter; + /* hwcursor display state */ + int last_hw_cursor_size; + int last_hw_cursor_x; + int last_hw_cursor_y; + int last_hw_cursor_y_start; + int last_hw_cursor_y_end; + int real_vram_size; /* XXX: suppress that */ + int device_id; + int bustype; +} CirrusVGAState; + +void cirrus_init_common(CirrusVGAState *s, Object *owner, + int device_id, int is_pci, + MemoryRegion *system_memory, MemoryRegion *system_io); + +#endif diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c new file mode 100644 index 0000000000..fa10b74230 --- /dev/null +++ b/hw/display/cirrus_vga_isa.c @@ -0,0 +1,98 @@ +/* + * QEMU Cirrus CLGD 54xx VGA Emulator, ISA bus support + * + * Copyright (c) 2004 Fabrice Bellard + * Copyright (c) 2004 Makoto Suzuki (suzu) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/loader.h" +#include "hw/isa/isa.h" +#include "cirrus_vga_internal.h" + +#define TYPE_ISA_CIRRUS_VGA "isa-cirrus-vga" +#define ISA_CIRRUS_VGA(obj) \ + OBJECT_CHECK(ISACirrusVGAState, (obj), TYPE_ISA_CIRRUS_VGA) + +typedef struct ISACirrusVGAState { + ISADevice parent_obj; + + CirrusVGAState cirrus_vga; +} ISACirrusVGAState; + +static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) +{ + ISADevice *isadev = ISA_DEVICE(dev); + ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); + VGACommonState *s = &d->cirrus_vga.vga; + + /* follow real hardware, cirrus card emulated has 4 MB video memory. + Also accept 8 MB/16 MB for backward compatibility. */ + if (s->vram_size_mb != 4 && s->vram_size_mb != 8 && + s->vram_size_mb != 16) { + error_setg(errp, "Invalid cirrus_vga ram size '%u'", + s->vram_size_mb); + return; + } + s->global_vmstate = true; + vga_common_init(s, OBJECT(dev)); + cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, + isa_address_space(isadev), + isa_address_space_io(isadev)); + s->con = graphic_console_init(dev, 0, s->hw_ops, s); + rom_add_vga(VGABIOS_CIRRUS_FILENAME); + /* XXX ISA-LFB support */ + /* FIXME not qdev yet */ +} + +static Property isa_cirrus_vga_properties[] = { + DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, + cirrus_vga.vga.vram_size_mb, 4), + DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, + cirrus_vga.enable_blitter, true), + DEFINE_PROP_END_OF_LIST(), +}; + +static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_cirrus_vga; + dc->realize = isa_cirrus_vga_realizefn; + dc->props = isa_cirrus_vga_properties; + set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); +} + +static const TypeInfo isa_cirrus_vga_info = { + .name = TYPE_ISA_CIRRUS_VGA, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(ISACirrusVGAState), + .class_init = isa_cirrus_vga_class_init, +}; + +static void cirrus_vga_isa_register_types(void) +{ + type_register_static(&isa_cirrus_vga_info); +} + +type_init(cirrus_vga_isa_register_types) diff --git a/hw/display/edid-generate.c b/hw/display/edid-generate.c index c80397ea96..bdf5e1d4d4 100644 --- a/hw/display/edid-generate.c +++ b/hw/display/edid-generate.c @@ -223,7 +223,7 @@ static void edid_desc_timing(uint8_t *desc, uint32_t clock = 75 * (xres + xblank) * (yres + yblank); - *(uint32_t *)(desc) = cpu_to_le32(clock / 10000); + stl_le_p(desc, clock / 10000); desc[2] = xres & 0xff; desc[3] = xblank & 0xff; @@ -301,7 +301,7 @@ void qemu_edid_generate(uint8_t *edid, size_t size, /* =============== set defaults =============== */ if (!info->vendor || strlen(info->vendor) != 3) { - info->vendor = "EMU"; + info->vendor = "RHT"; } if (!info->name) { info->name = "QEMU Monitor"; @@ -342,9 +342,9 @@ void qemu_edid_generate(uint8_t *edid, size_t size, (((info->vendor[2] - '@') & 0x1f) << 0)); uint16_t model_nr = 0x1234; uint32_t serial_nr = info->serial ? atoi(info->serial) : 0; - *(uint16_t *)(edid + 8) = cpu_to_be16(vendor_id); - *(uint16_t *)(edid + 10) = cpu_to_le16(model_nr); - *(uint32_t *)(edid + 12) = cpu_to_le32(serial_nr); + stw_be_p(edid + 8, vendor_id); + stw_le_p(edid + 10, model_nr); + stl_le_p(edid + 12, serial_nr); /* manufacture week and year */ edid[16] = 42; diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 747986478f..9087db5dee 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -290,7 +290,7 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) } cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST); - if (cfg->count == 1) { + if (cfg != NULL && cfg->count == 1) { qxl->guest_primary.resized = 1; qxl->guest_head0_width = cfg->heads[0].width; qxl->guest_head0_height = cfg->heads[0].height; @@ -848,7 +848,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt * qxl->guest_primary.commands++; qxl_track_command(qxl, ext); qxl_log_command(qxl, "csr", ext); - if (qxl->id == 0) { + if (qxl->have_vga) { qxl_render_cursor(qxl, ext); } trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode)); @@ -1255,7 +1255,7 @@ static void qxl_soft_reset(PCIQXLDevice *d) d->current_async = QXL_UNDEFINED_IO; qemu_mutex_unlock(&d->async_lock); - if (d->id == 0) { + if (d->have_vga) { qxl_enter_vga_mode(d); } else { d->mode = QXL_MODE_UNDEFINED; @@ -1893,7 +1893,31 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events) trace_qxl_send_events_vm_stopped(d->id, events); return; } - old_pending = atomic_fetch_or(&d->ram->int_pending, le_events); + /* + * Older versions of Spice forgot to define the QXLRam struct + * with the '__aligned__(4)' attribute. clang 7 and newer will + * thus warn that atomic_fetch_or(&d->ram->int_pending, ...) + * might be a misaligned atomic access, and will generate an + * out-of-line call for it, which results in a link error since + * we don't currently link against libatomic. + * + * In fact we set up d->ram in init_qxl_ram() so it always starts + * at a 4K boundary, so we know that &d->ram->int_pending is + * naturally aligned for a uint32_t. Newer Spice versions + * (with Spice commit beda5ec7a6848be20c0cac2a9a8ef2a41e8069c1) + * will fix the bug directly. To deal with older versions, + * we tell the compiler to assume the address really is aligned. + * Any compiler which cares about the misalignment will have + * __builtin_assume_aligned. + */ +#ifdef HAS_ASSUME_ALIGNED +#define ALIGNED_UINT32_PTR(P) ((uint32_t *)__builtin_assume_aligned(P, 4)) +#else +#define ALIGNED_UINT32_PTR(P) ((uint32_t *)P) +#endif + + old_pending = atomic_fetch_or(ALIGNED_UINT32_PTR(&d->ram->int_pending), + le_events); if ((old_pending & le_events) == le_events) { return; } @@ -2115,7 +2139,7 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) memory_region_init_io(&qxl->io_bar, OBJECT(qxl), &qxl_io_ops, qxl, "qxl-ioports", io_size); - if (qxl->id == 0) { + if (qxl->have_vga) { vga_dirty_log_start(&qxl->vga); } memory_region_set_flush_coalesced(&qxl->io_bar); @@ -2147,7 +2171,7 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) /* print pci bar details */ dprint(qxl, 1, "ram/%s: %" PRId64 " MB [region 0]\n", - qxl->id == 0 ? "pri" : "sec", qxl->vga.vram_size / MiB); + qxl->have_vga ? "pri" : "sec", qxl->vga.vram_size / MiB); dprint(qxl, 1, "vram/32: %" PRIx64 " MB [region 1]\n", qxl->vram32_size / MiB); dprint(qxl, 1, "vram/64: %" PRIx64 " MB %s\n", @@ -2175,7 +2199,6 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp) VGACommonState *vga = &qxl->vga; Error *local_err = NULL; - qxl->id = 0; qxl_init_ramsize(qxl); vga->vbe_size = qxl->vgamem_size; vga->vram_size_mb = qxl->vga.vram_size / MiB; @@ -2186,8 +2209,15 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp) vga, "vga"); portio_list_set_flush_coalesced(&qxl->vga_port_list); portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0); + qxl->have_vga = true; vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl); + qxl->id = qemu_console_get_index(vga->con); /* == channel_id */ + if (qxl->id != 0) { + error_setg(errp, "primary qxl-vga device must be console 0 " + "(first display device on the command line)"); + return; + } qxl_realize_common(qxl, &local_err); if (local_err) { @@ -2202,15 +2232,14 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp) static void qxl_realize_secondary(PCIDevice *dev, Error **errp) { - static int device_id = 1; PCIQXLDevice *qxl = PCI_QXL(dev); - qxl->id = device_id++; qxl_init_ramsize(qxl); memory_region_init_ram(&qxl->vga.vram, OBJECT(dev), "qxl.vgavram", qxl->vga.vram_size, &error_fatal); qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram); qxl->vga.con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl); + qxl->id = qemu_console_get_index(qxl->vga.con); /* == channel_id */ qxl_realize_common(qxl, errp); } diff --git a/hw/display/qxl.h b/hw/display/qxl.h index dd9c0522b7..6f9d1f21fa 100644 --- a/hw/display/qxl.h +++ b/hw/display/qxl.h @@ -34,6 +34,7 @@ typedef struct PCIQXLDevice { PortioList vga_port_list; SimpleSpiceDisplay ssd; int id; + bool have_vga; uint32_t debug; uint32_t guestdebug; uint32_t cmdlog; diff --git a/hw/display/tcx.c b/hw/display/tcx.c index b2786ee8d0..66f2459226 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -823,7 +823,7 @@ static void tcx_realizefn(DeviceState *dev, Error **errp) ret = load_image_mr(fcode_filename, &s->rom); g_free(fcode_filename); if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) { - error_report("tcx: could not load prom '%s'", TCX_ROM_FILE); + warn_report("tcx: could not load prom '%s'", TCX_ROM_FILE); } } diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 24ca1b3e1f..a17c96e703 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -309,6 +309,14 @@ static void pci_secondary_vga_exit(PCIDevice *dev) VGACommonState *s = &d->vga; graphic_console_close(s->con); + memory_region_del_subregion(&d->mmio, &d->mrs[0]); + memory_region_del_subregion(&d->mmio, &d->mrs[1]); + if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) { + memory_region_del_subregion(&d->mmio, &d->mrs[2]); + } + if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_EDID)) { + memory_region_del_subregion(&d->mmio, &d->mrs[3]); + } } static void pci_secondary_vga_init(Object *obj) diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index 6e4fa48a79..55c418eab5 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -166,7 +166,6 @@ MemoryRegion *vga_init_io(VGACommonState *s, Object *obj, const MemoryRegionPortio **vbe_ports); void vga_common_reset(VGACommonState *s); -void vga_sync_dirty_bitmap(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s); void vga_dirty_log_stop(VGACommonState *s); |