summaryrefslogtreecommitdiffstats
path: root/qemu/hw/display
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/display')
-rw-r--r--qemu/hw/display/Makefile.objs45
-rw-r--r--qemu/hw/display/ads7846.c178
-rw-r--r--qemu/hw/display/bcm2835_fb.c425
-rw-r--r--qemu/hw/display/blizzard.c987
-rw-r--r--qemu/hw/display/blizzard_template.h146
-rw-r--r--qemu/hw/display/cg3.c399
-rw-r--r--qemu/hw/display/cirrus_vga.c3091
-rw-r--r--qemu/hw/display/cirrus_vga_rop.h207
-rw-r--r--qemu/hw/display/cirrus_vga_rop2.h281
-rw-r--r--qemu/hw/display/exynos4210_fimd.c1952
-rw-r--r--qemu/hw/display/framebuffer.c125
-rw-r--r--qemu/hw/display/framebuffer.h65
-rw-r--r--qemu/hw/display/g364fb.c559
-rw-r--r--qemu/hw/display/jazz_led.c314
-rw-r--r--qemu/hw/display/milkymist-tmu2.c495
-rw-r--r--qemu/hw/display/milkymist-vgafb.c354
-rw-r--r--qemu/hw/display/milkymist-vgafb_template.h74
-rw-r--r--qemu/hw/display/omap_dss.c1091
-rw-r--r--qemu/hw/display/omap_lcd_template.h175
-rw-r--r--qemu/hw/display/omap_lcdc.c420
-rw-r--r--qemu/hw/display/pl110.c539
-rw-r--r--qemu/hw/display/pl110_template.h399
-rw-r--r--qemu/hw/display/pxa2xx_lcd.c1065
-rw-r--r--qemu/hw/display/pxa2xx_template.h447
-rw-r--r--qemu/hw/display/qxl-logger.c276
-rw-r--r--qemu/hw/display/qxl-render.c298
-rw-r--r--qemu/hw/display/qxl.c2359
-rw-r--r--qemu/hw/display/qxl.h174
-rw-r--r--qemu/hw/display/sm501.c1458
-rw-r--r--qemu/hw/display/sm501_template.h145
-rw-r--r--qemu/hw/display/ssd0303.c331
-rw-r--r--qemu/hw/display/ssd0323.c402
-rw-r--r--qemu/hw/display/tc6393xb.c598
-rw-r--r--qemu/hw/display/tc6393xb_template.h72
-rw-r--r--qemu/hw/display/tcx.c1106
-rw-r--r--qemu/hw/display/vga-helpers.h439
-rw-r--r--qemu/hw/display/vga-isa-mm.c143
-rw-r--r--qemu/hw/display/vga-isa.c106
-rw-r--r--qemu/hw/display/vga-pci.c387
-rw-r--r--qemu/hw/display/vga.c2289
-rw-r--r--qemu/hw/display/vga.h159
-rw-r--r--qemu/hw/display/vga_int.h227
-rw-r--r--qemu/hw/display/virtio-gpu-3d.c606
-rw-r--r--qemu/hw/display/virtio-gpu-pci.c77
-rw-r--r--qemu/hw/display/virtio-gpu.c1087
-rw-r--r--qemu/hw/display/virtio-vga.c193
-rw-r--r--qemu/hw/display/vmware_vga.c1370
-rw-r--r--qemu/hw/display/xenfb.c1004
48 files changed, 0 insertions, 29139 deletions
diff --git a/qemu/hw/display/Makefile.objs b/qemu/hw/display/Makefile.objs
deleted file mode 100644
index d99780eeb..000000000
--- a/qemu/hw/display/Makefile.objs
+++ /dev/null
@@ -1,45 +0,0 @@
-common-obj-$(CONFIG_ADS7846) += ads7846.o
-common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
-common-obj-$(CONFIG_G364FB) += g364fb.o
-common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
-common-obj-$(CONFIG_PL110) += pl110.o
-common-obj-$(CONFIG_SSD0303) += ssd0303.o
-common-obj-$(CONFIG_SSD0323) += ssd0323.o
-common-obj-$(CONFIG_XEN_BACKEND) += xenfb.o
-
-common-obj-$(CONFIG_VGA_PCI) += vga-pci.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_BLIZZARD) += blizzard.o
-common-obj-$(CONFIG_EXYNOS4) += exynos4210_fimd.o
-common-obj-$(CONFIG_FRAMEBUFFER) += framebuffer.o
-common-obj-$(CONFIG_MILKYMIST) += milkymist-vgafb.o
-common-obj-$(CONFIG_ZAURUS) += tc6393xb.o
-
-ifeq ($(CONFIG_MILKYMIST_TMU2),y)
-common-obj-y += milkymist-tmu2.o
-milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS)
-milkymist-tmu2.o-libs += $(OPENGL_LIBS)
-endif
-
-obj-$(CONFIG_OMAP) += omap_dss.o
-obj-$(CONFIG_OMAP) += omap_lcdc.o
-obj-$(CONFIG_PXA2XX) += pxa2xx_lcd.o
-obj-$(CONFIG_RASPI) += bcm2835_fb.o
-obj-$(CONFIG_SM501) += sm501.o
-obj-$(CONFIG_TCX) += tcx.o
-obj-$(CONFIG_CG3) += cg3.o
-
-obj-$(CONFIG_VGA) += vga.o
-
-common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
-
-obj-$(CONFIG_VIRTIO) += virtio-gpu.o virtio-gpu-3d.o
-obj-$(CONFIG_VIRTIO_PCI) += virtio-gpu-pci.o
-obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
-virtio-gpu.o-cflags := $(VIRGL_CFLAGS)
-virtio-gpu.o-libs += $(VIRGL_LIBS)
-virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
-virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
diff --git a/qemu/hw/display/ads7846.c b/qemu/hw/display/ads7846.c
deleted file mode 100644
index 05aa2d1e6..000000000
--- a/qemu/hw/display/ads7846.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * TI ADS7846 / TSC2046 chip emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/ssi/ssi.h"
-#include "ui/console.h"
-
-typedef struct {
- SSISlave ssidev;
- qemu_irq interrupt;
-
- int input[8];
- int pressure;
- int noise;
-
- int cycle;
- int output;
-} ADS7846State;
-
-/* Control-byte bitfields */
-#define CB_PD0 (1 << 0)
-#define CB_PD1 (1 << 1)
-#define CB_SER (1 << 2)
-#define CB_MODE (1 << 3)
-#define CB_A0 (1 << 4)
-#define CB_A1 (1 << 5)
-#define CB_A2 (1 << 6)
-#define CB_START (1 << 7)
-
-#define X_AXIS_DMAX 3470
-#define X_AXIS_MIN 290
-#define Y_AXIS_DMAX 3450
-#define Y_AXIS_MIN 200
-
-#define ADS_VBAT 2000
-#define ADS_VAUX 2000
-#define ADS_TEMP0 2000
-#define ADS_TEMP1 3000
-#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
-#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
-#define ADS_Z1POS(x, y) 600
-#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
-
-static void ads7846_int_update(ADS7846State *s)
-{
- if (s->interrupt)
- qemu_set_irq(s->interrupt, s->pressure == 0);
-}
-
-static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
-{
- ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
-
- switch (s->cycle ++) {
- case 0:
- if (!(value & CB_START)) {
- s->cycle = 0;
- break;
- }
-
- s->output = s->input[(value >> 4) & 7];
-
- /* Imitate the ADC noise, some drivers expect this. */
- s->noise = (s->noise + 3) & 7;
- switch ((value >> 4) & 7) {
- case 1: s->output += s->noise ^ 2; break;
- case 3: s->output += s->noise ^ 0; break;
- case 4: s->output += s->noise ^ 7; break;
- case 5: s->output += s->noise ^ 5; break;
- }
-
- if (value & CB_MODE)
- s->output >>= 4; /* 8 bits instead of 12 */
-
- break;
- case 1:
- s->cycle = 0;
- break;
- }
- return s->output;
-}
-
-static void ads7846_ts_event(void *opaque,
- int x, int y, int z, int buttons_state)
-{
- ADS7846State *s = opaque;
-
- if (buttons_state) {
- x = 0x7fff - x;
- s->input[1] = ADS_XPOS(x, y);
- s->input[3] = ADS_Z1POS(x, y);
- s->input[4] = ADS_Z2POS(x, y);
- s->input[5] = ADS_YPOS(x, y);
- }
-
- if (s->pressure == !buttons_state) {
- s->pressure = !!buttons_state;
-
- ads7846_int_update(s);
- }
-}
-
-static int ads7856_post_load(void *opaque, int version_id)
-{
- ADS7846State *s = opaque;
-
- s->pressure = 0;
- ads7846_int_update(s);
- return 0;
-}
-
-static const VMStateDescription vmstate_ads7846 = {
- .name = "ads7846",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = ads7856_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, ADS7846State),
- VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
- VMSTATE_INT32(noise, ADS7846State),
- VMSTATE_INT32(cycle, ADS7846State),
- VMSTATE_INT32(output, ADS7846State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int ads7846_init(SSISlave *d)
-{
- DeviceState *dev = DEVICE(d);
- ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
-
- qdev_init_gpio_out(dev, &s->interrupt, 1);
-
- s->input[0] = ADS_TEMP0; /* TEMP0 */
- s->input[2] = ADS_VBAT; /* VBAT */
- s->input[6] = ADS_VAUX; /* VAUX */
- s->input[7] = ADS_TEMP1; /* TEMP1 */
-
- /* We want absolute coordinates */
- qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
- "QEMU ADS7846-driven Touchscreen");
-
- ads7846_int_update(s);
-
- vmstate_register(NULL, -1, &vmstate_ads7846, s);
- return 0;
-}
-
-static void ads7846_class_init(ObjectClass *klass, void *data)
-{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = ads7846_init;
- k->transfer = ads7846_transfer;
-}
-
-static const TypeInfo ads7846_info = {
- .name = "ads7846",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(ADS7846State),
- .class_init = ads7846_class_init,
-};
-
-static void ads7846_register_types(void)
-{
- type_register_static(&ads7846_info);
-}
-
-type_init(ads7846_register_types)
diff --git a/qemu/hw/display/bcm2835_fb.c b/qemu/hw/display/bcm2835_fb.c
deleted file mode 100644
index 506f1d3d9..000000000
--- a/qemu/hw/display/bcm2835_fb.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Raspberry Pi emulation (c) 2012 Gregory Estrade
- * Refactoring for Pi2 Copyright (c) 2015, Microsoft. Written by Andrew Baumann.
- * This code is licensed under the GNU GPLv2 and later.
- *
- * Heavily based on milkymist-vgafb.c, copyright terms below:
- * QEMU model of the Milkymist VGA framebuffer.
- *
- * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/display/bcm2835_fb.h"
-#include "hw/display/framebuffer.h"
-#include "ui/pixel_ops.h"
-#include "hw/misc/bcm2835_mbox_defs.h"
-
-#define DEFAULT_VCRAM_SIZE 0x4000000
-#define BCM2835_FB_OFFSET 0x00100000
-
-static void fb_invalidate_display(void *opaque)
-{
- BCM2835FBState *s = BCM2835_FB(opaque);
-
- s->invalidate = true;
-}
-
-static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src,
- int width, int deststep)
-{
- BCM2835FBState *s = opaque;
- uint16_t rgb565;
- uint32_t rgb888;
- uint8_t r, g, b;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int bpp = surface_bits_per_pixel(surface);
-
- while (width--) {
- switch (s->bpp) {
- case 8:
- /* lookup palette starting at video ram base
- * TODO: cache translation, rather than doing this each time!
- */
- rgb888 = ldl_le_phys(&s->dma_as, s->vcram_base + (*src << 2));
- r = (rgb888 >> 0) & 0xff;
- g = (rgb888 >> 8) & 0xff;
- b = (rgb888 >> 16) & 0xff;
- src++;
- break;
- case 16:
- rgb565 = lduw_le_p(src);
- r = ((rgb565 >> 11) & 0x1f) << 3;
- g = ((rgb565 >> 5) & 0x3f) << 2;
- b = ((rgb565 >> 0) & 0x1f) << 3;
- src += 2;
- break;
- case 24:
- rgb888 = ldl_le_p(src);
- r = (rgb888 >> 0) & 0xff;
- g = (rgb888 >> 8) & 0xff;
- b = (rgb888 >> 16) & 0xff;
- src += 3;
- break;
- case 32:
- rgb888 = ldl_le_p(src);
- r = (rgb888 >> 0) & 0xff;
- g = (rgb888 >> 8) & 0xff;
- b = (rgb888 >> 16) & 0xff;
- src += 4;
- break;
- default:
- r = 0;
- g = 0;
- b = 0;
- break;
- }
-
- if (s->pixo == 0) {
- /* swap to BGR pixel format */
- uint8_t tmp = r;
- r = b;
- b = tmp;
- }
-
- switch (bpp) {
- case 8:
- *dst++ = rgb_to_pixel8(r, g, b);
- break;
- case 15:
- *(uint16_t *)dst = rgb_to_pixel15(r, g, b);
- dst += 2;
- break;
- case 16:
- *(uint16_t *)dst = rgb_to_pixel16(r, g, b);
- dst += 2;
- break;
- case 24:
- rgb888 = rgb_to_pixel24(r, g, b);
- *dst++ = rgb888 & 0xff;
- *dst++ = (rgb888 >> 8) & 0xff;
- *dst++ = (rgb888 >> 16) & 0xff;
- break;
- case 32:
- *(uint32_t *)dst = rgb_to_pixel32(r, g, b);
- dst += 4;
- break;
- default:
- return;
- }
- }
-}
-
-static void fb_update_display(void *opaque)
-{
- BCM2835FBState *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int first = 0;
- int last = 0;
- int src_width = 0;
- int dest_width = 0;
-
- if (s->lock || !s->xres) {
- return;
- }
-
- src_width = s->xres * (s->bpp >> 3);
- dest_width = s->xres;
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 8:
- break;
- case 15:
- dest_width *= 2;
- break;
- case 16:
- dest_width *= 2;
- break;
- case 24:
- dest_width *= 3;
- break;
- case 32:
- dest_width *= 4;
- break;
- default:
- hw_error("bcm2835_fb: bad color depth\n");
- break;
- }
-
- if (s->invalidate) {
- framebuffer_update_memory_section(&s->fbsection, s->dma_mr, s->base,
- s->yres, src_width);
- }
-
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
- src_width, dest_width, 0, s->invalidate,
- draw_line_src16, s, &first, &last);
-
- if (first >= 0) {
- dpy_gfx_update(s->con, 0, first, s->xres, last - first + 1);
- }
-
- s->invalidate = false;
-}
-
-static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
-{
- value &= ~0xf;
-
- s->lock = true;
-
- s->xres = ldl_le_phys(&s->dma_as, value);
- s->yres = ldl_le_phys(&s->dma_as, value + 4);
- s->xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
- s->yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
- s->bpp = ldl_le_phys(&s->dma_as, value + 20);
- s->xoffset = ldl_le_phys(&s->dma_as, value + 24);
- s->yoffset = ldl_le_phys(&s->dma_as, value + 28);
-
- s->base = s->vcram_base | (value & 0xc0000000);
- s->base += BCM2835_FB_OFFSET;
-
- /* TODO - Manage properly virtual resolution */
-
- s->pitch = s->xres * (s->bpp >> 3);
- s->size = s->yres * s->pitch;
-
- stl_le_phys(&s->dma_as, value + 16, s->pitch);
- stl_le_phys(&s->dma_as, value + 32, s->base);
- stl_le_phys(&s->dma_as, value + 36, s->size);
-
- s->invalidate = true;
- qemu_console_resize(s->con, s->xres, s->yres);
- s->lock = false;
-}
-
-void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
- uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp,
- uint32_t *pixo, uint32_t *alpha)
-{
- s->lock = true;
-
- /* TODO: input validation! */
- if (xres) {
- s->xres = *xres;
- }
- if (yres) {
- s->yres = *yres;
- }
- if (xoffset) {
- s->xoffset = *xoffset;
- }
- if (yoffset) {
- s->yoffset = *yoffset;
- }
- if (bpp) {
- s->bpp = *bpp;
- }
- if (pixo) {
- s->pixo = *pixo;
- }
- if (alpha) {
- s->alpha = *alpha;
- }
-
- /* TODO - Manage properly virtual resolution */
-
- s->pitch = s->xres * (s->bpp >> 3);
- s->size = s->yres * s->pitch;
-
- s->invalidate = true;
- qemu_console_resize(s->con, s->xres, s->yres);
- s->lock = false;
-}
-
-static uint64_t bcm2835_fb_read(void *opaque, hwaddr offset, unsigned size)
-{
- BCM2835FBState *s = opaque;
- uint32_t res = 0;
-
- switch (offset) {
- case MBOX_AS_DATA:
- res = MBOX_CHAN_FB;
- s->pending = false;
- qemu_set_irq(s->mbox_irq, 0);
- break;
-
- case MBOX_AS_PENDING:
- res = s->pending;
- break;
-
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
- __func__, offset);
- return 0;
- }
-
- return res;
-}
-
-static void bcm2835_fb_write(void *opaque, hwaddr offset, uint64_t value,
- unsigned size)
-{
- BCM2835FBState *s = opaque;
-
- switch (offset) {
- case MBOX_AS_DATA:
- /* bcm2835_mbox should check our pending status before pushing */
- assert(!s->pending);
- s->pending = true;
- bcm2835_fb_mbox_push(s, value);
- qemu_set_irq(s->mbox_irq, 1);
- break;
-
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
- __func__, offset);
- return;
- }
-}
-
-static const MemoryRegionOps bcm2835_fb_ops = {
- .read = bcm2835_fb_read,
- .write = bcm2835_fb_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid.min_access_size = 4,
- .valid.max_access_size = 4,
-};
-
-static const VMStateDescription vmstate_bcm2835_fb = {
- .name = TYPE_BCM2835_FB,
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_BOOL(lock, BCM2835FBState),
- VMSTATE_BOOL(invalidate, BCM2835FBState),
- VMSTATE_BOOL(pending, BCM2835FBState),
- VMSTATE_UINT32(xres, BCM2835FBState),
- VMSTATE_UINT32(yres, BCM2835FBState),
- VMSTATE_UINT32(xres_virtual, BCM2835FBState),
- VMSTATE_UINT32(yres_virtual, BCM2835FBState),
- VMSTATE_UINT32(xoffset, BCM2835FBState),
- VMSTATE_UINT32(yoffset, BCM2835FBState),
- VMSTATE_UINT32(bpp, BCM2835FBState),
- VMSTATE_UINT32(base, BCM2835FBState),
- VMSTATE_UINT32(pitch, BCM2835FBState),
- VMSTATE_UINT32(size, BCM2835FBState),
- VMSTATE_UINT32(pixo, BCM2835FBState),
- VMSTATE_UINT32(alpha, BCM2835FBState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps vgafb_ops = {
- .invalidate = fb_invalidate_display,
- .gfx_update = fb_update_display,
-};
-
-static void bcm2835_fb_init(Object *obj)
-{
- BCM2835FBState *s = BCM2835_FB(obj);
-
- memory_region_init_io(&s->iomem, obj, &bcm2835_fb_ops, s, TYPE_BCM2835_FB,
- 0x10);
- sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
- sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq);
-}
-
-static void bcm2835_fb_reset(DeviceState *dev)
-{
- BCM2835FBState *s = BCM2835_FB(dev);
-
- s->pending = false;
-
- s->xres_virtual = s->xres;
- s->yres_virtual = s->yres;
- s->xoffset = 0;
- s->yoffset = 0;
- s->base = s->vcram_base + BCM2835_FB_OFFSET;
- s->pitch = s->xres * (s->bpp >> 3);
- s->size = s->yres * s->pitch;
-
- s->invalidate = true;
- s->lock = false;
-}
-
-static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
-{
- BCM2835FBState *s = BCM2835_FB(dev);
- Error *err = NULL;
- Object *obj;
-
- if (s->vcram_base == 0) {
- error_setg(errp, "%s: required vcram-base property not set", __func__);
- return;
- }
-
- obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
- if (obj == NULL) {
- error_setg(errp, "%s: required dma-mr link not found: %s",
- __func__, error_get_pretty(err));
- return;
- }
-
- s->dma_mr = MEMORY_REGION(obj);
- address_space_init(&s->dma_as, s->dma_mr, NULL);
-
- bcm2835_fb_reset(dev);
-
- s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
- qemu_console_resize(s->con, s->xres, s->yres);
-}
-
-static Property bcm2835_fb_props[] = {
- DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/
- DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size,
- DEFAULT_VCRAM_SIZE),
- DEFINE_PROP_UINT32("xres", BCM2835FBState, xres, 640),
- DEFINE_PROP_UINT32("yres", BCM2835FBState, yres, 480),
- DEFINE_PROP_UINT32("bpp", BCM2835FBState, bpp, 16),
- DEFINE_PROP_UINT32("pixo", BCM2835FBState, pixo, 1), /* 1=RGB, 0=BGR */
- DEFINE_PROP_UINT32("alpha", BCM2835FBState, alpha, 2), /* alpha ignored */
- DEFINE_PROP_END_OF_LIST()
-};
-
-static void bcm2835_fb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->props = bcm2835_fb_props;
- dc->realize = bcm2835_fb_realize;
- dc->reset = bcm2835_fb_reset;
- dc->vmsd = &vmstate_bcm2835_fb;
-}
-
-static TypeInfo bcm2835_fb_info = {
- .name = TYPE_BCM2835_FB,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(BCM2835FBState),
- .class_init = bcm2835_fb_class_init,
- .instance_init = bcm2835_fb_init,
-};
-
-static void bcm2835_fb_register_types(void)
-{
- type_register_static(&bcm2835_fb_info);
-}
-
-type_init(bcm2835_fb_register_types)
diff --git a/qemu/hw/display/blizzard.c b/qemu/hw/display/blizzard.c
deleted file mode 100644
index c231960d9..000000000
--- a/qemu/hw/display/blizzard.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
- *
- * Copyright (C) 2008 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "hw/devices.h"
-#include "ui/pixel_ops.h"
-
-typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
-
-typedef struct {
- uint8_t reg;
- uint32_t addr;
- int swallow;
-
- int pll;
- int pll_range;
- int pll_ctrl;
- uint8_t pll_mode;
- uint8_t clksel;
- int memenable;
- int memrefresh;
- uint8_t timing[3];
- int priority;
-
- uint8_t lcd_config;
- int x;
- int y;
- int skipx;
- int skipy;
- uint8_t hndp;
- uint8_t vndp;
- uint8_t hsync;
- uint8_t vsync;
- uint8_t pclk;
- uint8_t u;
- uint8_t v;
- uint8_t yrc[2];
- int ix[2];
- int iy[2];
- int ox[2];
- int oy[2];
-
- int enable;
- int blank;
- int bpp;
- int invalidate;
- int mx[2];
- int my[2];
- uint8_t mode;
- uint8_t effect;
- uint8_t iformat;
- uint8_t source;
- QemuConsole *con;
- blizzard_fn_t *line_fn_tab[2];
- void *fb;
-
- uint8_t hssi_config[3];
- uint8_t tv_config;
- uint8_t tv_timing[4];
- uint8_t vbi;
- uint8_t tv_x;
- uint8_t tv_y;
- uint8_t tv_test;
- uint8_t tv_filter_config;
- uint8_t tv_filter_idx;
- uint8_t tv_filter_coeff[0x20];
- uint8_t border_r;
- uint8_t border_g;
- uint8_t border_b;
- uint8_t gamma_config;
- uint8_t gamma_idx;
- uint8_t gamma_lut[0x100];
- uint8_t matrix_ena;
- uint8_t matrix_coeff[0x12];
- uint8_t matrix_r;
- uint8_t matrix_g;
- uint8_t matrix_b;
- uint8_t pm;
- uint8_t status;
- uint8_t rgbgpio_dir;
- uint8_t rgbgpio;
- uint8_t gpio_dir;
- uint8_t gpio;
- uint8_t gpio_edge[2];
- uint8_t gpio_irq;
- uint8_t gpio_pdown;
-
- struct {
- int x;
- int y;
- int dx;
- int dy;
- int len;
- int buflen;
- void *buf;
- void *data;
- uint16_t *ptr;
- int angle;
- int pitch;
- blizzard_fn_t line_fn;
- } data;
-} BlizzardState;
-
-/* Bytes(!) per pixel */
-static const int blizzard_iformat_bpp[0x10] = {
- 0,
- 2, /* RGB 5:6:5*/
- 3, /* RGB 6:6:6 mode 1 */
- 3, /* RGB 8:8:8 mode 1 */
- 0, 0,
- 4, /* RGB 6:6:6 mode 2 */
- 4, /* RGB 8:8:8 mode 2 */
- 0, /* YUV 4:2:2 */
- 0, /* YUV 4:2:0 */
- 0, 0, 0, 0, 0, 0,
-};
-
-static void blizzard_window(BlizzardState *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- uint8_t *src, *dst;
- int bypp[2];
- int bypl[3];
- int y;
- blizzard_fn_t fn = s->data.line_fn;
-
- if (!fn)
- return;
- if (s->mx[0] > s->data.x)
- s->mx[0] = s->data.x;
- if (s->my[0] > s->data.y)
- s->my[0] = s->data.y;
- if (s->mx[1] < s->data.x + s->data.dx)
- s->mx[1] = s->data.x + s->data.dx;
- if (s->my[1] < s->data.y + s->data.dy)
- s->my[1] = s->data.y + s->data.dy;
-
- bypp[0] = s->bpp;
- bypp[1] = surface_bytes_per_pixel(surface);
- bypl[0] = bypp[0] * s->data.pitch;
- bypl[1] = bypp[1] * s->x;
- bypl[2] = bypp[0] * s->data.dx;
-
- src = s->data.data;
- dst = s->fb + bypl[1] * s->data.y + bypp[1] * s->data.x;
- for (y = s->data.dy; y > 0; y --, src += bypl[0], dst += bypl[1])
- fn(dst, src, bypl[2]);
-}
-
-static int blizzard_transfer_setup(BlizzardState *s)
-{
- if (s->source > 3 || !s->bpp ||
- s->ix[1] < s->ix[0] || s->iy[1] < s->iy[0])
- return 0;
-
- s->data.angle = s->effect & 3;
- s->data.line_fn = s->line_fn_tab[!!s->data.angle][s->iformat];
- s->data.x = s->ix[0];
- s->data.y = s->iy[0];
- s->data.dx = s->ix[1] - s->ix[0] + 1;
- s->data.dy = s->iy[1] - s->iy[0] + 1;
- s->data.len = s->bpp * s->data.dx * s->data.dy;
- s->data.pitch = s->data.dx;
- if (s->data.len > s->data.buflen) {
- s->data.buf = g_realloc(s->data.buf, s->data.len);
- s->data.buflen = s->data.len;
- }
- s->data.ptr = s->data.buf;
- s->data.data = s->data.buf;
- s->data.len /= 2;
- return 1;
-}
-
-static void blizzard_reset(BlizzardState *s)
-{
- s->reg = 0;
- s->swallow = 0;
-
- s->pll = 9;
- s->pll_range = 1;
- s->pll_ctrl = 0x14;
- s->pll_mode = 0x32;
- s->clksel = 0x00;
- s->memenable = 0;
- s->memrefresh = 0x25c;
- s->timing[0] = 0x3f;
- s->timing[1] = 0x13;
- s->timing[2] = 0x21;
- s->priority = 0;
-
- s->lcd_config = 0x74;
- s->x = 8;
- s->y = 1;
- s->skipx = 0;
- s->skipy = 0;
- s->hndp = 3;
- s->vndp = 2;
- s->hsync = 1;
- s->vsync = 1;
- s->pclk = 0x80;
-
- s->ix[0] = 0;
- s->ix[1] = 0;
- s->iy[0] = 0;
- s->iy[1] = 0;
- s->ox[0] = 0;
- s->ox[1] = 0;
- s->oy[0] = 0;
- s->oy[1] = 0;
-
- s->yrc[0] = 0x00;
- s->yrc[1] = 0x30;
- s->u = 0;
- s->v = 0;
-
- s->iformat = 3;
- s->source = 0;
- s->bpp = blizzard_iformat_bpp[s->iformat];
-
- s->hssi_config[0] = 0x00;
- s->hssi_config[1] = 0x00;
- s->hssi_config[2] = 0x01;
- s->tv_config = 0x00;
- s->tv_timing[0] = 0x00;
- s->tv_timing[1] = 0x00;
- s->tv_timing[2] = 0x00;
- s->tv_timing[3] = 0x00;
- s->vbi = 0x10;
- s->tv_x = 0x14;
- s->tv_y = 0x03;
- s->tv_test = 0x00;
- s->tv_filter_config = 0x80;
- s->tv_filter_idx = 0x00;
- s->border_r = 0x10;
- s->border_g = 0x80;
- s->border_b = 0x80;
- s->gamma_config = 0x00;
- s->gamma_idx = 0x00;
- s->matrix_ena = 0x00;
- memset(&s->matrix_coeff, 0, sizeof(s->matrix_coeff));
- s->matrix_r = 0x00;
- s->matrix_g = 0x00;
- s->matrix_b = 0x00;
- s->pm = 0x02;
- s->status = 0x00;
- s->rgbgpio_dir = 0x00;
- s->gpio_dir = 0x00;
- s->gpio_edge[0] = 0x00;
- s->gpio_edge[1] = 0x00;
- s->gpio_irq = 0x00;
- s->gpio_pdown = 0xff;
-}
-
-static inline void blizzard_invalidate_display(void *opaque) {
- BlizzardState *s = (BlizzardState *) opaque;
-
- s->invalidate = 1;
-}
-
-static uint16_t blizzard_reg_read(void *opaque, uint8_t reg)
-{
- BlizzardState *s = (BlizzardState *) opaque;
-
- switch (reg) {
- case 0x00: /* Revision Code */
- return 0xa5;
-
- case 0x02: /* Configuration Readback */
- return 0x83; /* Macrovision OK, CNF[2:0] = 3 */
-
- case 0x04: /* PLL M-Divider */
- return (s->pll - 1) | (1 << 7);
- case 0x06: /* PLL Lock Range Control */
- return s->pll_range;
- case 0x08: /* PLL Lock Synthesis Control 0 */
- return s->pll_ctrl & 0xff;
- case 0x0a: /* PLL Lock Synthesis Control 1 */
- return s->pll_ctrl >> 8;
- case 0x0c: /* PLL Mode Control 0 */
- return s->pll_mode;
-
- case 0x0e: /* Clock-Source Select */
- return s->clksel;
-
- case 0x10: /* Memory Controller Activate */
- case 0x14: /* Memory Controller Bank 0 Status Flag */
- return s->memenable;
-
- case 0x18: /* Auto-Refresh Interval Setting 0 */
- return s->memrefresh & 0xff;
- case 0x1a: /* Auto-Refresh Interval Setting 1 */
- return s->memrefresh >> 8;
-
- case 0x1c: /* Power-On Sequence Timing Control */
- return s->timing[0];
- case 0x1e: /* Timing Control 0 */
- return s->timing[1];
- case 0x20: /* Timing Control 1 */
- return s->timing[2];
-
- case 0x24: /* Arbitration Priority Control */
- return s->priority;
-
- case 0x28: /* LCD Panel Configuration */
- return s->lcd_config;
-
- case 0x2a: /* LCD Horizontal Display Width */
- return s->x >> 3;
- case 0x2c: /* LCD Horizontal Non-display Period */
- return s->hndp;
- case 0x2e: /* LCD Vertical Display Height 0 */
- return s->y & 0xff;
- case 0x30: /* LCD Vertical Display Height 1 */
- return s->y >> 8;
- case 0x32: /* LCD Vertical Non-display Period */
- return s->vndp;
- case 0x34: /* LCD HS Pulse-width */
- return s->hsync;
- case 0x36: /* LCd HS Pulse Start Position */
- return s->skipx >> 3;
- case 0x38: /* LCD VS Pulse-width */
- return s->vsync;
- case 0x3a: /* LCD VS Pulse Start Position */
- return s->skipy;
-
- case 0x3c: /* PCLK Polarity */
- return s->pclk;
-
- case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */
- return s->hssi_config[0];
- case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */
- return s->hssi_config[1];
- case 0x42: /* High-speed Serial Interface Tx Mode */
- return s->hssi_config[2];
- case 0x44: /* TV Display Configuration */
- return s->tv_config;
- case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits */
- return s->tv_timing[(reg - 0x46) >> 1];
- case 0x4e: /* VBI: Closed Caption / XDS Control / Status */
- return s->vbi;
- case 0x50: /* TV Horizontal Start Position */
- return s->tv_x;
- case 0x52: /* TV Vertical Start Position */
- return s->tv_y;
- case 0x54: /* TV Test Pattern Setting */
- return s->tv_test;
- case 0x56: /* TV Filter Setting */
- return s->tv_filter_config;
- case 0x58: /* TV Filter Coefficient Index */
- return s->tv_filter_idx;
- case 0x5a: /* TV Filter Coefficient Data */
- if (s->tv_filter_idx < 0x20)
- return s->tv_filter_coeff[s->tv_filter_idx ++];
- return 0;
-
- case 0x60: /* Input YUV/RGB Translate Mode 0 */
- return s->yrc[0];
- case 0x62: /* Input YUV/RGB Translate Mode 1 */
- return s->yrc[1];
- case 0x64: /* U Data Fix */
- return s->u;
- case 0x66: /* V Data Fix */
- return s->v;
-
- case 0x68: /* Display Mode */
- return s->mode;
-
- case 0x6a: /* Special Effects */
- return s->effect;
-
- case 0x6c: /* Input Window X Start Position 0 */
- return s->ix[0] & 0xff;
- case 0x6e: /* Input Window X Start Position 1 */
- return s->ix[0] >> 3;
- case 0x70: /* Input Window Y Start Position 0 */
- return s->ix[0] & 0xff;
- case 0x72: /* Input Window Y Start Position 1 */
- return s->ix[0] >> 3;
- case 0x74: /* Input Window X End Position 0 */
- return s->ix[1] & 0xff;
- case 0x76: /* Input Window X End Position 1 */
- return s->ix[1] >> 3;
- case 0x78: /* Input Window Y End Position 0 */
- return s->ix[1] & 0xff;
- case 0x7a: /* Input Window Y End Position 1 */
- return s->ix[1] >> 3;
- case 0x7c: /* Output Window X Start Position 0 */
- return s->ox[0] & 0xff;
- case 0x7e: /* Output Window X Start Position 1 */
- return s->ox[0] >> 3;
- case 0x80: /* Output Window Y Start Position 0 */
- return s->oy[0] & 0xff;
- case 0x82: /* Output Window Y Start Position 1 */
- return s->oy[0] >> 3;
- case 0x84: /* Output Window X End Position 0 */
- return s->ox[1] & 0xff;
- case 0x86: /* Output Window X End Position 1 */
- return s->ox[1] >> 3;
- case 0x88: /* Output Window Y End Position 0 */
- return s->oy[1] & 0xff;
- case 0x8a: /* Output Window Y End Position 1 */
- return s->oy[1] >> 3;
-
- case 0x8c: /* Input Data Format */
- return s->iformat;
- case 0x8e: /* Data Source Select */
- return s->source;
- case 0x90: /* Display Memory Data Port */
- return 0;
-
- case 0xa8: /* Border Color 0 */
- return s->border_r;
- case 0xaa: /* Border Color 1 */
- return s->border_g;
- case 0xac: /* Border Color 2 */
- return s->border_b;
-
- case 0xb4: /* Gamma Correction Enable */
- return s->gamma_config;
- case 0xb6: /* Gamma Correction Table Index */
- return s->gamma_idx;
- case 0xb8: /* Gamma Correction Table Data */
- return s->gamma_lut[s->gamma_idx ++];
-
- case 0xba: /* 3x3 Matrix Enable */
- return s->matrix_ena;
- case 0xbc ... 0xde: /* Coefficient Registers */
- return s->matrix_coeff[(reg - 0xbc) >> 1];
- case 0xe0: /* 3x3 Matrix Red Offset */
- return s->matrix_r;
- case 0xe2: /* 3x3 Matrix Green Offset */
- return s->matrix_g;
- case 0xe4: /* 3x3 Matrix Blue Offset */
- return s->matrix_b;
-
- case 0xe6: /* Power-save */
- return s->pm;
- case 0xe8: /* Non-display Period Control / Status */
- return s->status | (1 << 5);
- case 0xea: /* RGB Interface Control */
- return s->rgbgpio_dir;
- case 0xec: /* RGB Interface Status */
- return s->rgbgpio;
- case 0xee: /* General-purpose IO Pins Configuration */
- return s->gpio_dir;
- case 0xf0: /* General-purpose IO Pins Status / Control */
- return s->gpio;
- case 0xf2: /* GPIO Positive Edge Interrupt Trigger */
- return s->gpio_edge[0];
- case 0xf4: /* GPIO Negative Edge Interrupt Trigger */
- return s->gpio_edge[1];
- case 0xf6: /* GPIO Interrupt Status */
- return s->gpio_irq;
- case 0xf8: /* GPIO Pull-down Control */
- return s->gpio_pdown;
-
- default:
- fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg);
- return 0;
- }
-}
-
-static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
-{
- BlizzardState *s = (BlizzardState *) opaque;
-
- switch (reg) {
- case 0x04: /* PLL M-Divider */
- s->pll = (value & 0x3f) + 1;
- break;
- case 0x06: /* PLL Lock Range Control */
- s->pll_range = value & 3;
- break;
- case 0x08: /* PLL Lock Synthesis Control 0 */
- s->pll_ctrl &= 0xf00;
- s->pll_ctrl |= (value << 0) & 0x0ff;
- break;
- case 0x0a: /* PLL Lock Synthesis Control 1 */
- s->pll_ctrl &= 0x0ff;
- s->pll_ctrl |= (value << 8) & 0xf00;
- break;
- case 0x0c: /* PLL Mode Control 0 */
- s->pll_mode = value & 0x77;
- if ((value & 3) == 0 || (value & 3) == 3)
- fprintf(stderr, "%s: wrong PLL Control bits (%i)\n",
- __FUNCTION__, value & 3);
- break;
-
- case 0x0e: /* Clock-Source Select */
- s->clksel = value & 0xff;
- break;
-
- case 0x10: /* Memory Controller Activate */
- s->memenable = value & 1;
- break;
- case 0x14: /* Memory Controller Bank 0 Status Flag */
- break;
-
- case 0x18: /* Auto-Refresh Interval Setting 0 */
- s->memrefresh &= 0xf00;
- s->memrefresh |= (value << 0) & 0x0ff;
- break;
- case 0x1a: /* Auto-Refresh Interval Setting 1 */
- s->memrefresh &= 0x0ff;
- s->memrefresh |= (value << 8) & 0xf00;
- break;
-
- case 0x1c: /* Power-On Sequence Timing Control */
- s->timing[0] = value & 0x7f;
- break;
- case 0x1e: /* Timing Control 0 */
- s->timing[1] = value & 0x17;
- break;
- case 0x20: /* Timing Control 1 */
- s->timing[2] = value & 0x35;
- break;
-
- case 0x24: /* Arbitration Priority Control */
- s->priority = value & 1;
- break;
-
- case 0x28: /* LCD Panel Configuration */
- s->lcd_config = value & 0xff;
- if (value & (1 << 7))
- fprintf(stderr, "%s: data swap not supported!\n", __FUNCTION__);
- break;
-
- case 0x2a: /* LCD Horizontal Display Width */
- s->x = value << 3;
- break;
- case 0x2c: /* LCD Horizontal Non-display Period */
- s->hndp = value & 0xff;
- break;
- case 0x2e: /* LCD Vertical Display Height 0 */
- s->y &= 0x300;
- s->y |= (value << 0) & 0x0ff;
- break;
- case 0x30: /* LCD Vertical Display Height 1 */
- s->y &= 0x0ff;
- s->y |= (value << 8) & 0x300;
- break;
- case 0x32: /* LCD Vertical Non-display Period */
- s->vndp = value & 0xff;
- break;
- case 0x34: /* LCD HS Pulse-width */
- s->hsync = value & 0xff;
- break;
- case 0x36: /* LCD HS Pulse Start Position */
- s->skipx = value & 0xff;
- break;
- case 0x38: /* LCD VS Pulse-width */
- s->vsync = value & 0xbf;
- break;
- case 0x3a: /* LCD VS Pulse Start Position */
- s->skipy = value & 0xff;
- break;
-
- case 0x3c: /* PCLK Polarity */
- s->pclk = value & 0x82;
- /* Affects calculation of s->hndp, s->hsync and s->skipx. */
- break;
-
- case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */
- s->hssi_config[0] = value;
- break;
- case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */
- s->hssi_config[1] = value;
- if (((value >> 4) & 3) == 3)
- fprintf(stderr, "%s: Illegal active-data-links value\n",
- __FUNCTION__);
- break;
- case 0x42: /* High-speed Serial Interface Tx Mode */
- s->hssi_config[2] = value & 0xbd;
- break;
-
- case 0x44: /* TV Display Configuration */
- s->tv_config = value & 0xfe;
- break;
- case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits 0 */
- s->tv_timing[(reg - 0x46) >> 1] = value;
- break;
- case 0x4e: /* VBI: Closed Caption / XDS Control / Status */
- s->vbi = value;
- break;
- case 0x50: /* TV Horizontal Start Position */
- s->tv_x = value;
- break;
- case 0x52: /* TV Vertical Start Position */
- s->tv_y = value & 0x7f;
- break;
- case 0x54: /* TV Test Pattern Setting */
- s->tv_test = value;
- break;
- case 0x56: /* TV Filter Setting */
- s->tv_filter_config = value & 0xbf;
- break;
- case 0x58: /* TV Filter Coefficient Index */
- s->tv_filter_idx = value & 0x1f;
- break;
- case 0x5a: /* TV Filter Coefficient Data */
- if (s->tv_filter_idx < 0x20)
- s->tv_filter_coeff[s->tv_filter_idx ++] = value;
- break;
-
- case 0x60: /* Input YUV/RGB Translate Mode 0 */
- s->yrc[0] = value & 0xb0;
- break;
- case 0x62: /* Input YUV/RGB Translate Mode 1 */
- s->yrc[1] = value & 0x30;
- break;
- case 0x64: /* U Data Fix */
- s->u = value & 0xff;
- break;
- case 0x66: /* V Data Fix */
- s->v = value & 0xff;
- break;
-
- case 0x68: /* Display Mode */
- if ((s->mode ^ value) & 3)
- s->invalidate = 1;
- s->mode = value & 0xb7;
- s->enable = value & 1;
- s->blank = (value >> 1) & 1;
- if (value & (1 << 4))
- fprintf(stderr, "%s: Macrovision enable attempt!\n", __FUNCTION__);
- break;
-
- case 0x6a: /* Special Effects */
- s->effect = value & 0xfb;
- break;
-
- case 0x6c: /* Input Window X Start Position 0 */
- s->ix[0] &= 0x300;
- s->ix[0] |= (value << 0) & 0x0ff;
- break;
- case 0x6e: /* Input Window X Start Position 1 */
- s->ix[0] &= 0x0ff;
- s->ix[0] |= (value << 8) & 0x300;
- break;
- case 0x70: /* Input Window Y Start Position 0 */
- s->iy[0] &= 0x300;
- s->iy[0] |= (value << 0) & 0x0ff;
- break;
- case 0x72: /* Input Window Y Start Position 1 */
- s->iy[0] &= 0x0ff;
- s->iy[0] |= (value << 8) & 0x300;
- break;
- case 0x74: /* Input Window X End Position 0 */
- s->ix[1] &= 0x300;
- s->ix[1] |= (value << 0) & 0x0ff;
- break;
- case 0x76: /* Input Window X End Position 1 */
- s->ix[1] &= 0x0ff;
- s->ix[1] |= (value << 8) & 0x300;
- break;
- case 0x78: /* Input Window Y End Position 0 */
- s->iy[1] &= 0x300;
- s->iy[1] |= (value << 0) & 0x0ff;
- break;
- case 0x7a: /* Input Window Y End Position 1 */
- s->iy[1] &= 0x0ff;
- s->iy[1] |= (value << 8) & 0x300;
- break;
- case 0x7c: /* Output Window X Start Position 0 */
- s->ox[0] &= 0x300;
- s->ox[0] |= (value << 0) & 0x0ff;
- break;
- case 0x7e: /* Output Window X Start Position 1 */
- s->ox[0] &= 0x0ff;
- s->ox[0] |= (value << 8) & 0x300;
- break;
- case 0x80: /* Output Window Y Start Position 0 */
- s->oy[0] &= 0x300;
- s->oy[0] |= (value << 0) & 0x0ff;
- break;
- case 0x82: /* Output Window Y Start Position 1 */
- s->oy[0] &= 0x0ff;
- s->oy[0] |= (value << 8) & 0x300;
- break;
- case 0x84: /* Output Window X End Position 0 */
- s->ox[1] &= 0x300;
- s->ox[1] |= (value << 0) & 0x0ff;
- break;
- case 0x86: /* Output Window X End Position 1 */
- s->ox[1] &= 0x0ff;
- s->ox[1] |= (value << 8) & 0x300;
- break;
- case 0x88: /* Output Window Y End Position 0 */
- s->oy[1] &= 0x300;
- s->oy[1] |= (value << 0) & 0x0ff;
- break;
- case 0x8a: /* Output Window Y End Position 1 */
- s->oy[1] &= 0x0ff;
- s->oy[1] |= (value << 8) & 0x300;
- break;
-
- case 0x8c: /* Input Data Format */
- s->iformat = value & 0xf;
- s->bpp = blizzard_iformat_bpp[s->iformat];
- if (!s->bpp)
- fprintf(stderr, "%s: Illegal or unsupported input format %x\n",
- __FUNCTION__, s->iformat);
- break;
- case 0x8e: /* Data Source Select */
- s->source = value & 7;
- /* Currently all windows will be "destructive overlays". */
- if ((!(s->effect & (1 << 3)) && (s->ix[0] != s->ox[0] ||
- s->iy[0] != s->oy[0] ||
- s->ix[1] != s->ox[1] ||
- s->iy[1] != s->oy[1])) ||
- !((s->ix[1] - s->ix[0]) & (s->iy[1] - s->iy[0]) &
- (s->ox[1] - s->ox[0]) & (s->oy[1] - s->oy[0]) & 1))
- fprintf(stderr, "%s: Illegal input/output window positions\n",
- __FUNCTION__);
-
- blizzard_transfer_setup(s);
- break;
-
- case 0x90: /* Display Memory Data Port */
- if (!s->data.len && !blizzard_transfer_setup(s))
- break;
-
- *s->data.ptr ++ = value;
- if (-- s->data.len == 0)
- blizzard_window(s);
- break;
-
- case 0xa8: /* Border Color 0 */
- s->border_r = value;
- break;
- case 0xaa: /* Border Color 1 */
- s->border_g = value;
- break;
- case 0xac: /* Border Color 2 */
- s->border_b = value;
- break;
-
- case 0xb4: /* Gamma Correction Enable */
- s->gamma_config = value & 0x87;
- break;
- case 0xb6: /* Gamma Correction Table Index */
- s->gamma_idx = value;
- break;
- case 0xb8: /* Gamma Correction Table Data */
- s->gamma_lut[s->gamma_idx ++] = value;
- break;
-
- case 0xba: /* 3x3 Matrix Enable */
- s->matrix_ena = value & 1;
- break;
- case 0xbc ... 0xde: /* Coefficient Registers */
- s->matrix_coeff[(reg - 0xbc) >> 1] = value & ((reg & 2) ? 0x80 : 0xff);
- break;
- case 0xe0: /* 3x3 Matrix Red Offset */
- s->matrix_r = value;
- break;
- case 0xe2: /* 3x3 Matrix Green Offset */
- s->matrix_g = value;
- break;
- case 0xe4: /* 3x3 Matrix Blue Offset */
- s->matrix_b = value;
- break;
-
- case 0xe6: /* Power-save */
- s->pm = value & 0x83;
- if (value & s->mode & 1)
- fprintf(stderr, "%s: The display must be disabled before entering "
- "Standby Mode\n", __FUNCTION__);
- break;
- case 0xe8: /* Non-display Period Control / Status */
- s->status = value & 0x1b;
- break;
- case 0xea: /* RGB Interface Control */
- s->rgbgpio_dir = value & 0x8f;
- break;
- case 0xec: /* RGB Interface Status */
- s->rgbgpio = value & 0xcf;
- break;
- case 0xee: /* General-purpose IO Pins Configuration */
- s->gpio_dir = value;
- break;
- case 0xf0: /* General-purpose IO Pins Status / Control */
- s->gpio = value;
- break;
- case 0xf2: /* GPIO Positive Edge Interrupt Trigger */
- s->gpio_edge[0] = value;
- break;
- case 0xf4: /* GPIO Negative Edge Interrupt Trigger */
- s->gpio_edge[1] = value;
- break;
- case 0xf6: /* GPIO Interrupt Status */
- s->gpio_irq &= value;
- break;
- case 0xf8: /* GPIO Pull-down Control */
- s->gpio_pdown = value;
- break;
-
- default:
- fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg);
- break;
- }
-}
-
-uint16_t s1d13745_read(void *opaque, int dc)
-{
- BlizzardState *s = (BlizzardState *) opaque;
- uint16_t value = blizzard_reg_read(s, s->reg);
-
- if (s->swallow -- > 0)
- return 0;
- if (dc)
- s->reg ++;
-
- return value;
-}
-
-void s1d13745_write(void *opaque, int dc, uint16_t value)
-{
- BlizzardState *s = (BlizzardState *) opaque;
-
- if (s->swallow -- > 0)
- return;
- if (dc) {
- blizzard_reg_write(s, s->reg, value);
-
- if (s->reg != 0x90 && s->reg != 0x5a && s->reg != 0xb8)
- s->reg += 2;
- } else
- s->reg = value & 0xff;
-}
-
-void s1d13745_write_block(void *opaque, int dc,
- void *buf, size_t len, int pitch)
-{
- BlizzardState *s = (BlizzardState *) opaque;
-
- while (len > 0) {
- if (s->reg == 0x90 && dc &&
- (s->data.len || blizzard_transfer_setup(s)) &&
- len >= (s->data.len << 1)) {
- len -= s->data.len << 1;
- s->data.len = 0;
- s->data.data = buf;
- if (pitch)
- s->data.pitch = pitch;
- blizzard_window(s);
- s->data.data = s->data.buf;
- continue;
- }
-
- s1d13745_write(opaque, dc, *(uint16_t *) buf);
- len -= 2;
- buf += 2;
- }
-}
-
-static void blizzard_update_display(void *opaque)
-{
- BlizzardState *s = (BlizzardState *) opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int y, bypp, bypl, bwidth;
- uint8_t *src, *dst;
-
- if (!s->enable)
- return;
-
- if (s->x != surface_width(surface) || s->y != surface_height(surface)) {
- s->invalidate = 1;
- qemu_console_resize(s->con, s->x, s->y);
- surface = qemu_console_surface(s->con);
- }
-
- if (s->invalidate) {
- s->invalidate = 0;
-
- if (s->blank) {
- bypp = surface_bytes_per_pixel(surface);
- memset(surface_data(surface), 0, bypp * s->x * s->y);
- return;
- }
-
- s->mx[0] = 0;
- s->mx[1] = s->x;
- s->my[0] = 0;
- s->my[1] = s->y;
- }
-
- if (s->mx[1] <= s->mx[0])
- return;
-
- bypp = surface_bytes_per_pixel(surface);
- bypl = bypp * s->x;
- bwidth = bypp * (s->mx[1] - s->mx[0]);
- y = s->my[0];
- src = s->fb + bypl * y + bypp * s->mx[0];
- dst = surface_data(surface) + bypl * y + bypp * s->mx[0];
- for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
- memcpy(dst, src, bwidth);
-
- dpy_gfx_update(s->con, s->mx[0], s->my[0],
- s->mx[1] - s->mx[0], y - s->my[0]);
-
- s->mx[0] = s->x;
- s->mx[1] = 0;
- s->my[0] = s->y;
- s->my[1] = 0;
-}
-
-#define DEPTH 8
-#include "blizzard_template.h"
-#define DEPTH 15
-#include "blizzard_template.h"
-#define DEPTH 16
-#include "blizzard_template.h"
-#define DEPTH 24
-#include "blizzard_template.h"
-#define DEPTH 32
-#include "blizzard_template.h"
-
-static const GraphicHwOps blizzard_ops = {
- .invalidate = blizzard_invalidate_display,
- .gfx_update = blizzard_update_display,
-};
-
-void *s1d13745_init(qemu_irq gpio_int)
-{
- BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s));
- DisplaySurface *surface;
-
- s->fb = g_malloc(0x180000);
-
- s->con = graphic_console_init(NULL, 0, &blizzard_ops, s);
- surface = qemu_console_surface(s->con);
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- s->line_fn_tab[0] = s->line_fn_tab[1] =
- g_malloc0(sizeof(blizzard_fn_t) * 0x10);
- break;
- case 8:
- s->line_fn_tab[0] = blizzard_draw_fn_8;
- s->line_fn_tab[1] = blizzard_draw_fn_r_8;
- break;
- case 15:
- s->line_fn_tab[0] = blizzard_draw_fn_15;
- s->line_fn_tab[1] = blizzard_draw_fn_r_15;
- break;
- case 16:
- s->line_fn_tab[0] = blizzard_draw_fn_16;
- s->line_fn_tab[1] = blizzard_draw_fn_r_16;
- break;
- case 24:
- s->line_fn_tab[0] = blizzard_draw_fn_24;
- s->line_fn_tab[1] = blizzard_draw_fn_r_24;
- break;
- case 32:
- s->line_fn_tab[0] = blizzard_draw_fn_32;
- s->line_fn_tab[1] = blizzard_draw_fn_r_32;
- break;
- default:
- fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
- exit(1);
- }
-
- blizzard_reset(s);
-
- return s;
-}
diff --git a/qemu/hw/display/blizzard_template.h b/qemu/hw/display/blizzard_template.h
deleted file mode 100644
index b7ef27c80..000000000
--- a/qemu/hw/display/blizzard_template.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * QEMU Epson S1D13744/S1D13745 templates
- *
- * Copyright (C) 2008 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#define SKIP_PIXEL(to) (to += deststep)
-#if DEPTH == 8
-# define PIXEL_TYPE uint8_t
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
-# define COPY_PIXEL1(to, from) (*to++ = from)
-#elif DEPTH == 15 || DEPTH == 16
-# define PIXEL_TYPE uint16_t
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
-# define COPY_PIXEL1(to, from) (*to++ = from)
-#elif DEPTH == 24
-# define PIXEL_TYPE uint8_t
-# define COPY_PIXEL(to, from) \
- do { \
- to[0] = from; \
- to[1] = (from) >> 8; \
- to[2] = (from) >> 16; \
- SKIP_PIXEL(to); \
- } while (0)
-
-# define COPY_PIXEL1(to, from) \
- do { \
- *to++ = from; \
- *to++ = (from) >> 8; \
- *to++ = (from) >> 16; \
- } while (0)
-#elif DEPTH == 32
-# define PIXEL_TYPE uint32_t
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
-# define COPY_PIXEL1(to, from) (*to++ = from)
-#else
-# error unknown bit depth
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-# define SWAP_WORDS 1
-#endif
-
-static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
- const uint16_t *src, unsigned int width)
-{
-#if !defined(SWAP_WORDS) && DEPTH == 16
- memcpy(dest, src, width);
-#else
- uint16_t data;
- unsigned int r, g, b;
- const uint16_t *end = (const void *) src + width;
- while (src < end) {
- data = *src ++;
- b = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- r = (data & 0x1f) << 3;
- data >>= 5;
- COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
- }
-#endif
-}
-
-static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
- const uint8_t *src, unsigned int width)
-{
- /* TODO: check if SDL 24-bit planes are not in the same format and
- * if so, use memcpy */
- unsigned int r[2], g[2], b[2];
- const uint8_t *end = src + width;
- while (src < end) {
- g[0] = *src ++;
- r[0] = *src ++;
- r[1] = *src ++;
- b[0] = *src ++;
- COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0]));
- b[1] = *src ++;
- g[1] = *src ++;
- COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1]));
- }
-}
-
-static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
- const uint8_t *src, unsigned int width)
-{
- unsigned int r, g, b;
- const uint8_t *end = src + width;
- while (src < end) {
- r = *src ++;
- src ++;
- b = *src ++;
- g = *src ++;
- COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
- }
-}
-
-/* No rotation */
-static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
- NULL,
- /* RGB 5:6:5*/
- (blizzard_fn_t) glue(blizzard_draw_line16_, DEPTH),
- /* RGB 6:6:6 mode 1 */
- (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
- /* RGB 8:8:8 mode 1 */
- (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH),
- NULL, NULL,
- /* RGB 6:6:6 mode 2 */
- (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
- /* RGB 8:8:8 mode 2 */
- (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH),
- /* YUV 4:2:2 */
- NULL,
- /* YUV 4:2:0 */
- NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
-};
-
-/* 90deg, 180deg and 270deg rotation */
-static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = {
- /* TODO */
- [0 ... 0xf] = NULL,
-};
-
-#undef DEPTH
-#undef SKIP_PIXEL
-#undef COPY_PIXEL
-#undef COPY_PIXEL1
-#undef PIXEL_TYPE
-
-#undef SWAP_WORDS
diff --git a/qemu/hw/display/cg3.c b/qemu/hw/display/cg3.c
deleted file mode 100644
index fc0d97fa4..000000000
--- a/qemu/hw/display/cg3.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * QEMU CG3 Frame buffer
- *
- * Copyright (c) 2012 Bob Breuer
- * Copyright (c) 2013 Mark Cave-Ayland
- *
- * 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 "qemu-common.h"
-#include "qemu/error-report.h"
-#include "ui/console.h"
-#include "hw/sysbus.h"
-#include "hw/loader.h"
-
-/* Change to 1 to enable debugging */
-#define DEBUG_CG3 0
-
-#define CG3_ROM_FILE "QEMU,cgthree.bin"
-#define FCODE_MAX_ROM_SIZE 0x10000
-
-#define CG3_REG_SIZE 0x20
-
-#define CG3_REG_BT458_ADDR 0x0
-#define CG3_REG_BT458_COLMAP 0x4
-#define CG3_REG_FBC_CTRL 0x10
-#define CG3_REG_FBC_STATUS 0x11
-#define CG3_REG_FBC_CURSTART 0x12
-#define CG3_REG_FBC_CUREND 0x13
-#define CG3_REG_FBC_VCTRL 0x14
-
-/* Control register flags */
-#define CG3_CR_ENABLE_INTS 0x80
-
-/* Status register flags */
-#define CG3_SR_PENDING_INT 0x80
-#define CG3_SR_1152_900_76_B 0x60
-#define CG3_SR_ID_COLOR 0x01
-
-#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)
-
-typedef struct CG3State {
- SysBusDevice parent_obj;
-
- QemuConsole *con;
- qemu_irq irq;
- hwaddr prom_addr;
- MemoryRegion vram_mem;
- MemoryRegion rom;
- MemoryRegion reg;
- uint32_t vram_size;
- int full_update;
- uint8_t regs[16];
- uint8_t r[256], g[256], b[256];
- uint16_t width, height, depth;
- uint8_t dac_index, dac_state;
-} CG3State;
-
-static void cg3_update_display(void *opaque)
-{
- CG3State *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- const uint8_t *pix;
- uint32_t *data;
- uint32_t dval;
- int x, y, y_start;
- unsigned int width, height;
- ram_addr_t page, page_min, page_max;
-
- if (surface_bits_per_pixel(surface) != 32) {
- return;
- }
- width = s->width;
- height = s->height;
-
- y_start = -1;
- page_min = -1;
- page_max = 0;
- page = 0;
- pix = memory_region_get_ram_ptr(&s->vram_mem);
- data = (uint32_t *)surface_data(surface);
-
- memory_region_sync_dirty_bitmap(&s->vram_mem);
- for (y = 0; y < height; y++) {
- int update = s->full_update;
-
- page = (y * width) & TARGET_PAGE_MASK;
- update |= memory_region_get_dirty(&s->vram_mem, page, page + width,
- DIRTY_MEMORY_VGA);
- if (update) {
- if (y_start < 0) {
- y_start = y;
- }
- if (page < page_min) {
- page_min = page;
- }
- if (page > page_max) {
- page_max = page;
- }
-
- for (x = 0; x < width; x++) {
- dval = *pix++;
- dval = (s->r[dval] << 16) | (s->g[dval] << 8) | s->b[dval];
- *data++ = dval;
- }
- } else {
- if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
- y_start = -1;
- }
- pix += width;
- data += width;
- }
- }
- s->full_update = 0;
- if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
- }
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram_mem,
- page_min, page_max - page_min + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- }
- /* vsync interrupt? */
- if (s->regs[0] & CG3_CR_ENABLE_INTS) {
- s->regs[1] |= CG3_SR_PENDING_INT;
- qemu_irq_raise(s->irq);
- }
-}
-
-static void cg3_invalidate_display(void *opaque)
-{
- CG3State *s = opaque;
-
- memory_region_set_dirty(&s->vram_mem, 0, CG3_VRAM_SIZE);
-}
-
-static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size)
-{
- CG3State *s = opaque;
- int val;
-
- switch (addr) {
- case CG3_REG_BT458_ADDR:
- case CG3_REG_BT458_COLMAP:
- val = 0;
- break;
- case CG3_REG_FBC_CTRL:
- val = s->regs[0];
- break;
- case CG3_REG_FBC_STATUS:
- /* monitor ID 6, board type = 1 (color) */
- val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
- break;
- case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
- val = s->regs[addr - 0x10];
- break;
- default:
- qemu_log_mask(LOG_UNIMP,
- "cg3: Unimplemented register read "
- "reg 0x%" HWADDR_PRIx " size 0x%x\n",
- addr, size);
- val = 0;
- break;
- }
- DPRINTF("read %02x from reg %" HWADDR_PRIx "\n", val, addr);
- return val;
-}
-
-static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned size)
-{
- CG3State *s = opaque;
- uint8_t regval;
- int i;
-
- DPRINTF("write %" PRIx64 " to reg %" HWADDR_PRIx " size %d\n",
- val, addr, size);
-
- switch (addr) {
- case CG3_REG_BT458_ADDR:
- s->dac_index = val;
- s->dac_state = 0;
- break;
- case CG3_REG_BT458_COLMAP:
- /* This register can be written to as either a long word or a byte */
- if (size == 1) {
- val <<= 24;
- }
-
- for (i = 0; i < size; i++) {
- regval = val >> 24;
-
- switch (s->dac_state) {
- case 0:
- s->r[s->dac_index] = regval;
- s->dac_state++;
- break;
- case 1:
- s->g[s->dac_index] = regval;
- s->dac_state++;
- break;
- case 2:
- s->b[s->dac_index] = regval;
- /* Index autoincrement */
- s->dac_index = (s->dac_index + 1) & 0xff;
- default:
- s->dac_state = 0;
- break;
- }
- val <<= 8;
- }
- s->full_update = 1;
- break;
- case CG3_REG_FBC_CTRL:
- s->regs[0] = val;
- break;
- case CG3_REG_FBC_STATUS:
- if (s->regs[1] & CG3_SR_PENDING_INT) {
- /* clear interrupt */
- s->regs[1] &= ~CG3_SR_PENDING_INT;
- qemu_irq_lower(s->irq);
- }
- break;
- case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
- s->regs[addr - 0x10] = val;
- break;
- default:
- qemu_log_mask(LOG_UNIMP,
- "cg3: Unimplemented register write "
- "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
- addr, size, val);
- break;
- }
-}
-
-static const MemoryRegionOps cg3_reg_ops = {
- .read = cg3_reg_read,
- .write = cg3_reg_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 4,
- },
-};
-
-static const GraphicHwOps cg3_ops = {
- .invalidate = cg3_invalidate_display,
- .gfx_update = cg3_update_display,
-};
-
-static void cg3_initfn(Object *obj)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- CG3State *s = CG3(obj);
-
- memory_region_init_ram(&s->rom, obj, "cg3.prom", FCODE_MAX_ROM_SIZE,
- &error_fatal);
- memory_region_set_readonly(&s->rom, true);
- sysbus_init_mmio(sbd, &s->rom);
-
- memory_region_init_io(&s->reg, obj, &cg3_reg_ops, s, "cg3.reg",
- CG3_REG_SIZE);
- sysbus_init_mmio(sbd, &s->reg);
-}
-
-static void cg3_realizefn(DeviceState *dev, Error **errp)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- CG3State *s = CG3(dev);
- int ret;
- char *fcode_filename;
-
- /* FCode ROM */
- vmstate_register_ram_global(&s->rom);
- fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
- if (fcode_filename) {
- ret = load_image_targphys(fcode_filename, s->prom_addr,
- FCODE_MAX_ROM_SIZE);
- g_free(fcode_filename);
- if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
- }
- }
-
- memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size,
- &error_fatal);
- memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
- vmstate_register_ram_global(&s->vram_mem);
- sysbus_init_mmio(sbd, &s->vram_mem);
-
- sysbus_init_irq(sbd, &s->irq);
-
- s->con = graphic_console_init(DEVICE(dev), 0, &cg3_ops, s);
- qemu_console_resize(s->con, s->width, s->height);
-}
-
-static int vmstate_cg3_post_load(void *opaque, int version_id)
-{
- CG3State *s = opaque;
-
- cg3_invalidate_display(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_cg3 = {
- .name = "cg3",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = vmstate_cg3_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(height, CG3State),
- VMSTATE_UINT16(width, CG3State),
- VMSTATE_UINT16(depth, CG3State),
- VMSTATE_BUFFER(r, CG3State),
- VMSTATE_BUFFER(g, CG3State),
- VMSTATE_BUFFER(b, CG3State),
- VMSTATE_UINT8(dac_index, CG3State),
- VMSTATE_UINT8(dac_state, CG3State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void cg3_reset(DeviceState *d)
-{
- CG3State *s = CG3(d);
-
- /* Initialize palette */
- memset(s->r, 0, 256);
- memset(s->g, 0, 256);
- memset(s->b, 0, 256);
-
- s->dac_state = 0;
- s->full_update = 1;
- qemu_irq_lower(s->irq);
-}
-
-static Property cg3_properties[] = {
- DEFINE_PROP_UINT32("vram-size", CG3State, vram_size, -1),
- DEFINE_PROP_UINT16("width", CG3State, width, -1),
- DEFINE_PROP_UINT16("height", CG3State, height, -1),
- DEFINE_PROP_UINT16("depth", CG3State, depth, -1),
- DEFINE_PROP_UINT64("prom-addr", CG3State, prom_addr, -1),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void cg3_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = cg3_realizefn;
- dc->reset = cg3_reset;
- dc->vmsd = &vmstate_cg3;
- dc->props = cg3_properties;
-}
-
-static const TypeInfo cg3_info = {
- .name = TYPE_CG3,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(CG3State),
- .instance_init = cg3_initfn,
- .class_init = cg3_class_init,
-};
-
-static void cg3_register_types(void)
-{
- type_register_static(&cg3_info);
-}
-
-type_init(cg3_register_types)
diff --git a/qemu/hw/display/cirrus_vga.c b/qemu/hw/display/cirrus_vga.c
deleted file mode 100644
index 3d712d592..000000000
--- a/qemu/hw/display/cirrus_vga.c
+++ /dev/null
@@ -1,3091 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * 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.
- */
-/*
- * Reference: Finn Thogersons' VGADOC4b
- * available at http://home.worldonline.dk/~finth/
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/pci/pci.h"
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "vga_int.h"
-#include "hw/loader.h"
-
-/*
- * TODO:
- * - destination write mask support not complete (bits 5..7)
- * - optimize linear mappings
- * - optimize bitblt functions
- */
-
-//#define DEBUG_CIRRUS
-//#define DEBUG_BITBLT
-
-/***************************************
- *
- * definitions
- *
- ***************************************/
-
-// 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
-#define CIRRUS_SR7_BPP_MASK 0x0e
-#define CIRRUS_SR7_BPP_8 0x00
-#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
-#define CIRRUS_SR7_BPP_24 0x04
-#define CIRRUS_SR7_BPP_16 0x06
-#define CIRRUS_SR7_BPP_32 0x08
-#define CIRRUS_SR7_ISAADDR_MASK 0xe0
-
-// sequencer 0x0f
-#define CIRRUS_MEMSIZE_512k 0x08
-#define CIRRUS_MEMSIZE_1M 0x10
-#define CIRRUS_MEMSIZE_2M 0x18
-#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
-
-// sequencer 0x12
-#define CIRRUS_CURSOR_SHOW 0x01
-#define CIRRUS_CURSOR_HIDDENPEL 0x02
-#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
-
-// sequencer 0x17
-#define CIRRUS_BUSTYPE_VLBFAST 0x10
-#define CIRRUS_BUSTYPE_PCI 0x20
-#define CIRRUS_BUSTYPE_VLBSLOW 0x30
-#define CIRRUS_BUSTYPE_ISA 0x38
-#define CIRRUS_MMIO_ENABLE 0x04
-#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
-#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
-
-// control 0x0b
-#define CIRRUS_BANKING_DUAL 0x01
-#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
-
-// control 0x30
-#define CIRRUS_BLTMODE_BACKWARDS 0x01
-#define CIRRUS_BLTMODE_MEMSYSDEST 0x02
-#define CIRRUS_BLTMODE_MEMSYSSRC 0x04
-#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
-#define CIRRUS_BLTMODE_PATTERNCOPY 0x40
-#define CIRRUS_BLTMODE_COLOREXPAND 0x80
-#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
-#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
-#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
-#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
-#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
-
-// control 0x31
-#define CIRRUS_BLT_BUSY 0x01
-#define CIRRUS_BLT_START 0x02
-#define CIRRUS_BLT_RESET 0x04
-#define CIRRUS_BLT_FIFOUSED 0x10
-#define CIRRUS_BLT_AUTOSTART 0x80
-
-// control 0x32
-#define CIRRUS_ROP_0 0x00
-#define CIRRUS_ROP_SRC_AND_DST 0x05
-#define CIRRUS_ROP_NOP 0x06
-#define CIRRUS_ROP_SRC_AND_NOTDST 0x09
-#define CIRRUS_ROP_NOTDST 0x0b
-#define CIRRUS_ROP_SRC 0x0d
-#define CIRRUS_ROP_1 0x0e
-#define CIRRUS_ROP_NOTSRC_AND_DST 0x50
-#define CIRRUS_ROP_SRC_XOR_DST 0x59
-#define CIRRUS_ROP_SRC_OR_DST 0x6d
-#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
-#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
-#define CIRRUS_ROP_SRC_OR_NOTDST 0xad
-#define CIRRUS_ROP_NOTSRC 0xd0
-#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
-#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
-
-#define CIRRUS_ROP_NOP_INDEX 2
-#define CIRRUS_ROP_SRC_INDEX 5
-
-// control 0x33
-#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
-#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
-#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
-
-// memory-mapped IO
-#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
-#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword
-#define CIRRUS_MMIO_BLTWIDTH 0x08 // word
-#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word
-#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word
-#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word
-#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword
-#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword
-#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte
-#define CIRRUS_MMIO_BLTMODE 0x18 // byte
-#define CIRRUS_MMIO_BLTROP 0x1a // byte
-#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
-#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word
-#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte
-#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word
-#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word
-#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word
-#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
-#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte
-#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte
-#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte
-
-#define CIRRUS_PNPMMIO_SIZE 0x1000
-
-struct CirrusVGAState;
-typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
- uint8_t * dst, const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight);
-typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
- uint8_t *dst, 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];
- 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;
-} PCICirrusVGAState;
-
-#define TYPE_PCI_CIRRUS_VGA "cirrus-vga"
-#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];
-
-/***************************************
- *
- * prototypes.
- *
- ***************************************/
-
-
-static void cirrus_bitblt_reset(CirrusVGAState *s);
-static void cirrus_update_memory_access(CirrusVGAState *s);
-
-/***************************************
- *
- * raster operations
- *
- ***************************************/
-
-static bool blit_region_is_unsafe(struct CirrusVGAState *s,
- int32_t pitch, int32_t addr)
-{
- if (pitch < 0) {
- int64_t min = addr
- + ((int64_t)s->cirrus_blt_height-1) * pitch;
- int32_t max = addr
- + s->cirrus_blt_width;
- if (min < 0 || max > s->vga.vram_size) {
- return true;
- }
- } else {
- int64_t max = addr
- + ((int64_t)s->cirrus_blt_height-1) * pitch
- + s->cirrus_blt_width;
- if (max > s->vga.vram_size) {
- return true;
- }
- }
- return false;
-}
-
-static bool blit_is_unsafe(struct CirrusVGAState *s)
-{
- /* should be the case, see cirrus_bitblt_start */
- assert(s->cirrus_blt_width > 0);
- assert(s->cirrus_blt_height > 0);
-
- if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
- return true;
- }
-
- if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
- s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
- return true;
- }
- if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
- s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
- return true;
- }
-
- return false;
-}
-
-static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
-}
-
-static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
- uint8_t *dst,
- int dstpitch, int bltwidth,int bltheight)
-{
-}
-
-#define ROP_NAME 0
-#define ROP_FN(d, s) 0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_dst
-#define ROP_FN(d, s) (s) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_notdst
-#define ROP_FN(d, s) (s) & (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notdst
-#define ROP_FN(d, s) ~(d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src
-#define ROP_FN(d, s) s
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME 1
-#define ROP_FN(d, s) ~0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_dst
-#define ROP_FN(d, s) (~(s)) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_xor_dst
-#define ROP_FN(d, s) (s) ^ (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_dst
-#define ROP_FN(d, s) (s) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_notdst
-#define ROP_FN(d, s) (~(s)) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_notxor_dst
-#define ROP_FN(d, s) ~((s) ^ (d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_notdst
-#define ROP_FN(d, s) (s) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc
-#define ROP_FN(d, s) (~(s))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_dst
-#define ROP_FN(d, s) (~(s)) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_notdst
-#define ROP_FN(d, s) (~(s)) & (~(d))
-#include "cirrus_vga_rop.h"
-
-static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
- cirrus_bitblt_rop_fwd_0,
- cirrus_bitblt_rop_fwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_fwd_src_and_notdst,
- cirrus_bitblt_rop_fwd_notdst,
- cirrus_bitblt_rop_fwd_src,
- cirrus_bitblt_rop_fwd_1,
- cirrus_bitblt_rop_fwd_notsrc_and_dst,
- cirrus_bitblt_rop_fwd_src_xor_dst,
- cirrus_bitblt_rop_fwd_src_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_or_notdst,
- cirrus_bitblt_rop_fwd_src_notxor_dst,
- cirrus_bitblt_rop_fwd_src_or_notdst,
- cirrus_bitblt_rop_fwd_notsrc,
- cirrus_bitblt_rop_fwd_notsrc_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_and_notdst,
-};
-
-static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
- cirrus_bitblt_rop_bkwd_0,
- cirrus_bitblt_rop_bkwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_bkwd_src_and_notdst,
- cirrus_bitblt_rop_bkwd_notdst,
- cirrus_bitblt_rop_bkwd_src,
- cirrus_bitblt_rop_bkwd_1,
- cirrus_bitblt_rop_bkwd_notsrc_and_dst,
- cirrus_bitblt_rop_bkwd_src_xor_dst,
- cirrus_bitblt_rop_bkwd_src_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
- cirrus_bitblt_rop_bkwd_src_notxor_dst,
- cirrus_bitblt_rop_bkwd_src_or_notdst,
- cirrus_bitblt_rop_bkwd_notsrc,
- cirrus_bitblt_rop_bkwd_notsrc_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
-};
-
-#define TRANSP_ROP(name) {\
- name ## _8,\
- name ## _16,\
- }
-#define TRANSP_NOP(func) {\
- func,\
- func,\
- }
-
-static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
- TRANSP_NOP(cirrus_bitblt_rop_nop),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
- TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
- TRANSP_NOP(cirrus_bitblt_rop_nop),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
- TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
-};
-
-#define ROP2(name) {\
- name ## _8,\
- name ## _16,\
- name ## _24,\
- name ## _32,\
- }
-
-#define ROP_NOP2(func) {\
- func,\
- func,\
- func,\
- func,\
- }
-
-static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
- ROP2(cirrus_patternfill_0),
- ROP2(cirrus_patternfill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_patternfill_src_and_notdst),
- ROP2(cirrus_patternfill_notdst),
- ROP2(cirrus_patternfill_src),
- ROP2(cirrus_patternfill_1),
- ROP2(cirrus_patternfill_notsrc_and_dst),
- ROP2(cirrus_patternfill_src_xor_dst),
- ROP2(cirrus_patternfill_src_or_dst),
- ROP2(cirrus_patternfill_notsrc_or_notdst),
- ROP2(cirrus_patternfill_src_notxor_dst),
- ROP2(cirrus_patternfill_src_or_notdst),
- ROP2(cirrus_patternfill_notsrc),
- ROP2(cirrus_patternfill_notsrc_or_dst),
- ROP2(cirrus_patternfill_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
- ROP2(cirrus_colorexpand_transp_0),
- ROP2(cirrus_colorexpand_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_transp_notdst),
- ROP2(cirrus_colorexpand_transp_src),
- ROP2(cirrus_colorexpand_transp_1),
- ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_transp_notsrc),
- ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
- ROP2(cirrus_colorexpand_0),
- ROP2(cirrus_colorexpand_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_src_and_notdst),
- ROP2(cirrus_colorexpand_notdst),
- ROP2(cirrus_colorexpand_src),
- ROP2(cirrus_colorexpand_1),
- ROP2(cirrus_colorexpand_notsrc_and_dst),
- ROP2(cirrus_colorexpand_src_xor_dst),
- ROP2(cirrus_colorexpand_src_or_dst),
- ROP2(cirrus_colorexpand_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_src_notxor_dst),
- ROP2(cirrus_colorexpand_src_or_notdst),
- ROP2(cirrus_colorexpand_notsrc),
- ROP2(cirrus_colorexpand_notsrc_or_dst),
- ROP2(cirrus_colorexpand_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
- ROP2(cirrus_colorexpand_pattern_transp_0),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src),
- ROP2(cirrus_colorexpand_pattern_transp_1),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
- ROP2(cirrus_colorexpand_pattern_0),
- ROP2(cirrus_colorexpand_pattern_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_notdst),
- ROP2(cirrus_colorexpand_pattern_src),
- ROP2(cirrus_colorexpand_pattern_1),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_notsrc),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
-};
-
-static const cirrus_fill_t cirrus_fill[16][4] = {
- ROP2(cirrus_fill_0),
- ROP2(cirrus_fill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_fill_nop),
- ROP2(cirrus_fill_src_and_notdst),
- ROP2(cirrus_fill_notdst),
- ROP2(cirrus_fill_src),
- ROP2(cirrus_fill_1),
- ROP2(cirrus_fill_notsrc_and_dst),
- ROP2(cirrus_fill_src_xor_dst),
- ROP2(cirrus_fill_src_or_dst),
- ROP2(cirrus_fill_notsrc_or_notdst),
- ROP2(cirrus_fill_src_notxor_dst),
- ROP2(cirrus_fill_src_or_notdst),
- ROP2(cirrus_fill_notsrc),
- ROP2(cirrus_fill_notsrc_or_dst),
- ROP2(cirrus_fill_notsrc_and_notdst),
-};
-
-static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
- break;
- case 2:
- color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
- s->cirrus_blt_fgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
- (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
- (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
- s->cirrus_blt_fgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
- break;
- case 2:
- color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
- s->cirrus_blt_bgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
- (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
- (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
- s->cirrus_blt_bgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
- int off_pitch, int bytesperline,
- int lines)
-{
- int y;
- int off_cur;
- int off_cur_end;
-
- for (y = 0; y < lines; y++) {
- off_cur = off_begin;
- off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
- memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
- off_begin += off_pitch;
- }
-}
-
-static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
- const uint8_t * src)
-{
- uint8_t *dst;
-
- dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
-
- if (blit_is_unsafe(s))
- return 0;
-
- (*s->cirrus_rop) (s, dst, src,
- s->cirrus_blt_dstpitch, 0,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- return 1;
-}
-
-/* fill */
-
-static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
-{
- cirrus_fill_t rop_func;
-
- if (blit_is_unsafe(s)) {
- return 0;
- }
- rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
- s->cirrus_blt_dstpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- cirrus_bitblt_reset(s);
- return 1;
-}
-
-/***************************************
- *
- * bitblt (video-to-video)
- *
- ***************************************/
-
-static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
-{
- return cirrus_bitblt_common_patterncopy(s,
- s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
- s->cirrus_addr_mask));
-}
-
-static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
-{
- int sx = 0, sy = 0;
- int dx = 0, dy = 0;
- int depth = 0;
- int notify = 0;
-
- /* make sure to only copy if it's a plain copy ROP */
- if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
- *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
-
- int width, height;
-
- depth = s->vga.get_bpp(&s->vga) / 8;
- s->vga.get_resolution(&s->vga, &width, &height);
-
- /* extra x, y */
- sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
- sy = (src / ABS(s->cirrus_blt_srcpitch));
- dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
- dy = (dst / ABS(s->cirrus_blt_dstpitch));
-
- /* normalize width */
- w /= depth;
-
- /* if we're doing a backward copy, we have to adjust
- our x/y to be the upper left corner (instead of the lower
- right corner) */
- if (s->cirrus_blt_dstpitch < 0) {
- sx -= (s->cirrus_blt_width / depth) - 1;
- dx -= (s->cirrus_blt_width / depth) - 1;
- sy -= s->cirrus_blt_height - 1;
- dy -= s->cirrus_blt_height - 1;
- }
-
- /* are we in the visible portion of memory? */
- if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
- (sx + w) <= width && (sy + h) <= height &&
- (dx + w) <= width && (dy + h) <= height) {
- notify = 1;
- }
- }
-
- /* we have to flush all pending changes so that the copy
- is generated at the appropriate moment in time */
- if (notify)
- graphic_hw_update(s->vga.con);
-
- (*s->cirrus_rop) (s, s->vga.vram_ptr +
- (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
- s->vga.vram_ptr +
- (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
- s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
-
- if (notify) {
- qemu_console_copy(s->vga.con,
- sx, sy, dx, dy,
- s->cirrus_blt_width / depth,
- s->cirrus_blt_height);
- }
-
- /* we don't have to notify the display that this portion has
- changed since qemu_console_copy implies this */
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
-}
-
-static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
-{
- if (blit_is_unsafe(s))
- return 0;
-
- cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
- s->cirrus_blt_srcaddr - s->vga.start_addr,
- s->cirrus_blt_width, s->cirrus_blt_height);
-
- return 1;
-}
-
-/***************************************
- *
- * bitblt (cpu-to-video)
- *
- ***************************************/
-
-static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
-{
- int copy_count;
- uint8_t *end_ptr;
-
- if (s->cirrus_srccounter > 0) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
- the_end:
- s->cirrus_srccounter = 0;
- cirrus_bitblt_reset(s);
- } else {
- /* at least one scan line */
- do {
- (*s->cirrus_rop)(s, s->vga.vram_ptr +
- (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
- s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
- s->cirrus_blt_width, 1);
- s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
- s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
- if (s->cirrus_srccounter <= 0)
- goto the_end;
- /* more bytes than needed can be transferred because of
- word alignment, so we keep them for the next line */
- /* XXX: keep alignment to speed up transfer */
- end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- copy_count = s->cirrus_srcptr_end - end_ptr;
- memmove(s->cirrus_bltbuf, end_ptr, copy_count);
- s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
- }
- }
-}
-
-/***************************************
- *
- * bitblt wrapper
- *
- ***************************************/
-
-static void cirrus_bitblt_reset(CirrusVGAState * s)
-{
- int need_update;
-
- s->vga.gr[0x31] &=
- ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
- need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
- || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
- s->cirrus_srccounter = 0;
- if (!need_update)
- return;
- cirrus_update_memory_access(s);
-}
-
-static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
-{
- int w;
-
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- s->cirrus_blt_srcpitch = 8;
- } else {
- /* XXX: check for 24 bpp */
- s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch;
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
- s->cirrus_blt_srcpitch = ((w + 31) >> 5);
- else
- s->cirrus_blt_srcpitch = ((w + 7) >> 3);
- } else {
- /* always align input size to 32 bits */
- s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
- }
- s->cirrus_srcptr = s->cirrus_bltbuf;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- cirrus_update_memory_access(s);
- return 1;
-}
-
-static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
-{
- /* XXX */
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
-#endif
- return 0;
-}
-
-static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
-{
- int ret;
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- ret = cirrus_bitblt_videotovideo_patterncopy(s);
- } else {
- ret = cirrus_bitblt_videotovideo_copy(s);
- }
- if (ret)
- cirrus_bitblt_reset(s);
- return ret;
-}
-
-static void cirrus_bitblt_start(CirrusVGAState * s)
-{
- uint8_t blt_rop;
-
- s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
-
- s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
- s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
- s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
- s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
- s->cirrus_blt_dstaddr =
- (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
- s->cirrus_blt_srcaddr =
- (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
- s->cirrus_blt_mode = s->vga.gr[0x30];
- s->cirrus_blt_modeext = s->vga.gr[0x33];
- blt_rop = s->vga.gr[0x32];
-
-#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
-
- switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
- case CIRRUS_BLTMODE_PIXELWIDTH8:
- s->cirrus_blt_pixelwidth = 1;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH16:
- s->cirrus_blt_pixelwidth = 2;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH24:
- s->cirrus_blt_pixelwidth = 3;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH32:
- s->cirrus_blt_pixelwidth = 4;
- break;
- default:
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt - pixel width is unknown\n");
-#endif
- goto bitblt_ignore;
- }
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
-
- if ((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
- goto bitblt_ignore;
- }
-
- if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
- (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
- CIRRUS_BLTMODE_TRANSPARENTCOMP |
- CIRRUS_BLTMODE_PATTERNCOPY |
- CIRRUS_BLTMODE_COLOREXPAND)) ==
- (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_solidfill(s, blt_rop);
- } else {
- if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
- CIRRUS_BLTMODE_PATTERNCOPY)) ==
- CIRRUS_BLTMODE_COLOREXPAND) {
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } 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");
- goto bitblt_ignore;
- }
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
- s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
- s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
- s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
- s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
- s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
- s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
- } else {
- s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
- }
- }
- }
- // setup bitblt engine.
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
- if (!cirrus_bitblt_cputovideo(s))
- goto bitblt_ignore;
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
- if (!cirrus_bitblt_videotocpu(s))
- goto bitblt_ignore;
- } else {
- if (!cirrus_bitblt_videotovideo(s))
- goto bitblt_ignore;
- }
- }
- return;
- bitblt_ignore:;
- cirrus_bitblt_reset(s);
-}
-
-static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
-{
- unsigned old_value;
-
- old_value = s->vga.gr[0x31];
- s->vga.gr[0x31] = reg_value;
-
- if (((old_value & CIRRUS_BLT_RESET) != 0) &&
- ((reg_value & CIRRUS_BLT_RESET) == 0)) {
- cirrus_bitblt_reset(s);
- } else if (((old_value & CIRRUS_BLT_START) == 0) &&
- ((reg_value & CIRRUS_BLT_START) != 0)) {
- cirrus_bitblt_start(s);
- }
-}
-
-
-/***************************************
- *
- * basic parameters
- *
- ***************************************/
-
-static void cirrus_get_offsets(VGACommonState *s1,
- uint32_t *pline_offset,
- uint32_t *pstart_addr,
- uint32_t *pline_compare)
-{
- CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
- uint32_t start_addr, line_offset, line_compare;
-
- line_offset = s->vga.cr[0x13]
- | ((s->vga.cr[0x1b] & 0x10) << 4);
- line_offset <<= 3;
- *pline_offset = line_offset;
-
- start_addr = (s->vga.cr[0x0c] << 8)
- | s->vga.cr[0x0d]
- | ((s->vga.cr[0x1b] & 0x01) << 16)
- | ((s->vga.cr[0x1b] & 0x0c) << 15)
- | ((s->vga.cr[0x1d] & 0x80) << 12);
- *pstart_addr = start_addr;
-
- line_compare = s->vga.cr[0x18] |
- ((s->vga.cr[0x07] & 0x10) << 4) |
- ((s->vga.cr[0x09] & 0x40) << 3);
- *pline_compare = line_compare;
-}
-
-static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
-{
- uint32_t ret = 16;
-
- switch (s->cirrus_hidden_dac_data & 0xf) {
- case 0:
- ret = 15;
- break; /* Sierra HiColor */
- case 1:
- 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
- ret = 15; /* XXX */
- break;
- }
- return ret;
-}
-
-static int cirrus_get_bpp(VGACommonState *s1)
-{
- CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
- uint32_t ret = 8;
-
- if ((s->vga.sr[0x07] & 0x01) != 0) {
- /* Cirrus SVGA */
- switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
- case CIRRUS_SR7_BPP_8:
- ret = 8;
- break;
- case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_24:
- ret = 24;
- break;
- case CIRRUS_SR7_BPP_16:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_32:
- ret = 32;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
-#endif
- ret = 8;
- break;
- }
- } else {
- /* VGA */
- ret = 0;
- }
-
- return ret;
-}
-
-static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1);
- /* interlace support */
- if (s->cr[0x1a] & 0x01)
- height = height * 2;
- *pwidth = width;
- *pheight = height;
-}
-
-/***************************************
- *
- * bank memory
- *
- ***************************************/
-
-static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
-{
- unsigned offset;
- unsigned limit;
-
- if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */
- offset = s->vga.gr[0x09 + bank_index];
- else /* single bank */
- offset = s->vga.gr[0x09];
-
- if ((s->vga.gr[0x0b] & 0x20) != 0)
- offset <<= 14;
- else
- offset <<= 12;
-
- if (s->real_vram_size <= offset)
- limit = 0;
- else
- limit = s->real_vram_size - offset;
-
- if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
- if (limit > 0x8000) {
- offset += 0x8000;
- limit -= 0x8000;
- } else {
- limit = 0;
- }
- }
-
- if (limit > 0) {
- s->cirrus_bank_base[bank_index] = offset;
- s->cirrus_bank_limit[bank_index] = limit;
- } else {
- s->cirrus_bank_base[bank_index] = 0;
- s->cirrus_bank_limit[bank_index] = 0;
- }
-}
-
-/***************************************
- *
- * I/O access between 0x3c4-0x3c5
- *
- ***************************************/
-
-static int cirrus_vga_read_sr(CirrusVGAState * s)
-{
- switch (s->vga.sr_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- return s->vga.sr[s->vga.sr_index];
- case 0x06: // Unlock Cirrus extensions
- return s->vga.sr[s->vga.sr_index];
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- return s->vga.sr[0x10];
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- return s->vga.sr[0x11];
- case 0x05: // ???
- case 0x07: // Extended Sequencer Mode
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x12: // Graphics Cursor Attribute
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x17: // Configuration Readback and Extended Control
- case 0x18: // Signature Generator Control
- case 0x19: // Signal Generator Result
- case 0x1a: // Signal Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
-#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
- return 0xff;
- break;
- }
-}
-
-static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
-{
- switch (s->vga.sr_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
- if (s->vga.sr_index == 1)
- s->vga.update_retrace_info(&s->vga);
- break;
- case 0x06: // Unlock Cirrus extensions
- val &= 0x17;
- if (val == 0x12) {
- s->vga.sr[s->vga.sr_index] = 0x12;
- } else {
- s->vga.sr[s->vga.sr_index] = 0x0f;
- }
- break;
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- s->vga.sr[0x10] = val;
- s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
- break;
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- s->vga.sr[0x11] = val;
- s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
- break;
- case 0x07: // Extended Sequencer Mode
- cirrus_update_memory_access(s);
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x18: // Signature Generator Control
- case 0x19: // Signature Generator Result
- case 0x1a: // Signature Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
- s->vga.sr[s->vga.sr_index] = val;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
- s->vga.sr_index, val);
-#endif
- break;
- case 0x12: // Graphics Cursor Attribute
- s->vga.sr[0x12] = val;
- s->vga.force_shadow = !!(val & CIRRUS_CURSOR_SHOW);
-#ifdef DEBUG_CIRRUS
- printf("cirrus: cursor ctl SR12=%02x (force shadow: %d)\n",
- val, s->vga.force_shadow);
-#endif
- break;
- case 0x17: // Configuration Readback and Extended Control
- s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
- | (val & 0xc7);
- 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
- break;
- }
-}
-
-/***************************************
- *
- * I/O access at 0x3c6
- *
- ***************************************/
-
-static int cirrus_read_hidden_dac(CirrusVGAState * s)
-{
- if (++s->cirrus_hidden_dac_lockindex == 5) {
- s->cirrus_hidden_dac_lockindex = 0;
- return s->cirrus_hidden_dac_data;
- }
- return 0xff;
-}
-
-static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
-{
- if (s->cirrus_hidden_dac_lockindex == 4) {
- s->cirrus_hidden_dac_data = reg_value;
-#if defined(DEBUG_CIRRUS)
- printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
-#endif
- }
- s->cirrus_hidden_dac_lockindex = 0;
-}
-
-/***************************************
- *
- * I/O access at 0x3c9
- *
- ***************************************/
-
-static int cirrus_vga_read_palette(CirrusVGAState * s)
-{
- int val;
-
- if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
- val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
- s->vga.dac_sub_index];
- } else {
- val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
- }
- if (++s->vga.dac_sub_index == 3) {
- s->vga.dac_sub_index = 0;
- s->vga.dac_read_index++;
- }
- return val;
-}
-
-static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
-{
- s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
- if (++s->vga.dac_sub_index == 3) {
- if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
- memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
- s->vga.dac_cache, 3);
- } else {
- memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
- }
- /* XXX update cursor */
- s->vga.dac_sub_index = 0;
- s->vga.dac_write_index++;
- }
-}
-
-/***************************************
- *
- * I/O access between 0x3ce-0x3cf
- *
- ***************************************/
-
-static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- return s->cirrus_shadow_gr0;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- return s->cirrus_shadow_gr1;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- return s->vga.gr[s->vga.gr_index];
- case 0x05: // Standard VGA, Cirrus extended mode
- default:
- break;
- }
-
- if (reg_index < 0x3a) {
- return s->vga.gr[reg_index];
- } else {
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport gr_index %02x\n", reg_index);
-#endif
- return 0xff;
- }
-}
-
-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
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
- s->cirrus_shadow_gr0 = reg_value;
- break;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
- s->cirrus_shadow_gr1 = reg_value;
- break;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
- break;
- case 0x05: // Standard VGA, Cirrus extended mode
- s->vga.gr[reg_index] = reg_value & 0x7f;
- cirrus_update_memory_access(s);
- break;
- case 0x09: // bank offset #0
- case 0x0A: // bank offset #1
- s->vga.gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- cirrus_update_memory_access(s);
- break;
- case 0x0B:
- s->vga.gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- cirrus_update_memory_access(s);
- break;
- case 0x10: // BGCOLOR 0x0000ff00
- case 0x11: // FGCOLOR 0x0000ff00
- case 0x12: // BGCOLOR 0x00ff0000
- case 0x13: // FGCOLOR 0x00ff0000
- case 0x14: // BGCOLOR 0xff000000
- case 0x15: // FGCOLOR 0xff000000
- case 0x20: // BLT WIDTH 0x0000ff
- case 0x22: // BLT HEIGHT 0x0000ff
- case 0x24: // BLT DEST PITCH 0x0000ff
- case 0x26: // BLT SRC PITCH 0x0000ff
- case 0x28: // BLT DEST ADDR 0x0000ff
- case 0x29: // BLT DEST ADDR 0x00ff00
- case 0x2c: // BLT SRC ADDR 0x0000ff
- case 0x2d: // BLT SRC ADDR 0x00ff00
- case 0x2f: // BLT WRITEMASK
- case 0x30: // BLT MODE
- case 0x32: // RASTER OP
- case 0x33: // BLT MODEEXT
- case 0x34: // BLT TRANSPARENT COLOR 0x00ff
- case 0x35: // BLT TRANSPARENT COLOR 0xff00
- case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
- case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
- s->vga.gr[reg_index] = reg_value;
- break;
- case 0x21: // BLT WIDTH 0x001f00
- case 0x23: // BLT HEIGHT 0x001f00
- case 0x25: // BLT DEST PITCH 0x001f00
- case 0x27: // BLT SRC PITCH 0x001f00
- s->vga.gr[reg_index] = reg_value & 0x1f;
- break;
- case 0x2a: // BLT DEST ADDR 0x3f0000
- s->vga.gr[reg_index] = reg_value & 0x3f;
- /* if auto start mode, starts bit blt now */
- if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
- cirrus_bitblt_start(s);
- }
- break;
- case 0x2e: // BLT SRC ADDR 0x3f0000
- s->vga.gr[reg_index] = reg_value & 0x3f;
- break;
- case 0x31: // BLT STATUS/START
- 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
- break;
- }
-}
-
-/***************************************
- *
- * I/O access between 0x3d4-0x3d5
- *
- ***************************************/
-
-static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- return s->vga.cr[s->vga.cr_index];
- case 0x24: // Attribute Controller Toggle Readback (R)
- return (s->vga.ar_flip_flop << 7);
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x25: // Part Status
- case 0x27: // Part ID (R)
- return s->vga.cr[s->vga.cr_index];
- case 0x26: // Attribute Controller Index Readback (R)
- return s->vga.ar_index & 0x3f;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport cr_index %02x\n", reg_index);
-#endif
- return 0xff;
- }
-}
-
-static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
-{
- switch (s->vga.cr_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- /* handle CR0-7 protection */
- if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
- /* can always write bit 4 of CR7 */
- if (s->vga.cr_index == 7)
- s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
- return;
- }
- s->vga.cr[s->vga.cr_index] = reg_value;
- switch(s->vga.cr_index) {
- case 0x00:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x11:
- case 0x17:
- s->vga.update_retrace_info(&s->vga);
- break;
- }
- break;
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- s->vga.cr[s->vga.cr_index] = reg_value;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
- s->vga.cr_index, reg_value);
-#endif
- break;
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x24: // Attribute Controller Toggle Readback (R)
- case 0x26: // Attribute Controller Index Readback (R)
- case 0x27: // Part ID (R)
- 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
- break;
- }
-}
-
-/***************************************
- *
- * memory-mapped I/O (bitblt)
- *
- ***************************************/
-
-static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
-{
- int value = 0xff;
-
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- value = cirrus_vga_read_gr(s, 0x00);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- value = cirrus_vga_read_gr(s, 0x10);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- value = cirrus_vga_read_gr(s, 0x12);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- value = cirrus_vga_read_gr(s, 0x14);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- value = cirrus_vga_read_gr(s, 0x01);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- value = cirrus_vga_read_gr(s, 0x11);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- value = cirrus_vga_read_gr(s, 0x13);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- value = cirrus_vga_read_gr(s, 0x15);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- value = cirrus_vga_read_gr(s, 0x20);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- value = cirrus_vga_read_gr(s, 0x21);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- value = cirrus_vga_read_gr(s, 0x22);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- value = cirrus_vga_read_gr(s, 0x23);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- value = cirrus_vga_read_gr(s, 0x24);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- value = cirrus_vga_read_gr(s, 0x25);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- value = cirrus_vga_read_gr(s, 0x26);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- value = cirrus_vga_read_gr(s, 0x27);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- value = cirrus_vga_read_gr(s, 0x28);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- value = cirrus_vga_read_gr(s, 0x29);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- value = cirrus_vga_read_gr(s, 0x2a);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- value = cirrus_vga_read_gr(s, 0x2c);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- value = cirrus_vga_read_gr(s, 0x2d);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- value = cirrus_vga_read_gr(s, 0x2e);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- value = cirrus_vga_read_gr(s, 0x2f);
- break;
- case CIRRUS_MMIO_BLTMODE:
- value = cirrus_vga_read_gr(s, 0x30);
- break;
- case CIRRUS_MMIO_BLTROP:
- value = cirrus_vga_read_gr(s, 0x32);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- value = cirrus_vga_read_gr(s, 0x33);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- value = cirrus_vga_read_gr(s, 0x34);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- value = cirrus_vga_read_gr(s, 0x35);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- value = cirrus_vga_read_gr(s, 0x38);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- value = cirrus_vga_read_gr(s, 0x39);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- value = cirrus_vga_read_gr(s, 0x31);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mmio read - address 0x%04x\n", address);
-#endif
- break;
- }
-
- return (uint8_t) value;
-}
-
-static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
- uint8_t value)
-{
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- cirrus_vga_write_gr(s, 0x00, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- cirrus_vga_write_gr(s, 0x10, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- cirrus_vga_write_gr(s, 0x12, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- cirrus_vga_write_gr(s, 0x14, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- cirrus_vga_write_gr(s, 0x01, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- cirrus_vga_write_gr(s, 0x11, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- cirrus_vga_write_gr(s, 0x13, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- cirrus_vga_write_gr(s, 0x15, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- cirrus_vga_write_gr(s, 0x20, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- cirrus_vga_write_gr(s, 0x21, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- cirrus_vga_write_gr(s, 0x22, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- cirrus_vga_write_gr(s, 0x23, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- cirrus_vga_write_gr(s, 0x24, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- cirrus_vga_write_gr(s, 0x25, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- cirrus_vga_write_gr(s, 0x26, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- cirrus_vga_write_gr(s, 0x27, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- cirrus_vga_write_gr(s, 0x28, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- cirrus_vga_write_gr(s, 0x29, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- cirrus_vga_write_gr(s, 0x2a, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 3):
- /* ignored */
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- cirrus_vga_write_gr(s, 0x2c, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- cirrus_vga_write_gr(s, 0x2d, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- cirrus_vga_write_gr(s, 0x2e, value);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- cirrus_vga_write_gr(s, 0x2f, value);
- break;
- case CIRRUS_MMIO_BLTMODE:
- cirrus_vga_write_gr(s, 0x30, value);
- break;
- case CIRRUS_MMIO_BLTROP:
- cirrus_vga_write_gr(s, 0x32, value);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- cirrus_vga_write_gr(s, 0x33, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- cirrus_vga_write_gr(s, 0x34, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- cirrus_vga_write_gr(s, 0x35, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- cirrus_vga_write_gr(s, 0x38, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- cirrus_vga_write_gr(s, 0x39, value);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- 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
- break;
- }
-}
-
-/***************************************
- *
- * write mode 4/5
- *
- ***************************************/
-
-static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst = s->cirrus_shadow_gr1;
- } else if (mode == 5) {
- *dst = s->cirrus_shadow_gr0;
- }
- val <<= 1;
- dst++;
- }
- memory_region_set_dirty(&s->vga.vram, offset, 8);
-}
-
-static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst = s->cirrus_shadow_gr1;
- *(dst + 1) = s->vga.gr[0x11];
- } else if (mode == 5) {
- *dst = s->cirrus_shadow_gr0;
- *(dst + 1) = s->vga.gr[0x10];
- }
- val <<= 1;
- dst += 2;
- }
- memory_region_set_dirty(&s->vga.vram, offset, 16);
-}
-
-/***************************************
- *
- * memory access between 0xa0000-0xbffff
- *
- ***************************************/
-
-static uint64_t cirrus_vga_mem_read(void *opaque,
- hwaddr addr,
- uint32_t size)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- uint32_t val;
-
- if ((s->vga.sr[0x07] & 0x01) == 0) {
- return vga_mem_readb(&s->vga, addr);
- }
-
- if (addr < 0x10000) {
- /* XXX handle bitblt */
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->vga.gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- val = *(s->vga.vram_ptr + bank_offset);
- } else
- val = 0xff;
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- val = 0xff;
- if ((s->vga.sr[0x17] & 0x44) == 0x04) {
- val = cirrus_mmio_blt_read(s, addr & 0xff);
- }
- } else {
- val = 0xff;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr);
-#endif
- }
- return val;
-}
-
-static void cirrus_vga_mem_write(void *opaque,
- hwaddr addr,
- uint64_t mem_value,
- uint32_t size)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- unsigned mode;
-
- if ((s->vga.sr[0x07] & 0x01) == 0) {
- vga_mem_writeb(&s->vga, addr, mem_value);
- return;
- }
-
- if (addr < 0x10000) {
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) mem_value;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->vga.gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- mode = s->vga.gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
- *(s->vga.vram_ptr + bank_offset) = mem_value;
- memory_region_set_dirty(&s->vga.vram, bank_offset,
- sizeof(mem_value));
- } else {
- if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode,
- bank_offset,
- mem_value);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode,
- bank_offset,
- mem_value);
- }
- }
- }
- }
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- if ((s->vga.sr[0x17] & 0x44) == 0x04) {
- 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
- }
-}
-
-static const MemoryRegionOps cirrus_vga_mem_ops = {
- .read = cirrus_vga_mem_read,
- .write = cirrus_vga_mem_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-/***************************************
- *
- * hardware cursor
- *
- ***************************************/
-
-static inline void invalidate_cursor1(CirrusVGAState *s)
-{
- if (s->last_hw_cursor_size) {
- vga_invalidate_scanlines(&s->vga,
- s->last_hw_cursor_y + s->last_hw_cursor_y_start,
- s->last_hw_cursor_y + s->last_hw_cursor_y_end);
- }
-}
-
-static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
-{
- const uint8_t *src;
- uint32_t content;
- int y, y_min, y_max;
-
- src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->vga.sr[0x13] & 0x3c) * 256;
- y_min = 64;
- y_max = -1;
- for(y = 0; y < 64; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 16;
- }
- } else {
- src += (s->vga.sr[0x13] & 0x3f) * 256;
- y_min = 32;
- y_max = -1;
- for(y = 0; y < 32; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 4;
- }
- }
- if (y_min > y_max) {
- s->last_hw_cursor_y_start = 0;
- s->last_hw_cursor_y_end = 0;
- } else {
- s->last_hw_cursor_y_start = y_min;
- s->last_hw_cursor_y_end = y_max + 1;
- }
-}
-
-/* NOTE: we do not currently handle the cursor bitmap change, so we
- update the cursor only if it moves. */
-static void cirrus_cursor_invalidate(VGACommonState *s1)
-{
- CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
- int size;
-
- if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
- size = 0;
- } else {
- if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
- size = 64;
- else
- size = 32;
- }
- /* invalidate last cursor and new cursor if any change */
- if (s->last_hw_cursor_size != size ||
- s->last_hw_cursor_x != s->vga.hw_cursor_x ||
- s->last_hw_cursor_y != s->vga.hw_cursor_y) {
-
- invalidate_cursor1(s);
-
- s->last_hw_cursor_size = size;
- s->last_hw_cursor_x = s->vga.hw_cursor_x;
- s->last_hw_cursor_y = s->vga.hw_cursor_y;
- /* compute the real cursor min and max y */
- cirrus_cursor_compute_yrange(s);
- invalidate_cursor1(s);
- }
-}
-
-static void vga_draw_cursor_line(uint8_t *d1,
- const uint8_t *src1,
- int poffset, int w,
- unsigned int color0,
- unsigned int color1,
- unsigned int color_xor)
-{
- const uint8_t *plane0, *plane1;
- int x, b0, b1;
- uint8_t *d;
-
- d = d1;
- plane0 = src1;
- plane1 = src1 + poffset;
- for (x = 0; x < w; x++) {
- b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
- b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
- switch (b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- ((uint32_t *)d)[0] ^= color_xor;
- break;
- case 2:
- ((uint32_t *)d)[0] = color0;
- break;
- case 3:
- ((uint32_t *)d)[0] = color1;
- break;
- }
- d += 4;
- }
-}
-
-static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
-{
- CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
- int w, h, x1, x2, poffset;
- unsigned int color0, color1;
- const uint8_t *palette, *src;
- uint32_t content;
-
- if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
- return;
- /* fast test to see if the cursor intersects with the scan line */
- if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
- h = 64;
- } else {
- h = 32;
- }
- if (scr_y < s->vga.hw_cursor_y ||
- scr_y >= (s->vga.hw_cursor_y + h)) {
- return;
- }
-
- src = s->vga.vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->vga.sr[0x13] & 0x3c) * 256;
- src += (scr_y - s->vga.hw_cursor_y) * 16;
- poffset = 8;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- } else {
- src += (s->vga.sr[0x13] & 0x3f) * 256;
- src += (scr_y - s->vga.hw_cursor_y) * 4;
-
-
- poffset = 128;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- }
- /* if nothing to draw, no need to continue */
- if (!content)
- return;
- w = h;
-
- x1 = s->vga.hw_cursor_x;
- if (x1 >= s->vga.last_scr_width)
- return;
- x2 = s->vga.hw_cursor_x + w;
- if (x2 > s->vga.last_scr_width)
- x2 = s->vga.last_scr_width;
- w = x2 - x1;
- palette = s->cirrus_hidden_palette;
- color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]),
- c6_to_8(palette[0x0 * 3 + 1]),
- c6_to_8(palette[0x0 * 3 + 2]));
- color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]),
- c6_to_8(palette[0xf * 3 + 1]),
- c6_to_8(palette[0xf * 3 + 2]));
- d1 += x1 * 4;
- vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff);
-}
-
-/***************************************
- *
- * LFB memory access
- *
- ***************************************/
-
-static uint64_t cirrus_linear_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- CirrusVGAState *s = opaque;
- uint32_t ret;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- ret = cirrus_mmio_blt_read(s, addr & 0xff);
- } else if (0) {
- /* XXX handle bitblt */
- ret = 0xff;
- } else {
- /* video memory */
- if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->vga.gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
- ret = *(s->vga.vram_ptr + addr);
- }
-
- return ret;
-}
-
-static void cirrus_linear_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- CirrusVGAState *s = opaque;
- unsigned mode;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- cirrus_mmio_blt_write(s, addr & 0xff, val);
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->vga.gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
-
- mode = s->vga.gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
- *(s->vga.vram_ptr + addr) = (uint8_t) val;
- memory_region_set_dirty(&s->vga.vram, addr, 1);
- } else {
- if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
- }
- }
- }
-}
-
-/***************************************
- *
- * system to screen memory access
- *
- ***************************************/
-
-
-static uint64_t cirrus_linear_bitblt_read(void *opaque,
- hwaddr addr,
- unsigned size)
-{
- CirrusVGAState *s = opaque;
- uint32_t ret;
-
- /* XXX handle bitblt */
- (void)s;
- ret = 0xff;
- return ret;
-}
-
-static void cirrus_linear_bitblt_write(void *opaque,
- hwaddr addr,
- uint64_t val,
- unsigned size)
-{
- CirrusVGAState *s = opaque;
-
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- }
-}
-
-static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
- .read = cirrus_linear_bitblt_read,
- .write = cirrus_linear_bitblt_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
-{
- MemoryRegion *mr = &s->cirrus_bank[bank];
- bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end)
- && !((s->vga.sr[0x07] & 0x01) == 0)
- && !((s->vga.gr[0x0B] & 0x14) == 0x14)
- && !(s->vga.gr[0x0B] & 0x02);
-
- memory_region_set_enabled(mr, enabled);
- memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]);
-}
-
-static void map_linear_vram(CirrusVGAState *s)
-{
- if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) {
- s->linear_vram = true;
- memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
- }
- map_linear_vram_bank(s, 0);
- map_linear_vram_bank(s, 1);
-}
-
-static void unmap_linear_vram(CirrusVGAState *s)
-{
- if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) {
- s->linear_vram = false;
- memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
- }
- memory_region_set_enabled(&s->cirrus_bank[0], false);
- memory_region_set_enabled(&s->cirrus_bank[1], false);
-}
-
-/* Compute the memory access functions */
-static void cirrus_update_memory_access(CirrusVGAState *s)
-{
- unsigned mode;
-
- memory_region_transaction_begin();
- if ((s->vga.sr[0x17] & 0x44) == 0x44) {
- goto generic_io;
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- goto generic_io;
- } else {
- if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
- goto generic_io;
- } else if (s->vga.gr[0x0B] & 0x02) {
- goto generic_io;
- }
-
- mode = s->vga.gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
- map_linear_vram(s);
- } else {
- generic_io:
- unmap_linear_vram(s);
- }
- }
- memory_region_transaction_commit();
-}
-
-
-/* I/O ports */
-
-static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- CirrusVGAState *c = opaque;
- VGACommonState *s = &c->vga;
- int val, index;
-
- addr += 0x3b0;
-
- if (vga_ioport_invalid(s, addr)) {
- val = 0xff;
- } else {
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case 0x3c1:
- index = s->ar_index & 0x1f;
- if (index < 21)
- val = s->ar[index];
- else
- val = 0;
- break;
- case 0x3c2:
- val = s->st00;
- break;
- case 0x3c4:
- val = s->sr_index;
- break;
- case 0x3c5:
- val = cirrus_vga_read_sr(c);
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case 0x3c6:
- val = cirrus_read_hidden_dac(c);
- break;
- case 0x3c7:
- val = s->dac_state;
- break;
- case 0x3c8:
- val = s->dac_write_index;
- c->cirrus_hidden_dac_lockindex = 0;
- break;
- case 0x3c9:
- val = cirrus_vga_read_palette(c);
- break;
- case 0x3ca:
- val = s->fcr;
- break;
- case 0x3cc:
- val = s->msr;
- break;
- case 0x3ce:
- val = s->gr_index;
- break;
- case 0x3cf:
- val = cirrus_vga_read_gr(c, s->gr_index);
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case 0x3b4:
- case 0x3d4:
- val = s->cr_index;
- break;
- case 0x3b5:
- case 0x3d5:
- val = cirrus_vga_read_cr(c, s->cr_index);
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- /* just toggle to fool polling */
- val = s->st01 = s->retrace(s);
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned size)
-{
- CirrusVGAState *c = opaque;
- VGACommonState *s = &c->vga;
- int index;
-
- addr += 0x3b0;
-
- /* check port range access depending on color/monochrome mode */
- if (vga_ioport_invalid(s, addr)) {
- return;
- }
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch (index) {
- case 0x00 ... 0x0f:
- s->ar[index] = val & 0x3f;
- break;
- case 0x10:
- s->ar[index] = val & ~0x10;
- break;
- case 0x11:
- s->ar[index] = val;
- break;
- case 0x12:
- s->ar[index] = val & ~0xc0;
- break;
- case 0x13:
- s->ar[index] = val & ~0xf0;
- break;
- case 0x14:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case 0x3c2:
- s->msr = val & ~0x10;
- s->update_retrace_info(s);
- break;
- case 0x3c4:
- s->sr_index = val;
- break;
- case 0x3c5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val);
-#endif
- cirrus_vga_write_sr(c, val);
- break;
- case 0x3c6:
- cirrus_write_hidden_dac(c, val);
- break;
- case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case 0x3c9:
- cirrus_vga_write_palette(c, val);
- break;
- case 0x3ce:
- s->gr_index = val;
- break;
- case 0x3cf:
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val);
-#endif
- cirrus_vga_write_gr(c, s->gr_index, val);
- break;
- case 0x3b4:
- case 0x3d4:
- s->cr_index = val;
- break;
- case 0x3b5:
- case 0x3d5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val);
-#endif
- cirrus_vga_write_cr(c, val);
- break;
- case 0x3ba:
- case 0x3da:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-/***************************************
- *
- * memory-mapped I/O access
- *
- ***************************************/
-
-static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- CirrusVGAState *s = opaque;
-
- if (addr >= 0x100) {
- return cirrus_mmio_blt_read(s, addr - 0x100);
- } else {
- return cirrus_vga_ioport_read(s, addr + 0x10, size);
- }
-}
-
-static void cirrus_mmio_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- CirrusVGAState *s = opaque;
-
- if (addr >= 0x100) {
- cirrus_mmio_blt_write(s, addr - 0x100, val);
- } else {
- cirrus_vga_ioport_write(s, addr + 0x10, val, size);
- }
-}
-
-static const MemoryRegionOps cirrus_mmio_io_ops = {
- .read = cirrus_mmio_read,
- .write = cirrus_mmio_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-/* load/save state */
-
-static int cirrus_post_load(void *opaque, int version_id)
-{
- CirrusVGAState *s = opaque;
-
- s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
- s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
-
- cirrus_update_memory_access(s);
- /* force refresh */
- s->vga.graphic_mode = -1;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- return 0;
-}
-
-static const VMStateDescription vmstate_cirrus_vga = {
- .name = "cirrus_vga",
- .version_id = 2,
- .minimum_version_id = 1,
- .post_load = cirrus_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(vga.latch, CirrusVGAState),
- VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
- VMSTATE_BUFFER(vga.sr, CirrusVGAState),
- VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
- VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
- VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
- VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
- VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
- VMSTATE_BUFFER(vga.ar, CirrusVGAState),
- VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
- VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
- VMSTATE_BUFFER(vga.cr, CirrusVGAState),
- VMSTATE_UINT8(vga.msr, CirrusVGAState),
- VMSTATE_UINT8(vga.fcr, CirrusVGAState),
- VMSTATE_UINT8(vga.st00, CirrusVGAState),
- VMSTATE_UINT8(vga.st01, CirrusVGAState),
- VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
- VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
- VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
- VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
- VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
- VMSTATE_BUFFER(vga.palette, CirrusVGAState),
- VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
- VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
- VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
- VMSTATE_UINT32(vga.hw_cursor_x, CirrusVGAState),
- VMSTATE_UINT32(vga.hw_cursor_y, CirrusVGAState),
- /* XXX: we do not save the bitblt state - we assume we do not save
- the state when the blitter is active */
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_pci_cirrus_vga = {
- .name = "cirrus_vga",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
- VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
- vmstate_cirrus_vga, CirrusVGAState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/***************************************
- *
- * initialize
- *
- ***************************************/
-
-static void cirrus_reset(void *opaque)
-{
- CirrusVGAState *s = opaque;
-
- vga_common_reset(&s->vga);
- unmap_linear_vram(s);
- s->vga.sr[0x06] = 0x0f;
- if (s->device_id == CIRRUS_ID_CLGD5446) {
- /* 4MB 64 bit memory config, always PCI */
- s->vga.sr[0x1F] = 0x2d; // MemClock
- s->vga.gr[0x18] = 0x0f; // fastest memory configuration
- s->vga.sr[0x0f] = 0x98;
- s->vga.sr[0x17] = 0x20;
- s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
- } else {
- s->vga.sr[0x1F] = 0x22; // MemClock
- s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
- s->vga.sr[0x17] = s->bustype;
- s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
- }
- s->vga.cr[0x27] = s->device_id;
-
- s->cirrus_hidden_dac_lockindex = 5;
- s->cirrus_hidden_dac_data = 0;
-}
-
-static const MemoryRegionOps cirrus_linear_io_ops = {
- .read = cirrus_linear_read,
- .write = cirrus_linear_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static const MemoryRegionOps cirrus_vga_io_ops = {
- .read = cirrus_vga_ioport_read,
- .write = cirrus_vga_ioport_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static 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;
-
- if (!inited) {
- inited = 1;
- for(i = 0;i < 256; i++)
- rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
- rop_to_index[CIRRUS_ROP_0] = 0;
- rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
- rop_to_index[CIRRUS_ROP_NOP] = 2;
- rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
- rop_to_index[CIRRUS_ROP_NOTDST] = 4;
- rop_to_index[CIRRUS_ROP_SRC] = 5;
- rop_to_index[CIRRUS_ROP_1] = 6;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
- rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
- rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
- rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
- rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
- rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
- s->device_id = device_id;
- if (is_pci)
- s->bustype = CIRRUS_BUSTYPE_PCI;
- else
- s->bustype = CIRRUS_BUSTYPE_ISA;
- }
-
- /* Register ioport 0x3b0 - 0x3df */
- memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
- "cirrus-io", 0x30);
- memory_region_set_flush_coalesced(&s->cirrus_vga_io);
- memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
-
- memory_region_init(&s->low_mem_container, owner,
- "cirrus-lowmem-container",
- 0x20000);
-
- memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s,
- "cirrus-low-memory", 0x20000);
- memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
- for (i = 0; i < 2; ++i) {
- static const char *names[] = { "vga.bank0", "vga.bank1" };
- MemoryRegion *bank = &s->cirrus_bank[i];
- memory_region_init_alias(bank, owner, names[i], &s->vga.vram,
- 0, 0x8000);
- memory_region_set_enabled(bank, false);
- memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000,
- bank, 1);
- }
- memory_region_add_subregion_overlap(system_memory,
- 0x000a0000,
- &s->low_mem_container,
- 1);
- memory_region_set_coalescing(&s->low_mem);
-
- /* I/O handler for LFB */
- memory_region_init_io(&s->cirrus_linear_io, owner, &cirrus_linear_io_ops, s,
- "cirrus-linear-io", s->vga.vram_size_mb
- * 1024 * 1024);
- memory_region_set_flush_coalesced(&s->cirrus_linear_io);
-
- /* I/O handler for LFB */
- memory_region_init_io(&s->cirrus_linear_bitblt_io, owner,
- &cirrus_linear_bitblt_io_ops,
- s,
- "cirrus-bitblt-mmio",
- 0x400000);
- memory_region_set_flush_coalesced(&s->cirrus_linear_bitblt_io);
-
- /* I/O handler for memory-mapped I/O */
- memory_region_init_io(&s->cirrus_mmio_io, owner, &cirrus_mmio_io_ops, s,
- "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
- memory_region_set_flush_coalesced(&s->cirrus_mmio_io);
-
- s->real_vram_size =
- (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
-
- /* XXX: s->vga.vram_size must be a power of two */
- s->cirrus_addr_mask = s->real_vram_size - 1;
- s->linear_mmio_mask = s->real_vram_size - 256;
-
- s->vga.get_bpp = cirrus_get_bpp;
- s->vga.get_offsets = cirrus_get_offsets;
- s->vga.get_resolution = cirrus_get_resolution;
- s->vga.cursor_invalidate = cirrus_cursor_invalidate;
- s->vga.cursor_draw_line = cirrus_cursor_draw_line;
-
- qemu_register_reset(cirrus_reset, s);
-}
-
-/***************************************
- *
- * 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;
- }
- vga_common_init(s, OBJECT(dev), true);
- 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, 8),
- 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
- *
- ***************************************/
-
-static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
-{
- PCICirrusVGAState *d = PCI_CIRRUS_VGA(dev);
- CirrusVGAState *s = &d->cirrus_vga;
- PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
- int16_t device_id = pc->device_id;
-
- /* follow real hardware, cirrus card emulated has 4 MB video memory.
- Also accept 8 MB/16 MB for backward compatibility. */
- if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 &&
- s->vga.vram_size_mb != 16) {
- error_setg(errp, "Invalid cirrus_vga ram size '%u'",
- s->vga.vram_size_mb);
- return;
- }
- /* setup VGA */
- vga_common_init(&s->vga, OBJECT(dev), true);
- cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev),
- pci_address_space_io(dev));
- s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga);
-
- /* setup PCI */
-
- memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000);
-
- /* XXX: add byte swapping apertures */
- memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
- memory_region_add_subregion(&s->pci_bar, 0x1000000,
- &s->cirrus_linear_bitblt_io);
-
- /* setup memory space */
- /* memory #0 LFB */
- /* memory #1 memory-mapped I/O */
- /* XXX: s->vga.vram_size must be a power of two */
- pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
- if (device_id == CIRRUS_ID_CLGD5446) {
- pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
- }
-}
-
-static Property pci_vga_cirrus_properties[] = {
- DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
- cirrus_vga.vga.vram_size_mb, 8),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void cirrus_vga_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = pci_cirrus_vga_realize;
- k->romfile = VGABIOS_CIRRUS_FILENAME;
- k->vendor_id = PCI_VENDOR_ID_CIRRUS;
- k->device_id = CIRRUS_ID_CLGD5446;
- k->class_id = PCI_CLASS_DISPLAY_VGA;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->desc = "Cirrus CLGD 54xx VGA";
- dc->vmsd = &vmstate_pci_cirrus_vga;
- dc->props = pci_vga_cirrus_properties;
- dc->hotpluggable = false;
-}
-
-static const TypeInfo cirrus_vga_info = {
- .name = TYPE_PCI_CIRRUS_VGA,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCICirrusVGAState),
- .class_init = cirrus_vga_class_init,
-};
-
-static void cirrus_vga_register_types(void)
-{
- type_register_static(&isa_cirrus_vga_info);
- type_register_static(&cirrus_vga_info);
-}
-
-type_init(cirrus_vga_register_types)
diff --git a/qemu/hw/display/cirrus_vga_rop.h b/qemu/hw/display/cirrus_vga_rop.h
deleted file mode 100644
index 0925a009f..000000000
--- a/qemu/hw/display/cirrus_vga_rop.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * 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.
- */
-
-static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
-{
- *dst = ROP_FN(*dst, src);
-}
-
-static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
-{
- *dst = ROP_FN(*dst, src);
-}
-
-static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
-{
- *dst = ROP_FN(*dst, src);
-}
-
-#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
-#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
-#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
-#undef ROP_FN
-
-static void
-glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
-
- if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
- return;
- }
-
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(dst, *src);
- dst++;
- src++;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(dst, *src);
- dst--;
- src--;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint8_t p;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- p = *dst;
- ROP_OP(&p, *src);
- if (p != s->vga.gr[0x34]) *dst = p;
- dst++;
- src++;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint8_t p;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- p = *dst;
- ROP_OP(&p, *src);
- if (p != s->vga.gr[0x34]) *dst = p;
- dst--;
- src--;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint8_t p1, p2;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x+=2) {
- p1 = *dst;
- p2 = *(dst+1);
- ROP_OP(&p1, *src);
- ROP_OP(&p2, *(src + 1));
- if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
- *dst = p1;
- *(dst+1) = p2;
- }
- dst+=2;
- src+=2;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- uint8_t p1, p2;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x+=2) {
- p1 = *(dst-1);
- p2 = *dst;
- ROP_OP(&p1, *(src - 1));
- ROP_OP(&p2, *src);
- if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
- *(dst-1) = p1;
- *dst = p2;
- }
- dst-=2;
- src-=2;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-#define DEPTH 8
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 16
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 24
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 32
-#include "cirrus_vga_rop2.h"
-
-#undef ROP_NAME
-#undef ROP_OP
-#undef ROP_OP_16
-#undef ROP_OP_32
diff --git a/qemu/hw/display/cirrus_vga_rop2.h b/qemu/hw/display/cirrus_vga_rop2.h
deleted file mode 100644
index d28bcc6f2..000000000
--- a/qemu/hw/display/cirrus_vga_rop2.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * 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.
- */
-
-#if DEPTH == 8
-#define PUTPIXEL() ROP_OP(&d[0], col)
-#elif DEPTH == 16
-#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col)
-#elif DEPTH == 24
-#define PUTPIXEL() ROP_OP(&d[0], col); \
- ROP_OP(&d[1], (col >> 8)); \
- ROP_OP(&d[2], (col >> 16))
-#elif DEPTH == 32
-#define PUTPIXEL() ROP_OP_32(((uint32_t *)&d[0]), col)
-#else
-#error unsupported DEPTH
-#endif
-
-static void
-glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y, pattern_y, pattern_pitch, pattern_x;
- unsigned int col;
- const uint8_t *src1;
-#if DEPTH == 24
- int skipleft = s->vga.gr[0x2f] & 0x1f;
-#else
- int skipleft = (s->vga.gr[0x2f] & 0x07) * (DEPTH / 8);
-#endif
-
-#if DEPTH == 8
- pattern_pitch = 8;
-#elif DEPTH == 16
- pattern_pitch = 16;
-#else
- pattern_pitch = 32;
-#endif
- pattern_y = s->cirrus_blt_srcaddr & 7;
- for(y = 0; y < bltheight; y++) {
- pattern_x = skipleft;
- d = dst + skipleft;
- src1 = src + pattern_y * pattern_pitch;
- for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
-#if DEPTH == 8
- col = src1[pattern_x];
- pattern_x = (pattern_x + 1) & 7;
-#elif DEPTH == 16
- col = ((uint16_t *)(src1 + pattern_x))[0];
- pattern_x = (pattern_x + 2) & 15;
-#elif DEPTH == 24
- {
- const uint8_t *src2 = src1 + pattern_x * 3;
- col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
- pattern_x = (pattern_x + 1) & 7;
- }
-#else
- col = ((uint32_t *)(src1 + pattern_x))[0];
- pattern_x = (pattern_x + 4) & 31;
-#endif
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-/* NOTE: srcpitch is ignored */
-static void
-glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y;
- unsigned bits, bits_xor;
- unsigned int col;
- unsigned bitmask;
- unsigned index;
-#if DEPTH == 24
- int dstskipleft = s->vga.gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->vga.gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
-
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *src++ ^ bits_xor;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *src++ ^ bits_xor;
- }
- index = (bits & bitmask);
- if (index) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint32_t colors[2];
- uint8_t *d;
- int x, y;
- unsigned bits;
- unsigned int col;
- unsigned bitmask;
- int srcskipleft = s->vga.gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *src++;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *src++;
- }
- col = colors[!!(bits & bitmask)];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y, bitpos, pattern_y;
- unsigned int bits, bits_xor;
- unsigned int col;
-#if DEPTH == 24
- int dstskipleft = s->vga.gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->vga.gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = src[pattern_y] ^ bits_xor;
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bits >> bitpos) & 1) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint32_t colors[2];
- uint8_t *d;
- int x, y, bitpos, pattern_y;
- unsigned int bits;
- unsigned int col;
- int srcskipleft = s->vga.gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = src[pattern_y];
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- col = colors[(bits >> bitpos) & 1];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState *s,
- uint8_t *dst, int dst_pitch,
- int width, int height)
-{
- uint8_t *d, *d1;
- uint32_t col;
- int x, y;
-
- col = s->cirrus_blt_fgcol;
-
- d1 = dst;
- for(y = 0; y < height; y++) {
- d = d1;
- for(x = 0; x < width; x += (DEPTH / 8)) {
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- d1 += dst_pitch;
- }
-}
-
-#undef DEPTH
-#undef PUTPIXEL
diff --git a/qemu/hw/display/exynos4210_fimd.c b/qemu/hw/display/exynos4210_fimd.c
deleted file mode 100644
index 728eb214a..000000000
--- a/qemu/hw/display/exynos4210_fimd.c
+++ /dev/null
@@ -1,1952 +0,0 @@
-/*
- * Samsung exynos4210 Display Controller (FIMD)
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
- * All rights reserved.
- * Based on LCD controller for Samsung S5PC1xx-based board emulation
- * by Kirill Batuzov <batuzovk@ispras.ru>
- *
- * Contributed by Mitsyanko Igor <i.mitsyanko@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "hw/sysbus.h"
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "qemu/bswap.h"
-
-/* Debug messages configuration */
-#define EXYNOS4210_FIMD_DEBUG 0
-#define EXYNOS4210_FIMD_MODE_TRACE 0
-
-#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
- #define DPRINT_TRACE(fmt, args...) do { } while (0)
-#else
- #define DPRINT_TRACE(fmt, args...) \
- do {fprintf(stderr, "QEMU FIMD: "fmt, ## args); } while (0)
-#endif
-
-#define NUM_OF_WINDOWS 5
-#define FIMD_REGS_SIZE 0x4114
-
-/* Video main control registers */
-#define FIMD_VIDCON0 0x0000
-#define FIMD_VIDCON1 0x0004
-#define FIMD_VIDCON2 0x0008
-#define FIMD_VIDCON3 0x000C
-#define FIMD_VIDCON0_ENVID_F (1 << 0)
-#define FIMD_VIDCON0_ENVID (1 << 1)
-#define FIMD_VIDCON0_ENVID_MASK ((1 << 0) | (1 << 1))
-#define FIMD_VIDCON1_ROMASK 0x07FFE000
-
-/* Video time control registers */
-#define FIMD_VIDTCON_START 0x10
-#define FIMD_VIDTCON_END 0x1C
-#define FIMD_VIDTCON2_SIZE_MASK 0x07FF
-#define FIMD_VIDTCON2_HOR_SHIFT 0
-#define FIMD_VIDTCON2_VER_SHIFT 11
-
-/* Window control registers */
-#define FIMD_WINCON_START 0x0020
-#define FIMD_WINCON_END 0x0030
-#define FIMD_WINCON_ROMASK 0x82200000
-#define FIMD_WINCON_ENWIN (1 << 0)
-#define FIMD_WINCON_BLD_PIX (1 << 6)
-#define FIMD_WINCON_ALPHA_MUL (1 << 7)
-#define FIMD_WINCON_ALPHA_SEL (1 << 1)
-#define FIMD_WINCON_SWAP 0x078000
-#define FIMD_WINCON_SWAP_SHIFT 15
-#define FIMD_WINCON_SWAP_WORD 0x1
-#define FIMD_WINCON_SWAP_HWORD 0x2
-#define FIMD_WINCON_SWAP_BYTE 0x4
-#define FIMD_WINCON_SWAP_BITS 0x8
-#define FIMD_WINCON_BUFSTAT_L (1 << 21)
-#define FIMD_WINCON_BUFSTAT_H (1 << 31)
-#define FIMD_WINCON_BUFSTATUS ((1 << 21) | (1 << 31))
-#define FIMD_WINCON_BUF0_STAT ((0 << 21) | (0 << 31))
-#define FIMD_WINCON_BUF1_STAT ((1 << 21) | (0 << 31))
-#define FIMD_WINCON_BUF2_STAT ((0 << 21) | (1 << 31))
-#define FIMD_WINCON_BUFSELECT ((1 << 20) | (1 << 30))
-#define FIMD_WINCON_BUF0_SEL ((0 << 20) | (0 << 30))
-#define FIMD_WINCON_BUF1_SEL ((1 << 20) | (0 << 30))
-#define FIMD_WINCON_BUF2_SEL ((0 << 20) | (1 << 30))
-#define FIMD_WINCON_BUFMODE (1 << 14)
-#define IS_PALETTIZED_MODE(w) (w->wincon & 0xC)
-#define PAL_MODE_WITH_ALPHA(x) ((x) == 7)
-#define WIN_BPP_MODE(w) ((w->wincon >> 2) & 0xF)
-#define WIN_BPP_MODE_WITH_ALPHA(w) \
- (WIN_BPP_MODE(w) == 0xD || WIN_BPP_MODE(w) == 0xE)
-
-/* Shadow control register */
-#define FIMD_SHADOWCON 0x0034
-#define FIMD_WINDOW_PROTECTED(s, w) ((s) & (1 << (10 + (w))))
-/* Channel mapping control register */
-#define FIMD_WINCHMAP 0x003C
-
-/* Window position control registers */
-#define FIMD_VIDOSD_START 0x0040
-#define FIMD_VIDOSD_END 0x0088
-#define FIMD_VIDOSD_COORD_MASK 0x07FF
-#define FIMD_VIDOSD_HOR_SHIFT 11
-#define FIMD_VIDOSD_VER_SHIFT 0
-#define FIMD_VIDOSD_ALPHA_AEN0 0xFFF000
-#define FIMD_VIDOSD_AEN0_SHIFT 12
-#define FIMD_VIDOSD_ALPHA_AEN1 0x000FFF
-
-/* 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
-#define FIMD_VIDWADD2_END 0x0110
-#define FIMD_VIDWADD2_PAGEWIDTH 0x1FFF
-#define FIMD_VIDWADD2_OFFSIZE 0x1FFF
-#define FIMD_VIDWADD2_OFFSIZE_SHIFT 13
-#define FIMD_VIDW0ADD0_B2 0x20A0
-#define FIMD_VIDW4ADD0_B2 0x20C0
-
-/* Video interrupt control registers */
-#define FIMD_VIDINTCON0 0x130
-#define FIMD_VIDINTCON1 0x134
-
-/* Window color key registers */
-#define FIMD_WKEYCON_START 0x140
-#define FIMD_WKEYCON_END 0x15C
-#define FIMD_WKEYCON0_COMPKEY 0x00FFFFFF
-#define FIMD_WKEYCON0_CTL_SHIFT 24
-#define FIMD_WKEYCON0_DIRCON (1 << 24)
-#define FIMD_WKEYCON0_KEYEN (1 << 25)
-#define FIMD_WKEYCON0_KEYBLEN (1 << 26)
-/* Window color key alpha control register */
-#define FIMD_WKEYALPHA_START 0x160
-#define FIMD_WKEYALPHA_END 0x16C
-
-/* Dithering control register */
-#define FIMD_DITHMODE 0x170
-
-/* Window alpha control registers */
-#define FIMD_VIDALPHA_ALPHA_LOWER 0x000F0F0F
-#define FIMD_VIDALPHA_ALPHA_UPPER 0x00F0F0F0
-#define FIMD_VIDWALPHA_START 0x21C
-#define FIMD_VIDWALPHA_END 0x240
-
-/* Window color map registers */
-#define FIMD_WINMAP_START 0x180
-#define FIMD_WINMAP_END 0x190
-#define FIMD_WINMAP_EN (1 << 24)
-#define FIMD_WINMAP_COLOR_MASK 0x00FFFFFF
-
-/* Window palette control registers */
-#define FIMD_WPALCON_HIGH 0x019C
-#define FIMD_WPALCON_LOW 0x01A0
-#define FIMD_WPALCON_UPDATEEN (1 << 9)
-#define FIMD_WPAL_W0PAL_L 0x07
-#define FIMD_WPAL_W0PAL_L_SHT 0
-#define FIMD_WPAL_W1PAL_L 0x07
-#define FIMD_WPAL_W1PAL_L_SHT 3
-#define FIMD_WPAL_W2PAL_L 0x01
-#define FIMD_WPAL_W2PAL_L_SHT 6
-#define FIMD_WPAL_W2PAL_H 0x06
-#define FIMD_WPAL_W2PAL_H_SHT 8
-#define FIMD_WPAL_W3PAL_L 0x01
-#define FIMD_WPAL_W3PAL_L_SHT 7
-#define FIMD_WPAL_W3PAL_H 0x06
-#define FIMD_WPAL_W3PAL_H_SHT 12
-#define FIMD_WPAL_W4PAL_L 0x01
-#define FIMD_WPAL_W4PAL_L_SHT 8
-#define FIMD_WPAL_W4PAL_H 0x06
-#define FIMD_WPAL_W4PAL_H_SHT 16
-
-/* Trigger control registers */
-#define FIMD_TRIGCON 0x01A4
-#define FIMD_TRIGCON_ROMASK 0x00000004
-
-/* LCD I80 Interface Control */
-#define FIMD_I80IFCON_START 0x01B0
-#define FIMD_I80IFCON_END 0x01BC
-/* Color gain control register */
-#define FIMD_COLORGAINCON 0x01C0
-/* LCD i80 Interface Command Control */
-#define FIMD_LDI_CMDCON0 0x01D0
-#define FIMD_LDI_CMDCON1 0x01D4
-/* I80 System Interface Manual Command Control */
-#define FIMD_SIFCCON0 0x01E0
-#define FIMD_SIFCCON2 0x01E8
-
-/* Hue Control Registers */
-#define FIMD_HUECOEFCR_START 0x01EC
-#define FIMD_HUECOEFCR_END 0x01F4
-#define FIMD_HUECOEFCB_START 0x01FC
-#define FIMD_HUECOEFCB_END 0x0208
-#define FIMD_HUEOFFSET 0x020C
-
-/* Video interrupt control registers */
-#define FIMD_VIDINT_INTFIFOPEND (1 << 0)
-#define FIMD_VIDINT_INTFRMPEND (1 << 1)
-#define FIMD_VIDINT_INTI80PEND (1 << 2)
-#define FIMD_VIDINT_INTEN (1 << 0)
-#define FIMD_VIDINT_INTFIFOEN (1 << 1)
-#define FIMD_VIDINT_INTFRMEN (1 << 12)
-#define FIMD_VIDINT_I80IFDONE (1 << 17)
-
-/* Window blend equation control registers */
-#define FIMD_BLENDEQ_START 0x0244
-#define FIMD_BLENDEQ_END 0x0250
-#define FIMD_BLENDCON 0x0260
-#define FIMD_ALPHA_8BIT (1 << 0)
-#define FIMD_BLENDEQ_COEF_MASK 0xF
-
-/* Window RTQOS Control Registers */
-#define FIMD_WRTQOSCON_START 0x0264
-#define FIMD_WRTQOSCON_END 0x0274
-
-/* LCD I80 Interface Command */
-#define FIMD_I80IFCMD_START 0x0280
-#define FIMD_I80IFCMD_END 0x02AC
-
-/* Shadow windows control registers */
-#define FIMD_SHD_ADD0_START 0x40A0
-#define FIMD_SHD_ADD0_END 0x40C0
-#define FIMD_SHD_ADD1_START 0x40D0
-#define FIMD_SHD_ADD1_END 0x40F0
-#define FIMD_SHD_ADD2_START 0x4100
-#define FIMD_SHD_ADD2_END 0x4110
-
-/* Palette memory */
-#define FIMD_PAL_MEM_START 0x2400
-#define FIMD_PAL_MEM_END 0x37FC
-/* Palette memory aliases for windows 0 and 1 */
-#define FIMD_PALMEM_AL_START 0x0400
-#define FIMD_PALMEM_AL_END 0x0BFC
-
-typedef struct {
- uint8_t r, g, b;
- /* D[31..24]dummy, D[23..16]rAlpha, D[15..8]gAlpha, D[7..0]bAlpha */
- uint32_t a;
-} rgba;
-#define RGBA_SIZE 7
-
-typedef void pixel_to_rgb_func(uint32_t pixel, rgba *p);
-typedef struct Exynos4210fimdWindow Exynos4210fimdWindow;
-
-struct Exynos4210fimdWindow {
- uint32_t wincon; /* Window control register */
- uint32_t buf_start[3]; /* Start address for video frame buffer */
- uint32_t buf_end[3]; /* End address for video frame buffer */
- uint32_t keycon[2]; /* Window color key registers */
- uint32_t keyalpha; /* Color key alpha control register */
- uint32_t winmap; /* Window color map register */
- uint32_t blendeq; /* Window blending equation control register */
- uint32_t rtqoscon; /* Window RTQOS Control Registers */
- uint32_t palette[256]; /* Palette RAM */
- uint32_t shadow_buf_start; /* Start address of shadow frame buffer */
- uint32_t shadow_buf_end; /* End address of shadow frame buffer */
- uint32_t shadow_buf_size; /* Virtual shadow screen width */
-
- pixel_to_rgb_func *pixel_to_rgb;
- void (*draw_line)(Exynos4210fimdWindow *w, uint8_t *src, uint8_t *dst,
- bool blend);
- uint32_t (*get_alpha)(Exynos4210fimdWindow *w, uint32_t pix_a);
- uint16_t lefttop_x, lefttop_y; /* VIDOSD0 register */
- uint16_t rightbot_x, rightbot_y; /* VIDOSD1 register */
- uint32_t osdsize; /* VIDOSD2&3 register */
- uint32_t alpha_val[2]; /* VIDOSD2&3, VIDWALPHA registers */
- uint16_t virtpage_width; /* VIDWADD2 register */
- uint16_t virtpage_offsize; /* VIDWADD2 register */
- MemoryRegionSection mem_section; /* RAM fragment containing framebuffer */
- uint8_t *host_fb_addr; /* Host pointer to window's framebuffer */
- hwaddr fb_len; /* Framebuffer length */
-};
-
-#define TYPE_EXYNOS4210_FIMD "exynos4210.fimd"
-#define EXYNOS4210_FIMD(obj) \
- OBJECT_CHECK(Exynos4210fimdState, (obj), TYPE_EXYNOS4210_FIMD)
-
-typedef struct {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- QemuConsole *console;
- qemu_irq irq[3];
-
- uint32_t vidcon[4]; /* Video main control registers 0-3 */
- uint32_t vidtcon[4]; /* Video time control registers 0-3 */
- uint32_t shadowcon; /* Window shadow control register */
- uint32_t winchmap; /* Channel mapping control register */
- uint32_t vidintcon[2]; /* Video interrupt control registers */
- uint32_t dithmode; /* Dithering control register */
- uint32_t wpalcon[2]; /* Window palette control registers */
- uint32_t trigcon; /* Trigger control register */
- uint32_t i80ifcon[4]; /* I80 interface control registers */
- uint32_t colorgaincon; /* Color gain control register */
- uint32_t ldi_cmdcon[2]; /* LCD I80 interface command control */
- uint32_t sifccon[3]; /* I80 System Interface Manual Command Control */
- uint32_t huecoef_cr[4]; /* Hue control registers */
- uint32_t huecoef_cb[4]; /* Hue control registers */
- uint32_t hueoffset; /* Hue offset control register */
- uint32_t blendcon; /* Blending control register */
- uint32_t i80ifcmd[12]; /* LCD I80 Interface Command */
-
- Exynos4210fimdWindow window[5]; /* Window-specific registers */
- uint8_t *ifb; /* Internal frame buffer */
- bool invalidate; /* Image needs to be redrawn */
- bool enabled; /* Display controller is enabled */
-} Exynos4210fimdState;
-
-/* Perform byte/halfword/word swap of data according to WINCON */
-static inline void fimd_swap_data(unsigned int swap_ctl, uint64_t *data)
-{
- int i;
- uint64_t res;
- uint64_t x = *data;
-
- if (swap_ctl & FIMD_WINCON_SWAP_BITS) {
- res = 0;
- for (i = 0; i < 64; i++) {
- if (x & (1ULL << (63 - i))) {
- res |= (1ULL << i);
- }
- }
- x = res;
- }
-
- if (swap_ctl & FIMD_WINCON_SWAP_BYTE) {
- x = bswap64(x);
- }
-
- if (swap_ctl & FIMD_WINCON_SWAP_HWORD) {
- x = ((x & 0x000000000000FFFFULL) << 48) |
- ((x & 0x00000000FFFF0000ULL) << 16) |
- ((x & 0x0000FFFF00000000ULL) >> 16) |
- ((x & 0xFFFF000000000000ULL) >> 48);
- }
-
- if (swap_ctl & FIMD_WINCON_SWAP_WORD) {
- x = ((x & 0x00000000FFFFFFFFULL) << 32) |
- ((x & 0xFFFFFFFF00000000ULL) >> 32);
- }
-
- *data = x;
-}
-
-/* Conversion routines of Pixel data from frame buffer area to internal RGBA
- * pixel representation.
- * Every color component internally represented as 8-bit value. If original
- * data has less than 8 bit for component, data is extended to 8 bit. For
- * example, if blue component has only two possible values 0 and 1 it will be
- * extended to 0 and 0xFF */
-
-/* One bit for alpha representation */
-#define DEF_PIXEL_TO_RGB_A1(N, R, G, B) \
-static void N(uint32_t pixel, rgba *p) \
-{ \
- p->b = ((pixel & ((1 << (B)) - 1)) << (8 - (B))) | \
- ((pixel >> (2 * (B) - 8)) & ((1 << (8 - (B))) - 1)); \
- pixel >>= (B); \
- p->g = (pixel & ((1 << (G)) - 1)) << (8 - (G)) | \
- ((pixel >> (2 * (G) - 8)) & ((1 << (8 - (G))) - 1)); \
- pixel >>= (G); \
- p->r = (pixel & ((1 << (R)) - 1)) << (8 - (R)) | \
- ((pixel >> (2 * (R) - 8)) & ((1 << (8 - (R))) - 1)); \
- pixel >>= (R); \
- p->a = (pixel & 0x1); \
-}
-
-DEF_PIXEL_TO_RGB_A1(pixel_a444_to_rgb, 4, 4, 4)
-DEF_PIXEL_TO_RGB_A1(pixel_a555_to_rgb, 5, 5, 5)
-DEF_PIXEL_TO_RGB_A1(pixel_a666_to_rgb, 6, 6, 6)
-DEF_PIXEL_TO_RGB_A1(pixel_a665_to_rgb, 6, 6, 5)
-DEF_PIXEL_TO_RGB_A1(pixel_a888_to_rgb, 8, 8, 8)
-DEF_PIXEL_TO_RGB_A1(pixel_a887_to_rgb, 8, 8, 7)
-
-/* Alpha component is always zero */
-#define DEF_PIXEL_TO_RGB_A0(N, R, G, B) \
-static void N(uint32_t pixel, rgba *p) \
-{ \
- p->b = ((pixel & ((1 << (B)) - 1)) << (8 - (B))) | \
- ((pixel >> (2 * (B) - 8)) & ((1 << (8 - (B))) - 1)); \
- pixel >>= (B); \
- p->g = (pixel & ((1 << (G)) - 1)) << (8 - (G)) | \
- ((pixel >> (2 * (G) - 8)) & ((1 << (8 - (G))) - 1)); \
- pixel >>= (G); \
- p->r = (pixel & ((1 << (R)) - 1)) << (8 - (R)) | \
- ((pixel >> (2 * (R) - 8)) & ((1 << (8 - (R))) - 1)); \
- p->a = 0x0; \
-}
-
-DEF_PIXEL_TO_RGB_A0(pixel_565_to_rgb, 5, 6, 5)
-DEF_PIXEL_TO_RGB_A0(pixel_555_to_rgb, 5, 5, 5)
-DEF_PIXEL_TO_RGB_A0(pixel_666_to_rgb, 6, 6, 6)
-DEF_PIXEL_TO_RGB_A0(pixel_888_to_rgb, 8, 8, 8)
-
-/* Alpha component has some meaningful value */
-#define DEF_PIXEL_TO_RGB_A(N, R, G, B, A) \
-static void N(uint32_t pixel, rgba *p) \
-{ \
- p->b = ((pixel & ((1 << (B)) - 1)) << (8 - (B))) | \
- ((pixel >> (2 * (B) - 8)) & ((1 << (8 - (B))) - 1)); \
- pixel >>= (B); \
- p->g = (pixel & ((1 << (G)) - 1)) << (8 - (G)) | \
- ((pixel >> (2 * (G) - 8)) & ((1 << (8 - (G))) - 1)); \
- pixel >>= (G); \
- p->r = (pixel & ((1 << (R)) - 1)) << (8 - (R)) | \
- ((pixel >> (2 * (R) - 8)) & ((1 << (8 - (R))) - 1)); \
- pixel >>= (R); \
- p->a = (pixel & ((1 << (A)) - 1)) << (8 - (A)) | \
- ((pixel >> (2 * (A) - 8)) & ((1 << (8 - (A))) - 1)); \
- p->a = p->a | (p->a << 8) | (p->a << 16); \
-}
-
-DEF_PIXEL_TO_RGB_A(pixel_4444_to_rgb, 4, 4, 4, 4)
-DEF_PIXEL_TO_RGB_A(pixel_8888_to_rgb, 8, 8, 8, 8)
-
-/* Lookup table to extent 2-bit color component to 8 bit */
-static const uint8_t pixel_lutable_2b[4] = {
- 0x0, 0x55, 0xAA, 0xFF
-};
-/* Lookup table to extent 3-bit color component to 8 bit */
-static const uint8_t pixel_lutable_3b[8] = {
- 0x0, 0x24, 0x49, 0x6D, 0x92, 0xB6, 0xDB, 0xFF
-};
-/* Special case for a232 bpp mode */
-static void pixel_a232_to_rgb(uint32_t pixel, rgba *p)
-{
- p->b = pixel_lutable_2b[(pixel & 0x3)];
- pixel >>= 2;
- p->g = pixel_lutable_3b[(pixel & 0x7)];
- pixel >>= 3;
- p->r = pixel_lutable_2b[(pixel & 0x3)];
- pixel >>= 2;
- p->a = (pixel & 0x1);
-}
-
-/* Special case for (5+1, 5+1, 5+1) mode. Data bit 15 is common LSB
- * for all three color components */
-static void pixel_1555_to_rgb(uint32_t pixel, rgba *p)
-{
- uint8_t comm = (pixel >> 15) & 1;
- p->b = ((((pixel & 0x1F) << 1) | comm) << 2) | ((pixel >> 3) & 0x3);
- pixel >>= 5;
- p->g = ((((pixel & 0x1F) << 1) | comm) << 2) | ((pixel >> 3) & 0x3);
- pixel >>= 5;
- p->r = ((((pixel & 0x1F) << 1) | comm) << 2) | ((pixel >> 3) & 0x3);
- p->a = 0x0;
-}
-
-/* Put/get pixel to/from internal LCD Controller framebuffer */
-
-static int put_pixel_ifb(const rgba p, uint8_t *d)
-{
- *(uint8_t *)d++ = p.r;
- *(uint8_t *)d++ = p.g;
- *(uint8_t *)d++ = p.b;
- *(uint32_t *)d = p.a;
- return RGBA_SIZE;
-}
-
-static int get_pixel_ifb(const uint8_t *s, rgba *p)
-{
- p->r = *(uint8_t *)s++;
- p->g = *(uint8_t *)s++;
- p->b = *(uint8_t *)s++;
- p->a = (*(uint32_t *)s) & 0x00FFFFFF;
- return RGBA_SIZE;
-}
-
-static pixel_to_rgb_func *palette_data_format[8] = {
- [0] = pixel_565_to_rgb,
- [1] = pixel_a555_to_rgb,
- [2] = pixel_666_to_rgb,
- [3] = pixel_a665_to_rgb,
- [4] = pixel_a666_to_rgb,
- [5] = pixel_888_to_rgb,
- [6] = pixel_a888_to_rgb,
- [7] = pixel_8888_to_rgb
-};
-
-/* Returns Index in palette data formats table for given window number WINDOW */
-static uint32_t
-exynos4210_fimd_palette_format(Exynos4210fimdState *s, int window)
-{
- uint32_t ret;
-
- switch (window) {
- case 0:
- ret = (s->wpalcon[1] >> FIMD_WPAL_W0PAL_L_SHT) & FIMD_WPAL_W0PAL_L;
- if (ret != 7) {
- ret = 6 - ret;
- }
- break;
- case 1:
- ret = (s->wpalcon[1] >> FIMD_WPAL_W1PAL_L_SHT) & FIMD_WPAL_W1PAL_L;
- if (ret != 7) {
- ret = 6 - ret;
- }
- break;
- case 2:
- ret = ((s->wpalcon[0] >> FIMD_WPAL_W2PAL_H_SHT) & FIMD_WPAL_W2PAL_H) |
- ((s->wpalcon[1] >> FIMD_WPAL_W2PAL_L_SHT) & FIMD_WPAL_W2PAL_L);
- break;
- case 3:
- ret = ((s->wpalcon[0] >> FIMD_WPAL_W3PAL_H_SHT) & FIMD_WPAL_W3PAL_H) |
- ((s->wpalcon[1] >> FIMD_WPAL_W3PAL_L_SHT) & FIMD_WPAL_W3PAL_L);
- break;
- case 4:
- ret = ((s->wpalcon[0] >> FIMD_WPAL_W4PAL_H_SHT) & FIMD_WPAL_W4PAL_H) |
- ((s->wpalcon[1] >> FIMD_WPAL_W4PAL_L_SHT) & FIMD_WPAL_W4PAL_L);
- break;
- default:
- hw_error("exynos4210.fimd: incorrect window number %d\n", window);
- ret = 0;
- break;
- }
- return ret;
-}
-
-#define FIMD_1_MINUS_COLOR(x) \
- ((0xFF - ((x) & 0xFF)) | (0xFF00 - ((x) & 0xFF00)) | \
- (0xFF0000 - ((x) & 0xFF0000)))
-#define EXTEND_LOWER_HALFBYTE(x) (((x) & 0xF0F0F) | (((x) << 4) & 0xF0F0F0))
-#define EXTEND_UPPER_HALFBYTE(x) (((x) & 0xF0F0F0) | (((x) >> 4) & 0xF0F0F))
-
-/* Multiply three lower bytes of two 32-bit words with each other.
- * Each byte with values 0-255 is considered as a number with possible values
- * in a range [0 - 1] */
-static inline uint32_t fimd_mult_each_byte(uint32_t a, uint32_t b)
-{
- uint32_t tmp;
- uint32_t ret;
-
- ret = ((tmp = (((a & 0xFF) * (b & 0xFF)) / 0xFF)) > 0xFF) ? 0xFF : tmp;
- ret |= ((tmp = ((((a >> 8) & 0xFF) * ((b >> 8) & 0xFF)) / 0xFF)) > 0xFF) ?
- 0xFF00 : tmp << 8;
- ret |= ((tmp = ((((a >> 16) & 0xFF) * ((b >> 16) & 0xFF)) / 0xFF)) > 0xFF) ?
- 0xFF0000 : tmp << 16;
- return ret;
-}
-
-/* For each corresponding bytes of two 32-bit words: (a*b + c*d)
- * Byte values 0-255 are mapped to a range [0 .. 1] */
-static inline uint32_t
-fimd_mult_and_sum_each_byte(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
-{
- uint32_t tmp;
- uint32_t ret;
-
- ret = ((tmp = (((a & 0xFF) * (b & 0xFF) + (c & 0xFF) * (d & 0xFF)) / 0xFF))
- > 0xFF) ? 0xFF : tmp;
- ret |= ((tmp = ((((a >> 8) & 0xFF) * ((b >> 8) & 0xFF) + ((c >> 8) & 0xFF) *
- ((d >> 8) & 0xFF)) / 0xFF)) > 0xFF) ? 0xFF00 : tmp << 8;
- ret |= ((tmp = ((((a >> 16) & 0xFF) * ((b >> 16) & 0xFF) +
- ((c >> 16) & 0xFF) * ((d >> 16) & 0xFF)) / 0xFF)) > 0xFF) ?
- 0xFF0000 : tmp << 16;
- return ret;
-}
-
-/* These routines cover all possible sources of window's transparent factor
- * used in blending equation. Choice of routine is affected by WPALCON
- * registers, BLENDCON register and window's WINCON register */
-
-static uint32_t fimd_get_alpha_pix(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return pix_a;
-}
-
-static uint32_t
-fimd_get_alpha_pix_extlow(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return EXTEND_LOWER_HALFBYTE(pix_a);
-}
-
-static uint32_t
-fimd_get_alpha_pix_exthigh(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return EXTEND_UPPER_HALFBYTE(pix_a);
-}
-
-static uint32_t fimd_get_alpha_mult(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return fimd_mult_each_byte(pix_a, w->alpha_val[0]);
-}
-
-static uint32_t fimd_get_alpha_mult_ext(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return fimd_mult_each_byte(EXTEND_LOWER_HALFBYTE(pix_a),
- EXTEND_UPPER_HALFBYTE(w->alpha_val[0]));
-}
-
-static uint32_t fimd_get_alpha_aen(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return w->alpha_val[pix_a];
-}
-
-static uint32_t fimd_get_alpha_aen_ext(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return EXTEND_UPPER_HALFBYTE(w->alpha_val[pix_a]);
-}
-
-static uint32_t fimd_get_alpha_sel(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return w->alpha_val[(w->wincon & FIMD_WINCON_ALPHA_SEL) ? 1 : 0];
-}
-
-static uint32_t fimd_get_alpha_sel_ext(Exynos4210fimdWindow *w, uint32_t pix_a)
-{
- return EXTEND_UPPER_HALFBYTE(w->alpha_val[(w->wincon &
- FIMD_WINCON_ALPHA_SEL) ? 1 : 0]);
-}
-
-/* Updates currently active alpha value get function for specified window */
-static void fimd_update_get_alpha(Exynos4210fimdState *s, int win)
-{
- Exynos4210fimdWindow *w = &s->window[win];
- const bool alpha_is_8bit = s->blendcon & FIMD_ALPHA_8BIT;
-
- if (w->wincon & FIMD_WINCON_BLD_PIX) {
- if ((w->wincon & FIMD_WINCON_ALPHA_SEL) && WIN_BPP_MODE_WITH_ALPHA(w)) {
- /* In this case, alpha component contains meaningful value */
- if (w->wincon & FIMD_WINCON_ALPHA_MUL) {
- w->get_alpha = alpha_is_8bit ?
- fimd_get_alpha_mult : fimd_get_alpha_mult_ext;
- } else {
- w->get_alpha = alpha_is_8bit ?
- fimd_get_alpha_pix : fimd_get_alpha_pix_extlow;
- }
- } else {
- if (IS_PALETTIZED_MODE(w) &&
- PAL_MODE_WITH_ALPHA(exynos4210_fimd_palette_format(s, win))) {
- /* Alpha component has 8-bit numeric value */
- w->get_alpha = alpha_is_8bit ?
- fimd_get_alpha_pix : fimd_get_alpha_pix_exthigh;
- } else {
- /* Alpha has only two possible values (AEN) */
- w->get_alpha = alpha_is_8bit ?
- fimd_get_alpha_aen : fimd_get_alpha_aen_ext;
- }
- }
- } else {
- w->get_alpha = alpha_is_8bit ? fimd_get_alpha_sel :
- fimd_get_alpha_sel_ext;
- }
-}
-
-/* Blends current window's (w) pixel (foreground pixel *ret) with background
- * window (w_blend) pixel p_bg according to formula:
- * NEW_COLOR = a_coef x FG_PIXEL_COLOR + b_coef x BG_PIXEL_COLOR
- * NEW_ALPHA = p_coef x FG_ALPHA + q_coef x BG_ALPHA
- */
-static void
-exynos4210_fimd_blend_pixel(Exynos4210fimdWindow *w, rgba p_bg, rgba *ret)
-{
- rgba p_fg = *ret;
- uint32_t bg_color = ((p_bg.r & 0xFF) << 16) | ((p_bg.g & 0xFF) << 8) |
- (p_bg.b & 0xFF);
- uint32_t fg_color = ((p_fg.r & 0xFF) << 16) | ((p_fg.g & 0xFF) << 8) |
- (p_fg.b & 0xFF);
- uint32_t alpha_fg = p_fg.a;
- int i;
- /* It is possible that blending equation parameters a and b do not
- * depend on window BLENEQ register. Account for this with first_coef */
- enum { A_COEF = 0, B_COEF = 1, P_COEF = 2, Q_COEF = 3, COEF_NUM = 4};
- uint32_t first_coef = A_COEF;
- uint32_t blend_param[COEF_NUM];
-
- if (w->keycon[0] & FIMD_WKEYCON0_KEYEN) {
- uint32_t colorkey = (w->keycon[1] &
- ~(w->keycon[0] & FIMD_WKEYCON0_COMPKEY)) & FIMD_WKEYCON0_COMPKEY;
-
- if ((w->keycon[0] & FIMD_WKEYCON0_DIRCON) &&
- (bg_color & ~(w->keycon[0] & FIMD_WKEYCON0_COMPKEY)) == colorkey) {
- /* Foreground pixel is displayed */
- if (w->keycon[0] & FIMD_WKEYCON0_KEYBLEN) {
- alpha_fg = w->keyalpha;
- blend_param[A_COEF] = alpha_fg;
- blend_param[B_COEF] = FIMD_1_MINUS_COLOR(alpha_fg);
- } else {
- alpha_fg = 0;
- blend_param[A_COEF] = 0xFFFFFF;
- blend_param[B_COEF] = 0x0;
- }
- first_coef = P_COEF;
- } else if ((w->keycon[0] & FIMD_WKEYCON0_DIRCON) == 0 &&
- (fg_color & ~(w->keycon[0] & FIMD_WKEYCON0_COMPKEY)) == colorkey) {
- /* Background pixel is displayed */
- if (w->keycon[0] & FIMD_WKEYCON0_KEYBLEN) {
- alpha_fg = w->keyalpha;
- blend_param[A_COEF] = alpha_fg;
- blend_param[B_COEF] = FIMD_1_MINUS_COLOR(alpha_fg);
- } else {
- alpha_fg = 0;
- blend_param[A_COEF] = 0x0;
- blend_param[B_COEF] = 0xFFFFFF;
- }
- first_coef = P_COEF;
- }
- }
-
- for (i = first_coef; i < COEF_NUM; i++) {
- switch ((w->blendeq >> i * 6) & FIMD_BLENDEQ_COEF_MASK) {
- case 0:
- blend_param[i] = 0;
- break;
- case 1:
- blend_param[i] = 0xFFFFFF;
- break;
- case 2:
- blend_param[i] = alpha_fg;
- break;
- case 3:
- blend_param[i] = FIMD_1_MINUS_COLOR(alpha_fg);
- break;
- case 4:
- blend_param[i] = p_bg.a;
- break;
- case 5:
- blend_param[i] = FIMD_1_MINUS_COLOR(p_bg.a);
- break;
- case 6:
- blend_param[i] = w->alpha_val[0];
- break;
- case 10:
- blend_param[i] = fg_color;
- break;
- case 11:
- blend_param[i] = FIMD_1_MINUS_COLOR(fg_color);
- break;
- case 12:
- blend_param[i] = bg_color;
- break;
- case 13:
- blend_param[i] = FIMD_1_MINUS_COLOR(bg_color);
- break;
- default:
- hw_error("exynos4210.fimd: blend equation coef illegal value\n");
- break;
- }
- }
-
- fg_color = fimd_mult_and_sum_each_byte(bg_color, blend_param[B_COEF],
- fg_color, blend_param[A_COEF]);
- ret->b = fg_color & 0xFF;
- fg_color >>= 8;
- ret->g = fg_color & 0xFF;
- fg_color >>= 8;
- ret->r = fg_color & 0xFF;
- ret->a = fimd_mult_and_sum_each_byte(alpha_fg, blend_param[P_COEF],
- p_bg.a, blend_param[Q_COEF]);
-}
-
-/* These routines read data from video frame buffer in system RAM, convert
- * this data to display controller internal representation, if necessary,
- * perform pixel blending with data, currently presented in internal buffer.
- * Result is stored in display controller internal frame buffer. */
-
-/* Draw line with index in palette table in RAM frame buffer data */
-#define DEF_DRAW_LINE_PALETTE(N) \
-static void glue(draw_line_palette_, N)(Exynos4210fimdWindow *w, uint8_t *src, \
- uint8_t *dst, bool blend) \
-{ \
- int width = w->rightbot_x - w->lefttop_x + 1; \
- uint8_t *ifb = dst; \
- uint8_t swap = (w->wincon & FIMD_WINCON_SWAP) >> FIMD_WINCON_SWAP_SHIFT; \
- uint64_t data; \
- rgba p, p_old; \
- int i; \
- do { \
- memcpy(&data, src, sizeof(data)); \
- src += 8; \
- fimd_swap_data(swap, &data); \
- for (i = (64 / (N) - 1); i >= 0; i--) { \
- w->pixel_to_rgb(w->palette[(data >> ((N) * i)) & \
- ((1ULL << (N)) - 1)], &p); \
- p.a = w->get_alpha(w, p.a); \
- if (blend) { \
- ifb += get_pixel_ifb(ifb, &p_old); \
- exynos4210_fimd_blend_pixel(w, p_old, &p); \
- } \
- dst += put_pixel_ifb(p, dst); \
- } \
- width -= (64 / (N)); \
- } while (width > 0); \
-}
-
-/* Draw line with direct color value in RAM frame buffer data */
-#define DEF_DRAW_LINE_NOPALETTE(N) \
-static void glue(draw_line_, N)(Exynos4210fimdWindow *w, uint8_t *src, \
- uint8_t *dst, bool blend) \
-{ \
- int width = w->rightbot_x - w->lefttop_x + 1; \
- uint8_t *ifb = dst; \
- uint8_t swap = (w->wincon & FIMD_WINCON_SWAP) >> FIMD_WINCON_SWAP_SHIFT; \
- uint64_t data; \
- rgba p, p_old; \
- int i; \
- do { \
- memcpy(&data, src, sizeof(data)); \
- src += 8; \
- fimd_swap_data(swap, &data); \
- for (i = (64 / (N) - 1); i >= 0; i--) { \
- w->pixel_to_rgb((data >> ((N) * i)) & ((1ULL << (N)) - 1), &p); \
- p.a = w->get_alpha(w, p.a); \
- if (blend) { \
- ifb += get_pixel_ifb(ifb, &p_old); \
- exynos4210_fimd_blend_pixel(w, p_old, &p); \
- } \
- dst += put_pixel_ifb(p, dst); \
- } \
- width -= (64 / (N)); \
- } while (width > 0); \
-}
-
-DEF_DRAW_LINE_PALETTE(1)
-DEF_DRAW_LINE_PALETTE(2)
-DEF_DRAW_LINE_PALETTE(4)
-DEF_DRAW_LINE_PALETTE(8)
-DEF_DRAW_LINE_NOPALETTE(8) /* 8bpp mode has palette and non-palette versions */
-DEF_DRAW_LINE_NOPALETTE(16)
-DEF_DRAW_LINE_NOPALETTE(32)
-
-/* Special draw line routine for window color map case */
-static void draw_line_mapcolor(Exynos4210fimdWindow *w, uint8_t *src,
- uint8_t *dst, bool blend)
-{
- rgba p, p_old;
- uint8_t *ifb = dst;
- int width = w->rightbot_x - w->lefttop_x + 1;
- uint32_t map_color = w->winmap & FIMD_WINMAP_COLOR_MASK;
-
- do {
- pixel_888_to_rgb(map_color, &p);
- p.a = w->get_alpha(w, p.a);
- if (blend) {
- ifb += get_pixel_ifb(ifb, &p_old);
- exynos4210_fimd_blend_pixel(w, p_old, &p);
- }
- dst += put_pixel_ifb(p, dst);
- } while (--width);
-}
-
-/* Write RGB to QEMU's GraphicConsole framebuffer */
-
-static int put_to_qemufb_pixel8(const rgba p, uint8_t *d)
-{
- uint32_t pixel = rgb_to_pixel8(p.r, p.g, p.b);
- *(uint8_t *)d = pixel;
- return 1;
-}
-
-static int put_to_qemufb_pixel15(const rgba p, uint8_t *d)
-{
- uint32_t pixel = rgb_to_pixel15(p.r, p.g, p.b);
- *(uint16_t *)d = pixel;
- return 2;
-}
-
-static int put_to_qemufb_pixel16(const rgba p, uint8_t *d)
-{
- uint32_t pixel = rgb_to_pixel16(p.r, p.g, p.b);
- *(uint16_t *)d = pixel;
- return 2;
-}
-
-static int put_to_qemufb_pixel24(const rgba p, uint8_t *d)
-{
- uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b);
- *(uint8_t *)d++ = (pixel >> 0) & 0xFF;
- *(uint8_t *)d++ = (pixel >> 8) & 0xFF;
- *(uint8_t *)d++ = (pixel >> 16) & 0xFF;
- return 3;
-}
-
-static int put_to_qemufb_pixel32(const rgba p, uint8_t *d)
-{
- uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b);
- *(uint32_t *)d = pixel;
- return 4;
-}
-
-/* Routine to copy pixel from internal buffer to QEMU buffer */
-static int (*put_pixel_toqemu)(const rgba p, uint8_t *pixel);
-static inline void fimd_update_putpix_qemu(int bpp)
-{
- switch (bpp) {
- case 8:
- put_pixel_toqemu = put_to_qemufb_pixel8;
- break;
- case 15:
- put_pixel_toqemu = put_to_qemufb_pixel15;
- break;
- case 16:
- put_pixel_toqemu = put_to_qemufb_pixel16;
- break;
- case 24:
- put_pixel_toqemu = put_to_qemufb_pixel24;
- break;
- case 32:
- put_pixel_toqemu = put_to_qemufb_pixel32;
- break;
- default:
- hw_error("exynos4210.fimd: unsupported BPP (%d)", bpp);
- break;
- }
-}
-
-/* Routine to copy a line from internal frame buffer to QEMU display */
-static void fimd_copy_line_toqemu(int width, uint8_t *src, uint8_t *dst)
-{
- rgba p;
-
- do {
- src += get_pixel_ifb(src, &p);
- dst += put_pixel_toqemu(p, dst);
- } while (--width);
-}
-
-/* Parse BPPMODE_F = WINCON1[5:2] bits */
-static void exynos4210_fimd_update_win_bppmode(Exynos4210fimdState *s, int win)
-{
- Exynos4210fimdWindow *w = &s->window[win];
-
- if (w->winmap & FIMD_WINMAP_EN) {
- w->draw_line = draw_line_mapcolor;
- return;
- }
-
- switch (WIN_BPP_MODE(w)) {
- case 0:
- w->draw_line = draw_line_palette_1;
- w->pixel_to_rgb =
- palette_data_format[exynos4210_fimd_palette_format(s, win)];
- break;
- case 1:
- w->draw_line = draw_line_palette_2;
- w->pixel_to_rgb =
- palette_data_format[exynos4210_fimd_palette_format(s, win)];
- break;
- case 2:
- w->draw_line = draw_line_palette_4;
- w->pixel_to_rgb =
- palette_data_format[exynos4210_fimd_palette_format(s, win)];
- break;
- case 3:
- w->draw_line = draw_line_palette_8;
- w->pixel_to_rgb =
- palette_data_format[exynos4210_fimd_palette_format(s, win)];
- break;
- case 4:
- w->draw_line = draw_line_8;
- w->pixel_to_rgb = pixel_a232_to_rgb;
- break;
- case 5:
- w->draw_line = draw_line_16;
- w->pixel_to_rgb = pixel_565_to_rgb;
- break;
- case 6:
- w->draw_line = draw_line_16;
- w->pixel_to_rgb = pixel_a555_to_rgb;
- break;
- case 7:
- w->draw_line = draw_line_16;
- w->pixel_to_rgb = pixel_1555_to_rgb;
- break;
- case 8:
- w->draw_line = draw_line_32;
- w->pixel_to_rgb = pixel_666_to_rgb;
- break;
- case 9:
- w->draw_line = draw_line_32;
- w->pixel_to_rgb = pixel_a665_to_rgb;
- break;
- case 10:
- w->draw_line = draw_line_32;
- w->pixel_to_rgb = pixel_a666_to_rgb;
- break;
- case 11:
- w->draw_line = draw_line_32;
- w->pixel_to_rgb = pixel_888_to_rgb;
- break;
- case 12:
- w->draw_line = draw_line_32;
- w->pixel_to_rgb = pixel_a887_to_rgb;
- break;
- case 13:
- w->draw_line = draw_line_32;
- if ((w->wincon & FIMD_WINCON_BLD_PIX) && (w->wincon &
- FIMD_WINCON_ALPHA_SEL)) {
- w->pixel_to_rgb = pixel_8888_to_rgb;
- } else {
- w->pixel_to_rgb = pixel_a888_to_rgb;
- }
- break;
- case 14:
- w->draw_line = draw_line_16;
- if ((w->wincon & FIMD_WINCON_BLD_PIX) && (w->wincon &
- FIMD_WINCON_ALPHA_SEL)) {
- w->pixel_to_rgb = pixel_4444_to_rgb;
- } else {
- w->pixel_to_rgb = pixel_a444_to_rgb;
- }
- break;
- case 15:
- w->draw_line = draw_line_16;
- w->pixel_to_rgb = pixel_555_to_rgb;
- break;
- }
-}
-
-#if EXYNOS4210_FIMD_MODE_TRACE > 0
-static const char *exynos4210_fimd_get_bppmode(int mode_code)
-{
- switch (mode_code) {
- case 0:
- return "1 bpp";
- case 1:
- return "2 bpp";
- case 2:
- return "4 bpp";
- case 3:
- return "8 bpp (palettized)";
- case 4:
- return "8 bpp (non-palettized, A: 1-R:2-G:3-B:2)";
- case 5:
- return "16 bpp (non-palettized, R:5-G:6-B:5)";
- case 6:
- return "16 bpp (non-palettized, A:1-R:5-G:5-B:5)";
- case 7:
- return "16 bpp (non-palettized, I :1-R:5-G:5-B:5)";
- case 8:
- return "Unpacked 18 bpp (non-palettized, R:6-G:6-B:6)";
- case 9:
- return "Unpacked 18bpp (non-palettized,A:1-R:6-G:6-B:5)";
- case 10:
- return "Unpacked 19bpp (non-palettized,A:1-R:6-G:6-B:6)";
- case 11:
- return "Unpacked 24 bpp (non-palettized R:8-G:8-B:8)";
- case 12:
- return "Unpacked 24 bpp (non-palettized A:1-R:8-G:8-B:7)";
- case 13:
- return "Unpacked 25 bpp (non-palettized A:1-R:8-G:8-B:8)";
- case 14:
- return "Unpacked 13 bpp (non-palettized A:1-R:4-G:4-B:4)";
- case 15:
- return "Unpacked 15 bpp (non-palettized R:5-G:5-B:5)";
- default:
- return "Non-existing bpp mode";
- }
-}
-
-static inline void exynos4210_fimd_trace_bppmode(Exynos4210fimdState *s,
- int win_num, uint32_t val)
-{
- Exynos4210fimdWindow *w = &s->window[win_num];
-
- if (w->winmap & FIMD_WINMAP_EN) {
- printf("QEMU FIMD: Window %d is mapped with MAPCOLOR=0x%x\n",
- win_num, w->winmap & 0xFFFFFF);
- return;
- }
-
- if ((val != 0xFFFFFFFF) && ((w->wincon >> 2) & 0xF) == ((val >> 2) & 0xF)) {
- return;
- }
- printf("QEMU FIMD: Window %d BPP mode set to %s\n", win_num,
- exynos4210_fimd_get_bppmode((val >> 2) & 0xF));
-}
-#else
-static inline void exynos4210_fimd_trace_bppmode(Exynos4210fimdState *s,
- int win_num, uint32_t val)
-{
-
-}
-#endif
-
-static inline int fimd_get_buffer_id(Exynos4210fimdWindow *w)
-{
- switch (w->wincon & FIMD_WINCON_BUFSTATUS) {
- case FIMD_WINCON_BUF0_STAT:
- return 0;
- case FIMD_WINCON_BUF1_STAT:
- return 1;
- case FIMD_WINCON_BUF2_STAT:
- return 2;
- default:
- DPRINT_ERROR("Non-existent buffer index\n");
- return 0;
- }
-}
-
-static void exynos4210_fimd_invalidate(void *opaque)
-{
- Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
- s->invalidate = true;
-}
-
-/* Updates specified window's MemorySection based on values of WINCON,
- * VIDOSDA, VIDOSDB, VIDWADDx and SHADOWCON registers */
-static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(s);
- Exynos4210fimdWindow *w = &s->window[win];
- hwaddr fb_start_addr, fb_mapped_len;
-
- if (!s->enabled || !(w->wincon & FIMD_WINCON_ENWIN) ||
- FIMD_WINDOW_PROTECTED(s->shadowcon, win)) {
- return;
- }
-
- if (w->host_fb_addr) {
- cpu_physical_memory_unmap(w->host_fb_addr, w->fb_len, 0, 0);
- w->host_fb_addr = NULL;
- w->fb_len = 0;
- }
-
- fb_start_addr = w->buf_start[fimd_get_buffer_id(w)];
- /* Total number of bytes of virtual screen used by current window */
- w->fb_len = fb_mapped_len = (w->virtpage_width + w->virtpage_offsize) *
- (w->rightbot_y - w->lefttop_y + 1);
-
- /* TODO: add .exit and unref the region there. Not needed yet since sysbus
- * does not support hot-unplug.
- */
- 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 = memory_region_find(sysbus_address_space(sbd),
- fb_start_addr, w->fb_len);
- assert(w->mem_section.mr);
- assert(w->mem_section.offset_within_address_space == fb_start_addr);
- DPRINT_TRACE("Window %u framebuffer changed: address=0x%08x, len=0x%x\n",
- win, fb_start_addr, w->fb_len);
-
- 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);
- goto error_return;
- }
-
- w->host_fb_addr = cpu_physical_memory_map(fb_start_addr, &fb_mapped_len, 0);
- if (!w->host_fb_addr) {
- DPRINT_ERROR("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);
- cpu_physical_memory_unmap(w->host_fb_addr, fb_mapped_len, 0, 0);
- goto error_return;
- }
- memory_region_set_log(w->mem_section.mr, true, DIRTY_MEMORY_VGA);
- exynos4210_fimd_invalidate(s);
- return;
-
-error_return:
- memory_region_unref(w->mem_section.mr);
- w->mem_section.mr = NULL;
- w->mem_section.size = int128_zero();
- w->host_fb_addr = NULL;
- w->fb_len = 0;
-}
-
-static void exynos4210_fimd_enable(Exynos4210fimdState *s, bool enabled)
-{
- if (enabled && !s->enabled) {
- unsigned w;
- s->enabled = true;
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- fimd_update_memory_section(s, w);
- }
- }
- s->enabled = enabled;
- DPRINT_TRACE("display controller %s\n", enabled ? "enabled" : "disabled");
-}
-
-static inline uint32_t unpack_upper_4(uint32_t x)
-{
- return ((x & 0xF00) << 12) | ((x & 0xF0) << 8) | ((x & 0xF) << 4);
-}
-
-static inline uint32_t pack_upper_4(uint32_t x)
-{
- return (((x & 0xF00000) >> 12) | ((x & 0xF000) >> 8) |
- ((x & 0xF0) >> 4)) & 0xFFF;
-}
-
-static void exynos4210_fimd_update_irq(Exynos4210fimdState *s)
-{
- if (!(s->vidintcon[0] & FIMD_VIDINT_INTEN)) {
- qemu_irq_lower(s->irq[0]);
- qemu_irq_lower(s->irq[1]);
- qemu_irq_lower(s->irq[2]);
- return;
- }
- if ((s->vidintcon[0] & FIMD_VIDINT_INTFIFOEN) &&
- (s->vidintcon[1] & FIMD_VIDINT_INTFIFOPEND)) {
- qemu_irq_raise(s->irq[0]);
- } else {
- qemu_irq_lower(s->irq[0]);
- }
- if ((s->vidintcon[0] & FIMD_VIDINT_INTFRMEN) &&
- (s->vidintcon[1] & FIMD_VIDINT_INTFRMPEND)) {
- qemu_irq_raise(s->irq[1]);
- } else {
- qemu_irq_lower(s->irq[1]);
- }
- if ((s->vidintcon[0] & FIMD_VIDINT_I80IFDONE) &&
- (s->vidintcon[1] & FIMD_VIDINT_INTI80PEND)) {
- qemu_irq_raise(s->irq[2]);
- } else {
- qemu_irq_lower(s->irq[2]);
- }
-}
-
-static void exynos4210_update_resolution(Exynos4210fimdState *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->console);
-
- /* LCD resolution is stored in VIDEO TIME CONTROL REGISTER 2 */
- uint32_t width = ((s->vidtcon[2] >> FIMD_VIDTCON2_HOR_SHIFT) &
- FIMD_VIDTCON2_SIZE_MASK) + 1;
- uint32_t height = ((s->vidtcon[2] >> FIMD_VIDTCON2_VER_SHIFT) &
- FIMD_VIDTCON2_SIZE_MASK) + 1;
-
- if (s->ifb == NULL || surface_width(surface) != width ||
- surface_height(surface) != height) {
- DPRINT_L1("Resolution changed from %ux%u to %ux%u\n",
- surface_width(surface), surface_height(surface), width, height);
- qemu_console_resize(s->console, width, height);
- s->ifb = g_realloc(s->ifb, width * height * RGBA_SIZE + 1);
- memset(s->ifb, 0, width * height * RGBA_SIZE + 1);
- exynos4210_fimd_invalidate(s);
- }
-}
-
-static void exynos4210_fimd_update(void *opaque)
-{
- Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
- DisplaySurface *surface;
- Exynos4210fimdWindow *w;
- int i, line;
- hwaddr fb_line_addr, inc_size;
- int scrn_height;
- int first_line = -1, last_line = -1, scrn_width;
- bool blend = false;
- uint8_t *host_fb_addr;
- bool is_dirty = false;
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
- const int global_height = ((s->vidtcon[2] >> FIMD_VIDTCON2_VER_SHIFT) &
- FIMD_VIDTCON2_SIZE_MASK) + 1;
-
- if (!s || !s->console || !s->enabled ||
- surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
- return;
- }
- exynos4210_update_resolution(s);
- surface = qemu_console_surface(s->console);
-
- for (i = 0; i < NUM_OF_WINDOWS; i++) {
- w = &s->window[i];
- if ((w->wincon & FIMD_WINCON_ENWIN) && w->host_fb_addr) {
- scrn_height = w->rightbot_y - w->lefttop_y + 1;
- scrn_width = w->virtpage_width;
- /* Total width of virtual screen page in bytes */
- inc_size = scrn_width + w->virtpage_offsize;
- memory_region_sync_dirty_bitmap(w->mem_section.mr);
- host_fb_addr = w->host_fb_addr;
- fb_line_addr = w->mem_section.offset_within_region;
-
- for (line = 0; line < scrn_height; line++) {
- is_dirty = memory_region_get_dirty(w->mem_section.mr,
- fb_line_addr, scrn_width, DIRTY_MEMORY_VGA);
-
- if (s->invalidate || is_dirty) {
- if (first_line == -1) {
- first_line = line;
- }
- last_line = line;
- w->draw_line(w, host_fb_addr, s->ifb +
- w->lefttop_x * RGBA_SIZE + (w->lefttop_y + line) *
- global_width * RGBA_SIZE, blend);
- }
- host_fb_addr += inc_size;
- fb_line_addr += inc_size;
- is_dirty = false;
- }
- memory_region_reset_dirty(w->mem_section.mr,
- w->mem_section.offset_within_region,
- w->fb_len, DIRTY_MEMORY_VGA);
- blend = true;
- }
- }
-
- /* Copy resulting image to QEMU_CONSOLE. */
- if (first_line >= 0) {
- uint8_t *d;
- int bpp;
-
- bpp = surface_bits_per_pixel(surface);
- fimd_update_putpix_qemu(bpp);
- bpp = (bpp + 1) >> 3;
- d = surface_data(surface);
- for (line = first_line; line <= last_line; line++) {
- fimd_copy_line_toqemu(global_width, s->ifb + global_width * line *
- RGBA_SIZE, d + global_width * line * bpp);
- }
- dpy_gfx_update(s->console, 0, 0, global_width, global_height);
- }
- s->invalidate = false;
- s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND;
- if ((s->vidcon[0] & FIMD_VIDCON0_ENVID_F) == 0) {
- exynos4210_fimd_enable(s, false);
- }
- exynos4210_fimd_update_irq(s);
-}
-
-static void exynos4210_fimd_reset(DeviceState *d)
-{
- Exynos4210fimdState *s = EXYNOS4210_FIMD(d);
- unsigned w;
-
- DPRINT_TRACE("Display controller reset\n");
- /* Set all display controller registers to 0 */
- memset(&s->vidcon, 0, (uint8_t *)&s->window - (uint8_t *)&s->vidcon);
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- memset(&s->window[w], 0, sizeof(Exynos4210fimdWindow));
- s->window[w].blendeq = 0xC2;
- exynos4210_fimd_update_win_bppmode(s, w);
- exynos4210_fimd_trace_bppmode(s, w, 0xFFFFFFFF);
- fimd_update_get_alpha(s, w);
- }
-
- g_free(s->ifb);
- s->ifb = NULL;
-
- exynos4210_fimd_invalidate(s);
- exynos4210_fimd_enable(s, false);
- /* Some registers have non-zero initial values */
- s->winchmap = 0x7D517D51;
- s->colorgaincon = 0x10040100;
- s->huecoef_cr[0] = s->huecoef_cr[3] = 0x01000100;
- s->huecoef_cb[0] = s->huecoef_cb[3] = 0x01000100;
- s->hueoffset = 0x01800080;
-}
-
-static void exynos4210_fimd_write(void *opaque, hwaddr offset,
- uint64_t val, unsigned size)
-{
- Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
- unsigned w, i;
- uint32_t old_value;
-
- DPRINT_L2("write offset 0x%08x, value=%llu(0x%08llx)\n", offset,
- (long long unsigned int)val, (long long unsigned int)val);
-
- switch (offset) {
- case FIMD_VIDCON0:
- if ((val & FIMD_VIDCON0_ENVID_MASK) == FIMD_VIDCON0_ENVID_MASK) {
- exynos4210_fimd_enable(s, true);
- } else {
- if ((val & FIMD_VIDCON0_ENVID) == 0) {
- exynos4210_fimd_enable(s, false);
- }
- }
- s->vidcon[0] = val;
- break;
- case FIMD_VIDCON1:
- /* Leave read-only bits as is */
- val = (val & (~FIMD_VIDCON1_ROMASK)) |
- (s->vidcon[1] & FIMD_VIDCON1_ROMASK);
- s->vidcon[1] = val;
- break;
- case FIMD_VIDCON2 ... FIMD_VIDCON3:
- s->vidcon[(offset) >> 2] = val;
- break;
- case FIMD_VIDTCON_START ... FIMD_VIDTCON_END:
- s->vidtcon[(offset - FIMD_VIDTCON_START) >> 2] = val;
- break;
- case FIMD_WINCON_START ... FIMD_WINCON_END:
- w = (offset - FIMD_WINCON_START) >> 2;
- /* Window's current buffer ID */
- i = fimd_get_buffer_id(&s->window[w]);
- old_value = s->window[w].wincon;
- val = (val & ~FIMD_WINCON_ROMASK) |
- (s->window[w].wincon & FIMD_WINCON_ROMASK);
- if (w == 0) {
- /* Window 0 wincon ALPHA_MUL bit must always be 0 */
- val &= ~FIMD_WINCON_ALPHA_MUL;
- }
- exynos4210_fimd_trace_bppmode(s, w, val);
- switch (val & FIMD_WINCON_BUFSELECT) {
- case FIMD_WINCON_BUF0_SEL:
- val &= ~FIMD_WINCON_BUFSTATUS;
- break;
- case FIMD_WINCON_BUF1_SEL:
- val = (val & ~FIMD_WINCON_BUFSTAT_H) | FIMD_WINCON_BUFSTAT_L;
- break;
- case FIMD_WINCON_BUF2_SEL:
- if (val & FIMD_WINCON_BUFMODE) {
- val = (val & ~FIMD_WINCON_BUFSTAT_L) | FIMD_WINCON_BUFSTAT_H;
- }
- break;
- default:
- break;
- }
- s->window[w].wincon = val;
- exynos4210_fimd_update_win_bppmode(s, w);
- fimd_update_get_alpha(s, w);
- if ((i != fimd_get_buffer_id(&s->window[w])) ||
- (!(old_value & FIMD_WINCON_ENWIN) && (s->window[w].wincon &
- FIMD_WINCON_ENWIN))) {
- fimd_update_memory_section(s, w);
- }
- break;
- case FIMD_SHADOWCON:
- old_value = s->shadowcon;
- s->shadowcon = val;
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- if (FIMD_WINDOW_PROTECTED(old_value, w) &&
- !FIMD_WINDOW_PROTECTED(s->shadowcon, w)) {
- fimd_update_memory_section(s, w);
- }
- }
- break;
- case FIMD_WINCHMAP:
- s->winchmap = val;
- break;
- case FIMD_VIDOSD_START ... FIMD_VIDOSD_END:
- w = (offset - FIMD_VIDOSD_START) >> 4;
- i = ((offset - FIMD_VIDOSD_START) & 0xF) >> 2;
- switch (i) {
- case 0:
- old_value = s->window[w].lefttop_y;
- s->window[w].lefttop_x = (val >> FIMD_VIDOSD_HOR_SHIFT) &
- FIMD_VIDOSD_COORD_MASK;
- s->window[w].lefttop_y = (val >> FIMD_VIDOSD_VER_SHIFT) &
- FIMD_VIDOSD_COORD_MASK;
- if (s->window[w].lefttop_y != old_value) {
- fimd_update_memory_section(s, w);
- }
- break;
- case 1:
- old_value = s->window[w].rightbot_y;
- s->window[w].rightbot_x = (val >> FIMD_VIDOSD_HOR_SHIFT) &
- FIMD_VIDOSD_COORD_MASK;
- s->window[w].rightbot_y = (val >> FIMD_VIDOSD_VER_SHIFT) &
- FIMD_VIDOSD_COORD_MASK;
- if (s->window[w].rightbot_y != old_value) {
- fimd_update_memory_section(s, w);
- }
- break;
- case 2:
- if (w == 0) {
- s->window[w].osdsize = val;
- } else {
- s->window[w].alpha_val[0] =
- unpack_upper_4((val & FIMD_VIDOSD_ALPHA_AEN0) >>
- FIMD_VIDOSD_AEN0_SHIFT) |
- (s->window[w].alpha_val[0] & FIMD_VIDALPHA_ALPHA_LOWER);
- s->window[w].alpha_val[1] =
- unpack_upper_4(val & FIMD_VIDOSD_ALPHA_AEN1) |
- (s->window[w].alpha_val[1] & FIMD_VIDALPHA_ALPHA_LOWER);
- }
- break;
- case 3:
- if (w != 1 && w != 2) {
- DPRINT_ERROR("Bad write offset 0x%08x\n", offset);
- return;
- }
- s->window[w].osdsize = val;
- break;
- }
- break;
- case FIMD_VIDWADD0_START ... FIMD_VIDWADD0_END:
- w = (offset - FIMD_VIDWADD0_START) >> 3;
- i = ((offset - FIMD_VIDWADD0_START) >> 2) & 1;
- if (i == fimd_get_buffer_id(&s->window[w]) &&
- s->window[w].buf_start[i] != val) {
- s->window[w].buf_start[i] = val;
- fimd_update_memory_section(s, w);
- break;
- }
- s->window[w].buf_start[i] = val;
- break;
- case FIMD_VIDWADD1_START ... FIMD_VIDWADD1_END:
- w = (offset - FIMD_VIDWADD1_START) >> 3;
- i = ((offset - FIMD_VIDWADD1_START) >> 2) & 1;
- s->window[w].buf_end[i] = val;
- break;
- case FIMD_VIDWADD2_START ... FIMD_VIDWADD2_END:
- w = (offset - FIMD_VIDWADD2_START) >> 2;
- if (((val & FIMD_VIDWADD2_PAGEWIDTH) != s->window[w].virtpage_width) ||
- (((val >> FIMD_VIDWADD2_OFFSIZE_SHIFT) & FIMD_VIDWADD2_OFFSIZE) !=
- s->window[w].virtpage_offsize)) {
- s->window[w].virtpage_width = val & FIMD_VIDWADD2_PAGEWIDTH;
- s->window[w].virtpage_offsize =
- (val >> FIMD_VIDWADD2_OFFSIZE_SHIFT) & FIMD_VIDWADD2_OFFSIZE;
- fimd_update_memory_section(s, w);
- }
- break;
- case FIMD_VIDINTCON0:
- s->vidintcon[0] = val;
- break;
- case FIMD_VIDINTCON1:
- s->vidintcon[1] &= ~(val & 7);
- exynos4210_fimd_update_irq(s);
- break;
- case FIMD_WKEYCON_START ... FIMD_WKEYCON_END:
- w = ((offset - FIMD_WKEYCON_START) >> 3) + 1;
- i = ((offset - FIMD_WKEYCON_START) >> 2) & 1;
- s->window[w].keycon[i] = val;
- break;
- case FIMD_WKEYALPHA_START ... FIMD_WKEYALPHA_END:
- w = ((offset - FIMD_WKEYALPHA_START) >> 2) + 1;
- s->window[w].keyalpha = val;
- break;
- case FIMD_DITHMODE:
- s->dithmode = val;
- break;
- case FIMD_WINMAP_START ... FIMD_WINMAP_END:
- w = (offset - FIMD_WINMAP_START) >> 2;
- old_value = s->window[w].winmap;
- s->window[w].winmap = val;
- if ((val & FIMD_WINMAP_EN) ^ (old_value & FIMD_WINMAP_EN)) {
- exynos4210_fimd_invalidate(s);
- exynos4210_fimd_update_win_bppmode(s, w);
- exynos4210_fimd_trace_bppmode(s, w, 0xFFFFFFFF);
- exynos4210_fimd_update(s);
- }
- break;
- case FIMD_WPALCON_HIGH ... FIMD_WPALCON_LOW:
- i = (offset - FIMD_WPALCON_HIGH) >> 2;
- s->wpalcon[i] = val;
- if (s->wpalcon[1] & FIMD_WPALCON_UPDATEEN) {
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- exynos4210_fimd_update_win_bppmode(s, w);
- fimd_update_get_alpha(s, w);
- }
- }
- break;
- case FIMD_TRIGCON:
- val = (val & ~FIMD_TRIGCON_ROMASK) | (s->trigcon & FIMD_TRIGCON_ROMASK);
- s->trigcon = val;
- break;
- case FIMD_I80IFCON_START ... FIMD_I80IFCON_END:
- s->i80ifcon[(offset - FIMD_I80IFCON_START) >> 2] = val;
- break;
- case FIMD_COLORGAINCON:
- s->colorgaincon = val;
- break;
- case FIMD_LDI_CMDCON0 ... FIMD_LDI_CMDCON1:
- s->ldi_cmdcon[(offset - FIMD_LDI_CMDCON0) >> 2] = val;
- break;
- case FIMD_SIFCCON0 ... FIMD_SIFCCON2:
- i = (offset - FIMD_SIFCCON0) >> 2;
- if (i != 2) {
- s->sifccon[i] = val;
- }
- break;
- case FIMD_HUECOEFCR_START ... FIMD_HUECOEFCR_END:
- i = (offset - FIMD_HUECOEFCR_START) >> 2;
- s->huecoef_cr[i] = val;
- break;
- case FIMD_HUECOEFCB_START ... FIMD_HUECOEFCB_END:
- i = (offset - FIMD_HUECOEFCB_START) >> 2;
- s->huecoef_cb[i] = val;
- break;
- case FIMD_HUEOFFSET:
- s->hueoffset = val;
- break;
- case FIMD_VIDWALPHA_START ... FIMD_VIDWALPHA_END:
- w = ((offset - FIMD_VIDWALPHA_START) >> 3);
- i = ((offset - FIMD_VIDWALPHA_START) >> 2) & 1;
- if (w == 0) {
- s->window[w].alpha_val[i] = val;
- } else {
- s->window[w].alpha_val[i] = (val & FIMD_VIDALPHA_ALPHA_LOWER) |
- (s->window[w].alpha_val[i] & FIMD_VIDALPHA_ALPHA_UPPER);
- }
- break;
- case FIMD_BLENDEQ_START ... FIMD_BLENDEQ_END:
- s->window[(offset - FIMD_BLENDEQ_START) >> 2].blendeq = val;
- break;
- case FIMD_BLENDCON:
- old_value = s->blendcon;
- s->blendcon = val;
- if ((s->blendcon & FIMD_ALPHA_8BIT) != (old_value & FIMD_ALPHA_8BIT)) {
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- fimd_update_get_alpha(s, w);
- }
- }
- break;
- case FIMD_WRTQOSCON_START ... FIMD_WRTQOSCON_END:
- s->window[(offset - FIMD_WRTQOSCON_START) >> 2].rtqoscon = val;
- break;
- case FIMD_I80IFCMD_START ... FIMD_I80IFCMD_END:
- s->i80ifcmd[(offset - FIMD_I80IFCMD_START) >> 2] = val;
- break;
- case FIMD_VIDW0ADD0_B2 ... FIMD_VIDW4ADD0_B2:
- if (offset & 0x0004) {
- DPRINT_ERROR("bad write offset 0x%08x\n", offset);
- break;
- }
- w = (offset - FIMD_VIDW0ADD0_B2) >> 3;
- if (fimd_get_buffer_id(&s->window[w]) == 2 &&
- s->window[w].buf_start[2] != val) {
- s->window[w].buf_start[2] = val;
- fimd_update_memory_section(s, w);
- break;
- }
- s->window[w].buf_start[2] = val;
- break;
- case FIMD_SHD_ADD0_START ... FIMD_SHD_ADD0_END:
- if (offset & 0x0004) {
- DPRINT_ERROR("bad write offset 0x%08x\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);
- break;
- }
- s->window[(offset - FIMD_SHD_ADD1_START) >> 3].shadow_buf_end = val;
- break;
- case FIMD_SHD_ADD2_START ... FIMD_SHD_ADD2_END:
- s->window[(offset - FIMD_SHD_ADD2_START) >> 2].shadow_buf_size = val;
- break;
- case FIMD_PAL_MEM_START ... FIMD_PAL_MEM_END:
- w = (offset - FIMD_PAL_MEM_START) >> 10;
- i = ((offset - FIMD_PAL_MEM_START) >> 2) & 0xFF;
- s->window[w].palette[i] = val;
- break;
- case FIMD_PALMEM_AL_START ... FIMD_PALMEM_AL_END:
- /* Palette memory aliases for windows 0 and 1 */
- w = (offset - FIMD_PALMEM_AL_START) >> 10;
- i = ((offset - FIMD_PALMEM_AL_START) >> 2) & 0xFF;
- s->window[w].palette[i] = val;
- break;
- default:
- DPRINT_ERROR("bad write offset 0x%08x\n", offset);
- break;
- }
-}
-
-static uint64_t exynos4210_fimd_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
- int w, i;
- uint32_t ret = 0;
-
- DPRINT_L2("read offset 0x%08x\n", offset);
-
- switch (offset) {
- case FIMD_VIDCON0 ... FIMD_VIDCON3:
- return s->vidcon[(offset - FIMD_VIDCON0) >> 2];
- case FIMD_VIDTCON_START ... FIMD_VIDTCON_END:
- return s->vidtcon[(offset - FIMD_VIDTCON_START) >> 2];
- case FIMD_WINCON_START ... FIMD_WINCON_END:
- return s->window[(offset - FIMD_WINCON_START) >> 2].wincon;
- case FIMD_SHADOWCON:
- return s->shadowcon;
- case FIMD_WINCHMAP:
- return s->winchmap;
- case FIMD_VIDOSD_START ... FIMD_VIDOSD_END:
- w = (offset - FIMD_VIDOSD_START) >> 4;
- i = ((offset - FIMD_VIDOSD_START) & 0xF) >> 2;
- switch (i) {
- case 0:
- ret = ((s->window[w].lefttop_x & FIMD_VIDOSD_COORD_MASK) <<
- FIMD_VIDOSD_HOR_SHIFT) |
- (s->window[w].lefttop_y & FIMD_VIDOSD_COORD_MASK);
- break;
- case 1:
- ret = ((s->window[w].rightbot_x & FIMD_VIDOSD_COORD_MASK) <<
- FIMD_VIDOSD_HOR_SHIFT) |
- (s->window[w].rightbot_y & FIMD_VIDOSD_COORD_MASK);
- break;
- case 2:
- if (w == 0) {
- ret = s->window[w].osdsize;
- } else {
- ret = (pack_upper_4(s->window[w].alpha_val[0]) <<
- FIMD_VIDOSD_AEN0_SHIFT) |
- pack_upper_4(s->window[w].alpha_val[1]);
- }
- break;
- case 3:
- if (w != 1 && w != 2) {
- DPRINT_ERROR("bad read offset 0x%08x\n", offset);
- return 0xBAADBAAD;
- }
- ret = s->window[w].osdsize;
- break;
- }
- return ret;
- case FIMD_VIDWADD0_START ... FIMD_VIDWADD0_END:
- w = (offset - FIMD_VIDWADD0_START) >> 3;
- i = ((offset - FIMD_VIDWADD0_START) >> 2) & 1;
- return s->window[w].buf_start[i];
- case FIMD_VIDWADD1_START ... FIMD_VIDWADD1_END:
- w = (offset - FIMD_VIDWADD1_START) >> 3;
- i = ((offset - FIMD_VIDWADD1_START) >> 2) & 1;
- return s->window[w].buf_end[i];
- case FIMD_VIDWADD2_START ... FIMD_VIDWADD2_END:
- w = (offset - FIMD_VIDWADD2_START) >> 2;
- return s->window[w].virtpage_width | (s->window[w].virtpage_offsize <<
- FIMD_VIDWADD2_OFFSIZE_SHIFT);
- case FIMD_VIDINTCON0 ... FIMD_VIDINTCON1:
- return s->vidintcon[(offset - FIMD_VIDINTCON0) >> 2];
- case FIMD_WKEYCON_START ... FIMD_WKEYCON_END:
- w = ((offset - FIMD_WKEYCON_START) >> 3) + 1;
- i = ((offset - FIMD_WKEYCON_START) >> 2) & 1;
- return s->window[w].keycon[i];
- case FIMD_WKEYALPHA_START ... FIMD_WKEYALPHA_END:
- w = ((offset - FIMD_WKEYALPHA_START) >> 2) + 1;
- return s->window[w].keyalpha;
- case FIMD_DITHMODE:
- return s->dithmode;
- case FIMD_WINMAP_START ... FIMD_WINMAP_END:
- return s->window[(offset - FIMD_WINMAP_START) >> 2].winmap;
- case FIMD_WPALCON_HIGH ... FIMD_WPALCON_LOW:
- return s->wpalcon[(offset - FIMD_WPALCON_HIGH) >> 2];
- case FIMD_TRIGCON:
- return s->trigcon;
- case FIMD_I80IFCON_START ... FIMD_I80IFCON_END:
- return s->i80ifcon[(offset - FIMD_I80IFCON_START) >> 2];
- case FIMD_COLORGAINCON:
- return s->colorgaincon;
- case FIMD_LDI_CMDCON0 ... FIMD_LDI_CMDCON1:
- return s->ldi_cmdcon[(offset - FIMD_LDI_CMDCON0) >> 2];
- case FIMD_SIFCCON0 ... FIMD_SIFCCON2:
- i = (offset - FIMD_SIFCCON0) >> 2;
- return s->sifccon[i];
- case FIMD_HUECOEFCR_START ... FIMD_HUECOEFCR_END:
- i = (offset - FIMD_HUECOEFCR_START) >> 2;
- return s->huecoef_cr[i];
- case FIMD_HUECOEFCB_START ... FIMD_HUECOEFCB_END:
- i = (offset - FIMD_HUECOEFCB_START) >> 2;
- return s->huecoef_cb[i];
- case FIMD_HUEOFFSET:
- return s->hueoffset;
- case FIMD_VIDWALPHA_START ... FIMD_VIDWALPHA_END:
- w = ((offset - FIMD_VIDWALPHA_START) >> 3);
- i = ((offset - FIMD_VIDWALPHA_START) >> 2) & 1;
- return s->window[w].alpha_val[i] &
- (w == 0 ? 0xFFFFFF : FIMD_VIDALPHA_ALPHA_LOWER);
- case FIMD_BLENDEQ_START ... FIMD_BLENDEQ_END:
- return s->window[(offset - FIMD_BLENDEQ_START) >> 2].blendeq;
- case FIMD_BLENDCON:
- return s->blendcon;
- case FIMD_WRTQOSCON_START ... FIMD_WRTQOSCON_END:
- return s->window[(offset - FIMD_WRTQOSCON_START) >> 2].rtqoscon;
- case FIMD_I80IFCMD_START ... FIMD_I80IFCMD_END:
- return s->i80ifcmd[(offset - FIMD_I80IFCMD_START) >> 2];
- case FIMD_VIDW0ADD0_B2 ... FIMD_VIDW4ADD0_B2:
- if (offset & 0x0004) {
- break;
- }
- return s->window[(offset - FIMD_VIDW0ADD0_B2) >> 3].buf_start[2];
- case FIMD_SHD_ADD0_START ... FIMD_SHD_ADD0_END:
- if (offset & 0x0004) {
- break;
- }
- return s->window[(offset - FIMD_SHD_ADD0_START) >> 3].shadow_buf_start;
- case FIMD_SHD_ADD1_START ... FIMD_SHD_ADD1_END:
- if (offset & 0x0004) {
- break;
- }
- return s->window[(offset - FIMD_SHD_ADD1_START) >> 3].shadow_buf_end;
- case FIMD_SHD_ADD2_START ... FIMD_SHD_ADD2_END:
- return s->window[(offset - FIMD_SHD_ADD2_START) >> 2].shadow_buf_size;
- case FIMD_PAL_MEM_START ... FIMD_PAL_MEM_END:
- w = (offset - FIMD_PAL_MEM_START) >> 10;
- i = ((offset - FIMD_PAL_MEM_START) >> 2) & 0xFF;
- return s->window[w].palette[i];
- case FIMD_PALMEM_AL_START ... FIMD_PALMEM_AL_END:
- /* Palette aliases for win 0,1 */
- w = (offset - FIMD_PALMEM_AL_START) >> 10;
- i = ((offset - FIMD_PALMEM_AL_START) >> 2) & 0xFF;
- return s->window[w].palette[i];
- }
-
- DPRINT_ERROR("bad read offset 0x%08x\n", offset);
- return 0xBAADBAAD;
-}
-
-static const MemoryRegionOps exynos4210_fimd_mmio_ops = {
- .read = exynos4210_fimd_read,
- .write = exynos4210_fimd_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- .unaligned = false
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int exynos4210_fimd_load(void *opaque, int version_id)
-{
- Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
- int w;
-
- if (version_id != 1) {
- return -EINVAL;
- }
-
- for (w = 0; w < NUM_OF_WINDOWS; w++) {
- exynos4210_fimd_update_win_bppmode(s, w);
- fimd_update_get_alpha(s, w);
- fimd_update_memory_section(s, w);
- }
-
- /* Redraw the whole screen */
- exynos4210_update_resolution(s);
- exynos4210_fimd_invalidate(s);
- exynos4210_fimd_enable(s, (s->vidcon[0] & FIMD_VIDCON0_ENVID_MASK) ==
- FIMD_VIDCON0_ENVID_MASK);
- return 0;
-}
-
-static const VMStateDescription exynos4210_fimd_window_vmstate = {
- .name = "exynos4210.fimd_window",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(wincon, Exynos4210fimdWindow),
- VMSTATE_UINT32_ARRAY(buf_start, Exynos4210fimdWindow, 3),
- VMSTATE_UINT32_ARRAY(buf_end, Exynos4210fimdWindow, 3),
- VMSTATE_UINT32_ARRAY(keycon, Exynos4210fimdWindow, 2),
- VMSTATE_UINT32(keyalpha, Exynos4210fimdWindow),
- VMSTATE_UINT32(winmap, Exynos4210fimdWindow),
- VMSTATE_UINT32(blendeq, Exynos4210fimdWindow),
- VMSTATE_UINT32(rtqoscon, Exynos4210fimdWindow),
- VMSTATE_UINT32_ARRAY(palette, Exynos4210fimdWindow, 256),
- VMSTATE_UINT32(shadow_buf_start, Exynos4210fimdWindow),
- VMSTATE_UINT32(shadow_buf_end, Exynos4210fimdWindow),
- VMSTATE_UINT32(shadow_buf_size, Exynos4210fimdWindow),
- VMSTATE_UINT16(lefttop_x, Exynos4210fimdWindow),
- VMSTATE_UINT16(lefttop_y, Exynos4210fimdWindow),
- VMSTATE_UINT16(rightbot_x, Exynos4210fimdWindow),
- VMSTATE_UINT16(rightbot_y, Exynos4210fimdWindow),
- VMSTATE_UINT32(osdsize, Exynos4210fimdWindow),
- VMSTATE_UINT32_ARRAY(alpha_val, Exynos4210fimdWindow, 2),
- VMSTATE_UINT16(virtpage_width, Exynos4210fimdWindow),
- VMSTATE_UINT16(virtpage_offsize, Exynos4210fimdWindow),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription exynos4210_fimd_vmstate = {
- .name = "exynos4210.fimd",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = exynos4210_fimd_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(vidcon, Exynos4210fimdState, 4),
- VMSTATE_UINT32_ARRAY(vidtcon, Exynos4210fimdState, 4),
- VMSTATE_UINT32(shadowcon, Exynos4210fimdState),
- VMSTATE_UINT32(winchmap, Exynos4210fimdState),
- VMSTATE_UINT32_ARRAY(vidintcon, Exynos4210fimdState, 2),
- VMSTATE_UINT32(dithmode, Exynos4210fimdState),
- VMSTATE_UINT32_ARRAY(wpalcon, Exynos4210fimdState, 2),
- VMSTATE_UINT32(trigcon, Exynos4210fimdState),
- VMSTATE_UINT32_ARRAY(i80ifcon, Exynos4210fimdState, 4),
- VMSTATE_UINT32(colorgaincon, Exynos4210fimdState),
- VMSTATE_UINT32_ARRAY(ldi_cmdcon, Exynos4210fimdState, 2),
- VMSTATE_UINT32_ARRAY(sifccon, Exynos4210fimdState, 3),
- VMSTATE_UINT32_ARRAY(huecoef_cr, Exynos4210fimdState, 4),
- VMSTATE_UINT32_ARRAY(huecoef_cb, Exynos4210fimdState, 4),
- VMSTATE_UINT32(hueoffset, Exynos4210fimdState),
- VMSTATE_UINT32_ARRAY(i80ifcmd, Exynos4210fimdState, 12),
- VMSTATE_UINT32(blendcon, Exynos4210fimdState),
- VMSTATE_STRUCT_ARRAY(window, Exynos4210fimdState, 5, 1,
- exynos4210_fimd_window_vmstate, Exynos4210fimdWindow),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps exynos4210_fimd_ops = {
- .invalidate = exynos4210_fimd_invalidate,
- .gfx_update = exynos4210_fimd_update,
-};
-
-static int exynos4210_fimd_init(SysBusDevice *dev)
-{
- Exynos4210fimdState *s = EXYNOS4210_FIMD(dev);
-
- s->ifb = NULL;
-
- sysbus_init_irq(dev, &s->irq[0]);
- sysbus_init_irq(dev, &s->irq[1]);
- sysbus_init_irq(dev, &s->irq[2]);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_fimd_mmio_ops, s,
- "exynos4210.fimd", FIMD_REGS_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
- s->console = graphic_console_init(DEVICE(dev), 0, &exynos4210_fimd_ops, s);
-
- return 0;
-}
-
-static void exynos4210_fimd_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- dc->vmsd = &exynos4210_fimd_vmstate;
- dc->reset = exynos4210_fimd_reset;
- k->init = exynos4210_fimd_init;
-}
-
-static const TypeInfo exynos4210_fimd_info = {
- .name = TYPE_EXYNOS4210_FIMD,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(Exynos4210fimdState),
- .class_init = exynos4210_fimd_class_init,
-};
-
-static void exynos4210_fimd_register_types(void)
-{
- type_register_static(&exynos4210_fimd_info);
-}
-
-type_init(exynos4210_fimd_register_types)
diff --git a/qemu/hw/display/framebuffer.c b/qemu/hw/display/framebuffer.c
deleted file mode 100644
index df51358e7..000000000
--- a/qemu/hw/display/framebuffer.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Framebuffer device helper routines
- *
- * Copyright (c) 2009 CodeSourcery
- * Written by Paul Brook <paul@codesourcery.com>
- *
- * This code is licensed under the GNU GPLv2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-/* TODO:
- - Do something similar for framebuffers with local ram
- - Handle rotation here instead of hacking dest_pitch
- - Use common pixel conversion routines instead of per-device drawfn
- - Remove all DisplayState knowledge from devices.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "framebuffer.h"
-
-void framebuffer_update_memory_section(
- MemoryRegionSection *mem_section,
- MemoryRegion *root,
- hwaddr base,
- unsigned rows,
- unsigned src_width)
-{
- hwaddr src_len = (hwaddr)rows * src_width;
-
- if (mem_section->mr) {
- memory_region_set_log(mem_section->mr, false, DIRTY_MEMORY_VGA);
- memory_region_unref(mem_section->mr);
- mem_section->mr = NULL;
- }
-
- *mem_section = memory_region_find(root, base, src_len);
- if (!mem_section->mr) {
- return;
- }
-
- if (int128_get64(mem_section->size) < src_len ||
- !memory_region_is_ram(mem_section->mr)) {
- memory_region_unref(mem_section->mr);
- mem_section->mr = NULL;
- return;
- }
-
- memory_region_set_log(mem_section->mr, true, DIRTY_MEMORY_VGA);
-}
-
-/* Render an image from a shared memory framebuffer. */
-void framebuffer_update_display(
- DisplaySurface *ds,
- MemoryRegionSection *mem_section,
- int cols, /* Width in pixels. */
- int rows, /* Height in pixels. */
- int src_width, /* Length of source line, in bytes. */
- int dest_row_pitch, /* Bytes between adjacent horizontal output pixels. */
- int dest_col_pitch, /* Bytes between adjacent vertical output pixels. */
- int invalidate, /* nonzero to redraw the whole image. */
- drawfn fn,
- void *opaque,
- int *first_row, /* Input and output. */
- int *last_row /* Output only */)
-{
- hwaddr src_len;
- uint8_t *dest;
- uint8_t *src;
- int first, last = 0;
- int dirty;
- int i;
- ram_addr_t addr;
- MemoryRegion *mem;
-
- i = *first_row;
- *first_row = -1;
- src_len = src_width * rows;
-
- mem = mem_section->mr;
- if (!mem) {
- return;
- }
- memory_region_sync_dirty_bitmap(mem);
-
- addr = mem_section->offset_within_region;
- src = memory_region_get_ram_ptr(mem) + addr;
-
- dest = surface_data(ds);
- if (dest_col_pitch < 0) {
- dest -= dest_col_pitch * (cols - 1);
- }
- if (dest_row_pitch < 0) {
- dest -= dest_row_pitch * (rows - 1);
- }
- first = -1;
-
- addr += i * src_width;
- src += i * src_width;
- dest += i * dest_row_pitch;
-
- for (; i < rows; i++) {
- dirty = memory_region_get_dirty(mem, addr, src_width,
- DIRTY_MEMORY_VGA);
- if (dirty || invalidate) {
- fn(opaque, dest, src, cols, dest_col_pitch);
- if (first == -1)
- first = i;
- last = i;
- }
- addr += src_width;
- src += src_width;
- dest += dest_row_pitch;
- }
- if (first < 0) {
- return;
- }
- memory_region_reset_dirty(mem, mem_section->offset_within_region, src_len,
- DIRTY_MEMORY_VGA);
- *first_row = first;
- *last_row = last;
-}
diff --git a/qemu/hw/display/framebuffer.h b/qemu/hw/display/framebuffer.h
deleted file mode 100644
index 38fa0dcec..000000000
--- a/qemu/hw/display/framebuffer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef QEMU_FRAMEBUFFER_H
-#define QEMU_FRAMEBUFFER_H
-
-#include "exec/memory.h"
-
-/* Framebuffer device helper routines. */
-
-typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int);
-
-/* framebuffer_update_memory_section: Update framebuffer
- * #MemoryRegionSection, for example if the framebuffer is switched to
- * a different memory area.
- *
- * @mem_section: Output #MemoryRegionSection, to be passed to
- * framebuffer_update_display().
- * @root: #MemoryRegion within which the framebuffer lies
- * @base: Base address of the framebuffer within @root.
- * @rows: Height of the screen.
- * @src_width: Number of bytes in framebuffer memory between two rows.
- */
-void framebuffer_update_memory_section(
- MemoryRegionSection *mem_section,
- MemoryRegion *root,
- hwaddr base,
- unsigned rows,
- unsigned src_width);
-
-/* framebuffer_update_display: Draw the framebuffer on a surface.
- *
- * @ds: #DisplaySurface to draw to.
- * @mem_section: #MemoryRegionSection provided by
- * framebuffer_update_memory_section().
- * @cols: Width the screen.
- * @rows: Height of the screen.
- * @src_width: Number of bytes in framebuffer memory between two rows.
- * @dest_row_pitch: Number of bytes in the surface data between two rows.
- * Negative if the framebuffer is stored in the opposite order (e.g.
- * bottom-to-top) compared to the framebuffer.
- * @dest_col_pitch: Number of bytes in the surface data between two pixels.
- * Negative if the framebuffer is stored in the opposite order (e.g.
- * right-to-left) compared to the framebuffer.
- * @invalidate: True if the function should redraw the whole screen
- * without checking the DIRTY_MEMORY_VGA dirty bitmap.
- * @fn: Drawing function to be called for each row that has to be drawn.
- * @opaque: Opaque pointer passed to @fn.
- * @first_row: Pointer to an integer, receives the number of the first row
- * that was drawn (either the first dirty row, or 0 if @invalidate is true).
- * @last_row: Pointer to an integer, receives the number of the last row that
- * was drawn (either the last dirty row, or @rows-1 if @invalidate is true).
- */
-void framebuffer_update_display(
- DisplaySurface *ds,
- MemoryRegionSection *mem_section,
- int cols,
- int rows,
- int src_width,
- int dest_row_pitch,
- int dest_col_pitch,
- int invalidate,
- drawfn fn,
- void *opaque,
- int *first_row,
- int *last_row);
-
-#endif
diff --git a/qemu/hw/display/g364fb.c b/qemu/hw/display/g364fb.c
deleted file mode 100644
index 70ef2c745..000000000
--- a/qemu/hw/display/g364fb.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * QEMU G364 framebuffer Emulator.
- *
- * Copyright (c) 2007-2011 Herve Poussineau
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "qemu/error-report.h"
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "trace.h"
-#include "hw/sysbus.h"
-
-typedef struct G364State {
- /* hardware */
- uint8_t *vram;
- uint32_t vram_size;
- qemu_irq irq;
- MemoryRegion mem_vram;
- MemoryRegion mem_ctrl;
- /* registers */
- uint8_t color_palette[256][3];
- uint8_t cursor_palette[3][3];
- uint16_t cursor[512];
- uint32_t cursor_position;
- uint32_t ctla;
- uint32_t top_of_screen;
- uint32_t width, height; /* in pixels */
- /* display refresh support */
- QemuConsole *con;
- int depth;
- int blanked;
-} G364State;
-
-#define REG_BOOT 0x000000
-#define REG_DISPLAY 0x000118
-#define REG_VDISPLAY 0x000150
-#define REG_CTLA 0x000300
-#define REG_TOP 0x000400
-#define REG_CURS_PAL 0x000508
-#define REG_CURS_POS 0x000638
-#define REG_CLR_PAL 0x000800
-#define REG_CURS_PAT 0x001000
-#define REG_RESET 0x100000
-
-#define CTLA_FORCE_BLANK 0x00000400
-#define CTLA_NO_CURSOR 0x00800000
-
-#define G364_PAGE_SIZE 4096
-
-static inline int check_dirty(G364State *s, ram_addr_t page)
-{
- return memory_region_get_dirty(&s->mem_vram, page, G364_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
-}
-
-static inline void reset_dirty(G364State *s,
- ram_addr_t page_min, ram_addr_t page_max)
-{
- memory_region_reset_dirty(&s->mem_vram,
- page_min,
- page_max + G364_PAGE_SIZE - page_min - 1,
- DIRTY_MEMORY_VGA);
-}
-
-static void g364fb_draw_graphic8(G364State *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i, w;
- uint8_t *vram;
- uint8_t *data_display, *dd;
- ram_addr_t page, page_min, page_max;
- int x, y;
- int xmin, xmax;
- int ymin, ymax;
- int xcursor, ycursor;
- unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned int b);
-
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- rgb_to_pixel = rgb_to_pixel8;
- w = 1;
- break;
- case 15:
- rgb_to_pixel = rgb_to_pixel15;
- w = 2;
- break;
- case 16:
- rgb_to_pixel = rgb_to_pixel16;
- w = 2;
- break;
- case 32:
- rgb_to_pixel = rgb_to_pixel32;
- w = 4;
- break;
- default:
- hw_error("g364: unknown host depth %d",
- surface_bits_per_pixel(surface));
- return;
- }
-
- page = 0;
- page_min = (ram_addr_t)-1;
- page_max = 0;
-
- x = y = 0;
- xmin = s->width;
- xmax = 0;
- ymin = s->height;
- ymax = 0;
-
- if (!(s->ctla & CTLA_NO_CURSOR)) {
- xcursor = s->cursor_position >> 12;
- ycursor = s->cursor_position & 0xfff;
- } else {
- xcursor = ycursor = -65;
- }
-
- vram = s->vram + s->top_of_screen;
- /* XXX: out of range in vram? */
- data_display = dd = surface_data(surface);
- while (y < s->height) {
- if (check_dirty(s, page)) {
- if (y < ymin)
- ymin = ymax = y;
- if (page_min == (ram_addr_t)-1)
- page_min = page;
- page_max = page;
- if (x < xmin)
- xmin = x;
- for (i = 0; i < G364_PAGE_SIZE; i++) {
- uint8_t index;
- unsigned int color;
- if (unlikely((y >= ycursor && y < ycursor + 64) &&
- (x >= xcursor && x < xcursor + 64))) {
- /* pointer area */
- int xdiff = x - xcursor;
- uint16_t curs = s->cursor[(y - ycursor) * 8 + xdiff / 8];
- int op = (curs >> ((xdiff & 7) * 2)) & 3;
- if (likely(op == 0)) {
- /* transparent */
- index = *vram;
- color = (*rgb_to_pixel)(
- s->color_palette[index][0],
- s->color_palette[index][1],
- s->color_palette[index][2]);
- } else {
- /* get cursor color */
- index = op - 1;
- color = (*rgb_to_pixel)(
- s->cursor_palette[index][0],
- s->cursor_palette[index][1],
- s->cursor_palette[index][2]);
- }
- } else {
- /* normal area */
- index = *vram;
- color = (*rgb_to_pixel)(
- s->color_palette[index][0],
- s->color_palette[index][1],
- s->color_palette[index][2]);
- }
- memcpy(dd, &color, w);
- dd += w;
- x++;
- vram++;
- if (x == s->width) {
- xmax = s->width - 1;
- y++;
- if (y == s->height) {
- ymax = s->height - 1;
- goto done;
- }
- data_display = dd = data_display + surface_stride(surface);
- xmin = 0;
- x = 0;
- }
- }
- if (x > xmax)
- xmax = x;
- if (y > ymax)
- ymax = y;
- } else {
- int dy;
- if (page_min != (ram_addr_t)-1) {
- reset_dirty(s, page_min, page_max);
- page_min = (ram_addr_t)-1;
- page_max = 0;
- dpy_gfx_update(s->con, xmin, ymin,
- xmax - xmin + 1, ymax - ymin + 1);
- xmin = s->width;
- xmax = 0;
- ymin = s->height;
- ymax = 0;
- }
- x += G364_PAGE_SIZE;
- dy = x / s->width;
- x = x % s->width;
- y += dy;
- vram += G364_PAGE_SIZE;
- data_display += dy * surface_stride(surface);
- dd = data_display + x * w;
- }
- page += G364_PAGE_SIZE;
- }
-
-done:
- if (page_min != (ram_addr_t)-1) {
- dpy_gfx_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
- reset_dirty(s, page_min, page_max);
- }
-}
-
-static void g364fb_draw_blank(G364State *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i, w;
- uint8_t *d;
-
- if (s->blanked) {
- /* Screen is already blank. No need to redraw it */
- return;
- }
-
- w = s->width * surface_bytes_per_pixel(surface);
- d = surface_data(surface);
- for (i = 0; i < s->height; i++) {
- memset(d, 0, w);
- d += surface_stride(surface);
- }
-
- dpy_gfx_update(s->con, 0, 0, s->width, s->height);
- s->blanked = 1;
-}
-
-static void g364fb_update_display(void *opaque)
-{
- G364State *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
-
- qemu_flush_coalesced_mmio_buffer();
-
- if (s->width == 0 || s->height == 0)
- return;
-
- if (s->width != surface_width(surface) ||
- s->height != surface_height(surface)) {
- qemu_console_resize(s->con, s->width, s->height);
- }
-
- memory_region_sync_dirty_bitmap(&s->mem_vram);
- if (s->ctla & CTLA_FORCE_BLANK) {
- g364fb_draw_blank(s);
- } else if (s->depth == 8) {
- g364fb_draw_graphic8(s);
- } else {
- error_report("g364: unknown guest depth %d", s->depth);
- }
-
- qemu_irq_raise(s->irq);
-}
-
-static inline void g364fb_invalidate_display(void *opaque)
-{
- G364State *s = opaque;
-
- s->blanked = 0;
- memory_region_set_dirty(&s->mem_vram, 0, s->vram_size);
-}
-
-static void g364fb_reset(G364State *s)
-{
- qemu_irq_lower(s->irq);
-
- memset(s->color_palette, 0, sizeof(s->color_palette));
- memset(s->cursor_palette, 0, sizeof(s->cursor_palette));
- memset(s->cursor, 0, sizeof(s->cursor));
- s->cursor_position = 0;
- s->ctla = 0;
- s->top_of_screen = 0;
- s->width = s->height = 0;
- memset(s->vram, 0, s->vram_size);
- g364fb_invalidate_display(s);
-}
-
-/* called for accesses to io ports */
-static uint64_t g364fb_ctrl_read(void *opaque,
- hwaddr addr,
- unsigned int size)
-{
- G364State *s = opaque;
- uint32_t val;
-
- if (addr >= REG_CURS_PAT && addr < REG_CURS_PAT + 0x1000) {
- /* cursor pattern */
- int idx = (addr - REG_CURS_PAT) >> 3;
- val = s->cursor[idx];
- } else if (addr >= REG_CURS_PAL && addr < REG_CURS_PAL + 0x18) {
- /* cursor palette */
- int idx = (addr - REG_CURS_PAL) >> 3;
- val = ((uint32_t)s->cursor_palette[idx][0] << 16);
- val |= ((uint32_t)s->cursor_palette[idx][1] << 8);
- val |= ((uint32_t)s->cursor_palette[idx][2] << 0);
- } else {
- switch (addr) {
- case REG_DISPLAY:
- val = s->width / 4;
- break;
- case REG_VDISPLAY:
- val = s->height * 2;
- break;
- case REG_CTLA:
- val = s->ctla;
- break;
- default:
- {
- error_report("g364: invalid read at [" TARGET_FMT_plx "]",
- addr);
- val = 0;
- break;
- }
- }
- }
-
- trace_g364fb_read(addr, val);
-
- return val;
-}
-
-static void g364fb_update_depth(G364State *s)
-{
- static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 };
- s->depth = depths[(s->ctla & 0x00700000) >> 20];
-}
-
-static void g364_invalidate_cursor_position(G364State *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int ymin, ymax, start, end;
-
- /* invalidate only near the cursor */
- ymin = s->cursor_position & 0xfff;
- ymax = MIN(s->height, ymin + 64);
- start = ymin * surface_stride(surface);
- end = (ymax + 1) * surface_stride(surface);
-
- memory_region_set_dirty(&s->mem_vram, start, end - start);
-}
-
-static void g364fb_ctrl_write(void *opaque,
- hwaddr addr,
- uint64_t val,
- unsigned int size)
-{
- G364State *s = opaque;
-
- trace_g364fb_write(addr, val);
-
- if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) {
- /* color palette */
- int idx = (addr - REG_CLR_PAL) >> 3;
- s->color_palette[idx][0] = (val >> 16) & 0xff;
- s->color_palette[idx][1] = (val >> 8) & 0xff;
- s->color_palette[idx][2] = val & 0xff;
- g364fb_invalidate_display(s);
- } else if (addr >= REG_CURS_PAT && addr < REG_CURS_PAT + 0x1000) {
- /* cursor pattern */
- int idx = (addr - REG_CURS_PAT) >> 3;
- s->cursor[idx] = val;
- g364fb_invalidate_display(s);
- } else if (addr >= REG_CURS_PAL && addr < REG_CURS_PAL + 0x18) {
- /* cursor palette */
- int idx = (addr - REG_CURS_PAL) >> 3;
- s->cursor_palette[idx][0] = (val >> 16) & 0xff;
- s->cursor_palette[idx][1] = (val >> 8) & 0xff;
- s->cursor_palette[idx][2] = val & 0xff;
- g364fb_invalidate_display(s);
- } else {
- switch (addr) {
- case REG_BOOT: /* Boot timing */
- case 0x00108: /* Line timing: half sync */
- case 0x00110: /* Line timing: back porch */
- case 0x00120: /* Line timing: short display */
- case 0x00128: /* Frame timing: broad pulse */
- case 0x00130: /* Frame timing: v sync */
- case 0x00138: /* Frame timing: v preequalise */
- case 0x00140: /* Frame timing: v postequalise */
- case 0x00148: /* Frame timing: v blank */
- case 0x00158: /* Line timing: line time */
- case 0x00160: /* Frame store: line start */
- case 0x00168: /* vram cycle: mem init */
- case 0x00170: /* vram cycle: transfer delay */
- case 0x00200: /* vram cycle: mask register */
- /* ignore */
- break;
- case REG_TOP:
- s->top_of_screen = val;
- g364fb_invalidate_display(s);
- break;
- case REG_DISPLAY:
- s->width = val * 4;
- break;
- case REG_VDISPLAY:
- s->height = val / 2;
- break;
- case REG_CTLA:
- s->ctla = val;
- g364fb_update_depth(s);
- g364fb_invalidate_display(s);
- break;
- case REG_CURS_POS:
- g364_invalidate_cursor_position(s);
- s->cursor_position = val;
- g364_invalidate_cursor_position(s);
- break;
- case REG_RESET:
- g364fb_reset(s);
- break;
- default:
- error_report("g364: invalid write of 0x%" PRIx64
- " at [" TARGET_FMT_plx "]", val, addr);
- break;
- }
- }
- qemu_irq_lower(s->irq);
-}
-
-static const MemoryRegionOps g364fb_ctrl_ops = {
- .read = g364fb_ctrl_read,
- .write = g364fb_ctrl_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl.min_access_size = 4,
- .impl.max_access_size = 4,
-};
-
-static int g364fb_post_load(void *opaque, int version_id)
-{
- G364State *s = opaque;
-
- /* force refresh */
- g364fb_update_depth(s);
- g364fb_invalidate_display(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_g364fb = {
- .name = "g364fb",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = g364fb_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size),
- VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
- VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
- VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
- VMSTATE_UINT32(cursor_position, G364State),
- VMSTATE_UINT32(ctla, G364State),
- VMSTATE_UINT32(top_of_screen, G364State),
- VMSTATE_UINT32(width, G364State),
- VMSTATE_UINT32(height, G364State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps g364fb_ops = {
- .invalidate = g364fb_invalidate_display,
- .gfx_update = g364fb_update_display,
-};
-
-static void g364fb_init(DeviceState *dev, G364State *s)
-{
- s->vram = g_malloc0(s->vram_size);
-
- s->con = graphic_console_init(dev, 0, &g364fb_ops, s);
-
- memory_region_init_io(&s->mem_ctrl, NULL, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
- memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",
- s->vram_size, s->vram);
- vmstate_register_ram(&s->mem_vram, dev);
- memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA);
-}
-
-#define TYPE_G364 "sysbus-g364"
-#define G364(obj) OBJECT_CHECK(G364SysBusState, (obj), TYPE_G364)
-
-typedef struct {
- SysBusDevice parent_obj;
-
- G364State g364;
-} G364SysBusState;
-
-static int g364fb_sysbus_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- G364SysBusState *sbs = G364(dev);
- G364State *s = &sbs->g364;
-
- g364fb_init(dev, s);
- sysbus_init_irq(sbd, &s->irq);
- sysbus_init_mmio(sbd, &s->mem_ctrl);
- sysbus_init_mmio(sbd, &s->mem_vram);
-
- return 0;
-}
-
-static void g364fb_sysbus_reset(DeviceState *d)
-{
- G364SysBusState *s = G364(d);
-
- g364fb_reset(&s->g364);
-}
-
-static Property g364fb_sysbus_properties[] = {
- DEFINE_PROP_UINT32("vram_size", G364SysBusState, g364.vram_size,
- 8 * 1024 * 1024),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = g364fb_sysbus_init;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->desc = "G364 framebuffer";
- dc->reset = g364fb_sysbus_reset;
- dc->vmsd = &vmstate_g364fb;
- dc->props = g364fb_sysbus_properties;
-}
-
-static const TypeInfo g364fb_sysbus_info = {
- .name = TYPE_G364,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(G364SysBusState),
- .class_init = g364fb_sysbus_class_init,
-};
-
-static void g364fb_register_types(void)
-{
- type_register_static(&g364fb_sysbus_info);
-}
-
-type_init(g364fb_register_types)
diff --git a/qemu/hw/display/jazz_led.c b/qemu/hw/display/jazz_led.c
deleted file mode 100644
index 09dcdb46a..000000000
--- a/qemu/hw/display/jazz_led.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * QEMU JAZZ LED emulator.
- *
- * Copyright (c) 2007-2012 Herve Poussineau
- *
- * 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 "qemu-common.h"
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "trace.h"
-#include "hw/sysbus.h"
-
-typedef enum {
- REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
-} screen_state_t;
-
-#define TYPE_JAZZ_LED "jazz-led"
-#define JAZZ_LED(obj) OBJECT_CHECK(LedState, (obj), TYPE_JAZZ_LED)
-
-typedef struct LedState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint8_t segments;
- QemuConsole *con;
- screen_state_t state;
-} LedState;
-
-static uint64_t jazz_led_read(void *opaque, hwaddr addr,
- unsigned int size)
-{
- LedState *s = opaque;
- uint8_t val;
-
- val = s->segments;
- trace_jazz_led_read(addr, val);
-
- return val;
-}
-
-static void jazz_led_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned int size)
-{
- LedState *s = opaque;
- uint8_t new_val = val & 0xff;
-
- trace_jazz_led_write(addr, new_val);
-
- s->segments = new_val;
- s->state |= REDRAW_SEGMENTS;
-}
-
-static const MemoryRegionOps led_ops = {
- .read = jazz_led_read,
- .write = jazz_led_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl.min_access_size = 1,
- .impl.max_access_size = 1,
-};
-
-/***********************************************************/
-/* jazz_led display */
-
-static void draw_horizontal_line(DisplaySurface *ds,
- int posy, int posx1, int posx2,
- uint32_t color)
-{
- uint8_t *d;
- int x, bpp;
-
- bpp = (surface_bits_per_pixel(ds) + 7) >> 3;
- d = surface_data(ds) + surface_stride(ds) * posy + bpp * posx1;
- switch(bpp) {
- case 1:
- for (x = posx1; x <= posx2; x++) {
- *((uint8_t *)d) = color;
- d++;
- }
- break;
- case 2:
- for (x = posx1; x <= posx2; x++) {
- *((uint16_t *)d) = color;
- d += 2;
- }
- break;
- case 4:
- for (x = posx1; x <= posx2; x++) {
- *((uint32_t *)d) = color;
- d += 4;
- }
- break;
- }
-}
-
-static void draw_vertical_line(DisplaySurface *ds,
- int posx, int posy1, int posy2,
- uint32_t color)
-{
- uint8_t *d;
- int y, bpp;
-
- bpp = (surface_bits_per_pixel(ds) + 7) >> 3;
- d = surface_data(ds) + surface_stride(ds) * posy1 + bpp * posx;
- switch(bpp) {
- case 1:
- for (y = posy1; y <= posy2; y++) {
- *((uint8_t *)d) = color;
- d += surface_stride(ds);
- }
- break;
- case 2:
- for (y = posy1; y <= posy2; y++) {
- *((uint16_t *)d) = color;
- d += surface_stride(ds);
- }
- break;
- case 4:
- for (y = posy1; y <= posy2; y++) {
- *((uint32_t *)d) = color;
- d += surface_stride(ds);
- }
- break;
- }
-}
-
-static void jazz_led_update_display(void *opaque)
-{
- LedState *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- uint8_t *d1;
- uint32_t color_segment, color_led;
- int y, bpp;
-
- if (s->state & REDRAW_BACKGROUND) {
- /* clear screen */
- bpp = (surface_bits_per_pixel(surface) + 7) >> 3;
- d1 = surface_data(surface);
- for (y = 0; y < surface_height(surface); y++) {
- memset(d1, 0x00, surface_width(surface) * bpp);
- d1 += surface_stride(surface);
- }
- }
-
- if (s->state & REDRAW_SEGMENTS) {
- /* set colors according to bpp */
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa);
- color_led = rgb_to_pixel8(0x00, 0xff, 0x00);
- break;
- case 15:
- color_segment = rgb_to_pixel15(0xaa, 0xaa, 0xaa);
- color_led = rgb_to_pixel15(0x00, 0xff, 0x00);
- break;
- case 16:
- color_segment = rgb_to_pixel16(0xaa, 0xaa, 0xaa);
- color_led = rgb_to_pixel16(0x00, 0xff, 0x00);
- break;
- case 24:
- color_segment = rgb_to_pixel24(0xaa, 0xaa, 0xaa);
- color_led = rgb_to_pixel24(0x00, 0xff, 0x00);
- break;
- case 32:
- color_segment = rgb_to_pixel32(0xaa, 0xaa, 0xaa);
- color_led = rgb_to_pixel32(0x00, 0xff, 0x00);
- break;
- default:
- return;
- }
-
- /* display segments */
- draw_horizontal_line(surface, 40, 10, 40,
- (s->segments & 0x02) ? color_segment : 0);
- draw_vertical_line(surface, 10, 10, 40,
- (s->segments & 0x04) ? color_segment : 0);
- draw_vertical_line(surface, 10, 40, 70,
- (s->segments & 0x08) ? color_segment : 0);
- draw_horizontal_line(surface, 70, 10, 40,
- (s->segments & 0x10) ? color_segment : 0);
- draw_vertical_line(surface, 40, 40, 70,
- (s->segments & 0x20) ? color_segment : 0);
- draw_vertical_line(surface, 40, 10, 40,
- (s->segments & 0x40) ? color_segment : 0);
- draw_horizontal_line(surface, 10, 10, 40,
- (s->segments & 0x80) ? color_segment : 0);
-
- /* display led */
- if (!(s->segments & 0x01))
- color_led = 0; /* black */
- draw_horizontal_line(surface, 68, 50, 50, color_led);
- draw_horizontal_line(surface, 69, 49, 51, color_led);
- draw_horizontal_line(surface, 70, 48, 52, color_led);
- draw_horizontal_line(surface, 71, 49, 51, color_led);
- draw_horizontal_line(surface, 72, 50, 50, color_led);
- }
-
- s->state = REDRAW_NONE;
- dpy_gfx_update(s->con, 0, 0,
- surface_width(surface), surface_height(surface));
-}
-
-static void jazz_led_invalidate_display(void *opaque)
-{
- LedState *s = opaque;
- s->state |= REDRAW_SEGMENTS | REDRAW_BACKGROUND;
-}
-
-static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
-{
- LedState *s = opaque;
- char buf[2];
-
- dpy_text_cursor(s->con, -1, -1);
- qemu_console_resize(s->con, 2, 1);
-
- /* TODO: draw the segments */
- snprintf(buf, 2, "%02hhx\n", s->segments);
- console_write_ch(chardata++, ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE,
- QEMU_COLOR_BLACK, 1));
- console_write_ch(chardata++, ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE,
- QEMU_COLOR_BLACK, 1));
-
- dpy_text_update(s->con, 0, 0, 2, 1);
-}
-
-static int jazz_led_post_load(void *opaque, int version_id)
-{
- /* force refresh */
- jazz_led_invalidate_display(opaque);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_jazz_led = {
- .name = "jazz-led",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = jazz_led_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(segments, LedState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps jazz_led_ops = {
- .invalidate = jazz_led_invalidate_display,
- .gfx_update = jazz_led_update_display,
- .text_update = jazz_led_text_update,
-};
-
-static int jazz_led_init(SysBusDevice *dev)
-{
- LedState *s = JAZZ_LED(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &led_ops, s, "led", 1);
- sysbus_init_mmio(dev, &s->iomem);
-
- s->con = graphic_console_init(DEVICE(dev), 0, &jazz_led_ops, s);
-
- return 0;
-}
-
-static void jazz_led_reset(DeviceState *d)
-{
- LedState *s = JAZZ_LED(d);
-
- s->segments = 0;
- s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
- qemu_console_resize(s->con, 60, 80);
-}
-
-static void jazz_led_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = jazz_led_init;
- dc->desc = "Jazz LED display",
- dc->vmsd = &vmstate_jazz_led;
- dc->reset = jazz_led_reset;
-}
-
-static const TypeInfo jazz_led_info = {
- .name = TYPE_JAZZ_LED,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(LedState),
- .class_init = jazz_led_class_init,
-};
-
-static void jazz_led_register(void)
-{
- type_register_static(&jazz_led_info);
-}
-
-type_init(jazz_led_register);
diff --git a/qemu/hw/display/milkymist-tmu2.c b/qemu/hw/display/milkymist-tmu2.c
deleted file mode 100644
index 9bc88f93b..000000000
--- a/qemu/hw/display/milkymist-tmu2.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * QEMU model of the Milkymist texture mapping unit.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- * Copyright (c) 2010 Sebastien Bourdeauducq
- * <sebastien.bourdeauducq@lekernel.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- *
- * Specification available at:
- * http://www.milkymist.org/socdoc/tmu2.pdf
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "trace.h"
-#include "qemu/error-report.h"
-
-#include <X11/Xlib.h>
-#include <epoxy/gl.h>
-#include <epoxy/glx.h>
-
-enum {
- R_CTL = 0,
- R_HMESHLAST,
- R_VMESHLAST,
- R_BRIGHTNESS,
- R_CHROMAKEY,
- R_VERTICESADDR,
- R_TEXFBUF,
- R_TEXHRES,
- R_TEXVRES,
- R_TEXHMASK,
- R_TEXVMASK,
- R_DSTFBUF,
- R_DSTHRES,
- R_DSTVRES,
- R_DSTHOFFSET,
- R_DSTVOFFSET,
- R_DSTSQUAREW,
- R_DSTSQUAREH,
- R_ALPHA,
- R_MAX
-};
-
-enum {
- CTL_START_BUSY = (1<<0),
- CTL_CHROMAKEY = (1<<1),
-};
-
-enum {
- MAX_BRIGHTNESS = 63,
- MAX_ALPHA = 63,
-};
-
-enum {
- MESH_MAXSIZE = 128,
-};
-
-struct vertex {
- int x;
- int y;
-} QEMU_PACKED;
-
-#define TYPE_MILKYMIST_TMU2 "milkymist-tmu2"
-#define MILKYMIST_TMU2(obj) \
- OBJECT_CHECK(MilkymistTMU2State, (obj), TYPE_MILKYMIST_TMU2)
-
-struct MilkymistTMU2State {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- CharDriverState *chr;
- qemu_irq irq;
-
- uint32_t regs[R_MAX];
-
- Display *dpy;
- GLXFBConfig glx_fb_config;
- GLXContext glx_context;
-};
-typedef struct MilkymistTMU2State MilkymistTMU2State;
-
-static const int glx_fbconfig_attr[] = {
- GLX_GREEN_SIZE, 5,
- GLX_GREEN_SIZE, 6,
- GLX_BLUE_SIZE, 5,
- None
-};
-
-static int tmu2_glx_init(MilkymistTMU2State *s)
-{
- GLXFBConfig *configs;
- int nelements;
-
- s->dpy = XOpenDisplay(NULL); /* FIXME: call XCloseDisplay() */
- if (s->dpy == NULL) {
- return 1;
- }
-
- configs = glXChooseFBConfig(s->dpy, 0, glx_fbconfig_attr, &nelements);
- if (configs == NULL) {
- return 1;
- }
-
- s->glx_fb_config = *configs;
- XFree(configs);
-
- /* FIXME: call glXDestroyContext() */
- s->glx_context = glXCreateNewContext(s->dpy, s->glx_fb_config,
- GLX_RGBA_TYPE, NULL, 1);
- if (s->glx_context == NULL) {
- return 1;
- }
-
- return 0;
-}
-
-static void tmu2_gl_map(struct vertex *mesh, int texhres, int texvres,
- int hmeshlast, int vmeshlast, int ho, int vo, int sw, int sh)
-{
- int x, y;
- int x0, y0, x1, y1;
- int u0, v0, u1, v1, u2, v2, u3, v3;
- double xscale = 1.0 / ((double)(64 * texhres));
- double yscale = 1.0 / ((double)(64 * texvres));
-
- glLoadIdentity();
- glTranslatef(ho, vo, 0);
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
-
- for (y = 0; y < vmeshlast; y++) {
- y0 = y * sh;
- y1 = y0 + sh;
- for (x = 0; x < hmeshlast; x++) {
- x0 = x * sw;
- x1 = x0 + sw;
-
- u0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].x);
- v0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].y);
- u1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].x);
- v1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].y);
- u2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].x);
- v2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].y);
- u3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].x);
- v3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].y);
-
- glTexCoord2d(((double)u0) * xscale, ((double)v0) * yscale);
- glVertex3i(x0, y0, 0);
- glTexCoord2d(((double)u1) * xscale, ((double)v1) * yscale);
- glVertex3i(x1, y0, 0);
- glTexCoord2d(((double)u2) * xscale, ((double)v2) * yscale);
- glVertex3i(x1, y1, 0);
- glTexCoord2d(((double)u3) * xscale, ((double)v3) * yscale);
- glVertex3i(x0, y1, 0);
- }
- }
-
- glEnd();
-}
-
-static void tmu2_start(MilkymistTMU2State *s)
-{
- int pbuffer_attrib[6] = {
- GLX_PBUFFER_WIDTH,
- 0,
- GLX_PBUFFER_HEIGHT,
- 0,
- GLX_PRESERVED_CONTENTS,
- True
- };
-
- GLXPbuffer pbuffer;
- GLuint texture;
- void *fb;
- hwaddr fb_len;
- void *mesh;
- hwaddr mesh_len;
- float m;
-
- trace_milkymist_tmu2_start();
-
- /* Create and set up a suitable OpenGL context */
- pbuffer_attrib[1] = s->regs[R_DSTHRES];
- pbuffer_attrib[3] = s->regs[R_DSTVRES];
- pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib);
- glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context);
-
- /* Fixup endianness. TODO: would it work on BE hosts? */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- glPixelStorei(GL_PACK_SWAP_BYTES, 1);
-
- /* Row alignment */
- glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
- glPixelStorei(GL_PACK_ALIGNMENT, 2);
-
- /* Read the QEMU source framebuffer into an OpenGL texture */
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- fb_len = 2*s->regs[R_TEXHRES]*s->regs[R_TEXVRES];
- fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, 0);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
- glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES],
- 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
-
- /* Set up texturing options */
- /* WARNING:
- * Many cases of TMU2 masking are not supported by OpenGL.
- * We only implement the most common ones:
- * - full bilinear filtering vs. nearest texel
- * - texture clamping vs. texture wrapping
- */
- if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
- if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- }
- if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
-
- /* Translucency and decay */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f;
- glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f);
-
- /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */
- fb_len = 2 * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
- fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 0);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
- glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
-
- /* Map the texture */
- mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex);
- mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, 0);
- if (mesh == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- tmu2_gl_map((struct vertex *)mesh,
- s->regs[R_TEXHRES], s->regs[R_TEXVRES],
- s->regs[R_HMESHLAST], s->regs[R_VMESHLAST],
- s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET],
- s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]);
- cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len);
-
- /* Write back the OpenGL framebuffer to the QEMU framebuffer */
- fb_len = 2 * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
- fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 1);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 1, fb_len);
-
- /* Free OpenGL allocs */
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
-
- s->regs[R_CTL] &= ~CTL_START_BUSY;
-
- trace_milkymist_tmu2_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static uint64_t tmu2_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistTMU2State *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_BRIGHTNESS:
- case R_CHROMAKEY:
- case R_VERTICESADDR:
- case R_TEXFBUF:
- case R_TEXHRES:
- case R_TEXVRES:
- case R_TEXHMASK:
- case R_TEXVMASK:
- case R_DSTFBUF:
- case R_DSTHRES:
- case R_DSTVRES:
- case R_DSTHOFFSET:
- case R_DSTVOFFSET:
- case R_DSTSQUAREW:
- case R_DSTSQUAREH:
- case R_ALPHA:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_tmu2: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_tmu2_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void tmu2_check_registers(MilkymistTMU2State *s)
-{
- if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) {
- error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS);
- }
-
- if (s->regs[R_ALPHA] > MAX_ALPHA) {
- error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA);
- }
-
- if (s->regs[R_VERTICESADDR] & 0x07) {
- error_report("milkymist_tmu2: vertex mesh address has to be 64-bit "
- "aligned");
- }
-
- if (s->regs[R_TEXFBUF] & 0x01) {
- error_report("milkymist_tmu2: texture buffer address has to be "
- "16-bit aligned");
- }
-}
-
-static void tmu2_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistTMU2State *s = opaque;
-
- trace_milkymist_tmu2_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- s->regs[addr] = value;
- if (value & CTL_START_BUSY) {
- tmu2_start(s);
- }
- break;
- case R_BRIGHTNESS:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_CHROMAKEY:
- case R_VERTICESADDR:
- case R_TEXFBUF:
- case R_TEXHRES:
- case R_TEXVRES:
- case R_TEXHMASK:
- case R_TEXVMASK:
- case R_DSTFBUF:
- case R_DSTHRES:
- case R_DSTVRES:
- case R_DSTHOFFSET:
- case R_DSTVOFFSET:
- case R_DSTSQUAREW:
- case R_DSTSQUAREH:
- case R_ALPHA:
- s->regs[addr] = value;
- break;
-
- default:
- error_report("milkymist_tmu2: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- tmu2_check_registers(s);
-}
-
-static const MemoryRegionOps tmu2_mmio_ops = {
- .read = tmu2_read,
- .write = tmu2_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_tmu2_reset(DeviceState *d)
-{
- MilkymistTMU2State *s = MILKYMIST_TMU2(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-}
-
-static int milkymist_tmu2_init(SysBusDevice *dev)
-{
- MilkymistTMU2State *s = MILKYMIST_TMU2(dev);
-
- if (tmu2_glx_init(s)) {
- return 1;
- }
-
- sysbus_init_irq(dev, &s->irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &tmu2_mmio_ops, s,
- "milkymist-tmu2", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_milkymist_tmu2 = {
- .name = "milkymist-tmu2",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistTMU2State, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = milkymist_tmu2_init;
- dc->reset = milkymist_tmu2_reset;
- dc->vmsd = &vmstate_milkymist_tmu2;
-}
-
-static const TypeInfo milkymist_tmu2_info = {
- .name = TYPE_MILKYMIST_TMU2,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistTMU2State),
- .class_init = milkymist_tmu2_class_init,
-};
-
-static void milkymist_tmu2_register_types(void)
-{
- type_register_static(&milkymist_tmu2_info);
-}
-
-type_init(milkymist_tmu2_register_types)
diff --git a/qemu/hw/display/milkymist-vgafb.c b/qemu/hw/display/milkymist-vgafb.c
deleted file mode 100644
index 19ca25647..000000000
--- a/qemu/hw/display/milkymist-vgafb.c
+++ /dev/null
@@ -1,354 +0,0 @@
-
-/*
- * QEMU model of the Milkymist VGA framebuffer.
- *
- * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- *
- * Specification available at:
- * http://www.milkymist.org/socdoc/vgafb.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "trace.h"
-#include "ui/console.h"
-#include "framebuffer.h"
-#include "ui/pixel_ops.h"
-#include "qemu/error-report.h"
-
-#define BITS 8
-#include "milkymist-vgafb_template.h"
-#define BITS 15
-#include "milkymist-vgafb_template.h"
-#define BITS 16
-#include "milkymist-vgafb_template.h"
-#define BITS 24
-#include "milkymist-vgafb_template.h"
-#define BITS 32
-#include "milkymist-vgafb_template.h"
-
-enum {
- R_CTRL = 0,
- R_HRES,
- R_HSYNC_START,
- R_HSYNC_END,
- R_HSCAN,
- R_VRES,
- R_VSYNC_START,
- R_VSYNC_END,
- R_VSCAN,
- R_BASEADDRESS,
- R_BASEADDRESS_ACT,
- R_BURST_COUNT,
- R_DDC,
- R_SOURCE_CLOCK,
- R_MAX
-};
-
-enum {
- CTRL_RESET = (1<<0),
-};
-
-#define TYPE_MILKYMIST_VGAFB "milkymist-vgafb"
-#define MILKYMIST_VGAFB(obj) \
- OBJECT_CHECK(MilkymistVgafbState, (obj), TYPE_MILKYMIST_VGAFB)
-
-struct MilkymistVgafbState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- MemoryRegionSection fbsection;
- QemuConsole *con;
-
- int invalidate;
- uint32_t fb_offset;
- uint32_t fb_mask;
-
- uint32_t regs[R_MAX];
-};
-typedef struct MilkymistVgafbState MilkymistVgafbState;
-
-static int vgafb_enabled(MilkymistVgafbState *s)
-{
- return !(s->regs[R_CTRL] & CTRL_RESET);
-}
-
-static void vgafb_update_display(void *opaque)
-{
- MilkymistVgafbState *s = opaque;
- SysBusDevice *sbd;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width;
- int first = 0;
- int last = 0;
- drawfn fn;
-
- if (!vgafb_enabled(s)) {
- return;
- }
-
- sbd = SYS_BUS_DEVICE(s);
- int dest_width = s->regs[R_HRES];
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 8:
- fn = draw_line_8;
- break;
- case 15:
- fn = draw_line_15;
- dest_width *= 2;
- break;
- case 16:
- fn = draw_line_16;
- dest_width *= 2;
- break;
- case 24:
- fn = draw_line_24;
- dest_width *= 3;
- break;
- case 32:
- fn = draw_line_32;
- dest_width *= 4;
- break;
- default:
- hw_error("milkymist_vgafb: bad color depth\n");
- break;
- }
-
- src_width = s->regs[R_HRES] * 2;
- if (s->invalidate) {
- framebuffer_update_memory_section(&s->fbsection,
- sysbus_address_space(sbd),
- s->regs[R_BASEADDRESS] + s->fb_offset,
- s->regs[R_VRES], src_width);
- }
-
- framebuffer_update_display(surface, &s->fbsection,
- s->regs[R_HRES],
- s->regs[R_VRES],
- src_width,
- dest_width,
- 0,
- s->invalidate,
- fn,
- NULL,
- &first, &last);
-
- if (first >= 0) {
- dpy_gfx_update(s->con, 0, first, s->regs[R_HRES], last - first + 1);
- }
- s->invalidate = 0;
-}
-
-static void vgafb_invalidate_display(void *opaque)
-{
- MilkymistVgafbState *s = opaque;
- s->invalidate = 1;
-}
-
-static void vgafb_resize(MilkymistVgafbState *s)
-{
- if (!vgafb_enabled(s)) {
- return;
- }
-
- qemu_console_resize(s->con, s->regs[R_HRES], s->regs[R_VRES]);
- s->invalidate = 1;
-}
-
-static uint64_t vgafb_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistVgafbState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- case R_HRES:
- case R_HSYNC_START:
- case R_HSYNC_END:
- case R_HSCAN:
- case R_VRES:
- case R_VSYNC_START:
- case R_VSYNC_END:
- case R_VSCAN:
- case R_BASEADDRESS:
- case R_BURST_COUNT:
- case R_DDC:
- case R_SOURCE_CLOCK:
- r = s->regs[addr];
- break;
- case R_BASEADDRESS_ACT:
- r = s->regs[R_BASEADDRESS];
- break;
-
- default:
- error_report("milkymist_vgafb: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_vgafb_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void vgafb_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistVgafbState *s = opaque;
-
- trace_milkymist_vgafb_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- s->regs[addr] = value;
- vgafb_resize(s);
- break;
- case R_HSYNC_START:
- case R_HSYNC_END:
- case R_HSCAN:
- case R_VSYNC_START:
- case R_VSYNC_END:
- case R_VSCAN:
- case R_BURST_COUNT:
- case R_DDC:
- case R_SOURCE_CLOCK:
- s->regs[addr] = value;
- break;
- case R_BASEADDRESS:
- if (value & 0x1f) {
- error_report("milkymist_vgafb: framebuffer base address have to "
- "be 32 byte aligned");
- break;
- }
- s->regs[addr] = value & s->fb_mask;
- s->invalidate = 1;
- break;
- case R_HRES:
- case R_VRES:
- s->regs[addr] = value;
- vgafb_resize(s);
- break;
- case R_BASEADDRESS_ACT:
- error_report("milkymist_vgafb: write to read-only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
-
- default:
- error_report("milkymist_vgafb: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps vgafb_mmio_ops = {
- .read = vgafb_read,
- .write = vgafb_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_vgafb_reset(DeviceState *d)
-{
- MilkymistVgafbState *s = MILKYMIST_VGAFB(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- /* defaults */
- s->regs[R_CTRL] = CTRL_RESET;
- s->regs[R_HRES] = 640;
- s->regs[R_VRES] = 480;
- s->regs[R_BASEADDRESS] = 0;
-}
-
-static const GraphicHwOps vgafb_ops = {
- .invalidate = vgafb_invalidate_display,
- .gfx_update = vgafb_update_display,
-};
-
-static int milkymist_vgafb_init(SysBusDevice *dev)
-{
- MilkymistVgafbState *s = MILKYMIST_VGAFB(dev);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s,
- "milkymist-vgafb", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- s->con = graphic_console_init(DEVICE(dev), 0, &vgafb_ops, s);
-
- return 0;
-}
-
-static int vgafb_post_load(void *opaque, int version_id)
-{
- vgafb_invalidate_display(opaque);
- return 0;
-}
-
-static const VMStateDescription vmstate_milkymist_vgafb = {
- .name = "milkymist-vgafb",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = vgafb_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_vgafb_properties[] = {
- DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0),
- DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = milkymist_vgafb_init;
- dc->reset = milkymist_vgafb_reset;
- dc->vmsd = &vmstate_milkymist_vgafb;
- dc->props = milkymist_vgafb_properties;
-}
-
-static const TypeInfo milkymist_vgafb_info = {
- .name = TYPE_MILKYMIST_VGAFB,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistVgafbState),
- .class_init = milkymist_vgafb_class_init,
-};
-
-static void milkymist_vgafb_register_types(void)
-{
- type_register_static(&milkymist_vgafb_info);
-}
-
-type_init(milkymist_vgafb_register_types)
diff --git a/qemu/hw/display/milkymist-vgafb_template.h b/qemu/hw/display/milkymist-vgafb_template.h
deleted file mode 100644
index 48837809e..000000000
--- a/qemu/hw/display/milkymist-vgafb_template.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * QEMU model of the Milkymist VGA framebuffer.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#if BITS == 8
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *to = rgb_to_pixel8(r, g, b); \
- to += 1; \
- } while (0)
-#elif BITS == 15
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint16_t *)to = rgb_to_pixel15(r, g, b); \
- to += 2; \
- } while (0)
-#elif BITS == 16
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint16_t *)to = rgb_to_pixel16(r, g, b); \
- to += 2; \
- } while (0)
-#elif BITS == 24
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- uint32_t tmp = rgb_to_pixel24(r, g, b); \
- *(to++) = tmp & 0xff; \
- *(to++) = (tmp >> 8) & 0xff; \
- *(to++) = (tmp >> 16) & 0xff; \
- } while (0)
-#elif BITS == 32
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint32_t *)to = rgb_to_pixel32(r, g, b); \
- to += 4; \
- } while (0)
-#else
-#error unknown bit depth
-#endif
-
-static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s,
- int width, int deststep)
-{
- uint16_t rgb565;
- uint8_t r, g, b;
-
- while (width--) {
- rgb565 = lduw_be_p(s);
- r = ((rgb565 >> 11) & 0x1f) << 3;
- g = ((rgb565 >> 5) & 0x3f) << 2;
- b = ((rgb565 >> 0) & 0x1f) << 3;
- COPY_PIXEL(d, r, g, b);
- s += 2;
- }
-}
-
-#undef BITS
-#undef COPY_PIXEL
diff --git a/qemu/hw/display/omap_dss.c b/qemu/hw/display/omap_dss.c
deleted file mode 100644
index 783e9e131..000000000
--- a/qemu/hw/display/omap_dss.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * OMAP2 Display Subsystem.
- *
- * Copyright (C) 2008 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h"
-
-struct omap_dss_s {
- qemu_irq irq;
- qemu_irq drq;
- DisplayState *state;
- MemoryRegion iomem_diss1, iomem_disc1, iomem_rfbi1, iomem_venc1, iomem_im3;
-
- int autoidle;
- int control;
- int enable;
-
- struct omap_dss_panel_s {
- int enable;
- int nx;
- int ny;
-
- int x;
- int y;
- } dig, lcd;
-
- struct {
- uint32_t idlemode;
- uint32_t irqst;
- uint32_t irqen;
- uint32_t control;
- uint32_t config;
- uint32_t capable;
- uint32_t timing[4];
- int line;
- uint32_t bg[2];
- uint32_t trans[2];
-
- struct omap_dss_plane_s {
- int enable;
- int bpp;
- int posx;
- int posy;
- int nx;
- int ny;
-
- hwaddr addr[3];
-
- uint32_t attr;
- uint32_t tresh;
- int rowinc;
- int colinc;
- int wininc;
- } l[3];
-
- int invalidate;
- uint16_t palette[256];
- } dispc;
-
- struct {
- int idlemode;
- uint32_t control;
- int enable;
- int pixels;
- int busy;
- int skiplines;
- uint16_t rxbuf;
- uint32_t config[2];
- uint32_t time[4];
- uint32_t data[6];
- uint16_t vsync;
- uint16_t hsync;
- struct rfbi_chip_s *chip[2];
- } rfbi;
-};
-
-static void omap_dispc_interrupt_update(struct omap_dss_s *s)
-{
- qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen);
-}
-
-static void omap_rfbi_reset(struct omap_dss_s *s)
-{
- s->rfbi.idlemode = 0;
- s->rfbi.control = 2;
- s->rfbi.enable = 0;
- s->rfbi.pixels = 0;
- s->rfbi.skiplines = 0;
- s->rfbi.busy = 0;
- s->rfbi.config[0] = 0x00310000;
- s->rfbi.config[1] = 0x00310000;
- s->rfbi.time[0] = 0;
- s->rfbi.time[1] = 0;
- s->rfbi.time[2] = 0;
- s->rfbi.time[3] = 0;
- s->rfbi.data[0] = 0;
- s->rfbi.data[1] = 0;
- s->rfbi.data[2] = 0;
- s->rfbi.data[3] = 0;
- s->rfbi.data[4] = 0;
- s->rfbi.data[5] = 0;
- s->rfbi.vsync = 0;
- s->rfbi.hsync = 0;
-}
-
-void omap_dss_reset(struct omap_dss_s *s)
-{
- s->autoidle = 0;
- s->control = 0;
- s->enable = 0;
-
- s->dig.enable = 0;
- s->dig.nx = 1;
- s->dig.ny = 1;
-
- s->lcd.enable = 0;
- s->lcd.nx = 1;
- s->lcd.ny = 1;
-
- s->dispc.idlemode = 0;
- s->dispc.irqst = 0;
- s->dispc.irqen = 0;
- s->dispc.control = 0;
- s->dispc.config = 0;
- s->dispc.capable = 0x161;
- s->dispc.timing[0] = 0;
- s->dispc.timing[1] = 0;
- s->dispc.timing[2] = 0;
- s->dispc.timing[3] = 0;
- s->dispc.line = 0;
- s->dispc.bg[0] = 0;
- s->dispc.bg[1] = 0;
- s->dispc.trans[0] = 0;
- s->dispc.trans[1] = 0;
-
- s->dispc.l[0].enable = 0;
- s->dispc.l[0].bpp = 0;
- s->dispc.l[0].addr[0] = 0;
- s->dispc.l[0].addr[1] = 0;
- s->dispc.l[0].addr[2] = 0;
- s->dispc.l[0].posx = 0;
- s->dispc.l[0].posy = 0;
- s->dispc.l[0].nx = 1;
- s->dispc.l[0].ny = 1;
- s->dispc.l[0].attr = 0;
- s->dispc.l[0].tresh = 0;
- s->dispc.l[0].rowinc = 1;
- s->dispc.l[0].colinc = 1;
- s->dispc.l[0].wininc = 0;
-
- omap_rfbi_reset(s);
- omap_dispc_interrupt_update(s);
-}
-
-static uint64_t omap_diss_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* DSS_REVISIONNUMBER */
- return 0x20;
-
- case 0x10: /* DSS_SYSCONFIG */
- return s->autoidle;
-
- case 0x14: /* DSS_SYSSTATUS */
- return 1; /* RESETDONE */
-
- case 0x40: /* DSS_CONTROL */
- return s->control;
-
- case 0x50: /* DSS_PSA_LCD_REG_1 */
- case 0x54: /* DSS_PSA_LCD_REG_2 */
- case 0x58: /* DSS_PSA_VIDEO_REG */
- /* TODO: fake some values when appropriate s->control bits are set */
- return 0;
-
- case 0x5c: /* DSS_STATUS */
- return 1 + (s->control & 1);
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_diss_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* DSS_REVISIONNUMBER */
- case 0x14: /* DSS_SYSSTATUS */
- case 0x50: /* DSS_PSA_LCD_REG_1 */
- case 0x54: /* DSS_PSA_LCD_REG_2 */
- case 0x58: /* DSS_PSA_VIDEO_REG */
- case 0x5c: /* DSS_STATUS */
- OMAP_RO_REG(addr);
- break;
-
- case 0x10: /* DSS_SYSCONFIG */
- if (value & 2) /* SOFTRESET */
- omap_dss_reset(s);
- s->autoidle = value & 1;
- break;
-
- case 0x40: /* DSS_CONTROL */
- s->control = value & 0x3dd;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_diss_ops = {
- .read = omap_diss_read,
- .write = omap_diss_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t omap_disc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x000: /* DISPC_REVISION */
- return 0x20;
-
- case 0x010: /* DISPC_SYSCONFIG */
- return s->dispc.idlemode;
-
- case 0x014: /* DISPC_SYSSTATUS */
- return 1; /* RESETDONE */
-
- case 0x018: /* DISPC_IRQSTATUS */
- return s->dispc.irqst;
-
- case 0x01c: /* DISPC_IRQENABLE */
- return s->dispc.irqen;
-
- case 0x040: /* DISPC_CONTROL */
- return s->dispc.control;
-
- case 0x044: /* DISPC_CONFIG */
- return s->dispc.config;
-
- case 0x048: /* DISPC_CAPABLE */
- return s->dispc.capable;
-
- case 0x04c: /* DISPC_DEFAULT_COLOR0 */
- return s->dispc.bg[0];
- case 0x050: /* DISPC_DEFAULT_COLOR1 */
- return s->dispc.bg[1];
- case 0x054: /* DISPC_TRANS_COLOR0 */
- return s->dispc.trans[0];
- case 0x058: /* DISPC_TRANS_COLOR1 */
- return s->dispc.trans[1];
-
- case 0x05c: /* DISPC_LINE_STATUS */
- return 0x7ff;
- case 0x060: /* DISPC_LINE_NUMBER */
- return s->dispc.line;
-
- case 0x064: /* DISPC_TIMING_H */
- return s->dispc.timing[0];
- case 0x068: /* DISPC_TIMING_V */
- return s->dispc.timing[1];
- case 0x06c: /* DISPC_POL_FREQ */
- return s->dispc.timing[2];
- case 0x070: /* DISPC_DIVISOR */
- return s->dispc.timing[3];
-
- case 0x078: /* DISPC_SIZE_DIG */
- return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
- case 0x07c: /* DISPC_SIZE_LCD */
- return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
-
- case 0x080: /* DISPC_GFX_BA0 */
- return s->dispc.l[0].addr[0];
- case 0x084: /* DISPC_GFX_BA1 */
- return s->dispc.l[0].addr[1];
- case 0x088: /* DISPC_GFX_POSITION */
- return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx;
- case 0x08c: /* DISPC_GFX_SIZE */
- return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1);
- case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
- return s->dispc.l[0].attr;
- case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
- return s->dispc.l[0].tresh;
- case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
- return 256;
- case 0x0ac: /* DISPC_GFX_ROW_INC */
- return s->dispc.l[0].rowinc;
- case 0x0b0: /* DISPC_GFX_PIXEL_INC */
- return s->dispc.l[0].colinc;
- case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
- return s->dispc.l[0].wininc;
- case 0x0b8: /* DISPC_GFX_TABLE_BA */
- return s->dispc.l[0].addr[2];
-
- case 0x0bc: /* DISPC_VID1_BA0 */
- case 0x0c0: /* DISPC_VID1_BA1 */
- case 0x0c4: /* DISPC_VID1_POSITION */
- case 0x0c8: /* DISPC_VID1_SIZE */
- case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
- case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
- case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
- case 0x0d8: /* DISPC_VID1_ROW_INC */
- case 0x0dc: /* DISPC_VID1_PIXEL_INC */
- case 0x0e0: /* DISPC_VID1_FIR */
- case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
- case 0x0e8: /* DISPC_VID1_ACCU0 */
- case 0x0ec: /* DISPC_VID1_ACCU1 */
- case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
- case 0x14c: /* DISPC_VID2_BA0 */
- case 0x150: /* DISPC_VID2_BA1 */
- case 0x154: /* DISPC_VID2_POSITION */
- case 0x158: /* DISPC_VID2_SIZE */
- case 0x15c: /* DISPC_VID2_ATTRIBUTES */
- case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
- case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
- case 0x168: /* DISPC_VID2_ROW_INC */
- case 0x16c: /* DISPC_VID2_PIXEL_INC */
- case 0x170: /* DISPC_VID2_FIR */
- case 0x174: /* DISPC_VID2_PICTURE_SIZE */
- case 0x178: /* DISPC_VID2_ACCU0 */
- case 0x17c: /* DISPC_VID2_ACCU1 */
- case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
- case 0x1d4: /* DISPC_DATA_CYCLE1 */
- case 0x1d8: /* DISPC_DATA_CYCLE2 */
- case 0x1dc: /* DISPC_DATA_CYCLE3 */
- return 0;
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_disc_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x010: /* DISPC_SYSCONFIG */
- if (value & 2) /* SOFTRESET */
- omap_dss_reset(s);
- s->dispc.idlemode = value & 0x301b;
- break;
-
- case 0x018: /* DISPC_IRQSTATUS */
- s->dispc.irqst &= ~value;
- omap_dispc_interrupt_update(s);
- break;
-
- case 0x01c: /* DISPC_IRQENABLE */
- s->dispc.irqen = value & 0xffff;
- omap_dispc_interrupt_update(s);
- break;
-
- case 0x040: /* DISPC_CONTROL */
- s->dispc.control = value & 0x07ff9fff;
- s->dig.enable = (value >> 1) & 1;
- s->lcd.enable = (value >> 0) & 1;
- if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */
- if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) {
- fprintf(stderr, "%s: Overlay Optimization when no overlay "
- "region effectively exists leads to "
- "unpredictable behaviour!\n", __func__);
- }
- if (value & (1 << 6)) { /* GODIGITAL */
- /* XXX: Shadowed fields are:
- * s->dispc.config
- * s->dispc.capable
- * s->dispc.bg[0]
- * s->dispc.bg[1]
- * s->dispc.trans[0]
- * s->dispc.trans[1]
- * s->dispc.line
- * s->dispc.timing[0]
- * s->dispc.timing[1]
- * s->dispc.timing[2]
- * s->dispc.timing[3]
- * s->lcd.nx
- * s->lcd.ny
- * s->dig.nx
- * s->dig.ny
- * s->dispc.l[0].addr[0]
- * s->dispc.l[0].addr[1]
- * s->dispc.l[0].addr[2]
- * s->dispc.l[0].posx
- * s->dispc.l[0].posy
- * s->dispc.l[0].nx
- * s->dispc.l[0].ny
- * s->dispc.l[0].tresh
- * s->dispc.l[0].rowinc
- * s->dispc.l[0].colinc
- * s->dispc.l[0].wininc
- * All they need to be loaded here from their shadow registers.
- */
- }
- if (value & (1 << 5)) { /* GOLCD */
- /* XXX: Likewise for LCD here. */
- }
- s->dispc.invalidate = 1;
- break;
-
- case 0x044: /* DISPC_CONFIG */
- s->dispc.config = value & 0x3fff;
- /* XXX:
- * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
- * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
- */
- s->dispc.invalidate = 1;
- break;
-
- case 0x048: /* DISPC_CAPABLE */
- s->dispc.capable = value & 0x3ff;
- break;
-
- case 0x04c: /* DISPC_DEFAULT_COLOR0 */
- s->dispc.bg[0] = value & 0xffffff;
- s->dispc.invalidate = 1;
- break;
- case 0x050: /* DISPC_DEFAULT_COLOR1 */
- s->dispc.bg[1] = value & 0xffffff;
- s->dispc.invalidate = 1;
- break;
- case 0x054: /* DISPC_TRANS_COLOR0 */
- s->dispc.trans[0] = value & 0xffffff;
- s->dispc.invalidate = 1;
- break;
- case 0x058: /* DISPC_TRANS_COLOR1 */
- s->dispc.trans[1] = value & 0xffffff;
- s->dispc.invalidate = 1;
- break;
-
- case 0x060: /* DISPC_LINE_NUMBER */
- s->dispc.line = value & 0x7ff;
- break;
-
- case 0x064: /* DISPC_TIMING_H */
- s->dispc.timing[0] = value & 0x0ff0ff3f;
- break;
- case 0x068: /* DISPC_TIMING_V */
- s->dispc.timing[1] = value & 0x0ff0ff3f;
- break;
- case 0x06c: /* DISPC_POL_FREQ */
- s->dispc.timing[2] = value & 0x0003ffff;
- break;
- case 0x070: /* DISPC_DIVISOR */
- s->dispc.timing[3] = value & 0x00ff00ff;
- break;
-
- case 0x078: /* DISPC_SIZE_DIG */
- s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
- s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
- s->dispc.invalidate = 1;
- break;
- case 0x07c: /* DISPC_SIZE_LCD */
- s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
- s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
- s->dispc.invalidate = 1;
- break;
- case 0x080: /* DISPC_GFX_BA0 */
- s->dispc.l[0].addr[0] = (hwaddr) value;
- s->dispc.invalidate = 1;
- break;
- case 0x084: /* DISPC_GFX_BA1 */
- s->dispc.l[0].addr[1] = (hwaddr) value;
- s->dispc.invalidate = 1;
- break;
- case 0x088: /* DISPC_GFX_POSITION */
- s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */
- s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */
- s->dispc.invalidate = 1;
- break;
- case 0x08c: /* DISPC_GFX_SIZE */
- s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */
- s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */
- s->dispc.invalidate = 1;
- break;
- case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
- s->dispc.l[0].attr = value & 0x7ff;
- if (value & (3 << 9))
- fprintf(stderr, "%s: Big-endian pixel format not supported\n",
- __FUNCTION__);
- s->dispc.l[0].enable = value & 1;
- s->dispc.l[0].bpp = (value >> 1) & 0xf;
- s->dispc.invalidate = 1;
- break;
- case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
- s->dispc.l[0].tresh = value & 0x01ff01ff;
- break;
- case 0x0ac: /* DISPC_GFX_ROW_INC */
- s->dispc.l[0].rowinc = value;
- s->dispc.invalidate = 1;
- break;
- case 0x0b0: /* DISPC_GFX_PIXEL_INC */
- s->dispc.l[0].colinc = value;
- s->dispc.invalidate = 1;
- break;
- case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
- s->dispc.l[0].wininc = value;
- break;
- case 0x0b8: /* DISPC_GFX_TABLE_BA */
- s->dispc.l[0].addr[2] = (hwaddr) value;
- s->dispc.invalidate = 1;
- break;
-
- case 0x0bc: /* DISPC_VID1_BA0 */
- case 0x0c0: /* DISPC_VID1_BA1 */
- case 0x0c4: /* DISPC_VID1_POSITION */
- case 0x0c8: /* DISPC_VID1_SIZE */
- case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
- case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
- case 0x0d8: /* DISPC_VID1_ROW_INC */
- case 0x0dc: /* DISPC_VID1_PIXEL_INC */
- case 0x0e0: /* DISPC_VID1_FIR */
- case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
- case 0x0e8: /* DISPC_VID1_ACCU0 */
- case 0x0ec: /* DISPC_VID1_ACCU1 */
- case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
- case 0x14c: /* DISPC_VID2_BA0 */
- case 0x150: /* DISPC_VID2_BA1 */
- case 0x154: /* DISPC_VID2_POSITION */
- case 0x158: /* DISPC_VID2_SIZE */
- case 0x15c: /* DISPC_VID2_ATTRIBUTES */
- case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
- case 0x168: /* DISPC_VID2_ROW_INC */
- case 0x16c: /* DISPC_VID2_PIXEL_INC */
- case 0x170: /* DISPC_VID2_FIR */
- case 0x174: /* DISPC_VID2_PICTURE_SIZE */
- case 0x178: /* DISPC_VID2_ACCU0 */
- case 0x17c: /* DISPC_VID2_ACCU1 */
- case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
- case 0x1d4: /* DISPC_DATA_CYCLE1 */
- case 0x1d8: /* DISPC_DATA_CYCLE2 */
- case 0x1dc: /* DISPC_DATA_CYCLE3 */
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_disc_ops = {
- .read = omap_disc_read,
- .write = omap_disc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
-{
- if (!s->rfbi.busy)
- return;
-
- /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */
-
- s->rfbi.busy = 0;
-}
-
-static void omap_rfbi_transfer_start(struct omap_dss_s *s)
-{
- void *data;
- hwaddr len;
- hwaddr data_addr;
- int pitch;
- static void *bounce_buffer;
- static hwaddr bounce_len;
-
- if (!s->rfbi.enable || s->rfbi.busy)
- return;
-
- 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", __FUNCTION__);
- return;
- }
-
- if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */
- return;
- /* TODO: check that LCD output is enabled in DISPC. */
-
- s->rfbi.busy = 1;
-
- len = s->rfbi.pixels * 2;
-
- data_addr = s->dispc.l[0].addr[0];
- data = cpu_physical_memory_map(data_addr, &len, 0);
- if (data && len != s->rfbi.pixels * 2) {
- cpu_physical_memory_unmap(data, len, 0, 0);
- data = NULL;
- len = s->rfbi.pixels * 2;
- }
- if (!data) {
- if (len > bounce_len) {
- bounce_buffer = g_realloc(bounce_buffer, len);
- }
- data = bounce_buffer;
- cpu_physical_memory_read(data_addr, data, len);
- }
-
- /* TODO bpp */
- s->rfbi.pixels = 0;
-
- /* TODO: negative values */
- pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
-
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
- s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
- s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
-
- if (data != bounce_buffer) {
- cpu_physical_memory_unmap(data, len, 0, len);
- }
-
- omap_rfbi_transfer_stop(s);
-
- /* TODO */
- s->dispc.irqst |= 1; /* FRAMEDONE */
- omap_dispc_interrupt_update(s);
-}
-
-static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* RFBI_REVISION */
- return 0x10;
-
- case 0x10: /* RFBI_SYSCONFIG */
- return s->rfbi.idlemode;
-
- case 0x14: /* RFBI_SYSSTATUS */
- return 1 | (s->rfbi.busy << 8); /* RESETDONE */
-
- case 0x40: /* RFBI_CONTROL */
- return s->rfbi.control;
-
- case 0x44: /* RFBI_PIXELCNT */
- return s->rfbi.pixels;
-
- case 0x48: /* RFBI_LINE_NUMBER */
- return s->rfbi.skiplines;
-
- case 0x58: /* RFBI_READ */
- case 0x5c: /* RFBI_STATUS */
- return s->rfbi.rxbuf;
-
- case 0x60: /* RFBI_CONFIG0 */
- return s->rfbi.config[0];
- case 0x64: /* RFBI_ONOFF_TIME0 */
- return s->rfbi.time[0];
- case 0x68: /* RFBI_CYCLE_TIME0 */
- return s->rfbi.time[1];
- case 0x6c: /* RFBI_DATA_CYCLE1_0 */
- return s->rfbi.data[0];
- case 0x70: /* RFBI_DATA_CYCLE2_0 */
- return s->rfbi.data[1];
- case 0x74: /* RFBI_DATA_CYCLE3_0 */
- return s->rfbi.data[2];
-
- case 0x78: /* RFBI_CONFIG1 */
- return s->rfbi.config[1];
- case 0x7c: /* RFBI_ONOFF_TIME1 */
- return s->rfbi.time[2];
- case 0x80: /* RFBI_CYCLE_TIME1 */
- return s->rfbi.time[3];
- case 0x84: /* RFBI_DATA_CYCLE1_1 */
- return s->rfbi.data[3];
- case 0x88: /* RFBI_DATA_CYCLE2_1 */
- return s->rfbi.data[4];
- case 0x8c: /* RFBI_DATA_CYCLE3_1 */
- return s->rfbi.data[5];
-
- case 0x90: /* RFBI_VSYNC_WIDTH */
- return s->rfbi.vsync;
- case 0x94: /* RFBI_HSYNC_WIDTH */
- return s->rfbi.hsync;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_rfbi_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x10: /* RFBI_SYSCONFIG */
- if (value & 2) /* SOFTRESET */
- omap_rfbi_reset(s);
- s->rfbi.idlemode = value & 0x19;
- break;
-
- case 0x40: /* RFBI_CONTROL */
- s->rfbi.control = value & 0xf;
- s->rfbi.enable = value & 1;
- if (value & (1 << 4) && /* ITE */
- !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
- omap_rfbi_transfer_start(s);
- break;
-
- case 0x44: /* RFBI_PIXELCNT */
- s->rfbi.pixels = value;
- break;
-
- case 0x48: /* RFBI_LINE_NUMBER */
- s->rfbi.skiplines = value & 0x7ff;
- break;
-
- case 0x4c: /* RFBI_CMD */
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
- break;
- case 0x50: /* RFBI_PARAM */
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
- break;
- case 0x54: /* RFBI_DATA */
- /* TODO: take into account the format set up in s->rfbi.config[?] and
- * s->rfbi.data[?], but special-case the most usual scenario so that
- * speed doesn't suffer. */
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
- }
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
- }
- if (!-- s->rfbi.pixels)
- omap_rfbi_transfer_stop(s);
- break;
- case 0x58: /* RFBI_READ */
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
- s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
- else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
- s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 1);
- if (!-- s->rfbi.pixels)
- omap_rfbi_transfer_stop(s);
- break;
-
- case 0x5c: /* RFBI_STATUS */
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
- s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
- else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
- s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 0);
- if (!-- s->rfbi.pixels)
- omap_rfbi_transfer_stop(s);
- break;
-
- case 0x60: /* RFBI_CONFIG0 */
- s->rfbi.config[0] = value & 0x003f1fff;
- break;
-
- case 0x64: /* RFBI_ONOFF_TIME0 */
- s->rfbi.time[0] = value & 0x3fffffff;
- break;
- case 0x68: /* RFBI_CYCLE_TIME0 */
- s->rfbi.time[1] = value & 0x0fffffff;
- break;
- case 0x6c: /* RFBI_DATA_CYCLE1_0 */
- s->rfbi.data[0] = value & 0x0f1f0f1f;
- break;
- case 0x70: /* RFBI_DATA_CYCLE2_0 */
- s->rfbi.data[1] = value & 0x0f1f0f1f;
- break;
- case 0x74: /* RFBI_DATA_CYCLE3_0 */
- s->rfbi.data[2] = value & 0x0f1f0f1f;
- break;
- case 0x78: /* RFBI_CONFIG1 */
- s->rfbi.config[1] = value & 0x003f1fff;
- break;
-
- case 0x7c: /* RFBI_ONOFF_TIME1 */
- s->rfbi.time[2] = value & 0x3fffffff;
- break;
- case 0x80: /* RFBI_CYCLE_TIME1 */
- s->rfbi.time[3] = value & 0x0fffffff;
- break;
- case 0x84: /* RFBI_DATA_CYCLE1_1 */
- s->rfbi.data[3] = value & 0x0f1f0f1f;
- break;
- case 0x88: /* RFBI_DATA_CYCLE2_1 */
- s->rfbi.data[4] = value & 0x0f1f0f1f;
- break;
- case 0x8c: /* RFBI_DATA_CYCLE3_1 */
- s->rfbi.data[5] = value & 0x0f1f0f1f;
- break;
-
- case 0x90: /* RFBI_VSYNC_WIDTH */
- s->rfbi.vsync = value & 0xffff;
- break;
- case 0x94: /* RFBI_HSYNC_WIDTH */
- s->rfbi.hsync = value & 0xffff;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_rfbi_ops = {
- .read = omap_rfbi_read,
- .write = omap_rfbi_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t omap_venc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* REV_ID */
- case 0x04: /* STATUS */
- case 0x08: /* F_CONTROL */
- case 0x10: /* VIDOUT_CTRL */
- case 0x14: /* SYNC_CTRL */
- case 0x1c: /* LLEN */
- case 0x20: /* FLENS */
- case 0x24: /* HFLTR_CTRL */
- case 0x28: /* CC_CARR_WSS_CARR */
- case 0x2c: /* C_PHASE */
- case 0x30: /* GAIN_U */
- case 0x34: /* GAIN_V */
- case 0x38: /* GAIN_Y */
- case 0x3c: /* BLACK_LEVEL */
- case 0x40: /* BLANK_LEVEL */
- case 0x44: /* X_COLOR */
- case 0x48: /* M_CONTROL */
- case 0x4c: /* BSTAMP_WSS_DATA */
- case 0x50: /* S_CARR */
- case 0x54: /* LINE21 */
- case 0x58: /* LN_SEL */
- case 0x5c: /* L21__WC_CTL */
- case 0x60: /* HTRIGGER_VTRIGGER */
- case 0x64: /* SAVID__EAVID */
- case 0x68: /* FLEN__FAL */
- case 0x6c: /* LAL__PHASE_RESET */
- case 0x70: /* HS_INT_START_STOP_X */
- case 0x74: /* HS_EXT_START_STOP_X */
- case 0x78: /* VS_INT_START_X */
- case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
- case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
- case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
- case 0x88: /* VS_EXT_STOP_Y */
- case 0x90: /* AVID_START_STOP_X */
- case 0x94: /* AVID_START_STOP_Y */
- case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
- case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
- case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
- case 0xb0: /* TVDETGP_INT_START_STOP_X */
- case 0xb4: /* TVDETGP_INT_START_STOP_Y */
- case 0xb8: /* GEN_CTRL */
- case 0xc4: /* DAC_TST__DAC_A */
- case 0xc8: /* DAC_B__DAC_C */
- return 0;
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_venc_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, size);
- return;
- }
-
- switch (addr) {
- case 0x08: /* F_CONTROL */
- case 0x10: /* VIDOUT_CTRL */
- case 0x14: /* SYNC_CTRL */
- case 0x1c: /* LLEN */
- case 0x20: /* FLENS */
- case 0x24: /* HFLTR_CTRL */
- case 0x28: /* CC_CARR_WSS_CARR */
- case 0x2c: /* C_PHASE */
- case 0x30: /* GAIN_U */
- case 0x34: /* GAIN_V */
- case 0x38: /* GAIN_Y */
- case 0x3c: /* BLACK_LEVEL */
- case 0x40: /* BLANK_LEVEL */
- case 0x44: /* X_COLOR */
- case 0x48: /* M_CONTROL */
- case 0x4c: /* BSTAMP_WSS_DATA */
- case 0x50: /* S_CARR */
- case 0x54: /* LINE21 */
- case 0x58: /* LN_SEL */
- case 0x5c: /* L21__WC_CTL */
- case 0x60: /* HTRIGGER_VTRIGGER */
- case 0x64: /* SAVID__EAVID */
- case 0x68: /* FLEN__FAL */
- case 0x6c: /* LAL__PHASE_RESET */
- case 0x70: /* HS_INT_START_STOP_X */
- case 0x74: /* HS_EXT_START_STOP_X */
- case 0x78: /* VS_INT_START_X */
- case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
- case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
- case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
- case 0x88: /* VS_EXT_STOP_Y */
- case 0x90: /* AVID_START_STOP_X */
- case 0x94: /* AVID_START_STOP_Y */
- case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
- case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
- case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
- case 0xb0: /* TVDETGP_INT_START_STOP_X */
- case 0xb4: /* TVDETGP_INT_START_STOP_Y */
- case 0xb8: /* GEN_CTRL */
- case 0xc4: /* DAC_TST__DAC_A */
- case 0xc8: /* DAC_B__DAC_C */
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_venc_ops = {
- .read = omap_venc_read,
- .write = omap_venc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t omap_im3_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x0a8: /* SBIMERRLOGA */
- case 0x0b0: /* SBIMERRLOG */
- case 0x190: /* SBIMSTATE */
- case 0x198: /* SBTMSTATE_L */
- case 0x19c: /* SBTMSTATE_H */
- case 0x1a8: /* SBIMCONFIG_L */
- case 0x1ac: /* SBIMCONFIG_H */
- case 0x1f8: /* SBID_L */
- case 0x1fc: /* SBID_H */
- return 0;
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_im3_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x0b0: /* SBIMERRLOG */
- case 0x190: /* SBIMSTATE */
- case 0x198: /* SBTMSTATE_L */
- case 0x19c: /* SBTMSTATE_H */
- case 0x1a8: /* SBIMCONFIG_L */
- case 0x1ac: /* SBIMCONFIG_H */
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_im3_ops = {
- .read = omap_im3_read,
- .write = omap_im3_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
- MemoryRegion *sysmem,
- hwaddr l3_base,
- qemu_irq irq, qemu_irq drq,
- omap_clk fck1, omap_clk fck2, omap_clk ck54m,
- omap_clk ick1, omap_clk ick2)
-{
- struct omap_dss_s *s = g_new0(struct omap_dss_s, 1);
-
- s->irq = irq;
- s->drq = drq;
- omap_dss_reset(s);
-
- memory_region_init_io(&s->iomem_diss1, NULL, &omap_diss_ops, s, "omap.diss1",
- omap_l4_region_size(ta, 0));
- memory_region_init_io(&s->iomem_disc1, NULL, &omap_disc_ops, s, "omap.disc1",
- omap_l4_region_size(ta, 1));
- memory_region_init_io(&s->iomem_rfbi1, NULL, &omap_rfbi_ops, s, "omap.rfbi1",
- omap_l4_region_size(ta, 2));
- memory_region_init_io(&s->iomem_venc1, NULL, &omap_venc_ops, s, "omap.venc1",
- omap_l4_region_size(ta, 3));
- memory_region_init_io(&s->iomem_im3, NULL, &omap_im3_ops, s,
- "omap.im3", 0x1000);
-
- omap_l4_attach(ta, 0, &s->iomem_diss1);
- omap_l4_attach(ta, 1, &s->iomem_disc1);
- omap_l4_attach(ta, 2, &s->iomem_rfbi1);
- omap_l4_attach(ta, 3, &s->iomem_venc1);
- memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3);
-
-#if 0
- s->state = graphic_console_init(omap_update_display,
- omap_invalidate_display, omap_screen_dump, s);
-#endif
-
- return s;
-}
-
-void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
-{
- if (cs < 0 || cs > 1)
- hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
- s->rfbi.chip[cs] = chip;
-}
diff --git a/qemu/hw/display/omap_lcd_template.h b/qemu/hw/display/omap_lcd_template.h
deleted file mode 100644
index f0ce71fd6..000000000
--- a/qemu/hw/display/omap_lcd_template.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * QEMU OMAP LCD Emulator templates
- *
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if DEPTH == 8
-# define BPP 1
-# define PIXEL_TYPE uint8_t
-#elif DEPTH == 15 || DEPTH == 16
-# define BPP 2
-# define PIXEL_TYPE uint16_t
-#elif DEPTH == 32
-# define BPP 4
-# define PIXEL_TYPE uint32_t
-#else
-# error unsupport depth
-#endif
-
-/*
- * 2-bit colour
- */
-static void glue(draw_line2_, DEPTH)(void *opaque,
- uint8_t *d, const uint8_t *s, int width, int deststep)
-{
- uint16_t *pal = opaque;
- uint8_t v, r, g, b;
-
- do {
- v = ldub_p((void *) s);
- r = (pal[v & 3] >> 4) & 0xf0;
- g = pal[v & 3] & 0xf0;
- b = (pal[v & 3] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- v >>= 2;
- r = (pal[v & 3] >> 4) & 0xf0;
- g = pal[v & 3] & 0xf0;
- b = (pal[v & 3] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- v >>= 2;
- r = (pal[v & 3] >> 4) & 0xf0;
- g = pal[v & 3] & 0xf0;
- b = (pal[v & 3] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- v >>= 2;
- r = (pal[v & 3] >> 4) & 0xf0;
- g = pal[v & 3] & 0xf0;
- b = (pal[v & 3] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- s ++;
- width -= 4;
- } while (width > 0);
-}
-
-/*
- * 4-bit colour
- */
-static void glue(draw_line4_, DEPTH)(void *opaque,
- uint8_t *d, const uint8_t *s, int width, int deststep)
-{
- uint16_t *pal = opaque;
- uint8_t v, r, g, b;
-
- do {
- v = ldub_p((void *) s);
- r = (pal[v & 0xf] >> 4) & 0xf0;
- g = pal[v & 0xf] & 0xf0;
- b = (pal[v & 0xf] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- v >>= 4;
- r = (pal[v & 0xf] >> 4) & 0xf0;
- g = pal[v & 0xf] & 0xf0;
- b = (pal[v & 0xf] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- d += BPP;
- s ++;
- width -= 2;
- } while (width > 0);
-}
-
-/*
- * 8-bit colour
- */
-static void glue(draw_line8_, DEPTH)(void *opaque,
- uint8_t *d, const uint8_t *s, int width, int deststep)
-{
- uint16_t *pal = opaque;
- uint8_t v, r, g, b;
-
- do {
- v = ldub_p((void *) s);
- r = (pal[v] >> 4) & 0xf0;
- g = pal[v] & 0xf0;
- b = (pal[v] << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s ++;
- d += BPP;
- } while (-- width != 0);
-}
-
-/*
- * 12-bit colour
- */
-static void glue(draw_line12_, DEPTH)(void *opaque,
- uint8_t *d, const uint8_t *s, int width, int deststep)
-{
- uint16_t v;
- uint8_t r, g, b;
-
- do {
- v = lduw_le_p((void *) s);
- r = (v >> 4) & 0xf0;
- g = v & 0xf0;
- b = (v << 4) & 0xf0;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 2;
- d += BPP;
- } while (-- width != 0);
-}
-
-/*
- * 16-bit colour
- */
-static void glue(draw_line16_, DEPTH)(void *opaque,
- uint8_t *d, const uint8_t *s, int width, int deststep)
-{
-#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 2);
-#else
- uint16_t v;
- uint8_t r, g, b;
-
- do {
- v = lduw_le_p((void *) s);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 2;
- d += BPP;
- } while (-- width != 0);
-#endif
-}
-
-#undef DEPTH
-#undef BPP
-#undef PIXEL_TYPE
diff --git a/qemu/hw/display/omap_lcdc.c b/qemu/hw/display/omap_lcdc.c
deleted file mode 100644
index ce1058bf8..000000000
--- a/qemu/hw/display/omap_lcdc.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * OMAP LCD controller.
- *
- * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h"
-#include "framebuffer.h"
-#include "ui/pixel_ops.h"
-
-struct omap_lcd_panel_s {
- MemoryRegion *sysmem;
- MemoryRegion iomem;
- MemoryRegionSection fbsection;
- qemu_irq irq;
- QemuConsole *con;
-
- int plm;
- int tft;
- int mono;
- int enable;
- int width;
- int height;
- int interrupts;
- uint32_t timing[3];
- uint32_t subpanel;
- uint32_t ctrl;
-
- struct omap_dma_lcd_channel_s *dma;
- uint16_t palette[256];
- int palette_done;
- int frame_done;
- int invalidate;
- int sync_error;
-};
-
-static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
-{
- if (s->frame_done && (s->interrupts & 1)) {
- qemu_irq_raise(s->irq);
- return;
- }
-
- if (s->palette_done && (s->interrupts & 2)) {
- qemu_irq_raise(s->irq);
- return;
- }
-
- if (s->sync_error) {
- qemu_irq_raise(s->irq);
- return;
- }
-
- qemu_irq_lower(s->irq);
-}
-
-#define draw_line_func drawfn
-
-#define DEPTH 8
-#include "omap_lcd_template.h"
-#define DEPTH 15
-#include "omap_lcd_template.h"
-#define DEPTH 16
-#include "omap_lcd_template.h"
-#define DEPTH 32
-#include "omap_lcd_template.h"
-
-static draw_line_func draw_line_table2[33] = {
- [0 ... 32] = NULL,
- [8] = draw_line2_8,
- [15] = draw_line2_15,
- [16] = draw_line2_16,
- [32] = draw_line2_32,
-}, draw_line_table4[33] = {
- [0 ... 32] = NULL,
- [8] = draw_line4_8,
- [15] = draw_line4_15,
- [16] = draw_line4_16,
- [32] = draw_line4_32,
-}, draw_line_table8[33] = {
- [0 ... 32] = NULL,
- [8] = draw_line8_8,
- [15] = draw_line8_15,
- [16] = draw_line8_16,
- [32] = draw_line8_32,
-}, draw_line_table12[33] = {
- [0 ... 32] = NULL,
- [8] = draw_line12_8,
- [15] = draw_line12_15,
- [16] = draw_line12_16,
- [32] = draw_line12_32,
-}, draw_line_table16[33] = {
- [0 ... 32] = NULL,
- [8] = draw_line16_8,
- [15] = draw_line16_15,
- [16] = draw_line16_16,
- [32] = draw_line16_32,
-};
-
-static void omap_update_display(void *opaque)
-{
- struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
- draw_line_func draw_line;
- int size, height, first, last;
- int width, linesize, step, bpp, frame_offset;
- hwaddr frame_base;
-
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
- !surface_bits_per_pixel(surface)) {
- return;
- }
-
- frame_offset = 0;
- if (omap_lcd->plm != 2) {
- cpu_physical_memory_read(omap_lcd->dma->phys_framebuffer[
- omap_lcd->dma->current_frame],
- (void *)omap_lcd->palette, 0x200);
- switch (omap_lcd->palette[0] >> 12 & 7) {
- case 3 ... 7:
- frame_offset += 0x200;
- break;
- default:
- frame_offset += 0x20;
- }
- }
-
- /* Colour depth */
- switch ((omap_lcd->palette[0] >> 12) & 7) {
- case 1:
- draw_line = draw_line_table2[surface_bits_per_pixel(surface)];
- bpp = 2;
- break;
-
- case 2:
- draw_line = draw_line_table4[surface_bits_per_pixel(surface)];
- bpp = 4;
- break;
-
- case 3:
- draw_line = draw_line_table8[surface_bits_per_pixel(surface)];
- bpp = 8;
- break;
-
- case 4 ... 7:
- if (!omap_lcd->tft)
- draw_line = draw_line_table12[surface_bits_per_pixel(surface)];
- else
- draw_line = draw_line_table16[surface_bits_per_pixel(surface)];
- bpp = 16;
- break;
-
- default:
- /* Unsupported at the moment. */
- return;
- }
-
- /* Resolution */
- width = omap_lcd->width;
- if (width != surface_width(surface) ||
- omap_lcd->height != surface_height(surface)) {
- qemu_console_resize(omap_lcd->con,
- omap_lcd->width, omap_lcd->height);
- surface = qemu_console_surface(omap_lcd->con);
- omap_lcd->invalidate = 1;
- }
-
- if (omap_lcd->dma->current_frame == 0)
- size = omap_lcd->dma->src_f1_bottom - omap_lcd->dma->src_f1_top;
- else
- size = omap_lcd->dma->src_f2_bottom - omap_lcd->dma->src_f2_top;
-
- if (frame_offset + ((width * omap_lcd->height * bpp) >> 3) > size + 2) {
- omap_lcd->sync_error = 1;
- omap_lcd_interrupts(omap_lcd);
- omap_lcd->enable = 0;
- return;
- }
-
- /* Content */
- frame_base = omap_lcd->dma->phys_framebuffer[
- omap_lcd->dma->current_frame] + frame_offset;
- omap_lcd->dma->condition |= 1 << omap_lcd->dma->current_frame;
- if (omap_lcd->dma->interrupts & 1)
- qemu_irq_raise(omap_lcd->dma->irq);
- if (omap_lcd->dma->dual)
- omap_lcd->dma->current_frame ^= 1;
-
- if (!surface_bits_per_pixel(surface)) {
- return;
- }
-
- first = 0;
- height = omap_lcd->height;
- if (omap_lcd->subpanel & (1 << 31)) {
- if (omap_lcd->subpanel & (1 << 29))
- first = (omap_lcd->subpanel >> 16) & 0x3ff;
- else
- height = (omap_lcd->subpanel >> 16) & 0x3ff;
- /* TODO: fill the rest of the panel with DPD */
- }
-
- step = width * bpp >> 3;
- linesize = surface_stride(surface);
- if (omap_lcd->invalidate) {
- framebuffer_update_memory_section(&omap_lcd->fbsection,
- omap_lcd->sysmem, frame_base,
- height, step);
- }
-
- framebuffer_update_display(surface, &omap_lcd->fbsection,
- width, height,
- step, linesize, 0,
- omap_lcd->invalidate,
- draw_line, omap_lcd->palette,
- &first, &last);
-
- if (first >= 0) {
- dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1);
- }
- omap_lcd->invalidate = 0;
-}
-
-static void omap_invalidate_display(void *opaque) {
- struct omap_lcd_panel_s *omap_lcd = opaque;
- omap_lcd->invalidate = 1;
-}
-
-static void omap_lcd_update(struct omap_lcd_panel_s *s) {
- if (!s->enable) {
- s->dma->current_frame = -1;
- s->sync_error = 0;
- if (s->plm != 1)
- s->frame_done = 1;
- omap_lcd_interrupts(s);
- return;
- }
-
- if (s->dma->current_frame == -1) {
- s->frame_done = 0;
- s->palette_done = 0;
- s->dma->current_frame = 0;
- }
-
- if (!s->dma->mpu->port[s->dma->src].addr_valid(s->dma->mpu,
- s->dma->src_f1_top) ||
- !s->dma->mpu->port[
- s->dma->src].addr_valid(s->dma->mpu,
- s->dma->src_f1_bottom) ||
- (s->dma->dual &&
- (!s->dma->mpu->port[
- s->dma->src].addr_valid(s->dma->mpu,
- s->dma->src_f2_top) ||
- !s->dma->mpu->port[
- s->dma->src].addr_valid(s->dma->mpu,
- s->dma->src_f2_bottom)))) {
- s->dma->condition |= 1 << 2;
- if (s->dma->interrupts & (1 << 1))
- qemu_irq_raise(s->dma->irq);
- s->enable = 0;
- return;
- }
-
- s->dma->phys_framebuffer[0] = s->dma->src_f1_top;
- s->dma->phys_framebuffer[1] = s->dma->src_f2_top;
-
- if (s->plm != 2 && !s->palette_done) {
- cpu_physical_memory_read(
- s->dma->phys_framebuffer[s->dma->current_frame],
- (void *)s->palette, 0x200);
- s->palette_done = 1;
- omap_lcd_interrupts(s);
- }
-}
-
-static uint64_t omap_lcdc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
-
- switch (addr) {
- case 0x00: /* LCD_CONTROL */
- return (s->tft << 23) | (s->plm << 20) |
- (s->tft << 7) | (s->interrupts << 3) |
- (s->mono << 1) | s->enable | s->ctrl | 0xfe000c34;
-
- case 0x04: /* LCD_TIMING0 */
- return (s->timing[0] << 10) | (s->width - 1) | 0x0000000f;
-
- case 0x08: /* LCD_TIMING1 */
- return (s->timing[1] << 10) | (s->height - 1);
-
- case 0x0c: /* LCD_TIMING2 */
- return s->timing[2] | 0xfc000000;
-
- case 0x10: /* LCD_STATUS */
- return (s->palette_done << 6) | (s->sync_error << 2) | s->frame_done;
-
- case 0x14: /* LCD_SUBPANEL */
- return s->subpanel;
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_lcdc_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
-
- switch (addr) {
- case 0x00: /* LCD_CONTROL */
- s->plm = (value >> 20) & 3;
- s->tft = (value >> 7) & 1;
- s->interrupts = (value >> 3) & 3;
- s->mono = (value >> 1) & 1;
- s->ctrl = value & 0x01cff300;
- if (s->enable != (value & 1)) {
- s->enable = value & 1;
- omap_lcd_update(s);
- }
- break;
-
- case 0x04: /* LCD_TIMING0 */
- s->timing[0] = value >> 10;
- s->width = (value & 0x3ff) + 1;
- break;
-
- case 0x08: /* LCD_TIMING1 */
- s->timing[1] = value >> 10;
- s->height = (value & 0x3ff) + 1;
- break;
-
- case 0x0c: /* LCD_TIMING2 */
- s->timing[2] = value;
- break;
-
- case 0x10: /* LCD_STATUS */
- break;
-
- case 0x14: /* LCD_SUBPANEL */
- s->subpanel = value & 0xa1ffffff;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_lcdc_ops = {
- .read = omap_lcdc_read,
- .write = omap_lcdc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-void omap_lcdc_reset(struct omap_lcd_panel_s *s)
-{
- s->dma->current_frame = -1;
- s->plm = 0;
- s->tft = 0;
- s->mono = 0;
- s->enable = 0;
- s->width = 0;
- s->height = 0;
- s->interrupts = 0;
- s->timing[0] = 0;
- s->timing[1] = 0;
- s->timing[2] = 0;
- s->subpanel = 0;
- s->palette_done = 0;
- s->frame_done = 0;
- s->sync_error = 0;
- s->invalidate = 1;
- s->subpanel = 0;
- s->ctrl = 0;
-}
-
-static const GraphicHwOps omap_ops = {
- .invalidate = omap_invalidate_display,
- .gfx_update = omap_update_display,
-};
-
-struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
- hwaddr base,
- qemu_irq irq,
- struct omap_dma_lcd_channel_s *dma,
- omap_clk clk)
-{
- struct omap_lcd_panel_s *s = g_new0(struct omap_lcd_panel_s, 1);
-
- s->irq = irq;
- s->dma = dma;
- s->sysmem = sysmem;
- omap_lcdc_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
- memory_region_add_subregion(sysmem, base, &s->iomem);
-
- s->con = graphic_console_init(NULL, 0, &omap_ops, s);
-
- return s;
-}
diff --git a/qemu/hw/display/pl110.c b/qemu/hw/display/pl110.c
deleted file mode 100644
index d589959f1..000000000
--- a/qemu/hw/display/pl110.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Arm PrimeCell PL110 Color LCD Controller
- *
- * Copyright (c) 2005-2009 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GNU LGPL
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "ui/console.h"
-#include "framebuffer.h"
-#include "ui/pixel_ops.h"
-
-#define PL110_CR_EN 0x001
-#define PL110_CR_BGR 0x100
-#define PL110_CR_BEBO 0x200
-#define PL110_CR_BEPO 0x400
-#define PL110_CR_PWR 0x800
-
-enum pl110_bppmode
-{
- BPP_1,
- BPP_2,
- BPP_4,
- BPP_8,
- BPP_16,
- BPP_32,
- BPP_16_565, /* PL111 only */
- BPP_12 /* PL111 only */
-};
-
-
-/* The Versatile/PB uses a slightly modified PL110 controller. */
-enum pl110_version
-{
- PL110,
- PL110_VERSATILE,
- PL111
-};
-
-#define TYPE_PL110 "pl110"
-#define PL110(obj) OBJECT_CHECK(PL110State, (obj), TYPE_PL110)
-
-typedef struct PL110State {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- MemoryRegionSection fbsection;
- QemuConsole *con;
-
- int version;
- uint32_t timing[4];
- uint32_t cr;
- uint32_t upbase;
- uint32_t lpbase;
- uint32_t int_status;
- uint32_t int_mask;
- int cols;
- int rows;
- enum pl110_bppmode bpp;
- int invalidate;
- uint32_t mux_ctrl;
- uint32_t palette[256];
- uint32_t raw_palette[128];
- qemu_irq irq;
-} PL110State;
-
-static int vmstate_pl110_post_load(void *opaque, int version_id);
-
-static const VMStateDescription vmstate_pl110 = {
- .name = "pl110",
- .version_id = 2,
- .minimum_version_id = 1,
- .post_load = vmstate_pl110_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(version, PL110State),
- VMSTATE_UINT32_ARRAY(timing, PL110State, 4),
- VMSTATE_UINT32(cr, PL110State),
- VMSTATE_UINT32(upbase, PL110State),
- VMSTATE_UINT32(lpbase, PL110State),
- VMSTATE_UINT32(int_status, PL110State),
- VMSTATE_UINT32(int_mask, PL110State),
- VMSTATE_INT32(cols, PL110State),
- VMSTATE_INT32(rows, PL110State),
- VMSTATE_UINT32(bpp, PL110State),
- VMSTATE_INT32(invalidate, PL110State),
- VMSTATE_UINT32_ARRAY(palette, PL110State, 256),
- VMSTATE_UINT32_ARRAY(raw_palette, PL110State, 128),
- VMSTATE_UINT32_V(mux_ctrl, PL110State, 2),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const unsigned char pl110_id[] =
-{ 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static const unsigned char pl111_id[] = {
- 0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1
-};
-
-
-/* Indexed by pl110_version */
-static const unsigned char *idregs[] = {
- pl110_id,
- /* The ARM documentation (DDI0224C) says the CLCDC on the Versatile board
- * has a different ID (0x93, 0x10, 0x04, 0x00, ...). However the hardware
- * itself has the same ID values as a stock PL110, and guests (in
- * particular Linux) rely on this. We emulate what the hardware does,
- * rather than what the docs claim it ought to do.
- */
- pl110_id,
- pl111_id
-};
-
-#define BITS 8
-#include "pl110_template.h"
-#define BITS 15
-#include "pl110_template.h"
-#define BITS 16
-#include "pl110_template.h"
-#define BITS 24
-#include "pl110_template.h"
-#define BITS 32
-#include "pl110_template.h"
-
-static int pl110_enabled(PL110State *s)
-{
- return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR);
-}
-
-static void pl110_update_display(void *opaque)
-{
- PL110State *s = (PL110State *)opaque;
- SysBusDevice *sbd;
- DisplaySurface *surface = qemu_console_surface(s->con);
- drawfn* fntable;
- drawfn fn;
- int dest_width;
- int src_width;
- int bpp_offset;
- int first;
- int last;
-
- if (!pl110_enabled(s)) {
- return;
- }
-
- sbd = SYS_BUS_DEVICE(s);
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 8:
- fntable = pl110_draw_fn_8;
- dest_width = 1;
- break;
- case 15:
- fntable = pl110_draw_fn_15;
- dest_width = 2;
- break;
- case 16:
- fntable = pl110_draw_fn_16;
- dest_width = 2;
- break;
- case 24:
- fntable = pl110_draw_fn_24;
- dest_width = 3;
- break;
- case 32:
- fntable = pl110_draw_fn_32;
- dest_width = 4;
- break;
- default:
- fprintf(stderr, "pl110: Bad color depth\n");
- exit(1);
- }
- if (s->cr & PL110_CR_BGR)
- bpp_offset = 0;
- else
- bpp_offset = 24;
-
- if ((s->version != PL111) && (s->bpp == BPP_16)) {
- /* The PL110's native 16 bit mode is 5551; however
- * most boards with a PL110 implement an external
- * mux which allows bits to be reshuffled to give
- * 565 format. The mux is typically controlled by
- * an external system register.
- * This is controlled by a GPIO input pin
- * so boards can wire it up to their register.
- *
- * The PL111 straightforwardly implements both
- * 5551 and 565 under control of the bpp field
- * in the LCDControl register.
- */
- switch (s->mux_ctrl) {
- case 3: /* 565 BGR */
- bpp_offset = (BPP_16_565 - BPP_16);
- break;
- case 1: /* 5551 */
- break;
- case 0: /* 888; also if we have loaded vmstate from an old version */
- case 2: /* 565 RGB */
- default:
- /* treat as 565 but honour BGR bit */
- bpp_offset += (BPP_16_565 - BPP_16);
- break;
- }
- }
-
- if (s->cr & PL110_CR_BEBO)
- fn = fntable[s->bpp + 8 + bpp_offset];
- else if (s->cr & PL110_CR_BEPO)
- fn = fntable[s->bpp + 16 + bpp_offset];
- else
- fn = fntable[s->bpp + bpp_offset];
-
- src_width = s->cols;
- switch (s->bpp) {
- case BPP_1:
- src_width >>= 3;
- break;
- case BPP_2:
- src_width >>= 2;
- break;
- case BPP_4:
- src_width >>= 1;
- break;
- case BPP_8:
- break;
- case BPP_16:
- case BPP_16_565:
- case BPP_12:
- src_width <<= 1;
- break;
- case BPP_32:
- src_width <<= 2;
- break;
- }
- dest_width *= s->cols;
- first = 0;
- if (s->invalidate) {
- framebuffer_update_memory_section(&s->fbsection,
- sysbus_address_space(sbd),
- s->upbase,
- s->rows, src_width);
- }
-
- framebuffer_update_display(surface, &s->fbsection,
- s->cols, s->rows,
- src_width, dest_width, 0,
- s->invalidate,
- fn, s->palette,
- &first, &last);
-
- if (first >= 0) {
- dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
- }
- s->invalidate = 0;
-}
-
-static void pl110_invalidate_display(void * opaque)
-{
- PL110State *s = (PL110State *)opaque;
- s->invalidate = 1;
- if (pl110_enabled(s)) {
- qemu_console_resize(s->con, s->cols, s->rows);
- }
-}
-
-static void pl110_update_palette(PL110State *s, int n)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i;
- uint32_t raw;
- unsigned int r, g, b;
-
- raw = s->raw_palette[n];
- n <<= 1;
- for (i = 0; i < 2; i++) {
- r = (raw & 0x1f) << 3;
- raw >>= 5;
- g = (raw & 0x1f) << 3;
- raw >>= 5;
- b = (raw & 0x1f) << 3;
- /* The I bit is ignored. */
- raw >>= 6;
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- s->palette[n] = rgb_to_pixel8(r, g, b);
- break;
- case 15:
- s->palette[n] = rgb_to_pixel15(r, g, b);
- break;
- case 16:
- s->palette[n] = rgb_to_pixel16(r, g, b);
- break;
- case 24:
- case 32:
- s->palette[n] = rgb_to_pixel32(r, g, b);
- break;
- }
- n++;
- }
-}
-
-static void pl110_resize(PL110State *s, int width, int height)
-{
- if (width != s->cols || height != s->rows) {
- if (pl110_enabled(s)) {
- qemu_console_resize(s->con, width, height);
- }
- }
- s->cols = width;
- s->rows = height;
-}
-
-/* Update interrupts. */
-static void pl110_update(PL110State *s)
-{
- /* TODO: Implement interrupts. */
-}
-
-static uint64_t pl110_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PL110State *s = (PL110State *)opaque;
-
- if (offset >= 0xfe0 && offset < 0x1000) {
- return idregs[s->version][(offset - 0xfe0) >> 2];
- }
- if (offset >= 0x200 && offset < 0x400) {
- return s->raw_palette[(offset - 0x200) >> 2];
- }
- switch (offset >> 2) {
- case 0: /* LCDTiming0 */
- return s->timing[0];
- case 1: /* LCDTiming1 */
- return s->timing[1];
- case 2: /* LCDTiming2 */
- return s->timing[2];
- case 3: /* LCDTiming3 */
- return s->timing[3];
- case 4: /* LCDUPBASE */
- return s->upbase;
- case 5: /* LCDLPBASE */
- return s->lpbase;
- case 6: /* LCDIMSC */
- if (s->version != PL110) {
- return s->cr;
- }
- return s->int_mask;
- case 7: /* LCDControl */
- if (s->version != PL110) {
- return s->int_mask;
- }
- return s->cr;
- case 8: /* LCDRIS */
- return s->int_status;
- case 9: /* LCDMIS */
- return s->int_status & s->int_mask;
- case 11: /* LCDUPCURR */
- /* TODO: Implement vertical refresh. */
- return s->upbase;
- case 12: /* LCDLPCURR */
- return s->lpbase;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl110_read: Bad offset %x\n", (int)offset);
- return 0;
- }
-}
-
-static void pl110_write(void *opaque, hwaddr offset,
- uint64_t val, unsigned size)
-{
- PL110State *s = (PL110State *)opaque;
- int n;
-
- /* For simplicity invalidate the display whenever a control register
- is written to. */
- s->invalidate = 1;
- if (offset >= 0x200 && offset < 0x400) {
- /* Palette. */
- n = (offset - 0x200) >> 2;
- s->raw_palette[(offset - 0x200) >> 2] = val;
- pl110_update_palette(s, n);
- return;
- }
- switch (offset >> 2) {
- case 0: /* LCDTiming0 */
- s->timing[0] = val;
- n = ((val & 0xfc) + 4) * 4;
- pl110_resize(s, n, s->rows);
- break;
- case 1: /* LCDTiming1 */
- s->timing[1] = val;
- n = (val & 0x3ff) + 1;
- pl110_resize(s, s->cols, n);
- break;
- case 2: /* LCDTiming2 */
- s->timing[2] = val;
- break;
- case 3: /* LCDTiming3 */
- s->timing[3] = val;
- break;
- case 4: /* LCDUPBASE */
- s->upbase = val;
- break;
- case 5: /* LCDLPBASE */
- s->lpbase = val;
- break;
- case 6: /* LCDIMSC */
- if (s->version != PL110) {
- goto control;
- }
- imsc:
- s->int_mask = val;
- pl110_update(s);
- break;
- case 7: /* LCDControl */
- if (s->version != PL110) {
- goto imsc;
- }
- control:
- s->cr = val;
- s->bpp = (val >> 1) & 7;
- if (pl110_enabled(s)) {
- qemu_console_resize(s->con, s->cols, s->rows);
- }
- break;
- case 10: /* LCDICR */
- s->int_status &= ~val;
- pl110_update(s);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl110_write: Bad offset %x\n", (int)offset);
- }
-}
-
-static const MemoryRegionOps pl110_ops = {
- .read = pl110_read,
- .write = pl110_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void pl110_mux_ctrl_set(void *opaque, int line, int level)
-{
- PL110State *s = (PL110State *)opaque;
- s->mux_ctrl = level;
-}
-
-static int vmstate_pl110_post_load(void *opaque, int version_id)
-{
- PL110State *s = opaque;
- /* Make sure we redraw, and at the right size */
- pl110_invalidate_display(s);
- return 0;
-}
-
-static const GraphicHwOps pl110_gfx_ops = {
- .invalidate = pl110_invalidate_display,
- .gfx_update = pl110_update_display,
-};
-
-static int pl110_initfn(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- PL110State *s = PL110(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq);
- qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
- s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
- return 0;
-}
-
-static void pl110_init(Object *obj)
-{
- PL110State *s = PL110(obj);
-
- s->version = PL110;
-}
-
-static void pl110_versatile_init(Object *obj)
-{
- PL110State *s = PL110(obj);
-
- s->version = PL110_VERSATILE;
-}
-
-static void pl111_init(Object *obj)
-{
- PL110State *s = PL110(obj);
-
- s->version = PL111;
-}
-
-static void pl110_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = pl110_initfn;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->vmsd = &vmstate_pl110;
-}
-
-static const TypeInfo pl110_info = {
- .name = TYPE_PL110,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PL110State),
- .instance_init = pl110_init,
- .class_init = pl110_class_init,
-};
-
-static const TypeInfo pl110_versatile_info = {
- .name = "pl110_versatile",
- .parent = TYPE_PL110,
- .instance_init = pl110_versatile_init,
-};
-
-static const TypeInfo pl111_info = {
- .name = "pl111",
- .parent = TYPE_PL110,
- .instance_init = pl111_init,
-};
-
-static void pl110_register_types(void)
-{
- type_register_static(&pl110_info);
- type_register_static(&pl110_versatile_info);
- type_register_static(&pl111_info);
-}
-
-type_init(pl110_register_types)
diff --git a/qemu/hw/display/pl110_template.h b/qemu/hw/display/pl110_template.h
deleted file mode 100644
index 36ba791c6..000000000
--- a/qemu/hw/display/pl110_template.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Arm PrimeCell PL110 Color LCD Controller
- *
- * Copyright (c) 2005 CodeSourcery, LLC.
- * Written by Paul Brook
- *
- * This code is licensed under the GNU LGPL
- *
- * Framebuffer format conversion routines.
- */
-
-#ifndef ORDER
-
-#if BITS == 8
-#define COPY_PIXEL(to, from) *(to++) = from
-#elif BITS == 15 || BITS == 16
-#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
-#elif BITS == 24
-#define COPY_PIXEL(to, from) \
- do { \
- *(to++) = from; \
- *(to++) = (from) >> 8; \
- *(to++) = (from) >> 16; \
- } while (0)
-#elif BITS == 32
-#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
-#else
-#error unknown bit depth
-#endif
-
-#undef RGB
-#define BORDER bgr
-#define ORDER 0
-#include "pl110_template.h"
-#define ORDER 1
-#include "pl110_template.h"
-#define ORDER 2
-#include "pl110_template.h"
-#undef BORDER
-#define RGB
-#define BORDER rgb
-#define ORDER 0
-#include "pl110_template.h"
-#define ORDER 1
-#include "pl110_template.h"
-#define ORDER 2
-#include "pl110_template.h"
-#undef BORDER
-
-static drawfn glue(pl110_draw_fn_,BITS)[48] =
-{
- glue(pl110_draw_line1_lblp_bgr,BITS),
- glue(pl110_draw_line2_lblp_bgr,BITS),
- glue(pl110_draw_line4_lblp_bgr,BITS),
- glue(pl110_draw_line8_lblp_bgr,BITS),
- glue(pl110_draw_line16_555_lblp_bgr,BITS),
- glue(pl110_draw_line32_lblp_bgr,BITS),
- glue(pl110_draw_line16_lblp_bgr,BITS),
- glue(pl110_draw_line12_lblp_bgr,BITS),
-
- glue(pl110_draw_line1_bbbp_bgr,BITS),
- glue(pl110_draw_line2_bbbp_bgr,BITS),
- glue(pl110_draw_line4_bbbp_bgr,BITS),
- glue(pl110_draw_line8_bbbp_bgr,BITS),
- glue(pl110_draw_line16_555_bbbp_bgr,BITS),
- glue(pl110_draw_line32_bbbp_bgr,BITS),
- glue(pl110_draw_line16_bbbp_bgr,BITS),
- glue(pl110_draw_line12_bbbp_bgr,BITS),
-
- glue(pl110_draw_line1_lbbp_bgr,BITS),
- glue(pl110_draw_line2_lbbp_bgr,BITS),
- glue(pl110_draw_line4_lbbp_bgr,BITS),
- glue(pl110_draw_line8_lbbp_bgr,BITS),
- glue(pl110_draw_line16_555_lbbp_bgr,BITS),
- glue(pl110_draw_line32_lbbp_bgr,BITS),
- glue(pl110_draw_line16_lbbp_bgr,BITS),
- glue(pl110_draw_line12_lbbp_bgr,BITS),
-
- glue(pl110_draw_line1_lblp_rgb,BITS),
- glue(pl110_draw_line2_lblp_rgb,BITS),
- glue(pl110_draw_line4_lblp_rgb,BITS),
- glue(pl110_draw_line8_lblp_rgb,BITS),
- glue(pl110_draw_line16_555_lblp_rgb,BITS),
- glue(pl110_draw_line32_lblp_rgb,BITS),
- glue(pl110_draw_line16_lblp_rgb,BITS),
- glue(pl110_draw_line12_lblp_rgb,BITS),
-
- glue(pl110_draw_line1_bbbp_rgb,BITS),
- glue(pl110_draw_line2_bbbp_rgb,BITS),
- glue(pl110_draw_line4_bbbp_rgb,BITS),
- glue(pl110_draw_line8_bbbp_rgb,BITS),
- glue(pl110_draw_line16_555_bbbp_rgb,BITS),
- glue(pl110_draw_line32_bbbp_rgb,BITS),
- glue(pl110_draw_line16_bbbp_rgb,BITS),
- glue(pl110_draw_line12_bbbp_rgb,BITS),
-
- glue(pl110_draw_line1_lbbp_rgb,BITS),
- glue(pl110_draw_line2_lbbp_rgb,BITS),
- glue(pl110_draw_line4_lbbp_rgb,BITS),
- glue(pl110_draw_line8_lbbp_rgb,BITS),
- glue(pl110_draw_line16_555_lbbp_rgb,BITS),
- glue(pl110_draw_line32_lbbp_rgb,BITS),
- glue(pl110_draw_line16_lbbp_rgb,BITS),
- glue(pl110_draw_line12_lbbp_rgb,BITS),
-};
-
-#undef BITS
-#undef COPY_PIXEL
-
-#else
-
-#if ORDER == 0
-#define NAME glue(glue(lblp_, BORDER), BITS)
-#ifdef HOST_WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#elif ORDER == 1
-#define NAME glue(glue(bbbp_, BORDER), BITS)
-#ifndef HOST_WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#else
-#define SWAP_PIXELS 1
-#define NAME glue(glue(lbbp_, BORDER), BITS)
-#ifdef HOST_WORDS_BIGENDIAN
-#define SWAP_WORDS 1
-#endif
-#endif
-
-#define FN_2(x, y) FN(x, y) FN(x+1, y)
-#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
-#define FN_8(y) FN_4(0, y) FN_4(4, y)
-
-static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
-#else
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
-#endif
-#ifdef SWAP_WORDS
- FN_8(24)
- FN_8(16)
- FN_8(8)
- FN_8(0)
-#else
- FN_8(0)
- FN_8(8)
- FN_8(16)
- FN_8(24)
-#endif
-#undef FN
- width -= 32;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
-#else
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
-#endif
-#ifdef SWAP_WORDS
- FN_4(0, 24)
- FN_4(0, 16)
- FN_4(0, 8)
- FN_4(0, 0)
-#else
- FN_4(0, 0)
- FN_4(0, 8)
- FN_4(0, 16)
- FN_4(0, 24)
-#endif
-#undef FN
- width -= 16;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_PIXELS
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
-#else
-#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
-#endif
-#ifdef SWAP_WORDS
- FN_2(0, 24)
- FN_2(0, 16)
- FN_2(0, 8)
- FN_2(0, 0)
-#else
- FN_2(0, 0)
- FN_2(0, 8)
- FN_2(0, 16)
- FN_2(0, 24)
-#endif
-#undef FN
- width -= 8;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *)src;
-#define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
-#ifdef SWAP_WORDS
- FN(24)
- FN(16)
- FN(8)
- FN(0)
-#else
- FN(0)
- FN(8)
- FN(16)
- FN(24)
-#endif
-#undef FN
- width -= 4;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
-#ifdef RGB
-#define LSB r
-#define MSB b
-#else
-#define LSB b
-#define MSB r
-#endif
-#if 0
- LSB = data & 0x1f;
- data >>= 5;
- g = data & 0x3f;
- data >>= 6;
- MSB = data & 0x1f;
- data >>= 5;
-#else
- LSB = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- MSB = (data & 0x1f) << 3;
- data >>= 5;
-#endif
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- LSB = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- MSB = (data & 0x1f) << 3;
- data >>= 5;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
-#undef MSB
-#undef LSB
- width -= 2;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef RGB
-#define LSB r
-#define MSB b
-#else
-#define LSB b
-#define MSB r
-#endif
-#ifndef SWAP_WORDS
- LSB = data & 0xff;
- g = (data >> 8) & 0xff;
- MSB = (data >> 16) & 0xff;
-#else
- LSB = (data >> 24) & 0xff;
- g = (data >> 16) & 0xff;
- MSB = (data >> 8) & 0xff;
-#endif
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
-#undef MSB
-#undef LSB
- width--;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- /* RGB 555 plus an intensity bit (which we ignore) */
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
-#ifdef RGB
-#define LSB r
-#define MSB b
-#else
-#define LSB b
-#define MSB r
-#endif
- LSB = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x1f) << 3;
- data >>= 5;
- MSB = (data & 0x1f) << 3;
- data >>= 5;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- LSB = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x1f) << 3;
- data >>= 5;
- MSB = (data & 0x1f) << 3;
- data >>= 6;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
-#undef MSB
-#undef LSB
- width -= 2;
- src += 4;
- }
-}
-
-static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
-{
- /* RGB 444 with 4 bits of zeroes at the top of each halfword */
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *)src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
-#ifdef RGB
-#define LSB r
-#define MSB b
-#else
-#define LSB b
-#define MSB r
-#endif
- LSB = (data & 0xf) << 4;
- data >>= 4;
- g = (data & 0xf) << 4;
- data >>= 4;
- MSB = (data & 0xf) << 4;
- data >>= 8;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
- LSB = (data & 0xf) << 4;
- data >>= 4;
- g = (data & 0xf) << 4;
- data >>= 4;
- MSB = (data & 0xf) << 4;
- data >>= 8;
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
-#undef MSB
-#undef LSB
- width -= 2;
- src += 4;
- }
-}
-
-#undef SWAP_PIXELS
-#undef NAME
-#undef SWAP_WORDS
-#undef ORDER
-
-#endif
diff --git a/qemu/hw/display/pxa2xx_lcd.c b/qemu/hw/display/pxa2xx_lcd.c
deleted file mode 100644
index 845521c5b..000000000
--- a/qemu/hw/display/pxa2xx_lcd.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*
- * Intel XScale PXA255/270 LCDC emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GPLv2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/arm/pxa.h"
-#include "ui/pixel_ops.h"
-/* FIXME: For graphic_rotate. Should probably be done in common code. */
-#include "sysemu/sysemu.h"
-#include "framebuffer.h"
-
-struct DMAChannel {
- uint32_t branch;
- uint8_t up;
- uint8_t palette[1024];
- uint8_t pbuffer[1024];
- void (*redraw)(PXA2xxLCDState *s, hwaddr addr,
- int *miny, int *maxy);
-
- uint32_t descriptor;
- uint32_t source;
- uint32_t id;
- uint32_t command;
-};
-
-struct PXA2xxLCDState {
- MemoryRegion *sysmem;
- MemoryRegion iomem;
- MemoryRegionSection fbsection;
- qemu_irq irq;
- int irqlevel;
-
- int invalidated;
- QemuConsole *con;
- drawfn *line_fn[2];
- int dest_width;
- int xres, yres;
- int pal_for;
- int transp;
- enum {
- pxa_lcdc_2bpp = 1,
- pxa_lcdc_4bpp = 2,
- pxa_lcdc_8bpp = 3,
- pxa_lcdc_16bpp = 4,
- pxa_lcdc_18bpp = 5,
- pxa_lcdc_18pbpp = 6,
- pxa_lcdc_19bpp = 7,
- pxa_lcdc_19pbpp = 8,
- pxa_lcdc_24bpp = 9,
- pxa_lcdc_25bpp = 10,
- } bpp;
-
- uint32_t control[6];
- uint32_t status[2];
- uint32_t ovl1c[2];
- uint32_t ovl2c[2];
- uint32_t ccr;
- uint32_t cmdcr;
- uint32_t trgbr;
- uint32_t tcr;
- uint32_t liidr;
- uint8_t bscntr;
-
- struct DMAChannel dma_ch[7];
-
- qemu_irq vsync_cb;
- int orientation;
-};
-
-typedef struct QEMU_PACKED {
- uint32_t fdaddr;
- uint32_t fsaddr;
- uint32_t fidr;
- uint32_t ldcmd;
-} PXAFrameDescriptor;
-
-#define LCCR0 0x000 /* LCD Controller Control register 0 */
-#define LCCR1 0x004 /* LCD Controller Control register 1 */
-#define LCCR2 0x008 /* LCD Controller Control register 2 */
-#define LCCR3 0x00c /* LCD Controller Control register 3 */
-#define LCCR4 0x010 /* LCD Controller Control register 4 */
-#define LCCR5 0x014 /* LCD Controller Control register 5 */
-
-#define FBR0 0x020 /* DMA Channel 0 Frame Branch register */
-#define FBR1 0x024 /* DMA Channel 1 Frame Branch register */
-#define FBR2 0x028 /* DMA Channel 2 Frame Branch register */
-#define FBR3 0x02c /* DMA Channel 3 Frame Branch register */
-#define FBR4 0x030 /* DMA Channel 4 Frame Branch register */
-#define FBR5 0x110 /* DMA Channel 5 Frame Branch register */
-#define FBR6 0x114 /* DMA Channel 6 Frame Branch register */
-
-#define LCSR1 0x034 /* LCD Controller Status register 1 */
-#define LCSR0 0x038 /* LCD Controller Status register 0 */
-#define LIIDR 0x03c /* LCD Controller Interrupt ID register */
-
-#define TRGBR 0x040 /* TMED RGB Seed register */
-#define TCR 0x044 /* TMED Control register */
-
-#define OVL1C1 0x050 /* Overlay 1 Control register 1 */
-#define OVL1C2 0x060 /* Overlay 1 Control register 2 */
-#define OVL2C1 0x070 /* Overlay 2 Control register 1 */
-#define OVL2C2 0x080 /* Overlay 2 Control register 2 */
-#define CCR 0x090 /* Cursor Control register */
-
-#define CMDCR 0x100 /* Command Control register */
-#define PRSR 0x104 /* Panel Read Status register */
-
-#define PXA_LCDDMA_CHANS 7
-#define DMA_FDADR 0x00 /* Frame Descriptor Address register */
-#define DMA_FSADR 0x04 /* Frame Source Address register */
-#define DMA_FIDR 0x08 /* Frame ID register */
-#define DMA_LDCMD 0x0c /* Command register */
-
-/* LCD Buffer Strength Control register */
-#define BSCNTR 0x04000054
-
-/* Bitfield masks */
-#define LCCR0_ENB (1 << 0)
-#define LCCR0_CMS (1 << 1)
-#define LCCR0_SDS (1 << 2)
-#define LCCR0_LDM (1 << 3)
-#define LCCR0_SOFM0 (1 << 4)
-#define LCCR0_IUM (1 << 5)
-#define LCCR0_EOFM0 (1 << 6)
-#define LCCR0_PAS (1 << 7)
-#define LCCR0_DPD (1 << 9)
-#define LCCR0_DIS (1 << 10)
-#define LCCR0_QDM (1 << 11)
-#define LCCR0_PDD (0xff << 12)
-#define LCCR0_BSM0 (1 << 20)
-#define LCCR0_OUM (1 << 21)
-#define LCCR0_LCDT (1 << 22)
-#define LCCR0_RDSTM (1 << 23)
-#define LCCR0_CMDIM (1 << 24)
-#define LCCR0_OUC (1 << 25)
-#define LCCR0_LDDALT (1 << 26)
-#define LCCR1_PPL(x) ((x) & 0x3ff)
-#define LCCR2_LPP(x) ((x) & 0x3ff)
-#define LCCR3_API (15 << 16)
-#define LCCR3_BPP(x) ((((x) >> 24) & 7) | (((x) >> 26) & 8))
-#define LCCR3_PDFOR(x) (((x) >> 30) & 3)
-#define LCCR4_K1(x) (((x) >> 0) & 7)
-#define LCCR4_K2(x) (((x) >> 3) & 7)
-#define LCCR4_K3(x) (((x) >> 6) & 7)
-#define LCCR4_PALFOR(x) (((x) >> 15) & 3)
-#define LCCR5_SOFM(ch) (1 << (ch - 1))
-#define LCCR5_EOFM(ch) (1 << (ch + 7))
-#define LCCR5_BSM(ch) (1 << (ch + 15))
-#define LCCR5_IUM(ch) (1 << (ch + 23))
-#define OVLC1_EN (1 << 31)
-#define CCR_CEN (1 << 31)
-#define FBR_BRA (1 << 0)
-#define FBR_BINT (1 << 1)
-#define FBR_SRCADDR (0xfffffff << 4)
-#define LCSR0_LDD (1 << 0)
-#define LCSR0_SOF0 (1 << 1)
-#define LCSR0_BER (1 << 2)
-#define LCSR0_ABC (1 << 3)
-#define LCSR0_IU0 (1 << 4)
-#define LCSR0_IU1 (1 << 5)
-#define LCSR0_OU (1 << 6)
-#define LCSR0_QD (1 << 7)
-#define LCSR0_EOF0 (1 << 8)
-#define LCSR0_BS0 (1 << 9)
-#define LCSR0_SINT (1 << 10)
-#define LCSR0_RDST (1 << 11)
-#define LCSR0_CMDINT (1 << 12)
-#define LCSR0_BERCH(x) (((x) & 7) << 28)
-#define LCSR1_SOF(ch) (1 << (ch - 1))
-#define LCSR1_EOF(ch) (1 << (ch + 7))
-#define LCSR1_BS(ch) (1 << (ch + 15))
-#define LCSR1_IU(ch) (1 << (ch + 23))
-#define LDCMD_LENGTH(x) ((x) & 0x001ffffc)
-#define LDCMD_EOFINT (1 << 21)
-#define LDCMD_SOFINT (1 << 22)
-#define LDCMD_PAL (1 << 26)
-
-/* Route internal interrupt lines to the global IC */
-static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
-{
- int level = 0;
- level |= (s->status[0] & LCSR0_LDD) && !(s->control[0] & LCCR0_LDM);
- level |= (s->status[0] & LCSR0_SOF0) && !(s->control[0] & LCCR0_SOFM0);
- level |= (s->status[0] & LCSR0_IU0) && !(s->control[0] & LCCR0_IUM);
- level |= (s->status[0] & LCSR0_IU1) && !(s->control[5] & LCCR5_IUM(1));
- level |= (s->status[0] & LCSR0_OU) && !(s->control[0] & LCCR0_OUM);
- level |= (s->status[0] & LCSR0_QD) && !(s->control[0] & LCCR0_QDM);
- level |= (s->status[0] & LCSR0_EOF0) && !(s->control[0] & LCCR0_EOFM0);
- level |= (s->status[0] & LCSR0_BS0) && !(s->control[0] & LCCR0_BSM0);
- level |= (s->status[0] & LCSR0_RDST) && !(s->control[0] & LCCR0_RDSTM);
- level |= (s->status[0] & LCSR0_CMDINT) && !(s->control[0] & LCCR0_CMDIM);
- level |= (s->status[1] & ~s->control[5]);
-
- qemu_set_irq(s->irq, !!level);
- s->irqlevel = level;
-}
-
-/* Set Branch Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
-{
- int unmasked;
- if (ch == 0) {
- s->status[0] |= LCSR0_BS0;
- unmasked = !(s->control[0] & LCCR0_BSM0);
- } else {
- s->status[1] |= LCSR1_BS(ch);
- unmasked = !(s->control[5] & LCCR5_BSM(ch));
- }
-
- if (unmasked) {
- if (s->irqlevel)
- s->status[0] |= LCSR0_SINT;
- else
- s->liidr = s->dma_ch[ch].id;
- }
-}
-
-/* Set Start Of Frame Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
-{
- int unmasked;
- if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
- return;
-
- if (ch == 0) {
- s->status[0] |= LCSR0_SOF0;
- unmasked = !(s->control[0] & LCCR0_SOFM0);
- } else {
- s->status[1] |= LCSR1_SOF(ch);
- unmasked = !(s->control[5] & LCCR5_SOFM(ch));
- }
-
- if (unmasked) {
- if (s->irqlevel)
- s->status[0] |= LCSR0_SINT;
- else
- s->liidr = s->dma_ch[ch].id;
- }
-}
-
-/* Set End Of Frame Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
-{
- int unmasked;
- if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
- return;
-
- if (ch == 0) {
- s->status[0] |= LCSR0_EOF0;
- unmasked = !(s->control[0] & LCCR0_EOFM0);
- } else {
- s->status[1] |= LCSR1_EOF(ch);
- unmasked = !(s->control[5] & LCCR5_EOFM(ch));
- }
-
- if (unmasked) {
- if (s->irqlevel)
- s->status[0] |= LCSR0_SINT;
- else
- s->liidr = s->dma_ch[ch].id;
- }
-}
-
-/* Set Bus Error Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
-{
- s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
- if (s->irqlevel)
- s->status[0] |= LCSR0_SINT;
- else
- s->liidr = s->dma_ch[ch].id;
-}
-
-/* Load new Frame Descriptors from DMA */
-static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
-{
- PXAFrameDescriptor desc;
- hwaddr descptr;
- int i;
-
- for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
- s->dma_ch[i].source = 0;
-
- if (!s->dma_ch[i].up)
- continue;
-
- if (s->dma_ch[i].branch & FBR_BRA) {
- descptr = s->dma_ch[i].branch & FBR_SRCADDR;
- if (s->dma_ch[i].branch & FBR_BINT)
- pxa2xx_dma_bs_set(s, i);
- s->dma_ch[i].branch &= ~FBR_BRA;
- } else
- descptr = s->dma_ch[i].descriptor;
-
- if (!((descptr >= PXA2XX_SDRAM_BASE && descptr +
- sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size) ||
- (descptr >= PXA2XX_INTERNAL_BASE && descptr + sizeof(desc) <=
- PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
- continue;
- }
-
- cpu_physical_memory_read(descptr, &desc, sizeof(desc));
- s->dma_ch[i].descriptor = le32_to_cpu(desc.fdaddr);
- s->dma_ch[i].source = le32_to_cpu(desc.fsaddr);
- s->dma_ch[i].id = le32_to_cpu(desc.fidr);
- s->dma_ch[i].command = le32_to_cpu(desc.ldcmd);
- }
-}
-
-static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- int ch;
-
- switch (offset) {
- case LCCR0:
- return s->control[0];
- case LCCR1:
- return s->control[1];
- case LCCR2:
- return s->control[2];
- case LCCR3:
- return s->control[3];
- case LCCR4:
- return s->control[4];
- case LCCR5:
- return s->control[5];
-
- case OVL1C1:
- return s->ovl1c[0];
- case OVL1C2:
- return s->ovl1c[1];
- case OVL2C1:
- return s->ovl2c[0];
- case OVL2C2:
- return s->ovl2c[1];
-
- case CCR:
- return s->ccr;
-
- case CMDCR:
- return s->cmdcr;
-
- case TRGBR:
- return s->trgbr;
- case TCR:
- return s->tcr;
-
- case 0x200 ... 0x1000: /* DMA per-channel registers */
- ch = (offset - 0x200) >> 4;
- if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
- goto fail;
-
- switch (offset & 0xf) {
- case DMA_FDADR:
- return s->dma_ch[ch].descriptor;
- case DMA_FSADR:
- return s->dma_ch[ch].source;
- case DMA_FIDR:
- return s->dma_ch[ch].id;
- case DMA_LDCMD:
- return s->dma_ch[ch].command;
- default:
- goto fail;
- }
-
- case FBR0:
- return s->dma_ch[0].branch;
- case FBR1:
- return s->dma_ch[1].branch;
- case FBR2:
- return s->dma_ch[2].branch;
- case FBR3:
- return s->dma_ch[3].branch;
- case FBR4:
- return s->dma_ch[4].branch;
- case FBR5:
- return s->dma_ch[5].branch;
- case FBR6:
- return s->dma_ch[6].branch;
-
- case BSCNTR:
- return s->bscntr;
-
- case PRSR:
- return 0;
-
- case LCSR0:
- return s->status[0];
- case LCSR1:
- return s->status[1];
- case LIIDR:
- return s->liidr;
-
- default:
- fail:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-
- return 0;
-}
-
-static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- int ch;
-
- switch (offset) {
- case LCCR0:
- /* ACK Quick Disable done */
- 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", __FUNCTION__);
-
- if ((s->control[3] & LCCR3_API) &&
- (value & LCCR0_ENB) && !(value & LCCR0_LCDT))
- s->status[0] |= LCSR0_ABC;
-
- s->control[0] = value & 0x07ffffff;
- pxa2xx_lcdc_int_update(s);
-
- s->dma_ch[0].up = !!(value & LCCR0_ENB);
- s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS);
- break;
-
- case LCCR1:
- s->control[1] = value;
- break;
-
- case LCCR2:
- s->control[2] = value;
- break;
-
- case LCCR3:
- s->control[3] = value & 0xefffffff;
- s->bpp = LCCR3_BPP(value);
- break;
-
- case LCCR4:
- s->control[4] = value & 0x83ff81ff;
- break;
-
- case LCCR5:
- s->control[5] = value & 0x3f3f3f3f;
- break;
-
- case OVL1C1:
- if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN))
- printf("%s: Overlay 1 not supported\n", __FUNCTION__);
-
- s->ovl1c[0] = value & 0x80ffffff;
- s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS);
- break;
-
- case OVL1C2:
- s->ovl1c[1] = value & 0x000fffff;
- break;
-
- case OVL2C1:
- if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN))
- printf("%s: Overlay 2 not supported\n", __FUNCTION__);
-
- s->ovl2c[0] = value & 0x80ffffff;
- s->dma_ch[2].up = !!(value & OVLC1_EN);
- s->dma_ch[3].up = !!(value & OVLC1_EN);
- s->dma_ch[4].up = !!(value & OVLC1_EN);
- break;
-
- case OVL2C2:
- s->ovl2c[1] = value & 0x007fffff;
- break;
-
- case CCR:
- if (!(s->ccr & CCR_CEN) && (value & CCR_CEN))
- printf("%s: Hardware cursor unimplemented\n", __FUNCTION__);
-
- s->ccr = value & 0x81ffffe7;
- s->dma_ch[5].up = !!(value & CCR_CEN);
- break;
-
- case CMDCR:
- s->cmdcr = value & 0xff;
- break;
-
- case TRGBR:
- s->trgbr = value & 0x00ffffff;
- break;
-
- case TCR:
- s->tcr = value & 0x7fff;
- break;
-
- case 0x200 ... 0x1000: /* DMA per-channel registers */
- ch = (offset - 0x200) >> 4;
- if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
- goto fail;
-
- switch (offset & 0xf) {
- case DMA_FDADR:
- s->dma_ch[ch].descriptor = value & 0xfffffff0;
- break;
-
- default:
- goto fail;
- }
- break;
-
- case FBR0:
- s->dma_ch[0].branch = value & 0xfffffff3;
- break;
- case FBR1:
- s->dma_ch[1].branch = value & 0xfffffff3;
- break;
- case FBR2:
- s->dma_ch[2].branch = value & 0xfffffff3;
- break;
- case FBR3:
- s->dma_ch[3].branch = value & 0xfffffff3;
- break;
- case FBR4:
- s->dma_ch[4].branch = value & 0xfffffff3;
- break;
- case FBR5:
- s->dma_ch[5].branch = value & 0xfffffff3;
- break;
- case FBR6:
- s->dma_ch[6].branch = value & 0xfffffff3;
- break;
-
- case BSCNTR:
- s->bscntr = value & 0xf;
- break;
-
- case PRSR:
- break;
-
- case LCSR0:
- s->status[0] &= ~(value & 0xfff);
- if (value & LCSR0_BER)
- s->status[0] &= ~LCSR0_BERCH(7);
- break;
-
- case LCSR1:
- s->status[1] &= ~(value & 0x3e3f3f);
- break;
-
- default:
- fail:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-}
-
-static const MemoryRegionOps pxa2xx_lcdc_ops = {
- .read = pxa2xx_lcdc_read,
- .write = pxa2xx_lcdc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-/* Load new palette for a given DMA channel, convert to internal format */
-static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i, n, format, r, g, b, alpha;
- uint32_t *dest;
- uint8_t *src;
- s->pal_for = LCCR4_PALFOR(s->control[4]);
- format = s->pal_for;
-
- switch (bpp) {
- case pxa_lcdc_2bpp:
- n = 4;
- break;
- case pxa_lcdc_4bpp:
- n = 16;
- break;
- case pxa_lcdc_8bpp:
- n = 256;
- break;
- default:
- format = 0;
- return;
- }
-
- src = (uint8_t *) s->dma_ch[ch].pbuffer;
- dest = (uint32_t *) s->dma_ch[ch].palette;
- alpha = r = g = b = 0;
-
- for (i = 0; i < n; i ++) {
- switch (format) {
- case 0: /* 16 bpp, no transparency */
- alpha = 0;
- if (s->control[0] & LCCR0_CMS) {
- r = g = b = *(uint16_t *) src & 0xff;
- }
- else {
- r = (*(uint16_t *) src & 0xf800) >> 8;
- g = (*(uint16_t *) src & 0x07e0) >> 3;
- b = (*(uint16_t *) src & 0x001f) << 3;
- }
- src += 2;
- break;
- case 1: /* 16 bpp plus transparency */
- alpha = *(uint32_t *) src & (1 << 24);
- if (s->control[0] & LCCR0_CMS)
- r = g = b = *(uint32_t *) src & 0xff;
- else {
- r = (*(uint32_t *) src & 0xf80000) >> 16;
- g = (*(uint32_t *) src & 0x00fc00) >> 8;
- b = (*(uint32_t *) src & 0x0000f8);
- }
- src += 4;
- break;
- case 2: /* 18 bpp plus transparency */
- alpha = *(uint32_t *) src & (1 << 24);
- if (s->control[0] & LCCR0_CMS)
- r = g = b = *(uint32_t *) src & 0xff;
- else {
- r = (*(uint32_t *) src & 0xfc0000) >> 16;
- g = (*(uint32_t *) src & 0x00fc00) >> 8;
- b = (*(uint32_t *) src & 0x0000fc);
- }
- src += 4;
- break;
- case 3: /* 24 bpp plus transparency */
- alpha = *(uint32_t *) src & (1 << 24);
- if (s->control[0] & LCCR0_CMS)
- r = g = b = *(uint32_t *) src & 0xff;
- else {
- r = (*(uint32_t *) src & 0xff0000) >> 16;
- g = (*(uint32_t *) src & 0x00ff00) >> 8;
- b = (*(uint32_t *) src & 0x0000ff);
- }
- src += 4;
- break;
- }
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- *dest = rgb_to_pixel8(r, g, b) | alpha;
- break;
- case 15:
- *dest = rgb_to_pixel15(r, g, b) | alpha;
- break;
- case 16:
- *dest = rgb_to_pixel16(r, g, b) | alpha;
- break;
- case 24:
- *dest = rgb_to_pixel24(r, g, b) | alpha;
- break;
- case 32:
- *dest = rgb_to_pixel32(r, g, b) | alpha;
- break;
- }
- dest ++;
- }
-}
-
-static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
- hwaddr addr, int *miny, int *maxy)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width, dest_width;
- drawfn fn = NULL;
- if (s->dest_width)
- fn = s->line_fn[s->transp][s->bpp];
- if (!fn)
- return;
-
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
- src_width *= 3;
- else if (s->bpp > pxa_lcdc_16bpp)
- src_width *= 4;
- else if (s->bpp > pxa_lcdc_8bpp)
- src_width *= 2;
-
- dest_width = s->xres * s->dest_width;
- *miny = 0;
- if (s->invalidated) {
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
- addr, s->yres, src_width);
- }
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
- src_width, dest_width, s->dest_width,
- s->invalidated,
- fn, s->dma_ch[0].palette, miny, maxy);
-}
-
-static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
- hwaddr addr, int *miny, int *maxy)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width, dest_width;
- drawfn fn = NULL;
- if (s->dest_width)
- fn = s->line_fn[s->transp][s->bpp];
- if (!fn)
- return;
-
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
- src_width *= 3;
- else if (s->bpp > pxa_lcdc_16bpp)
- src_width *= 4;
- else if (s->bpp > pxa_lcdc_8bpp)
- src_width *= 2;
-
- dest_width = s->yres * s->dest_width;
- *miny = 0;
- if (s->invalidated) {
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
- addr, s->yres, src_width);
- }
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
- src_width, s->dest_width, -dest_width,
- s->invalidated,
- fn, s->dma_ch[0].palette,
- miny, maxy);
-}
-
-static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
- hwaddr addr, int *miny, int *maxy)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width, dest_width;
- drawfn fn = NULL;
- if (s->dest_width) {
- fn = s->line_fn[s->transp][s->bpp];
- }
- if (!fn) {
- return;
- }
-
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
- src_width *= 3;
- } else if (s->bpp > pxa_lcdc_16bpp) {
- src_width *= 4;
- } else if (s->bpp > pxa_lcdc_8bpp) {
- src_width *= 2;
- }
-
- dest_width = s->xres * s->dest_width;
- *miny = 0;
- if (s->invalidated) {
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
- addr, s->yres, src_width);
- }
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
- src_width, -dest_width, -s->dest_width,
- s->invalidated,
- fn, s->dma_ch[0].palette, miny, maxy);
-}
-
-static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
- hwaddr addr, int *miny, int *maxy)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width, dest_width;
- drawfn fn = NULL;
- if (s->dest_width) {
- fn = s->line_fn[s->transp][s->bpp];
- }
- if (!fn) {
- return;
- }
-
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
- src_width *= 3;
- } else if (s->bpp > pxa_lcdc_16bpp) {
- src_width *= 4;
- } else if (s->bpp > pxa_lcdc_8bpp) {
- src_width *= 2;
- }
-
- dest_width = s->yres * s->dest_width;
- *miny = 0;
- if (s->invalidated) {
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
- addr, s->yres, src_width);
- }
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
- src_width, -s->dest_width, dest_width,
- s->invalidated,
- fn, s->dma_ch[0].palette,
- miny, maxy);
-}
-
-static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
-{
- int width, height;
- if (!(s->control[0] & LCCR0_ENB))
- return;
-
- width = LCCR1_PPL(s->control[1]) + 1;
- height = LCCR2_LPP(s->control[2]) + 1;
-
- if (width != s->xres || height != s->yres) {
- if (s->orientation == 90 || s->orientation == 270) {
- qemu_console_resize(s->con, height, width);
- } else {
- qemu_console_resize(s->con, width, height);
- }
- s->invalidated = 1;
- s->xres = width;
- s->yres = height;
- }
-}
-
-static void pxa2xx_update_display(void *opaque)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- hwaddr fbptr;
- int miny, maxy;
- int ch;
- if (!(s->control[0] & LCCR0_ENB))
- return;
-
- pxa2xx_descriptor_load(s);
-
- pxa2xx_lcdc_resize(s);
- miny = s->yres;
- maxy = 0;
- s->transp = s->dma_ch[2].up || s->dma_ch[3].up;
- /* Note: With overlay planes the order depends on LCCR0 bit 25. */
- for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++)
- if (s->dma_ch[ch].up) {
- if (!s->dma_ch[ch].source) {
- pxa2xx_dma_ber_set(s, ch);
- continue;
- }
- fbptr = s->dma_ch[ch].source;
- if (!((fbptr >= PXA2XX_SDRAM_BASE &&
- fbptr <= PXA2XX_SDRAM_BASE + ram_size) ||
- (fbptr >= PXA2XX_INTERNAL_BASE &&
- fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
- pxa2xx_dma_ber_set(s, ch);
- continue;
- }
-
- if (s->dma_ch[ch].command & LDCMD_PAL) {
- cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
- MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
- sizeof(s->dma_ch[ch].pbuffer)));
- pxa2xx_palette_parse(s, ch, s->bpp);
- } else {
- /* Do we need to reparse palette */
- if (LCCR4_PALFOR(s->control[4]) != s->pal_for)
- pxa2xx_palette_parse(s, ch, s->bpp);
-
- /* ACK frame start */
- pxa2xx_dma_sof_set(s, ch);
-
- s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
- s->invalidated = 0;
-
- /* ACK frame completed */
- pxa2xx_dma_eof_set(s, ch);
- }
- }
-
- if (s->control[0] & LCCR0_DIS) {
- /* ACK last frame completed */
- s->control[0] &= ~LCCR0_ENB;
- s->status[0] |= LCSR0_LDD;
- }
-
- if (miny >= 0) {
- switch (s->orientation) {
- case 0:
- dpy_gfx_update(s->con, 0, miny, s->xres, maxy - miny + 1);
- break;
- case 90:
- dpy_gfx_update(s->con, miny, 0, maxy - miny + 1, s->xres);
- break;
- case 180:
- maxy = s->yres - maxy - 1;
- miny = s->yres - miny - 1;
- dpy_gfx_update(s->con, 0, maxy, s->xres, miny - maxy + 1);
- break;
- case 270:
- maxy = s->yres - maxy - 1;
- miny = s->yres - miny - 1;
- dpy_gfx_update(s->con, maxy, 0, miny - maxy + 1, s->xres);
- break;
- }
- }
- pxa2xx_lcdc_int_update(s);
-
- qemu_irq_raise(s->vsync_cb);
-}
-
-static void pxa2xx_invalidate_display(void *opaque)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
- s->invalidated = 1;
-}
-
-static void pxa2xx_lcdc_orientation(void *opaque, int angle)
-{
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
-
- switch (angle) {
- case 0:
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0;
- break;
- case 90:
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90;
- break;
- case 180:
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180;
- break;
- case 270:
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270;
- break;
- }
-
- s->orientation = angle;
- s->xres = s->yres = -1;
- pxa2xx_lcdc_resize(s);
-}
-
-static const VMStateDescription vmstate_dma_channel = {
- .name = "dma_channel",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(branch, struct DMAChannel),
- VMSTATE_UINT8(up, struct DMAChannel),
- VMSTATE_BUFFER(pbuffer, struct DMAChannel),
- VMSTATE_UINT32(descriptor, struct DMAChannel),
- VMSTATE_UINT32(source, struct DMAChannel),
- VMSTATE_UINT32(id, struct DMAChannel),
- VMSTATE_UINT32(command, struct DMAChannel),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
-{
- PXA2xxLCDState *s = opaque;
-
- s->bpp = LCCR3_BPP(s->control[3]);
- s->xres = s->yres = s->pal_for = -1;
-
- return 0;
-}
-
-static const VMStateDescription vmstate_pxa2xx_lcdc = {
- .name = "pxa2xx_lcdc",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = pxa2xx_lcdc_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(irqlevel, PXA2xxLCDState),
- VMSTATE_INT32(transp, PXA2xxLCDState),
- VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
- VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
- VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
- VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
- VMSTATE_UINT32(ccr, PXA2xxLCDState),
- VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
- VMSTATE_UINT32(trgbr, PXA2xxLCDState),
- VMSTATE_UINT32(tcr, PXA2xxLCDState),
- VMSTATE_UINT32(liidr, PXA2xxLCDState),
- VMSTATE_UINT8(bscntr, PXA2xxLCDState),
- VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
- vmstate_dma_channel, struct DMAChannel),
- VMSTATE_END_OF_LIST()
- }
-};
-
-#define BITS 8
-#include "pxa2xx_template.h"
-#define BITS 15
-#include "pxa2xx_template.h"
-#define BITS 16
-#include "pxa2xx_template.h"
-#define BITS 24
-#include "pxa2xx_template.h"
-#define BITS 32
-#include "pxa2xx_template.h"
-
-static const GraphicHwOps pxa2xx_ops = {
- .invalidate = pxa2xx_invalidate_display,
- .gfx_update = pxa2xx_update_display,
-};
-
-PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
- hwaddr base, qemu_irq irq)
-{
- PXA2xxLCDState *s;
- DisplaySurface *surface;
-
- s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
- s->invalidated = 1;
- s->irq = irq;
- s->sysmem = sysmem;
-
- pxa2xx_lcdc_orientation(s, graphic_rotate);
-
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
- "pxa2xx-lcd-controller", 0x00100000);
- memory_region_add_subregion(sysmem, base, &s->iomem);
-
- s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
- surface = qemu_console_surface(s->con);
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- s->dest_width = 0;
- break;
- case 8:
- s->line_fn[0] = pxa2xx_draw_fn_8;
- s->line_fn[1] = pxa2xx_draw_fn_8t;
- s->dest_width = 1;
- break;
- case 15:
- s->line_fn[0] = pxa2xx_draw_fn_15;
- s->line_fn[1] = pxa2xx_draw_fn_15t;
- s->dest_width = 2;
- break;
- case 16:
- s->line_fn[0] = pxa2xx_draw_fn_16;
- s->line_fn[1] = pxa2xx_draw_fn_16t;
- s->dest_width = 2;
- break;
- case 24:
- s->line_fn[0] = pxa2xx_draw_fn_24;
- s->line_fn[1] = pxa2xx_draw_fn_24t;
- s->dest_width = 3;
- break;
- case 32:
- s->line_fn[0] = pxa2xx_draw_fn_32;
- s->line_fn[1] = pxa2xx_draw_fn_32t;
- s->dest_width = 4;
- break;
- default:
- fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
- exit(1);
- }
-
- vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
-
- return s;
-}
-
-void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
-{
- s->vsync_cb = handler;
-}
diff --git a/qemu/hw/display/pxa2xx_template.h b/qemu/hw/display/pxa2xx_template.h
deleted file mode 100644
index c64eebc4b..000000000
--- a/qemu/hw/display/pxa2xx_template.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Intel XScale PXA255/270 LCDC emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GPLv2.
- *
- * Framebuffer format conversion routines.
- */
-
-# define SKIP_PIXEL(to) to += deststep
-#if BITS == 8
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
-#elif BITS == 15 || BITS == 16
-# define COPY_PIXEL(to, from) \
- do { \
- *(uint16_t *) to = from; \
- SKIP_PIXEL(to); \
- } while (0)
-#elif BITS == 24
-# define COPY_PIXEL(to, from) \
- do { \
- *(uint16_t *) to = from; \
- *(to + 2) = (from) >> 16; \
- SKIP_PIXEL(to); \
- } while (0)
-#elif BITS == 32
-# define COPY_PIXEL(to, from) \
- do { \
- *(uint32_t *) to = from; \
- SKIP_PIXEL(to); \
- } while (0)
-#else
-# error unknown bit depth
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-# define SWAP_WORDS 1
-#endif
-
-#define FN_2(x) FN(x + 1) FN(x)
-#define FN_4(x) FN_2(x + 2) FN_2(x)
-
-static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *) src;
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
-#ifdef SWAP_WORDS
- FN_4(12)
- FN_4(8)
- FN_4(4)
- FN_4(0)
-#else
- FN_4(0)
- FN_4(4)
- FN_4(8)
- FN_4(12)
-#endif
-#undef FN
- width -= 16;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *) src;
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
-#ifdef SWAP_WORDS
- FN_2(6)
- FN_2(4)
- FN_2(2)
- FN_2(0)
-#else
- FN_2(0)
- FN_2(2)
- FN_2(4)
- FN_2(6)
-#endif
-#undef FN
- width -= 8;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t *palette = opaque;
- uint32_t data;
- while (width > 0) {
- data = *(uint32_t *) src;
-#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
-#ifdef SWAP_WORDS
- FN(24)
- FN(16)
- FN(8)
- FN(0)
-#else
- FN(0)
- FN(8)
- FN(16)
- FN(24)
-#endif
-#undef FN
- width -= 4;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- r = (data & 0x1f) << 3;
- data >>= 5;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- b = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x3f) << 2;
- data >>= 6;
- r = (data & 0x1f) << 3;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 2;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x1f) << 3;
- data >>= 5;
- r = (data & 0x1f) << 3;
- data >>= 5;
- if (data & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- data >>= 1;
- b = (data & 0x1f) << 3;
- data >>= 5;
- g = (data & 0x1f) << 3;
- data >>= 5;
- r = (data & 0x1f) << 3;
- data >>= 5;
- if (data & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 2;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = (data & 0x3f) << 2;
- data >>= 6;
- g = (data & 0x3f) << 2;
- data >>= 6;
- r = (data & 0x3f) << 2;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 1;
- src += 4;
- }
-}
-
-/* The wicked packed format */
-static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data[3];
- unsigned int r, g, b;
- while (width > 0) {
- data[0] = *(uint32_t *) src;
- src += 4;
- data[1] = *(uint32_t *) src;
- src += 4;
- data[2] = *(uint32_t *) src;
- src += 4;
-#ifdef SWAP_WORDS
- data[0] = bswap32(data[0]);
- data[1] = bswap32(data[1]);
- data[2] = bswap32(data[2]);
-#endif
- b = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- g = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- r = (data[0] & 0x3f) << 2;
- data[0] >>= 12;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- b = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
- data[1] >>= 4;
- r = (data[1] & 0x3f) << 2;
- data[1] >>= 12;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- b = (data[1] & 0x3f) << 2;
- data[1] >>= 6;
- g = (data[1] & 0x3f) << 2;
- data[1] >>= 6;
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
- data[2] >>= 8;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- b = (data[2] & 0x3f) << 2;
- data[2] >>= 6;
- g = (data[2] & 0x3f) << 2;
- data[2] >>= 6;
- r = data[2] << 2;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 4;
- }
-}
-
-static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = (data & 0x3f) << 2;
- data >>= 6;
- g = (data & 0x3f) << 2;
- data >>= 6;
- r = (data & 0x3f) << 2;
- data >>= 6;
- if (data & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 1;
- src += 4;
- }
-}
-
-/* The wicked packed format */
-static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data[3];
- unsigned int r, g, b;
- while (width > 0) {
- data[0] = *(uint32_t *) src;
- src += 4;
- data[1] = *(uint32_t *) src;
- src += 4;
- data[2] = *(uint32_t *) src;
- src += 4;
-# ifdef SWAP_WORDS
- data[0] = bswap32(data[0]);
- data[1] = bswap32(data[1]);
- data[2] = bswap32(data[2]);
-# endif
- b = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- g = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- r = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- if (data[0] & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- data[0] >>= 6;
- b = (data[0] & 0x3f) << 2;
- data[0] >>= 6;
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
- data[1] >>= 4;
- r = (data[1] & 0x3f) << 2;
- data[1] >>= 6;
- if (data[1] & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- data[1] >>= 6;
- b = (data[1] & 0x3f) << 2;
- data[1] >>= 6;
- g = (data[1] & 0x3f) << 2;
- data[1] >>= 6;
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
- data[2] >>= 2;
- if (data[2] & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- data[2] >>= 6;
- b = (data[2] & 0x3f) << 2;
- data[2] >>= 6;
- g = (data[2] & 0x3f) << 2;
- data[2] >>= 6;
- r = data[2] << 2;
- data[2] >>= 6;
- if (data[2] & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 4;
- }
-}
-
-static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = data & 0xff;
- data >>= 8;
- g = data & 0xff;
- data >>= 8;
- r = data & 0xff;
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 1;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = (data & 0x7f) << 1;
- data >>= 7;
- g = data & 0xff;
- data >>= 8;
- r = data & 0xff;
- data >>= 8;
- if (data & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 1;
- src += 4;
- }
-}
-
-static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
- uint8_t *dest, const uint8_t *src, int width, int deststep)
-{
- uint32_t data;
- unsigned int r, g, b;
- while (width > 0) {
- data = *(uint32_t *) src;
-#ifdef SWAP_WORDS
- data = bswap32(data);
-#endif
- b = data & 0xff;
- data >>= 8;
- g = data & 0xff;
- data >>= 8;
- r = data & 0xff;
- data >>= 8;
- if (data & 1)
- SKIP_PIXEL(dest);
- else
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
- width -= 1;
- src += 4;
- }
-}
-
-/* Overlay planes disabled, no transparency */
-static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
-{
- [0 ... 0xf] = NULL,
- [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
- [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
- [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
-};
-
-/* Overlay planes enabled, transparency used */
-static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
-{
- [0 ... 0xf] = NULL,
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
- [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
- [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
- [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
-};
-
-#undef BITS
-#undef COPY_PIXEL
-#undef SKIP_PIXEL
-
-#ifdef SWAP_WORDS
-# undef SWAP_WORDS
-#endif
diff --git a/qemu/hw/display/qxl-logger.c b/qemu/hw/display/qxl-logger.c
deleted file mode 100644
index 2ec6d8fa3..000000000
--- a/qemu/hw/display/qxl-logger.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * qxl command logging -- for debug purposes
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * maintained by Gerd Hoffmann <kraxel@redhat.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/timer.h"
-#include "qxl.h"
-
-static const char *const qxl_type[] = {
- [ QXL_CMD_NOP ] = "nop",
- [ QXL_CMD_DRAW ] = "draw",
- [ QXL_CMD_UPDATE ] = "update",
- [ QXL_CMD_CURSOR ] = "cursor",
- [ QXL_CMD_MESSAGE ] = "message",
- [ QXL_CMD_SURFACE ] = "surface",
-};
-
-static const char *const qxl_draw_type[] = {
- [ QXL_DRAW_NOP ] = "nop",
- [ QXL_DRAW_FILL ] = "fill",
- [ QXL_DRAW_OPAQUE ] = "opaque",
- [ QXL_DRAW_COPY ] = "copy",
- [ QXL_COPY_BITS ] = "copy-bits",
- [ QXL_DRAW_BLEND ] = "blend",
- [ QXL_DRAW_BLACKNESS ] = "blackness",
- [ QXL_DRAW_WHITENESS ] = "whitemess",
- [ QXL_DRAW_INVERS ] = "invers",
- [ QXL_DRAW_ROP3 ] = "rop3",
- [ QXL_DRAW_STROKE ] = "stroke",
- [ QXL_DRAW_TEXT ] = "text",
- [ QXL_DRAW_TRANSPARENT ] = "transparent",
- [ QXL_DRAW_ALPHA_BLEND ] = "alpha-blend",
-};
-
-static const char *const qxl_draw_effect[] = {
- [ QXL_EFFECT_BLEND ] = "blend",
- [ QXL_EFFECT_OPAQUE ] = "opaque",
- [ QXL_EFFECT_REVERT_ON_DUP ] = "revert-on-dup",
- [ QXL_EFFECT_BLACKNESS_ON_DUP ] = "blackness-on-dup",
- [ QXL_EFFECT_WHITENESS_ON_DUP ] = "whiteness-on-dup",
- [ QXL_EFFECT_NOP_ON_DUP ] = "nop-on-dup",
- [ QXL_EFFECT_NOP ] = "nop",
- [ QXL_EFFECT_OPAQUE_BRUSH ] = "opaque-brush",
-};
-
-static const char *const qxl_surface_cmd[] = {
- [ QXL_SURFACE_CMD_CREATE ] = "create",
- [ QXL_SURFACE_CMD_DESTROY ] = "destroy",
-};
-
-static const char *const spice_surface_fmt[] = {
- [ SPICE_SURFACE_FMT_INVALID ] = "invalid",
- [ SPICE_SURFACE_FMT_1_A ] = "alpha/1",
- [ SPICE_SURFACE_FMT_8_A ] = "alpha/8",
- [ SPICE_SURFACE_FMT_16_555 ] = "555/16",
- [ SPICE_SURFACE_FMT_16_565 ] = "565/16",
- [ SPICE_SURFACE_FMT_32_xRGB ] = "xRGB/32",
- [ SPICE_SURFACE_FMT_32_ARGB ] = "ARGB/32",
-};
-
-static const char *const qxl_cursor_cmd[] = {
- [ QXL_CURSOR_SET ] = "set",
- [ QXL_CURSOR_MOVE ] = "move",
- [ QXL_CURSOR_HIDE ] = "hide",
- [ QXL_CURSOR_TRAIL ] = "trail",
-};
-
-static const char *const spice_cursor_type[] = {
- [ SPICE_CURSOR_TYPE_ALPHA ] = "alpha",
- [ SPICE_CURSOR_TYPE_MONO ] = "mono",
- [ SPICE_CURSOR_TYPE_COLOR4 ] = "color4",
- [ SPICE_CURSOR_TYPE_COLOR8 ] = "color8",
- [ SPICE_CURSOR_TYPE_COLOR16 ] = "color16",
- [ SPICE_CURSOR_TYPE_COLOR24 ] = "color24",
- [ SPICE_CURSOR_TYPE_COLOR32 ] = "color32",
-};
-
-static const char *qxl_v2n(const char *const n[], size_t l, int v)
-{
- if (v >= l || !n[v]) {
- return "???";
- }
- return n[v];
-}
-#define qxl_name(_list, _value) qxl_v2n(_list, ARRAY_SIZE(_list), _value)
-
-static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
-{
- QXLImage *image;
- QXLImageDescriptor *desc;
-
- image = qxl_phys2virt(qxl, addr, group_id);
- if (!image) {
- return 1;
- }
- desc = &image->descriptor;
- fprintf(stderr, " (id %" PRIx64 " type %d flags %d width %d height %d",
- desc->id, desc->type, desc->flags, desc->width, desc->height);
- switch (desc->type) {
- case SPICE_IMAGE_TYPE_BITMAP:
- fprintf(stderr, ", fmt %d flags %d x %d y %d stride %d"
- " palette %" PRIx64 " data %" PRIx64,
- image->bitmap.format, image->bitmap.flags,
- image->bitmap.x, image->bitmap.y,
- image->bitmap.stride,
- image->bitmap.palette, image->bitmap.data);
- break;
- }
- fprintf(stderr, ")");
- return 0;
-}
-
-static void qxl_log_rect(QXLRect *rect)
-{
- fprintf(stderr, " %dx%d+%d+%d",
- rect->right - rect->left,
- rect->bottom - rect->top,
- rect->left, rect->top);
-}
-
-static int qxl_log_cmd_draw_copy(PCIQXLDevice *qxl, QXLCopy *copy,
- int group_id)
-{
- int ret;
-
- fprintf(stderr, " src %" PRIx64,
- copy->src_bitmap);
- ret = qxl_log_image(qxl, copy->src_bitmap, group_id);
- if (ret != 0) {
- return ret;
- }
- fprintf(stderr, " area");
- qxl_log_rect(&copy->src_area);
- fprintf(stderr, " rop %d", copy->rop_descriptor);
- return 0;
-}
-
-static int qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id)
-{
- fprintf(stderr, ": surface_id %d type %s effect %s",
- draw->surface_id,
- qxl_name(qxl_draw_type, draw->type),
- qxl_name(qxl_draw_effect, draw->effect));
- switch (draw->type) {
- case QXL_DRAW_COPY:
- return qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
- break;
- }
- return 0;
-}
-
-static int qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw,
- int group_id)
-{
- fprintf(stderr, ": type %s effect %s",
- qxl_name(qxl_draw_type, draw->type),
- qxl_name(qxl_draw_effect, draw->effect));
- if (draw->bitmap_offset) {
- fprintf(stderr, ": bitmap %d",
- draw->bitmap_offset);
- qxl_log_rect(&draw->bitmap_area);
- }
- switch (draw->type) {
- case QXL_DRAW_COPY:
- return qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
- break;
- }
- return 0;
-}
-
-static void qxl_log_cmd_surface(PCIQXLDevice *qxl, QXLSurfaceCmd *cmd)
-{
- fprintf(stderr, ": %s id %d",
- qxl_name(qxl_surface_cmd, cmd->type),
- cmd->surface_id);
- if (cmd->type == QXL_SURFACE_CMD_CREATE) {
- fprintf(stderr, " size %dx%d stride %d format %s (count %d, max %d)",
- cmd->u.surface_create.width,
- cmd->u.surface_create.height,
- cmd->u.surface_create.stride,
- qxl_name(spice_surface_fmt, cmd->u.surface_create.format),
- qxl->guest_surfaces.count, qxl->guest_surfaces.max);
- }
- if (cmd->type == QXL_SURFACE_CMD_DESTROY) {
- fprintf(stderr, " (count %d)", qxl->guest_surfaces.count);
- }
-}
-
-int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
-{
- QXLCursor *cursor;
-
- fprintf(stderr, ": %s",
- qxl_name(qxl_cursor_cmd, cmd->type));
- switch (cmd->type) {
- case QXL_CURSOR_SET:
- fprintf(stderr, " +%d+%d visible %s, shape @ 0x%" PRIx64,
- cmd->u.set.position.x,
- cmd->u.set.position.y,
- cmd->u.set.visible ? "yes" : "no",
- cmd->u.set.shape);
- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id);
- if (!cursor) {
- return 1;
- }
- fprintf(stderr, " type %s size %dx%d hot-spot +%d+%d"
- " unique 0x%" PRIx64 " data-size %d",
- qxl_name(spice_cursor_type, cursor->header.type),
- cursor->header.width, cursor->header.height,
- cursor->header.hot_spot_x, cursor->header.hot_spot_y,
- cursor->header.unique, cursor->data_size);
- break;
- case QXL_CURSOR_MOVE:
- fprintf(stderr, " +%d+%d", cmd->u.position.x, cmd->u.position.y);
- break;
- }
- return 0;
-}
-
-int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
-{
- bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT;
- void *data;
- int ret;
-
- if (!qxl->cmdlog) {
- return 0;
- }
- fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
- qxl->id, ring);
- fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
- qxl_name(qxl_type, ext->cmd.type),
- compat ? "(compat)" : "");
-
- data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
- if (!data) {
- return 1;
- }
- switch (ext->cmd.type) {
- case QXL_CMD_DRAW:
- if (!compat) {
- ret = qxl_log_cmd_draw(qxl, data, ext->group_id);
- } else {
- ret = qxl_log_cmd_draw_compat(qxl, data, ext->group_id);
- }
- if (ret) {
- return ret;
- }
- break;
- case QXL_CMD_SURFACE:
- qxl_log_cmd_surface(qxl, data);
- break;
- case QXL_CMD_CURSOR:
- qxl_log_cmd_cursor(qxl, data, ext->group_id);
- break;
- }
- fprintf(stderr, "\n");
- return 0;
-}
diff --git a/qemu/hw/display/qxl-render.c b/qemu/hw/display/qxl-render.c
deleted file mode 100644
index 9ad9d9e0f..000000000
--- a/qemu/hw/display/qxl-render.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * qxl local rendering (aka display on sdl/vnc)
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * maintained by Gerd Hoffmann <kraxel@redhat.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qxl.h"
-#include "trace.h"
-
-static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
-{
- DisplaySurface *surface = qemu_console_surface(qxl->vga.con);
- uint8_t *dst = surface_data(surface);
- uint8_t *src;
- int len, i;
-
- if (is_buffer_shared(surface)) {
- return;
- }
- trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
- rect->left, rect->right, rect->top, rect->bottom);
- src = qxl->guest_primary.data;
- if (qxl->guest_primary.qxl_stride < 0) {
- /* qxl surface is upside down, walk src scanlines
- * in reverse order to flip it */
- src += (qxl->guest_primary.surface.height - rect->top - 1) *
- qxl->guest_primary.abs_stride;
- } else {
- src += rect->top * qxl->guest_primary.abs_stride;
- }
- dst += rect->top * qxl->guest_primary.abs_stride;
- src += rect->left * qxl->guest_primary.bytes_pp;
- dst += rect->left * qxl->guest_primary.bytes_pp;
- len = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;
-
- for (i = rect->top; i < rect->bottom; i++) {
- memcpy(dst, src, len);
- dst += qxl->guest_primary.abs_stride;
- src += qxl->guest_primary.qxl_stride;
- }
-}
-
-void qxl_render_resize(PCIQXLDevice *qxl)
-{
- QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
-
- qxl->guest_primary.qxl_stride = sc->stride;
- qxl->guest_primary.abs_stride = abs(sc->stride);
- qxl->guest_primary.resized++;
- switch (sc->format) {
- case SPICE_SURFACE_FMT_16_555:
- qxl->guest_primary.bytes_pp = 2;
- qxl->guest_primary.bits_pp = 15;
- break;
- case SPICE_SURFACE_FMT_16_565:
- qxl->guest_primary.bytes_pp = 2;
- qxl->guest_primary.bits_pp = 16;
- break;
- case SPICE_SURFACE_FMT_32_xRGB:
- case SPICE_SURFACE_FMT_32_ARGB:
- qxl->guest_primary.bytes_pp = 4;
- qxl->guest_primary.bits_pp = 32;
- break;
- default:
- fprintf(stderr, "%s: unhandled format: %x\n", __FUNCTION__,
- qxl->guest_primary.surface.format);
- qxl->guest_primary.bytes_pp = 4;
- qxl->guest_primary.bits_pp = 32;
- break;
- }
-}
-
-static void qxl_set_rect_to_surface(PCIQXLDevice *qxl, QXLRect *area)
-{
- area->left = 0;
- area->right = qxl->guest_primary.surface.width;
- area->top = 0;
- area->bottom = qxl->guest_primary.surface.height;
-}
-
-static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
-{
- VGACommonState *vga = &qxl->vga;
- DisplaySurface *surface;
- int i;
-
- if (qxl->guest_primary.resized) {
- qxl->guest_primary.resized = 0;
- qxl->guest_primary.data = qxl_phys2virt(qxl,
- qxl->guest_primary.surface.mem,
- MEMSLOT_GROUP_GUEST);
- if (!qxl->guest_primary.data) {
- return;
- }
- qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
- qxl->num_dirty_rects = 1;
- trace_qxl_render_guest_primary_resized(
- qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- qxl->guest_primary.qxl_stride,
- qxl->guest_primary.bytes_pp,
- qxl->guest_primary.bits_pp);
- if (qxl->guest_primary.qxl_stride > 0) {
- pixman_format_code_t format =
- qemu_default_pixman_format(qxl->guest_primary.bits_pp, true);
- surface = qemu_create_displaysurface_from
- (qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- format,
- qxl->guest_primary.abs_stride,
- qxl->guest_primary.data);
- } else {
- surface = qemu_create_displaysurface
- (qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height);
- }
- dpy_gfx_replace_surface(vga->con, surface);
- }
-
- if (!qxl->guest_primary.data) {
- return;
- }
- for (i = 0; i < qxl->num_dirty_rects; i++) {
- if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
- break;
- }
- if (qxl->dirty[i].left < 0 ||
- qxl->dirty[i].top < 0 ||
- qxl->dirty[i].left > qxl->dirty[i].right ||
- qxl->dirty[i].top > qxl->dirty[i].bottom ||
- qxl->dirty[i].right > qxl->guest_primary.surface.width ||
- qxl->dirty[i].bottom > qxl->guest_primary.surface.height) {
- continue;
- }
- qxl_blit(qxl, qxl->dirty+i);
- dpy_gfx_update(vga->con,
- qxl->dirty[i].left, qxl->dirty[i].top,
- qxl->dirty[i].right - qxl->dirty[i].left,
- qxl->dirty[i].bottom - qxl->dirty[i].top);
- }
- qxl->num_dirty_rects = 0;
-}
-
-/*
- * use ssd.lock to protect render_update_cookie_num.
- * qxl_render_update is called by io thread or vcpu thread, and the completion
- * callbacks are called by spice_server thread, deferring to bh called from the
- * io thread.
- */
-void qxl_render_update(PCIQXLDevice *qxl)
-{
- QXLCookie *cookie;
-
- qemu_mutex_lock(&qxl->ssd.lock);
-
- if (!runstate_is_running() || !qxl->guest_primary.commands) {
- qxl_render_update_area_unlocked(qxl);
- qemu_mutex_unlock(&qxl->ssd.lock);
- return;
- }
-
- qxl->guest_primary.commands = 0;
- qxl->render_update_cookie_num++;
- qemu_mutex_unlock(&qxl->ssd.lock);
- cookie = qxl_cookie_new(QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
- 0);
- qxl_set_rect_to_surface(qxl, &cookie->u.render.area);
- qxl_spice_update_area(qxl, 0, &cookie->u.render.area, NULL,
- 0, 1 /* clear_dirty_region */, QXL_ASYNC, cookie);
-}
-
-void qxl_render_update_area_bh(void *opaque)
-{
- PCIQXLDevice *qxl = opaque;
-
- qemu_mutex_lock(&qxl->ssd.lock);
- qxl_render_update_area_unlocked(qxl);
- qemu_mutex_unlock(&qxl->ssd.lock);
-}
-
-void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
-{
- qemu_mutex_lock(&qxl->ssd.lock);
- trace_qxl_render_update_area_done(cookie);
- qemu_bh_schedule(qxl->update_area_bh);
- qxl->render_update_cookie_num--;
- qemu_mutex_unlock(&qxl->ssd.lock);
- g_free(cookie);
-}
-
-static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
-{
- QEMUCursor *c;
- uint8_t *image, *mask;
- size_t size;
-
- c = cursor_alloc(cursor->header.width, cursor->header.height);
- c->hot_x = cursor->header.hot_spot_x;
- c->hot_y = cursor->header.hot_spot_y;
- switch (cursor->header.type) {
- case SPICE_CURSOR_TYPE_ALPHA:
- size = sizeof(uint32_t) * cursor->header.width * cursor->header.height;
- memcpy(c->data, cursor->chunk.data, size);
- if (qxl->debug > 2) {
- cursor_print_ascii_art(c, "qxl/alpha");
- }
- break;
- case SPICE_CURSOR_TYPE_MONO:
- mask = cursor->chunk.data;
- image = mask + cursor_get_mono_bpl(c) * c->width;
- cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask);
- if (qxl->debug > 2) {
- cursor_print_ascii_art(c, "qxl/mono");
- }
- break;
- default:
- fprintf(stderr, "%s: not implemented: type %d\n",
- __FUNCTION__, cursor->header.type);
- goto fail;
- }
- return c;
-
-fail:
- cursor_put(c);
- return NULL;
-}
-
-
-/* called from spice server thread context only */
-int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
-{
- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
- QXLCursor *cursor;
- QEMUCursor *c;
-
- if (!cmd) {
- return 1;
- }
-
- if (!dpy_cursor_define_supported(qxl->vga.con)) {
- return 0;
- }
-
- if (qxl->debug > 1 && cmd->type != QXL_CURSOR_MOVE) {
- fprintf(stderr, "%s", __FUNCTION__);
- qxl_log_cmd_cursor(qxl, cmd, ext->group_id);
- fprintf(stderr, "\n");
- }
- switch (cmd->type) {
- case QXL_CURSOR_SET:
- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id);
- if (!cursor) {
- return 1;
- }
- if (cursor->chunk.data_size != cursor->data_size) {
- fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__);
- return 1;
- }
- c = qxl_cursor(qxl, cursor);
- if (c == NULL) {
- c = cursor_builtin_left_ptr();
- }
- qemu_mutex_lock(&qxl->ssd.lock);
- if (qxl->ssd.cursor) {
- cursor_put(qxl->ssd.cursor);
- }
- qxl->ssd.cursor = c;
- qxl->ssd.mouse_x = cmd->u.set.position.x;
- qxl->ssd.mouse_y = cmd->u.set.position.y;
- qemu_mutex_unlock(&qxl->ssd.lock);
- qemu_bh_schedule(qxl->ssd.cursor_bh);
- break;
- case QXL_CURSOR_MOVE:
- qemu_mutex_lock(&qxl->ssd.lock);
- qxl->ssd.mouse_x = cmd->u.position.x;
- qxl->ssd.mouse_y = cmd->u.position.y;
- qemu_mutex_unlock(&qxl->ssd.lock);
- qemu_bh_schedule(qxl->ssd.cursor_bh);
- break;
- }
- return 0;
-}
diff --git a/qemu/hw/display/qxl.c b/qemu/hw/display/qxl.c
deleted file mode 100644
index 919dc5cd3..000000000
--- a/qemu/hw/display/qxl.c
+++ /dev/null
@@ -1,2359 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * written by Yaniv Kamay, Izik Eidus, Gerd Hoffmann
- * maintained by Gerd Hoffmann <kraxel@redhat.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include <zlib.h>
-
-#include "qemu-common.h"
-#include "qemu/timer.h"
-#include "qemu/queue.h"
-#include "qemu/atomic.h"
-#include "sysemu/sysemu.h"
-#include "trace.h"
-
-#include "qxl.h"
-
-/*
- * NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
- * such can be changed by the guest, so to avoid a guest trigerrable
- * abort we just qxl_set_guest_bug and set the return to NULL. Still
- * it may happen as a result of emulator bug as well.
- */
-#undef SPICE_RING_PROD_ITEM
-#define SPICE_RING_PROD_ITEM(qxl, r, ret) { \
- uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \
- if (prod >= ARRAY_SIZE((r)->items)) { \
- qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \
- "%u >= %zu", prod, ARRAY_SIZE((r)->items)); \
- ret = NULL; \
- } else { \
- ret = &(r)->items[prod].el; \
- } \
- }
-
-#undef SPICE_RING_CONS_ITEM
-#define SPICE_RING_CONS_ITEM(qxl, r, ret) { \
- uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \
- if (cons >= ARRAY_SIZE((r)->items)) { \
- qxl_set_guest_bug(qxl, "SPICE_RING_CONS_ITEM indices mismatch " \
- "%u >= %zu", cons, ARRAY_SIZE((r)->items)); \
- ret = NULL; \
- } else { \
- ret = &(r)->items[cons].el; \
- } \
- }
-
-#undef ALIGN
-#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
-
-#define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9"
-
-#define QXL_MODE(_x, _y, _b, _o) \
- { .x_res = _x, \
- .y_res = _y, \
- .bits = _b, \
- .stride = (_x) * (_b) / 8, \
- .x_mili = PIXEL_SIZE * (_x), \
- .y_mili = PIXEL_SIZE * (_y), \
- .orientation = _o, \
- }
-
-#define QXL_MODE_16_32(x_res, y_res, orientation) \
- QXL_MODE(x_res, y_res, 16, orientation), \
- QXL_MODE(x_res, y_res, 32, orientation)
-
-#define QXL_MODE_EX(x_res, y_res) \
- QXL_MODE_16_32(x_res, y_res, 0), \
- QXL_MODE_16_32(x_res, y_res, 1)
-
-static QXLMode qxl_modes[] = {
- QXL_MODE_EX(640, 480),
- QXL_MODE_EX(800, 480),
- QXL_MODE_EX(800, 600),
- QXL_MODE_EX(832, 624),
- QXL_MODE_EX(960, 640),
- QXL_MODE_EX(1024, 600),
- QXL_MODE_EX(1024, 768),
- QXL_MODE_EX(1152, 864),
- QXL_MODE_EX(1152, 870),
- QXL_MODE_EX(1280, 720),
- QXL_MODE_EX(1280, 760),
- QXL_MODE_EX(1280, 768),
- QXL_MODE_EX(1280, 800),
- QXL_MODE_EX(1280, 960),
- QXL_MODE_EX(1280, 1024),
- QXL_MODE_EX(1360, 768),
- QXL_MODE_EX(1366, 768),
- QXL_MODE_EX(1400, 1050),
- QXL_MODE_EX(1440, 900),
- QXL_MODE_EX(1600, 900),
- QXL_MODE_EX(1600, 1200),
- QXL_MODE_EX(1680, 1050),
- QXL_MODE_EX(1920, 1080),
- /* these modes need more than 8 MB video memory */
- QXL_MODE_EX(1920, 1200),
- QXL_MODE_EX(1920, 1440),
- QXL_MODE_EX(2000, 2000),
- QXL_MODE_EX(2048, 1536),
- QXL_MODE_EX(2048, 2048),
- QXL_MODE_EX(2560, 1440),
- QXL_MODE_EX(2560, 1600),
- /* these modes need more than 16 MB video memory */
- QXL_MODE_EX(2560, 2048),
- QXL_MODE_EX(2800, 2100),
- QXL_MODE_EX(3200, 2400),
- /* these modes need more than 32 MB video memory */
- QXL_MODE_EX(3840, 2160), /* 4k mainstream */
- QXL_MODE_EX(4096, 2160), /* 4k */
- /* these modes need more than 64 MB video memory */
- QXL_MODE_EX(7680, 4320), /* 8k mainstream */
- /* these modes need more than 128 MB video memory */
- QXL_MODE_EX(8192, 4320), /* 8k */
-};
-
-static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
-static void qxl_reset_memslots(PCIQXLDevice *d);
-static void qxl_reset_surfaces(PCIQXLDevice *d);
-static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
-
-static void qxl_hw_update(void *opaque);
-
-void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
-{
- trace_qxl_set_guest_bug(qxl->id);
- qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
- qxl->guest_bug = 1;
- if (qxl->guestdebug) {
- va_list ap;
- va_start(ap, msg);
- fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- }
-}
-
-static void qxl_clear_guest_bug(PCIQXLDevice *qxl)
-{
- qxl->guest_bug = 0;
-}
-
-void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
- struct QXLRect *area, struct QXLRect *dirty_rects,
- uint32_t num_dirty_rects,
- uint32_t clear_dirty_region,
- qxl_async_io async, struct QXLCookie *cookie)
-{
- trace_qxl_spice_update_area(qxl->id, surface_id, area->left, area->right,
- area->top, area->bottom);
- trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
- clear_dirty_region);
- if (async == QXL_SYNC) {
- spice_qxl_update_area(&qxl->ssd.qxl, surface_id, area,
- dirty_rects, num_dirty_rects, clear_dirty_region);
- } else {
- assert(cookie != NULL);
- spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
- clear_dirty_region, (uintptr_t)cookie);
- }
-}
-
-static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
- uint32_t id)
-{
- trace_qxl_spice_destroy_surface_wait_complete(qxl->id, id);
- qemu_mutex_lock(&qxl->track_lock);
- qxl->guest_surfaces.cmds[id] = 0;
- qxl->guest_surfaces.count--;
- qemu_mutex_unlock(&qxl->track_lock);
-}
-
-static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
- qxl_async_io async)
-{
- QXLCookie *cookie;
-
- trace_qxl_spice_destroy_surface_wait(qxl->id, id, async);
- if (async) {
- cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_DESTROY_SURFACE_ASYNC);
- cookie->u.surface_id = id;
- spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
- } else {
- spice_qxl_destroy_surface_wait(&qxl->ssd.qxl, id);
- qxl_spice_destroy_surface_wait_complete(qxl, id);
- }
-}
-
-static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
- qxl->num_free_res);
- spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_FLUSH_SURFACES_ASYNC));
-}
-
-void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
- uint32_t count)
-{
- trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
- spice_qxl_loadvm_commands(&qxl->ssd.qxl, ext, count);
-}
-
-void qxl_spice_oom(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_oom(qxl->id);
- spice_qxl_oom(&qxl->ssd.qxl);
-}
-
-void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_reset_memslots(qxl->id);
- spice_qxl_reset_memslots(&qxl->ssd.qxl);
-}
-
-static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_destroy_surfaces_complete(qxl->id);
- qemu_mutex_lock(&qxl->track_lock);
- memset(qxl->guest_surfaces.cmds, 0,
- sizeof(qxl->guest_surfaces.cmds[0]) * qxl->ssd.num_surfaces);
- qxl->guest_surfaces.count = 0;
- qemu_mutex_unlock(&qxl->track_lock);
-}
-
-static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
-{
- trace_qxl_spice_destroy_surfaces(qxl->id, async);
- if (async) {
- spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
- } else {
- spice_qxl_destroy_surfaces(&qxl->ssd.qxl);
- qxl_spice_destroy_surfaces_complete(qxl);
- }
-}
-
-static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
-{
- trace_qxl_spice_monitors_config(qxl->id);
- if (replay) {
- /*
- * don't use QXL_COOKIE_TYPE_IO:
- * - we are not running yet (post_load), we will assert
- * in send_events
- * - this is not a guest io, but a reply, so async_io isn't set.
- */
- spice_qxl_monitors_config_async(&qxl->ssd.qxl,
- qxl->guest_monitors_config,
- MEMSLOT_GROUP_GUEST,
- (uintptr_t)qxl_cookie_new(
- QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
- 0));
- } else {
-#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
- if (qxl->max_outputs) {
- spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
- }
-#endif
- qxl->guest_monitors_config = qxl->ram->monitors_config;
- spice_qxl_monitors_config_async(&qxl->ssd.qxl,
- qxl->ram->monitors_config,
- MEMSLOT_GROUP_GUEST,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_MONITORS_CONFIG_ASYNC));
- }
-}
-
-void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_reset_image_cache(qxl->id);
- spice_qxl_reset_image_cache(&qxl->ssd.qxl);
-}
-
-void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
-{
- trace_qxl_spice_reset_cursor(qxl->id);
- spice_qxl_reset_cursor(&qxl->ssd.qxl);
- qemu_mutex_lock(&qxl->track_lock);
- qxl->guest_cursor = 0;
- qemu_mutex_unlock(&qxl->track_lock);
- if (qxl->ssd.cursor) {
- cursor_put(qxl->ssd.cursor);
- }
- qxl->ssd.cursor = cursor_builtin_hidden();
-}
-
-static ram_addr_t qxl_rom_size(void)
-{
- uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) +
- sizeof(qxl_modes);
- uint32_t rom_size = 8192; /* two pages */
-
- QEMU_BUILD_BUG_ON(required_rom_size > rom_size);
- return rom_size;
-}
-
-static void init_qxl_rom(PCIQXLDevice *d)
-{
- QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
- QXLModes *modes = (QXLModes *)(rom + 1);
- uint32_t ram_header_size;
- uint32_t surface0_area_size;
- uint32_t num_pages;
- uint32_t fb;
- int i, n;
-
- memset(rom, 0, d->rom_size);
-
- rom->magic = cpu_to_le32(QXL_ROM_MAGIC);
- rom->id = cpu_to_le32(d->id);
- rom->log_level = cpu_to_le32(d->guestdebug);
- rom->modes_offset = cpu_to_le32(sizeof(QXLRom));
-
- rom->slot_gen_bits = MEMSLOT_GENERATION_BITS;
- rom->slot_id_bits = MEMSLOT_SLOT_BITS;
- rom->slots_start = 1;
- rom->slots_end = NUM_MEMSLOTS - 1;
- rom->n_surfaces = cpu_to_le32(d->ssd.num_surfaces);
-
- for (i = 0, n = 0; i < ARRAY_SIZE(qxl_modes); i++) {
- fb = qxl_modes[i].y_res * qxl_modes[i].stride;
- if (fb > d->vgamem_size) {
- continue;
- }
- modes->modes[n].id = cpu_to_le32(i);
- modes->modes[n].x_res = cpu_to_le32(qxl_modes[i].x_res);
- modes->modes[n].y_res = cpu_to_le32(qxl_modes[i].y_res);
- modes->modes[n].bits = cpu_to_le32(qxl_modes[i].bits);
- modes->modes[n].stride = cpu_to_le32(qxl_modes[i].stride);
- modes->modes[n].x_mili = cpu_to_le32(qxl_modes[i].x_mili);
- modes->modes[n].y_mili = cpu_to_le32(qxl_modes[i].y_mili);
- modes->modes[n].orientation = cpu_to_le32(qxl_modes[i].orientation);
- n++;
- }
- modes->n_modes = cpu_to_le32(n);
-
- ram_header_size = ALIGN(sizeof(QXLRam), 4096);
- surface0_area_size = ALIGN(d->vgamem_size, 4096);
- num_pages = d->vga.vram_size;
- num_pages -= ram_header_size;
- num_pages -= surface0_area_size;
- num_pages = num_pages / QXL_PAGE_SIZE;
-
- assert(ram_header_size + surface0_area_size <= d->vga.vram_size);
-
- rom->draw_area_offset = cpu_to_le32(0);
- rom->surface0_area_size = cpu_to_le32(surface0_area_size);
- rom->pages_offset = cpu_to_le32(surface0_area_size);
- rom->num_pages = cpu_to_le32(num_pages);
- rom->ram_header_offset = cpu_to_le32(d->vga.vram_size - ram_header_size);
-
- d->shadow_rom = *rom;
- d->rom = rom;
- d->modes = modes;
-}
-
-static void init_qxl_ram(PCIQXLDevice *d)
-{
- uint8_t *buf;
- uint64_t *item;
-
- buf = d->vga.vram_ptr;
- d->ram = (QXLRam *)(buf + le32_to_cpu(d->shadow_rom.ram_header_offset));
- d->ram->magic = cpu_to_le32(QXL_RAM_MAGIC);
- d->ram->int_pending = cpu_to_le32(0);
- d->ram->int_mask = cpu_to_le32(0);
- d->ram->update_surface = 0;
- d->ram->monitors_config = 0;
- SPICE_RING_INIT(&d->ram->cmd_ring);
- SPICE_RING_INIT(&d->ram->cursor_ring);
- SPICE_RING_INIT(&d->ram->release_ring);
- SPICE_RING_PROD_ITEM(d, &d->ram->release_ring, item);
- assert(item);
- *item = 0;
- qxl_ring_set_dirty(d);
-}
-
-/* can be called from spice server thread context */
-static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
-{
- memory_region_set_dirty(mr, addr, end - addr);
-}
-
-static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
-{
- qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
-}
-
-/* called from spice server thread context only */
-static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
-{
- void *base = qxl->vga.vram_ptr;
- intptr_t offset;
-
- offset = ptr - base;
- assert(offset < qxl->vga.vram_size);
- qxl_set_dirty(&qxl->vga.vram, offset, offset + 3);
-}
-
-/* can be called from spice server thread context */
-static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
-{
- ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
- ram_addr_t end = qxl->vga.vram_size;
- qxl_set_dirty(&qxl->vga.vram, addr, end);
-}
-
-/*
- * keep track of some command state, for savevm/loadvm.
- * called from spice server thread context only
- */
-static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
-{
- switch (le32_to_cpu(ext->cmd.type)) {
- case QXL_CMD_SURFACE:
- {
- QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-
- if (!cmd) {
- return 1;
- }
- uint32_t id = le32_to_cpu(cmd->surface_id);
-
- if (id >= qxl->ssd.num_surfaces) {
- qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE id %d >= %d", id,
- qxl->ssd.num_surfaces);
- return 1;
- }
- if (cmd->type == QXL_SURFACE_CMD_CREATE &&
- (cmd->u.surface_create.stride & 0x03) != 0) {
- qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE stride = %d %% 4 != 0\n",
- cmd->u.surface_create.stride);
- return 1;
- }
- qemu_mutex_lock(&qxl->track_lock);
- if (cmd->type == QXL_SURFACE_CMD_CREATE) {
- qxl->guest_surfaces.cmds[id] = ext->cmd.data;
- qxl->guest_surfaces.count++;
- if (qxl->guest_surfaces.max < qxl->guest_surfaces.count)
- qxl->guest_surfaces.max = qxl->guest_surfaces.count;
- }
- if (cmd->type == QXL_SURFACE_CMD_DESTROY) {
- qxl->guest_surfaces.cmds[id] = 0;
- qxl->guest_surfaces.count--;
- }
- qemu_mutex_unlock(&qxl->track_lock);
- break;
- }
- case QXL_CMD_CURSOR:
- {
- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
-
- if (!cmd) {
- return 1;
- }
- if (cmd->type == QXL_CURSOR_SET) {
- qemu_mutex_lock(&qxl->track_lock);
- qxl->guest_cursor = ext->cmd.data;
- qemu_mutex_unlock(&qxl->track_lock);
- }
- break;
- }
- }
- return 0;
-}
-
-/* spice display interface callbacks */
-
-static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-
- trace_qxl_interface_attach_worker(qxl->id);
- qxl->ssd.worker = qxl_worker;
-}
-
-static void interface_set_compression_level(QXLInstance *sin, int level)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-
- trace_qxl_interface_set_compression_level(qxl->id, level);
- qxl->shadow_rom.compression_level = cpu_to_le32(level);
- qxl->rom->compression_level = cpu_to_le32(level);
- qxl_rom_set_dirty(qxl);
-}
-
-static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-
- if (!qemu_spice_display_is_running(&qxl->ssd)) {
- return;
- }
-
- trace_qxl_interface_set_mm_time(qxl->id, mm_time);
- qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
- qxl->rom->mm_clock = cpu_to_le32(mm_time);
- qxl_rom_set_dirty(qxl);
-}
-
-static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-
- trace_qxl_interface_get_init_info(qxl->id);
- info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
- info->memslot_id_bits = MEMSLOT_SLOT_BITS;
- info->num_memslots = NUM_MEMSLOTS;
- info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
- info->internal_groupslot_id = 0;
- info->qxl_ram_size =
- le32_to_cpu(qxl->shadow_rom.num_pages) << QXL_PAGE_BITS;
- info->n_surfaces = qxl->ssd.num_surfaces;
-}
-
-static const char *qxl_mode_to_string(int mode)
-{
- switch (mode) {
- case QXL_MODE_COMPAT:
- return "compat";
- case QXL_MODE_NATIVE:
- return "native";
- case QXL_MODE_UNDEFINED:
- return "undefined";
- case QXL_MODE_VGA:
- return "vga";
- }
- return "INVALID";
-}
-
-static const char *io_port_to_string(uint32_t io_port)
-{
- if (io_port >= QXL_IO_RANGE_SIZE) {
- return "out of range";
- }
- static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {
- [QXL_IO_NOTIFY_CMD] = "QXL_IO_NOTIFY_CMD",
- [QXL_IO_NOTIFY_CURSOR] = "QXL_IO_NOTIFY_CURSOR",
- [QXL_IO_UPDATE_AREA] = "QXL_IO_UPDATE_AREA",
- [QXL_IO_UPDATE_IRQ] = "QXL_IO_UPDATE_IRQ",
- [QXL_IO_NOTIFY_OOM] = "QXL_IO_NOTIFY_OOM",
- [QXL_IO_RESET] = "QXL_IO_RESET",
- [QXL_IO_SET_MODE] = "QXL_IO_SET_MODE",
- [QXL_IO_LOG] = "QXL_IO_LOG",
- [QXL_IO_MEMSLOT_ADD] = "QXL_IO_MEMSLOT_ADD",
- [QXL_IO_MEMSLOT_DEL] = "QXL_IO_MEMSLOT_DEL",
- [QXL_IO_DETACH_PRIMARY] = "QXL_IO_DETACH_PRIMARY",
- [QXL_IO_ATTACH_PRIMARY] = "QXL_IO_ATTACH_PRIMARY",
- [QXL_IO_CREATE_PRIMARY] = "QXL_IO_CREATE_PRIMARY",
- [QXL_IO_DESTROY_PRIMARY] = "QXL_IO_DESTROY_PRIMARY",
- [QXL_IO_DESTROY_SURFACE_WAIT] = "QXL_IO_DESTROY_SURFACE_WAIT",
- [QXL_IO_DESTROY_ALL_SURFACES] = "QXL_IO_DESTROY_ALL_SURFACES",
- [QXL_IO_UPDATE_AREA_ASYNC] = "QXL_IO_UPDATE_AREA_ASYNC",
- [QXL_IO_MEMSLOT_ADD_ASYNC] = "QXL_IO_MEMSLOT_ADD_ASYNC",
- [QXL_IO_CREATE_PRIMARY_ASYNC] = "QXL_IO_CREATE_PRIMARY_ASYNC",
- [QXL_IO_DESTROY_PRIMARY_ASYNC] = "QXL_IO_DESTROY_PRIMARY_ASYNC",
- [QXL_IO_DESTROY_SURFACE_ASYNC] = "QXL_IO_DESTROY_SURFACE_ASYNC",
- [QXL_IO_DESTROY_ALL_SURFACES_ASYNC]
- = "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
- [QXL_IO_FLUSH_SURFACES_ASYNC] = "QXL_IO_FLUSH_SURFACES_ASYNC",
- [QXL_IO_FLUSH_RELEASE] = "QXL_IO_FLUSH_RELEASE",
- [QXL_IO_MONITORS_CONFIG_ASYNC] = "QXL_IO_MONITORS_CONFIG_ASYNC",
- };
- return io_port_to_string[io_port];
-}
-
-/* called from spice server thread context only */
-static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- SimpleSpiceUpdate *update;
- QXLCommandRing *ring;
- QXLCommand *cmd;
- int notify, ret;
-
- trace_qxl_ring_command_check(qxl->id, qxl_mode_to_string(qxl->mode));
-
- switch (qxl->mode) {
- case QXL_MODE_VGA:
- ret = false;
- qemu_mutex_lock(&qxl->ssd.lock);
- update = QTAILQ_FIRST(&qxl->ssd.updates);
- if (update != NULL) {
- QTAILQ_REMOVE(&qxl->ssd.updates, update, next);
- *ext = update->ext;
- ret = true;
- }
- qemu_mutex_unlock(&qxl->ssd.lock);
- if (ret) {
- trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
- qxl_log_command(qxl, "vga", ext);
- }
- return ret;
- case QXL_MODE_COMPAT:
- case QXL_MODE_NATIVE:
- case QXL_MODE_UNDEFINED:
- ring = &qxl->ram->cmd_ring;
- if (qxl->guest_bug || SPICE_RING_IS_EMPTY(ring)) {
- return false;
- }
- SPICE_RING_CONS_ITEM(qxl, ring, cmd);
- if (!cmd) {
- return false;
- }
- ext->cmd = *cmd;
- ext->group_id = MEMSLOT_GROUP_GUEST;
- ext->flags = qxl->cmdflags;
- SPICE_RING_POP(ring, notify);
- qxl_ring_set_dirty(qxl);
- if (notify) {
- qxl_send_events(qxl, QXL_INTERRUPT_DISPLAY);
- }
- qxl->guest_primary.commands++;
- qxl_track_command(qxl, ext);
- qxl_log_command(qxl, "cmd", ext);
- trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
- return true;
- default:
- return false;
- }
-}
-
-/* called from spice server thread context only */
-static int interface_req_cmd_notification(QXLInstance *sin)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- int wait = 1;
-
- trace_qxl_ring_command_req_notification(qxl->id);
- switch (qxl->mode) {
- case QXL_MODE_COMPAT:
- case QXL_MODE_NATIVE:
- case QXL_MODE_UNDEFINED:
- SPICE_RING_CONS_WAIT(&qxl->ram->cmd_ring, wait);
- qxl_ring_set_dirty(qxl);
- break;
- default:
- /* nothing */
- break;
- }
- return wait;
-}
-
-/* called from spice server thread context only */
-static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
-{
- QXLReleaseRing *ring = &d->ram->release_ring;
- uint64_t *item;
- int notify;
-
-#define QXL_FREE_BUNCH_SIZE 32
-
- if (ring->prod - ring->cons + 1 == ring->num_items) {
- /* ring full -- can't push */
- return;
- }
- if (!flush && d->oom_running) {
- /* collect everything from oom handler before pushing */
- return;
- }
- if (!flush && d->num_free_res < QXL_FREE_BUNCH_SIZE) {
- /* collect a bit more before pushing */
- return;
- }
-
- SPICE_RING_PUSH(ring, notify);
- trace_qxl_ring_res_push(d->id, qxl_mode_to_string(d->mode),
- d->guest_surfaces.count, d->num_free_res,
- d->last_release, notify ? "yes" : "no");
- trace_qxl_ring_res_push_rest(d->id, ring->prod - ring->cons,
- ring->num_items, ring->prod, ring->cons);
- if (notify) {
- qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
- }
- SPICE_RING_PROD_ITEM(d, ring, item);
- if (!item) {
- return;
- }
- *item = 0;
- d->num_free_res = 0;
- d->last_release = NULL;
- qxl_ring_set_dirty(d);
-}
-
-/* called from spice server thread context only */
-static void interface_release_resource(QXLInstance *sin,
- QXLReleaseInfoExt ext)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- QXLReleaseRing *ring;
- uint64_t *item, id;
-
- if (ext.group_id == MEMSLOT_GROUP_HOST) {
- /* host group -> vga mode update request */
- QXLCommandExt *cmdext = (void *)(intptr_t)(ext.info->id);
- SimpleSpiceUpdate *update;
- g_assert(cmdext->cmd.type == QXL_CMD_DRAW);
- update = container_of(cmdext, SimpleSpiceUpdate, ext);
- qemu_spice_destroy_update(&qxl->ssd, update);
- return;
- }
-
- /*
- * ext->info points into guest-visible memory
- * pci bar 0, $command.release_info
- */
- ring = &qxl->ram->release_ring;
- SPICE_RING_PROD_ITEM(qxl, ring, item);
- if (!item) {
- return;
- }
- if (*item == 0) {
- /* stick head into the ring */
- id = ext.info->id;
- ext.info->next = 0;
- qxl_ram_set_dirty(qxl, &ext.info->next);
- *item = id;
- qxl_ring_set_dirty(qxl);
- } else {
- /* append item to the list */
- qxl->last_release->next = ext.info->id;
- qxl_ram_set_dirty(qxl, &qxl->last_release->next);
- ext.info->next = 0;
- qxl_ram_set_dirty(qxl, &ext.info->next);
- }
- qxl->last_release = ext.info;
- qxl->num_free_res++;
- trace_qxl_ring_res_put(qxl->id, qxl->num_free_res);
- qxl_push_free_res(qxl, 0);
-}
-
-/* called from spice server thread context only */
-static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- QXLCursorRing *ring;
- QXLCommand *cmd;
- int notify;
-
- trace_qxl_ring_cursor_check(qxl->id, qxl_mode_to_string(qxl->mode));
-
- switch (qxl->mode) {
- case QXL_MODE_COMPAT:
- case QXL_MODE_NATIVE:
- case QXL_MODE_UNDEFINED:
- ring = &qxl->ram->cursor_ring;
- if (SPICE_RING_IS_EMPTY(ring)) {
- return false;
- }
- SPICE_RING_CONS_ITEM(qxl, ring, cmd);
- if (!cmd) {
- return false;
- }
- ext->cmd = *cmd;
- ext->group_id = MEMSLOT_GROUP_GUEST;
- ext->flags = qxl->cmdflags;
- SPICE_RING_POP(ring, notify);
- qxl_ring_set_dirty(qxl);
- if (notify) {
- qxl_send_events(qxl, QXL_INTERRUPT_CURSOR);
- }
- qxl->guest_primary.commands++;
- qxl_track_command(qxl, ext);
- qxl_log_command(qxl, "csr", ext);
- if (qxl->id == 0) {
- qxl_render_cursor(qxl, ext);
- }
- trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode));
- return true;
- default:
- return false;
- }
-}
-
-/* called from spice server thread context only */
-static int interface_req_cursor_notification(QXLInstance *sin)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- int wait = 1;
-
- trace_qxl_ring_cursor_req_notification(qxl->id);
- switch (qxl->mode) {
- case QXL_MODE_COMPAT:
- case QXL_MODE_NATIVE:
- case QXL_MODE_UNDEFINED:
- SPICE_RING_CONS_WAIT(&qxl->ram->cursor_ring, wait);
- qxl_ring_set_dirty(qxl);
- break;
- default:
- /* nothing */
- break;
- }
- return wait;
-}
-
-/* called from spice server thread context */
-static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
-{
- /*
- * Called by spice-server as a result of a QXL_CMD_UPDATE which is not in
- * use by xf86-video-qxl and is defined out in the qxl windows driver.
- * Probably was at some earlier version that is prior to git start (2009),
- * and is still guest trigerrable.
- */
- fprintf(stderr, "%s: deprecated\n", __func__);
-}
-
-/* called from spice server thread context only */
-static int interface_flush_resources(QXLInstance *sin)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- int ret;
-
- ret = qxl->num_free_res;
- if (ret) {
- qxl_push_free_res(qxl, 1);
- }
- return ret;
-}
-
-static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
-
-/* called from spice server thread context only */
-static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
-{
- uint32_t current_async;
-
- qemu_mutex_lock(&qxl->async_lock);
- current_async = qxl->current_async;
- qxl->current_async = QXL_UNDEFINED_IO;
- qemu_mutex_unlock(&qxl->async_lock);
-
- trace_qxl_interface_async_complete_io(qxl->id, current_async, cookie);
- if (!cookie) {
- fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
- return;
- }
- if (cookie && current_async != cookie->io) {
- fprintf(stderr,
- "qxl: %s: error: current_async = %d != %"
- PRId64 " = cookie->io\n", __func__, current_async, cookie->io);
- }
- switch (current_async) {
- case QXL_IO_MEMSLOT_ADD_ASYNC:
- case QXL_IO_DESTROY_PRIMARY_ASYNC:
- case QXL_IO_UPDATE_AREA_ASYNC:
- case QXL_IO_FLUSH_SURFACES_ASYNC:
- case QXL_IO_MONITORS_CONFIG_ASYNC:
- break;
- case QXL_IO_CREATE_PRIMARY_ASYNC:
- qxl_create_guest_primary_complete(qxl);
- break;
- case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
- qxl_spice_destroy_surfaces_complete(qxl);
- break;
- case QXL_IO_DESTROY_SURFACE_ASYNC:
- qxl_spice_destroy_surface_wait_complete(qxl, cookie->u.surface_id);
- break;
- default:
- fprintf(stderr, "qxl: %s: unexpected current_async %d\n", __func__,
- current_async);
- }
- qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
-}
-
-/* called from spice server thread context only */
-static void interface_update_area_complete(QXLInstance *sin,
- uint32_t surface_id,
- QXLRect *dirty, uint32_t num_updated_rects)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- int i;
- int qxl_i;
-
- qemu_mutex_lock(&qxl->ssd.lock);
- if (surface_id != 0 || !qxl->render_update_cookie_num) {
- qemu_mutex_unlock(&qxl->ssd.lock);
- return;
- }
- trace_qxl_interface_update_area_complete(qxl->id, surface_id, dirty->left,
- dirty->right, dirty->top, dirty->bottom);
- trace_qxl_interface_update_area_complete_rest(qxl->id, num_updated_rects);
- if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
- /*
- * overflow - treat this as a full update. Not expected to be common.
- */
- trace_qxl_interface_update_area_complete_overflow(qxl->id,
- QXL_NUM_DIRTY_RECTS);
- qxl->guest_primary.resized = 1;
- }
- if (qxl->guest_primary.resized) {
- /*
- * Don't bother copying or scheduling the bh since we will flip
- * the whole area anyway on completion of the update_area async call
- */
- qemu_mutex_unlock(&qxl->ssd.lock);
- return;
- }
- qxl_i = qxl->num_dirty_rects;
- for (i = 0; i < num_updated_rects; i++) {
- qxl->dirty[qxl_i++] = dirty[i];
- }
- qxl->num_dirty_rects += num_updated_rects;
- trace_qxl_interface_update_area_complete_schedule_bh(qxl->id,
- qxl->num_dirty_rects);
- qemu_bh_schedule(qxl->update_area_bh);
- qemu_mutex_unlock(&qxl->ssd.lock);
-}
-
-/* called from spice server thread context only */
-static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
-
- switch (cookie->type) {
- case QXL_COOKIE_TYPE_IO:
- interface_async_complete_io(qxl, cookie);
- g_free(cookie);
- break;
- case QXL_COOKIE_TYPE_RENDER_UPDATE_AREA:
- qxl_render_update_area_done(qxl, cookie);
- break;
- case QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG:
- break;
- default:
- fprintf(stderr, "qxl: %s: unexpected cookie type %d\n",
- __func__, cookie->type);
- g_free(cookie);
- }
-}
-
-/* called from spice server thread context only */
-static void interface_set_client_capabilities(QXLInstance *sin,
- uint8_t client_present,
- uint8_t caps[58])
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
-
- if (qxl->revision < 4) {
- trace_qxl_set_client_capabilities_unsupported_by_revision(qxl->id,
- qxl->revision);
- return;
- }
-
- if (runstate_check(RUN_STATE_INMIGRATE) ||
- runstate_check(RUN_STATE_POSTMIGRATE)) {
- return;
- }
-
- qxl->shadow_rom.client_present = client_present;
- memcpy(qxl->shadow_rom.client_capabilities, caps,
- sizeof(qxl->shadow_rom.client_capabilities));
- qxl->rom->client_present = client_present;
- memcpy(qxl->rom->client_capabilities, caps,
- sizeof(qxl->rom->client_capabilities));
- qxl_rom_set_dirty(qxl);
-
- qxl_send_events(qxl, QXL_INTERRUPT_CLIENT);
-}
-
-static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
-{
- /*
- * zlib xors the seed with 0xffffffff, and xors the result
- * again with 0xffffffff; Both are not done with linux's crc32,
- * which we want to be compatible with, so undo that.
- */
- return crc32(0xffffffff, p, len) ^ 0xffffffff;
-}
-
-/* called from main context only */
-static int interface_client_monitors_config(QXLInstance *sin,
- VDAgentMonitorsConfig *monitors_config)
-{
- PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
- int i;
- unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads);
-
- if (qxl->revision < 4) {
- trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
- qxl->revision);
- return 0;
- }
- /*
- * Older windows drivers set int_mask to 0 when their ISR is called,
- * then later set it to ~0. So it doesn't relate to the actual interrupts
- * handled. However, they are old, so clearly they don't support this
- * interrupt
- */
- if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 ||
- !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) {
- trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id,
- qxl->ram->int_mask,
- monitors_config);
- return 0;
- }
- if (!monitors_config) {
- return 1;
- }
-
-#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
- /* limit number of outputs based on setting limit */
- if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
- max_outputs = qxl->max_outputs;
- }
-#endif
-
- memset(&rom->client_monitors_config, 0,
- sizeof(rom->client_monitors_config));
- rom->client_monitors_config.count = monitors_config->num_of_monitors;
- /* monitors_config->flags ignored */
- if (rom->client_monitors_config.count >= max_outputs) {
- trace_qxl_client_monitors_config_capped(qxl->id,
- monitors_config->num_of_monitors,
- max_outputs);
- rom->client_monitors_config.count = max_outputs;
- }
- for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
- VDAgentMonConfig *monitor = &monitors_config->monitors[i];
- QXLURect *rect = &rom->client_monitors_config.heads[i];
- /* monitor->depth ignored */
- rect->left = monitor->x;
- rect->top = monitor->y;
- rect->right = monitor->x + monitor->width;
- rect->bottom = monitor->y + monitor->height;
- }
- rom->client_monitors_config_crc = qxl_crc32(
- (const uint8_t *)&rom->client_monitors_config,
- sizeof(rom->client_monitors_config));
- trace_qxl_client_monitors_config_crc(qxl->id,
- sizeof(rom->client_monitors_config),
- rom->client_monitors_config_crc);
-
- trace_qxl_interrupt_client_monitors_config(qxl->id,
- rom->client_monitors_config.count,
- rom->client_monitors_config.heads);
- qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
- return 1;
-}
-
-static const QXLInterface qxl_interface = {
- .base.type = SPICE_INTERFACE_QXL,
- .base.description = "qxl gpu",
- .base.major_version = SPICE_INTERFACE_QXL_MAJOR,
- .base.minor_version = SPICE_INTERFACE_QXL_MINOR,
-
- .attache_worker = interface_attach_worker,
- .set_compression_level = interface_set_compression_level,
- .set_mm_time = interface_set_mm_time,
- .get_init_info = interface_get_init_info,
-
- /* the callbacks below are called from spice server thread context */
- .get_command = interface_get_command,
- .req_cmd_notification = interface_req_cmd_notification,
- .release_resource = interface_release_resource,
- .get_cursor_command = interface_get_cursor_command,
- .req_cursor_notification = interface_req_cursor_notification,
- .notify_update = interface_notify_update,
- .flush_resources = interface_flush_resources,
- .async_complete = interface_async_complete,
- .update_area_complete = interface_update_area_complete,
- .set_client_capabilities = interface_set_client_capabilities,
- .client_monitors_config = interface_client_monitors_config,
-};
-
-static const GraphicHwOps qxl_ops = {
- .gfx_update = qxl_hw_update,
-};
-
-static void qxl_enter_vga_mode(PCIQXLDevice *d)
-{
- if (d->mode == QXL_MODE_VGA) {
- return;
- }
- trace_qxl_enter_vga_mode(d->id);
-#if SPICE_SERVER_VERSION >= 0x000c03 /* release 0.12.3 */
- spice_qxl_driver_unload(&d->ssd.qxl);
-#endif
- graphic_console_set_hwops(d->ssd.dcl.con, d->vga.hw_ops, &d->vga);
- update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_DEFAULT);
- qemu_spice_create_host_primary(&d->ssd);
- d->mode = QXL_MODE_VGA;
- vga_dirty_log_start(&d->vga);
- graphic_hw_update(d->vga.con);
-}
-
-static void qxl_exit_vga_mode(PCIQXLDevice *d)
-{
- if (d->mode != QXL_MODE_VGA) {
- return;
- }
- trace_qxl_exit_vga_mode(d->id);
- graphic_console_set_hwops(d->ssd.dcl.con, &qxl_ops, d);
- update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_IDLE);
- vga_dirty_log_stop(&d->vga);
- qxl_destroy_primary(d, QXL_SYNC);
-}
-
-static void qxl_update_irq(PCIQXLDevice *d)
-{
- uint32_t pending = le32_to_cpu(d->ram->int_pending);
- uint32_t mask = le32_to_cpu(d->ram->int_mask);
- int level = !!(pending & mask);
- pci_set_irq(&d->pci, level);
- qxl_ring_set_dirty(d);
-}
-
-static void qxl_check_state(PCIQXLDevice *d)
-{
- QXLRam *ram = d->ram;
- int spice_display_running = qemu_spice_display_is_running(&d->ssd);
-
- assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
- assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
-}
-
-static void qxl_reset_state(PCIQXLDevice *d)
-{
- QXLRom *rom = d->rom;
-
- qxl_check_state(d);
- d->shadow_rom.update_id = cpu_to_le32(0);
- *rom = d->shadow_rom;
- qxl_rom_set_dirty(d);
- init_qxl_ram(d);
- d->num_free_res = 0;
- d->last_release = NULL;
- memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
- qxl_update_irq(d);
-}
-
-static void qxl_soft_reset(PCIQXLDevice *d)
-{
- trace_qxl_soft_reset(d->id);
- qxl_check_state(d);
- qxl_clear_guest_bug(d);
- qemu_mutex_lock(&d->async_lock);
- d->current_async = QXL_UNDEFINED_IO;
- qemu_mutex_unlock(&d->async_lock);
-
- if (d->id == 0) {
- qxl_enter_vga_mode(d);
- } else {
- d->mode = QXL_MODE_UNDEFINED;
- }
-}
-
-static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
-{
- bool startstop = qemu_spice_display_is_running(&d->ssd);
-
- trace_qxl_hard_reset(d->id, loadvm);
-
- if (startstop) {
- qemu_spice_display_stop();
- }
-
- qxl_spice_reset_cursor(d);
- qxl_spice_reset_image_cache(d);
- qxl_reset_surfaces(d);
- qxl_reset_memslots(d);
-
- /* pre loadvm reset must not touch QXLRam. This lives in
- * device memory, is migrated together with RAM and thus
- * already loaded at this point */
- if (!loadvm) {
- qxl_reset_state(d);
- }
- qemu_spice_create_host_memslot(&d->ssd);
- qxl_soft_reset(d);
-
- if (startstop) {
- qemu_spice_display_start();
- }
-}
-
-static void qxl_reset_handler(DeviceState *dev)
-{
- PCIQXLDevice *d = PCI_QXL(PCI_DEVICE(dev));
-
- qxl_hard_reset(d, 0);
-}
-
-static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- VGACommonState *vga = opaque;
- PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
-
- trace_qxl_io_write_vga(qxl->id, qxl_mode_to_string(qxl->mode), addr, val);
- if (qxl->mode != QXL_MODE_VGA) {
- qxl_destroy_primary(qxl, QXL_SYNC);
- qxl_soft_reset(qxl);
- }
- vga_ioport_write(opaque, addr, val);
-}
-
-static const MemoryRegionPortio qxl_vga_portio_list[] = {
- { 0x04, 2, 1, .read = vga_ioport_read,
- .write = qxl_vga_ioport_write }, /* 3b4 */
- { 0x0a, 1, 1, .read = vga_ioport_read,
- .write = qxl_vga_ioport_write }, /* 3ba */
- { 0x10, 16, 1, .read = vga_ioport_read,
- .write = qxl_vga_ioport_write }, /* 3c0 */
- { 0x24, 2, 1, .read = vga_ioport_read,
- .write = qxl_vga_ioport_write }, /* 3d4 */
- { 0x2a, 1, 1, .read = vga_ioport_read,
- .write = qxl_vga_ioport_write }, /* 3da */
- PORTIO_END_OF_LIST(),
-};
-
-static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
- qxl_async_io async)
-{
- static const int regions[] = {
- QXL_RAM_RANGE_INDEX,
- QXL_VRAM_RANGE_INDEX,
- QXL_VRAM64_RANGE_INDEX,
- };
- uint64_t guest_start;
- uint64_t guest_end;
- int pci_region;
- pcibus_t pci_start;
- pcibus_t pci_end;
- intptr_t virt_start;
- QXLDevMemSlot memslot;
- int i;
-
- guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
- guest_end = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
-
- trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
-
- if (slot_id >= NUM_MEMSLOTS) {
- qxl_set_guest_bug(d, "%s: slot_id >= NUM_MEMSLOTS %d >= %d", __func__,
- slot_id, NUM_MEMSLOTS);
- return 1;
- }
- if (guest_start > guest_end) {
- qxl_set_guest_bug(d, "%s: guest_start > guest_end 0x%" PRIx64
- " > 0x%" PRIx64, __func__, guest_start, guest_end);
- return 1;
- }
-
- for (i = 0; i < ARRAY_SIZE(regions); i++) {
- pci_region = regions[i];
- pci_start = d->pci.io_regions[pci_region].addr;
- pci_end = pci_start + d->pci.io_regions[pci_region].size;
- /* mapped? */
- if (pci_start == -1) {
- continue;
- }
- /* start address in range ? */
- if (guest_start < pci_start || guest_start > pci_end) {
- continue;
- }
- /* end address in range ? */
- if (guest_end > pci_end) {
- continue;
- }
- /* passed */
- break;
- }
- if (i == ARRAY_SIZE(regions)) {
- qxl_set_guest_bug(d, "%s: finished loop without match", __func__);
- return 1;
- }
-
- switch (pci_region) {
- case QXL_RAM_RANGE_INDEX:
- virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
- break;
- case QXL_VRAM_RANGE_INDEX:
- case 4 /* vram 64bit */:
- virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
- break;
- default:
- /* should not happen */
- qxl_set_guest_bug(d, "%s: pci_region = %d", __func__, pci_region);
- return 1;
- }
-
- memslot.slot_id = slot_id;
- memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
- memslot.virt_start = virt_start + (guest_start - pci_start);
- memslot.virt_end = virt_start + (guest_end - pci_start);
- memslot.addr_delta = memslot.virt_start - delta;
- memslot.generation = d->rom->slot_generation = 0;
- qxl_rom_set_dirty(d);
-
- qemu_spice_add_memslot(&d->ssd, &memslot, async);
- d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
- d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
- d->guest_slots[slot_id].delta = delta;
- d->guest_slots[slot_id].active = 1;
- return 0;
-}
-
-static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
-{
- qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
- d->guest_slots[slot_id].active = 0;
-}
-
-static void qxl_reset_memslots(PCIQXLDevice *d)
-{
- qxl_spice_reset_memslots(d);
- memset(&d->guest_slots, 0, sizeof(d->guest_slots));
-}
-
-static void qxl_reset_surfaces(PCIQXLDevice *d)
-{
- trace_qxl_reset_surfaces(d->id);
- d->mode = QXL_MODE_UNDEFINED;
- qxl_spice_destroy_surfaces(d, QXL_SYNC);
-}
-
-/* can be also called from spice server thread context */
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
-{
- uint64_t phys = le64_to_cpu(pqxl);
- uint32_t slot = (phys >> (64 - 8)) & 0xff;
- uint64_t offset = phys & 0xffffffffffff;
-
- switch (group_id) {
- case MEMSLOT_GROUP_HOST:
- return (void *)(intptr_t)offset;
- case MEMSLOT_GROUP_GUEST:
- if (slot >= NUM_MEMSLOTS) {
- qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
- NUM_MEMSLOTS);
- return NULL;
- }
- if (!qxl->guest_slots[slot].active) {
- qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
- return NULL;
- }
- if (offset < qxl->guest_slots[slot].delta) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
- slot, offset, qxl->guest_slots[slot].delta);
- return NULL;
- }
- offset -= qxl->guest_slots[slot].delta;
- if (offset > qxl->guest_slots[slot].size) {
- qxl_set_guest_bug(qxl,
- "slot %d offset %"PRIu64" > size %"PRIu64"\n",
- slot, offset, qxl->guest_slots[slot].size);
- return NULL;
- }
- return qxl->guest_slots[slot].ptr + offset;
- }
- return NULL;
-}
-
-static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
-{
- /* for local rendering */
- qxl_render_resize(qxl);
-}
-
-static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
- qxl_async_io async)
-{
- QXLDevSurfaceCreate surface;
- QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
- uint32_t requested_height = le32_to_cpu(sc->height);
- int requested_stride = le32_to_cpu(sc->stride);
-
- if (requested_stride == INT32_MIN ||
- abs(requested_stride) * (uint64_t)requested_height
- > qxl->vgamem_size) {
- qxl_set_guest_bug(qxl, "%s: requested primary larger than framebuffer"
- " stride %d x height %" PRIu32 " > %" PRIu32,
- __func__, requested_stride, requested_height,
- qxl->vgamem_size);
- return;
- }
-
- if (qxl->mode == QXL_MODE_NATIVE) {
- qxl_set_guest_bug(qxl, "%s: nop since already in QXL_MODE_NATIVE",
- __func__);
- }
- qxl_exit_vga_mode(qxl);
-
- surface.format = le32_to_cpu(sc->format);
- surface.height = le32_to_cpu(sc->height);
- surface.mem = le64_to_cpu(sc->mem);
- surface.position = le32_to_cpu(sc->position);
- surface.stride = le32_to_cpu(sc->stride);
- surface.width = le32_to_cpu(sc->width);
- surface.type = le32_to_cpu(sc->type);
- surface.flags = le32_to_cpu(sc->flags);
- trace_qxl_create_guest_primary(qxl->id, sc->width, sc->height, sc->mem,
- sc->format, sc->position);
- trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
- sc->flags);
-
- if ((surface.stride & 0x3) != 0) {
- qxl_set_guest_bug(qxl, "primary surface stride = %d %% 4 != 0",
- surface.stride);
- return;
- }
-
- surface.mouse_mode = true;
- surface.group_id = MEMSLOT_GROUP_GUEST;
- if (loadvm) {
- surface.flags |= QXL_SURF_FLAG_KEEP_DATA;
- }
-
- qxl->mode = QXL_MODE_NATIVE;
- qxl->cmdflags = 0;
- qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async);
-
- if (async == QXL_SYNC) {
- qxl_create_guest_primary_complete(qxl);
- }
-}
-
-/* return 1 if surface destoy was initiated (in QXL_ASYNC case) or
- * done (in QXL_SYNC case), 0 otherwise. */
-static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
-{
- if (d->mode == QXL_MODE_UNDEFINED) {
- return 0;
- }
- trace_qxl_destroy_primary(d->id);
- d->mode = QXL_MODE_UNDEFINED;
- qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
- qxl_spice_reset_cursor(d);
- return 1;
-}
-
-static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm)
-{
- pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
- pcibus_t end = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start;
- QXLMode *mode = d->modes->modes + modenr;
- uint64_t devmem = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
- QXLMemSlot slot = {
- .mem_start = start,
- .mem_end = end
- };
-
- if (modenr >= d->modes->n_modes) {
- qxl_set_guest_bug(d, "mode number out of range");
- return;
- }
-
- QXLSurfaceCreate surface = {
- .width = mode->x_res,
- .height = mode->y_res,
- .stride = -mode->x_res * 4,
- .format = SPICE_SURFACE_FMT_32_xRGB,
- .flags = loadvm ? QXL_SURF_FLAG_KEEP_DATA : 0,
- .mouse_mode = true,
- .mem = devmem + d->shadow_rom.draw_area_offset,
- };
-
- trace_qxl_set_mode(d->id, modenr, mode->x_res, mode->y_res, mode->bits,
- devmem);
- if (!loadvm) {
- qxl_hard_reset(d, 0);
- }
-
- d->guest_slots[0].slot = slot;
- assert(qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0);
-
- d->guest_primary.surface = surface;
- qxl_create_guest_primary(d, 0, QXL_SYNC);
-
- d->mode = QXL_MODE_COMPAT;
- d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
- if (mode->bits == 16) {
- d->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP;
- }
- d->shadow_rom.mode = cpu_to_le32(modenr);
- d->rom->mode = cpu_to_le32(modenr);
- qxl_rom_set_dirty(d);
-}
-
-static void ioport_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- PCIQXLDevice *d = opaque;
- uint32_t io_port = addr;
- qxl_async_io async = QXL_SYNC;
- uint32_t orig_io_port = io_port;
-
- if (d->guest_bug && io_port != QXL_IO_RESET) {
- return;
- }
-
- if (d->revision <= QXL_REVISION_STABLE_V10 &&
- io_port > QXL_IO_FLUSH_RELEASE) {
- qxl_set_guest_bug(d, "unsupported io %d for revision %d\n",
- io_port, d->revision);
- return;
- }
-
- switch (io_port) {
- case QXL_IO_RESET:
- case QXL_IO_SET_MODE:
- case QXL_IO_MEMSLOT_ADD:
- case QXL_IO_MEMSLOT_DEL:
- case QXL_IO_CREATE_PRIMARY:
- case QXL_IO_UPDATE_IRQ:
- case QXL_IO_LOG:
- case QXL_IO_MEMSLOT_ADD_ASYNC:
- case QXL_IO_CREATE_PRIMARY_ASYNC:
- break;
- default:
- if (d->mode != QXL_MODE_VGA) {
- break;
- }
- trace_qxl_io_unexpected_vga_mode(d->id,
- addr, val, io_port_to_string(io_port));
- /* be nice to buggy guest drivers */
- if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
- io_port < QXL_IO_RANGE_SIZE) {
- qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
- }
- return;
- }
-
- /* we change the io_port to avoid ifdeffery in the main switch */
- orig_io_port = io_port;
- switch (io_port) {
- case QXL_IO_UPDATE_AREA_ASYNC:
- io_port = QXL_IO_UPDATE_AREA;
- goto async_common;
- case QXL_IO_MEMSLOT_ADD_ASYNC:
- io_port = QXL_IO_MEMSLOT_ADD;
- goto async_common;
- case QXL_IO_CREATE_PRIMARY_ASYNC:
- io_port = QXL_IO_CREATE_PRIMARY;
- goto async_common;
- case QXL_IO_DESTROY_PRIMARY_ASYNC:
- io_port = QXL_IO_DESTROY_PRIMARY;
- goto async_common;
- case QXL_IO_DESTROY_SURFACE_ASYNC:
- io_port = QXL_IO_DESTROY_SURFACE_WAIT;
- goto async_common;
- case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
- io_port = QXL_IO_DESTROY_ALL_SURFACES;
- goto async_common;
- case QXL_IO_FLUSH_SURFACES_ASYNC:
- case QXL_IO_MONITORS_CONFIG_ASYNC:
-async_common:
- async = QXL_ASYNC;
- qemu_mutex_lock(&d->async_lock);
- if (d->current_async != QXL_UNDEFINED_IO) {
- qxl_set_guest_bug(d, "%d async started before last (%d) complete",
- io_port, d->current_async);
- qemu_mutex_unlock(&d->async_lock);
- return;
- }
- d->current_async = orig_io_port;
- qemu_mutex_unlock(&d->async_lock);
- break;
- default:
- break;
- }
- trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode),
- addr, io_port_to_string(addr),
- val, size, async);
-
- switch (io_port) {
- case QXL_IO_UPDATE_AREA:
- {
- QXLCookie *cookie = NULL;
- QXLRect update = d->ram->update_area;
-
- if (d->ram->update_surface > d->ssd.num_surfaces) {
- qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
- d->ram->update_surface);
- break;
- }
- if (update.left >= update.right || update.top >= update.bottom ||
- update.left < 0 || update.top < 0) {
- qxl_set_guest_bug(d,
- "QXL_IO_UPDATE_AREA: invalid area (%ux%u)x(%ux%u)\n",
- update.left, update.top, update.right, update.bottom);
- if (update.left == update.right || update.top == update.bottom) {
- /* old drivers may provide empty area, keep going */
- qxl_clear_guest_bug(d);
- goto cancel_async;
- }
- break;
- }
- if (async == QXL_ASYNC) {
- cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_UPDATE_AREA_ASYNC);
- cookie->u.area = update;
- }
- qxl_spice_update_area(d, d->ram->update_surface,
- cookie ? &cookie->u.area : &update,
- NULL, 0, 0, async, cookie);
- break;
- }
- case QXL_IO_NOTIFY_CMD:
- qemu_spice_wakeup(&d->ssd);
- break;
- case QXL_IO_NOTIFY_CURSOR:
- qemu_spice_wakeup(&d->ssd);
- break;
- case QXL_IO_UPDATE_IRQ:
- qxl_update_irq(d);
- break;
- case QXL_IO_NOTIFY_OOM:
- if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
- break;
- }
- d->oom_running = 1;
- qxl_spice_oom(d);
- d->oom_running = 0;
- break;
- case QXL_IO_SET_MODE:
- qxl_set_mode(d, val, 0);
- break;
- case QXL_IO_LOG:
- trace_qxl_io_log(d->id, d->ram->log_buf);
- if (d->guestdebug) {
- fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), d->ram->log_buf);
- }
- break;
- case QXL_IO_RESET:
- qxl_hard_reset(d, 0);
- break;
- case QXL_IO_MEMSLOT_ADD:
- if (val >= NUM_MEMSLOTS) {
- qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
- break;
- }
- if (d->guest_slots[val].active) {
- qxl_set_guest_bug(d,
- "QXL_IO_MEMSLOT_ADD: memory slot already active");
- break;
- }
- d->guest_slots[val].slot = d->ram->mem_slot;
- qxl_add_memslot(d, val, 0, async);
- break;
- case QXL_IO_MEMSLOT_DEL:
- if (val >= NUM_MEMSLOTS) {
- qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
- break;
- }
- qxl_del_memslot(d, val);
- break;
- case QXL_IO_CREATE_PRIMARY:
- if (val != 0) {
- qxl_set_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0",
- async);
- goto cancel_async;
- }
- d->guest_primary.surface = d->ram->create_surface;
- qxl_create_guest_primary(d, 0, async);
- break;
- case QXL_IO_DESTROY_PRIMARY:
- if (val != 0) {
- qxl_set_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
- async);
- goto cancel_async;
- }
- if (!qxl_destroy_primary(d, async)) {
- trace_qxl_io_destroy_primary_ignored(d->id,
- qxl_mode_to_string(d->mode));
- goto cancel_async;
- }
- break;
- case QXL_IO_DESTROY_SURFACE_WAIT:
- if (val >= d->ssd.num_surfaces) {
- qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"
- "%" PRIu64 " >= NUM_SURFACES", async, val);
- goto cancel_async;
- }
- qxl_spice_destroy_surface_wait(d, val, async);
- break;
- case QXL_IO_FLUSH_RELEASE: {
- QXLReleaseRing *ring = &d->ram->release_ring;
- if (ring->prod - ring->cons + 1 == ring->num_items) {
- fprintf(stderr,
- "ERROR: no flush, full release ring [p%d,%dc]\n",
- ring->prod, ring->cons);
- }
- qxl_push_free_res(d, 1 /* flush */);
- break;
- }
- case QXL_IO_FLUSH_SURFACES_ASYNC:
- qxl_spice_flush_surfaces_async(d);
- break;
- case QXL_IO_DESTROY_ALL_SURFACES:
- d->mode = QXL_MODE_UNDEFINED;
- qxl_spice_destroy_surfaces(d, async);
- break;
- case QXL_IO_MONITORS_CONFIG_ASYNC:
- qxl_spice_monitors_config_async(d, 0);
- break;
- default:
- qxl_set_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port);
- }
- return;
-cancel_async:
- if (async) {
- qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
- qemu_mutex_lock(&d->async_lock);
- d->current_async = QXL_UNDEFINED_IO;
- qemu_mutex_unlock(&d->async_lock);
- }
-}
-
-static uint64_t ioport_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PCIQXLDevice *qxl = opaque;
-
- trace_qxl_io_read_unexpected(qxl->id);
- return 0xff;
-}
-
-static const MemoryRegionOps qxl_io_ops = {
- .read = ioport_read,
- .write = ioport_write,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static void qxl_update_irq_bh(void *opaque)
-{
- PCIQXLDevice *d = opaque;
- qxl_update_irq(d);
-}
-
-static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
-{
- uint32_t old_pending;
- uint32_t le_events = cpu_to_le32(events);
-
- trace_qxl_send_events(d->id, events);
- if (!qemu_spice_display_is_running(&d->ssd)) {
- /* spice-server tracks guest running state and should not do this */
- fprintf(stderr, "%s: spice-server bug: guest stopped, ignoring\n",
- __func__);
- trace_qxl_send_events_vm_stopped(d->id, events);
- return;
- }
- old_pending = atomic_fetch_or(&d->ram->int_pending, le_events);
- if ((old_pending & le_events) == le_events) {
- return;
- }
- qemu_bh_schedule(d->update_irq);
-}
-
-/* graphics console */
-
-static void qxl_hw_update(void *opaque)
-{
- PCIQXLDevice *qxl = opaque;
-
- qxl_render_update(qxl);
-}
-
-static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
-{
- uintptr_t vram_start;
- int i;
-
- if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
- return;
- }
-
- /* dirty the primary surface */
- qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
- qxl->shadow_rom.surface0_area_size);
-
- vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
-
- /* dirty the off-screen surfaces */
- for (i = 0; i < qxl->ssd.num_surfaces; i++) {
- QXLSurfaceCmd *cmd;
- intptr_t surface_offset;
- int surface_size;
-
- if (qxl->guest_surfaces.cmds[i] == 0) {
- continue;
- }
-
- cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
- MEMSLOT_GROUP_GUEST);
- assert(cmd);
- assert(cmd->type == QXL_SURFACE_CMD_CREATE);
- surface_offset = (intptr_t)qxl_phys2virt(qxl,
- cmd->u.surface_create.data,
- MEMSLOT_GROUP_GUEST);
- assert(surface_offset);
- surface_offset -= vram_start;
- surface_size = cmd->u.surface_create.height *
- abs(cmd->u.surface_create.stride);
- trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
- qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
- }
-}
-
-static void qxl_vm_change_state_handler(void *opaque, int running,
- RunState state)
-{
- PCIQXLDevice *qxl = opaque;
-
- if (running) {
- /*
- * if qxl_send_events was called from spice server context before
- * migration ended, qxl_update_irq for these events might not have been
- * called
- */
- qxl_update_irq(qxl);
- } else {
- /* make sure surfaces are saved before migration */
- qxl_dirty_surfaces(qxl);
- }
-}
-
-/* display change listener */
-
-static void display_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
-
- if (qxl->mode == QXL_MODE_VGA) {
- qemu_spice_display_update(&qxl->ssd, x, y, w, h);
- }
-}
-
-static void display_switch(DisplayChangeListener *dcl,
- struct DisplaySurface *surface)
-{
- PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
-
- qxl->ssd.ds = surface;
- if (qxl->mode == QXL_MODE_VGA) {
- qemu_spice_display_switch(&qxl->ssd, surface);
- }
-}
-
-static void display_refresh(DisplayChangeListener *dcl)
-{
- PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
-
- if (qxl->mode == QXL_MODE_VGA) {
- qemu_spice_display_refresh(&qxl->ssd);
- }
-}
-
-static DisplayChangeListenerOps display_listener_ops = {
- .dpy_name = "spice/qxl",
- .dpy_gfx_update = display_update,
- .dpy_gfx_switch = display_switch,
- .dpy_refresh = display_refresh,
-};
-
-static void qxl_init_ramsize(PCIQXLDevice *qxl)
-{
- /* vga mode framebuffer / primary surface (bar 0, first part) */
- if (qxl->vgamem_size_mb < 8) {
- qxl->vgamem_size_mb = 8;
- }
- /* XXX: we round vgamem_size_mb up to a nearest power of two and it must be
- * less than vga_common_init()'s maximum on qxl->vga.vram_size (512 now).
- */
- if (qxl->vgamem_size_mb > 256) {
- qxl->vgamem_size_mb = 256;
- }
- qxl->vgamem_size = qxl->vgamem_size_mb * 1024 * 1024;
-
- /* vga ram (bar 0, total) */
- if (qxl->ram_size_mb != -1) {
- qxl->vga.vram_size = qxl->ram_size_mb * 1024 * 1024;
- }
- if (qxl->vga.vram_size < qxl->vgamem_size * 2) {
- qxl->vga.vram_size = qxl->vgamem_size * 2;
- }
-
- /* vram32 (surfaces, 32bit, bar 1) */
- if (qxl->vram32_size_mb != -1) {
- qxl->vram32_size = qxl->vram32_size_mb * 1024 * 1024;
- }
- if (qxl->vram32_size < 4096) {
- qxl->vram32_size = 4096;
- }
-
- /* vram (surfaces, 64bit, bar 4+5) */
- if (qxl->vram_size_mb != -1) {
- qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
- }
- if (qxl->vram_size < qxl->vram32_size) {
- qxl->vram_size = qxl->vram32_size;
- }
-
- if (qxl->revision == 1) {
- qxl->vram32_size = 4096;
- qxl->vram_size = 4096;
- }
- qxl->vgamem_size = pow2ceil(qxl->vgamem_size);
- qxl->vga.vram_size = pow2ceil(qxl->vga.vram_size);
- qxl->vram32_size = pow2ceil(qxl->vram32_size);
- qxl->vram_size = pow2ceil(qxl->vram_size);
-}
-
-static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp)
-{
- uint8_t* config = qxl->pci.config;
- uint32_t pci_device_rev;
- uint32_t io_size;
-
- qxl->mode = QXL_MODE_UNDEFINED;
- qxl->generation = 1;
- qxl->num_memslots = NUM_MEMSLOTS;
- qemu_mutex_init(&qxl->track_lock);
- qemu_mutex_init(&qxl->async_lock);
- qxl->current_async = QXL_UNDEFINED_IO;
- qxl->guest_bug = 0;
-
- switch (qxl->revision) {
- case 1: /* spice 0.4 -- qxl-1 */
- pci_device_rev = QXL_REVISION_STABLE_V04;
- io_size = 8;
- break;
- case 2: /* spice 0.6 -- qxl-2 */
- pci_device_rev = QXL_REVISION_STABLE_V06;
- io_size = 16;
- break;
- case 3: /* qxl-3 */
- pci_device_rev = QXL_REVISION_STABLE_V10;
- io_size = 32; /* PCI region size must be pow2 */
- break;
- case 4: /* qxl-4 */
- pci_device_rev = QXL_REVISION_STABLE_V12;
- io_size = pow2ceil(QXL_IO_RANGE_SIZE);
- break;
- default:
- error_setg(errp, "Invalid revision %d for qxl device (max %d)",
- qxl->revision, QXL_DEFAULT_REVISION);
- return;
- }
-
- pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
- pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
-
- qxl->rom_size = qxl_rom_size();
- memory_region_init_ram(&qxl->rom_bar, OBJECT(qxl), "qxl.vrom",
- qxl->rom_size, &error_fatal);
- vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev);
- init_qxl_rom(qxl);
- init_qxl_ram(qxl);
-
- qxl->guest_surfaces.cmds = g_new0(QXLPHYSICAL, qxl->ssd.num_surfaces);
- memory_region_init_ram(&qxl->vram_bar, OBJECT(qxl), "qxl.vram",
- qxl->vram_size, &error_fatal);
- vmstate_register_ram(&qxl->vram_bar, &qxl->pci.qdev);
- memory_region_init_alias(&qxl->vram32_bar, OBJECT(qxl), "qxl.vram32",
- &qxl->vram_bar, 0, qxl->vram32_size);
-
- memory_region_init_io(&qxl->io_bar, OBJECT(qxl), &qxl_io_ops, qxl,
- "qxl-ioports", io_size);
- if (qxl->id == 0) {
- vga_dirty_log_start(&qxl->vga);
- }
- memory_region_set_flush_coalesced(&qxl->io_bar);
-
-
- pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
- PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
-
- pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
- PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
-
- pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
- PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
-
- pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
- PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram32_bar);
-
- if (qxl->vram32_size < qxl->vram_size) {
- /*
- * Make the 64bit vram bar show up only in case it is
- * configured to be larger than the 32bit vram bar.
- */
- pci_register_bar(&qxl->pci, QXL_VRAM64_RANGE_INDEX,
- PCI_BASE_ADDRESS_SPACE_MEMORY |
- PCI_BASE_ADDRESS_MEM_TYPE_64 |
- PCI_BASE_ADDRESS_MEM_PREFETCH,
- &qxl->vram_bar);
- }
-
- /* print pci bar details */
- dprint(qxl, 1, "ram/%s: %d MB [region 0]\n",
- qxl->id == 0 ? "pri" : "sec",
- qxl->vga.vram_size / (1024*1024));
- dprint(qxl, 1, "vram/32: %d MB [region 1]\n",
- qxl->vram32_size / (1024*1024));
- dprint(qxl, 1, "vram/64: %d MB %s\n",
- qxl->vram_size / (1024*1024),
- qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
-
- qxl->ssd.qxl.base.sif = &qxl_interface.base;
- if (qemu_spice_add_display_interface(&qxl->ssd.qxl, qxl->vga.con) != 0) {
- error_setg(errp, "qxl interface %d.%d not supported by spice-server",
- SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
- return;
- }
- qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
-
- qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
- qxl_reset_state(qxl);
-
- qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
- qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd);
-}
-
-static void qxl_realize_primary(PCIDevice *dev, Error **errp)
-{
- PCIQXLDevice *qxl = PCI_QXL(dev);
- 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 >> 20;
- vga_common_init(vga, OBJECT(dev), true);
- vga_init(vga, OBJECT(dev),
- pci_address_space(dev), pci_address_space_io(dev), false);
- portio_list_init(&qxl->vga_port_list, OBJECT(dev), qxl_vga_portio_list,
- vga, "vga");
- portio_list_set_flush_coalesced(&qxl->vga_port_list);
- portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0);
-
- vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
- qemu_spice_display_init_common(&qxl->ssd);
-
- qxl_realize_common(qxl, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- qxl->ssd.dcl.ops = &display_listener_ops;
- qxl->ssd.dcl.con = vga->con;
- register_displaychangelistener(&qxl->ssd.dcl);
-}
-
-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);
- vmstate_register_ram(&qxl->vga.vram, &qxl->pci.qdev);
- 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_realize_common(qxl, errp);
-}
-
-static void qxl_pre_save(void *opaque)
-{
- PCIQXLDevice* d = opaque;
- uint8_t *ram_start = d->vga.vram_ptr;
-
- trace_qxl_pre_save(d->id);
- if (d->last_release == NULL) {
- d->last_release_offset = 0;
- } else {
- d->last_release_offset = (uint8_t *)d->last_release - ram_start;
- }
- assert(d->last_release_offset < d->vga.vram_size);
-}
-
-static int qxl_pre_load(void *opaque)
-{
- PCIQXLDevice* d = opaque;
-
- trace_qxl_pre_load(d->id);
- qxl_hard_reset(d, 1);
- qxl_exit_vga_mode(d);
- return 0;
-}
-
-static void qxl_create_memslots(PCIQXLDevice *d)
-{
- int i;
-
- for (i = 0; i < NUM_MEMSLOTS; i++) {
- if (!d->guest_slots[i].active) {
- continue;
- }
- qxl_add_memslot(d, i, 0, QXL_SYNC);
- }
-}
-
-static int qxl_post_load(void *opaque, int version)
-{
- PCIQXLDevice* d = opaque;
- uint8_t *ram_start = d->vga.vram_ptr;
- QXLCommandExt *cmds;
- int in, out, newmode;
-
- assert(d->last_release_offset < d->vga.vram_size);
- if (d->last_release_offset == 0) {
- d->last_release = NULL;
- } else {
- d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);
- }
-
- d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
-
- trace_qxl_post_load(d->id, qxl_mode_to_string(d->mode));
- newmode = d->mode;
- d->mode = QXL_MODE_UNDEFINED;
-
- switch (newmode) {
- case QXL_MODE_UNDEFINED:
- qxl_create_memslots(d);
- break;
- case QXL_MODE_VGA:
- qxl_create_memslots(d);
- qxl_enter_vga_mode(d);
- break;
- case QXL_MODE_NATIVE:
- qxl_create_memslots(d);
- qxl_create_guest_primary(d, 1, QXL_SYNC);
-
- /* replay surface-create and cursor-set commands */
- cmds = g_new0(QXLCommandExt, d->ssd.num_surfaces + 1);
- for (in = 0, out = 0; in < d->ssd.num_surfaces; in++) {
- if (d->guest_surfaces.cmds[in] == 0) {
- continue;
- }
- cmds[out].cmd.data = d->guest_surfaces.cmds[in];
- cmds[out].cmd.type = QXL_CMD_SURFACE;
- cmds[out].group_id = MEMSLOT_GROUP_GUEST;
- out++;
- }
- if (d->guest_cursor) {
- cmds[out].cmd.data = d->guest_cursor;
- cmds[out].cmd.type = QXL_CMD_CURSOR;
- cmds[out].group_id = MEMSLOT_GROUP_GUEST;
- out++;
- }
- qxl_spice_loadvm_commands(d, cmds, out);
- g_free(cmds);
- if (d->guest_monitors_config) {
- qxl_spice_monitors_config_async(d, 1);
- }
- break;
- case QXL_MODE_COMPAT:
- /* note: no need to call qxl_create_memslots, qxl_set_mode
- * creates the mem slot. */
- qxl_set_mode(d, d->shadow_rom.mode, 1);
- break;
- }
- return 0;
-}
-
-#define QXL_SAVE_VERSION 21
-
-static bool qxl_monitors_config_needed(void *opaque)
-{
- PCIQXLDevice *qxl = opaque;
-
- return qxl->guest_monitors_config != 0;
-}
-
-
-static VMStateDescription qxl_memslot = {
- .name = "qxl-memslot",
- .version_id = QXL_SAVE_VERSION,
- .minimum_version_id = QXL_SAVE_VERSION,
- .fields = (VMStateField[]) {
- VMSTATE_UINT64(slot.mem_start, struct guest_slots),
- VMSTATE_UINT64(slot.mem_end, struct guest_slots),
- VMSTATE_UINT32(active, struct guest_slots),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static VMStateDescription qxl_surface = {
- .name = "qxl-surface",
- .version_id = QXL_SAVE_VERSION,
- .minimum_version_id = QXL_SAVE_VERSION,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(width, QXLSurfaceCreate),
- VMSTATE_UINT32(height, QXLSurfaceCreate),
- VMSTATE_INT32(stride, QXLSurfaceCreate),
- VMSTATE_UINT32(format, QXLSurfaceCreate),
- VMSTATE_UINT32(position, QXLSurfaceCreate),
- VMSTATE_UINT32(mouse_mode, QXLSurfaceCreate),
- VMSTATE_UINT32(flags, QXLSurfaceCreate),
- VMSTATE_UINT32(type, QXLSurfaceCreate),
- VMSTATE_UINT64(mem, QXLSurfaceCreate),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static VMStateDescription qxl_vmstate_monitors_config = {
- .name = "qxl/monitors-config",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = qxl_monitors_config_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINT64(guest_monitors_config, PCIQXLDevice),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static VMStateDescription qxl_vmstate = {
- .name = "qxl",
- .version_id = QXL_SAVE_VERSION,
- .minimum_version_id = QXL_SAVE_VERSION,
- .pre_save = qxl_pre_save,
- .pre_load = qxl_pre_load,
- .post_load = qxl_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
- VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
- VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
- VMSTATE_UINT32(num_free_res, PCIQXLDevice),
- VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
- VMSTATE_UINT32(mode, PCIQXLDevice),
- VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
- VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
- VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
- qxl_memslot, struct guest_slots),
- VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
- qxl_surface, QXLSurfaceCreate),
- VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice),
- VMSTATE_VARRAY_INT32(guest_surfaces.cmds, PCIQXLDevice,
- ssd.num_surfaces, 0,
- vmstate_info_uint64, uint64_t),
- VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &qxl_vmstate_monitors_config,
- NULL
- }
-};
-
-static Property qxl_properties[] = {
- DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
- 64 * 1024 * 1024),
- DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size,
- 64 * 1024 * 1024),
- DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
- QXL_DEFAULT_REVISION),
- DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
- DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
- DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
- DEFINE_PROP_UINT32("ram_size_mb", PCIQXLDevice, ram_size_mb, -1),
- DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1),
- DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
- DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
- DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
-#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
- DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
-#endif
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void qxl_pci_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->vendor_id = REDHAT_PCI_VENDOR_ID;
- k->device_id = QXL_DEVICE_ID_STABLE;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->reset = qxl_reset_handler;
- dc->vmsd = &qxl_vmstate;
- dc->props = qxl_properties;
-}
-
-static const TypeInfo qxl_pci_type_info = {
- .name = TYPE_PCI_QXL,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCIQXLDevice),
- .abstract = true,
- .class_init = qxl_pci_class_init,
-};
-
-static void qxl_primary_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = qxl_realize_primary;
- k->romfile = "vgabios-qxl.bin";
- k->class_id = PCI_CLASS_DISPLAY_VGA;
- dc->desc = "Spice QXL GPU (primary, vga compatible)";
- dc->hotpluggable = false;
-}
-
-static const TypeInfo qxl_primary_info = {
- .name = "qxl-vga",
- .parent = TYPE_PCI_QXL,
- .class_init = qxl_primary_class_init,
-};
-
-static void qxl_secondary_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = qxl_realize_secondary;
- k->class_id = PCI_CLASS_DISPLAY_OTHER;
- dc->desc = "Spice QXL GPU (secondary)";
-}
-
-static const TypeInfo qxl_secondary_info = {
- .name = "qxl",
- .parent = TYPE_PCI_QXL,
- .class_init = qxl_secondary_class_init,
-};
-
-static void qxl_register_types(void)
-{
- type_register_static(&qxl_pci_type_info);
- type_register_static(&qxl_primary_info);
- type_register_static(&qxl_secondary_info);
-}
-
-type_init(qxl_register_types)
diff --git a/qemu/hw/display/qxl.h b/qemu/hw/display/qxl.h
deleted file mode 100644
index 2ddf065e1..000000000
--- a/qemu/hw/display/qxl.h
+++ /dev/null
@@ -1,174 +0,0 @@
-#ifndef HW_QXL_H
-#define HW_QXL_H 1
-
-#include "qemu-common.h"
-
-#include "ui/console.h"
-#include "hw/hw.h"
-#include "hw/pci/pci.h"
-#include "vga_int.h"
-#include "qemu/thread.h"
-
-#include "ui/qemu-spice.h"
-#include "ui/spice-display.h"
-
-enum qxl_mode {
- QXL_MODE_UNDEFINED,
- QXL_MODE_VGA,
- QXL_MODE_COMPAT, /* spice 0.4.x */
- QXL_MODE_NATIVE,
-};
-
-#ifndef QXL_VRAM64_RANGE_INDEX
-#define QXL_VRAM64_RANGE_INDEX 4
-#endif
-
-#define QXL_UNDEFINED_IO UINT32_MAX
-
-#define QXL_NUM_DIRTY_RECTS 64
-
-#define QXL_PAGE_BITS 12
-#define QXL_PAGE_SIZE (1 << QXL_PAGE_BITS);
-
-typedef struct PCIQXLDevice {
- PCIDevice pci;
- PortioList vga_port_list;
- SimpleSpiceDisplay ssd;
- int id;
- uint32_t debug;
- uint32_t guestdebug;
- uint32_t cmdlog;
-
- uint32_t guest_bug;
-
- enum qxl_mode mode;
- uint32_t cmdflags;
- int generation;
- uint32_t revision;
-
- int32_t num_memslots;
-
- uint32_t current_async;
- QemuMutex async_lock;
-
- struct guest_slots {
- QXLMemSlot slot;
- void *ptr;
- uint64_t size;
- uint64_t delta;
- uint32_t active;
- } guest_slots[NUM_MEMSLOTS];
-
- struct guest_primary {
- QXLSurfaceCreate surface;
- uint32_t commands;
- uint32_t resized;
- int32_t qxl_stride;
- uint32_t abs_stride;
- uint32_t bits_pp;
- uint32_t bytes_pp;
- uint8_t *data;
- } guest_primary;
-
- struct surfaces {
- QXLPHYSICAL *cmds;
- uint32_t count;
- uint32_t max;
- } guest_surfaces;
- QXLPHYSICAL guest_cursor;
-
- QXLPHYSICAL guest_monitors_config;
-
- QemuMutex track_lock;
-
- /* thread signaling */
- QEMUBH *update_irq;
-
- /* ram pci bar */
- QXLRam *ram;
- VGACommonState vga;
- uint32_t num_free_res;
- QXLReleaseInfo *last_release;
- uint32_t last_release_offset;
- uint32_t oom_running;
- uint32_t vgamem_size;
-
- /* rom pci bar */
- QXLRom shadow_rom;
- QXLRom *rom;
- QXLModes *modes;
- uint32_t rom_size;
- MemoryRegion rom_bar;
-#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
- uint16_t max_outputs;
-#endif
-
- /* vram pci bar */
- uint32_t vram_size;
- MemoryRegion vram_bar;
- uint32_t vram32_size;
- MemoryRegion vram32_bar;
-
- /* io bar */
- MemoryRegion io_bar;
-
- /* user-friendly properties (in megabytes) */
- uint32_t ram_size_mb;
- uint32_t vram_size_mb;
- uint32_t vram32_size_mb;
- uint32_t vgamem_size_mb;
-
- /* qxl_render_update state */
- int render_update_cookie_num;
- int num_dirty_rects;
- QXLRect dirty[QXL_NUM_DIRTY_RECTS];
- QEMUBH *update_area_bh;
-} PCIQXLDevice;
-
-#define TYPE_PCI_QXL "pci-qxl"
-#define PCI_QXL(obj) OBJECT_CHECK(PCIQXLDevice, (obj), TYPE_PCI_QXL)
-
-#define PANIC_ON(x) if ((x)) { \
- printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
- abort(); \
-}
-
-#define dprint(_qxl, _level, _fmt, ...) \
- do { \
- if (_qxl->debug >= _level) { \
- fprintf(stderr, "qxl-%d: ", _qxl->id); \
- fprintf(stderr, _fmt, ## __VA_ARGS__); \
- } \
- } while (0)
-
-#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
-
-/* qxl.c */
-void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
- GCC_FMT_ATTR(2, 3);
-
-void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
- struct QXLRect *area, struct QXLRect *dirty_rects,
- uint32_t num_dirty_rects,
- uint32_t clear_dirty_region,
- qxl_async_io async, QXLCookie *cookie);
-void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
- uint32_t count);
-void qxl_spice_oom(PCIQXLDevice *qxl);
-void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
-void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
-void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
-
-/* qxl-logger.c */
-int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
-int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
-
-/* qxl-render.c */
-void qxl_render_resize(PCIQXLDevice *qxl);
-void qxl_render_update(PCIQXLDevice *qxl);
-int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
-void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
-void qxl_render_update_area_bh(void *opaque);
-
-#endif
diff --git a/qemu/hw/display/sm501.c b/qemu/hw/display/sm501.c
deleted file mode 100644
index 5f7101210..000000000
--- a/qemu/hw/display/sm501.c
+++ /dev/null
@@ -1,1458 +0,0 @@
-/*
- * QEMU SM501 Device
- *
- * Copyright (c) 2008 Shin-ichiro KAWASAKI
- *
- * 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 "qemu-common.h"
-#include "cpu.h"
-#include "hw/hw.h"
-#include "hw/char/serial.h"
-#include "ui/console.h"
-#include "hw/devices.h"
-#include "hw/sysbus.h"
-#include "qemu/range.h"
-#include "ui/pixel_ops.h"
-#include "exec/address-spaces.h"
-
-/*
- * Status: 2010/05/07
- * - Minimum implementation for Linux console : mmio regs and CRT layer.
- * - 2D grapihcs acceleration partially supported : only fill rectangle.
- *
- * TODO:
- * - Panel support
- * - Touch panel support
- * - USB support
- * - UART support
- * - More 2D graphics engine support
- * - Performance tuning
- */
-
-//#define DEBUG_SM501
-//#define DEBUG_BITBLT
-
-#ifdef DEBUG_SM501
-#define SM501_DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define SM501_DPRINTF(fmt, ...) do {} while(0)
-#endif
-
-
-#define MMIO_BASE_OFFSET 0x3e00000
-
-/* SM501 register definitions taken from "linux/include/linux/sm501-regs.h" */
-
-/* System Configuration area */
-/* System config base */
-#define SM501_SYS_CONFIG (0x000000)
-
-/* config 1 */
-#define SM501_SYSTEM_CONTROL (0x000000)
-
-#define SM501_SYSCTRL_PANEL_TRISTATE (1<<0)
-#define SM501_SYSCTRL_MEM_TRISTATE (1<<1)
-#define SM501_SYSCTRL_CRT_TRISTATE (1<<2)
-
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3<<4)
-
-#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
-#define SM501_SYSCTRL_PCI_RETRY_DISABLE (1<<7)
-#define SM501_SYSCTRL_PCI_SUBSYS_LOCK (1<<11)
-#define SM501_SYSCTRL_PCI_BURST_READ_EN (1<<15)
-
-/* miscellaneous control */
-
-#define SM501_MISC_CONTROL (0x000004)
-
-#define SM501_MISC_BUS_SH (0x0)
-#define SM501_MISC_BUS_PCI (0x1)
-#define SM501_MISC_BUS_XSCALE (0x2)
-#define SM501_MISC_BUS_NEC (0x6)
-#define SM501_MISC_BUS_MASK (0x7)
-
-#define SM501_MISC_VR_62MB (1<<3)
-#define SM501_MISC_CDR_RESET (1<<7)
-#define SM501_MISC_USB_LB (1<<8)
-#define SM501_MISC_USB_SLAVE (1<<9)
-#define SM501_MISC_BL_1 (1<<10)
-#define SM501_MISC_MC (1<<11)
-#define SM501_MISC_DAC_POWER (1<<12)
-#define SM501_MISC_IRQ_INVERT (1<<16)
-#define SM501_MISC_SH (1<<17)
-
-#define SM501_MISC_HOLD_EMPTY (0<<18)
-#define SM501_MISC_HOLD_8 (1<<18)
-#define SM501_MISC_HOLD_16 (2<<18)
-#define SM501_MISC_HOLD_24 (3<<18)
-#define SM501_MISC_HOLD_32 (4<<18)
-#define SM501_MISC_HOLD_MASK (7<<18)
-
-#define SM501_MISC_FREQ_12 (1<<24)
-#define SM501_MISC_PNL_24BIT (1<<25)
-#define SM501_MISC_8051_LE (1<<26)
-
-
-
-#define SM501_GPIO31_0_CONTROL (0x000008)
-#define SM501_GPIO63_32_CONTROL (0x00000C)
-#define SM501_DRAM_CONTROL (0x000010)
-
-/* command list */
-#define SM501_ARBTRTN_CONTROL (0x000014)
-
-/* command list */
-#define SM501_COMMAND_LIST_STATUS (0x000024)
-
-/* interrupt debug */
-#define SM501_RAW_IRQ_STATUS (0x000028)
-#define SM501_RAW_IRQ_CLEAR (0x000028)
-#define SM501_IRQ_STATUS (0x00002C)
-#define SM501_IRQ_MASK (0x000030)
-#define SM501_DEBUG_CONTROL (0x000034)
-
-/* power management */
-#define SM501_POWERMODE_P2X_SRC (1<<29)
-#define SM501_POWERMODE_V2X_SRC (1<<20)
-#define SM501_POWERMODE_M_SRC (1<<12)
-#define SM501_POWERMODE_M1_SRC (1<<4)
-
-#define SM501_CURRENT_GATE (0x000038)
-#define SM501_CURRENT_CLOCK (0x00003C)
-#define SM501_POWER_MODE_0_GATE (0x000040)
-#define SM501_POWER_MODE_0_CLOCK (0x000044)
-#define SM501_POWER_MODE_1_GATE (0x000048)
-#define SM501_POWER_MODE_1_CLOCK (0x00004C)
-#define SM501_SLEEP_MODE_GATE (0x000050)
-#define SM501_POWER_MODE_CONTROL (0x000054)
-
-/* power gates for units within the 501 */
-#define SM501_GATE_HOST (0)
-#define SM501_GATE_MEMORY (1)
-#define SM501_GATE_DISPLAY (2)
-#define SM501_GATE_2D_ENGINE (3)
-#define SM501_GATE_CSC (4)
-#define SM501_GATE_ZVPORT (5)
-#define SM501_GATE_GPIO (6)
-#define SM501_GATE_UART0 (7)
-#define SM501_GATE_UART1 (8)
-#define SM501_GATE_SSP (10)
-#define SM501_GATE_USB_HOST (11)
-#define SM501_GATE_USB_GADGET (12)
-#define SM501_GATE_UCONTROLLER (17)
-#define SM501_GATE_AC97 (18)
-
-/* panel clock */
-#define SM501_CLOCK_P2XCLK (24)
-/* crt clock */
-#define SM501_CLOCK_V2XCLK (16)
-/* main clock */
-#define SM501_CLOCK_MCLK (8)
-/* SDRAM controller clock */
-#define SM501_CLOCK_M1XCLK (0)
-
-/* config 2 */
-#define SM501_PCI_MASTER_BASE (0x000058)
-#define SM501_ENDIAN_CONTROL (0x00005C)
-#define SM501_DEVICEID (0x000060)
-/* 0x050100A0 */
-
-#define SM501_DEVICEID_SM501 (0x05010000)
-#define SM501_DEVICEID_IDMASK (0xffff0000)
-#define SM501_DEVICEID_REVMASK (0x000000ff)
-
-#define SM501_PLLCLOCK_COUNT (0x000064)
-#define SM501_MISC_TIMING (0x000068)
-#define SM501_CURRENT_SDRAM_CLOCK (0x00006C)
-
-#define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074)
-
-/* GPIO base */
-#define SM501_GPIO (0x010000)
-#define SM501_GPIO_DATA_LOW (0x00)
-#define SM501_GPIO_DATA_HIGH (0x04)
-#define SM501_GPIO_DDR_LOW (0x08)
-#define SM501_GPIO_DDR_HIGH (0x0C)
-#define SM501_GPIO_IRQ_SETUP (0x10)
-#define SM501_GPIO_IRQ_STATUS (0x14)
-#define SM501_GPIO_IRQ_RESET (0x14)
-
-/* I2C controller base */
-#define SM501_I2C (0x010040)
-#define SM501_I2C_BYTE_COUNT (0x00)
-#define SM501_I2C_CONTROL (0x01)
-#define SM501_I2C_STATUS (0x02)
-#define SM501_I2C_RESET (0x02)
-#define SM501_I2C_SLAVE_ADDRESS (0x03)
-#define SM501_I2C_DATA (0x04)
-
-/* SSP base */
-#define SM501_SSP (0x020000)
-
-/* Uart 0 base */
-#define SM501_UART0 (0x030000)
-
-/* Uart 1 base */
-#define SM501_UART1 (0x030020)
-
-/* USB host port base */
-#define SM501_USB_HOST (0x040000)
-
-/* USB slave/gadget base */
-#define SM501_USB_GADGET (0x060000)
-
-/* USB slave/gadget data port base */
-#define SM501_USB_GADGET_DATA (0x070000)
-
-/* Display controller/video engine base */
-#define SM501_DC (0x080000)
-
-/* common defines for the SM501 address registers */
-#define SM501_ADDR_FLIP (1<<31)
-#define SM501_ADDR_EXT (1<<27)
-#define SM501_ADDR_CS1 (1<<26)
-#define SM501_ADDR_MASK (0x3f << 26)
-
-#define SM501_FIFO_MASK (0x3 << 16)
-#define SM501_FIFO_1 (0x0 << 16)
-#define SM501_FIFO_3 (0x1 << 16)
-#define SM501_FIFO_7 (0x2 << 16)
-#define SM501_FIFO_11 (0x3 << 16)
-
-/* common registers for panel and the crt */
-#define SM501_OFF_DC_H_TOT (0x000)
-#define SM501_OFF_DC_V_TOT (0x008)
-#define SM501_OFF_DC_H_SYNC (0x004)
-#define SM501_OFF_DC_V_SYNC (0x00C)
-
-#define SM501_DC_PANEL_CONTROL (0x000)
-
-#define SM501_DC_PANEL_CONTROL_FPEN (1<<27)
-#define SM501_DC_PANEL_CONTROL_BIAS (1<<26)
-#define SM501_DC_PANEL_CONTROL_DATA (1<<25)
-#define SM501_DC_PANEL_CONTROL_VDD (1<<24)
-#define SM501_DC_PANEL_CONTROL_DP (1<<23)
-
-#define SM501_DC_PANEL_CONTROL_TFT_888 (0<<21)
-#define SM501_DC_PANEL_CONTROL_TFT_333 (1<<21)
-#define SM501_DC_PANEL_CONTROL_TFT_444 (2<<21)
-
-#define SM501_DC_PANEL_CONTROL_DE (1<<20)
-
-#define SM501_DC_PANEL_CONTROL_LCD_TFT (0<<18)
-#define SM501_DC_PANEL_CONTROL_LCD_STN8 (1<<18)
-#define SM501_DC_PANEL_CONTROL_LCD_STN12 (2<<18)
-
-#define SM501_DC_PANEL_CONTROL_CP (1<<14)
-#define SM501_DC_PANEL_CONTROL_VSP (1<<13)
-#define SM501_DC_PANEL_CONTROL_HSP (1<<12)
-#define SM501_DC_PANEL_CONTROL_CK (1<<9)
-#define SM501_DC_PANEL_CONTROL_TE (1<<8)
-#define SM501_DC_PANEL_CONTROL_VPD (1<<7)
-#define SM501_DC_PANEL_CONTROL_VP (1<<6)
-#define SM501_DC_PANEL_CONTROL_HPD (1<<5)
-#define SM501_DC_PANEL_CONTROL_HP (1<<4)
-#define SM501_DC_PANEL_CONTROL_GAMMA (1<<3)
-#define SM501_DC_PANEL_CONTROL_EN (1<<2)
-
-#define SM501_DC_PANEL_CONTROL_8BPP (0<<0)
-#define SM501_DC_PANEL_CONTROL_16BPP (1<<0)
-#define SM501_DC_PANEL_CONTROL_32BPP (2<<0)
-
-
-#define SM501_DC_PANEL_PANNING_CONTROL (0x004)
-#define SM501_DC_PANEL_COLOR_KEY (0x008)
-#define SM501_DC_PANEL_FB_ADDR (0x00C)
-#define SM501_DC_PANEL_FB_OFFSET (0x010)
-#define SM501_DC_PANEL_FB_WIDTH (0x014)
-#define SM501_DC_PANEL_FB_HEIGHT (0x018)
-#define SM501_DC_PANEL_TL_LOC (0x01C)
-#define SM501_DC_PANEL_BR_LOC (0x020)
-#define SM501_DC_PANEL_H_TOT (0x024)
-#define SM501_DC_PANEL_H_SYNC (0x028)
-#define SM501_DC_PANEL_V_TOT (0x02C)
-#define SM501_DC_PANEL_V_SYNC (0x030)
-#define SM501_DC_PANEL_CUR_LINE (0x034)
-
-#define SM501_DC_VIDEO_CONTROL (0x040)
-#define SM501_DC_VIDEO_FB0_ADDR (0x044)
-#define SM501_DC_VIDEO_FB_WIDTH (0x048)
-#define SM501_DC_VIDEO_FB0_LAST_ADDR (0x04C)
-#define SM501_DC_VIDEO_TL_LOC (0x050)
-#define SM501_DC_VIDEO_BR_LOC (0x054)
-#define SM501_DC_VIDEO_SCALE (0x058)
-#define SM501_DC_VIDEO_INIT_SCALE (0x05C)
-#define SM501_DC_VIDEO_YUV_CONSTANTS (0x060)
-#define SM501_DC_VIDEO_FB1_ADDR (0x064)
-#define SM501_DC_VIDEO_FB1_LAST_ADDR (0x068)
-
-#define SM501_DC_VIDEO_ALPHA_CONTROL (0x080)
-#define SM501_DC_VIDEO_ALPHA_FB_ADDR (0x084)
-#define SM501_DC_VIDEO_ALPHA_FB_OFFSET (0x088)
-#define SM501_DC_VIDEO_ALPHA_FB_LAST_ADDR (0x08C)
-#define SM501_DC_VIDEO_ALPHA_TL_LOC (0x090)
-#define SM501_DC_VIDEO_ALPHA_BR_LOC (0x094)
-#define SM501_DC_VIDEO_ALPHA_SCALE (0x098)
-#define SM501_DC_VIDEO_ALPHA_INIT_SCALE (0x09C)
-#define SM501_DC_VIDEO_ALPHA_CHROMA_KEY (0x0A0)
-#define SM501_DC_VIDEO_ALPHA_COLOR_LOOKUP (0x0A4)
-
-#define SM501_DC_PANEL_HWC_BASE (0x0F0)
-#define SM501_DC_PANEL_HWC_ADDR (0x0F0)
-#define SM501_DC_PANEL_HWC_LOC (0x0F4)
-#define SM501_DC_PANEL_HWC_COLOR_1_2 (0x0F8)
-#define SM501_DC_PANEL_HWC_COLOR_3 (0x0FC)
-
-#define SM501_HWC_EN (1<<31)
-
-#define SM501_OFF_HWC_ADDR (0x00)
-#define SM501_OFF_HWC_LOC (0x04)
-#define SM501_OFF_HWC_COLOR_1_2 (0x08)
-#define SM501_OFF_HWC_COLOR_3 (0x0C)
-
-#define SM501_DC_ALPHA_CONTROL (0x100)
-#define SM501_DC_ALPHA_FB_ADDR (0x104)
-#define SM501_DC_ALPHA_FB_OFFSET (0x108)
-#define SM501_DC_ALPHA_TL_LOC (0x10C)
-#define SM501_DC_ALPHA_BR_LOC (0x110)
-#define SM501_DC_ALPHA_CHROMA_KEY (0x114)
-#define SM501_DC_ALPHA_COLOR_LOOKUP (0x118)
-
-#define SM501_DC_CRT_CONTROL (0x200)
-
-#define SM501_DC_CRT_CONTROL_TVP (1<<15)
-#define SM501_DC_CRT_CONTROL_CP (1<<14)
-#define SM501_DC_CRT_CONTROL_VSP (1<<13)
-#define SM501_DC_CRT_CONTROL_HSP (1<<12)
-#define SM501_DC_CRT_CONTROL_VS (1<<11)
-#define SM501_DC_CRT_CONTROL_BLANK (1<<10)
-#define SM501_DC_CRT_CONTROL_SEL (1<<9)
-#define SM501_DC_CRT_CONTROL_TE (1<<8)
-#define SM501_DC_CRT_CONTROL_PIXEL_MASK (0xF << 4)
-#define SM501_DC_CRT_CONTROL_GAMMA (1<<3)
-#define SM501_DC_CRT_CONTROL_ENABLE (1<<2)
-
-#define SM501_DC_CRT_CONTROL_8BPP (0<<0)
-#define SM501_DC_CRT_CONTROL_16BPP (1<<0)
-#define SM501_DC_CRT_CONTROL_32BPP (2<<0)
-
-#define SM501_DC_CRT_FB_ADDR (0x204)
-#define SM501_DC_CRT_FB_OFFSET (0x208)
-#define SM501_DC_CRT_H_TOT (0x20C)
-#define SM501_DC_CRT_H_SYNC (0x210)
-#define SM501_DC_CRT_V_TOT (0x214)
-#define SM501_DC_CRT_V_SYNC (0x218)
-#define SM501_DC_CRT_SIGNATURE_ANALYZER (0x21C)
-#define SM501_DC_CRT_CUR_LINE (0x220)
-#define SM501_DC_CRT_MONITOR_DETECT (0x224)
-
-#define SM501_DC_CRT_HWC_BASE (0x230)
-#define SM501_DC_CRT_HWC_ADDR (0x230)
-#define SM501_DC_CRT_HWC_LOC (0x234)
-#define SM501_DC_CRT_HWC_COLOR_1_2 (0x238)
-#define SM501_DC_CRT_HWC_COLOR_3 (0x23C)
-
-#define SM501_DC_PANEL_PALETTE (0x400)
-
-#define SM501_DC_VIDEO_PALETTE (0x800)
-
-#define SM501_DC_CRT_PALETTE (0xC00)
-
-/* Zoom Video port base */
-#define SM501_ZVPORT (0x090000)
-
-/* AC97/I2S base */
-#define SM501_AC97 (0x0A0000)
-
-/* 8051 micro controller base */
-#define SM501_UCONTROLLER (0x0B0000)
-
-/* 8051 micro controller SRAM base */
-#define SM501_UCONTROLLER_SRAM (0x0C0000)
-
-/* DMA base */
-#define SM501_DMA (0x0D0000)
-
-/* 2d engine base */
-#define SM501_2D_ENGINE (0x100000)
-#define SM501_2D_SOURCE (0x00)
-#define SM501_2D_DESTINATION (0x04)
-#define SM501_2D_DIMENSION (0x08)
-#define SM501_2D_CONTROL (0x0C)
-#define SM501_2D_PITCH (0x10)
-#define SM501_2D_FOREGROUND (0x14)
-#define SM501_2D_BACKGROUND (0x18)
-#define SM501_2D_STRETCH (0x1C)
-#define SM501_2D_COLOR_COMPARE (0x20)
-#define SM501_2D_COLOR_COMPARE_MASK (0x24)
-#define SM501_2D_MASK (0x28)
-#define SM501_2D_CLIP_TL (0x2C)
-#define SM501_2D_CLIP_BR (0x30)
-#define SM501_2D_MONO_PATTERN_LOW (0x34)
-#define SM501_2D_MONO_PATTERN_HIGH (0x38)
-#define SM501_2D_WINDOW_WIDTH (0x3C)
-#define SM501_2D_SOURCE_BASE (0x40)
-#define SM501_2D_DESTINATION_BASE (0x44)
-#define SM501_2D_ALPHA (0x48)
-#define SM501_2D_WRAP (0x4C)
-#define SM501_2D_STATUS (0x50)
-
-#define SM501_CSC_Y_SOURCE_BASE (0xC8)
-#define SM501_CSC_CONSTANTS (0xCC)
-#define SM501_CSC_Y_SOURCE_X (0xD0)
-#define SM501_CSC_Y_SOURCE_Y (0xD4)
-#define SM501_CSC_U_SOURCE_BASE (0xD8)
-#define SM501_CSC_V_SOURCE_BASE (0xDC)
-#define SM501_CSC_SOURCE_DIMENSION (0xE0)
-#define SM501_CSC_SOURCE_PITCH (0xE4)
-#define SM501_CSC_DESTINATION (0xE8)
-#define SM501_CSC_DESTINATION_DIMENSION (0xEC)
-#define SM501_CSC_DESTINATION_PITCH (0xF0)
-#define SM501_CSC_SCALE_FACTOR (0xF4)
-#define SM501_CSC_DESTINATION_BASE (0xF8)
-#define SM501_CSC_CONTROL (0xFC)
-
-/* 2d engine data port base */
-#define SM501_2D_ENGINE_DATA (0x110000)
-
-/* end of register definitions */
-
-#define SM501_HWC_WIDTH (64)
-#define SM501_HWC_HEIGHT (64)
-
-/* SM501 local memory size taken from "linux/drivers/mfd/sm501.c" */
-static const uint32_t sm501_mem_local_size[] = {
- [0] = 4*1024*1024,
- [1] = 8*1024*1024,
- [2] = 16*1024*1024,
- [3] = 32*1024*1024,
- [4] = 64*1024*1024,
- [5] = 2*1024*1024,
-};
-#define get_local_mem_size(s) sm501_mem_local_size[(s)->local_mem_size_index]
-
-typedef struct SM501State {
- /* graphic console status */
- QemuConsole *con;
-
- /* status & internal resources */
- hwaddr base;
- uint32_t local_mem_size_index;
- uint8_t * local_mem;
- MemoryRegion local_mem_region;
- uint32_t last_width;
- uint32_t last_height;
-
- /* mmio registers */
- uint32_t system_control;
- uint32_t misc_control;
- uint32_t gpio_31_0_control;
- uint32_t gpio_63_32_control;
- uint32_t dram_control;
- uint32_t irq_mask;
- uint32_t misc_timing;
- uint32_t power_mode_control;
-
- uint32_t uart0_ier;
- uint32_t uart0_lcr;
- uint32_t uart0_mcr;
- uint32_t uart0_scr;
-
- uint8_t dc_palette[0x400 * 3];
-
- uint32_t dc_panel_control;
- uint32_t dc_panel_panning_control;
- uint32_t dc_panel_fb_addr;
- uint32_t dc_panel_fb_offset;
- uint32_t dc_panel_fb_width;
- uint32_t dc_panel_fb_height;
- uint32_t dc_panel_tl_location;
- uint32_t dc_panel_br_location;
- uint32_t dc_panel_h_total;
- uint32_t dc_panel_h_sync;
- uint32_t dc_panel_v_total;
- uint32_t dc_panel_v_sync;
-
- uint32_t dc_panel_hwc_addr;
- uint32_t dc_panel_hwc_location;
- uint32_t dc_panel_hwc_color_1_2;
- uint32_t dc_panel_hwc_color_3;
-
- uint32_t dc_crt_control;
- uint32_t dc_crt_fb_addr;
- uint32_t dc_crt_fb_offset;
- uint32_t dc_crt_h_total;
- uint32_t dc_crt_h_sync;
- uint32_t dc_crt_v_total;
- uint32_t dc_crt_v_sync;
-
- uint32_t dc_crt_hwc_addr;
- uint32_t dc_crt_hwc_location;
- uint32_t dc_crt_hwc_color_1_2;
- uint32_t dc_crt_hwc_color_3;
-
- uint32_t twoD_source;
- uint32_t twoD_destination;
- uint32_t twoD_dimension;
- uint32_t twoD_control;
- uint32_t twoD_pitch;
- uint32_t twoD_foreground;
- uint32_t twoD_stretch;
- uint32_t twoD_color_compare_mask;
- uint32_t twoD_mask;
- uint32_t twoD_window_width;
- uint32_t twoD_source_base;
- uint32_t twoD_destination_base;
-
-} SM501State;
-
-static uint32_t get_local_mem_size_index(uint32_t size)
-{
- uint32_t norm_size = 0;
- int i, index = 0;
-
- for (i = 0; i < ARRAY_SIZE(sm501_mem_local_size); i++) {
- uint32_t new_size = sm501_mem_local_size[i];
- if (new_size >= size) {
- if (norm_size == 0 || norm_size > new_size) {
- norm_size = new_size;
- index = i;
- }
- }
- }
-
- return index;
-}
-
-/**
- * Check the availability of hardware cursor.
- * @param crt 0 for PANEL, 1 for CRT.
- */
-static inline int is_hwc_enabled(SM501State *state, int crt)
-{
- uint32_t addr = crt ? state->dc_crt_hwc_addr : state->dc_panel_hwc_addr;
- return addr & 0x80000000;
-}
-
-/**
- * Get the address which holds cursor pattern data.
- * @param crt 0 for PANEL, 1 for CRT.
- */
-static inline uint32_t get_hwc_address(SM501State *state, int crt)
-{
- uint32_t addr = crt ? state->dc_crt_hwc_addr : state->dc_panel_hwc_addr;
- return (addr & 0x03FFFFF0)/* >> 4*/;
-}
-
-/**
- * Get the cursor position in y coordinate.
- * @param crt 0 for PANEL, 1 for CRT.
- */
-static inline uint32_t get_hwc_y(SM501State *state, int crt)
-{
- uint32_t location = crt ? state->dc_crt_hwc_location
- : state->dc_panel_hwc_location;
- return (location & 0x07FF0000) >> 16;
-}
-
-/**
- * Get the cursor position in x coordinate.
- * @param crt 0 for PANEL, 1 for CRT.
- */
-static inline uint32_t get_hwc_x(SM501State *state, int crt)
-{
- uint32_t location = crt ? state->dc_crt_hwc_location
- : state->dc_panel_hwc_location;
- return location & 0x000007FF;
-}
-
-/**
- * Get the cursor position in x coordinate.
- * @param crt 0 for PANEL, 1 for CRT.
- * @param index 0, 1, 2 or 3 which specifies color of corsor dot.
- */
-static inline uint16_t get_hwc_color(SM501State *state, int crt, int index)
-{
- uint32_t color_reg = 0;
- uint16_t color_565 = 0;
-
- if (index == 0) {
- return 0;
- }
-
- switch (index) {
- case 1:
- case 2:
- color_reg = crt ? state->dc_crt_hwc_color_1_2
- : state->dc_panel_hwc_color_1_2;
- break;
- case 3:
- color_reg = crt ? state->dc_crt_hwc_color_3
- : state->dc_panel_hwc_color_3;
- break;
- default:
- printf("invalid hw cursor color.\n");
- abort();
- }
-
- switch (index) {
- case 1:
- case 3:
- color_565 = (uint16_t)(color_reg & 0xFFFF);
- break;
- case 2:
- color_565 = (uint16_t)((color_reg >> 16) & 0xFFFF);
- break;
- }
- return color_565;
-}
-
-static int within_hwc_y_range(SM501State *state, int y, int crt)
-{
- int hwc_y = get_hwc_y(state, crt);
- return (hwc_y <= y && y < hwc_y + SM501_HWC_HEIGHT);
-}
-
-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;
-
- /* get frame buffer info */
- uint8_t * src = s->local_mem + (s->twoD_source_base & 0x03FFFFFF);
- uint8_t * dst = s->local_mem + (s->twoD_destination_base & 0x03FFFFFF);
- int src_width = (s->dc_crt_h_total & 0x00000FFF) + 1;
- int dst_width = (s->dc_crt_h_total & 0x00000FFF) + 1;
-
- if (addressing != 0x0) {
- printf("%s: only XY addressing is supported.\n", __func__);
- abort();
- }
-
- if ((s->twoD_source_base & 0x08000000) ||
- (s->twoD_destination_base & 0x08000000)) {
- printf("%s: only local memory is supported.\n", __func__);
- abort();
- }
-
- 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++) { \
- 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; \
- } \
- *(_pixel_type*)&dst[index_d] = *(_pixel_type*)&src[index_s];\
- } \
- } \
- }
- 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;
- }
- 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; \
- } \
- } \
- }
-
- switch (format_flags) {
- case 0:
- FILL_RECT(1, uint8_t);
- break;
- case 1:
- FILL_RECT(2, uint16_t);
- break;
- case 2:
- FILL_RECT(4, uint32_t);
- break;
- }
- break;
-
- default:
- printf("non-implemented SM501 2D operation. %d\n", operation);
- abort();
- break;
- }
-}
-
-static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- uint32_t ret = 0;
- SM501_DPRINTF("sm501 system config regs : read addr=%x\n", (int)addr);
-
- switch(addr) {
- case SM501_SYSTEM_CONTROL:
- ret = s->system_control;
- break;
- case SM501_MISC_CONTROL:
- ret = s->misc_control;
- break;
- case SM501_GPIO31_0_CONTROL:
- ret = s->gpio_31_0_control;
- break;
- case SM501_GPIO63_32_CONTROL:
- ret = s->gpio_63_32_control;
- break;
- case SM501_DEVICEID:
- ret = 0x050100A0;
- break;
- case SM501_DRAM_CONTROL:
- ret = (s->dram_control & 0x07F107C0) | s->local_mem_size_index << 13;
- break;
- case SM501_IRQ_MASK:
- ret = s->irq_mask;
- break;
- case SM501_MISC_TIMING:
- /* TODO : simulate gate control */
- ret = s->misc_timing;
- break;
- case SM501_CURRENT_GATE:
- /* TODO : simulate gate control */
- ret = 0x00021807;
- break;
- case SM501_CURRENT_CLOCK:
- ret = 0x2A1A0A09;
- break;
- case SM501_POWER_MODE_CONTROL:
- ret = s->power_mode_control;
- break;
-
- default:
- printf("sm501 system config : not implemented register read."
- " addr=%x\n", (int)addr);
- abort();
- }
-
- return ret;
-}
-
-static void sm501_system_config_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 system config regs : write addr=%x, val=%x\n",
- (uint32_t)addr, (uint32_t)value);
-
- switch(addr) {
- case SM501_SYSTEM_CONTROL:
- s->system_control = value & 0xE300B8F7;
- break;
- case SM501_MISC_CONTROL:
- s->misc_control = value & 0xFF7FFF20;
- break;
- case SM501_GPIO31_0_CONTROL:
- s->gpio_31_0_control = value;
- break;
- case SM501_GPIO63_32_CONTROL:
- s->gpio_63_32_control = value;
- break;
- case SM501_DRAM_CONTROL:
- s->local_mem_size_index = (value >> 13) & 0x7;
- /* rODO : check validity of size change */
- s->dram_control |= value & 0x7FFFFFC3;
- break;
- case SM501_IRQ_MASK:
- s->irq_mask = value;
- break;
- case SM501_MISC_TIMING:
- s->misc_timing = value & 0xF31F1FFF;
- break;
- case SM501_POWER_MODE_0_GATE:
- case SM501_POWER_MODE_1_GATE:
- case SM501_POWER_MODE_0_CLOCK:
- case SM501_POWER_MODE_1_CLOCK:
- /* TODO : simulate gate & clock control */
- break;
- case SM501_POWER_MODE_CONTROL:
- s->power_mode_control = value & 0x00000003;
- break;
-
- default:
- printf("sm501 system config : not implemented register write."
- " addr=%x, val=%x\n", (int)addr, (uint32_t)value);
- abort();
- }
-}
-
-static const MemoryRegionOps sm501_system_config_ops = {
- .read = sm501_system_config_read,
- .write = sm501_system_config_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint32_t sm501_palette_read(void *opaque, hwaddr addr)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);
-
- /* TODO : consider BYTE/WORD access */
- /* TODO : consider endian */
-
- assert(range_covers_byte(0, 0x400 * 3, addr));
- return *(uint32_t*)&s->dc_palette[addr];
-}
-
-static void sm501_palette_write(void *opaque,
- hwaddr addr, uint32_t value)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n",
- (int)addr, value);
-
- /* TODO : consider BYTE/WORD access */
- /* TODO : consider endian */
-
- assert(range_covers_byte(0, 0x400 * 3, addr));
- *(uint32_t*)&s->dc_palette[addr] = value;
-}
-
-static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- uint32_t ret = 0;
- SM501_DPRINTF("sm501 disp ctrl regs : read addr=%x\n", (int)addr);
-
- switch(addr) {
-
- case SM501_DC_PANEL_CONTROL:
- ret = s->dc_panel_control;
- break;
- case SM501_DC_PANEL_PANNING_CONTROL:
- ret = s->dc_panel_panning_control;
- break;
- case SM501_DC_PANEL_FB_ADDR:
- ret = s->dc_panel_fb_addr;
- break;
- case SM501_DC_PANEL_FB_OFFSET:
- ret = s->dc_panel_fb_offset;
- break;
- case SM501_DC_PANEL_FB_WIDTH:
- ret = s->dc_panel_fb_width;
- break;
- case SM501_DC_PANEL_FB_HEIGHT:
- ret = s->dc_panel_fb_height;
- break;
- case SM501_DC_PANEL_TL_LOC:
- ret = s->dc_panel_tl_location;
- break;
- case SM501_DC_PANEL_BR_LOC:
- ret = s->dc_panel_br_location;
- break;
-
- case SM501_DC_PANEL_H_TOT:
- ret = s->dc_panel_h_total;
- break;
- case SM501_DC_PANEL_H_SYNC:
- ret = s->dc_panel_h_sync;
- break;
- case SM501_DC_PANEL_V_TOT:
- ret = s->dc_panel_v_total;
- break;
- case SM501_DC_PANEL_V_SYNC:
- ret = s->dc_panel_v_sync;
- break;
-
- case SM501_DC_CRT_CONTROL:
- ret = s->dc_crt_control;
- break;
- case SM501_DC_CRT_FB_ADDR:
- ret = s->dc_crt_fb_addr;
- break;
- case SM501_DC_CRT_FB_OFFSET:
- ret = s->dc_crt_fb_offset;
- break;
- case SM501_DC_CRT_H_TOT:
- ret = s->dc_crt_h_total;
- break;
- case SM501_DC_CRT_H_SYNC:
- ret = s->dc_crt_h_sync;
- break;
- case SM501_DC_CRT_V_TOT:
- ret = s->dc_crt_v_total;
- break;
- case SM501_DC_CRT_V_SYNC:
- ret = s->dc_crt_v_sync;
- break;
-
- case SM501_DC_CRT_HWC_ADDR:
- ret = s->dc_crt_hwc_addr;
- break;
- case SM501_DC_CRT_HWC_LOC:
- ret = s->dc_crt_hwc_location;
- break;
- case SM501_DC_CRT_HWC_COLOR_1_2:
- ret = s->dc_crt_hwc_color_1_2;
- break;
- case SM501_DC_CRT_HWC_COLOR_3:
- ret = s->dc_crt_hwc_color_3;
- break;
-
- case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4:
- ret = sm501_palette_read(opaque, addr - SM501_DC_PANEL_PALETTE);
- break;
-
- default:
- printf("sm501 disp ctrl : not implemented register read."
- " addr=%x\n", (int)addr);
- abort();
- }
-
- return ret;
-}
-
-static void sm501_disp_ctrl_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 disp ctrl regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
-
- switch(addr) {
- case SM501_DC_PANEL_CONTROL:
- s->dc_panel_control = value & 0x0FFF73FF;
- break;
- case SM501_DC_PANEL_PANNING_CONTROL:
- s->dc_panel_panning_control = value & 0xFF3FFF3F;
- break;
- case SM501_DC_PANEL_FB_ADDR:
- s->dc_panel_fb_addr = value & 0x8FFFFFF0;
- break;
- case SM501_DC_PANEL_FB_OFFSET:
- s->dc_panel_fb_offset = value & 0x3FF03FF0;
- break;
- case SM501_DC_PANEL_FB_WIDTH:
- s->dc_panel_fb_width = value & 0x0FFF0FFF;
- break;
- case SM501_DC_PANEL_FB_HEIGHT:
- s->dc_panel_fb_height = value & 0x0FFF0FFF;
- break;
- case SM501_DC_PANEL_TL_LOC:
- s->dc_panel_tl_location = value & 0x07FF07FF;
- break;
- case SM501_DC_PANEL_BR_LOC:
- s->dc_panel_br_location = value & 0x07FF07FF;
- break;
-
- case SM501_DC_PANEL_H_TOT:
- s->dc_panel_h_total = value & 0x0FFF0FFF;
- break;
- case SM501_DC_PANEL_H_SYNC:
- s->dc_panel_h_sync = value & 0x00FF0FFF;
- break;
- case SM501_DC_PANEL_V_TOT:
- s->dc_panel_v_total = value & 0x0FFF0FFF;
- break;
- case SM501_DC_PANEL_V_SYNC:
- s->dc_panel_v_sync = value & 0x003F0FFF;
- break;
-
- case SM501_DC_PANEL_HWC_ADDR:
- s->dc_panel_hwc_addr = value & 0x8FFFFFF0;
- break;
- case SM501_DC_PANEL_HWC_LOC:
- s->dc_panel_hwc_location = value & 0x0FFF0FFF;
- break;
- case SM501_DC_PANEL_HWC_COLOR_1_2:
- s->dc_panel_hwc_color_1_2 = value;
- break;
- case SM501_DC_PANEL_HWC_COLOR_3:
- s->dc_panel_hwc_color_3 = value & 0x0000FFFF;
- break;
-
- case SM501_DC_CRT_CONTROL:
- s->dc_crt_control = value & 0x0003FFFF;
- break;
- case SM501_DC_CRT_FB_ADDR:
- s->dc_crt_fb_addr = value & 0x8FFFFFF0;
- break;
- case SM501_DC_CRT_FB_OFFSET:
- s->dc_crt_fb_offset = value & 0x3FF03FF0;
- break;
- case SM501_DC_CRT_H_TOT:
- s->dc_crt_h_total = value & 0x0FFF0FFF;
- break;
- case SM501_DC_CRT_H_SYNC:
- s->dc_crt_h_sync = value & 0x00FF0FFF;
- break;
- case SM501_DC_CRT_V_TOT:
- s->dc_crt_v_total = value & 0x0FFF0FFF;
- break;
- case SM501_DC_CRT_V_SYNC:
- s->dc_crt_v_sync = value & 0x003F0FFF;
- break;
-
- case SM501_DC_CRT_HWC_ADDR:
- s->dc_crt_hwc_addr = value & 0x8FFFFFF0;
- break;
- case SM501_DC_CRT_HWC_LOC:
- s->dc_crt_hwc_location = value & 0x0FFF0FFF;
- break;
- case SM501_DC_CRT_HWC_COLOR_1_2:
- s->dc_crt_hwc_color_1_2 = value;
- break;
- case SM501_DC_CRT_HWC_COLOR_3:
- s->dc_crt_hwc_color_3 = value & 0x0000FFFF;
- break;
-
- case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4:
- sm501_palette_write(opaque, addr - SM501_DC_PANEL_PALETTE, value);
- break;
-
- default:
- printf("sm501 disp ctrl : not implemented register write."
- " addr=%x, val=%x\n", (int)addr, (unsigned)value);
- abort();
- }
-}
-
-static const MemoryRegionOps sm501_disp_ctrl_ops = {
- .read = sm501_disp_ctrl_read,
- .write = sm501_disp_ctrl_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- uint32_t ret = 0;
- SM501_DPRINTF("sm501 2d engine regs : read addr=%x\n", (int)addr);
-
- switch(addr) {
- case SM501_2D_SOURCE_BASE:
- ret = s->twoD_source_base;
- break;
- default:
- printf("sm501 disp ctrl : not implemented register read."
- " addr=%x\n", (int)addr);
- abort();
- }
-
- return ret;
-}
-
-static void sm501_2d_engine_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 2d engine regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
-
- switch(addr) {
- case SM501_2D_SOURCE:
- s->twoD_source = value;
- break;
- case SM501_2D_DESTINATION:
- s->twoD_destination = value;
- break;
- case SM501_2D_DIMENSION:
- s->twoD_dimension = value;
- break;
- case SM501_2D_CONTROL:
- s->twoD_control = value;
-
- /* do 2d operation if start flag is set. */
- if (value & 0x80000000) {
- sm501_2d_operation(s);
- s->twoD_control &= ~0x80000000; /* start flag down */
- }
-
- break;
- case SM501_2D_PITCH:
- s->twoD_pitch = value;
- break;
- case SM501_2D_FOREGROUND:
- s->twoD_foreground = value;
- break;
- case SM501_2D_STRETCH:
- s->twoD_stretch = value;
- break;
- case SM501_2D_COLOR_COMPARE_MASK:
- s->twoD_color_compare_mask = value;
- break;
- case SM501_2D_MASK:
- s->twoD_mask = value;
- break;
- case SM501_2D_WINDOW_WIDTH:
- s->twoD_window_width = value;
- break;
- case SM501_2D_SOURCE_BASE:
- s->twoD_source_base = value;
- break;
- case SM501_2D_DESTINATION_BASE:
- s->twoD_destination_base = value;
- break;
- default:
- printf("sm501 2d engine : not implemented register write."
- " addr=%x, val=%x\n", (int)addr, (unsigned)value);
- abort();
- }
-}
-
-static const MemoryRegionOps sm501_2d_engine_ops = {
- .read = sm501_2d_engine_read,
- .write = sm501_2d_engine_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-/* draw line functions for all console modes */
-
-typedef void draw_line_func(uint8_t *d, const uint8_t *s,
- int width, const uint32_t *pal);
-
-typedef void draw_hwc_line_func(SM501State * s, int crt, uint8_t * palette,
- int c_y, uint8_t *d, int width);
-
-#define DEPTH 8
-#include "sm501_template.h"
-
-#define DEPTH 15
-#include "sm501_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 15
-#include "sm501_template.h"
-
-#define DEPTH 16
-#include "sm501_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 16
-#include "sm501_template.h"
-
-#define DEPTH 32
-#include "sm501_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 32
-#include "sm501_template.h"
-
-static draw_line_func * draw_line8_funcs[] = {
- draw_line8_8,
- draw_line8_15,
- draw_line8_16,
- draw_line8_32,
- draw_line8_32bgr,
- draw_line8_15bgr,
- draw_line8_16bgr,
-};
-
-static draw_line_func * draw_line16_funcs[] = {
- draw_line16_8,
- draw_line16_15,
- draw_line16_16,
- draw_line16_32,
- draw_line16_32bgr,
- draw_line16_15bgr,
- draw_line16_16bgr,
-};
-
-static draw_line_func * draw_line32_funcs[] = {
- draw_line32_8,
- draw_line32_15,
- draw_line32_16,
- draw_line32_32,
- draw_line32_32bgr,
- draw_line32_15bgr,
- draw_line32_16bgr,
-};
-
-static draw_hwc_line_func * draw_hwc_line_funcs[] = {
- draw_hwc_line_8,
- draw_hwc_line_15,
- draw_hwc_line_16,
- draw_hwc_line_32,
- draw_hwc_line_32bgr,
- draw_hwc_line_15bgr,
- draw_hwc_line_16bgr,
-};
-
-static inline int get_depth_index(DisplaySurface *surface)
-{
- switch (surface_bits_per_pixel(surface)) {
- default:
- case 8:
- return 0;
- case 15:
- return 1;
- case 16:
- return 2;
- case 32:
- if (is_surface_bgr(surface)) {
- return 4;
- } else {
- return 3;
- }
- }
-}
-
-static void sm501_draw_crt(SM501State * s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int y;
- int width = (s->dc_crt_h_total & 0x00000FFF) + 1;
- int height = (s->dc_crt_v_total & 0x00000FFF) + 1;
-
- uint8_t * src = s->local_mem;
- int src_bpp = 0;
- int dst_bpp = surface_bytes_per_pixel(surface);
- uint32_t * palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE
- - SM501_DC_PANEL_PALETTE];
- uint8_t hwc_palette[3 * 3];
- int ds_depth_index = get_depth_index(surface);
- draw_line_func * draw_line = NULL;
- draw_hwc_line_func * draw_hwc_line = NULL;
- int full_update = 0;
- int y_start = -1;
- ram_addr_t page_min = ~0l;
- ram_addr_t page_max = 0l;
- ram_addr_t offset = 0;
-
- /* choose draw_line function */
- switch (s->dc_crt_control & 3) {
- case SM501_DC_CRT_CONTROL_8BPP:
- src_bpp = 1;
- draw_line = draw_line8_funcs[ds_depth_index];
- break;
- case SM501_DC_CRT_CONTROL_16BPP:
- src_bpp = 2;
- draw_line = draw_line16_funcs[ds_depth_index];
- break;
- case SM501_DC_CRT_CONTROL_32BPP:
- src_bpp = 4;
- draw_line = draw_line32_funcs[ds_depth_index];
- break;
- default:
- printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n",
- s->dc_crt_control);
- abort();
- break;
- }
-
- /* set up to draw hardware cursor */
- if (is_hwc_enabled(s, 1)) {
- int i;
-
- /* get cursor palette */
- for (i = 0; i < 3; i++) {
- uint16_t rgb565 = get_hwc_color(s, 1, i + 1);
- hwc_palette[i * 3 + 0] = (rgb565 & 0xf800) >> 8; /* red */
- hwc_palette[i * 3 + 1] = (rgb565 & 0x07e0) >> 3; /* green */
- hwc_palette[i * 3 + 2] = (rgb565 & 0x001f) << 3; /* blue */
- }
-
- /* choose cursor draw line function */
- draw_hwc_line = draw_hwc_line_funcs[ds_depth_index];
- }
-
- /* adjust console size */
- if (s->last_width != width || s->last_height != height) {
- qemu_console_resize(s->con, width, height);
- surface = qemu_console_surface(s->con);
- s->last_width = width;
- s->last_height = height;
- full_update = 1;
- }
-
- /* draw each line according to conditions */
- memory_region_sync_dirty_bitmap(&s->local_mem_region);
- for (y = 0; y < height; y++) {
- int update_hwc = draw_hwc_line ? within_hwc_y_range(s, y, 1) : 0;
- int update = full_update || update_hwc;
- ram_addr_t page0 = offset;
- ram_addr_t page1 = offset + width * src_bpp - 1;
-
- /* check dirty flags for each line */
- update = memory_region_get_dirty(&s->local_mem_region, page0,
- page1 - page0, DIRTY_MEMORY_VGA);
-
- /* draw line and change status */
- if (update) {
- uint8_t *d = surface_data(surface);
- d += y * width * dst_bpp;
-
- /* draw graphics layer */
- draw_line(d, src, width, palette);
-
- /* draw haredware cursor */
- if (update_hwc) {
- draw_hwc_line(s, 1, hwc_palette, y - get_hwc_y(s, 1), d, width);
- }
-
- if (y_start < 0)
- y_start = y;
- if (page0 < page_min)
- page_min = page0;
- if (page1 > page_max)
- page_max = page1;
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
- y_start = -1;
- }
- }
-
- src += width * src_bpp;
- offset += width * src_bpp;
- }
-
- /* complete flush to display */
- if (y_start >= 0)
- dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
-
- /* clear dirty flags */
- if (page_min != ~0l) {
- memory_region_reset_dirty(&s->local_mem_region,
- page_min, page_max + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- }
-}
-
-static void sm501_update_display(void *opaque)
-{
- SM501State * s = (SM501State *)opaque;
-
- if (s->dc_crt_control & SM501_DC_CRT_CONTROL_ENABLE)
- sm501_draw_crt(s);
-}
-
-static const GraphicHwOps sm501_ops = {
- .gfx_update = sm501_update_display,
-};
-
-void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
- uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr)
-{
- SM501State * s;
- DeviceState *dev;
- MemoryRegion *sm501_system_config = g_new(MemoryRegion, 1);
- MemoryRegion *sm501_disp_ctrl = g_new(MemoryRegion, 1);
- MemoryRegion *sm501_2d_engine = g_new(MemoryRegion, 1);
-
- /* allocate management data region */
- s = (SM501State *)g_malloc0(sizeof(SM501State));
- s->base = base;
- s->local_mem_size_index
- = get_local_mem_size_index(local_mem_bytes);
- SM501_DPRINTF("local mem size=%x. index=%d\n", get_local_mem_size(s),
- s->local_mem_size_index);
- s->system_control = 0x00100000;
- s->misc_control = 0x00001000; /* assumes SH, active=low */
- s->dc_panel_control = 0x00010000;
- s->dc_crt_control = 0x00010000;
-
- /* allocate local memory */
- memory_region_init_ram(&s->local_mem_region, NULL, "sm501.local",
- local_mem_bytes, &error_fatal);
- vmstate_register_ram_global(&s->local_mem_region);
- memory_region_set_log(&s->local_mem_region, true, DIRTY_MEMORY_VGA);
- s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region);
- memory_region_add_subregion(address_space_mem, base, &s->local_mem_region);
-
- /* map mmio */
- memory_region_init_io(sm501_system_config, NULL, &sm501_system_config_ops, s,
- "sm501-system-config", 0x6c);
- memory_region_add_subregion(address_space_mem, base + MMIO_BASE_OFFSET,
- sm501_system_config);
- memory_region_init_io(sm501_disp_ctrl, NULL, &sm501_disp_ctrl_ops, s,
- "sm501-disp-ctrl", 0x1000);
- memory_region_add_subregion(address_space_mem,
- base + MMIO_BASE_OFFSET + SM501_DC,
- sm501_disp_ctrl);
- memory_region_init_io(sm501_2d_engine, NULL, &sm501_2d_engine_ops, s,
- "sm501-2d-engine", 0x54);
- memory_region_add_subregion(address_space_mem,
- base + MMIO_BASE_OFFSET + SM501_2D_ENGINE,
- sm501_2d_engine);
-
- /* bridge to usb host emulation module */
- dev = qdev_create(NULL, "sysbus-ohci");
- qdev_prop_set_uint32(dev, "num-ports", 2);
- qdev_prop_set_uint64(dev, "dma-offset", base);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
- base + MMIO_BASE_OFFSET + SM501_USB_HOST);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
-
- /* bridge to serial emulation module */
- if (chr) {
- serial_mm_init(address_space_mem,
- base + MMIO_BASE_OFFSET + SM501_UART0, 2,
- NULL, /* TODO : chain irq to IRL */
- 115200, chr, DEVICE_NATIVE_ENDIAN);
- }
-
- /* create qemu graphic console */
- s->con = graphic_console_init(DEVICE(dev), 0, &sm501_ops, s);
-}
diff --git a/qemu/hw/display/sm501_template.h b/qemu/hw/display/sm501_template.h
deleted file mode 100644
index f33e499be..000000000
--- a/qemu/hw/display/sm501_template.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Pixel drawing function templates for QEMU SM501 Device
- *
- * Copyright (c) 2008 Shin-ichiro KAWASAKI
- *
- * 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.
- */
-
-#if DEPTH == 8
-#define BPP 1
-#define PIXEL_TYPE uint8_t
-#elif DEPTH == 15 || DEPTH == 16
-#define BPP 2
-#define PIXEL_TYPE uint16_t
-#elif DEPTH == 32
-#define BPP 4
-#define PIXEL_TYPE uint32_t
-#else
-#error unsupport depth
-#endif
-
-#ifdef BGR_FORMAT
-#define PIXEL_NAME glue(DEPTH, bgr)
-#else
-#define PIXEL_NAME DEPTH
-#endif /* BGR_FORMAT */
-
-
-static void glue(draw_line8_, PIXEL_NAME)(
- uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
-{
- uint8_t v, r, g, b;
- do {
- v = ldub_p(s);
- r = (pal[v] >> 16) & 0xff;
- g = (pal[v] >> 8) & 0xff;
- b = (pal[v] >> 0) & 0xff;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s ++;
- d += BPP;
- } while (-- width != 0);
-}
-
-static void glue(draw_line16_, PIXEL_NAME)(
- uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
-{
- uint16_t rgb565;
- uint8_t r, g, b;
-
- do {
- rgb565 = lduw_p(s);
- r = ((rgb565 >> 11) & 0x1f) << 3;
- g = ((rgb565 >> 5) & 0x3f) << 2;
- b = ((rgb565 >> 0) & 0x1f) << 3;
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 2;
- d += BPP;
- } while (-- width != 0);
-}
-
-static void glue(draw_line32_, PIXEL_NAME)(
- uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
-{
- uint8_t r, g, b;
-
- do {
- ldub_p(s);
-#if defined(TARGET_WORDS_BIGENDIAN)
- r = s[1];
- g = s[2];
- b = s[3];
-#else
- b = s[0];
- g = s[1];
- r = s[2];
-#endif
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- s += 4;
- d += BPP;
- } while (-- width != 0);
-}
-
-/**
- * Draw hardware cursor image on the given line.
- */
-static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State * s, int crt,
- uint8_t * palette, int c_y, uint8_t *d, int width)
-{
- int x, i;
- uint8_t bitset = 0;
-
- /* get hardware cursor pattern */
- uint32_t cursor_addr = get_hwc_address(s, crt);
- assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
- cursor_addr += 64 * c_y / 4; /* 4 pixels per byte */
- cursor_addr += s->base;
-
- /* get cursor position */
- x = get_hwc_x(s, crt);
- d += x * BPP;
-
- for (i = 0; i < SM501_HWC_WIDTH && x + i < width; i++) {
- uint8_t v;
-
- /* get pixel value */
- if (i % 4 == 0) {
- bitset = ldub_phys(&address_space_memory, cursor_addr);
- cursor_addr++;
- }
- v = bitset & 3;
- bitset >>= 2;
-
- /* write pixel */
- if (v) {
- v--;
- uint8_t r = palette[v * 3 + 0];
- uint8_t g = palette[v * 3 + 1];
- uint8_t b = palette[v * 3 + 2];
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
- }
- d += BPP;
- }
-}
-
-#undef DEPTH
-#undef BPP
-#undef PIXEL_TYPE
-#undef PIXEL_NAME
-#undef BGR_FORMAT
diff --git a/qemu/hw/display/ssd0303.c b/qemu/hw/display/ssd0303.c
deleted file mode 100644
index d3017563f..000000000
--- a/qemu/hw/display/ssd0303.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * SSD0303 OLED controller with OSRAM Pictiva 96x16 display.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-/* The controller can support a variety of different displays, but we only
- implement one. Most of the commends relating to brightness and geometry
- setup are ignored. */
-#include "qemu/osdep.h"
-#include "hw/i2c/i2c.h"
-#include "ui/console.h"
-
-//#define DEBUG_SSD0303 1
-
-#ifdef DEBUG_SSD0303
-#define DPRINTF(fmt, ...) \
-do { printf("ssd0303: " fmt , ## __VA_ARGS__); } while (0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "ssd0303: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while(0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "ssd0303: error: " fmt , ## __VA_ARGS__);} while (0)
-#endif
-
-/* Scaling factor for pixels. */
-#define MAGNIFY 4
-
-enum ssd0303_mode
-{
- SSD0303_IDLE,
- SSD0303_DATA,
- SSD0303_CMD
-};
-
-enum ssd0303_cmd {
- SSD0303_CMD_NONE,
- SSD0303_CMD_SKIP1
-};
-
-#define TYPE_SSD0303 "ssd0303"
-#define SSD0303(obj) OBJECT_CHECK(ssd0303_state, (obj), TYPE_SSD0303)
-
-typedef struct {
- I2CSlave parent_obj;
-
- QemuConsole *con;
- int row;
- int col;
- int start_line;
- int mirror;
- int flash;
- int enabled;
- int inverse;
- int redraw;
- enum ssd0303_mode mode;
- enum ssd0303_cmd cmd_state;
- uint8_t framebuffer[132*8];
-} ssd0303_state;
-
-static int ssd0303_recv(I2CSlave *i2c)
-{
- BADF("Reads not implemented\n");
- return -1;
-}
-
-static int ssd0303_send(I2CSlave *i2c, uint8_t data)
-{
- ssd0303_state *s = SSD0303(i2c);
- enum ssd0303_cmd old_cmd_state;
-
- switch (s->mode) {
- case SSD0303_IDLE:
- DPRINTF("byte 0x%02x\n", data);
- if (data == 0x80)
- s->mode = SSD0303_CMD;
- else if (data == 0x40)
- s->mode = SSD0303_DATA;
- else
- BADF("Unexpected byte 0x%x\n", data);
- break;
- case SSD0303_DATA:
- DPRINTF("data 0x%02x\n", data);
- if (s->col < 132) {
- s->framebuffer[s->col + s->row * 132] = data;
- s->col++;
- s->redraw = 1;
- }
- break;
- case SSD0303_CMD:
- old_cmd_state = s->cmd_state;
- s->cmd_state = SSD0303_CMD_NONE;
- switch (old_cmd_state) {
- case SSD0303_CMD_NONE:
- DPRINTF("cmd 0x%02x\n", data);
- s->mode = SSD0303_IDLE;
- switch (data) {
- case 0x00 ... 0x0f: /* Set lower column address. */
- s->col = (s->col & 0xf0) | (data & 0xf);
- break;
- case 0x10 ... 0x20: /* Set higher column address. */
- s->col = (s->col & 0x0f) | ((data & 0xf) << 4);
- break;
- case 0x40 ... 0x7f: /* Set start line. */
- s->start_line = 0;
- break;
- case 0x81: /* Set contrast (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xa0: /* Mirror off. */
- s->mirror = 0;
- break;
- case 0xa1: /* Mirror off. */
- s->mirror = 1;
- break;
- case 0xa4: /* Entire display off. */
- s->flash = 0;
- break;
- case 0xa5: /* Entire display on. */
- s->flash = 1;
- break;
- case 0xa6: /* Inverse off. */
- s->inverse = 0;
- break;
- case 0xa7: /* Inverse on. */
- s->inverse = 1;
- break;
- case 0xa8: /* Set multiplied ratio (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xad: /* DC-DC power control. */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xae: /* Display off. */
- s->enabled = 0;
- break;
- case 0xaf: /* Display on. */
- s->enabled = 1;
- break;
- case 0xb0 ... 0xbf: /* Set Page address. */
- s->row = data & 7;
- break;
- case 0xc0 ... 0xc8: /* Set COM output direction (Ignored). */
- break;
- case 0xd3: /* Set display offset (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xd5: /* Set display clock (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xd8: /* Set color and power mode (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xd9: /* Set pre-charge period (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xda: /* Set COM pin configuration (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xdb: /* Set VCOM dselect level (Ignored). */
- s->cmd_state = SSD0303_CMD_SKIP1;
- break;
- case 0xe3: /* no-op. */
- break;
- default:
- BADF("Unknown command: 0x%x\n", data);
- }
- break;
- case SSD0303_CMD_SKIP1:
- DPRINTF("skip 0x%02x\n", data);
- break;
- }
- break;
- }
- return 0;
-}
-
-static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
-{
- ssd0303_state *s = SSD0303(i2c);
-
- switch (event) {
- case I2C_FINISH:
- s->mode = SSD0303_IDLE;
- break;
- case I2C_START_RECV:
- case I2C_START_SEND:
- case I2C_NACK:
- /* Nothing to do. */
- break;
- }
-}
-
-static void ssd0303_update_display(void *opaque)
-{
- ssd0303_state *s = (ssd0303_state *)opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- uint8_t *dest;
- uint8_t *src;
- int x;
- int y;
- int line;
- char *colors[2];
- char colortab[MAGNIFY * 8];
- int dest_width;
- uint8_t mask;
-
- if (!s->redraw)
- return;
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 15:
- dest_width = 2;
- break;
- case 16:
- dest_width = 2;
- break;
- case 24:
- dest_width = 3;
- break;
- case 32:
- dest_width = 4;
- break;
- default:
- BADF("Bad color depth\n");
- return;
- }
- dest_width *= MAGNIFY;
- memset(colortab, 0xff, dest_width);
- memset(colortab + dest_width, 0, dest_width);
- if (s->flash) {
- colors[0] = colortab;
- colors[1] = colortab;
- } else if (s->inverse) {
- colors[0] = colortab;
- colors[1] = colortab + dest_width;
- } else {
- colors[0] = colortab + dest_width;
- colors[1] = colortab;
- }
- dest = surface_data(surface);
- for (y = 0; y < 16; y++) {
- line = (y + s->start_line) & 63;
- src = s->framebuffer + 132 * (line >> 3) + 36;
- mask = 1 << (line & 7);
- for (x = 0; x < 96; x++) {
- memcpy(dest, colors[(*src & mask) != 0], dest_width);
- dest += dest_width;
- src++;
- }
- for (x = 1; x < MAGNIFY; x++) {
- memcpy(dest, dest - dest_width * 96, dest_width * 96);
- dest += dest_width * 96;
- }
- }
- s->redraw = 0;
- dpy_gfx_update(s->con, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
-}
-
-static void ssd0303_invalidate_display(void * opaque)
-{
- ssd0303_state *s = (ssd0303_state *)opaque;
- s->redraw = 1;
-}
-
-static const VMStateDescription vmstate_ssd0303 = {
- .name = "ssd0303_oled",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(row, ssd0303_state),
- VMSTATE_INT32(col, ssd0303_state),
- VMSTATE_INT32(start_line, ssd0303_state),
- VMSTATE_INT32(mirror, ssd0303_state),
- VMSTATE_INT32(flash, ssd0303_state),
- VMSTATE_INT32(enabled, ssd0303_state),
- VMSTATE_INT32(inverse, ssd0303_state),
- VMSTATE_INT32(redraw, ssd0303_state),
- VMSTATE_UINT32(mode, ssd0303_state),
- VMSTATE_UINT32(cmd_state, ssd0303_state),
- VMSTATE_BUFFER(framebuffer, ssd0303_state),
- VMSTATE_I2C_SLAVE(parent_obj, ssd0303_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps ssd0303_ops = {
- .invalidate = ssd0303_invalidate_display,
- .gfx_update = ssd0303_update_display,
-};
-
-static int ssd0303_init(I2CSlave *i2c)
-{
- ssd0303_state *s = SSD0303(i2c);
-
- s->con = graphic_console_init(DEVICE(i2c), 0, &ssd0303_ops, s);
- qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
- return 0;
-}
-
-static void ssd0303_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
-
- k->init = ssd0303_init;
- k->event = ssd0303_event;
- k->recv = ssd0303_recv;
- k->send = ssd0303_send;
- dc->vmsd = &vmstate_ssd0303;
-}
-
-static const TypeInfo ssd0303_info = {
- .name = TYPE_SSD0303,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(ssd0303_state),
- .class_init = ssd0303_class_init,
-};
-
-static void ssd0303_register_types(void)
-{
- type_register_static(&ssd0303_info);
-}
-
-type_init(ssd0303_register_types)
diff --git a/qemu/hw/display/ssd0323.c b/qemu/hw/display/ssd0323.c
deleted file mode 100644
index 14c1bf339..000000000
--- a/qemu/hw/display/ssd0323.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * SSD0323 OLED controller with OSRAM Pictiva 128x64 display.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-/* The controller can support a variety of different displays, but we only
- implement one. Most of the commends relating to brightness and geometry
- setup are ignored. */
-#include "qemu/osdep.h"
-#include "hw/ssi/ssi.h"
-#include "ui/console.h"
-
-//#define DEBUG_SSD0323 1
-
-#ifdef DEBUG_SSD0323
-#define DPRINTF(fmt, ...) \
-do { printf("ssd0323: " fmt , ## __VA_ARGS__); } while (0)
-#define BADF(fmt, ...) \
-do { \
- fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__); abort(); \
-} while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while(0)
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__);} while (0)
-#endif
-
-/* Scaling factor for pixels. */
-#define MAGNIFY 4
-
-#define REMAP_SWAP_COLUMN 0x01
-#define REMAP_SWAP_NYBBLE 0x02
-#define REMAP_VERTICAL 0x04
-#define REMAP_SWAP_COM 0x10
-#define REMAP_SPLIT_COM 0x40
-
-enum ssd0323_mode
-{
- SSD0323_CMD,
- SSD0323_DATA
-};
-
-typedef struct {
- SSISlave ssidev;
- QemuConsole *con;
-
- int cmd_len;
- int cmd;
- int cmd_data[8];
- int row;
- int row_start;
- int row_end;
- int col;
- int col_start;
- int col_end;
- int redraw;
- int remap;
- enum ssd0323_mode mode;
- uint8_t framebuffer[128 * 80 / 2];
-} ssd0323_state;
-
-static uint32_t ssd0323_transfer(SSISlave *dev, uint32_t data)
-{
- ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
-
- switch (s->mode) {
- case SSD0323_DATA:
- DPRINTF("data 0x%02x\n", data);
- s->framebuffer[s->col + s->row * 64] = data;
- if (s->remap & REMAP_VERTICAL) {
- s->row++;
- if (s->row > s->row_end) {
- s->row = s->row_start;
- s->col++;
- }
- if (s->col > s->col_end) {
- s->col = s->col_start;
- }
- } else {
- s->col++;
- if (s->col > s->col_end) {
- s->row++;
- s->col = s->col_start;
- }
- if (s->row > s->row_end) {
- s->row = s->row_start;
- }
- }
- s->redraw = 1;
- break;
- case SSD0323_CMD:
- DPRINTF("cmd 0x%02x\n", data);
- if (s->cmd_len == 0) {
- s->cmd = data;
- } else {
- s->cmd_data[s->cmd_len - 1] = data;
- }
- s->cmd_len++;
- switch (s->cmd) {
-#define DATA(x) if (s->cmd_len <= (x)) return 0
- case 0x15: /* Set column. */
- DATA(2);
- s->col = s->col_start = s->cmd_data[0] % 64;
- s->col_end = s->cmd_data[1] % 64;
- break;
- case 0x75: /* Set row. */
- DATA(2);
- s->row = s->row_start = s->cmd_data[0] % 80;
- s->row_end = s->cmd_data[1] % 80;
- break;
- case 0x81: /* Set contrast */
- DATA(1);
- break;
- case 0x84: case 0x85: case 0x86: /* Max current. */
- DATA(0);
- break;
- case 0xa0: /* Set remapping. */
- /* FIXME: Implement this. */
- DATA(1);
- s->remap = s->cmd_data[0];
- break;
- case 0xa1: /* Set display start line. */
- case 0xa2: /* Set display offset. */
- /* FIXME: Implement these. */
- DATA(1);
- break;
- case 0xa4: /* Normal mode. */
- case 0xa5: /* All on. */
- case 0xa6: /* All off. */
- case 0xa7: /* Inverse. */
- /* FIXME: Implement these. */
- DATA(0);
- break;
- case 0xa8: /* Set multiplex ratio. */
- case 0xad: /* Set DC-DC converter. */
- DATA(1);
- /* Ignored. Don't care. */
- break;
- case 0xae: /* Display off. */
- case 0xaf: /* Display on. */
- DATA(0);
- /* TODO: Implement power control. */
- break;
- case 0xb1: /* Set phase length. */
- case 0xb2: /* Set row period. */
- case 0xb3: /* Set clock rate. */
- case 0xbc: /* Set precharge. */
- case 0xbe: /* Set VCOMH. */
- case 0xbf: /* Set segment low. */
- DATA(1);
- /* Ignored. Don't care. */
- break;
- case 0xb8: /* Set grey scale table. */
- /* FIXME: Implement this. */
- DATA(8);
- break;
- case 0xe3: /* NOP. */
- DATA(0);
- break;
- case 0xff: /* Nasty hack because we don't handle chip selects
- properly. */
- break;
- default:
- BADF("Unknown command: 0x%x\n", data);
- }
- s->cmd_len = 0;
- return 0;
- }
- return 0;
-}
-
-static void ssd0323_update_display(void *opaque)
-{
- ssd0323_state *s = (ssd0323_state *)opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- uint8_t *dest;
- uint8_t *src;
- int x;
- int y;
- int i;
- int line;
- char *colors[16];
- char colortab[MAGNIFY * 64];
- char *p;
- int dest_width;
-
- if (!s->redraw)
- return;
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 15:
- dest_width = 2;
- break;
- case 16:
- dest_width = 2;
- break;
- case 24:
- dest_width = 3;
- break;
- case 32:
- dest_width = 4;
- break;
- default:
- BADF("Bad color depth\n");
- return;
- }
- p = colortab;
- for (i = 0; i < 16; i++) {
- int n;
- colors[i] = p;
- switch (surface_bits_per_pixel(surface)) {
- case 15:
- n = i * 2 + (i >> 3);
- p[0] = n | (n << 5);
- p[1] = (n << 2) | (n >> 3);
- break;
- case 16:
- n = i * 2 + (i >> 3);
- p[0] = n | (n << 6) | ((n << 1) & 0x20);
- p[1] = (n << 3) | (n >> 2);
- break;
- case 24:
- case 32:
- n = (i << 4) | i;
- p[0] = p[1] = p[2] = n;
- break;
- default:
- BADF("Bad color depth\n");
- return;
- }
- p += dest_width;
- }
- /* TODO: Implement row/column remapping. */
- dest = surface_data(surface);
- for (y = 0; y < 64; y++) {
- line = y;
- src = s->framebuffer + 64 * line;
- for (x = 0; x < 64; x++) {
- int val;
- val = *src >> 4;
- for (i = 0; i < MAGNIFY; i++) {
- memcpy(dest, colors[val], dest_width);
- dest += dest_width;
- }
- val = *src & 0xf;
- for (i = 0; i < MAGNIFY; i++) {
- memcpy(dest, colors[val], dest_width);
- dest += dest_width;
- }
- src++;
- }
- for (i = 1; i < MAGNIFY; i++) {
- memcpy(dest, dest - dest_width * MAGNIFY * 128,
- dest_width * 128 * MAGNIFY);
- dest += dest_width * 128 * MAGNIFY;
- }
- }
- s->redraw = 0;
- dpy_gfx_update(s->con, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
-}
-
-static void ssd0323_invalidate_display(void * opaque)
-{
- ssd0323_state *s = (ssd0323_state *)opaque;
- s->redraw = 1;
-}
-
-/* Command/data input. */
-static void ssd0323_cd(void *opaque, int n, int level)
-{
- ssd0323_state *s = (ssd0323_state *)opaque;
- DPRINTF("%s mode\n", level ? "Data" : "Command");
- s->mode = level ? SSD0323_DATA : SSD0323_CMD;
-}
-
-static void ssd0323_save(QEMUFile *f, void *opaque)
-{
- SSISlave *ss = SSI_SLAVE(opaque);
- ssd0323_state *s = (ssd0323_state *)opaque;
- int i;
-
- qemu_put_be32(f, s->cmd_len);
- qemu_put_be32(f, s->cmd);
- for (i = 0; i < 8; i++)
- qemu_put_be32(f, s->cmd_data[i]);
- qemu_put_be32(f, s->row);
- qemu_put_be32(f, s->row_start);
- qemu_put_be32(f, s->row_end);
- qemu_put_be32(f, s->col);
- qemu_put_be32(f, s->col_start);
- qemu_put_be32(f, s->col_end);
- qemu_put_be32(f, s->redraw);
- qemu_put_be32(f, s->remap);
- qemu_put_be32(f, s->mode);
- qemu_put_buffer(f, s->framebuffer, sizeof(s->framebuffer));
-
- qemu_put_be32(f, ss->cs);
-}
-
-static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
-{
- SSISlave *ss = SSI_SLAVE(opaque);
- ssd0323_state *s = (ssd0323_state *)opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->cmd_len = qemu_get_be32(f);
- if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
- return -EINVAL;
- }
- s->cmd = qemu_get_be32(f);
- for (i = 0; i < 8; i++)
- s->cmd_data[i] = qemu_get_be32(f);
- s->row = qemu_get_be32(f);
- if (s->row < 0 || s->row >= 80) {
- return -EINVAL;
- }
- s->row_start = qemu_get_be32(f);
- if (s->row_start < 0 || s->row_start >= 80) {
- return -EINVAL;
- }
- s->row_end = qemu_get_be32(f);
- if (s->row_end < 0 || s->row_end >= 80) {
- return -EINVAL;
- }
- s->col = qemu_get_be32(f);
- if (s->col < 0 || s->col >= 64) {
- return -EINVAL;
- }
- s->col_start = qemu_get_be32(f);
- if (s->col_start < 0 || s->col_start >= 64) {
- return -EINVAL;
- }
- s->col_end = qemu_get_be32(f);
- if (s->col_end < 0 || s->col_end >= 64) {
- return -EINVAL;
- }
- s->redraw = qemu_get_be32(f);
- s->remap = qemu_get_be32(f);
- s->mode = qemu_get_be32(f);
- if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
- return -EINVAL;
- }
- qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
-
- ss->cs = qemu_get_be32(f);
-
- return 0;
-}
-
-static const GraphicHwOps ssd0323_ops = {
- .invalidate = ssd0323_invalidate_display,
- .gfx_update = ssd0323_update_display,
-};
-
-static int ssd0323_init(SSISlave *d)
-{
- DeviceState *dev = DEVICE(d);
- ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
-
- s->col_end = 63;
- s->row_end = 79;
- s->con = graphic_console_init(dev, 0, &ssd0323_ops, s);
- qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
-
- qdev_init_gpio_in(dev, ssd0323_cd, 1);
-
- register_savevm(dev, "ssd0323_oled", -1, 1,
- ssd0323_save, ssd0323_load, s);
- return 0;
-}
-
-static void ssd0323_class_init(ObjectClass *klass, void *data)
-{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = ssd0323_init;
- k->transfer = ssd0323_transfer;
- k->cs_polarity = SSI_CS_HIGH;
-}
-
-static const TypeInfo ssd0323_info = {
- .name = "ssd0323",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(ssd0323_state),
- .class_init = ssd0323_class_init,
-};
-
-static void ssd03232_register_types(void)
-{
- type_register_static(&ssd0323_info);
-}
-
-type_init(ssd03232_register_types)
diff --git a/qemu/hw/display/tc6393xb.c b/qemu/hw/display/tc6393xb.c
deleted file mode 100644
index da3ceceb0..000000000
--- a/qemu/hw/display/tc6393xb.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * Toshiba TC6393XB I/O Controller.
- * Found in Sharp Zaurus SL-6000 (tosa) or some
- * Toshiba e-Series PDAs.
- *
- * Most features are currently unsupported!!!
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/devices.h"
-#include "hw/block/flash.h"
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-
-#define IRQ_TC6393_NAND 0
-#define IRQ_TC6393_MMC 1
-#define IRQ_TC6393_OHCI 2
-#define IRQ_TC6393_SERIAL 3
-#define IRQ_TC6393_FB 4
-
-#define TC6393XB_NR_IRQS 8
-
-#define TC6393XB_GPIOS 16
-
-#define SCR_REVID 0x08 /* b Revision ID */
-#define SCR_ISR 0x50 /* b Interrupt Status */
-#define SCR_IMR 0x52 /* b Interrupt Mask */
-#define SCR_IRR 0x54 /* b Interrupt Routing */
-#define SCR_GPER 0x60 /* w GP Enable */
-#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */
-#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */
-#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */
-#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */
-#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */
-#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */
-#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */
-#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */
-#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */
-#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */
-#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */
-#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */
-#define SCR_CCR 0x98 /* w Clock Control */
-#define SCR_PLL2CR 0x9a /* w PLL2 Control */
-#define SCR_PLL1CR 0x9c /* l PLL1 Control */
-#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */
-#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */
-#define SCR_FER 0xe0 /* b Function Enable */
-#define SCR_MCR 0xe4 /* w Mode Control */
-#define SCR_CONFIG 0xfc /* b Configuration Control */
-#define SCR_DEBUG 0xff /* b Debug */
-
-#define NAND_CFG_COMMAND 0x04 /* w Command */
-#define NAND_CFG_BASE 0x10 /* l Control Base Address */
-#define NAND_CFG_INTP 0x3d /* b Interrupt Pin */
-#define NAND_CFG_INTE 0x48 /* b Int Enable */
-#define NAND_CFG_EC 0x4a /* b Event Control */
-#define NAND_CFG_ICC 0x4c /* b Internal Clock Control */
-#define NAND_CFG_ECCC 0x5b /* b ECC Control */
-#define NAND_CFG_NFTC 0x60 /* b NAND Flash Transaction Control */
-#define NAND_CFG_NFM 0x61 /* b NAND Flash Monitor */
-#define NAND_CFG_NFPSC 0x62 /* b NAND Flash Power Supply Control */
-#define NAND_CFG_NFDC 0x63 /* b NAND Flash Detect Control */
-
-#define NAND_DATA 0x00 /* l Data */
-#define NAND_MODE 0x04 /* b Mode */
-#define NAND_STATUS 0x05 /* b Status */
-#define NAND_ISR 0x06 /* b Interrupt Status */
-#define NAND_IMR 0x07 /* b Interrupt Mask */
-
-#define NAND_MODE_WP 0x80
-#define NAND_MODE_CE 0x10
-#define NAND_MODE_ALE 0x02
-#define NAND_MODE_CLE 0x01
-#define NAND_MODE_ECC_MASK 0x60
-#define NAND_MODE_ECC_EN 0x20
-#define NAND_MODE_ECC_READ 0x40
-#define NAND_MODE_ECC_RST 0x60
-
-struct TC6393xbState {
- MemoryRegion iomem;
- qemu_irq irq;
- qemu_irq *sub_irqs;
- struct {
- uint8_t ISR;
- uint8_t IMR;
- uint8_t IRR;
- uint16_t GPER;
- uint8_t GPI_SR[3];
- uint8_t GPI_IMR[3];
- uint8_t GPI_EDER[3];
- uint8_t GPI_LIR[3];
- uint8_t GP_IARCR[3];
- uint8_t GP_IARLCR[3];
- uint8_t GPI_BCR[3];
- uint16_t GPA_IARCR;
- uint16_t GPA_IARLCR;
- uint16_t CCR;
- uint16_t PLL2CR;
- uint32_t PLL1CR;
- uint8_t DIARCR;
- uint8_t DBOCR;
- uint8_t FER;
- uint16_t MCR;
- uint8_t CONFIG;
- uint8_t DEBUG;
- } scr;
- uint32_t gpio_dir;
- uint32_t gpio_level;
- uint32_t prev_level;
- qemu_irq handler[TC6393XB_GPIOS];
- qemu_irq *gpio_in;
-
- struct {
- uint8_t mode;
- uint8_t isr;
- uint8_t imr;
- } nand;
- int nand_enable;
- uint32_t nand_phys;
- DeviceState *flash;
- ECCState ecc;
-
- QemuConsole *con;
- MemoryRegion vram;
- uint16_t *vram_ptr;
- uint32_t scr_width, scr_height; /* in pixels */
- qemu_irq l3v;
- unsigned blank : 1,
- blanked : 1;
-};
-
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
-{
- return s->gpio_in;
-}
-
-static void tc6393xb_gpio_set(void *opaque, int line, int level)
-{
-// TC6393xbState *s = opaque;
-
- if (line > TC6393XB_GPIOS) {
- printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
- return;
- }
-
- // FIXME: how does the chip reflect the GPIO input level change?
-}
-
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
- qemu_irq handler)
-{
- if (line >= TC6393XB_GPIOS) {
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
- return;
- }
-
- s->handler[line] = handler;
-}
-
-static void tc6393xb_gpio_handler_update(TC6393xbState *s)
-{
- uint32_t level, diff;
- int bit;
-
- level = s->gpio_level & s->gpio_dir;
-
- for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ctz32(diff);
- qemu_set_irq(s->handler[bit], (level >> bit) & 1);
- }
-
- s->prev_level = level;
-}
-
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s)
-{
- return s->l3v;
-}
-
-static void tc6393xb_l3v(void *opaque, int line, int level)
-{
- TC6393xbState *s = opaque;
- s->blank = !level;
- fprintf(stderr, "L3V: %d\n", level);
-}
-
-static void tc6393xb_sub_irq(void *opaque, int line, int level) {
- TC6393xbState *s = opaque;
- uint8_t isr = s->scr.ISR;
- if (level)
- isr |= 1 << line;
- else
- isr &= ~(1 << line);
- s->scr.ISR = isr;
- qemu_set_irq(s->irq, isr & s->scr.IMR);
-}
-
-#define SCR_REG_B(N) \
- case SCR_ ##N: return s->scr.N
-#define SCR_REG_W(N) \
- case SCR_ ##N: return s->scr.N; \
- case SCR_ ##N + 1: return s->scr.N >> 8;
-#define SCR_REG_L(N) \
- case SCR_ ##N: return s->scr.N; \
- case SCR_ ##N + 1: return s->scr.N >> 8; \
- case SCR_ ##N + 2: return s->scr.N >> 16; \
- case SCR_ ##N + 3: return s->scr.N >> 24;
-#define SCR_REG_A(N) \
- case SCR_ ##N(0): return s->scr.N[0]; \
- case SCR_ ##N(1): return s->scr.N[1]; \
- case SCR_ ##N(2): return s->scr.N[2]
-
-static uint32_t tc6393xb_scr_readb(TC6393xbState *s, hwaddr addr)
-{
- switch (addr) {
- case SCR_REVID:
- return 3;
- case SCR_REVID+1:
- return 0;
- SCR_REG_B(ISR);
- SCR_REG_B(IMR);
- SCR_REG_B(IRR);
- SCR_REG_W(GPER);
- SCR_REG_A(GPI_SR);
- SCR_REG_A(GPI_IMR);
- SCR_REG_A(GPI_EDER);
- SCR_REG_A(GPI_LIR);
- case SCR_GPO_DSR(0):
- case SCR_GPO_DSR(1):
- case SCR_GPO_DSR(2):
- return (s->gpio_level >> ((addr - SCR_GPO_DSR(0)) * 8)) & 0xff;
- case SCR_GPO_DOECR(0):
- case SCR_GPO_DOECR(1):
- case SCR_GPO_DOECR(2):
- return (s->gpio_dir >> ((addr - SCR_GPO_DOECR(0)) * 8)) & 0xff;
- SCR_REG_A(GP_IARCR);
- SCR_REG_A(GP_IARLCR);
- SCR_REG_A(GPI_BCR);
- SCR_REG_W(GPA_IARCR);
- SCR_REG_W(GPA_IARLCR);
- SCR_REG_W(CCR);
- SCR_REG_W(PLL2CR);
- SCR_REG_L(PLL1CR);
- SCR_REG_B(DIARCR);
- SCR_REG_B(DBOCR);
- SCR_REG_B(FER);
- SCR_REG_W(MCR);
- SCR_REG_B(CONFIG);
- SCR_REG_B(DEBUG);
- }
- fprintf(stderr, "tc6393xb_scr: unhandled read at %08x\n", (uint32_t) addr);
- return 0;
-}
-#undef SCR_REG_B
-#undef SCR_REG_W
-#undef SCR_REG_L
-#undef SCR_REG_A
-
-#define SCR_REG_B(N) \
- case SCR_ ##N: s->scr.N = value; return;
-#define SCR_REG_W(N) \
- case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \
- case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); return
-#define SCR_REG_L(N) \
- case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \
- case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); return; \
- case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); return; \
- case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); return;
-#define SCR_REG_A(N) \
- case SCR_ ##N(0): s->scr.N[0] = value; return; \
- case SCR_ ##N(1): s->scr.N[1] = value; return; \
- case SCR_ ##N(2): s->scr.N[2] = value; return
-
-static void tc6393xb_scr_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
-{
- switch (addr) {
- SCR_REG_B(ISR);
- SCR_REG_B(IMR);
- SCR_REG_B(IRR);
- SCR_REG_W(GPER);
- SCR_REG_A(GPI_SR);
- SCR_REG_A(GPI_IMR);
- SCR_REG_A(GPI_EDER);
- SCR_REG_A(GPI_LIR);
- case SCR_GPO_DSR(0):
- case SCR_GPO_DSR(1):
- case SCR_GPO_DSR(2):
- s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8));
- tc6393xb_gpio_handler_update(s);
- return;
- case SCR_GPO_DOECR(0):
- case SCR_GPO_DOECR(1):
- case SCR_GPO_DOECR(2):
- s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8));
- tc6393xb_gpio_handler_update(s);
- return;
- SCR_REG_A(GP_IARCR);
- SCR_REG_A(GP_IARLCR);
- SCR_REG_A(GPI_BCR);
- SCR_REG_W(GPA_IARCR);
- SCR_REG_W(GPA_IARLCR);
- SCR_REG_W(CCR);
- SCR_REG_W(PLL2CR);
- SCR_REG_L(PLL1CR);
- SCR_REG_B(DIARCR);
- SCR_REG_B(DBOCR);
- SCR_REG_B(FER);
- SCR_REG_W(MCR);
- SCR_REG_B(CONFIG);
- SCR_REG_B(DEBUG);
- }
- fprintf(stderr, "tc6393xb_scr: unhandled write at %08x: %02x\n",
- (uint32_t) addr, value & 0xff);
-}
-#undef SCR_REG_B
-#undef SCR_REG_W
-#undef SCR_REG_L
-#undef SCR_REG_A
-
-static void tc6393xb_nand_irq(TC6393xbState *s) {
- qemu_set_irq(s->sub_irqs[IRQ_TC6393_NAND],
- (s->nand.imr & 0x80) && (s->nand.imr & s->nand.isr));
-}
-
-static uint32_t tc6393xb_nand_cfg_readb(TC6393xbState *s, hwaddr addr) {
- switch (addr) {
- case NAND_CFG_COMMAND:
- return s->nand_enable ? 2 : 0;
- case NAND_CFG_BASE:
- case NAND_CFG_BASE + 1:
- case NAND_CFG_BASE + 2:
- case NAND_CFG_BASE + 3:
- return s->nand_phys >> (addr - NAND_CFG_BASE);
- }
- fprintf(stderr, "tc6393xb_nand_cfg: unhandled read at %08x\n", (uint32_t) addr);
- return 0;
-}
-static void tc6393xb_nand_cfg_writeb(TC6393xbState *s, hwaddr addr, uint32_t value) {
- switch (addr) {
- case NAND_CFG_COMMAND:
- s->nand_enable = (value & 0x2);
- return;
- case NAND_CFG_BASE:
- case NAND_CFG_BASE + 1:
- case NAND_CFG_BASE + 2:
- case NAND_CFG_BASE + 3:
- s->nand_phys &= ~(0xff << ((addr - NAND_CFG_BASE) * 8));
- s->nand_phys |= (value & 0xff) << ((addr - NAND_CFG_BASE) * 8);
- return;
- }
- fprintf(stderr, "tc6393xb_nand_cfg: unhandled write at %08x: %02x\n",
- (uint32_t) addr, value & 0xff);
-}
-
-static uint32_t tc6393xb_nand_readb(TC6393xbState *s, hwaddr addr) {
- switch (addr) {
- case NAND_DATA + 0:
- case NAND_DATA + 1:
- case NAND_DATA + 2:
- case NAND_DATA + 3:
- return nand_getio(s->flash);
- case NAND_MODE:
- return s->nand.mode;
- case NAND_STATUS:
- return 0x14;
- case NAND_ISR:
- return s->nand.isr;
- case NAND_IMR:
- return s->nand.imr;
- }
- fprintf(stderr, "tc6393xb_nand: unhandled read at %08x\n", (uint32_t) addr);
- return 0;
-}
-static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value) {
-// fprintf(stderr, "tc6393xb_nand: write at %08x: %02x\n",
-// (uint32_t) addr, value & 0xff);
- switch (addr) {
- case NAND_DATA + 0:
- case NAND_DATA + 1:
- case NAND_DATA + 2:
- case NAND_DATA + 3:
- nand_setio(s->flash, value);
- s->nand.isr |= 1;
- tc6393xb_nand_irq(s);
- return;
- case NAND_MODE:
- s->nand.mode = value;
- nand_setpins(s->flash,
- value & NAND_MODE_CLE,
- value & NAND_MODE_ALE,
- !(value & NAND_MODE_CE),
- value & NAND_MODE_WP,
- 0); // FIXME: gnd
- switch (value & NAND_MODE_ECC_MASK) {
- case NAND_MODE_ECC_RST:
- ecc_reset(&s->ecc);
- break;
- case NAND_MODE_ECC_READ:
- // FIXME
- break;
- case NAND_MODE_ECC_EN:
- ecc_reset(&s->ecc);
- }
- return;
- case NAND_ISR:
- s->nand.isr = value;
- tc6393xb_nand_irq(s);
- return;
- case NAND_IMR:
- s->nand.imr = value;
- tc6393xb_nand_irq(s);
- return;
- }
- fprintf(stderr, "tc6393xb_nand: unhandled write at %08x: %02x\n",
- (uint32_t) addr, value & 0xff);
-}
-
-#define BITS 8
-#include "tc6393xb_template.h"
-#define BITS 15
-#include "tc6393xb_template.h"
-#define BITS 16
-#include "tc6393xb_template.h"
-#define BITS 24
-#include "tc6393xb_template.h"
-#define BITS 32
-#include "tc6393xb_template.h"
-
-static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
-
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- tc6393xb_draw_graphic8(s);
- break;
- case 15:
- tc6393xb_draw_graphic15(s);
- break;
- case 16:
- tc6393xb_draw_graphic16(s);
- break;
- case 24:
- tc6393xb_draw_graphic24(s);
- break;
- case 32:
- tc6393xb_draw_graphic32(s);
- break;
- default:
- printf("tc6393xb: unknown depth %d\n",
- surface_bits_per_pixel(surface));
- return;
- }
-
- dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height);
-}
-
-static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i, w;
- uint8_t *d;
-
- if (!full_update)
- return;
-
- w = s->scr_width * surface_bytes_per_pixel(surface);
- d = surface_data(surface);
- for(i = 0; i < s->scr_height; i++) {
- memset(d, 0, w);
- d += surface_stride(surface);
- }
-
- dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height);
-}
-
-static void tc6393xb_update_display(void *opaque)
-{
- TC6393xbState *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int full_update;
-
- if (s->scr_width == 0 || s->scr_height == 0)
- return;
-
- full_update = 0;
- if (s->blanked != s->blank) {
- s->blanked = s->blank;
- full_update = 1;
- }
- if (s->scr_width != surface_width(surface) ||
- s->scr_height != surface_height(surface)) {
- qemu_console_resize(s->con, s->scr_width, s->scr_height);
- full_update = 1;
- }
- if (s->blanked)
- tc6393xb_draw_blank(s, full_update);
- else
- tc6393xb_draw_graphic(s, full_update);
-}
-
-
-static uint64_t tc6393xb_readb(void *opaque, hwaddr addr,
- unsigned size)
-{
- TC6393xbState *s = opaque;
-
- switch (addr >> 8) {
- case 0:
- return tc6393xb_scr_readb(s, addr & 0xff);
- case 1:
- return tc6393xb_nand_cfg_readb(s, addr & 0xff);
- };
-
- if ((addr &~0xff) == s->nand_phys && s->nand_enable) {
-// return tc6393xb_nand_readb(s, addr & 0xff);
- uint8_t d = tc6393xb_nand_readb(s, addr & 0xff);
-// fprintf(stderr, "tc6393xb_nand: read at %08x: %02hhx\n", (uint32_t) addr, d);
- return d;
- }
-
-// fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr);
- return 0;
-}
-
-static void tc6393xb_writeb(void *opaque, hwaddr addr,
- uint64_t value, unsigned size) {
- TC6393xbState *s = opaque;
-
- switch (addr >> 8) {
- case 0:
- tc6393xb_scr_writeb(s, addr & 0xff, value);
- return;
- case 1:
- tc6393xb_nand_cfg_writeb(s, addr & 0xff, value);
- return;
- };
-
- if ((addr &~0xff) == s->nand_phys && s->nand_enable)
- tc6393xb_nand_writeb(s, addr & 0xff, value);
- else
- fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n",
- (uint32_t) addr, (int)value & 0xff);
-}
-
-static const GraphicHwOps tc6393xb_gfx_ops = {
- .gfx_update = tc6393xb_update_display,
-};
-
-TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
-{
- TC6393xbState *s;
- DriveInfo *nand;
- static const MemoryRegionOps tc6393xb_ops = {
- .read = tc6393xb_readb,
- .write = tc6393xb_writeb,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
- };
-
- s = (TC6393xbState *) g_malloc0(sizeof(TC6393xbState));
- s->irq = irq;
- s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS);
-
- s->l3v = qemu_allocate_irq(tc6393xb_l3v, s, 0);
- s->blanked = 1;
-
- s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
-
- nand = drive_get(IF_MTD, 0, 0);
- s->flash = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
- NAND_MFR_TOSHIBA, 0x76);
-
- memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
- memory_region_add_subregion(sysmem, base, &s->iomem);
-
- memory_region_init_ram(&s->vram, NULL, "tc6393xb.vram", 0x100000,
- &error_fatal);
- vmstate_register_ram_global(&s->vram);
- s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
- memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
- s->scr_width = 480;
- s->scr_height = 640;
- s->con = graphic_console_init(NULL, 0, &tc6393xb_gfx_ops, s);
-
- return s;
-}
diff --git a/qemu/hw/display/tc6393xb_template.h b/qemu/hw/display/tc6393xb_template.h
deleted file mode 100644
index 78629c07f..000000000
--- a/qemu/hw/display/tc6393xb_template.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Toshiba TC6393XB I/O Controller.
- * Found in Sharp Zaurus SL-6000 (tosa) or some
- * Toshiba e-Series PDAs.
- *
- * FB support code. Based on G364 fb emulator
- *
- * Copyright (c) 2007 Hervé Poussineau
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#if BITS == 8
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
-#elif BITS == 15 || BITS == 16
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
-#elif BITS == 24
-# define SET_PIXEL(addr, color) \
- do { \
- addr[0] = color; \
- addr[1] = (color) >> 8; \
- addr[2] = (color) >> 16; \
- } while (0)
-#elif BITS == 32
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
-#else
-# error unknown bit depth
-#endif
-
-
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i;
- uint16_t *data_buffer;
- uint8_t *data_display;
-
- data_buffer = s->vram_ptr;
- data_display = surface_data(surface);
- for(i = 0; i < s->scr_height; i++) {
-#if (BITS == 16)
- memcpy(data_display, data_buffer, s->scr_width * 2);
- data_buffer += s->scr_width;
- data_display += surface_stride(surface);
-#else
- int j;
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
- uint16_t color = *data_buffer;
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
- ((color & 0xf800) * 0x108) >> 11,
- ((color & 0x7e0) * 0x41) >> 9,
- ((color & 0x1f) * 0x21) >> 2
- );
- SET_PIXEL(data_display, dest_color);
- }
-#endif
- }
-}
-
-#undef BITS
-#undef SET_PIXEL
diff --git a/qemu/hw/display/tcx.c b/qemu/hw/display/tcx.c
deleted file mode 100644
index 8e26aae80..000000000
--- a/qemu/hw/display/tcx.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * QEMU TCX Frame buffer
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * 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 "qemu-common.h"
-#include "cpu.h" /* FIXME shouldn't use TARGET_PAGE_SIZE */
-#include "ui/console.h"
-#include "ui/pixel_ops.h"
-#include "hw/loader.h"
-#include "hw/sysbus.h"
-#include "qemu/error-report.h"
-
-#define TCX_ROM_FILE "QEMU,tcx.bin"
-#define FCODE_MAX_ROM_SIZE 0x10000
-
-#define MAXX 1024
-#define MAXY 768
-#define TCX_DAC_NREGS 16
-#define TCX_THC_NREGS 0x1000
-#define TCX_DHC_NREGS 0x4000
-#define TCX_TEC_NREGS 0x1000
-#define TCX_ALT_NREGS 0x8000
-#define TCX_STIP_NREGS 0x800000
-#define TCX_BLIT_NREGS 0x800000
-#define TCX_RSTIP_NREGS 0x800000
-#define TCX_RBLIT_NREGS 0x800000
-
-#define TCX_THC_MISC 0x818
-#define TCX_THC_CURSXY 0x8fc
-#define TCX_THC_CURSMASK 0x900
-#define TCX_THC_CURSBITS 0x980
-
-#define TYPE_TCX "SUNW,tcx"
-#define TCX(obj) OBJECT_CHECK(TCXState, (obj), TYPE_TCX)
-
-typedef struct TCXState {
- SysBusDevice parent_obj;
-
- QemuConsole *con;
- qemu_irq irq;
- uint8_t *vram;
- uint32_t *vram24, *cplane;
- hwaddr prom_addr;
- MemoryRegion rom;
- MemoryRegion vram_mem;
- MemoryRegion vram_8bit;
- MemoryRegion vram_24bit;
- MemoryRegion stip;
- MemoryRegion blit;
- MemoryRegion vram_cplane;
- MemoryRegion rstip;
- MemoryRegion rblit;
- MemoryRegion tec;
- MemoryRegion dac;
- MemoryRegion thc;
- MemoryRegion dhc;
- MemoryRegion alt;
- MemoryRegion thc24;
-
- ram_addr_t vram24_offset, cplane_offset;
- uint32_t tmpblit;
- uint32_t vram_size;
- uint32_t palette[260];
- uint8_t r[260], g[260], b[260];
- uint16_t width, height, depth;
- uint8_t dac_index, dac_state;
- uint32_t thcmisc;
- uint32_t cursmask[32];
- uint32_t cursbits[32];
- uint16_t cursx;
- uint16_t cursy;
-} TCXState;
-
-static void tcx_set_dirty(TCXState *s)
-{
- memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
-}
-
-static inline int tcx24_check_dirty(TCXState *s, ram_addr_t page,
- ram_addr_t page24, ram_addr_t cpage)
-{
- int ret;
-
- ret = memory_region_get_dirty(&s->vram_mem, page, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- ret |= memory_region_get_dirty(&s->vram_mem, page24, TARGET_PAGE_SIZE * 4,
- DIRTY_MEMORY_VGA);
- ret |= memory_region_get_dirty(&s->vram_mem, cpage, TARGET_PAGE_SIZE * 4,
- DIRTY_MEMORY_VGA);
- return ret;
-}
-
-static inline void tcx24_reset_dirty(TCXState *ts, ram_addr_t page_min,
- ram_addr_t page_max, ram_addr_t page24,
- ram_addr_t cpage)
-{
- memory_region_reset_dirty(&ts->vram_mem,
- page_min,
- (page_max - page_min) + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- memory_region_reset_dirty(&ts->vram_mem,
- page24 + page_min * 4,
- (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- memory_region_reset_dirty(&ts->vram_mem,
- cpage + page_min * 4,
- (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
-}
-
-static void update_palette_entries(TCXState *s, int start, int end)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i;
-
- for (i = start; i < end; i++) {
- switch (surface_bits_per_pixel(surface)) {
- default:
- case 8:
- s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]);
- break;
- case 15:
- s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
- break;
- case 16:
- s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
- break;
- case 32:
- if (is_surface_bgr(surface)) {
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
- } else {
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
- }
- break;
- }
- }
- tcx_set_dirty(s);
-}
-
-static void tcx_draw_line32(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
- uint32_t *p = (uint32_t *)d;
-
- for (x = 0; x < width; x++) {
- val = *s++;
- *p++ = s1->palette[val];
- }
-}
-
-static void tcx_draw_line16(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
- uint16_t *p = (uint16_t *)d;
-
- for (x = 0; x < width; x++) {
- val = *s++;
- *p++ = s1->palette[val];
- }
-}
-
-static void tcx_draw_line8(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int x;
- uint8_t val;
-
- for(x = 0; x < width; x++) {
- val = *s++;
- *d++ = s1->palette[val];
- }
-}
-
-static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
- int y, int width)
-{
- int x, len;
- uint32_t mask, bits;
- uint32_t *p = (uint32_t *)d;
-
- y = y - s1->cursy;
- mask = s1->cursmask[y];
- bits = s1->cursbits[y];
- len = MIN(width - s1->cursx, 32);
- p = &p[s1->cursx];
- for (x = 0; x < len; x++) {
- if (mask & 0x80000000) {
- if (bits & 0x80000000) {
- *p = s1->palette[259];
- } else {
- *p = s1->palette[258];
- }
- }
- p++;
- mask <<= 1;
- bits <<= 1;
- }
-}
-
-static void tcx_draw_cursor16(TCXState *s1, uint8_t *d,
- int y, int width)
-{
- int x, len;
- uint32_t mask, bits;
- uint16_t *p = (uint16_t *)d;
-
- y = y - s1->cursy;
- mask = s1->cursmask[y];
- bits = s1->cursbits[y];
- len = MIN(width - s1->cursx, 32);
- p = &p[s1->cursx];
- for (x = 0; x < len; x++) {
- if (mask & 0x80000000) {
- if (bits & 0x80000000) {
- *p = s1->palette[259];
- } else {
- *p = s1->palette[258];
- }
- }
- p++;
- mask <<= 1;
- bits <<= 1;
- }
-}
-
-static void tcx_draw_cursor8(TCXState *s1, uint8_t *d,
- int y, int width)
-{
- int x, len;
- uint32_t mask, bits;
-
- y = y - s1->cursy;
- mask = s1->cursmask[y];
- bits = s1->cursbits[y];
- len = MIN(width - s1->cursx, 32);
- d = &d[s1->cursx];
- for (x = 0; x < len; x++) {
- if (mask & 0x80000000) {
- if (bits & 0x80000000) {
- *d = s1->palette[259];
- } else {
- *d = s1->palette[258];
- }
- }
- d++;
- mask <<= 1;
- bits <<= 1;
- }
-}
-
-/*
- XXX Could be much more optimal:
- * detect if line/page/whole screen is in 24 bit mode
- * if destination is also BGR, use memcpy
- */
-static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
- const uint8_t *s, int width,
- const uint32_t *cplane,
- const uint32_t *s24)
-{
- DisplaySurface *surface = qemu_console_surface(s1->con);
- int x, bgr, r, g, b;
- uint8_t val, *p8;
- uint32_t *p = (uint32_t *)d;
- uint32_t dval;
- bgr = is_surface_bgr(surface);
- for(x = 0; x < width; x++, s++, s24++) {
- if (be32_to_cpu(*cplane) & 0x03000000) {
- /* 24-bit direct, BGR order */
- p8 = (uint8_t *)s24;
- p8++;
- b = *p8++;
- g = *p8++;
- r = *p8;
- if (bgr)
- dval = rgb_to_pixel32bgr(r, g, b);
- else
- dval = rgb_to_pixel32(r, g, b);
- } else {
- /* 8-bit pseudocolor */
- val = *s;
- dval = s1->palette[val];
- }
- *p++ = dval;
- cplane++;
- }
-}
-
-/* Fixed line length 1024 allows us to do nice tricks not possible on
- VGA... */
-
-static void tcx_update_display(void *opaque)
-{
- TCXState *ts = opaque;
- DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max;
- int y, y_start, dd, ds;
- uint8_t *d, *s;
- void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);
- void (*fc)(TCXState *s1, uint8_t *dst, int y, int width);
-
- if (surface_bits_per_pixel(surface) == 0) {
- return;
- }
-
- page = 0;
- y_start = -1;
- page_min = -1;
- page_max = 0;
- d = surface_data(surface);
- s = ts->vram;
- dd = surface_stride(surface);
- ds = 1024;
-
- switch (surface_bits_per_pixel(surface)) {
- case 32:
- f = tcx_draw_line32;
- fc = tcx_draw_cursor32;
- break;
- case 15:
- case 16:
- f = tcx_draw_line16;
- fc = tcx_draw_cursor16;
- break;
- default:
- case 8:
- f = tcx_draw_line8;
- fc = tcx_draw_cursor8;
- break;
- case 0:
- return;
- }
-
- memory_region_sync_dirty_bitmap(&ts->vram_mem);
- for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE) {
- if (memory_region_get_dirty(&ts->vram_mem, page, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA)) {
- if (y_start < 0)
- y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
-
- f(ts, d, s, ts->width);
- if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
- fc(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- y++;
-
- f(ts, d, s, ts->width);
- if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
- fc(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- y++;
-
- f(ts, d, s, ts->width);
- if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
- fc(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- y++;
-
- f(ts, d, s, ts->width);
- if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
- fc(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- y++;
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(ts->con, 0, y_start,
- ts->width, y - y_start);
- y_start = -1;
- }
- d += dd * 4;
- s += ds * 4;
- y += 4;
- }
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(ts->con, 0, y_start,
- ts->width, y - y_start);
- }
- /* reset modified pages */
- if (page_max >= page_min) {
- memory_region_reset_dirty(&ts->vram_mem,
- page_min,
- (page_max - page_min) + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- }
-}
-
-static void tcx24_update_display(void *opaque)
-{
- TCXState *ts = opaque;
- DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max, cpage, page24;
- int y, y_start, dd, ds;
- uint8_t *d, *s;
- uint32_t *cptr, *s24;
-
- if (surface_bits_per_pixel(surface) != 32) {
- return;
- }
-
- page = 0;
- page24 = ts->vram24_offset;
- cpage = ts->cplane_offset;
- y_start = -1;
- page_min = -1;
- page_max = 0;
- d = surface_data(surface);
- s = ts->vram;
- s24 = ts->vram24;
- cptr = ts->cplane;
- dd = surface_stride(surface);
- ds = 1024;
-
- memory_region_sync_dirty_bitmap(&ts->vram_mem);
- for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE,
- page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) {
- if (tcx24_check_dirty(ts, page, page24, cpage)) {
- if (y_start < 0)
- y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
- tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
- if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
- tcx_draw_cursor32(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- cptr += ds;
- s24 += ds;
- y++;
- tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
- if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
- tcx_draw_cursor32(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- cptr += ds;
- s24 += ds;
- y++;
- tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
- if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
- tcx_draw_cursor32(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- cptr += ds;
- s24 += ds;
- y++;
- tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
- if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
- tcx_draw_cursor32(ts, d, y, ts->width);
- }
- d += dd;
- s += ds;
- cptr += ds;
- s24 += ds;
- y++;
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(ts->con, 0, y_start,
- ts->width, y - y_start);
- y_start = -1;
- }
- d += dd * 4;
- s += ds * 4;
- cptr += ds * 4;
- s24 += ds * 4;
- y += 4;
- }
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(ts->con, 0, y_start,
- ts->width, y - y_start);
- }
- /* reset modified pages */
- if (page_max >= page_min) {
- tcx24_reset_dirty(ts, page_min, page_max, page24, cpage);
- }
-}
-
-static void tcx_invalidate_display(void *opaque)
-{
- TCXState *s = opaque;
-
- tcx_set_dirty(s);
- qemu_console_resize(s->con, s->width, s->height);
-}
-
-static void tcx24_invalidate_display(void *opaque)
-{
- TCXState *s = opaque;
-
- tcx_set_dirty(s);
- qemu_console_resize(s->con, s->width, s->height);
-}
-
-static int vmstate_tcx_post_load(void *opaque, int version_id)
-{
- TCXState *s = opaque;
-
- update_palette_entries(s, 0, 256);
- tcx_set_dirty(s);
- return 0;
-}
-
-static const VMStateDescription vmstate_tcx = {
- .name ="tcx",
- .version_id = 4,
- .minimum_version_id = 4,
- .post_load = vmstate_tcx_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(height, TCXState),
- VMSTATE_UINT16(width, TCXState),
- VMSTATE_UINT16(depth, TCXState),
- VMSTATE_BUFFER(r, TCXState),
- VMSTATE_BUFFER(g, TCXState),
- VMSTATE_BUFFER(b, TCXState),
- VMSTATE_UINT8(dac_index, TCXState),
- VMSTATE_UINT8(dac_state, TCXState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void tcx_reset(DeviceState *d)
-{
- TCXState *s = TCX(d);
-
- /* Initialize palette */
- memset(s->r, 0, 260);
- memset(s->g, 0, 260);
- memset(s->b, 0, 260);
- s->r[255] = s->g[255] = s->b[255] = 255;
- s->r[256] = s->g[256] = s->b[256] = 255;
- s->r[258] = s->g[258] = s->b[258] = 255;
- update_palette_entries(s, 0, 260);
- memset(s->vram, 0, MAXX*MAXY);
- memory_region_reset_dirty(&s->vram_mem, 0, MAXX * MAXY * (1 + 4 + 4),
- DIRTY_MEMORY_VGA);
- s->dac_index = 0;
- s->dac_state = 0;
- s->cursx = 0xf000; /* Put cursor off screen */
- s->cursy = 0xf000;
-}
-
-static uint64_t tcx_dac_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
- TCXState *s = opaque;
- uint32_t val = 0;
-
- switch (s->dac_state) {
- case 0:
- val = s->r[s->dac_index] << 24;
- s->dac_state++;
- break;
- case 1:
- val = s->g[s->dac_index] << 24;
- s->dac_state++;
- break;
- case 2:
- val = s->b[s->dac_index] << 24;
- s->dac_index = (s->dac_index + 1) & 0xff; /* Index autoincrement */
- default:
- s->dac_state = 0;
- break;
- }
-
- return val;
-}
-
-static void tcx_dac_writel(void *opaque, hwaddr addr, uint64_t val,
- unsigned size)
-{
- TCXState *s = opaque;
- unsigned index;
-
- switch (addr) {
- case 0: /* Address */
- s->dac_index = val >> 24;
- s->dac_state = 0;
- break;
- case 4: /* Pixel colours */
- case 12: /* Overlay (cursor) colours */
- if (addr & 8) {
- index = (s->dac_index & 3) + 256;
- } else {
- index = s->dac_index;
- }
- switch (s->dac_state) {
- case 0:
- s->r[index] = val >> 24;
- update_palette_entries(s, index, index + 1);
- s->dac_state++;
- break;
- case 1:
- s->g[index] = val >> 24;
- update_palette_entries(s, index, index + 1);
- s->dac_state++;
- break;
- case 2:
- s->b[index] = val >> 24;
- update_palette_entries(s, index, index + 1);
- s->dac_index = (s->dac_index + 1) & 0xff; /* Index autoincrement */
- default:
- s->dac_state = 0;
- break;
- }
- break;
- default: /* Control registers */
- break;
- }
-}
-
-static const MemoryRegionOps tcx_dac_ops = {
- .read = tcx_dac_readl,
- .write = tcx_dac_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static uint64_t tcx_stip_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
- return 0;
-}
-
-static void tcx_stip_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- TCXState *s = opaque;
- int i;
- uint32_t col;
-
- if (!(addr & 4)) {
- s->tmpblit = val;
- } else {
- addr = (addr >> 3) & 0xfffff;
- col = cpu_to_be32(s->tmpblit);
- if (s->depth == 24) {
- for (i = 0; i < 32; i++) {
- if (val & 0x80000000) {
- s->vram[addr + i] = s->tmpblit;
- s->vram24[addr + i] = col;
- }
- val <<= 1;
- }
- } else {
- for (i = 0; i < 32; i++) {
- if (val & 0x80000000) {
- s->vram[addr + i] = s->tmpblit;
- }
- val <<= 1;
- }
- }
- memory_region_set_dirty(&s->vram_mem, addr, 32);
- }
-}
-
-static void tcx_rstip_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- TCXState *s = opaque;
- int i;
- uint32_t col;
-
- if (!(addr & 4)) {
- s->tmpblit = val;
- } else {
- addr = (addr >> 3) & 0xfffff;
- col = cpu_to_be32(s->tmpblit);
- if (s->depth == 24) {
- for (i = 0; i < 32; i++) {
- if (val & 0x80000000) {
- s->vram[addr + i] = s->tmpblit;
- s->vram24[addr + i] = col;
- s->cplane[addr + i] = col;
- }
- val <<= 1;
- }
- } else {
- for (i = 0; i < 32; i++) {
- if (val & 0x80000000) {
- s->vram[addr + i] = s->tmpblit;
- }
- val <<= 1;
- }
- }
- memory_region_set_dirty(&s->vram_mem, addr, 32);
- }
-}
-
-static const MemoryRegionOps tcx_stip_ops = {
- .read = tcx_stip_readl,
- .write = tcx_stip_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static const MemoryRegionOps tcx_rstip_ops = {
- .read = tcx_stip_readl,
- .write = tcx_rstip_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static uint64_t tcx_blit_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
- return 0;
-}
-
-static void tcx_blit_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- TCXState *s = opaque;
- uint32_t adsr, len;
- int i;
-
- if (!(addr & 4)) {
- s->tmpblit = val;
- } else {
- addr = (addr >> 3) & 0xfffff;
- adsr = val & 0xffffff;
- len = ((val >> 24) & 0x1f) + 1;
- if (adsr == 0xffffff) {
- memset(&s->vram[addr], s->tmpblit, len);
- if (s->depth == 24) {
- val = s->tmpblit & 0xffffff;
- val = cpu_to_be32(val);
- for (i = 0; i < len; i++) {
- s->vram24[addr + i] = val;
- }
- }
- } else {
- memcpy(&s->vram[addr], &s->vram[adsr], len);
- if (s->depth == 24) {
- memcpy(&s->vram24[addr], &s->vram24[adsr], len * 4);
- }
- }
- memory_region_set_dirty(&s->vram_mem, addr, len);
- }
-}
-
-static void tcx_rblit_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- TCXState *s = opaque;
- uint32_t adsr, len;
- int i;
-
- if (!(addr & 4)) {
- s->tmpblit = val;
- } else {
- addr = (addr >> 3) & 0xfffff;
- adsr = val & 0xffffff;
- len = ((val >> 24) & 0x1f) + 1;
- if (adsr == 0xffffff) {
- memset(&s->vram[addr], s->tmpblit, len);
- if (s->depth == 24) {
- val = s->tmpblit & 0xffffff;
- val = cpu_to_be32(val);
- for (i = 0; i < len; i++) {
- s->vram24[addr + i] = val;
- s->cplane[addr + i] = val;
- }
- }
- } else {
- memcpy(&s->vram[addr], &s->vram[adsr], len);
- if (s->depth == 24) {
- memcpy(&s->vram24[addr], &s->vram24[adsr], len * 4);
- memcpy(&s->cplane[addr], &s->cplane[adsr], len * 4);
- }
- }
- memory_region_set_dirty(&s->vram_mem, addr, len);
- }
-}
-
-static const MemoryRegionOps tcx_blit_ops = {
- .read = tcx_blit_readl,
- .write = tcx_blit_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static const MemoryRegionOps tcx_rblit_ops = {
- .read = tcx_blit_readl,
- .write = tcx_rblit_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static void tcx_invalidate_cursor_position(TCXState *s)
-{
- int ymin, ymax, start, end;
-
- /* invalidate only near the cursor */
- ymin = s->cursy;
- if (ymin >= s->height) {
- return;
- }
- ymax = MIN(s->height, ymin + 32);
- start = ymin * 1024;
- end = ymax * 1024;
-
- memory_region_set_dirty(&s->vram_mem, start, end-start);
-}
-
-static uint64_t tcx_thc_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
- TCXState *s = opaque;
- uint64_t val;
-
- if (addr == TCX_THC_MISC) {
- val = s->thcmisc | 0x02000000;
- } else {
- val = 0;
- }
- return val;
-}
-
-static void tcx_thc_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- TCXState *s = opaque;
-
- if (addr == TCX_THC_CURSXY) {
- tcx_invalidate_cursor_position(s);
- s->cursx = val >> 16;
- s->cursy = val;
- tcx_invalidate_cursor_position(s);
- } else if (addr >= TCX_THC_CURSMASK && addr < TCX_THC_CURSMASK + 128) {
- s->cursmask[(addr - TCX_THC_CURSMASK) >> 2] = val;
- tcx_invalidate_cursor_position(s);
- } else if (addr >= TCX_THC_CURSBITS && addr < TCX_THC_CURSBITS + 128) {
- s->cursbits[(addr - TCX_THC_CURSBITS) >> 2] = val;
- tcx_invalidate_cursor_position(s);
- } else if (addr == TCX_THC_MISC) {
- s->thcmisc = val;
- }
-
-}
-
-static const MemoryRegionOps tcx_thc_ops = {
- .read = tcx_thc_readl,
- .write = tcx_thc_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static uint64_t tcx_dummy_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
- return 0;
-}
-
-static void tcx_dummy_writel(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- return;
-}
-
-static const MemoryRegionOps tcx_dummy_ops = {
- .read = tcx_dummy_readl,
- .write = tcx_dummy_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static const GraphicHwOps tcx_ops = {
- .invalidate = tcx_invalidate_display,
- .gfx_update = tcx_update_display,
-};
-
-static const GraphicHwOps tcx24_ops = {
- .invalidate = tcx24_invalidate_display,
- .gfx_update = tcx24_update_display,
-};
-
-static void tcx_initfn(Object *obj)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- TCXState *s = TCX(obj);
-
- memory_region_init_ram(&s->rom, obj, "tcx.prom", FCODE_MAX_ROM_SIZE,
- &error_fatal);
- memory_region_set_readonly(&s->rom, true);
- sysbus_init_mmio(sbd, &s->rom);
-
- /* 2/STIP : Stippler */
- memory_region_init_io(&s->stip, obj, &tcx_stip_ops, s, "tcx.stip",
- TCX_STIP_NREGS);
- sysbus_init_mmio(sbd, &s->stip);
-
- /* 3/BLIT : Blitter */
- memory_region_init_io(&s->blit, obj, &tcx_blit_ops, s, "tcx.blit",
- TCX_BLIT_NREGS);
- sysbus_init_mmio(sbd, &s->blit);
-
- /* 5/RSTIP : Raw Stippler */
- memory_region_init_io(&s->rstip, obj, &tcx_rstip_ops, s, "tcx.rstip",
- TCX_RSTIP_NREGS);
- sysbus_init_mmio(sbd, &s->rstip);
-
- /* 6/RBLIT : Raw Blitter */
- memory_region_init_io(&s->rblit, obj, &tcx_rblit_ops, s, "tcx.rblit",
- TCX_RBLIT_NREGS);
- sysbus_init_mmio(sbd, &s->rblit);
-
- /* 7/TEC : ??? */
- memory_region_init_io(&s->tec, obj, &tcx_dummy_ops, s, "tcx.tec",
- TCX_TEC_NREGS);
- sysbus_init_mmio(sbd, &s->tec);
-
- /* 8/CMAP : DAC */
- memory_region_init_io(&s->dac, obj, &tcx_dac_ops, s, "tcx.dac",
- TCX_DAC_NREGS);
- sysbus_init_mmio(sbd, &s->dac);
-
- /* 9/THC : Cursor */
- memory_region_init_io(&s->thc, obj, &tcx_thc_ops, s, "tcx.thc",
- TCX_THC_NREGS);
- sysbus_init_mmio(sbd, &s->thc);
-
- /* 11/DHC : ??? */
- memory_region_init_io(&s->dhc, obj, &tcx_dummy_ops, s, "tcx.dhc",
- TCX_DHC_NREGS);
- sysbus_init_mmio(sbd, &s->dhc);
-
- /* 12/ALT : ??? */
- memory_region_init_io(&s->alt, obj, &tcx_dummy_ops, s, "tcx.alt",
- TCX_ALT_NREGS);
- sysbus_init_mmio(sbd, &s->alt);
-}
-
-static void tcx_realizefn(DeviceState *dev, Error **errp)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- TCXState *s = TCX(dev);
- ram_addr_t vram_offset = 0;
- int size, ret;
- uint8_t *vram_base;
- char *fcode_filename;
-
- memory_region_init_ram(&s->vram_mem, OBJECT(s), "tcx.vram",
- s->vram_size * (1 + 4 + 4), &error_fatal);
- vmstate_register_ram_global(&s->vram_mem);
- memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
- vram_base = memory_region_get_ram_ptr(&s->vram_mem);
-
- /* 10/ROM : FCode ROM */
- vmstate_register_ram_global(&s->rom);
- fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, TCX_ROM_FILE);
- if (fcode_filename) {
- ret = load_image_targphys(fcode_filename, s->prom_addr,
- FCODE_MAX_ROM_SIZE);
- g_free(fcode_filename);
- if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("tcx: could not load prom '%s'", TCX_ROM_FILE);
- }
- }
-
- /* 0/DFB8 : 8-bit plane */
- s->vram = vram_base;
- size = s->vram_size;
- memory_region_init_alias(&s->vram_8bit, OBJECT(s), "tcx.vram.8bit",
- &s->vram_mem, vram_offset, size);
- sysbus_init_mmio(sbd, &s->vram_8bit);
- vram_offset += size;
- vram_base += size;
-
- /* 1/DFB24 : 24bit plane */
- size = s->vram_size * 4;
- s->vram24 = (uint32_t *)vram_base;
- s->vram24_offset = vram_offset;
- memory_region_init_alias(&s->vram_24bit, OBJECT(s), "tcx.vram.24bit",
- &s->vram_mem, vram_offset, size);
- sysbus_init_mmio(sbd, &s->vram_24bit);
- vram_offset += size;
- vram_base += size;
-
- /* 4/RDFB32 : Raw Framebuffer */
- size = s->vram_size * 4;
- s->cplane = (uint32_t *)vram_base;
- s->cplane_offset = vram_offset;
- memory_region_init_alias(&s->vram_cplane, OBJECT(s), "tcx.vram.cplane",
- &s->vram_mem, vram_offset, size);
- sysbus_init_mmio(sbd, &s->vram_cplane);
-
- /* 9/THC24bits : NetBSD writes here even with 8-bit display: dummy */
- if (s->depth == 8) {
- memory_region_init_io(&s->thc24, OBJECT(s), &tcx_dummy_ops, s,
- "tcx.thc24", TCX_THC_NREGS);
- sysbus_init_mmio(sbd, &s->thc24);
- }
-
- sysbus_init_irq(sbd, &s->irq);
-
- if (s->depth == 8) {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx_ops, s);
- } else {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx24_ops, s);
- }
- s->thcmisc = 0;
-
- qemu_console_resize(s->con, s->width, s->height);
-}
-
-static Property tcx_properties[] = {
- DEFINE_PROP_UINT32("vram_size", TCXState, vram_size, -1),
- DEFINE_PROP_UINT16("width", TCXState, width, -1),
- DEFINE_PROP_UINT16("height", TCXState, height, -1),
- DEFINE_PROP_UINT16("depth", TCXState, depth, -1),
- DEFINE_PROP_UINT64("prom_addr", TCXState, prom_addr, -1),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void tcx_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = tcx_realizefn;
- dc->reset = tcx_reset;
- dc->vmsd = &vmstate_tcx;
- dc->props = tcx_properties;
-}
-
-static const TypeInfo tcx_info = {
- .name = TYPE_TCX,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(TCXState),
- .instance_init = tcx_initfn,
- .class_init = tcx_class_init,
-};
-
-static void tcx_register_types(void)
-{
- type_register_static(&tcx_info);
-}
-
-type_init(tcx_register_types)
diff --git a/qemu/hw/display/vga-helpers.h b/qemu/hw/display/vga-helpers.h
deleted file mode 100644
index 94f6de204..000000000
--- a/qemu/hw/display/vga-helpers.h
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * QEMU VGA Emulator templates
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.
- */
-
-static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
- uint32_t xorcol, uint32_t bgcol)
-{
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
-}
-
-static void vga_draw_glyph8(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- vga_draw_glyph_line(d, font_data, xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void vga_draw_glyph16(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- vga_draw_glyph_line(d, expand4to8[font_data >> 4],
- xorcol, bgcol);
- vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
- xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void vga_draw_glyph9(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9)
-{
- uint32_t font_data, xorcol, v;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = v;
- if (dup9)
- ((uint32_t *)d)[8] = v;
- else
- ((uint32_t *)d)[8] = bgcol;
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-/*
- * 4 color mode
- */
-static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- ((uint32_t *)d)[0] = palette[v >> 12];
- ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- ((uint32_t *)d)[4] = palette[v >> 12];
- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
- d += 32;
- s += 4;
- }
-}
-
-#define PUT_PIXEL2(d, n, v) \
-((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
-
-/*
- * 4 color mode, dup2 horizontal
- */
-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- PUT_PIXEL2(d, 0, palette[v >> 12]);
- PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- PUT_PIXEL2(d, 4, palette[v >> 12]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += 64;
- s += 4;
- }
-}
-
-/*
- * 16 color mode
- */
-static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- ((uint32_t *)d)[0] = palette[v >> 28];
- ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
- ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
- ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
- ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
- d += 32;
- s += 4;
- }
-}
-
-/*
- * 16 color mode, dup2 horizontal
- */
-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- PUT_PIXEL2(d, 0, palette[v >> 28]);
- PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
- PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += 64;
- s += 4;
- }
-}
-
-/*
- * 256 color mode, double pixels
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- PUT_PIXEL2(d, 0, palette[s[0]]);
- PUT_PIXEL2(d, 1, palette[s[1]]);
- PUT_PIXEL2(d, 2, palette[s[2]]);
- PUT_PIXEL2(d, 3, palette[s[3]]);
- d += 32;
- s += 4;
- }
-}
-
-/*
- * standard 256 color mode
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- ((uint32_t *)d)[0] = palette[s[0]];
- ((uint32_t *)d)[1] = palette[s[1]];
- ((uint32_t *)d)[2] = palette[s[2]];
- ((uint32_t *)d)[3] = palette[s[3]];
- ((uint32_t *)d)[4] = palette[s[4]];
- ((uint32_t *)d)[5] = palette[s[5]];
- ((uint32_t *)d)[6] = palette[s[6]];
- ((uint32_t *)d)[7] = palette[s[7]];
- d += 32;
- s += 8;
- }
-}
-
-/*
- * 15 bit color
- */
-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_le_p((void *)s);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
- d += 4;
- } while (--w != 0);
-}
-
-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_be_p((void *)s);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
- d += 4;
- } while (--w != 0);
-}
-
-/*
- * 16 bit color
- */
-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_le_p((void *)s);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
- d += 4;
- } while (--w != 0);
-}
-
-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_be_p((void *)s);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 2;
- d += 4;
- } while (--w != 0);
-}
-
-/*
- * 24 bit color
- */
-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
- b = s[0];
- g = s[1];
- r = s[2];
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 3;
- d += 4;
- } while (--w != 0);
-}
-
-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
- r = s[0];
- g = s[1];
- b = s[2];
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 3;
- d += 4;
- } while (--w != 0);
-}
-
-/*
- * 32 bit color
- */
-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#ifndef HOST_WORDS_BIGENDIAN
- memcpy(d, s, width * 4);
-#else
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
- b = s[0];
- g = s[1];
- r = s[2];
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 4;
- d += 4;
- } while (--w != 0);
-#endif
-}
-
-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#ifdef HOST_WORDS_BIGENDIAN
- memcpy(d, s, width * 4);
-#else
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
- r = s[1];
- g = s[2];
- b = s[3];
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- s += 4;
- d += 4;
- } while (--w != 0);
-#endif
-}
diff --git a/qemu/hw/display/vga-isa-mm.c b/qemu/hw/display/vga-isa-mm.c
deleted file mode 100644
index 51ccbccc4..000000000
--- a/qemu/hw/display/vga-isa-mm.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * QEMU ISA MM VGA Emulator.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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 "hw/hw.h"
-#include "ui/console.h"
-#include "hw/i386/pc.h"
-#include "vga_int.h"
-#include "ui/pixel_ops.h"
-#include "qemu/timer.h"
-
-#define VGA_RAM_SIZE (8192 * 1024)
-
-typedef struct ISAVGAMMState {
- VGACommonState vga;
- int it_shift;
-} ISAVGAMMState;
-
-/* Memory mapped interface */
-static uint32_t vga_mm_readb (void *opaque, hwaddr addr)
-{
- ISAVGAMMState *s = opaque;
-
- return vga_ioport_read(&s->vga, addr >> s->it_shift) & 0xff;
-}
-
-static void vga_mm_writeb (void *opaque,
- hwaddr addr, uint32_t value)
-{
- ISAVGAMMState *s = opaque;
-
- vga_ioport_write(&s->vga, addr >> s->it_shift, value & 0xff);
-}
-
-static uint32_t vga_mm_readw (void *opaque, hwaddr addr)
-{
- ISAVGAMMState *s = opaque;
-
- return vga_ioport_read(&s->vga, addr >> s->it_shift) & 0xffff;
-}
-
-static void vga_mm_writew (void *opaque,
- hwaddr addr, uint32_t value)
-{
- ISAVGAMMState *s = opaque;
-
- vga_ioport_write(&s->vga, addr >> s->it_shift, value & 0xffff);
-}
-
-static uint32_t vga_mm_readl (void *opaque, hwaddr addr)
-{
- ISAVGAMMState *s = opaque;
-
- return vga_ioport_read(&s->vga, addr >> s->it_shift);
-}
-
-static void vga_mm_writel (void *opaque,
- hwaddr addr, uint32_t value)
-{
- ISAVGAMMState *s = opaque;
-
- vga_ioport_write(&s->vga, addr >> s->it_shift, value);
-}
-
-static const MemoryRegionOps vga_mm_ctrl_ops = {
- .old_mmio = {
- .read = {
- vga_mm_readb,
- vga_mm_readw,
- vga_mm_readl,
- },
- .write = {
- vga_mm_writeb,
- vga_mm_writew,
- vga_mm_writel,
- },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void vga_mm_init(ISAVGAMMState *s, hwaddr vram_base,
- hwaddr ctrl_base, int it_shift,
- MemoryRegion *address_space)
-{
- MemoryRegion *s_ioport_ctrl, *vga_io_memory;
-
- s->it_shift = it_shift;
- s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl));
- memory_region_init_io(s_ioport_ctrl, NULL, &vga_mm_ctrl_ops, s,
- "vga-mm-ctrl", 0x100000);
- memory_region_set_flush_coalesced(s_ioport_ctrl);
-
- vga_io_memory = g_malloc(sizeof(*vga_io_memory));
- /* XXX: endianness? */
- memory_region_init_io(vga_io_memory, NULL, &vga_mem_ops, &s->vga,
- "vga-mem", 0x20000);
-
- vmstate_register(NULL, 0, &vmstate_vga_common, s);
-
- memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl);
- s->vga.bank_offset = 0;
- memory_region_add_subregion(address_space,
- vram_base + 0x000a0000, vga_io_memory);
- memory_region_set_coalescing(vga_io_memory);
-}
-
-int isa_vga_mm_init(hwaddr vram_base,
- hwaddr ctrl_base, int it_shift,
- MemoryRegion *address_space)
-{
- ISAVGAMMState *s;
-
- s = g_malloc0(sizeof(*s));
-
- s->vga.vram_size_mb = VGA_RAM_SIZE >> 20;
- vga_common_init(&s->vga, NULL, true);
- vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
-
- s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s);
-
- vga_init_vbe(&s->vga, NULL, address_space);
- return 0;
-}
diff --git a/qemu/hw/display/vga-isa.c b/qemu/hw/display/vga-isa.c
deleted file mode 100644
index f5aff1cbe..000000000
--- a/qemu/hw/display/vga-isa.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * QEMU ISA VGA Emulator.
- *
- * see docs/specs/standard-vga.txt for virtual hardware specs.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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 "hw/hw.h"
-#include "ui/console.h"
-#include "hw/i386/pc.h"
-#include "vga_int.h"
-#include "ui/pixel_ops.h"
-#include "qemu/timer.h"
-#include "hw/loader.h"
-
-#define TYPE_ISA_VGA "isa-vga"
-#define ISA_VGA(obj) OBJECT_CHECK(ISAVGAState, (obj), TYPE_ISA_VGA)
-
-typedef struct ISAVGAState {
- ISADevice parent_obj;
-
- struct VGACommonState state;
-} ISAVGAState;
-
-static void vga_isa_reset(DeviceState *dev)
-{
- ISAVGAState *d = ISA_VGA(dev);
- VGACommonState *s = &d->state;
-
- vga_common_reset(s);
-}
-
-static void vga_isa_realizefn(DeviceState *dev, Error **errp)
-{
- ISADevice *isadev = ISA_DEVICE(dev);
- ISAVGAState *d = ISA_VGA(dev);
- VGACommonState *s = &d->state;
- MemoryRegion *vga_io_memory;
- const MemoryRegionPortio *vga_ports, *vbe_ports;
-
- vga_common_init(s, OBJECT(dev), true);
- s->legacy_address_space = isa_address_space(isadev);
- vga_io_memory = vga_init_io(s, OBJECT(dev), &vga_ports, &vbe_ports);
- isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga");
- if (vbe_ports) {
- isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe");
- }
- memory_region_add_subregion_overlap(isa_address_space(isadev),
- 0x000a0000,
- vga_io_memory, 1);
- memory_region_set_coalescing(vga_io_memory);
- s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
-
- vga_init_vbe(s, OBJECT(dev), isa_address_space(isadev));
- /* ROM BIOS */
- rom_add_vga(VGABIOS_FILENAME);
-}
-
-static Property vga_isa_properties[] = {
- DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void vga_isa_class_initfn(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = vga_isa_realizefn;
- dc->reset = vga_isa_reset;
- dc->vmsd = &vmstate_vga_common;
- dc->props = vga_isa_properties;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
-}
-
-static const TypeInfo vga_isa_info = {
- .name = TYPE_ISA_VGA,
- .parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(ISAVGAState),
- .class_init = vga_isa_class_initfn,
-};
-
-static void vga_isa_register_types(void)
-{
- type_register_static(&vga_isa_info);
-}
-
-type_init(vga_isa_register_types)
diff --git a/qemu/hw/display/vga-pci.c b/qemu/hw/display/vga-pci.c
deleted file mode 100644
index ac9a76499..000000000
--- a/qemu/hw/display/vga-pci.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * QEMU PCI VGA Emulator.
- *
- * see docs/specs/standard-vga.txt for virtual hardware specs.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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 "hw/hw.h"
-#include "ui/console.h"
-#include "hw/pci/pci.h"
-#include "vga_int.h"
-#include "ui/pixel_ops.h"
-#include "qemu/timer.h"
-#include "hw/loader.h"
-
-#define PCI_VGA_IOPORT_OFFSET 0x400
-#define PCI_VGA_IOPORT_SIZE (0x3e0 - 0x3c0)
-#define PCI_VGA_BOCHS_OFFSET 0x500
-#define PCI_VGA_BOCHS_SIZE (0x0b * 2)
-#define PCI_VGA_QEXT_OFFSET 0x600
-#define PCI_VGA_QEXT_SIZE (2 * 4)
-#define PCI_VGA_MMIO_SIZE 0x1000
-
-#define PCI_VGA_QEXT_REG_SIZE (0 * 4)
-#define PCI_VGA_QEXT_REG_BYTEORDER (1 * 4)
-#define PCI_VGA_QEXT_LITTLE_ENDIAN 0x1e1e1e1e
-#define PCI_VGA_QEXT_BIG_ENDIAN 0xbebebebe
-
-enum vga_pci_flags {
- PCI_VGA_FLAG_ENABLE_MMIO = 1,
- PCI_VGA_FLAG_ENABLE_QEXT = 2,
-};
-
-typedef struct PCIVGAState {
- PCIDevice dev;
- VGACommonState vga;
- uint32_t flags;
- MemoryRegion mmio;
- MemoryRegion mrs[3];
-} PCIVGAState;
-
-#define TYPE_PCI_VGA "pci-vga"
-#define PCI_VGA(obj) OBJECT_CHECK(PCIVGAState, (obj), TYPE_PCI_VGA)
-
-static const VMStateDescription vmstate_vga_pci = {
- .name = "vga",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, PCIVGAState),
- VMSTATE_STRUCT(vga, PCIVGAState, 0, vmstate_vga_common, VGACommonState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static uint64_t pci_vga_ioport_read(void *ptr, hwaddr addr,
- unsigned size)
-{
- VGACommonState *s = ptr;
- uint64_t ret = 0;
-
- switch (size) {
- case 1:
- ret = vga_ioport_read(s, addr + 0x3c0);
- break;
- case 2:
- ret = vga_ioport_read(s, addr + 0x3c0);
- ret |= vga_ioport_read(s, addr + 0x3c1) << 8;
- break;
- }
- return ret;
-}
-
-static void pci_vga_ioport_write(void *ptr, hwaddr addr,
- uint64_t val, unsigned size)
-{
- VGACommonState *s = ptr;
-
- switch (size) {
- case 1:
- vga_ioport_write(s, addr + 0x3c0, val);
- break;
- case 2:
- /*
- * Update bytes in little endian order. Allows to update
- * indexed registers with a single word write because the
- * index byte is updated first.
- */
- vga_ioport_write(s, addr + 0x3c0, val & 0xff);
- vga_ioport_write(s, addr + 0x3c1, (val >> 8) & 0xff);
- break;
- }
-}
-
-static const MemoryRegionOps pci_vga_ioport_ops = {
- .read = pci_vga_ioport_read,
- .write = pci_vga_ioport_write,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .impl.min_access_size = 1,
- .impl.max_access_size = 2,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static uint64_t pci_vga_bochs_read(void *ptr, hwaddr addr,
- unsigned size)
-{
- VGACommonState *s = ptr;
- int index = addr >> 1;
-
- vbe_ioport_write_index(s, 0, index);
- return vbe_ioport_read_data(s, 0);
-}
-
-static void pci_vga_bochs_write(void *ptr, hwaddr addr,
- uint64_t val, unsigned size)
-{
- VGACommonState *s = ptr;
- int index = addr >> 1;
-
- vbe_ioport_write_index(s, 0, index);
- vbe_ioport_write_data(s, 0, val);
-}
-
-static const MemoryRegionOps pci_vga_bochs_ops = {
- .read = pci_vga_bochs_read,
- .write = pci_vga_bochs_write,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .impl.min_access_size = 2,
- .impl.max_access_size = 2,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static uint64_t pci_vga_qext_read(void *ptr, hwaddr addr, unsigned size)
-{
- VGACommonState *s = ptr;
-
- switch (addr) {
- case PCI_VGA_QEXT_REG_SIZE:
- return PCI_VGA_QEXT_SIZE;
- case PCI_VGA_QEXT_REG_BYTEORDER:
- return s->big_endian_fb ?
- PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
- default:
- return 0;
- }
-}
-
-static void pci_vga_qext_write(void *ptr, hwaddr addr,
- uint64_t val, unsigned size)
-{
- VGACommonState *s = ptr;
-
- switch (addr) {
- case PCI_VGA_QEXT_REG_BYTEORDER:
- if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
- s->big_endian_fb = true;
- }
- if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
- s->big_endian_fb = false;
- }
- break;
- }
-}
-
-static bool vga_get_big_endian_fb(Object *obj, Error **errp)
-{
- PCIVGAState *d = PCI_VGA(PCI_DEVICE(obj));
-
- return d->vga.big_endian_fb;
-}
-
-static void vga_set_big_endian_fb(Object *obj, bool value, Error **errp)
-{
- PCIVGAState *d = PCI_VGA(PCI_DEVICE(obj));
-
- d->vga.big_endian_fb = value;
-}
-
-static const MemoryRegionOps pci_vga_qext_ops = {
- .read = pci_vga_qext_read,
- .write = pci_vga_qext_write,
- .valid.min_access_size = 4,
- .valid.max_access_size = 4,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void pci_std_vga_mmio_region_init(VGACommonState *s,
- MemoryRegion *parent,
- MemoryRegion *subs,
- bool qext)
-{
- memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s,
- "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
- memory_region_add_subregion(parent, PCI_VGA_IOPORT_OFFSET,
- &subs[0]);
-
- memory_region_init_io(&subs[1], NULL, &pci_vga_bochs_ops, s,
- "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
- memory_region_add_subregion(parent, PCI_VGA_BOCHS_OFFSET,
- &subs[1]);
-
- if (qext) {
- memory_region_init_io(&subs[2], NULL, &pci_vga_qext_ops, s,
- "qemu extended regs", PCI_VGA_QEXT_SIZE);
- memory_region_add_subregion(parent, PCI_VGA_QEXT_OFFSET,
- &subs[2]);
- }
-}
-
-static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
-{
- PCIVGAState *d = PCI_VGA(dev);
- VGACommonState *s = &d->vga;
- bool qext = false;
-
- /* vga + console init */
- vga_common_init(s, OBJECT(dev), true);
- vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev),
- true);
-
- s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
-
- /* XXX: VGA_RAM_SIZE must be a power of two */
- pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
-
- /* mmio bar for vga register access */
- if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_MMIO)) {
- memory_region_init(&d->mmio, NULL, "vga.mmio", 4096);
-
- if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
- qext = true;
- pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
- }
- pci_std_vga_mmio_region_init(s, &d->mmio, d->mrs, qext);
-
- pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
- }
-
- if (!dev->rom_bar) {
- /* compatibility with pc-0.13 and older */
- vga_init_vbe(s, OBJECT(dev), pci_address_space(dev));
- }
-}
-
-static void pci_std_vga_init(Object *obj)
-{
- /* Expose framebuffer byteorder via QOM */
- object_property_add_bool(obj, "big-endian-framebuffer",
- vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
-}
-
-static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
-{
- PCIVGAState *d = PCI_VGA(dev);
- VGACommonState *s = &d->vga;
- bool qext = false;
-
- /* vga + console init */
- vga_common_init(s, OBJECT(dev), false);
- s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
-
- /* mmio bar */
- memory_region_init(&d->mmio, OBJECT(dev), "vga.mmio", 4096);
-
- if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
- qext = true;
- pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
- }
- pci_std_vga_mmio_region_init(s, &d->mmio, d->mrs, qext);
-
- pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
- pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
-}
-
-static void pci_secondary_vga_init(Object *obj)
-{
- /* Expose framebuffer byteorder via QOM */
- object_property_add_bool(obj, "big-endian-framebuffer",
- vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
-}
-
-static void pci_secondary_vga_reset(DeviceState *dev)
-{
- PCIVGAState *d = PCI_VGA(PCI_DEVICE(dev));
- vga_common_reset(&d->vga);
-}
-
-static Property vga_pci_properties[] = {
- DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
- DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true),
- DEFINE_PROP_BIT("qemu-extended-regs",
- PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static Property secondary_pci_properties[] = {
- DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
- DEFINE_PROP_BIT("qemu-extended-regs",
- PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void vga_pci_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->vendor_id = PCI_VENDOR_ID_QEMU;
- k->device_id = PCI_DEVICE_ID_QEMU_VGA;
- dc->vmsd = &vmstate_vga_pci;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
-}
-
-static const TypeInfo vga_pci_type_info = {
- .name = TYPE_PCI_VGA,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCIVGAState),
- .abstract = true,
- .class_init = vga_pci_class_init,
-};
-
-static void vga_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = pci_std_vga_realize;
- k->romfile = "vgabios-stdvga.bin";
- k->class_id = PCI_CLASS_DISPLAY_VGA;
- dc->props = vga_pci_properties;
- dc->hotpluggable = false;
-}
-
-static void secondary_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = pci_secondary_vga_realize;
- k->class_id = PCI_CLASS_DISPLAY_OTHER;
- dc->props = secondary_pci_properties;
- dc->reset = pci_secondary_vga_reset;
-}
-
-static const TypeInfo vga_info = {
- .name = "VGA",
- .parent = TYPE_PCI_VGA,
- .instance_init = pci_std_vga_init,
- .class_init = vga_class_init,
-};
-
-static const TypeInfo secondary_info = {
- .name = "secondary-vga",
- .parent = TYPE_PCI_VGA,
- .instance_init = pci_secondary_vga_init,
- .class_init = secondary_class_init,
-};
-
-static void vga_register_types(void)
-{
- type_register_static(&vga_pci_type_info);
- type_register_static(&vga_info);
- type_register_static(&secondary_info);
-}
-
-type_init(vga_register_types)
diff --git a/qemu/hw/display/vga.c b/qemu/hw/display/vga.c
deleted file mode 100644
index 4a55ec6db..000000000
--- a/qemu/hw/display/vga.c
+++ /dev/null
@@ -1,2289 +0,0 @@
-/*
- * QEMU VGA Emulator.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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 "vga.h"
-#include "ui/console.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "vga_int.h"
-#include "ui/pixel_ops.h"
-#include "qemu/timer.h"
-#include "hw/xen/xen.h"
-#include "trace.h"
-
-//#define DEBUG_VGA
-//#define DEBUG_VGA_MEM
-//#define DEBUG_VGA_REG
-
-//#define DEBUG_BOCHS_VBE
-
-/* 16 state changes per vertical frame @60 Hz */
-#define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60)
-
-/*
- * Video Graphics Array (VGA)
- *
- * Chipset docs for original IBM VGA:
- * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
- *
- * FreeVGA site:
- * http://www.osdever.net/FreeVGA/home.htm
- *
- * Standard VGA features and Bochs VBE extensions are implemented.
- */
-
-/* force some bits to zero */
-const uint8_t sr_mask[8] = {
- 0x03,
- 0x3d,
- 0x0f,
- 0x3f,
- 0x0e,
- 0x00,
- 0x00,
- 0xff,
-};
-
-const uint8_t gr_mask[16] = {
- 0x0f, /* 0x00 */
- 0x0f, /* 0x01 */
- 0x0f, /* 0x02 */
- 0x1f, /* 0x03 */
- 0x03, /* 0x04 */
- 0x7b, /* 0x05 */
- 0x0f, /* 0x06 */
- 0x0f, /* 0x07 */
- 0xff, /* 0x08 */
- 0x00, /* 0x09 */
- 0x00, /* 0x0a */
- 0x00, /* 0x0b */
- 0x00, /* 0x0c */
- 0x00, /* 0x0d */
- 0x00, /* 0x0e */
- 0x00, /* 0x0f */
-};
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define PAT(x) cbswap_32(x)
-#else
-#define PAT(x) (x)
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define BIG 1
-#else
-#define BIG 0
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
-#else
-#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
-#endif
-
-static const uint32_t mask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-#undef PAT
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define PAT(x) (x)
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static uint32_t expand4[256];
-static uint16_t expand2[256];
-static uint8_t expand4to8[16];
-
-static void vbe_update_vgaregs(VGACommonState *s);
-
-static inline bool vbe_enabled(VGACommonState *s)
-{
- return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
-}
-
-static void vga_update_memory_access(VGACommonState *s)
-{
- hwaddr base, offset, size;
-
- if (s->legacy_address_space == NULL) {
- return;
- }
-
- if (s->has_chain4_alias) {
- memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);
- object_unparent(OBJECT(&s->chain4_alias));
- s->has_chain4_alias = false;
- s->plane_updated = 0xf;
- }
- if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
- VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
- offset = 0;
- switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
- case 0:
- base = 0xa0000;
- size = 0x20000;
- break;
- case 1:
- base = 0xa0000;
- size = 0x10000;
- offset = s->bank_offset;
- break;
- case 2:
- base = 0xb0000;
- size = 0x8000;
- break;
- case 3:
- default:
- base = 0xb8000;
- size = 0x8000;
- break;
- }
- assert(offset + size <= s->vram_size);
- memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
- "vga.chain4", &s->vram, offset, size);
- memory_region_add_subregion_overlap(s->legacy_address_space, base,
- &s->chain4_alias, 2);
- s->has_chain4_alias = true;
- }
-}
-
-static void vga_dumb_update_retrace_info(VGACommonState *s)
-{
- (void) s;
-}
-
-static void vga_precise_update_retrace_info(VGACommonState *s)
-{
- int htotal_chars;
- int hretr_start_char;
- int hretr_skew_chars;
- int hretr_end_char;
-
- int vtotal_lines;
- int vretr_start_line;
- int vretr_end_line;
-
- int dots;
-#if 0
- int div2, sldiv2;
-#endif
- int clocking_mode;
- int clock_sel;
- const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
- int64_t chars_per_sec;
- struct vga_precise_retrace *r = &s->retrace_info.precise;
-
- htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
- hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
- hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
- hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
-
- vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
- (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
- ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
- vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
- ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
- ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
- vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
-
- clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
- clock_sel = (s->msr >> 2) & 3;
- dots = (s->msr & 1) ? 8 : 9;
-
- chars_per_sec = clk_hz[clock_sel] / dots;
-
- htotal_chars <<= clocking_mode;
-
- r->total_chars = vtotal_lines * htotal_chars;
- if (r->freq) {
- r->ticks_per_char = NANOSECONDS_PER_SECOND / (r->total_chars * r->freq);
- } else {
- r->ticks_per_char = NANOSECONDS_PER_SECOND / chars_per_sec;
- }
-
- r->vstart = vretr_start_line;
- r->vend = r->vstart + vretr_end_line + 1;
-
- r->hstart = hretr_start_char + hretr_skew_chars;
- r->hend = r->hstart + hretr_end_char + 1;
- r->htotal = htotal_chars;
-
-#if 0
- div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
- sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
- printf (
- "hz=%f\n"
- "htotal = %d\n"
- "hretr_start = %d\n"
- "hretr_skew = %d\n"
- "hretr_end = %d\n"
- "vtotal = %d\n"
- "vretr_start = %d\n"
- "vretr_end = %d\n"
- "div2 = %d sldiv2 = %d\n"
- "clocking_mode = %d\n"
- "clock_sel = %d %d\n"
- "dots = %d\n"
- "ticks/char = %" PRId64 "\n"
- "\n",
- (double) NANOSECONDS_PER_SECOND / (r->ticks_per_char * r->total_chars),
- htotal_chars,
- hretr_start_char,
- hretr_skew_chars,
- hretr_end_char,
- vtotal_lines,
- vretr_start_line,
- vretr_end_line,
- div2, sldiv2,
- clocking_mode,
- clock_sel,
- clk_hz[clock_sel],
- dots,
- r->ticks_per_char
- );
-#endif
-}
-
-static uint8_t vga_precise_retrace(VGACommonState *s)
-{
- struct vga_precise_retrace *r = &s->retrace_info.precise;
- uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
-
- if (r->total_chars) {
- int cur_line, cur_line_char, cur_char;
- int64_t cur_tick;
-
- cur_tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
- cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
- cur_line = cur_char / r->htotal;
-
- if (cur_line >= r->vstart && cur_line <= r->vend) {
- val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
- } else {
- cur_line_char = cur_char % r->htotal;
- if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
- val |= ST01_DISP_ENABLE;
- }
- }
-
- return val;
- } else {
- return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
- }
-}
-
-static uint8_t vga_dumb_retrace(VGACommonState *s)
-{
- return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
-}
-
-int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
-{
- if (s->msr & VGA_MIS_COLOR) {
- /* Color */
- return (addr >= 0x3b0 && addr <= 0x3bf);
- } else {
- /* Monochrome */
- return (addr >= 0x3d0 && addr <= 0x3df);
- }
-}
-
-uint32_t vga_ioport_read(void *opaque, uint32_t addr)
-{
- VGACommonState *s = opaque;
- int val, index;
-
- if (vga_ioport_invalid(s, addr)) {
- val = 0xff;
- } else {
- switch(addr) {
- case VGA_ATT_W:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case VGA_ATT_R:
- index = s->ar_index & 0x1f;
- if (index < VGA_ATT_C) {
- val = s->ar[index];
- } else {
- val = 0;
- }
- break;
- case VGA_MIS_W:
- val = s->st00;
- break;
- case VGA_SEQ_I:
- val = s->sr_index;
- break;
- case VGA_SEQ_D:
- val = s->sr[s->sr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case VGA_PEL_IR:
- val = s->dac_state;
- break;
- case VGA_PEL_IW:
- val = s->dac_write_index;
- break;
- case VGA_PEL_D:
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- break;
- case VGA_FTC_R:
- val = s->fcr;
- break;
- case VGA_MIS_R:
- val = s->msr;
- break;
- case VGA_GFX_I:
- val = s->gr_index;
- break;
- case VGA_GFX_D:
- val = s->gr[s->gr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case VGA_CRT_IM:
- case VGA_CRT_IC:
- val = s->cr_index;
- break;
- case VGA_CRT_DM:
- case VGA_CRT_DC:
- val = s->cr[s->cr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- break;
- case VGA_IS1_RM:
- case VGA_IS1_RC:
- /* just toggle to fool polling */
- val = s->st01 = s->retrace(s);
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- VGACommonState *s = opaque;
- int index;
-
- /* check port range access depending on color/monochrome mode */
- if (vga_ioport_invalid(s, addr)) {
- return;
- }
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch(addr) {
- case VGA_ATT_W:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch(index) {
- case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
- s->ar[index] = val & 0x3f;
- break;
- case VGA_ATC_MODE:
- s->ar[index] = val & ~0x10;
- break;
- case VGA_ATC_OVERSCAN:
- s->ar[index] = val;
- break;
- case VGA_ATC_PLANE_ENABLE:
- s->ar[index] = val & ~0xc0;
- break;
- case VGA_ATC_PEL:
- s->ar[index] = val & ~0xf0;
- break;
- case VGA_ATC_COLOR_PAGE:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case VGA_MIS_W:
- s->msr = val & ~0x10;
- s->update_retrace_info(s);
- break;
- case VGA_SEQ_I:
- s->sr_index = val & 7;
- break;
- case VGA_SEQ_D:
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
- vbe_update_vgaregs(s);
- if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
- s->update_retrace_info(s);
- }
- vga_update_memory_access(s);
- break;
- case VGA_PEL_IR:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case VGA_PEL_IW:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case VGA_PEL_D:
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- break;
- case VGA_GFX_I:
- s->gr_index = val & 0x0f;
- break;
- case VGA_GFX_D:
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
- vbe_update_vgaregs(s);
- vga_update_memory_access(s);
- break;
- case VGA_CRT_IM:
- case VGA_CRT_IC:
- s->cr_index = val;
- break;
- case VGA_CRT_DM:
- case VGA_CRT_DC:
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- /* handle CR0-7 protection */
- if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
- s->cr_index <= VGA_CRTC_OVERFLOW) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == VGA_CRTC_OVERFLOW) {
- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
- (val & 0x10);
- vbe_update_vgaregs(s);
- }
- return;
- }
- s->cr[s->cr_index] = val;
- vbe_update_vgaregs(s);
-
- switch(s->cr_index) {
- case VGA_CRTC_H_TOTAL:
- case VGA_CRTC_H_SYNC_START:
- case VGA_CRTC_H_SYNC_END:
- case VGA_CRTC_V_TOTAL:
- case VGA_CRTC_OVERFLOW:
- case VGA_CRTC_V_SYNC_END:
- case VGA_CRTC_MODE:
- s->update_retrace_info(s);
- break;
- }
- break;
- case VGA_IS1_RM:
- case VGA_IS1_RC:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-/*
- * Sanity check vbe register writes.
- *
- * As we don't have a way to signal errors to the guest in the bochs
- * dispi interface we'll go adjust the registers to the closest valid
- * value.
- */
-static void vbe_fixup_regs(VGACommonState *s)
-{
- uint16_t *r = s->vbe_regs;
- uint32_t bits, linelength, maxy, offset;
-
- if (!vbe_enabled(s)) {
- /* vbe is turned off -- nothing to do */
- return;
- }
-
- /* check depth */
- switch (r[VBE_DISPI_INDEX_BPP]) {
- case 4:
- case 8:
- case 16:
- case 24:
- case 32:
- bits = r[VBE_DISPI_INDEX_BPP];
- break;
- case 15:
- bits = 16;
- break;
- default:
- bits = r[VBE_DISPI_INDEX_BPP] = 8;
- break;
- }
-
- /* check width */
- r[VBE_DISPI_INDEX_XRES] &= ~7u;
- if (r[VBE_DISPI_INDEX_XRES] == 0) {
- r[VBE_DISPI_INDEX_XRES] = 8;
- }
- if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
- r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
- }
- r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
- if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
- r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
- }
- if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
- r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
- }
-
- /* check height */
- linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
- maxy = s->vbe_size / linelength;
- if (r[VBE_DISPI_INDEX_YRES] == 0) {
- r[VBE_DISPI_INDEX_YRES] = 1;
- }
- if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
- r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
- }
- if (r[VBE_DISPI_INDEX_YRES] > maxy) {
- r[VBE_DISPI_INDEX_YRES] = maxy;
- }
-
- /* check offset */
- if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
- r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
- }
- if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
- r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
- }
- offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
- offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
- if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
- r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
- offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
- if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
- r[VBE_DISPI_INDEX_X_OFFSET] = 0;
- offset = 0;
- }
- }
-
- /* update vga state */
- r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
- s->vbe_line_offset = linelength;
- s->vbe_start_addr = offset / 4;
-}
-
-/* we initialize the VGA graphic mode */
-static void vbe_update_vgaregs(VGACommonState *s)
-{
- int h, shift_control;
-
- if (!vbe_enabled(s)) {
- /* vbe is turned off -- nothing to do */
- return;
- }
-
- /* graphic mode + memory map 1 */
- s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
- VGA_GR06_GRAPHICS_MODE;
- s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
- s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
- /* width */
- s->cr[VGA_CRTC_H_DISP] =
- (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
- /* height (only meaningful if < 1024) */
- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
- s->cr[VGA_CRTC_V_DISP_END] = h;
- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
- /* line compare to 1023 */
- s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
- s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
- s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- shift_control = 0;
- s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
- } else {
- shift_control = 2;
- /* set chain 4 mode */
- s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
- /* activate all planes */
- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
- }
- s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
- (shift_control << 5);
- s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
-}
-
-static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
-{
- VGACommonState *s = opaque;
- uint32_t val;
- val = s->vbe_index;
- return val;
-}
-
-uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
-{
- VGACommonState *s = opaque;
- uint32_t val;
-
- if (s->vbe_index < VBE_DISPI_INDEX_NB) {
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
- switch(s->vbe_index) {
- /* XXX: do not hardcode ? */
- case VBE_DISPI_INDEX_XRES:
- val = VBE_DISPI_MAX_XRES;
- break;
- case VBE_DISPI_INDEX_YRES:
- val = VBE_DISPI_MAX_YRES;
- break;
- case VBE_DISPI_INDEX_BPP:
- val = VBE_DISPI_MAX_BPP;
- break;
- default:
- val = s->vbe_regs[s->vbe_index];
- break;
- }
- } else {
- val = s->vbe_regs[s->vbe_index];
- }
- } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
- val = s->vbe_size / (64 * 1024);
- } else {
- val = 0;
- }
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- return val;
-}
-
-void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
-{
- VGACommonState *s = opaque;
- s->vbe_index = val;
-}
-
-void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
-{
- VGACommonState *s = opaque;
-
- if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- switch(s->vbe_index) {
- case VBE_DISPI_INDEX_ID:
- if (val == VBE_DISPI_ID0 ||
- val == VBE_DISPI_ID1 ||
- val == VBE_DISPI_ID2 ||
- val == VBE_DISPI_ID3 ||
- val == VBE_DISPI_ID4) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_XRES:
- case VBE_DISPI_INDEX_YRES:
- case VBE_DISPI_INDEX_BPP:
- case VBE_DISPI_INDEX_VIRT_WIDTH:
- case VBE_DISPI_INDEX_X_OFFSET:
- case VBE_DISPI_INDEX_Y_OFFSET:
- s->vbe_regs[s->vbe_index] = val;
- vbe_fixup_regs(s);
- vbe_update_vgaregs(s);
- break;
- case VBE_DISPI_INDEX_BANK:
- val &= s->vbe_bank_mask;
- s->vbe_regs[s->vbe_index] = val;
- s->bank_offset = (val << 16);
- vga_update_memory_access(s);
- break;
- case VBE_DISPI_INDEX_ENABLE:
- if ((val & VBE_DISPI_ENABLED) &&
- !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
-
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
- vbe_fixup_regs(s);
- vbe_update_vgaregs(s);
-
- /* clear the screen */
- if (!(val & VBE_DISPI_NOCLEARMEM)) {
- memset(s->vram_ptr, 0,
- s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
- }
- } else {
- s->bank_offset = 0;
- }
- s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
- s->vbe_regs[s->vbe_index] = val;
- vga_update_memory_access(s);
- break;
- default:
- break;
- }
- }
-}
-
-/* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
-{
- int memory_map_mode, plane;
- uint32_t ret;
-
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return 0xff;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- }
-
- if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
- /* chain 4 mode : simplest access */
- assert(addr < s->vram_size);
- ret = s->vram_ptr[addr];
- } else if (s->gr[VGA_GFX_MODE] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
- addr = ((addr & ~1) << 1) | plane;
- if (addr >= s->vram_size) {
- return 0xff;
- }
- ret = s->vram_ptr[addr];
- } else {
- /* standard VGA latched access */
- if (addr * sizeof(uint32_t) >= s->vram_size) {
- return 0xff;
- }
- s->latch = ((uint32_t *)s->vram_ptr)[addr];
-
- if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
- /* read mode 0 */
- plane = s->gr[VGA_GFX_PLANE_READ];
- ret = GET_PLANE(s->latch, plane);
- } else {
- /* read mode 1 */
- ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
- mask16[s->gr[VGA_GFX_COMPARE_MASK]];
- ret |= ret >> 16;
- ret |= ret >> 8;
- ret = (~ret) & 0xff;
- }
- }
- return ret;
-}
-
-/* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
-{
- int memory_map_mode, plane, write_mode, b, func_select, mask;
- uint32_t write_mask, bit_mask, set_mask;
-
-#ifdef DEBUG_VGA_MEM
- printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
-#endif
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return;
- break;
- }
-
- if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
- /* chain 4 mode : simplest access */
- plane = addr & 3;
- mask = (1 << plane);
- if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
- assert(addr < s->vram_size);
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- memory_region_set_dirty(&s->vram, addr, 1);
- }
- } else if (s->gr[VGA_GFX_MODE] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
- mask = (1 << plane);
- if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
- addr = ((addr & ~1) << 1) | plane;
- if (addr >= s->vram_size) {
- return;
- }
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- memory_region_set_dirty(&s->vram, addr, 1);
- }
- } else {
- /* standard VGA latched access */
- write_mode = s->gr[VGA_GFX_MODE] & 3;
- switch(write_mode) {
- default:
- case 0:
- /* rotate */
- b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
- val = ((val >> b) | (val << (8 - b))) & 0xff;
- val |= val << 8;
- val |= val << 16;
-
- /* apply set/reset mask */
- set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
- val = (val & ~set_mask) |
- (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
- bit_mask = s->gr[VGA_GFX_BIT_MASK];
- break;
- case 1:
- val = s->latch;
- goto do_write;
- case 2:
- val = mask16[val & 0x0f];
- bit_mask = s->gr[VGA_GFX_BIT_MASK];
- break;
- case 3:
- /* rotate */
- b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
- val = (val >> b) | (val << (8 - b));
-
- bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
- val = mask16[s->gr[VGA_GFX_SR_VALUE]];
- break;
- }
-
- /* apply logical operation */
- func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
- switch(func_select) {
- case 0:
- default:
- /* nothing to do */
- break;
- case 1:
- /* and */
- val &= s->latch;
- break;
- case 2:
- /* or */
- val |= s->latch;
- break;
- case 3:
- /* xor */
- val ^= s->latch;
- break;
- }
-
- /* apply bit mask */
- bit_mask |= bit_mask << 8;
- bit_mask |= bit_mask << 16;
- val = (val & bit_mask) | (s->latch & ~bit_mask);
-
- do_write:
- /* mask data according to sr[2] */
- mask = s->sr[VGA_SEQ_PLANE_WRITE];
- s->plane_updated |= mask; /* only used to detect font change */
- write_mask = mask16[mask];
- if (addr * sizeof(uint32_t) >= s->vram_size) {
- return;
- }
- ((uint32_t *)s->vram_ptr)[addr] =
- (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
- (val & write_mask);
-#ifdef DEBUG_VGA_MEM
- printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
- addr * 4, write_mask, val);
-#endif
- memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
- }
-}
-
-typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width);
-
-#include "vga-helpers.h"
-
-/* return true if the palette was modified */
-static int update_palette16(VGACommonState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- for(i = 0; i < 16; i++) {
- v = s->ar[i];
- if (s->ar[VGA_ATC_MODE] & 0x80) {
- v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
- } else {
- v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
- }
- v = v * 3;
- col = rgb_to_pixel32(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- }
- return full_update;
-}
-
-/* return true if the palette was modified */
-static int update_palette256(VGACommonState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- v = 0;
- for(i = 0; i < 256; i++) {
- if (s->dac_8bit) {
- col = rgb_to_pixel32(s->palette[v],
- s->palette[v + 1],
- s->palette[v + 2]);
- } else {
- col = rgb_to_pixel32(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- }
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- v += 3;
- }
- return full_update;
-}
-
-static void vga_get_offsets(VGACommonState *s,
- uint32_t *pline_offset,
- uint32_t *pstart_addr,
- uint32_t *pline_compare)
-{
- uint32_t start_addr, line_offset, line_compare;
-
- if (vbe_enabled(s)) {
- line_offset = s->vbe_line_offset;
- start_addr = s->vbe_start_addr;
- line_compare = 65535;
- } else {
- /* compute line_offset in bytes */
- line_offset = s->cr[VGA_CRTC_OFFSET];
- line_offset <<= 3;
-
- /* starting address */
- start_addr = s->cr[VGA_CRTC_START_LO] |
- (s->cr[VGA_CRTC_START_HI] << 8);
-
- /* line compare */
- line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
- ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
- }
- *pline_offset = line_offset;
- *pstart_addr = start_addr;
- *pline_compare = line_compare;
-}
-
-/* update start_addr and line_offset. Return TRUE if modified */
-static int update_basic_params(VGACommonState *s)
-{
- int full_update;
- uint32_t start_addr, line_offset, line_compare;
-
- full_update = 0;
-
- s->get_offsets(s, &line_offset, &start_addr, &line_compare);
-
- if (line_offset != s->line_offset ||
- start_addr != s->start_addr ||
- line_compare != s->line_compare) {
- s->line_offset = line_offset;
- s->start_addr = start_addr;
- s->line_compare = line_compare;
- full_update = 1;
- }
- return full_update;
-}
-
-
-static const uint8_t cursor_glyph[32 * 4] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
- int *pcwidth, int *pcheight)
-{
- int width, cwidth, height, cheight;
-
- /* total width & height */
- cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
- cwidth = 8;
- if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
- cwidth = 9;
- }
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
- cwidth = 16; /* NOTE: no 18 pixel wide */
- }
- width = (s->cr[VGA_CRTC_H_DISP] + 1);
- if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
- /* ugly hack for CGA 160x100x16 - explain me the logic */
- height = 100;
- } else {
- height = s->cr[VGA_CRTC_V_DISP_END] |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
- height = (height + 1) / cheight;
- }
-
- *pwidth = width;
- *pheight = height;
- *pcwidth = cwidth;
- *pcheight = cheight;
-}
-
-/*
- * Text mode update
- * Missing:
- * - double scan
- * - double width
- * - underline
- * - flashing
- */
-static void vga_draw_text(VGACommonState *s, int full_update)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
- int cx_min, cx_max, linesize, x_incr, line, line1;
- uint32_t offset, fgcol, bgcol, v, cursor_offset;
- uint8_t *d1, *d, *src, *dest, *cursor_ptr;
- const uint8_t *font_ptr, *font_base[2];
- int dup9, line_offset;
- uint32_t *palette;
- uint32_t *ch_attr_ptr;
- int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
-
- /* compute font data address (in plane 2) */
- v = s->sr[VGA_SEQ_CHARACTER_MAP];
- offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
- if (offset != s->font_offsets[0]) {
- s->font_offsets[0] = offset;
- full_update = 1;
- }
- font_base[0] = s->vram_ptr + offset;
-
- offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
- font_base[1] = s->vram_ptr + offset;
- if (offset != s->font_offsets[1]) {
- s->font_offsets[1] = offset;
- full_update = 1;
- }
- if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
- /* if the plane 2 was modified since the last display, it
- indicates the font may have been modified */
- s->plane_updated = 0;
- full_update = 1;
- }
- full_update |= update_basic_params(s);
-
- line_offset = s->line_offset;
-
- vga_get_text_resolution(s, &width, &height, &cw, &cheight);
- if ((height * width) <= 1) {
- /* better than nothing: exit if transient size is too small */
- return;
- }
- if ((height * width) > CH_ATTR_SIZE) {
- /* better than nothing: exit if transient size is too big */
- return;
- }
-
- if (width != s->last_width || height != s->last_height ||
- cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
- qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
- surface = qemu_console_surface(s->con);
- dpy_text_resize(s->con, width, height);
- s->last_depth = 0;
- s->last_width = width;
- s->last_height = height;
- s->last_ch = cheight;
- s->last_cw = cw;
- full_update = 1;
- }
- full_update |= update_palette16(s);
- palette = s->last_palette;
- x_incr = cw * surface_bytes_per_pixel(surface);
-
- if (full_update) {
- s->full_update_text = 1;
- }
- if (s->full_update_gfx) {
- s->full_update_gfx = 0;
- full_update |= 1;
- }
-
- cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
- s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
- if (cursor_offset != s->cursor_offset ||
- s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
- s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
- /* if the cursor position changed, we update the old and new
- chars */
- if (s->cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[s->cursor_offset] = -1;
- if (cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[cursor_offset] = -1;
- s->cursor_offset = cursor_offset;
- s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
- s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
- }
- cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
- if (now >= s->cursor_blink_time) {
- s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
- s->cursor_visible_phase = !s->cursor_visible_phase;
- }
-
- dest = surface_data(surface);
- linesize = surface_stride(surface);
- ch_attr_ptr = s->last_ch_attr;
- line = 0;
- offset = s->start_addr * 4;
- for(cy = 0; cy < height; cy++) {
- d1 = dest;
- src = s->vram_ptr + offset;
- cx_min = width;
- cx_max = -1;
- for(cx = 0; cx < width; cx++) {
- ch_attr = *(uint16_t *)src;
- if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
- if (cx < cx_min)
- cx_min = cx;
- if (cx > cx_max)
- cx_max = cx;
- *ch_attr_ptr = ch_attr;
-#ifdef HOST_WORDS_BIGENDIAN
- ch = ch_attr >> 8;
- cattr = ch_attr & 0xff;
-#else
- ch = ch_attr & 0xff;
- cattr = ch_attr >> 8;
-#endif
- font_ptr = font_base[(cattr >> 3) & 1];
- font_ptr += 32 * 4 * ch;
- bgcol = palette[cattr >> 4];
- fgcol = palette[cattr & 0x0f];
- if (cw == 16) {
- vga_draw_glyph16(d1, linesize,
- font_ptr, cheight, fgcol, bgcol);
- } else if (cw != 9) {
- vga_draw_glyph8(d1, linesize,
- font_ptr, cheight, fgcol, bgcol);
- } else {
- dup9 = 0;
- if (ch >= 0xb0 && ch <= 0xdf &&
- (s->ar[VGA_ATC_MODE] & 0x04)) {
- dup9 = 1;
- }
- vga_draw_glyph9(d1, linesize,
- font_ptr, cheight, fgcol, bgcol, dup9);
- }
- if (src == cursor_ptr &&
- !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
- s->cursor_visible_phase) {
- int line_start, line_last, h;
- /* draw the cursor */
- line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
- line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
- /* XXX: check that */
- if (line_last > cheight - 1)
- line_last = cheight - 1;
- if (line_last >= line_start && line_start < cheight) {
- h = line_last - line_start + 1;
- d = d1 + linesize * line_start;
- if (cw == 16) {
- vga_draw_glyph16(d, linesize,
- cursor_glyph, h, fgcol, bgcol);
- } else if (cw != 9) {
- vga_draw_glyph8(d, linesize,
- cursor_glyph, h, fgcol, bgcol);
- } else {
- vga_draw_glyph9(d, linesize,
- cursor_glyph, h, fgcol, bgcol, 1);
- }
- }
- }
- }
- d1 += x_incr;
- src += 4;
- ch_attr_ptr++;
- }
- if (cx_max != -1) {
- dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
- (cx_max - cx_min + 1) * cw, cheight);
- }
- dest += linesize * cheight;
- line1 = line + cheight;
- offset += line_offset;
- if (line < s->line_compare && line1 >= s->line_compare) {
- offset = 0;
- }
- line = line1;
- }
-}
-
-enum {
- VGA_DRAW_LINE2,
- VGA_DRAW_LINE2D2,
- VGA_DRAW_LINE4,
- VGA_DRAW_LINE4D2,
- VGA_DRAW_LINE8D2,
- VGA_DRAW_LINE8,
- VGA_DRAW_LINE15_LE,
- VGA_DRAW_LINE16_LE,
- VGA_DRAW_LINE24_LE,
- VGA_DRAW_LINE32_LE,
- VGA_DRAW_LINE15_BE,
- VGA_DRAW_LINE16_BE,
- VGA_DRAW_LINE24_BE,
- VGA_DRAW_LINE32_BE,
- VGA_DRAW_LINE_NB,
-};
-
-static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
- vga_draw_line2,
- vga_draw_line2d2,
- vga_draw_line4,
- vga_draw_line4d2,
- vga_draw_line8d2,
- vga_draw_line8,
- vga_draw_line15_le,
- vga_draw_line16_le,
- vga_draw_line24_le,
- vga_draw_line32_le,
- vga_draw_line15_be,
- vga_draw_line16_be,
- vga_draw_line24_be,
- vga_draw_line32_be,
-};
-
-static int vga_get_bpp(VGACommonState *s)
-{
- int ret;
-
- if (vbe_enabled(s)) {
- ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- } else {
- ret = 0;
- }
- return ret;
-}
-
-static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
- if (vbe_enabled(s)) {
- width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
- } else {
- width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
- height = s->cr[VGA_CRTC_V_DISP_END] |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
- height = (height + 1);
- }
- *pwidth = width;
- *pheight = height;
-}
-
-void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
-{
- int y;
- if (y1 >= VGA_MAX_HEIGHT)
- return;
- if (y2 >= VGA_MAX_HEIGHT)
- y2 = VGA_MAX_HEIGHT;
- for(y = y1; y < y2; y++) {
- s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
- }
-}
-
-void vga_sync_dirty_bitmap(VGACommonState *s)
-{
- memory_region_sync_dirty_bitmap(&s->vram);
-}
-
-void vga_dirty_log_start(VGACommonState *s)
-{
- memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
-}
-
-void vga_dirty_log_stop(VGACommonState *s)
-{
- memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
-}
-
-/*
- * graphic modes
- */
-static void vga_draw_graphic(VGACommonState *s, int full_update)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int y1, y, update, linesize, y_start, double_scan, mask, depth;
- int width, height, shift_control, line_offset, bwidth, bits;
- ram_addr_t page0, page1, page_min, page_max;
- int disp_width, multi_scan, multi_run;
- uint8_t *d;
- uint32_t v, addr1, addr;
- vga_draw_line_func *vga_draw_line = NULL;
- bool share_surface;
- pixman_format_code_t format;
-#ifdef HOST_WORDS_BIGENDIAN
- bool byteswap = !s->big_endian_fb;
-#else
- bool byteswap = s->big_endian_fb;
-#endif
-
- full_update |= update_basic_params(s);
-
- if (!full_update)
- vga_sync_dirty_bitmap(s);
-
- s->get_resolution(s, &width, &height);
- disp_width = width;
-
- shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
- double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
- if (shift_control != 1) {
- multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
- - 1;
- } else {
- /* in CGA modes, multi_scan is ignored */
- /* XXX: is it correct ? */
- multi_scan = double_scan;
- }
- multi_run = multi_scan;
- if (shift_control != s->shift_control ||
- double_scan != s->double_scan) {
- full_update = 1;
- s->shift_control = shift_control;
- s->double_scan = double_scan;
- }
-
- if (shift_control == 0) {
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
- disp_width <<= 1;
- }
- } else if (shift_control == 1) {
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
- disp_width <<= 1;
- }
- }
-
- depth = s->get_bpp(s);
-
- /*
- * Check whether we can share the surface with the backend
- * or whether we need a shadow surface. We share native
- * endian surfaces for 15bpp and above and byteswapped
- * surfaces for 24bpp and above.
- */
- format = qemu_default_pixman_format(depth, !byteswap);
- if (format) {
- share_surface = dpy_gfx_check_format(s->con, format)
- && !s->force_shadow;
- } else {
- share_surface = false;
- }
- if (s->line_offset != s->last_line_offset ||
- disp_width != s->last_width ||
- height != s->last_height ||
- s->last_depth != depth ||
- s->last_byteswap != byteswap ||
- share_surface != is_buffer_shared(surface)) {
- if (share_surface) {
- surface = qemu_create_displaysurface_from(disp_width,
- height, format, s->line_offset,
- s->vram_ptr + (s->start_addr * 4));
- dpy_gfx_replace_surface(s->con, surface);
-#ifdef DEBUG_VGA
- printf("VGA: Using shared surface for depth=%d swap=%d\n",
- depth, byteswap);
-#endif
- } else {
- qemu_console_resize(s->con, disp_width, height);
- surface = qemu_console_surface(s->con);
-#ifdef DEBUG_VGA
- printf("VGA: Using shadow surface for depth=%d swap=%d\n",
- depth, byteswap);
-#endif
- }
- s->last_scr_width = disp_width;
- s->last_scr_height = height;
- s->last_width = disp_width;
- s->last_height = height;
- s->last_line_offset = s->line_offset;
- s->last_depth = depth;
- s->last_byteswap = byteswap;
- full_update = 1;
- } else if (is_buffer_shared(surface) &&
- (full_update || surface_data(surface) != s->vram_ptr
- + (s->start_addr * 4))) {
- pixman_format_code_t format =
- qemu_default_pixman_format(depth, !byteswap);
- surface = qemu_create_displaysurface_from(disp_width,
- height, format, s->line_offset,
- s->vram_ptr + (s->start_addr * 4));
- dpy_gfx_replace_surface(s->con, surface);
- }
-
- if (shift_control == 0) {
- full_update |= update_palette16(s);
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
- v = VGA_DRAW_LINE4D2;
- } else {
- v = VGA_DRAW_LINE4;
- }
- bits = 4;
- } else if (shift_control == 1) {
- full_update |= update_palette16(s);
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
- v = VGA_DRAW_LINE2D2;
- } else {
- v = VGA_DRAW_LINE2;
- }
- bits = 4;
- } else {
- switch(s->get_bpp(s)) {
- default:
- case 0:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8D2;
- bits = 4;
- break;
- case 8:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8;
- bits = 8;
- break;
- case 15:
- v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
- bits = 16;
- break;
- case 16:
- v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
- bits = 16;
- break;
- case 24:
- v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
- bits = 24;
- break;
- case 32:
- v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
- bits = 32;
- break;
- }
- }
- vga_draw_line = vga_draw_line_table[v];
-
- if (!is_buffer_shared(surface) && s->cursor_invalidate) {
- s->cursor_invalidate(s);
- }
-
- line_offset = s->line_offset;
-#if 0
- printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
- width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
- s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
-#endif
- addr1 = (s->start_addr * 4);
- bwidth = (width * bits + 7) / 8;
- y_start = -1;
- page_min = -1;
- page_max = 0;
- d = surface_data(surface);
- linesize = surface_stride(surface);
- y1 = 0;
- for(y = 0; y < height; y++) {
- addr = addr1;
- if (!(s->cr[VGA_CRTC_MODE] & 1)) {
- int shift;
- /* CGA compatibility handling */
- shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
- addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
- }
- if (!(s->cr[VGA_CRTC_MODE] & 2)) {
- addr = (addr & ~0x8000) | ((y1 & 2) << 14);
- }
- update = full_update;
- page0 = addr;
- page1 = addr + bwidth - 1;
- update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
- DIRTY_MEMORY_VGA);
- /* explicit invalidation for the hardware cursor */
- update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
- if (update) {
- if (y_start < 0)
- y_start = y;
- if (page0 < page_min)
- page_min = page0;
- if (page1 > page_max)
- page_max = page1;
- if (!(is_buffer_shared(surface))) {
- vga_draw_line(s, d, s->vram_ptr + addr, width);
- if (s->cursor_draw_line)
- s->cursor_draw_line(s, d, y);
- }
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(s->con, 0, y_start,
- disp_width, y - y_start);
- y_start = -1;
- }
- }
- if (!multi_run) {
- mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
- if ((y1 & mask) == mask)
- addr1 += line_offset;
- y1++;
- multi_run = multi_scan;
- } else {
- multi_run--;
- }
- /* line compare acts on the displayed lines */
- if (y == s->line_compare)
- addr1 = 0;
- d += linesize;
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_gfx_update(s->con, 0, y_start,
- disp_width, y - y_start);
- }
- /* reset modified pages */
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram,
- page_min,
- page_max - page_min,
- DIRTY_MEMORY_VGA);
- }
- memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
-}
-
-static void vga_draw_blank(VGACommonState *s, int full_update)
-{
- DisplaySurface *surface = qemu_console_surface(s->con);
- int i, w;
- uint8_t *d;
-
- if (!full_update)
- return;
- if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
- return;
-
- w = s->last_scr_width * surface_bytes_per_pixel(surface);
- d = surface_data(surface);
- for(i = 0; i < s->last_scr_height; i++) {
- memset(d, 0, w);
- d += surface_stride(surface);
- }
- dpy_gfx_update(s->con, 0, 0,
- s->last_scr_width, s->last_scr_height);
-}
-
-#define GMODE_TEXT 0
-#define GMODE_GRAPH 1
-#define GMODE_BLANK 2
-
-static void vga_update_display(void *opaque)
-{
- VGACommonState *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int full_update, graphic_mode;
-
- qemu_flush_coalesced_mmio_buffer();
-
- if (surface_bits_per_pixel(surface) == 0) {
- /* nothing to do */
- } else {
- full_update = 0;
- if (!(s->ar_index & 0x20)) {
- graphic_mode = GMODE_BLANK;
- } else {
- graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
- }
- if (graphic_mode != s->graphic_mode) {
- s->graphic_mode = graphic_mode;
- s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
- full_update = 1;
- }
- switch(graphic_mode) {
- case GMODE_TEXT:
- vga_draw_text(s, full_update);
- break;
- case GMODE_GRAPH:
- vga_draw_graphic(s, full_update);
- break;
- case GMODE_BLANK:
- default:
- vga_draw_blank(s, full_update);
- break;
- }
- }
-}
-
-/* force a full display refresh */
-static void vga_invalidate_display(void *opaque)
-{
- VGACommonState *s = opaque;
-
- s->last_width = -1;
- s->last_height = -1;
-}
-
-void vga_common_reset(VGACommonState *s)
-{
- s->sr_index = 0;
- memset(s->sr, '\0', sizeof(s->sr));
- s->gr_index = 0;
- memset(s->gr, '\0', sizeof(s->gr));
- s->ar_index = 0;
- memset(s->ar, '\0', sizeof(s->ar));
- s->ar_flip_flop = 0;
- s->cr_index = 0;
- memset(s->cr, '\0', sizeof(s->cr));
- s->msr = 0;
- s->fcr = 0;
- s->st00 = 0;
- s->st01 = 0;
- s->dac_state = 0;
- s->dac_sub_index = 0;
- s->dac_read_index = 0;
- s->dac_write_index = 0;
- memset(s->dac_cache, '\0', sizeof(s->dac_cache));
- s->dac_8bit = 0;
- memset(s->palette, '\0', sizeof(s->palette));
- s->bank_offset = 0;
- s->vbe_index = 0;
- memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
- s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
- s->vbe_start_addr = 0;
- s->vbe_line_offset = 0;
- s->vbe_bank_mask = (s->vram_size >> 16) - 1;
- memset(s->font_offsets, '\0', sizeof(s->font_offsets));
- s->graphic_mode = -1; /* force full update */
- s->shift_control = 0;
- s->double_scan = 0;
- s->line_offset = 0;
- s->line_compare = 0;
- s->start_addr = 0;
- s->plane_updated = 0;
- s->last_cw = 0;
- s->last_ch = 0;
- s->last_width = 0;
- s->last_height = 0;
- s->last_scr_width = 0;
- s->last_scr_height = 0;
- s->cursor_start = 0;
- s->cursor_end = 0;
- s->cursor_offset = 0;
- s->big_endian_fb = s->default_endian_fb;
- memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
- memset(s->last_palette, '\0', sizeof(s->last_palette));
- memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
- switch (vga_retrace_method) {
- case VGA_RETRACE_DUMB:
- break;
- case VGA_RETRACE_PRECISE:
- memset(&s->retrace_info, 0, sizeof (s->retrace_info));
- break;
- }
- vga_update_memory_access(s);
-}
-
-static void vga_reset(void *opaque)
-{
- VGACommonState *s = opaque;
- vga_common_reset(s);
-}
-
-#define TEXTMODE_X(x) ((x) % width)
-#define TEXTMODE_Y(x) ((x) / width)
-#define VMEM2CHTYPE(v) ((v & 0xff0007ff) | \
- ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
-/* relay text rendering to the display driver
- * instead of doing a full vga_update_display() */
-static void vga_update_text(void *opaque, console_ch_t *chardata)
-{
- VGACommonState *s = opaque;
- int graphic_mode, i, cursor_offset, cursor_visible;
- int cw, cheight, width, height, size, c_min, c_max;
- uint32_t *src;
- console_ch_t *dst, val;
- char msg_buffer[80];
- int full_update = 0;
-
- qemu_flush_coalesced_mmio_buffer();
-
- if (!(s->ar_index & 0x20)) {
- graphic_mode = GMODE_BLANK;
- } else {
- graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
- }
- if (graphic_mode != s->graphic_mode) {
- s->graphic_mode = graphic_mode;
- full_update = 1;
- }
- if (s->last_width == -1) {
- s->last_width = 0;
- full_update = 1;
- }
-
- switch (graphic_mode) {
- case GMODE_TEXT:
- /* TODO: update palette */
- full_update |= update_basic_params(s);
-
- /* total width & height */
- cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
- cw = 8;
- if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
- cw = 9;
- }
- if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
- cw = 16; /* NOTE: no 18 pixel wide */
- }
- width = (s->cr[VGA_CRTC_H_DISP] + 1);
- if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
- /* ugly hack for CGA 160x100x16 - explain me the logic */
- height = 100;
- } else {
- height = s->cr[VGA_CRTC_V_DISP_END] |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
- ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
- height = (height + 1) / cheight;
- }
-
- size = (height * width);
- if (size > CH_ATTR_SIZE) {
- if (!full_update)
- return;
-
- snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
- width, height);
- break;
- }
-
- if (width != s->last_width || height != s->last_height ||
- cw != s->last_cw || cheight != s->last_ch) {
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
- qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
- dpy_text_resize(s->con, width, height);
- s->last_depth = 0;
- s->last_width = width;
- s->last_height = height;
- s->last_ch = cheight;
- s->last_cw = cw;
- full_update = 1;
- }
-
- if (full_update) {
- s->full_update_gfx = 1;
- }
- if (s->full_update_text) {
- s->full_update_text = 0;
- full_update |= 1;
- }
-
- /* Update "hardware" cursor */
- cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
- s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
- if (cursor_offset != s->cursor_offset ||
- s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
- s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
- cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
- if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
- dpy_text_cursor(s->con,
- TEXTMODE_X(cursor_offset),
- TEXTMODE_Y(cursor_offset));
- else
- dpy_text_cursor(s->con, -1, -1);
- s->cursor_offset = cursor_offset;
- s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
- s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
- }
-
- src = (uint32_t *) s->vram_ptr + s->start_addr;
- dst = chardata;
-
- if (full_update) {
- for (i = 0; i < size; src ++, dst ++, i ++)
- console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
-
- dpy_text_update(s->con, 0, 0, width, height);
- } else {
- c_max = 0;
-
- for (i = 0; i < size; src ++, dst ++, i ++) {
- console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
- if (*dst != val) {
- *dst = val;
- c_max = i;
- break;
- }
- }
- c_min = i;
- for (; i < size; src ++, dst ++, i ++) {
- console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
- if (*dst != val) {
- *dst = val;
- c_max = i;
- }
- }
-
- if (c_min <= c_max) {
- i = TEXTMODE_Y(c_min);
- dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
- }
- }
-
- return;
- case GMODE_GRAPH:
- if (!full_update)
- return;
-
- s->get_resolution(s, &width, &height);
- snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
- width, height);
- break;
- case GMODE_BLANK:
- default:
- if (!full_update)
- return;
-
- snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
- break;
- }
-
- /* Display a message */
- s->last_width = 60;
- s->last_height = height = 3;
- dpy_text_cursor(s->con, -1, -1);
- dpy_text_resize(s->con, s->last_width, height);
-
- for (dst = chardata, i = 0; i < s->last_width * height; i ++)
- console_write_ch(dst ++, ' ');
-
- size = strlen(msg_buffer);
- width = (s->last_width - size) / 2;
- dst = chardata + s->last_width + width;
- for (i = 0; i < size; i ++)
- console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
- QEMU_COLOR_BLACK, 1));
-
- dpy_text_update(s->con, 0, 0, s->last_width, height);
-}
-
-static uint64_t vga_mem_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- VGACommonState *s = opaque;
-
- return vga_mem_readb(s, addr);
-}
-
-static void vga_mem_write(void *opaque, hwaddr addr,
- uint64_t data, unsigned size)
-{
- VGACommonState *s = opaque;
-
- vga_mem_writeb(s, addr, data);
-}
-
-const MemoryRegionOps vga_mem_ops = {
- .read = vga_mem_read,
- .write = vga_mem_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static int vga_common_post_load(void *opaque, int version_id)
-{
- VGACommonState *s = opaque;
-
- /* force refresh */
- s->graphic_mode = -1;
- return 0;
-}
-
-static bool vga_endian_state_needed(void *opaque)
-{
- VGACommonState *s = opaque;
-
- /*
- * Only send the endian state if it's different from the
- * default one, thus ensuring backward compatibility for
- * migration of the common case
- */
- return s->default_endian_fb != s->big_endian_fb;
-}
-
-static const VMStateDescription vmstate_vga_endian = {
- .name = "vga.endian",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = vga_endian_state_needed,
- .fields = (VMStateField[]) {
- VMSTATE_BOOL(big_endian_fb, VGACommonState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_vga_common = {
- .name = "vga",
- .version_id = 2,
- .minimum_version_id = 2,
- .post_load = vga_common_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(latch, VGACommonState),
- VMSTATE_UINT8(sr_index, VGACommonState),
- VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
- VMSTATE_UINT8(gr_index, VGACommonState),
- VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
- VMSTATE_UINT8(ar_index, VGACommonState),
- VMSTATE_BUFFER(ar, VGACommonState),
- VMSTATE_INT32(ar_flip_flop, VGACommonState),
- VMSTATE_UINT8(cr_index, VGACommonState),
- VMSTATE_BUFFER(cr, VGACommonState),
- VMSTATE_UINT8(msr, VGACommonState),
- VMSTATE_UINT8(fcr, VGACommonState),
- VMSTATE_UINT8(st00, VGACommonState),
- VMSTATE_UINT8(st01, VGACommonState),
-
- VMSTATE_UINT8(dac_state, VGACommonState),
- VMSTATE_UINT8(dac_sub_index, VGACommonState),
- VMSTATE_UINT8(dac_read_index, VGACommonState),
- VMSTATE_UINT8(dac_write_index, VGACommonState),
- VMSTATE_BUFFER(dac_cache, VGACommonState),
- VMSTATE_BUFFER(palette, VGACommonState),
-
- VMSTATE_INT32(bank_offset, VGACommonState),
- VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
- VMSTATE_UINT16(vbe_index, VGACommonState),
- VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
- VMSTATE_UINT32(vbe_start_addr, VGACommonState),
- VMSTATE_UINT32(vbe_line_offset, VGACommonState),
- VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_vga_endian,
- NULL
- }
-};
-
-static const GraphicHwOps vga_ops = {
- .invalidate = vga_invalidate_display,
- .gfx_update = vga_update_display,
- .text_update = vga_update_text,
-};
-
-static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
-{
- if (val < vmin) {
- return vmin;
- }
- if (val > vmax) {
- return vmax;
- }
- return val;
-}
-
-void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
-{
- int i, j, v, b;
-
- for(i = 0;i < 256; i++) {
- v = 0;
- for(j = 0; j < 8; j++) {
- v |= ((i >> j) & 1) << (j * 4);
- }
- expand4[i] = v;
-
- v = 0;
- for(j = 0; j < 4; j++) {
- v |= ((i >> (2 * j)) & 3) << (j * 4);
- }
- expand2[i] = v;
- }
- for(i = 0; i < 16; i++) {
- v = 0;
- for(j = 0; j < 4; j++) {
- b = ((i >> j) & 1);
- v |= b << (2 * j);
- v |= b << (2 * j + 1);
- }
- expand4to8[i] = v;
- }
-
- s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
- s->vram_size_mb = pow2ceil(s->vram_size_mb);
- s->vram_size = s->vram_size_mb << 20;
-
- if (!s->vbe_size) {
- s->vbe_size = s->vram_size;
- }
-
- s->is_vbe_vmstate = 1;
- memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size,
- &error_fatal);
- vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj));
- xen_register_framebuffer(&s->vram);
- s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
- s->get_bpp = vga_get_bpp;
- s->get_offsets = vga_get_offsets;
- s->get_resolution = vga_get_resolution;
- s->hw_ops = &vga_ops;
- switch (vga_retrace_method) {
- case VGA_RETRACE_DUMB:
- s->retrace = vga_dumb_retrace;
- s->update_retrace_info = vga_dumb_update_retrace_info;
- break;
-
- case VGA_RETRACE_PRECISE:
- s->retrace = vga_precise_retrace;
- s->update_retrace_info = vga_precise_update_retrace_info;
- break;
- }
-
- /*
- * Set default fb endian based on target, could probably be turned
- * into a device attribute set by the machine/platform to remove
- * all target endian dependencies from this file.
- */
-#ifdef TARGET_WORDS_BIGENDIAN
- s->default_endian_fb = true;
-#else
- s->default_endian_fb = false;
-#endif
- vga_dirty_log_start(s);
-}
-
-static const MemoryRegionPortio vga_portio_list[] = {
- { 0x04, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
- { 0x0a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
- { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
- { 0x24, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
- { 0x2a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
- PORTIO_END_OF_LIST(),
-};
-
-static const MemoryRegionPortio vbe_portio_list[] = {
- { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
-# ifdef TARGET_I386
- { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
-# endif
- { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
- PORTIO_END_OF_LIST(),
-};
-
-/* Used by both ISA and PCI */
-MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
- const MemoryRegionPortio **vga_ports,
- const MemoryRegionPortio **vbe_ports)
-{
- MemoryRegion *vga_mem;
-
- *vga_ports = vga_portio_list;
- *vbe_ports = vbe_portio_list;
-
- vga_mem = g_malloc(sizeof(*vga_mem));
- memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
- "vga-lowmem", 0x20000);
- memory_region_set_flush_coalesced(vga_mem);
-
- return vga_mem;
-}
-
-void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
- MemoryRegion *address_space_io, bool init_vga_ports)
-{
- MemoryRegion *vga_io_memory;
- const MemoryRegionPortio *vga_ports, *vbe_ports;
-
- qemu_register_reset(vga_reset, s);
-
- s->bank_offset = 0;
-
- s->legacy_address_space = address_space;
-
- vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
- memory_region_add_subregion_overlap(address_space,
- 0x000a0000,
- vga_io_memory,
- 1);
- memory_region_set_coalescing(vga_io_memory);
- if (init_vga_ports) {
- portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
- portio_list_set_flush_coalesced(&s->vga_port_list);
- portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
- }
- if (vbe_ports) {
- portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
- portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
- }
-}
-
-void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
-{
- /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
- * so use an alias to avoid double-mapping the same region.
- */
- memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
- &s->vram, 0, memory_region_size(&s->vram));
- /* XXX: use optimized standard vga accesses */
- memory_region_add_subregion(system_memory,
- VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- &s->vram_vbe);
- s->vbe_mapped = 1;
-}
diff --git a/qemu/hw/display/vga.h b/qemu/hw/display/vga.h
deleted file mode 100644
index d917046da..000000000
--- a/qemu/hw/display/vga.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * linux/include/video/vga.h -- standard VGA chipset interaction
- *
- * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
- *
- * Copyright history from vga16fb.c:
- * Copyright 1999 Ben Pfaff and Petr Vandrovec
- * Based on VGA info at http://www.osdever.net/FreeVGA/home.htm
- * Based on VESA framebuffer (c) 1998 Gerd Knorr
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- *
- */
-
-#ifndef __linux_video_vga_h__
-#define __linux_video_vga_h__
-
-/* Some of the code below is taken from SVGAlib. The original,
- unmodified copyright notice for that code is below. */
-/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it without any restrictions. This library is distributed */
-/* in the hope that it will be useful, but without any warranty. */
-
-/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
-/* partially copyrighted (C) 1993 by Hartmut Schirmer */
-
-/* VGA data register ports */
-#define VGA_CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
-#define VGA_CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
-#define VGA_ATT_R 0x3C1 /* Attribute Controller Data Read Register */
-#define VGA_ATT_W 0x3C0 /* Attribute Controller Data Write Register */
-#define VGA_GFX_D 0x3CF /* Graphics Controller Data Register */
-#define VGA_SEQ_D 0x3C5 /* Sequencer Data Register */
-#define VGA_MIS_R 0x3CC /* Misc Output Read Register */
-#define VGA_MIS_W 0x3C2 /* Misc Output Write Register */
-#define VGA_FTC_R 0x3CA /* Feature Control Read Register */
-#define VGA_IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
-#define VGA_IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
-#define VGA_PEL_D 0x3C9 /* PEL Data Register */
-#define VGA_PEL_MSK 0x3C6 /* PEL mask register */
-
-/* EGA-specific registers */
-#define EGA_GFX_E0 0x3CC /* Graphics enable processor 0 */
-#define EGA_GFX_E1 0x3CA /* Graphics enable processor 1 */
-
-/* VGA index register ports */
-#define VGA_CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
-#define VGA_CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
-#define VGA_ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
-#define VGA_GFX_I 0x3CE /* Graphics Controller Index */
-#define VGA_SEQ_I 0x3C4 /* Sequencer Index */
-#define VGA_PEL_IW 0x3C8 /* PEL Write Index */
-#define VGA_PEL_IR 0x3C7 /* PEL Read Index */
-
-/* standard VGA indexes max counts */
-#define VGA_CRT_C 0x19 /* Number of CRT Controller Registers */
-#define VGA_ATT_C 0x15 /* Number of Attribute Controller Registers */
-#define VGA_GFX_C 0x09 /* Number of Graphics Controller Registers */
-#define VGA_SEQ_C 0x05 /* Number of Sequencer Registers */
-#define VGA_MIS_C 0x01 /* Number of Misc Output Register */
-
-/* VGA misc register bit masks */
-#define VGA_MIS_COLOR 0x01
-#define VGA_MIS_ENB_MEM_ACCESS 0x02
-#define VGA_MIS_DCLK_28322_720 0x04
-#define VGA_MIS_ENB_PLL_LOAD (0x04 | 0x08)
-#define VGA_MIS_SEL_HIGH_PAGE 0x20
-
-/* VGA CRT controller register indices */
-#define VGA_CRTC_H_TOTAL 0
-#define VGA_CRTC_H_DISP 1
-#define VGA_CRTC_H_BLANK_START 2
-#define VGA_CRTC_H_BLANK_END 3
-#define VGA_CRTC_H_SYNC_START 4
-#define VGA_CRTC_H_SYNC_END 5
-#define VGA_CRTC_V_TOTAL 6
-#define VGA_CRTC_OVERFLOW 7
-#define VGA_CRTC_PRESET_ROW 8
-#define VGA_CRTC_MAX_SCAN 9
-#define VGA_CRTC_CURSOR_START 0x0A
-#define VGA_CRTC_CURSOR_END 0x0B
-#define VGA_CRTC_START_HI 0x0C
-#define VGA_CRTC_START_LO 0x0D
-#define VGA_CRTC_CURSOR_HI 0x0E
-#define VGA_CRTC_CURSOR_LO 0x0F
-#define VGA_CRTC_V_SYNC_START 0x10
-#define VGA_CRTC_V_SYNC_END 0x11
-#define VGA_CRTC_V_DISP_END 0x12
-#define VGA_CRTC_OFFSET 0x13
-#define VGA_CRTC_UNDERLINE 0x14
-#define VGA_CRTC_V_BLANK_START 0x15
-#define VGA_CRTC_V_BLANK_END 0x16
-#define VGA_CRTC_MODE 0x17
-#define VGA_CRTC_LINE_COMPARE 0x18
-#define VGA_CRTC_REGS VGA_CRT_C
-
-/* VGA CRT controller bit masks */
-#define VGA_CR11_LOCK_CR0_CR7 0x80 /* lock writes to CR0 - CR7 */
-#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
-
-/* VGA attribute controller register indices */
-#define VGA_ATC_PALETTE0 0x00
-#define VGA_ATC_PALETTE1 0x01
-#define VGA_ATC_PALETTE2 0x02
-#define VGA_ATC_PALETTE3 0x03
-#define VGA_ATC_PALETTE4 0x04
-#define VGA_ATC_PALETTE5 0x05
-#define VGA_ATC_PALETTE6 0x06
-#define VGA_ATC_PALETTE7 0x07
-#define VGA_ATC_PALETTE8 0x08
-#define VGA_ATC_PALETTE9 0x09
-#define VGA_ATC_PALETTEA 0x0A
-#define VGA_ATC_PALETTEB 0x0B
-#define VGA_ATC_PALETTEC 0x0C
-#define VGA_ATC_PALETTED 0x0D
-#define VGA_ATC_PALETTEE 0x0E
-#define VGA_ATC_PALETTEF 0x0F
-#define VGA_ATC_MODE 0x10
-#define VGA_ATC_OVERSCAN 0x11
-#define VGA_ATC_PLANE_ENABLE 0x12
-#define VGA_ATC_PEL 0x13
-#define VGA_ATC_COLOR_PAGE 0x14
-
-#define VGA_AR_ENABLE_DISPLAY 0x20
-
-/* VGA sequencer register indices */
-#define VGA_SEQ_RESET 0x00
-#define VGA_SEQ_CLOCK_MODE 0x01
-#define VGA_SEQ_PLANE_WRITE 0x02
-#define VGA_SEQ_CHARACTER_MAP 0x03
-#define VGA_SEQ_MEMORY_MODE 0x04
-
-/* VGA sequencer register bit masks */
-#define VGA_SR01_CHAR_CLK_8DOTS 0x01 /* bit 0: character clocks 8 dots wide are generated */
-#define VGA_SR01_SCREEN_OFF 0x20 /* bit 5: Screen is off */
-#define VGA_SR02_ALL_PLANES 0x0F /* bits 3-0: enable access to all planes */
-#define VGA_SR04_EXT_MEM 0x02 /* bit 1: allows complete mem access to 256K */
-#define VGA_SR04_SEQ_MODE 0x04 /* bit 2: directs system to use a sequential addressing mode */
-#define VGA_SR04_CHN_4M 0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
-
-/* VGA graphics controller register indices */
-#define VGA_GFX_SR_VALUE 0x00
-#define VGA_GFX_SR_ENABLE 0x01
-#define VGA_GFX_COMPARE_VALUE 0x02
-#define VGA_GFX_DATA_ROTATE 0x03
-#define VGA_GFX_PLANE_READ 0x04
-#define VGA_GFX_MODE 0x05
-#define VGA_GFX_MISC 0x06
-#define VGA_GFX_COMPARE_MASK 0x07
-#define VGA_GFX_BIT_MASK 0x08
-
-/* VGA graphics controller bit masks */
-#define VGA_GR06_GRAPHICS_MODE 0x01
-
-#endif /* __linux_video_vga_h__ */
diff --git a/qemu/hw/display/vga_int.h b/qemu/hw/display/vga_int.h
deleted file mode 100644
index bdb43a5a3..000000000
--- a/qemu/hw/display/vga_int.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * QEMU internal VGA defines.
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * 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 HW_VGA_INT_H
-#define HW_VGA_INT_H 1
-
-#include <hw/hw.h>
-#include "exec/memory.h"
-
-#define ST01_V_RETRACE 0x08
-#define ST01_DISP_ENABLE 0x01
-
-#define VBE_DISPI_MAX_XRES 16000
-#define VBE_DISPI_MAX_YRES 12000
-#define VBE_DISPI_MAX_BPP 32
-
-#define VBE_DISPI_INDEX_ID 0x0
-#define VBE_DISPI_INDEX_XRES 0x1
-#define VBE_DISPI_INDEX_YRES 0x2
-#define VBE_DISPI_INDEX_BPP 0x3
-#define VBE_DISPI_INDEX_ENABLE 0x4
-#define VBE_DISPI_INDEX_BANK 0x5
-#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
-#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
-#define VBE_DISPI_INDEX_X_OFFSET 0x8
-#define VBE_DISPI_INDEX_Y_OFFSET 0x9
-#define VBE_DISPI_INDEX_NB 0xa /* size of vbe_regs[] */
-#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
-
-#define VBE_DISPI_ID0 0xB0C0
-#define VBE_DISPI_ID1 0xB0C1
-#define VBE_DISPI_ID2 0xB0C2
-#define VBE_DISPI_ID3 0xB0C3
-#define VBE_DISPI_ID4 0xB0C4
-#define VBE_DISPI_ID5 0xB0C5
-
-#define VBE_DISPI_DISABLED 0x00
-#define VBE_DISPI_ENABLED 0x01
-#define VBE_DISPI_GETCAPS 0x02
-#define VBE_DISPI_8BIT_DAC 0x20
-#define VBE_DISPI_LFB_ENABLED 0x40
-#define VBE_DISPI_NOCLEARMEM 0x80
-
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
-
-#define CH_ATTR_SIZE (160 * 100)
-#define VGA_MAX_HEIGHT 2048
-
-struct vga_precise_retrace {
- int64_t ticks_per_char;
- int64_t total_chars;
- int htotal;
- int hstart;
- int hend;
- int vstart;
- int vend;
- int freq;
-};
-
-union vga_retrace {
- struct vga_precise_retrace precise;
-};
-
-struct VGACommonState;
-typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s);
-typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
-
-typedef struct VGACommonState {
- MemoryRegion *legacy_address_space;
- uint8_t *vram_ptr;
- MemoryRegion vram;
- MemoryRegion vram_vbe;
- uint32_t vram_size;
- uint32_t vram_size_mb; /* property */
- uint32_t vbe_size;
- uint32_t latch;
- bool has_chain4_alias;
- MemoryRegion chain4_alias;
- uint8_t sr_index;
- uint8_t sr[256];
- uint8_t gr_index;
- uint8_t gr[256];
- uint8_t ar_index;
- uint8_t ar[21];
- int ar_flip_flop;
- uint8_t cr_index;
- uint8_t cr[256]; /* CRT registers */
- uint8_t msr; /* Misc Output Register */
- uint8_t fcr; /* Feature Control Register */
- uint8_t st00; /* status 0 */
- uint8_t st01; /* status 1 */
- uint8_t dac_state;
- uint8_t dac_sub_index;
- uint8_t dac_read_index;
- uint8_t dac_write_index;
- uint8_t dac_cache[3]; /* used when writing */
- int dac_8bit;
- uint8_t palette[768];
- int32_t bank_offset;
- int (*get_bpp)(struct VGACommonState *s);
- void (*get_offsets)(struct VGACommonState *s,
- uint32_t *pline_offset,
- uint32_t *pstart_addr,
- uint32_t *pline_compare);
- void (*get_resolution)(struct VGACommonState *s,
- int *pwidth,
- int *pheight);
- PortioList vga_port_list;
- PortioList vbe_port_list;
- /* bochs vbe state */
- uint16_t vbe_index;
- uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
- uint32_t vbe_start_addr;
- uint32_t vbe_line_offset;
- uint32_t vbe_bank_mask;
- int vbe_mapped;
- /* display refresh support */
- QemuConsole *con;
- uint32_t font_offsets[2];
- int graphic_mode;
- uint8_t shift_control;
- uint8_t double_scan;
- uint32_t line_offset;
- uint32_t line_compare;
- uint32_t start_addr;
- uint32_t plane_updated;
- uint32_t last_line_offset;
- uint8_t last_cw, last_ch;
- uint32_t last_width, last_height; /* in chars or pixels */
- uint32_t last_scr_width, last_scr_height; /* in pixels */
- uint32_t last_depth; /* in bits */
- bool last_byteswap;
- bool force_shadow;
- uint8_t cursor_start, cursor_end;
- bool cursor_visible_phase;
- int64_t cursor_blink_time;
- uint32_t cursor_offset;
- const GraphicHwOps *hw_ops;
- bool full_update_text;
- bool full_update_gfx;
- bool big_endian_fb;
- bool default_endian_fb;
- /* hardware mouse cursor support */
- uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
- uint32_t hw_cursor_x;
- uint32_t hw_cursor_y;
- void (*cursor_invalidate)(struct VGACommonState *s);
- void (*cursor_draw_line)(struct VGACommonState *s, uint8_t *d, int y);
- /* tell for each page if it has been updated since the last time */
- uint32_t last_palette[256];
- uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
- /* retrace */
- vga_retrace_fn retrace;
- vga_update_retrace_info_fn update_retrace_info;
- union vga_retrace retrace_info;
- uint8_t is_vbe_vmstate;
-} VGACommonState;
-
-static inline int c6_to_8(int v)
-{
- int b;
- v &= 0x3f;
- b = v & 1;
- return (v << 2) | (b << 1) | b;
-}
-
-void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate);
-void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
- MemoryRegion *address_space_io, bool init_vga_ports);
-MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
- const MemoryRegionPortio **vga_ports,
- 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);
-
-extern const VMStateDescription vmstate_vga_common;
-uint32_t vga_ioport_read(void *opaque, uint32_t addr);
-void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr);
-void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val);
-void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
-
-int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
-
-void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *address_space);
-uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr);
-void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val);
-void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val);
-
-extern const uint8_t sr_mask[8];
-extern const uint8_t gr_mask[16];
-
-#define VGABIOS_FILENAME "vgabios.bin"
-#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
-
-extern const MemoryRegionOps vga_mem_ops;
-
-/* vga-pci.c */
-void pci_std_vga_mmio_region_init(VGACommonState *s,
- MemoryRegion *parent,
- MemoryRegion *subs,
- bool qext);
-
-#endif
diff --git a/qemu/hw/display/virtio-gpu-3d.c b/qemu/hw/display/virtio-gpu-3d.c
deleted file mode 100644
index fa192946a..000000000
--- a/qemu/hw/display/virtio-gpu-3d.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Virtio GPU Device
- *
- * Copyright Red Hat, Inc. 2013-2014
- *
- * Authors:
- * Dave Airlie <airlied@redhat.com>
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/iov.h"
-#include "trace.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-gpu.h"
-
-#ifdef CONFIG_VIRGL
-
-#include "virglrenderer.h"
-
-static struct virgl_renderer_callbacks virtio_gpu_3d_cbs;
-
-static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_create_2d c2d;
- struct virgl_renderer_resource_create_args args;
-
- VIRTIO_GPU_FILL_CMD(c2d);
- trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
- c2d.width, c2d.height);
-
- args.handle = c2d.resource_id;
- args.target = 2;
- args.format = c2d.format;
- args.bind = (1 << 1);
- args.width = c2d.width;
- args.height = c2d.height;
- args.depth = 1;
- args.array_size = 1;
- args.last_level = 0;
- args.nr_samples = 0;
- args.flags = VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP;
- virgl_renderer_resource_create(&args, NULL, 0);
-}
-
-static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_create_3d c3d;
- struct virgl_renderer_resource_create_args args;
-
- VIRTIO_GPU_FILL_CMD(c3d);
- trace_virtio_gpu_cmd_res_create_3d(c3d.resource_id, c3d.format,
- c3d.width, c3d.height, c3d.depth);
-
- args.handle = c3d.resource_id;
- args.target = c3d.target;
- args.format = c3d.format;
- args.bind = c3d.bind;
- args.width = c3d.width;
- args.height = c3d.height;
- args.depth = c3d.depth;
- args.array_size = c3d.array_size;
- args.last_level = c3d.last_level;
- args.nr_samples = c3d.nr_samples;
- args.flags = c3d.flags;
- virgl_renderer_resource_create(&args, NULL, 0);
-}
-
-static void virgl_cmd_resource_unref(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_unref unref;
-
- VIRTIO_GPU_FILL_CMD(unref);
- trace_virtio_gpu_cmd_res_unref(unref.resource_id);
-
- virgl_renderer_resource_unref(unref.resource_id);
-}
-
-static void virgl_cmd_context_create(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_ctx_create cc;
-
- VIRTIO_GPU_FILL_CMD(cc);
- trace_virtio_gpu_cmd_ctx_create(cc.hdr.ctx_id,
- cc.debug_name);
-
- virgl_renderer_context_create(cc.hdr.ctx_id, cc.nlen,
- cc.debug_name);
-}
-
-static void virgl_cmd_context_destroy(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_ctx_destroy cd;
-
- VIRTIO_GPU_FILL_CMD(cd);
- trace_virtio_gpu_cmd_ctx_destroy(cd.hdr.ctx_id);
-
- virgl_renderer_context_destroy(cd.hdr.ctx_id);
-}
-
-static void virtio_gpu_rect_update(VirtIOGPU *g, int idx, int x, int y,
- int width, int height)
-{
- if (!g->scanout[idx].con) {
- return;
- }
-
- dpy_gl_update(g->scanout[idx].con, x, y, width, height);
-}
-
-static void virgl_cmd_resource_flush(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_flush rf;
- int i;
-
- VIRTIO_GPU_FILL_CMD(rf);
- trace_virtio_gpu_cmd_res_flush(rf.resource_id,
- rf.r.width, rf.r.height, rf.r.x, rf.r.y);
-
- for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
- if (g->scanout[i].resource_id != rf.resource_id) {
- continue;
- }
- virtio_gpu_rect_update(g, i, rf.r.x, rf.r.y, rf.r.width, rf.r.height);
- }
-}
-
-static void virgl_cmd_set_scanout(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_set_scanout ss;
- struct virgl_renderer_resource_info info;
- int ret;
-
- VIRTIO_GPU_FILL_CMD(ss);
- trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
- ss.r.width, ss.r.height, ss.r.x, ss.r.y);
-
- if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
- __func__, ss.scanout_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
- return;
- }
- g->enable = 1;
-
- memset(&info, 0, sizeof(info));
-
- if (ss.resource_id && ss.r.width && ss.r.height) {
- ret = virgl_renderer_resource_get_info(ss.resource_id, &info);
- if (ret == -1) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: illegal resource specified %d\n",
- __func__, ss.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
- qemu_console_resize(g->scanout[ss.scanout_id].con,
- ss.r.width, ss.r.height);
- virgl_renderer_force_ctx_0();
- dpy_gl_scanout(g->scanout[ss.scanout_id].con, info.tex_id,
- info.flags & 1 /* FIXME: Y_0_TOP */,
- ss.r.x, ss.r.y, ss.r.width, ss.r.height);
- } else {
- if (ss.scanout_id != 0) {
- dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);
- }
- dpy_gl_scanout(g->scanout[ss.scanout_id].con, 0, false,
- 0, 0, 0, 0);
- }
- g->scanout[ss.scanout_id].resource_id = ss.resource_id;
-}
-
-static void virgl_cmd_submit_3d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_cmd_submit cs;
- void *buf;
- size_t s;
-
- VIRTIO_GPU_FILL_CMD(cs);
- trace_virtio_gpu_cmd_ctx_submit(cs.hdr.ctx_id, cs.size);
-
- buf = g_malloc(cs.size);
- s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
- sizeof(cs), buf, cs.size);
- if (s != cs.size) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: size mismatch (%zd/%d)",
- __func__, s, cs.size);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- goto out;
- }
-
- if (virtio_gpu_stats_enabled(g->conf)) {
- g->stats.req_3d++;
- g->stats.bytes_3d += cs.size;
- }
-
- virgl_renderer_submit_cmd(buf, cs.hdr.ctx_id, cs.size / 4);
-
-out:
- g_free(buf);
-}
-
-static void virgl_cmd_transfer_to_host_2d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_transfer_to_host_2d t2d;
- struct virtio_gpu_box box;
-
- VIRTIO_GPU_FILL_CMD(t2d);
- trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
-
- box.x = t2d.r.x;
- box.y = t2d.r.y;
- box.z = 0;
- box.w = t2d.r.width;
- box.h = t2d.r.height;
- box.d = 1;
-
- virgl_renderer_transfer_write_iov(t2d.resource_id,
- 0,
- 0,
- 0,
- 0,
- (struct virgl_box *)&box,
- t2d.offset, NULL, 0);
-}
-
-static void virgl_cmd_transfer_to_host_3d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_transfer_host_3d t3d;
-
- VIRTIO_GPU_FILL_CMD(t3d);
- trace_virtio_gpu_cmd_res_xfer_toh_3d(t3d.resource_id);
-
- virgl_renderer_transfer_write_iov(t3d.resource_id,
- t3d.hdr.ctx_id,
- t3d.level,
- t3d.stride,
- t3d.layer_stride,
- (struct virgl_box *)&t3d.box,
- t3d.offset, NULL, 0);
-}
-
-static void
-virgl_cmd_transfer_from_host_3d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_transfer_host_3d tf3d;
-
- VIRTIO_GPU_FILL_CMD(tf3d);
- trace_virtio_gpu_cmd_res_xfer_fromh_3d(tf3d.resource_id);
-
- virgl_renderer_transfer_read_iov(tf3d.resource_id,
- tf3d.hdr.ctx_id,
- tf3d.level,
- tf3d.stride,
- tf3d.layer_stride,
- (struct virgl_box *)&tf3d.box,
- tf3d.offset, NULL, 0);
-}
-
-
-static void virgl_resource_attach_backing(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_attach_backing att_rb;
- struct iovec *res_iovs;
- int ret;
-
- VIRTIO_GPU_FILL_CMD(att_rb);
- trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id);
-
- ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, &res_iovs);
- if (ret != 0) {
- cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- return;
- }
-
- virgl_renderer_resource_attach_iov(att_rb.resource_id,
- res_iovs, att_rb.nr_entries);
-}
-
-static void virgl_resource_detach_backing(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resource_detach_backing detach_rb;
- struct iovec *res_iovs = NULL;
- int num_iovs = 0;
-
- VIRTIO_GPU_FILL_CMD(detach_rb);
- trace_virtio_gpu_cmd_res_back_detach(detach_rb.resource_id);
-
- virgl_renderer_resource_detach_iov(detach_rb.resource_id,
- &res_iovs,
- &num_iovs);
- if (res_iovs == NULL || num_iovs == 0) {
- return;
- }
- virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs);
-}
-
-
-static void virgl_cmd_ctx_attach_resource(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_ctx_resource att_res;
-
- VIRTIO_GPU_FILL_CMD(att_res);
- trace_virtio_gpu_cmd_ctx_res_attach(att_res.hdr.ctx_id,
- att_res.resource_id);
-
- virgl_renderer_ctx_attach_resource(att_res.hdr.ctx_id, att_res.resource_id);
-}
-
-static void virgl_cmd_ctx_detach_resource(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_ctx_resource det_res;
-
- VIRTIO_GPU_FILL_CMD(det_res);
- trace_virtio_gpu_cmd_ctx_res_detach(det_res.hdr.ctx_id,
- det_res.resource_id);
-
- virgl_renderer_ctx_detach_resource(det_res.hdr.ctx_id, det_res.resource_id);
-}
-
-static void virgl_cmd_get_capset_info(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_get_capset_info info;
- struct virtio_gpu_resp_capset_info resp;
-
- VIRTIO_GPU_FILL_CMD(info);
-
- if (info.capset_index == 0) {
- resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL;
- virgl_renderer_get_cap_set(resp.capset_id,
- &resp.capset_max_version,
- &resp.capset_max_size);
- } else {
- resp.capset_max_version = 0;
- resp.capset_max_size = 0;
- }
- resp.hdr.type = VIRTIO_GPU_RESP_OK_CAPSET_INFO;
- virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));
-}
-
-static void virgl_cmd_get_capset(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_get_capset gc;
- struct virtio_gpu_resp_capset *resp;
- uint32_t max_ver, max_size;
- VIRTIO_GPU_FILL_CMD(gc);
-
- virgl_renderer_get_cap_set(gc.capset_id, &max_ver,
- &max_size);
- resp = g_malloc(sizeof(*resp) + max_size);
-
- resp->hdr.type = VIRTIO_GPU_RESP_OK_CAPSET;
- virgl_renderer_fill_caps(gc.capset_id,
- gc.capset_version,
- (void *)resp->capset_data);
- virtio_gpu_ctrl_response(g, cmd, &resp->hdr, sizeof(*resp) + max_size);
- g_free(resp);
-}
-
-void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
-
- cmd->waiting = g->renderer_blocked;
- if (cmd->waiting) {
- return;
- }
-
- virgl_renderer_force_ctx_0();
- switch (cmd->cmd_hdr.type) {
- case VIRTIO_GPU_CMD_CTX_CREATE:
- virgl_cmd_context_create(g, cmd);
- break;
- case VIRTIO_GPU_CMD_CTX_DESTROY:
- virgl_cmd_context_destroy(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
- virgl_cmd_create_resource_2d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_CREATE_3D:
- virgl_cmd_create_resource_3d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_SUBMIT_3D:
- virgl_cmd_submit_3d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D:
- virgl_cmd_transfer_to_host_2d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D:
- virgl_cmd_transfer_to_host_3d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D:
- virgl_cmd_transfer_from_host_3d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
- virgl_resource_attach_backing(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING:
- virgl_resource_detach_backing(g, cmd);
- break;
- case VIRTIO_GPU_CMD_SET_SCANOUT:
- virgl_cmd_set_scanout(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_FLUSH:
- virgl_cmd_resource_flush(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_UNREF:
- virgl_cmd_resource_unref(g, cmd);
- break;
- case VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE:
- /* TODO add security */
- virgl_cmd_ctx_attach_resource(g, cmd);
- break;
- case VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE:
- /* TODO add security */
- virgl_cmd_ctx_detach_resource(g, cmd);
- break;
- case VIRTIO_GPU_CMD_GET_CAPSET_INFO:
- virgl_cmd_get_capset_info(g, cmd);
- break;
- case VIRTIO_GPU_CMD_GET_CAPSET:
- virgl_cmd_get_capset(g, cmd);
- break;
-
- case VIRTIO_GPU_CMD_GET_DISPLAY_INFO:
- virtio_gpu_get_display_info(g, cmd);
- break;
- default:
- cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- break;
- }
-
- if (cmd->finished) {
- return;
- }
- if (cmd->error) {
- fprintf(stderr, "%s: ctrl 0x%x, error 0x%x\n", __func__,
- cmd->cmd_hdr.type, cmd->error);
- virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error);
- return;
- }
- if (!(cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE)) {
- virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NODATA);
- return;
- }
-
- trace_virtio_gpu_fence_ctrl(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type);
- virgl_renderer_create_fence(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type);
-}
-
-static void virgl_write_fence(void *opaque, uint32_t fence)
-{
- VirtIOGPU *g = opaque;
- struct virtio_gpu_ctrl_command *cmd, *tmp;
-
- QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) {
- /*
- * the guest can end up emitting fences out of order
- * so we should check all fenced cmds not just the first one.
- */
- if (cmd->cmd_hdr.fence_id > fence) {
- continue;
- }
- 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->conf)) {
- fprintf(stderr, "inflight: %3d (-)\r", g->inflight);
- }
- }
-}
-
-static virgl_renderer_gl_context
-virgl_create_context(void *opaque, int scanout_idx,
- struct virgl_renderer_gl_ctx_param *params)
-{
- VirtIOGPU *g = opaque;
- QEMUGLContext ctx;
- QEMUGLParams qparams;
-
- qparams.major_ver = params->major_ver;
- qparams.minor_ver = params->minor_ver;
-
- ctx = dpy_gl_ctx_create(g->scanout[scanout_idx].con, &qparams);
- return (virgl_renderer_gl_context)ctx;
-}
-
-static void virgl_destroy_context(void *opaque, virgl_renderer_gl_context ctx)
-{
- VirtIOGPU *g = opaque;
- QEMUGLContext qctx = (QEMUGLContext)ctx;
-
- dpy_gl_ctx_destroy(g->scanout[0].con, qctx);
-}
-
-static int virgl_make_context_current(void *opaque, int scanout_idx,
- virgl_renderer_gl_context ctx)
-{
- VirtIOGPU *g = opaque;
- QEMUGLContext qctx = (QEMUGLContext)ctx;
-
- return dpy_gl_ctx_make_current(g->scanout[scanout_idx].con, qctx);
-}
-
-static struct virgl_renderer_callbacks virtio_gpu_3d_cbs = {
- .version = 1,
- .write_fence = virgl_write_fence,
- .create_gl_context = virgl_create_context,
- .destroy_gl_context = virgl_destroy_context,
- .make_current = virgl_make_context_current,
-};
-
-static void virtio_gpu_print_stats(void *opaque)
-{
- VirtIOGPU *g = opaque;
-
- if (g->stats.requests) {
- fprintf(stderr, "stats: vq req %4d, %3d -- 3D %4d (%5d)\n",
- g->stats.requests,
- g->stats.max_inflight,
- g->stats.req_3d,
- g->stats.bytes_3d);
- g->stats.requests = 0;
- g->stats.max_inflight = 0;
- g->stats.req_3d = 0;
- g->stats.bytes_3d = 0;
- } else {
- fprintf(stderr, "stats: idle\r");
- }
- timer_mod(g->print_stats, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
-}
-
-static void virtio_gpu_fence_poll(void *opaque)
-{
- VirtIOGPU *g = opaque;
-
- virgl_renderer_poll();
- virtio_gpu_process_cmdq(g);
- if (!QTAILQ_EMPTY(&g->cmdq) || !QTAILQ_EMPTY(&g->fenceq)) {
- timer_mod(g->fence_poll, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 10);
- }
-}
-
-void virtio_gpu_virgl_fence_poll(VirtIOGPU *g)
-{
- virtio_gpu_fence_poll(g);
-}
-
-void virtio_gpu_virgl_reset(VirtIOGPU *g)
-{
- int i;
-
- /* virgl_renderer_reset() ??? */
- for (i = 0; i < g->conf.max_outputs; i++) {
- if (i != 0) {
- dpy_gfx_replace_surface(g->scanout[i].con, NULL);
- }
- dpy_gl_scanout(g->scanout[i].con, 0, false, 0, 0, 0, 0);
- }
-}
-
-int virtio_gpu_virgl_init(VirtIOGPU *g)
-{
- int ret;
-
- ret = virgl_renderer_init(g, 0, &virtio_gpu_3d_cbs);
- if (ret != 0) {
- return ret;
- }
-
- g->fence_poll = timer_new_ms(QEMU_CLOCK_VIRTUAL,
- virtio_gpu_fence_poll, g);
-
- if (virtio_gpu_stats_enabled(g->conf)) {
- g->print_stats = timer_new_ms(QEMU_CLOCK_VIRTUAL,
- virtio_gpu_print_stats, g);
- timer_mod(g->print_stats, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
- }
- return 0;
-}
-
-#endif /* CONFIG_VIRGL */
diff --git a/qemu/hw/display/virtio-gpu-pci.c b/qemu/hw/display/virtio-gpu-pci.c
deleted file mode 100644
index a71b230d3..000000000
--- a/qemu/hw/display/virtio-gpu-pci.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Virtio video device
- *
- * Copyright Red Hat
- *
- * Authors:
- * Dave Airlie
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#include "qemu/osdep.h"
-#include "hw/pci/pci.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-bus.h"
-#include "hw/virtio/virtio-pci.h"
-#include "hw/virtio/virtio-gpu.h"
-
-static Property virtio_gpu_pci_properties[] = {
- DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
-{
- VirtIOGPUPCI *vgpu = VIRTIO_GPU_PCI(vpci_dev);
- VirtIOGPU *g = &vgpu->vdev;
- DeviceState *vdev = DEVICE(&vgpu->vdev);
- int i;
-
- qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
- /* force virtio-1.0 */
- vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
- vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
- object_property_set_bool(OBJECT(vdev), true, "realized", errp);
-
- for (i = 0; i < g->conf.max_outputs; i++) {
- object_property_set_link(OBJECT(g->scanout[i].con),
- OBJECT(vpci_dev),
- "device", errp);
- }
-}
-
-static void virtio_gpu_pci_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
- PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->props = virtio_gpu_pci_properties;
- k->realize = virtio_gpu_pci_realize;
- pcidev_k->class_id = PCI_CLASS_DISPLAY_OTHER;
-}
-
-static void virtio_gpu_initfn(Object *obj)
-{
- VirtIOGPUPCI *dev = VIRTIO_GPU_PCI(obj);
-
- virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
- TYPE_VIRTIO_GPU);
-}
-
-static const TypeInfo virtio_gpu_pci_info = {
- .name = TYPE_VIRTIO_GPU_PCI,
- .parent = TYPE_VIRTIO_PCI,
- .instance_size = sizeof(VirtIOGPUPCI),
- .instance_init = virtio_gpu_initfn,
- .class_init = virtio_gpu_pci_class_init,
-};
-
-static void virtio_gpu_pci_register_types(void)
-{
- type_register_static(&virtio_gpu_pci_info);
-}
-type_init(virtio_gpu_pci_register_types)
diff --git a/qemu/hw/display/virtio-gpu.c b/qemu/hw/display/virtio-gpu.c
deleted file mode 100644
index c181fb364..000000000
--- a/qemu/hw/display/virtio-gpu.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Virtio GPU Device
- *
- * Copyright Red Hat, Inc. 2013-2014
- *
- * Authors:
- * Dave Airlie <airlied@redhat.com>
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/iov.h"
-#include "ui/console.h"
-#include "trace.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-gpu.h"
-#include "hw/virtio/virtio-bus.h"
-
-static struct virtio_gpu_simple_resource*
-virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
-
-#ifdef CONFIG_VIRGL
-#include "virglrenderer.h"
-#define VIRGL(_g, _virgl, _simple, ...) \
- do { \
- if (_g->use_virgl_renderer) { \
- _virgl(__VA_ARGS__); \
- } else { \
- _simple(__VA_ARGS__); \
- } \
- } while (0)
-#else
-#define VIRGL(_g, _virgl, _simple, ...) \
- do { \
- _simple(__VA_ARGS__); \
- } while (0)
-#endif
-
-static void update_cursor_data_simple(VirtIOGPU *g,
- struct virtio_gpu_scanout *s,
- uint32_t resource_id)
-{
- struct virtio_gpu_simple_resource *res;
- uint32_t pixels;
-
- res = virtio_gpu_find_resource(g, resource_id);
- if (!res) {
- return;
- }
-
- if (pixman_image_get_width(res->image) != s->current_cursor->width ||
- pixman_image_get_height(res->image) != s->current_cursor->height) {
- return;
- }
-
- pixels = s->current_cursor->width * s->current_cursor->height;
- memcpy(s->current_cursor->data,
- pixman_image_get_data(res->image),
- pixels * sizeof(uint32_t));
-}
-
-#ifdef CONFIG_VIRGL
-
-static void update_cursor_data_virgl(VirtIOGPU *g,
- struct virtio_gpu_scanout *s,
- uint32_t resource_id)
-{
- uint32_t width, height;
- uint32_t pixels, *data;
-
- data = virgl_renderer_get_cursor_data(resource_id, &width, &height);
- if (!data) {
- return;
- }
-
- if (width != s->current_cursor->width ||
- height != s->current_cursor->height) {
- return;
- }
-
- pixels = s->current_cursor->width * s->current_cursor->height;
- memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t));
- free(data);
-}
-
-#endif
-
-static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
-{
- struct virtio_gpu_scanout *s;
- bool move = cursor->hdr.type != VIRTIO_GPU_CMD_MOVE_CURSOR;
-
- if (cursor->pos.scanout_id >= g->conf.max_outputs) {
- return;
- }
- s = &g->scanout[cursor->pos.scanout_id];
-
- trace_virtio_gpu_update_cursor(cursor->pos.scanout_id,
- cursor->pos.x,
- cursor->pos.y,
- move ? "move" : "update",
- cursor->resource_id);
-
- if (move) {
- if (!s->current_cursor) {
- s->current_cursor = cursor_alloc(64, 64);
- }
-
- s->current_cursor->hot_x = cursor->hot_x;
- s->current_cursor->hot_y = cursor->hot_y;
-
- if (cursor->resource_id > 0) {
- VIRGL(g, update_cursor_data_virgl, update_cursor_data_simple,
- g, s, cursor->resource_id);
- }
- dpy_cursor_define(s->con, s->current_cursor);
- }
- dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y,
- cursor->resource_id ? 1 : 0);
-}
-
-static void virtio_gpu_get_config(VirtIODevice *vdev, uint8_t *config)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- memcpy(config, &g->virtio_config, sizeof(g->virtio_config));
-}
-
-static void virtio_gpu_set_config(VirtIODevice *vdev, const uint8_t *config)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- struct virtio_gpu_config vgconfig;
-
- memcpy(&vgconfig, config, sizeof(g->virtio_config));
-
- if (vgconfig.events_clear) {
- g->virtio_config.events_read &= ~vgconfig.events_clear;
- }
-}
-
-static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features,
- Error **errp)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
-
- if (virtio_gpu_virgl_enabled(g->conf)) {
- features |= (1 << VIRTIO_GPU_F_VIRGL);
- }
- return features;
-}
-
-static void virtio_gpu_set_features(VirtIODevice *vdev, uint64_t features)
-{
- static const uint32_t virgl = (1 << VIRTIO_GPU_F_VIRGL);
- VirtIOGPU *g = VIRTIO_GPU(vdev);
-
- g->use_virgl_renderer = ((features & virgl) == virgl);
- trace_virtio_gpu_features(g->use_virgl_renderer);
-}
-
-static void virtio_gpu_notify_event(VirtIOGPU *g, uint32_t event_type)
-{
- g->virtio_config.events_read |= event_type;
- virtio_notify_config(&g->parent_obj);
-}
-
-static struct virtio_gpu_simple_resource *
-virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
-{
- struct virtio_gpu_simple_resource *res;
-
- QTAILQ_FOREACH(res, &g->reslist, next) {
- if (res->resource_id == resource_id) {
- return res;
- }
- }
- return NULL;
-}
-
-void virtio_gpu_ctrl_response(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd,
- struct virtio_gpu_ctrl_hdr *resp,
- size_t resp_len)
-{
- size_t s;
-
- if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE) {
- resp->flags |= VIRTIO_GPU_FLAG_FENCE;
- resp->fence_id = cmd->cmd_hdr.fence_id;
- resp->ctx_id = cmd->cmd_hdr.ctx_id;
- }
- s = iov_from_buf(cmd->elem.in_sg, cmd->elem.in_num, 0, resp, resp_len);
- if (s != resp_len) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: response size incorrect %zu vs %zu\n",
- __func__, s, resp_len);
- }
- virtqueue_push(cmd->vq, &cmd->elem, s);
- virtio_notify(VIRTIO_DEVICE(g), cmd->vq);
- cmd->finished = true;
-}
-
-void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd,
- enum virtio_gpu_ctrl_type type)
-{
- struct virtio_gpu_ctrl_hdr resp;
-
- memset(&resp, 0, sizeof(resp));
- resp.type = type;
- virtio_gpu_ctrl_response(g, cmd, &resp, sizeof(resp));
-}
-
-static void
-virtio_gpu_fill_display_info(VirtIOGPU *g,
- struct virtio_gpu_resp_display_info *dpy_info)
-{
- int i;
-
- for (i = 0; i < g->conf.max_outputs; i++) {
- if (g->enabled_output_bitmask & (1 << i)) {
- dpy_info->pmodes[i].enabled = 1;
- dpy_info->pmodes[i].r.width = g->req_state[i].width;
- dpy_info->pmodes[i].r.height = g->req_state[i].height;
- }
- }
-}
-
-void virtio_gpu_get_display_info(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_resp_display_info display_info;
-
- trace_virtio_gpu_cmd_get_display_info();
- memset(&display_info, 0, sizeof(display_info));
- display_info.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
- virtio_gpu_fill_display_info(g, &display_info);
- virtio_gpu_ctrl_response(g, cmd, &display_info.hdr,
- sizeof(display_info));
-}
-
-static pixman_format_code_t get_pixman_format(uint32_t virtio_gpu_format)
-{
- switch (virtio_gpu_format) {
-#ifdef HOST_WORDS_BIGENDIAN
- case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
- return PIXMAN_b8g8r8x8;
- case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
- return PIXMAN_b8g8r8a8;
- case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
- return PIXMAN_x8r8g8b8;
- case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
- return PIXMAN_a8r8g8b8;
- case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
- return PIXMAN_r8g8b8x8;
- case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
- return PIXMAN_r8g8b8a8;
- case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
- return PIXMAN_x8b8g8r8;
- case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
- return PIXMAN_a8b8g8r8;
-#else
- case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
- return PIXMAN_x8r8g8b8;
- case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
- return PIXMAN_a8r8g8b8;
- case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
- return PIXMAN_b8g8r8x8;
- case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
- return PIXMAN_b8g8r8a8;
- case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
- return PIXMAN_x8b8g8r8;
- case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
- return PIXMAN_a8b8g8r8;
- case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
- return PIXMAN_r8g8b8x8;
- case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
- return PIXMAN_r8g8b8a8;
-#endif
- default:
- return 0;
- }
-}
-
-static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- pixman_format_code_t pformat;
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_resource_create_2d c2d;
-
- VIRTIO_GPU_FILL_CMD(c2d);
- trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
- c2d.width, c2d.height);
-
- if (c2d.resource_id == 0) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
- __func__);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- res = virtio_gpu_find_resource(g, c2d.resource_id);
- if (res) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
- __func__, c2d.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- res = g_new0(struct virtio_gpu_simple_resource, 1);
-
- res->width = c2d.width;
- res->height = c2d.height;
- res->format = c2d.format;
- res->resource_id = c2d.resource_id;
-
- pformat = get_pixman_format(c2d.format);
- if (!pformat) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: host couldn't handle guest format %d\n",
- __func__, c2d.format);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- return;
- }
- res->image = pixman_image_create_bits(pformat,
- c2d.width,
- c2d.height,
- NULL, 0);
-
- if (!res->image) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: resource creation failed %d %d %d\n",
- __func__, c2d.resource_id, c2d.width, c2d.height);
- g_free(res);
- cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
- return;
- }
-
- QTAILQ_INSERT_HEAD(&g->reslist, res, next);
-}
-
-static void virtio_gpu_resource_destroy(VirtIOGPU *g,
- struct virtio_gpu_simple_resource *res)
-{
- pixman_image_unref(res->image);
- QTAILQ_REMOVE(&g->reslist, res, next);
- g_free(res);
-}
-
-static void virtio_gpu_resource_unref(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_resource_unref unref;
-
- VIRTIO_GPU_FILL_CMD(unref);
- trace_virtio_gpu_cmd_res_unref(unref.resource_id);
-
- res = virtio_gpu_find_resource(g, unref.resource_id);
- if (!res) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, unref.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
- virtio_gpu_resource_destroy(g, res);
-}
-
-static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- int h;
- uint32_t src_offset, dst_offset, stride;
- int bpp;
- pixman_format_code_t format;
- struct virtio_gpu_transfer_to_host_2d t2d;
-
- VIRTIO_GPU_FILL_CMD(t2d);
- trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
-
- res = virtio_gpu_find_resource(g, t2d.resource_id);
- if (!res || !res->iov) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, t2d.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- if (t2d.r.x > res->width ||
- t2d.r.y > res->height ||
- t2d.r.width > res->width ||
- t2d.r.height > res->height ||
- t2d.r.x + t2d.r.width > res->width ||
- t2d.r.y + t2d.r.height > res->height) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: transfer bounds outside resource"
- " bounds for resource %d: %d %d %d %d vs %d %d\n",
- __func__, t2d.resource_id, t2d.r.x, t2d.r.y,
- t2d.r.width, t2d.r.height, res->width, res->height);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- return;
- }
-
- format = pixman_image_get_format(res->image);
- bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;
- stride = pixman_image_get_stride(res->image);
-
- if (t2d.offset || t2d.r.x || t2d.r.y ||
- t2d.r.width != pixman_image_get_width(res->image)) {
- void *img_data = pixman_image_get_data(res->image);
- for (h = 0; h < t2d.r.height; h++) {
- src_offset = t2d.offset + stride * h;
- dst_offset = (t2d.r.y + h) * stride + (t2d.r.x * bpp);
-
- iov_to_buf(res->iov, res->iov_cnt, src_offset,
- (uint8_t *)img_data
- + dst_offset, t2d.r.width * bpp);
- }
- } else {
- iov_to_buf(res->iov, res->iov_cnt, 0,
- pixman_image_get_data(res->image),
- pixman_image_get_stride(res->image)
- * pixman_image_get_height(res->image));
- }
-}
-
-static void virtio_gpu_resource_flush(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_resource_flush rf;
- pixman_region16_t flush_region;
- int i;
-
- VIRTIO_GPU_FILL_CMD(rf);
- trace_virtio_gpu_cmd_res_flush(rf.resource_id,
- rf.r.width, rf.r.height, rf.r.x, rf.r.y);
-
- res = virtio_gpu_find_resource(g, rf.resource_id);
- if (!res) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, rf.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- if (rf.r.x > res->width ||
- rf.r.y > res->height ||
- rf.r.width > res->width ||
- rf.r.height > res->height ||
- rf.r.x + rf.r.width > res->width ||
- rf.r.y + rf.r.height > res->height) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
- " bounds for resource %d: %d %d %d %d vs %d %d\n",
- __func__, rf.resource_id, rf.r.x, rf.r.y,
- rf.r.width, rf.r.height, res->width, res->height);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- return;
- }
-
- pixman_region_init_rect(&flush_region,
- rf.r.x, rf.r.y, rf.r.width, rf.r.height);
- for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
- struct virtio_gpu_scanout *scanout;
- pixman_region16_t region, finalregion;
- pixman_box16_t *extents;
-
- if (!(res->scanout_bitmask & (1 << i))) {
- continue;
- }
- scanout = &g->scanout[i];
-
- pixman_region_init(&finalregion);
- pixman_region_init_rect(&region, scanout->x, scanout->y,
- scanout->width, scanout->height);
-
- pixman_region_intersect(&finalregion, &flush_region, &region);
- pixman_region_translate(&finalregion, -scanout->x, -scanout->y);
- extents = pixman_region_extents(&finalregion);
- /* work out the area we need to update for each console */
- dpy_gfx_update(g->scanout[i].con,
- extents->x1, extents->y1,
- extents->x2 - extents->x1,
- extents->y2 - extents->y1);
-
- pixman_region_fini(&region);
- pixman_region_fini(&finalregion);
- }
- pixman_region_fini(&flush_region);
-}
-
-static void virtio_gpu_set_scanout(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_scanout *scanout;
- pixman_format_code_t format;
- uint32_t offset;
- int bpp;
- struct virtio_gpu_set_scanout ss;
-
- VIRTIO_GPU_FILL_CMD(ss);
- trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
- ss.r.width, ss.r.height, ss.r.x, ss.r.y);
-
- g->enable = 1;
- if (ss.resource_id == 0) {
- scanout = &g->scanout[ss.scanout_id];
- if (scanout->resource_id) {
- res = virtio_gpu_find_resource(g, scanout->resource_id);
- if (res) {
- res->scanout_bitmask &= ~(1 << ss.scanout_id);
- }
- }
- if (ss.scanout_id == 0 ||
- ss.scanout_id >= g->conf.max_outputs) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: illegal scanout id specified %d",
- __func__, ss.scanout_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
- return;
- }
- dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);
- scanout->ds = NULL;
- scanout->width = 0;
- scanout->height = 0;
- return;
- }
-
- /* create a surface for this scanout */
- if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT ||
- ss.scanout_id >= g->conf.max_outputs) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
- __func__, ss.scanout_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
- return;
- }
-
- res = virtio_gpu_find_resource(g, ss.resource_id);
- if (!res) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, ss.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- if (ss.r.x > res->width ||
- ss.r.y > res->height ||
- ss.r.width > res->width ||
- ss.r.height > res->height ||
- ss.r.x + ss.r.width > res->width ||
- ss.r.y + ss.r.height > res->height) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
- " resource %d, (%d,%d)+%d,%d vs %d %d\n",
- __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,
- ss.r.width, ss.r.height, res->width, res->height);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- return;
- }
-
- scanout = &g->scanout[ss.scanout_id];
-
- format = pixman_image_get_format(res->image);
- bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;
- offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);
- if (!scanout->ds || surface_data(scanout->ds)
- != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
- scanout->width != ss.r.width ||
- scanout->height != ss.r.height) {
- /* realloc the surface ptr */
- scanout->ds = qemu_create_displaysurface_pixman(res->image);
- if (!scanout->ds) {
- cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- return;
- }
- dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds);
- }
-
- res->scanout_bitmask |= (1 << ss.scanout_id);
- scanout->resource_id = ss.resource_id;
- scanout->x = ss.r.x;
- scanout->y = ss.r.y;
- scanout->width = ss.r.width;
- scanout->height = ss.r.height;
-}
-
-int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
- struct virtio_gpu_ctrl_command *cmd,
- struct iovec **iov)
-{
- struct virtio_gpu_mem_entry *ents;
- size_t esize, s;
- int i;
-
- if (ab->nr_entries > 16384) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: nr_entries is too big (%d > 16384)\n",
- __func__, ab->nr_entries);
- return -1;
- }
-
- esize = sizeof(*ents) * ab->nr_entries;
- ents = g_malloc(esize);
- s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
- sizeof(*ab), ents, esize);
- if (s != esize) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: command data size incorrect %zu vs %zu\n",
- __func__, s, esize);
- g_free(ents);
- return -1;
- }
-
- *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries);
- for (i = 0; i < ab->nr_entries; i++) {
- hwaddr len = ents[i].length;
- (*iov)[i].iov_len = ents[i].length;
- (*iov)[i].iov_base = cpu_physical_memory_map(ents[i].addr, &len, 1);
- if (!(*iov)[i].iov_base || len != ents[i].length) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
- " resource %d element %d\n",
- __func__, ab->resource_id, i);
- virtio_gpu_cleanup_mapping_iov(*iov, i);
- g_free(ents);
- *iov = NULL;
- return -1;
- }
- }
- g_free(ents);
- return 0;
-}
-
-void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- cpu_physical_memory_unmap(iov[i].iov_base, iov[i].iov_len, 1,
- iov[i].iov_len);
- }
- g_free(iov);
-}
-
-static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res)
-{
- virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt);
- res->iov = NULL;
- res->iov_cnt = 0;
-}
-
-static void
-virtio_gpu_resource_attach_backing(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_resource_attach_backing ab;
- int ret;
-
- VIRTIO_GPU_FILL_CMD(ab);
- trace_virtio_gpu_cmd_res_back_attach(ab.resource_id);
-
- res = virtio_gpu_find_resource(g, ab.resource_id);
- if (!res) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, ab.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
-
- ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->iov);
- if (ret != 0) {
- cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- return;
- }
-
- res->iov_cnt = ab.nr_entries;
-}
-
-static void
-virtio_gpu_resource_detach_backing(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- struct virtio_gpu_simple_resource *res;
- struct virtio_gpu_resource_detach_backing detach;
-
- VIRTIO_GPU_FILL_CMD(detach);
- trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
-
- res = virtio_gpu_find_resource(g, detach.resource_id);
- if (!res || !res->iov) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
- __func__, detach.resource_id);
- cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
- return;
- }
- virtio_gpu_cleanup_mapping(res);
-}
-
-static void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
-{
- VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
-
- switch (cmd->cmd_hdr.type) {
- case VIRTIO_GPU_CMD_GET_DISPLAY_INFO:
- virtio_gpu_get_display_info(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
- virtio_gpu_resource_create_2d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_UNREF:
- virtio_gpu_resource_unref(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_FLUSH:
- virtio_gpu_resource_flush(g, cmd);
- break;
- case VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D:
- virtio_gpu_transfer_to_host_2d(g, cmd);
- break;
- case VIRTIO_GPU_CMD_SET_SCANOUT:
- virtio_gpu_set_scanout(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
- virtio_gpu_resource_attach_backing(g, cmd);
- break;
- case VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING:
- virtio_gpu_resource_detach_backing(g, cmd);
- break;
- default:
- cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- break;
- }
- if (!cmd->finished) {
- virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error :
- VIRTIO_GPU_RESP_OK_NODATA);
- }
-}
-
-static void virtio_gpu_handle_ctrl_cb(VirtIODevice *vdev, VirtQueue *vq)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- qemu_bh_schedule(g->ctrl_bh);
-}
-
-static void virtio_gpu_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *vq)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- qemu_bh_schedule(g->cursor_bh);
-}
-
-void virtio_gpu_process_cmdq(VirtIOGPU *g)
-{
- struct virtio_gpu_ctrl_command *cmd;
-
- while (!QTAILQ_EMPTY(&g->cmdq)) {
- cmd = QTAILQ_FIRST(&g->cmdq);
-
- /* process command */
- VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
- g, cmd);
- if (cmd->waiting) {
- break;
- }
- QTAILQ_REMOVE(&g->cmdq, cmd, next);
- if (virtio_gpu_stats_enabled(g->conf)) {
- g->stats.requests++;
- }
-
- if (!cmd->finished) {
- QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next);
- g->inflight++;
- if (virtio_gpu_stats_enabled(g->conf)) {
- if (g->stats.max_inflight < g->inflight) {
- g->stats.max_inflight = g->inflight;
- }
- fprintf(stderr, "inflight: %3d (+)\r", g->inflight);
- }
- } else {
- g_free(cmd);
- }
- }
-}
-
-static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- struct virtio_gpu_ctrl_command *cmd;
-
- if (!virtio_queue_ready(vq)) {
- return;
- }
-
-#ifdef CONFIG_VIRGL
- if (!g->renderer_inited && g->use_virgl_renderer) {
- virtio_gpu_virgl_init(g);
- g->renderer_inited = true;
- }
-#endif
-
- cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
- while (cmd) {
- cmd->vq = vq;
- cmd->error = 0;
- cmd->finished = false;
- cmd->waiting = false;
- QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
- cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
- }
-
- virtio_gpu_process_cmdq(g);
-
-#ifdef CONFIG_VIRGL
- if (g->use_virgl_renderer) {
- virtio_gpu_virgl_fence_poll(g);
- }
-#endif
-}
-
-static void virtio_gpu_ctrl_bh(void *opaque)
-{
- VirtIOGPU *g = opaque;
- virtio_gpu_handle_ctrl(&g->parent_obj, g->ctrl_vq);
-}
-
-static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- VirtQueueElement *elem;
- size_t s;
- struct virtio_gpu_update_cursor cursor_info;
-
- if (!virtio_queue_ready(vq)) {
- return;
- }
- for (;;) {
- elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
- if (!elem) {
- break;
- }
-
- s = iov_to_buf(elem->out_sg, elem->out_num, 0,
- &cursor_info, sizeof(cursor_info));
- if (s != sizeof(cursor_info)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: cursor size incorrect %zu vs %zu\n",
- __func__, s, sizeof(cursor_info));
- } else {
- update_cursor(g, &cursor_info);
- }
- virtqueue_push(vq, elem, 0);
- virtio_notify(vdev, vq);
- g_free(elem);
- }
-}
-
-static void virtio_gpu_cursor_bh(void *opaque)
-{
- VirtIOGPU *g = opaque;
- virtio_gpu_handle_cursor(&g->parent_obj, g->cursor_vq);
-}
-
-static void virtio_gpu_invalidate_display(void *opaque)
-{
-}
-
-static void virtio_gpu_update_display(void *opaque)
-{
-}
-
-static void virtio_gpu_text_update(void *opaque, console_ch_t *chardata)
-{
-}
-
-static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
-{
- VirtIOGPU *g = opaque;
-
- if (idx > g->conf.max_outputs) {
- return -1;
- }
-
- g->req_state[idx].x = info->xoff;
- g->req_state[idx].y = info->yoff;
- g->req_state[idx].width = info->width;
- g->req_state[idx].height = info->height;
-
- if (info->width && info->height) {
- g->enabled_output_bitmask |= (1 << idx);
- } else {
- g->enabled_output_bitmask &= ~(1 << idx);
- }
-
- /* send event to guest */
- virtio_gpu_notify_event(g, VIRTIO_GPU_EVENT_DISPLAY);
- return 0;
-}
-
-static void virtio_gpu_gl_block(void *opaque, bool block)
-{
- VirtIOGPU *g = opaque;
-
- g->renderer_blocked = block;
- if (!block) {
- virtio_gpu_process_cmdq(g);
- }
-}
-
-const GraphicHwOps virtio_gpu_ops = {
- .invalidate = virtio_gpu_invalidate_display,
- .gfx_update = virtio_gpu_update_display,
- .text_update = virtio_gpu_text_update,
- .ui_info = virtio_gpu_ui_info,
- .gl_block = virtio_gpu_gl_block,
-};
-
-static const VMStateDescription vmstate_virtio_gpu_unmigratable = {
- .name = "virtio-gpu",
- .unmigratable = 1,
-};
-
-static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
- VirtIOGPU *g = VIRTIO_GPU(qdev);
- bool have_virgl;
- int i;
-
- g->config_size = sizeof(struct virtio_gpu_config);
- g->virtio_config.num_scanouts = g->conf.max_outputs;
- virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
- g->config_size);
-
- g->req_state[0].width = 1024;
- g->req_state[0].height = 768;
-
- g->use_virgl_renderer = false;
-#if !defined(CONFIG_VIRGL) || defined(HOST_WORDS_BIGENDIAN)
- have_virgl = false;
-#else
- have_virgl = display_opengl;
-#endif
- if (!have_virgl) {
- g->conf.flags &= ~(1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED);
- }
-
- if (virtio_gpu_virgl_enabled(g->conf)) {
- /* use larger control queue in 3d mode */
- g->ctrl_vq = virtio_add_queue(vdev, 256, virtio_gpu_handle_ctrl_cb);
- g->cursor_vq = virtio_add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
- g->virtio_config.num_capsets = 1;
- } else {
- g->ctrl_vq = virtio_add_queue(vdev, 64, virtio_gpu_handle_ctrl_cb);
- g->cursor_vq = virtio_add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
- }
-
- g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
- g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
- QTAILQ_INIT(&g->reslist);
- QTAILQ_INIT(&g->cmdq);
- QTAILQ_INIT(&g->fenceq);
-
- g->enabled_output_bitmask = 1;
- g->qdev = qdev;
-
- for (i = 0; i < g->conf.max_outputs; i++) {
- g->scanout[i].con =
- graphic_console_init(DEVICE(g), i, &virtio_gpu_ops, g);
- if (i > 0) {
- dpy_gfx_replace_surface(g->scanout[i].con, NULL);
- }
- }
-
- vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g);
-}
-
-static void virtio_gpu_instance_init(Object *obj)
-{
-}
-
-static void virtio_gpu_reset(VirtIODevice *vdev)
-{
- VirtIOGPU *g = VIRTIO_GPU(vdev);
- struct virtio_gpu_simple_resource *res, *tmp;
- int i;
-
- g->enable = 0;
-
- QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
- virtio_gpu_resource_destroy(g, res);
- }
- for (i = 0; i < g->conf.max_outputs; i++) {
-#if 0
- g->req_state[i].x = 0;
- g->req_state[i].y = 0;
- if (i == 0) {
- g->req_state[0].width = 1024;
- g->req_state[0].height = 768;
- } else {
- g->req_state[i].width = 0;
- g->req_state[i].height = 0;
- }
-#endif
- g->scanout[i].resource_id = 0;
- g->scanout[i].width = 0;
- g->scanout[i].height = 0;
- g->scanout[i].x = 0;
- g->scanout[i].y = 0;
- g->scanout[i].ds = NULL;
- }
- g->enabled_output_bitmask = 1;
-
-#ifdef CONFIG_VIRGL
- if (g->use_virgl_renderer) {
- virtio_gpu_virgl_reset(g);
- g->use_virgl_renderer = 0;
- }
-#endif
-}
-
-static Property virtio_gpu_properties[] = {
- DEFINE_PROP_UINT32("max_outputs", VirtIOGPU, conf.max_outputs, 1),
-#ifdef CONFIG_VIRGL
- DEFINE_PROP_BIT("virgl", VirtIOGPU, conf.flags,
- VIRTIO_GPU_FLAG_VIRGL_ENABLED, true),
- DEFINE_PROP_BIT("stats", VirtIOGPU, conf.flags,
- VIRTIO_GPU_FLAG_STATS_ENABLED, false),
-#endif
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_gpu_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-
- vdc->realize = virtio_gpu_device_realize;
- vdc->get_config = virtio_gpu_get_config;
- vdc->set_config = virtio_gpu_set_config;
- vdc->get_features = virtio_gpu_get_features;
- vdc->set_features = virtio_gpu_set_features;
-
- vdc->reset = virtio_gpu_reset;
-
- dc->props = virtio_gpu_properties;
-}
-
-static const TypeInfo virtio_gpu_info = {
- .name = TYPE_VIRTIO_GPU,
- .parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(VirtIOGPU),
- .instance_init = virtio_gpu_instance_init,
- .class_init = virtio_gpu_class_init,
-};
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_gpu_info);
-}
-
-type_init(virtio_register_types)
-
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctrl_hdr) != 24);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_update_cursor) != 56);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_unref) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_2d) != 40);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_set_scanout) != 48);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_flush) != 48);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_to_host_2d) != 56);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_mem_entry) != 16);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_attach_backing) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_detach_backing) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_display_info) != 408);
-
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_host_3d) != 72);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_3d) != 72);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_create) != 96);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_destroy) != 24);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_resource) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_cmd_submit) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset_info) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset_info) != 40);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset) != 32);
-QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset) != 24);
diff --git a/qemu/hw/display/virtio-vga.c b/qemu/hw/display/virtio-vga.c
deleted file mode 100644
index e58b165ae..000000000
--- a/qemu/hw/display/virtio-vga.c
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/pci/pci.h"
-#include "ui/console.h"
-#include "vga_int.h"
-#include "hw/virtio/virtio-pci.h"
-
-/*
- * virtio-vga: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_VGA "virtio-vga"
-#define VIRTIO_VGA(obj) \
- OBJECT_CHECK(VirtIOVGA, (obj), TYPE_VIRTIO_VGA)
-
-typedef struct VirtIOVGA {
- VirtIOPCIProxy parent_obj;
- VirtIOGPU vdev;
- VGACommonState vga;
- MemoryRegion vga_mrs[3];
-} VirtIOVGA;
-
-static void virtio_vga_invalidate_display(void *opaque)
-{
- VirtIOVGA *vvga = opaque;
-
- if (vvga->vdev.enable) {
- virtio_gpu_ops.invalidate(&vvga->vdev);
- } else {
- vvga->vga.hw_ops->invalidate(&vvga->vga);
- }
-}
-
-static void virtio_vga_update_display(void *opaque)
-{
- VirtIOVGA *vvga = opaque;
-
- if (vvga->vdev.enable) {
- virtio_gpu_ops.gfx_update(&vvga->vdev);
- } else {
- vvga->vga.hw_ops->gfx_update(&vvga->vga);
- }
-}
-
-static void virtio_vga_text_update(void *opaque, console_ch_t *chardata)
-{
- VirtIOVGA *vvga = opaque;
-
- if (vvga->vdev.enable) {
- if (virtio_gpu_ops.text_update) {
- virtio_gpu_ops.text_update(&vvga->vdev, chardata);
- }
- } else {
- if (vvga->vga.hw_ops->text_update) {
- vvga->vga.hw_ops->text_update(&vvga->vga, chardata);
- }
- }
-}
-
-static int virtio_vga_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
-{
- VirtIOVGA *vvga = opaque;
-
- if (virtio_gpu_ops.ui_info) {
- return virtio_gpu_ops.ui_info(&vvga->vdev, idx, info);
- }
- return -1;
-}
-
-static void virtio_vga_gl_block(void *opaque, bool block)
-{
- VirtIOVGA *vvga = opaque;
-
- if (virtio_gpu_ops.gl_block) {
- virtio_gpu_ops.gl_block(&vvga->vdev, block);
- }
-}
-
-static const GraphicHwOps virtio_vga_ops = {
- .invalidate = virtio_vga_invalidate_display,
- .gfx_update = virtio_vga_update_display,
- .text_update = virtio_vga_text_update,
- .ui_info = virtio_vga_ui_info,
- .gl_block = virtio_vga_gl_block,
-};
-
-/* VGA device wrapper around PCI device around virtio GPU */
-static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
-{
- VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
- VirtIOGPU *g = &vvga->vdev;
- VGACommonState *vga = &vvga->vga;
- uint32_t offset;
- int i;
-
- /* init vga compat bits */
- vga->vram_size_mb = 8;
- vga_common_init(vga, OBJECT(vpci_dev), false);
- vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev),
- pci_address_space_io(&vpci_dev->pci_dev), true);
- pci_register_bar(&vpci_dev->pci_dev, 0,
- PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
-
- /*
- * Configure virtio bar and regions
- *
- * We use bar #2 for the mmio regions, to be compatible with stdvga.
- * virtio regions are moved to the end of bar #2, to make room for
- * the stdvga mmio registers at the start of bar #2.
- */
- vpci_dev->modern_mem_bar = 2;
- vpci_dev->msix_bar = 4;
- offset = memory_region_size(&vpci_dev->modern_bar);
- offset -= vpci_dev->notify.size;
- vpci_dev->notify.offset = offset;
- offset -= vpci_dev->device.size;
- vpci_dev->device.offset = offset;
- offset -= vpci_dev->isr.size;
- vpci_dev->isr.offset = offset;
- offset -= vpci_dev->common.size;
- vpci_dev->common.offset = offset;
-
- /* init virtio bits */
- qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
- /* force virtio-1.0 */
- vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
- vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
- object_property_set_bool(OBJECT(g), true, "realized", errp);
-
- /* add stdvga mmio regions */
- pci_std_vga_mmio_region_init(vga, &vpci_dev->modern_bar,
- vvga->vga_mrs, true);
-
- vga->con = g->scanout[0].con;
- graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);
-
- for (i = 0; i < g->conf.max_outputs; i++) {
- object_property_set_link(OBJECT(g->scanout[i].con),
- OBJECT(vpci_dev),
- "device", errp);
- }
-}
-
-static void virtio_vga_reset(DeviceState *dev)
-{
- VirtIOVGA *vvga = VIRTIO_VGA(dev);
- vvga->vdev.enable = 0;
-
- vga_dirty_log_start(&vvga->vga);
-}
-
-static Property virtio_vga_properties[] = {
- DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_vga_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
- PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
- dc->props = virtio_vga_properties;
- dc->reset = virtio_vga_reset;
- dc->hotpluggable = false;
-
- k->realize = virtio_vga_realize;
- pcidev_k->romfile = "vgabios-virtio.bin";
- pcidev_k->class_id = PCI_CLASS_DISPLAY_VGA;
-}
-
-static void virtio_vga_inst_initfn(Object *obj)
-{
- VirtIOVGA *dev = VIRTIO_VGA(obj);
-
- virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
- TYPE_VIRTIO_GPU);
-}
-
-static TypeInfo virtio_vga_info = {
- .name = TYPE_VIRTIO_VGA,
- .parent = TYPE_VIRTIO_PCI,
- .instance_size = sizeof(struct VirtIOVGA),
- .instance_init = virtio_vga_inst_initfn,
- .class_init = virtio_vga_class_init,
-};
-
-static void virtio_vga_register_types(void)
-{
- type_register_static(&virtio_vga_info);
-}
-
-type_init(virtio_vga_register_types)
diff --git a/qemu/hw/display/vmware_vga.c b/qemu/hw/display/vmware_vga.c
deleted file mode 100644
index 0c63fa851..000000000
--- a/qemu/hw/display/vmware_vga.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * QEMU VMware-SVGA "chipset".
- *
- * Copyright (c) 2007 Andrzej Zaborowski <balrog@zabor.org>
- *
- * 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 "trace.h"
-#include "ui/console.h"
-#include "ui/vnc.h"
-#include "hw/pci/pci.h"
-
-#undef VERBOSE
-#define HW_RECT_ACCEL
-#define HW_FILL_ACCEL
-#define HW_MOUSE_ACCEL
-
-#include "vga_int.h"
-
-/* See http://vmware-svga.sf.net/ for some documentation on VMWare SVGA */
-
-struct vmsvga_state_s {
- VGACommonState vga;
-
- int invalidated;
- int enable;
- int config;
- struct {
- int id;
- int x;
- int y;
- int on;
- } cursor;
-
- int index;
- int scratch_size;
- uint32_t *scratch;
- int new_width;
- int new_height;
- int new_depth;
- uint32_t guest;
- uint32_t svgaid;
- int syncing;
-
- MemoryRegion fifo_ram;
- uint8_t *fifo_ptr;
- unsigned int fifo_size;
-
- union {
- uint32_t *fifo;
- struct QEMU_PACKED {
- uint32_t min;
- uint32_t max;
- uint32_t next_cmd;
- uint32_t stop;
- /* Add registers here when adding capabilities. */
- uint32_t fifo[0];
- } *cmd;
- };
-
-#define REDRAW_FIFO_LEN 512
- struct vmsvga_rect_s {
- int x, y, w, h;
- } redraw_fifo[REDRAW_FIFO_LEN];
- int redraw_fifo_first, redraw_fifo_last;
-};
-
-#define TYPE_VMWARE_SVGA "vmware-svga"
-
-#define VMWARE_SVGA(obj) \
- OBJECT_CHECK(struct pci_vmsvga_state_s, (obj), TYPE_VMWARE_SVGA)
-
-struct pci_vmsvga_state_s {
- /*< private >*/
- PCIDevice parent_obj;
- /*< public >*/
-
- struct vmsvga_state_s chip;
- MemoryRegion io_bar;
-};
-
-#define SVGA_MAGIC 0x900000UL
-#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
-#define SVGA_ID_0 SVGA_MAKE_ID(0)
-#define SVGA_ID_1 SVGA_MAKE_ID(1)
-#define SVGA_ID_2 SVGA_MAKE_ID(2)
-
-#define SVGA_LEGACY_BASE_PORT 0x4560
-#define SVGA_INDEX_PORT 0x0
-#define SVGA_VALUE_PORT 0x1
-#define SVGA_BIOS_PORT 0x2
-
-#define SVGA_VERSION_2
-
-#ifdef SVGA_VERSION_2
-# define SVGA_ID SVGA_ID_2
-# define SVGA_IO_BASE SVGA_LEGACY_BASE_PORT
-# define SVGA_IO_MUL 1
-# define SVGA_FIFO_SIZE 0x10000
-# define SVGA_PCI_DEVICE_ID PCI_DEVICE_ID_VMWARE_SVGA2
-#else
-# define SVGA_ID SVGA_ID_1
-# define SVGA_IO_BASE SVGA_LEGACY_BASE_PORT
-# define SVGA_IO_MUL 4
-# define SVGA_FIFO_SIZE 0x10000
-# define SVGA_PCI_DEVICE_ID PCI_DEVICE_ID_VMWARE_SVGA
-#endif
-
-enum {
- /* ID 0, 1 and 2 registers */
- SVGA_REG_ID = 0,
- SVGA_REG_ENABLE = 1,
- SVGA_REG_WIDTH = 2,
- SVGA_REG_HEIGHT = 3,
- SVGA_REG_MAX_WIDTH = 4,
- SVGA_REG_MAX_HEIGHT = 5,
- SVGA_REG_DEPTH = 6,
- SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
- SVGA_REG_PSEUDOCOLOR = 8,
- SVGA_REG_RED_MASK = 9,
- SVGA_REG_GREEN_MASK = 10,
- SVGA_REG_BLUE_MASK = 11,
- SVGA_REG_BYTES_PER_LINE = 12,
- SVGA_REG_FB_START = 13,
- SVGA_REG_FB_OFFSET = 14,
- SVGA_REG_VRAM_SIZE = 15,
- SVGA_REG_FB_SIZE = 16,
-
- /* ID 1 and 2 registers */
- SVGA_REG_CAPABILITIES = 17,
- SVGA_REG_MEM_START = 18, /* Memory for command FIFO */
- SVGA_REG_MEM_SIZE = 19,
- SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
- SVGA_REG_SYNC = 21, /* Write to force synchronization */
- SVGA_REG_BUSY = 22, /* Read to check if sync is done */
- SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
- SVGA_REG_CURSOR_ID = 24, /* ID of cursor */
- SVGA_REG_CURSOR_X = 25, /* Set cursor X position */
- SVGA_REG_CURSOR_Y = 26, /* Set cursor Y position */
- SVGA_REG_CURSOR_ON = 27, /* Turn cursor on/off */
- SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* Current bpp in the host */
- SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */
- SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */
- SVGA_REG_NUM_DISPLAYS = 31, /* Number of guest displays */
- SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */
-
- SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
- SVGA_PALETTE_END = SVGA_PALETTE_BASE + 767,
- SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + 768,
-};
-
-#define SVGA_CAP_NONE 0
-#define SVGA_CAP_RECT_FILL (1 << 0)
-#define SVGA_CAP_RECT_COPY (1 << 1)
-#define SVGA_CAP_RECT_PAT_FILL (1 << 2)
-#define SVGA_CAP_LEGACY_OFFSCREEN (1 << 3)
-#define SVGA_CAP_RASTER_OP (1 << 4)
-#define SVGA_CAP_CURSOR (1 << 5)
-#define SVGA_CAP_CURSOR_BYPASS (1 << 6)
-#define SVGA_CAP_CURSOR_BYPASS_2 (1 << 7)
-#define SVGA_CAP_8BIT_EMULATION (1 << 8)
-#define SVGA_CAP_ALPHA_CURSOR (1 << 9)
-#define SVGA_CAP_GLYPH (1 << 10)
-#define SVGA_CAP_GLYPH_CLIPPING (1 << 11)
-#define SVGA_CAP_OFFSCREEN_1 (1 << 12)
-#define SVGA_CAP_ALPHA_BLEND (1 << 13)
-#define SVGA_CAP_3D (1 << 14)
-#define SVGA_CAP_EXTENDED_FIFO (1 << 15)
-#define SVGA_CAP_MULTIMON (1 << 16)
-#define SVGA_CAP_PITCHLOCK (1 << 17)
-
-/*
- * FIFO offsets (seen as an array of 32-bit words)
- */
-enum {
- /*
- * The original defined FIFO offsets
- */
- SVGA_FIFO_MIN = 0,
- SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */
- SVGA_FIFO_NEXT_CMD,
- SVGA_FIFO_STOP,
-
- /*
- * Additional offsets added as of SVGA_CAP_EXTENDED_FIFO
- */
- SVGA_FIFO_CAPABILITIES = 4,
- SVGA_FIFO_FLAGS,
- SVGA_FIFO_FENCE,
- SVGA_FIFO_3D_HWVERSION,
- SVGA_FIFO_PITCHLOCK,
-};
-
-#define SVGA_FIFO_CAP_NONE 0
-#define SVGA_FIFO_CAP_FENCE (1 << 0)
-#define SVGA_FIFO_CAP_ACCELFRONT (1 << 1)
-#define SVGA_FIFO_CAP_PITCHLOCK (1 << 2)
-
-#define SVGA_FIFO_FLAG_NONE 0
-#define SVGA_FIFO_FLAG_ACCELFRONT (1 << 0)
-
-/* These values can probably be changed arbitrarily. */
-#define SVGA_SCRATCH_SIZE 0x8000
-#define SVGA_MAX_WIDTH ROUND_UP(2360, VNC_DIRTY_PIXELS_PER_BIT)
-#define SVGA_MAX_HEIGHT 1770
-
-#ifdef VERBOSE
-# define GUEST_OS_BASE 0x5001
-static const char *vmsvga_guest_id[] = {
- [0x00] = "Dos",
- [0x01] = "Windows 3.1",
- [0x02] = "Windows 95",
- [0x03] = "Windows 98",
- [0x04] = "Windows ME",
- [0x05] = "Windows NT",
- [0x06] = "Windows 2000",
- [0x07] = "Linux",
- [0x08] = "OS/2",
- [0x09] = "an unknown OS",
- [0x0a] = "BSD",
- [0x0b] = "Whistler",
- [0x0c] = "an unknown OS",
- [0x0d] = "an unknown OS",
- [0x0e] = "an unknown OS",
- [0x0f] = "an unknown OS",
- [0x10] = "an unknown OS",
- [0x11] = "an unknown OS",
- [0x12] = "an unknown OS",
- [0x13] = "an unknown OS",
- [0x14] = "an unknown OS",
- [0x15] = "Windows 2003",
-};
-#endif
-
-enum {
- SVGA_CMD_INVALID_CMD = 0,
- SVGA_CMD_UPDATE = 1,
- SVGA_CMD_RECT_FILL = 2,
- SVGA_CMD_RECT_COPY = 3,
- SVGA_CMD_DEFINE_BITMAP = 4,
- SVGA_CMD_DEFINE_BITMAP_SCANLINE = 5,
- SVGA_CMD_DEFINE_PIXMAP = 6,
- SVGA_CMD_DEFINE_PIXMAP_SCANLINE = 7,
- SVGA_CMD_RECT_BITMAP_FILL = 8,
- SVGA_CMD_RECT_PIXMAP_FILL = 9,
- SVGA_CMD_RECT_BITMAP_COPY = 10,
- SVGA_CMD_RECT_PIXMAP_COPY = 11,
- SVGA_CMD_FREE_OBJECT = 12,
- SVGA_CMD_RECT_ROP_FILL = 13,
- SVGA_CMD_RECT_ROP_COPY = 14,
- SVGA_CMD_RECT_ROP_BITMAP_FILL = 15,
- SVGA_CMD_RECT_ROP_PIXMAP_FILL = 16,
- SVGA_CMD_RECT_ROP_BITMAP_COPY = 17,
- SVGA_CMD_RECT_ROP_PIXMAP_COPY = 18,
- SVGA_CMD_DEFINE_CURSOR = 19,
- SVGA_CMD_DISPLAY_CURSOR = 20,
- SVGA_CMD_MOVE_CURSOR = 21,
- SVGA_CMD_DEFINE_ALPHA_CURSOR = 22,
- SVGA_CMD_DRAW_GLYPH = 23,
- SVGA_CMD_DRAW_GLYPH_CLIPPED = 24,
- SVGA_CMD_UPDATE_VERBOSE = 25,
- SVGA_CMD_SURFACE_FILL = 26,
- SVGA_CMD_SURFACE_COPY = 27,
- SVGA_CMD_SURFACE_ALPHA_BLEND = 28,
- SVGA_CMD_FRONT_ROP_FILL = 29,
- SVGA_CMD_FENCE = 30,
-};
-
-/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
-enum {
- SVGA_CURSOR_ON_HIDE = 0,
- SVGA_CURSOR_ON_SHOW = 1,
- SVGA_CURSOR_ON_REMOVE_FROM_FB = 2,
- SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
-};
-
-static inline bool vmsvga_verify_rect(DisplaySurface *surface,
- const char *name,
- int x, int y, int w, int h)
-{
- if (x < 0) {
- fprintf(stderr, "%s: x was < 0 (%d)\n", name, x);
- return false;
- }
- if (x > SVGA_MAX_WIDTH) {
- fprintf(stderr, "%s: x was > %d (%d)\n", name, SVGA_MAX_WIDTH, x);
- return false;
- }
- if (w < 0) {
- fprintf(stderr, "%s: w was < 0 (%d)\n", name, w);
- return false;
- }
- if (w > SVGA_MAX_WIDTH) {
- fprintf(stderr, "%s: w was > %d (%d)\n", name, SVGA_MAX_WIDTH, w);
- return false;
- }
- if (x + w > surface_width(surface)) {
- fprintf(stderr, "%s: width was > %d (x: %d, w: %d)\n",
- name, surface_width(surface), x, w);
- return false;
- }
-
- if (y < 0) {
- fprintf(stderr, "%s: y was < 0 (%d)\n", name, y);
- return false;
- }
- if (y > SVGA_MAX_HEIGHT) {
- fprintf(stderr, "%s: y was > %d (%d)\n", name, SVGA_MAX_HEIGHT, y);
- return false;
- }
- if (h < 0) {
- fprintf(stderr, "%s: h was < 0 (%d)\n", name, h);
- return false;
- }
- if (h > SVGA_MAX_HEIGHT) {
- fprintf(stderr, "%s: h was > %d (%d)\n", name, SVGA_MAX_HEIGHT, h);
- return false;
- }
- if (y + h > surface_height(surface)) {
- fprintf(stderr, "%s: update height > %d (y: %d, h: %d)\n",
- name, surface_height(surface), y, h);
- return false;
- }
-
- return true;
-}
-
-static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
- int x, int y, int w, int h)
-{
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
- int line;
- int bypl;
- int width;
- int start;
- uint8_t *src;
- uint8_t *dst;
-
- if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
- /* go for a fullscreen update as fallback */
- x = 0;
- y = 0;
- w = surface_width(surface);
- h = surface_height(surface);
- }
-
- bypl = surface_stride(surface);
- width = surface_bytes_per_pixel(surface) * w;
- start = surface_bytes_per_pixel(surface) * x + bypl * y;
- src = s->vga.vram_ptr + start;
- dst = surface_data(surface) + start;
-
- for (line = h; line > 0; line--, src += bypl, dst += bypl) {
- memcpy(dst, src, width);
- }
- dpy_gfx_update(s->vga.con, x, y, w, h);
-}
-
-static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
- int x, int y, int w, int h)
-{
- struct vmsvga_rect_s *rect = &s->redraw_fifo[s->redraw_fifo_last++];
-
- s->redraw_fifo_last &= REDRAW_FIFO_LEN - 1;
- rect->x = x;
- rect->y = y;
- rect->w = w;
- rect->h = h;
-}
-
-static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
-{
- struct vmsvga_rect_s *rect;
-
- if (s->invalidated) {
- s->redraw_fifo_first = s->redraw_fifo_last;
- return;
- }
- /* Overlapping region updates can be optimised out here - if someone
- * knows a smart algorithm to do that, please share. */
- while (s->redraw_fifo_first != s->redraw_fifo_last) {
- rect = &s->redraw_fifo[s->redraw_fifo_first++];
- s->redraw_fifo_first &= REDRAW_FIFO_LEN - 1;
- vmsvga_update_rect(s, rect->x, rect->y, rect->w, rect->h);
- }
-}
-
-#ifdef HW_RECT_ACCEL
-static inline int vmsvga_copy_rect(struct vmsvga_state_s *s,
- int x0, int y0, int x1, int y1, int w, int h)
-{
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
- uint8_t *vram = s->vga.vram_ptr;
- int bypl = surface_stride(surface);
- int bypp = surface_bytes_per_pixel(surface);
- int width = bypp * w;
- int line = h;
- uint8_t *ptr[2];
-
- if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/src", x0, y0, w, h)) {
- return -1;
- }
- if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/dst", x1, y1, w, h)) {
- return -1;
- }
-
- if (y1 > y0) {
- ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);
- ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);
- for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) {
- memmove(ptr[1], ptr[0], width);
- }
- } else {
- ptr[0] = vram + bypp * x0 + bypl * y0;
- ptr[1] = vram + bypp * x1 + bypl * y1;
- for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) {
- memmove(ptr[1], ptr[0], width);
- }
- }
-
- vmsvga_update_rect_delayed(s, x1, y1, w, h);
- return 0;
-}
-#endif
-
-#ifdef HW_FILL_ACCEL
-static inline int vmsvga_fill_rect(struct vmsvga_state_s *s,
- uint32_t c, int x, int y, int w, int h)
-{
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
- int bypl = surface_stride(surface);
- int width = surface_bytes_per_pixel(surface) * w;
- int line = h;
- int column;
- uint8_t *fst;
- uint8_t *dst;
- uint8_t *src;
- uint8_t col[4];
-
- if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
- return -1;
- }
-
- col[0] = c;
- col[1] = c >> 8;
- col[2] = c >> 16;
- col[3] = c >> 24;
-
- fst = s->vga.vram_ptr + surface_bytes_per_pixel(surface) * x + bypl * y;
-
- if (line--) {
- dst = fst;
- src = col;
- for (column = width; column > 0; column--) {
- *(dst++) = *(src++);
- if (src - col == surface_bytes_per_pixel(surface)) {
- src = col;
- }
- }
- dst = fst;
- for (; line > 0; line--) {
- dst += bypl;
- memcpy(dst, fst, width);
- }
- }
-
- vmsvga_update_rect_delayed(s, x, y, w, h);
- return 0;
-}
-#endif
-
-struct vmsvga_cursor_definition_s {
- uint32_t width;
- uint32_t height;
- int id;
- uint32_t bpp;
- int hot_x;
- int hot_y;
- uint32_t mask[1024];
- uint32_t image[4096];
-};
-
-#define SVGA_BITMAP_SIZE(w, h) ((((w) + 31) >> 5) * (h))
-#define SVGA_PIXMAP_SIZE(w, h, bpp) (((((w) * (bpp)) + 31) >> 5) * (h))
-
-#ifdef HW_MOUSE_ACCEL
-static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
- struct vmsvga_cursor_definition_s *c)
-{
- QEMUCursor *qc;
- int i, pixels;
-
- qc = cursor_alloc(c->width, c->height);
- qc->hot_x = c->hot_x;
- qc->hot_y = c->hot_y;
- switch (c->bpp) {
- case 1:
- cursor_set_mono(qc, 0xffffff, 0x000000, (void *)c->image,
- 1, (void *)c->mask);
-#ifdef DEBUG
- cursor_print_ascii_art(qc, "vmware/mono");
-#endif
- break;
- case 32:
- /* fill alpha channel from mask, set color to zero */
- cursor_set_mono(qc, 0x000000, 0x000000, (void *)c->mask,
- 1, (void *)c->mask);
- /* add in rgb values */
- pixels = c->width * c->height;
- for (i = 0; i < pixels; i++) {
- qc->data[i] |= c->image[i] & 0xffffff;
- }
-#ifdef DEBUG
- cursor_print_ascii_art(qc, "vmware/32bit");
-#endif
- break;
- default:
- fprintf(stderr, "%s: unhandled bpp %d, using fallback cursor\n",
- __func__, c->bpp);
- cursor_put(qc);
- qc = cursor_builtin_left_ptr();
- }
-
- dpy_cursor_define(s->vga.con, qc);
- cursor_put(qc);
-}
-#endif
-
-#define CMD(f) le32_to_cpu(s->cmd->f)
-
-static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
-{
- int num;
-
- if (!s->config || !s->enable) {
- return 0;
- }
- num = CMD(next_cmd) - CMD(stop);
- if (num < 0) {
- num += CMD(max) - CMD(min);
- }
- return num >> 2;
-}
-
-static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
-{
- uint32_t cmd = s->fifo[CMD(stop) >> 2];
-
- s->cmd->stop = cpu_to_le32(CMD(stop) + 4);
- if (CMD(stop) >= CMD(max)) {
- s->cmd->stop = s->cmd->min;
- }
- return cmd;
-}
-
-static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
-{
- return le32_to_cpu(vmsvga_fifo_read_raw(s));
-}
-
-static void vmsvga_fifo_run(struct vmsvga_state_s *s)
-{
- uint32_t cmd, colour;
- int args, len;
- int x, y, dx, dy, width, height;
- struct vmsvga_cursor_definition_s cursor;
- uint32_t cmd_start;
-
- len = vmsvga_fifo_length(s);
- while (len > 0) {
- /* May need to go back to the start of the command if incomplete */
- cmd_start = s->cmd->stop;
-
- switch (cmd = vmsvga_fifo_read(s)) {
- case SVGA_CMD_UPDATE:
- case SVGA_CMD_UPDATE_VERBOSE:
- len -= 5;
- if (len < 0) {
- goto rewind;
- }
-
- x = vmsvga_fifo_read(s);
- y = vmsvga_fifo_read(s);
- width = vmsvga_fifo_read(s);
- height = vmsvga_fifo_read(s);
- vmsvga_update_rect_delayed(s, x, y, width, height);
- break;
-
- case SVGA_CMD_RECT_FILL:
- len -= 6;
- if (len < 0) {
- goto rewind;
- }
-
- colour = vmsvga_fifo_read(s);
- x = vmsvga_fifo_read(s);
- y = vmsvga_fifo_read(s);
- width = vmsvga_fifo_read(s);
- height = vmsvga_fifo_read(s);
-#ifdef HW_FILL_ACCEL
- if (vmsvga_fill_rect(s, colour, x, y, width, height) == 0) {
- break;
- }
-#endif
- args = 0;
- goto badcmd;
-
- case SVGA_CMD_RECT_COPY:
- len -= 7;
- if (len < 0) {
- goto rewind;
- }
-
- x = vmsvga_fifo_read(s);
- y = vmsvga_fifo_read(s);
- dx = vmsvga_fifo_read(s);
- dy = vmsvga_fifo_read(s);
- width = vmsvga_fifo_read(s);
- height = vmsvga_fifo_read(s);
-#ifdef HW_RECT_ACCEL
- if (vmsvga_copy_rect(s, x, y, dx, dy, width, height) == 0) {
- break;
- }
-#endif
- args = 0;
- goto badcmd;
-
- case SVGA_CMD_DEFINE_CURSOR:
- len -= 8;
- if (len < 0) {
- goto rewind;
- }
-
- cursor.id = vmsvga_fifo_read(s);
- cursor.hot_x = vmsvga_fifo_read(s);
- cursor.hot_y = vmsvga_fifo_read(s);
- cursor.width = x = vmsvga_fifo_read(s);
- cursor.height = y = vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- cursor.bpp = vmsvga_fifo_read(s);
-
- args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
- if (cursor.width > 256 ||
- cursor.height > 256 ||
- cursor.bpp > 32 ||
- SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
- SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
- goto badcmd;
- }
-
- len -= args;
- if (len < 0) {
- goto rewind;
- }
-
- for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args++) {
- cursor.mask[args] = vmsvga_fifo_read_raw(s);
- }
- for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args++) {
- cursor.image[args] = vmsvga_fifo_read_raw(s);
- }
-#ifdef HW_MOUSE_ACCEL
- vmsvga_cursor_define(s, &cursor);
- break;
-#else
- args = 0;
- goto badcmd;
-#endif
-
- /*
- * Other commands that we at least know the number of arguments
- * for so we can avoid FIFO desync if driver uses them illegally.
- */
- case SVGA_CMD_DEFINE_ALPHA_CURSOR:
- len -= 6;
- if (len < 0) {
- goto rewind;
- }
- vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- x = vmsvga_fifo_read(s);
- y = vmsvga_fifo_read(s);
- args = x * y;
- goto badcmd;
- case SVGA_CMD_RECT_ROP_FILL:
- args = 6;
- goto badcmd;
- case SVGA_CMD_RECT_ROP_COPY:
- args = 7;
- goto badcmd;
- case SVGA_CMD_DRAW_GLYPH_CLIPPED:
- len -= 4;
- if (len < 0) {
- goto rewind;
- }
- vmsvga_fifo_read(s);
- vmsvga_fifo_read(s);
- args = 7 + (vmsvga_fifo_read(s) >> 2);
- goto badcmd;
- case SVGA_CMD_SURFACE_ALPHA_BLEND:
- args = 12;
- goto badcmd;
-
- /*
- * Other commands that are not listed as depending on any
- * CAPABILITIES bits, but are not described in the README either.
- */
- case SVGA_CMD_SURFACE_FILL:
- case SVGA_CMD_SURFACE_COPY:
- case SVGA_CMD_FRONT_ROP_FILL:
- case SVGA_CMD_FENCE:
- case SVGA_CMD_INVALID_CMD:
- break; /* Nop */
-
- default:
- args = 0;
- badcmd:
- len -= args;
- if (len < 0) {
- goto rewind;
- }
- while (args--) {
- vmsvga_fifo_read(s);
- }
- printf("%s: Unknown command 0x%02x in SVGA command FIFO\n",
- __func__, cmd);
- break;
-
- rewind:
- s->cmd->stop = cmd_start;
- break;
- }
- }
-
- s->syncing = 0;
-}
-
-static uint32_t vmsvga_index_read(void *opaque, uint32_t address)
-{
- struct vmsvga_state_s *s = opaque;
-
- return s->index;
-}
-
-static void vmsvga_index_write(void *opaque, uint32_t address, uint32_t index)
-{
- struct vmsvga_state_s *s = opaque;
-
- s->index = index;
-}
-
-static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
-{
- uint32_t caps;
- struct vmsvga_state_s *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
- PixelFormat pf;
- uint32_t ret;
-
- switch (s->index) {
- case SVGA_REG_ID:
- ret = s->svgaid;
- break;
-
- case SVGA_REG_ENABLE:
- ret = s->enable;
- break;
-
- case SVGA_REG_WIDTH:
- ret = s->new_width ? s->new_width : surface_width(surface);
- break;
-
- case SVGA_REG_HEIGHT:
- ret = s->new_height ? s->new_height : surface_height(surface);
- break;
-
- case SVGA_REG_MAX_WIDTH:
- ret = SVGA_MAX_WIDTH;
- break;
-
- case SVGA_REG_MAX_HEIGHT:
- ret = SVGA_MAX_HEIGHT;
- break;
-
- case SVGA_REG_DEPTH:
- ret = (s->new_depth == 32) ? 24 : s->new_depth;
- break;
-
- case SVGA_REG_BITS_PER_PIXEL:
- case SVGA_REG_HOST_BITS_PER_PIXEL:
- ret = s->new_depth;
- break;
-
- case SVGA_REG_PSEUDOCOLOR:
- ret = 0x0;
- break;
-
- case SVGA_REG_RED_MASK:
- pf = qemu_default_pixelformat(s->new_depth);
- ret = pf.rmask;
- break;
-
- case SVGA_REG_GREEN_MASK:
- pf = qemu_default_pixelformat(s->new_depth);
- ret = pf.gmask;
- break;
-
- case SVGA_REG_BLUE_MASK:
- pf = qemu_default_pixelformat(s->new_depth);
- ret = pf.bmask;
- break;
-
- case SVGA_REG_BYTES_PER_LINE:
- if (s->new_width) {
- ret = (s->new_depth * s->new_width) / 8;
- } else {
- ret = surface_stride(surface);
- }
- break;
-
- case SVGA_REG_FB_START: {
- struct pci_vmsvga_state_s *pci_vmsvga
- = container_of(s, struct pci_vmsvga_state_s, chip);
- ret = pci_get_bar_addr(PCI_DEVICE(pci_vmsvga), 1);
- break;
- }
-
- case SVGA_REG_FB_OFFSET:
- ret = 0x0;
- break;
-
- case SVGA_REG_VRAM_SIZE:
- ret = s->vga.vram_size; /* No physical VRAM besides the framebuffer */
- break;
-
- case SVGA_REG_FB_SIZE:
- ret = s->vga.vram_size;
- break;
-
- case SVGA_REG_CAPABILITIES:
- caps = SVGA_CAP_NONE;
-#ifdef HW_RECT_ACCEL
- caps |= SVGA_CAP_RECT_COPY;
-#endif
-#ifdef HW_FILL_ACCEL
- caps |= SVGA_CAP_RECT_FILL;
-#endif
-#ifdef HW_MOUSE_ACCEL
- if (dpy_cursor_define_supported(s->vga.con)) {
- caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
- SVGA_CAP_CURSOR_BYPASS;
- }
-#endif
- ret = caps;
- break;
-
- case SVGA_REG_MEM_START: {
- struct pci_vmsvga_state_s *pci_vmsvga
- = container_of(s, struct pci_vmsvga_state_s, chip);
- ret = pci_get_bar_addr(PCI_DEVICE(pci_vmsvga), 2);
- break;
- }
-
- case SVGA_REG_MEM_SIZE:
- ret = s->fifo_size;
- break;
-
- case SVGA_REG_CONFIG_DONE:
- ret = s->config;
- break;
-
- case SVGA_REG_SYNC:
- case SVGA_REG_BUSY:
- ret = s->syncing;
- break;
-
- case SVGA_REG_GUEST_ID:
- ret = s->guest;
- break;
-
- case SVGA_REG_CURSOR_ID:
- ret = s->cursor.id;
- break;
-
- case SVGA_REG_CURSOR_X:
- ret = s->cursor.x;
- break;
-
- case SVGA_REG_CURSOR_Y:
- ret = s->cursor.y;
- break;
-
- case SVGA_REG_CURSOR_ON:
- ret = s->cursor.on;
- break;
-
- case SVGA_REG_SCRATCH_SIZE:
- ret = s->scratch_size;
- break;
-
- case SVGA_REG_MEM_REGS:
- case SVGA_REG_NUM_DISPLAYS:
- case SVGA_REG_PITCHLOCK:
- case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:
- ret = 0;
- break;
-
- default:
- if (s->index >= SVGA_SCRATCH_BASE &&
- s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
- ret = s->scratch[s->index - SVGA_SCRATCH_BASE];
- break;
- }
- printf("%s: Bad register %02x\n", __func__, s->index);
- ret = 0;
- break;
- }
-
- if (s->index >= SVGA_SCRATCH_BASE) {
- trace_vmware_scratch_read(s->index, ret);
- } else if (s->index >= SVGA_PALETTE_BASE) {
- trace_vmware_palette_read(s->index, ret);
- } else {
- trace_vmware_value_read(s->index, ret);
- }
- return ret;
-}
-
-static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
-{
- struct vmsvga_state_s *s = opaque;
-
- if (s->index >= SVGA_SCRATCH_BASE) {
- trace_vmware_scratch_write(s->index, value);
- } else if (s->index >= SVGA_PALETTE_BASE) {
- trace_vmware_palette_write(s->index, value);
- } else {
- trace_vmware_value_write(s->index, value);
- }
- switch (s->index) {
- case SVGA_REG_ID:
- if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {
- s->svgaid = value;
- }
- break;
-
- case SVGA_REG_ENABLE:
- s->enable = !!value;
- s->invalidated = 1;
- s->vga.hw_ops->invalidate(&s->vga);
- if (s->enable && s->config) {
- vga_dirty_log_stop(&s->vga);
- } else {
- vga_dirty_log_start(&s->vga);
- }
- break;
-
- case SVGA_REG_WIDTH:
- if (value <= SVGA_MAX_WIDTH) {
- s->new_width = value;
- s->invalidated = 1;
- } else {
- printf("%s: Bad width: %i\n", __func__, value);
- }
- break;
-
- case SVGA_REG_HEIGHT:
- if (value <= SVGA_MAX_HEIGHT) {
- s->new_height = value;
- s->invalidated = 1;
- } else {
- printf("%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);
- s->config = 0;
- s->invalidated = 1;
- }
- break;
-
- case SVGA_REG_CONFIG_DONE:
- if (value) {
- s->fifo = (uint32_t *) s->fifo_ptr;
- /* Check range and alignment. */
- if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {
- break;
- }
- if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {
- break;
- }
- if (CMD(max) > SVGA_FIFO_SIZE) {
- break;
- }
- if (CMD(max) < CMD(min) + 10 * 1024) {
- break;
- }
- vga_dirty_log_stop(&s->vga);
- }
- s->config = !!value;
- break;
-
- case SVGA_REG_SYNC:
- s->syncing = 1;
- vmsvga_fifo_run(s); /* Or should we just wait for update_display? */
- break;
-
- case SVGA_REG_GUEST_ID:
- s->guest = value;
-#ifdef VERBOSE
- if (value >= GUEST_OS_BASE && value < GUEST_OS_BASE +
- ARRAY_SIZE(vmsvga_guest_id)) {
- printf("%s: guest runs %s.\n", __func__,
- vmsvga_guest_id[value - GUEST_OS_BASE]);
- }
-#endif
- break;
-
- case SVGA_REG_CURSOR_ID:
- s->cursor.id = value;
- break;
-
- case SVGA_REG_CURSOR_X:
- s->cursor.x = value;
- break;
-
- case SVGA_REG_CURSOR_Y:
- s->cursor.y = value;
- break;
-
- case SVGA_REG_CURSOR_ON:
- s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);
- s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);
-#ifdef HW_MOUSE_ACCEL
- if (value <= SVGA_CURSOR_ON_SHOW) {
- dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);
- }
-#endif
- break;
-
- case SVGA_REG_DEPTH:
- case SVGA_REG_MEM_REGS:
- case SVGA_REG_NUM_DISPLAYS:
- case SVGA_REG_PITCHLOCK:
- case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:
- break;
-
- default:
- if (s->index >= SVGA_SCRATCH_BASE &&
- s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
- s->scratch[s->index - SVGA_SCRATCH_BASE] = value;
- break;
- }
- printf("%s: Bad register %02x\n", __func__, s->index);
- }
-}
-
-static uint32_t vmsvga_bios_read(void *opaque, uint32_t address)
-{
- printf("%s: what are we supposed to return?\n", __func__);
- return 0xcafe;
-}
-
-static void vmsvga_bios_write(void *opaque, uint32_t address, uint32_t data)
-{
- printf("%s: what are we supposed to do with (%08x)?\n", __func__, data);
-}
-
-static inline void vmsvga_check_size(struct vmsvga_state_s *s)
-{
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
-
- if (s->new_width != surface_width(surface) ||
- s->new_height != surface_height(surface) ||
- s->new_depth != surface_bits_per_pixel(surface)) {
- int stride = (s->new_depth * s->new_width) / 8;
- pixman_format_code_t format =
- qemu_default_pixman_format(s->new_depth, true);
- trace_vmware_setmode(s->new_width, s->new_height, s->new_depth);
- surface = qemu_create_displaysurface_from(s->new_width, s->new_height,
- format, stride,
- s->vga.vram_ptr);
- dpy_gfx_replace_surface(s->vga.con, surface);
- s->invalidated = 1;
- }
-}
-
-static void vmsvga_update_display(void *opaque)
-{
- struct vmsvga_state_s *s = opaque;
- DisplaySurface *surface;
- bool dirty = false;
-
- if (!s->enable) {
- s->vga.hw_ops->gfx_update(&s->vga);
- return;
- }
-
- vmsvga_check_size(s);
- surface = qemu_console_surface(s->vga.con);
-
- vmsvga_fifo_run(s);
- vmsvga_update_rect_flush(s);
-
- /*
- * Is it more efficient to look at vram VGA-dirty bits or wait
- * for the driver to issue SVGA_CMD_UPDATE?
- */
- if (memory_region_is_logging(&s->vga.vram, DIRTY_MEMORY_VGA)) {
- vga_sync_dirty_bitmap(&s->vga);
- dirty = memory_region_get_dirty(&s->vga.vram, 0,
- surface_stride(surface) * surface_height(surface),
- DIRTY_MEMORY_VGA);
- }
- if (s->invalidated || dirty) {
- s->invalidated = 0;
- dpy_gfx_update(s->vga.con, 0, 0,
- surface_width(surface), surface_height(surface));
- }
- if (dirty) {
- memory_region_reset_dirty(&s->vga.vram, 0,
- surface_stride(surface) * surface_height(surface),
- DIRTY_MEMORY_VGA);
- }
-}
-
-static void vmsvga_reset(DeviceState *dev)
-{
- struct pci_vmsvga_state_s *pci = VMWARE_SVGA(dev);
- struct vmsvga_state_s *s = &pci->chip;
-
- s->index = 0;
- s->enable = 0;
- s->config = 0;
- s->svgaid = SVGA_ID;
- s->cursor.on = 0;
- s->redraw_fifo_first = 0;
- s->redraw_fifo_last = 0;
- s->syncing = 0;
-
- vga_dirty_log_start(&s->vga);
-}
-
-static void vmsvga_invalidate_display(void *opaque)
-{
- struct vmsvga_state_s *s = opaque;
- if (!s->enable) {
- s->vga.hw_ops->invalidate(&s->vga);
- return;
- }
-
- s->invalidated = 1;
-}
-
-static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
-{
- struct vmsvga_state_s *s = opaque;
-
- if (s->vga.hw_ops->text_update) {
- s->vga.hw_ops->text_update(&s->vga, chardata);
- }
-}
-
-static int vmsvga_post_load(void *opaque, int version_id)
-{
- struct vmsvga_state_s *s = opaque;
-
- s->invalidated = 1;
- if (s->config) {
- s->fifo = (uint32_t *) s->fifo_ptr;
- }
- return 0;
-}
-
-static const VMStateDescription vmstate_vmware_vga_internal = {
- .name = "vmware_vga_internal",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = vmsvga_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s),
- VMSTATE_INT32(enable, struct vmsvga_state_s),
- VMSTATE_INT32(config, struct vmsvga_state_s),
- VMSTATE_INT32(cursor.id, struct vmsvga_state_s),
- VMSTATE_INT32(cursor.x, struct vmsvga_state_s),
- VMSTATE_INT32(cursor.y, struct vmsvga_state_s),
- VMSTATE_INT32(cursor.on, struct vmsvga_state_s),
- VMSTATE_INT32(index, struct vmsvga_state_s),
- VMSTATE_VARRAY_INT32(scratch, struct vmsvga_state_s,
- scratch_size, 0, vmstate_info_uint32, uint32_t),
- VMSTATE_INT32(new_width, struct vmsvga_state_s),
- VMSTATE_INT32(new_height, struct vmsvga_state_s),
- VMSTATE_UINT32(guest, struct vmsvga_state_s),
- VMSTATE_UINT32(svgaid, struct vmsvga_state_s),
- VMSTATE_INT32(syncing, struct vmsvga_state_s),
- VMSTATE_UNUSED(4), /* was fb_size */
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_vmware_vga = {
- .name = "vmware_vga",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(parent_obj, struct pci_vmsvga_state_s),
- VMSTATE_STRUCT(chip, struct pci_vmsvga_state_s, 0,
- vmstate_vmware_vga_internal, struct vmsvga_state_s),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const GraphicHwOps vmsvga_ops = {
- .invalidate = vmsvga_invalidate_display,
- .gfx_update = vmsvga_update_display,
- .text_update = vmsvga_text_update,
-};
-
-static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,
- MemoryRegion *address_space, MemoryRegion *io)
-{
- s->scratch_size = SVGA_SCRATCH_SIZE;
- s->scratch = g_malloc(s->scratch_size * 4);
-
- s->vga.con = graphic_console_init(dev, 0, &vmsvga_ops, s);
-
- s->fifo_size = SVGA_FIFO_SIZE;
- memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size,
- &error_fatal);
- vmstate_register_ram_global(&s->fifo_ram);
- s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
-
- vga_common_init(&s->vga, OBJECT(dev), true);
- vga_init(&s->vga, OBJECT(dev), address_space, io, true);
- vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
- s->new_depth = 32;
-}
-
-static uint64_t vmsvga_io_read(void *opaque, hwaddr addr, unsigned size)
-{
- struct vmsvga_state_s *s = opaque;
-
- switch (addr) {
- case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
- case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
- case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
- default: return -1u;
- }
-}
-
-static void vmsvga_io_write(void *opaque, hwaddr addr,
- uint64_t data, unsigned size)
-{
- struct vmsvga_state_s *s = opaque;
-
- switch (addr) {
- case SVGA_IO_MUL * SVGA_INDEX_PORT:
- vmsvga_index_write(s, addr, data);
- break;
- case SVGA_IO_MUL * SVGA_VALUE_PORT:
- vmsvga_value_write(s, addr, data);
- break;
- case SVGA_IO_MUL * SVGA_BIOS_PORT:
- vmsvga_bios_write(s, addr, data);
- break;
- }
-}
-
-static const MemoryRegionOps vmsvga_io_ops = {
- .read = vmsvga_io_read,
- .write = vmsvga_io_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- .unaligned = true,
- },
- .impl = {
- .unaligned = true,
- },
-};
-
-static void pci_vmsvga_realize(PCIDevice *dev, Error **errp)
-{
- struct pci_vmsvga_state_s *s = VMWARE_SVGA(dev);
-
- dev->config[PCI_CACHE_LINE_SIZE] = 0x08;
- 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,
- "vmsvga-io", 0x10);
- memory_region_set_flush_coalesced(&s->io_bar);
- pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
-
- vmsvga_init(DEVICE(dev), &s->chip,
- pci_address_space(dev), pci_address_space_io(dev));
-
- pci_register_bar(dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
- &s->chip.vga.vram);
- pci_register_bar(dev, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
- &s->chip.fifo_ram);
-
- if (!dev->rom_bar) {
- /* compatibility with pc-0.13 and older */
- vga_init_vbe(&s->chip.vga, OBJECT(dev), pci_address_space(dev));
- }
-}
-
-static Property vga_vmware_properties[] = {
- DEFINE_PROP_UINT32("vgamem_mb", struct pci_vmsvga_state_s,
- chip.vga.vram_size_mb, 16),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void vmsvga_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = pci_vmsvga_realize;
- k->romfile = "vgabios-vmware.bin";
- k->vendor_id = PCI_VENDOR_ID_VMWARE;
- k->device_id = SVGA_PCI_DEVICE_ID;
- k->class_id = PCI_CLASS_DISPLAY_VGA;
- k->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
- k->subsystem_id = SVGA_PCI_DEVICE_ID;
- dc->reset = vmsvga_reset;
- dc->vmsd = &vmstate_vmware_vga;
- dc->props = vga_vmware_properties;
- dc->hotpluggable = false;
- set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
-}
-
-static const TypeInfo vmsvga_info = {
- .name = TYPE_VMWARE_SVGA,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(struct pci_vmsvga_state_s),
- .class_init = vmsvga_class_init,
-};
-
-static void vmsvga_register_types(void)
-{
- type_register_static(&vmsvga_info);
-}
-
-type_init(vmsvga_register_types)
diff --git a/qemu/hw/display/xenfb.c b/qemu/hw/display/xenfb.c
deleted file mode 100644
index 9866dfda5..000000000
--- a/qemu/hw/display/xenfb.c
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * xen paravirt framebuffer backend
- *
- * Copyright IBM, Corp. 2005-2006
- * Copyright Red Hat, Inc. 2006-2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>,
- * Markus Armbruster <armbru@redhat.com>,
- * Daniel P. Berrange <berrange@redhat.com>,
- * Pat Campbell <plc@novell.com>,
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include <sys/mman.h>
-
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "sysemu/char.h"
-#include "hw/xen/xen_backend.h"
-
-#include <xen/event_channel.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/protocols.h>
-
-#include "trace.h"
-
-#ifndef BTN_LEFT
-#define BTN_LEFT 0x110 /* from <linux/input.h> */
-#endif
-
-/* -------------------------------------------------------------------- */
-
-struct common {
- struct XenDevice xendev; /* must be first */
- void *page;
- QemuConsole *con;
-};
-
-struct XenInput {
- struct common c;
- int abs_pointer_wanted; /* Whether guest supports absolute pointer */
- int button_state; /* Last seen pointer button state */
- int extended;
- QEMUPutMouseEntry *qmouse;
-};
-
-#define UP_QUEUE 8
-
-struct XenFB {
- struct common c;
- size_t fb_len;
- int row_stride;
- int depth;
- int width;
- int height;
- int offset;
- void *pixels;
- int fbpages;
- int feature_update;
- int bug_trigger;
- int have_console;
- int do_resize;
-
- struct {
- int x,y,w,h;
- } up_rects[UP_QUEUE];
- int up_count;
- int up_fullscreen;
-};
-
-/* -------------------------------------------------------------------- */
-
-static int common_bind(struct common *c)
-{
- uint64_t val;
- xen_pfn_t mfn;
-
- if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
- return -1;
- mfn = (xen_pfn_t)val;
- assert(val == mfn);
-
- if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
- return -1;
-
- c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
- PROT_READ | PROT_WRITE, 1, &mfn, NULL);
- if (c->page == NULL)
- return -1;
-
- xen_be_bind_evtchn(&c->xendev);
- xen_be_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
- mfn, c->xendev.remote_port, c->xendev.local_port);
-
- return 0;
-}
-
-static void common_unbind(struct common *c)
-{
- xen_be_unbind_evtchn(&c->xendev);
- if (c->page) {
- xenforeignmemory_unmap(xen_fmem, c->page, 1);
- c->page = NULL;
- }
-}
-
-/* -------------------------------------------------------------------- */
-
-#if 0
-/*
- * These two tables are not needed any more, but left in here
- * intentionally as documentation, to show how scancode2linux[]
- * was generated.
- *
- * Tables to map from scancode to Linux input layer keycode.
- * Scancodes are hardware-specific. These maps assumes a
- * standard AT or PS/2 keyboard which is what QEMU feeds us.
- */
-const unsigned char atkbd_set2_keycode[512] = {
-
- 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117,
- 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0,
- 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
- 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
- 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
- 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
- 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
- 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
- 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
- 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142,
- 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
- 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
- 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
-
-};
-
-const unsigned char atkbd_unxlate_table[128] = {
-
- 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
- 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-
-};
-#endif
-
-/*
- * for (i = 0; i < 128; i++) {
- * scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
- * scancode2linux[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
- * }
- */
-static const unsigned char scancode2linux[512] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 99, 0, 86, 87, 88,117, 0, 0, 95,183,184,185,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 93, 0, 0, 89, 0, 0, 85, 91, 90, 92, 0, 94, 0,124,121, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 165, 0, 0, 0, 0, 0, 0, 0, 0,163, 0, 0, 96, 97, 0, 0,
- 113,140,164, 0,166, 0, 0, 0, 0, 0,255, 0, 0, 0,114, 0,
- 115, 0,150, 0, 0, 98,255, 99,100, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,119,119,102,103,104, 0,105,112,106,118,107,
- 108,109,110,111, 0, 0, 0, 0, 0, 0, 0,125,126,127,116,142,
- 0, 0, 0,143, 0,217,156,173,128,159,158,157,155,226, 0,112,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-/* Send an event to the keyboard frontend driver */
-static int xenfb_kbd_event(struct XenInput *xenfb,
- union xenkbd_in_event *event)
-{
- struct xenkbd_page *page = xenfb->c.page;
- uint32_t prod;
-
- if (xenfb->c.xendev.be_state != XenbusStateConnected)
- return 0;
- if (!page)
- return 0;
-
- prod = page->in_prod;
- if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
- errno = EAGAIN;
- return -1;
- }
-
- xen_mb(); /* ensure ring space available */
- XENKBD_IN_RING_REF(page, prod) = *event;
- xen_wmb(); /* ensure ring contents visible */
- page->in_prod = prod + 1;
- return xen_be_send_notify(&xenfb->c.xendev);
-}
-
-/* Send a keyboard (or mouse button) event */
-static int xenfb_send_key(struct XenInput *xenfb, bool down, int keycode)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_KEY;
- event.key.pressed = down ? 1 : 0;
- event.key.keycode = keycode;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/* Send a relative mouse movement event */
-static int xenfb_send_motion(struct XenInput *xenfb,
- int rel_x, int rel_y, int rel_z)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_MOTION;
- event.motion.rel_x = rel_x;
- event.motion.rel_y = rel_y;
- event.motion.rel_z = rel_z;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/* Send an absolute mouse movement event */
-static int xenfb_send_position(struct XenInput *xenfb,
- int abs_x, int abs_y, int z)
-{
- union xenkbd_in_event event;
-
- memset(&event, 0, XENKBD_IN_EVENT_SIZE);
- event.type = XENKBD_TYPE_POS;
- event.pos.abs_x = abs_x;
- event.pos.abs_y = abs_y;
- event.pos.rel_z = z;
-
- return xenfb_kbd_event(xenfb, &event);
-}
-
-/*
- * Send a key event from the client to the guest OS
- * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
- * We have to turn this into a Linux Input layer keycode.
- *
- * Extra complexity from the fact that with extended scancodes
- * (like those produced by arrow keys) this method gets called
- * twice, but we only want to send a single event. So we have to
- * track the '0xe0' scancode state & collapse the extended keys
- * as needed.
- *
- * Wish we could just send scancodes straight to the guest which
- * already has code for dealing with this...
- */
-static void xenfb_key_event(void *opaque, int scancode)
-{
- struct XenInput *xenfb = opaque;
- int down = 1;
-
- if (scancode == 0xe0) {
- xenfb->extended = 1;
- return;
- } else if (scancode & 0x80) {
- scancode &= 0x7f;
- down = 0;
- }
- if (xenfb->extended) {
- scancode |= 0x80;
- xenfb->extended = 0;
- }
- xenfb_send_key(xenfb, down, scancode2linux[scancode]);
-}
-
-/*
- * Send a mouse event from the client to the guest OS
- *
- * The QEMU mouse can be in either relative, or absolute mode.
- * Movement is sent separately from button state, which has to
- * be encoded as virtual key events. We also don't actually get
- * given any button up/down events, so have to track changes in
- * the button state.
- */
-static void xenfb_mouse_event(void *opaque,
- int dx, int dy, int dz, int button_state)
-{
- struct XenInput *xenfb = opaque;
- DisplaySurface *surface = qemu_console_surface(xenfb->c.con);
- int dw = surface_width(surface);
- int dh = surface_height(surface);
- int i;
-
- trace_xenfb_mouse_event(opaque, dx, dy, dz, button_state,
- xenfb->abs_pointer_wanted);
- if (xenfb->abs_pointer_wanted)
- xenfb_send_position(xenfb,
- dx * (dw - 1) / 0x7fff,
- dy * (dh - 1) / 0x7fff,
- dz);
- else
- xenfb_send_motion(xenfb, dx, dy, dz);
-
- for (i = 0 ; i < 8 ; i++) {
- int lastDown = xenfb->button_state & (1 << i);
- int down = button_state & (1 << i);
- if (down == lastDown)
- continue;
-
- if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
- return;
- }
- xenfb->button_state = button_state;
-}
-
-static int input_init(struct XenDevice *xendev)
-{
- xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
- return 0;
-}
-
-static int input_initialise(struct XenDevice *xendev)
-{
- struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
- int rc;
-
- if (!in->c.con) {
- xen_be_printf(xendev, 1, "ds not set (yet)\n");
- return -1;
- }
-
- rc = common_bind(&in->c);
- if (rc != 0)
- return rc;
-
- qemu_add_kbd_event_handler(xenfb_key_event, in);
- return 0;
-}
-
-static void input_connected(struct XenDevice *xendev)
-{
- struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
-
- if (xenstore_read_fe_int(xendev, "request-abs-pointer",
- &in->abs_pointer_wanted) == -1) {
- in->abs_pointer_wanted = 0;
- }
-
- if (in->qmouse) {
- qemu_remove_mouse_event_handler(in->qmouse);
- }
- trace_xenfb_input_connected(xendev, in->abs_pointer_wanted);
- in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
- in->abs_pointer_wanted,
- "Xen PVFB Mouse");
-}
-
-static void input_disconnect(struct XenDevice *xendev)
-{
- struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
-
- if (in->qmouse) {
- qemu_remove_mouse_event_handler(in->qmouse);
- in->qmouse = NULL;
- }
- qemu_add_kbd_event_handler(NULL, NULL);
- common_unbind(&in->c);
-}
-
-static void input_event(struct XenDevice *xendev)
-{
- struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
- struct xenkbd_page *page = xenfb->c.page;
-
- /* We don't understand any keyboard events, so just ignore them. */
- if (page->out_prod == page->out_cons)
- return;
- page->out_cons = page->out_prod;
- xen_be_send_notify(&xenfb->c.xendev);
-}
-
-/* -------------------------------------------------------------------- */
-
-static void xenfb_copy_mfns(int mode, int count, xen_pfn_t *dst, void *src)
-{
- uint32_t *src32 = src;
- uint64_t *src64 = src;
- int i;
-
- for (i = 0; i < count; i++)
- dst[i] = (mode == 32) ? src32[i] : src64[i];
-}
-
-static int xenfb_map_fb(struct XenFB *xenfb)
-{
- struct xenfb_page *page = xenfb->c.page;
- char *protocol = xenfb->c.xendev.protocol;
- int n_fbdirs;
- xen_pfn_t *pgmfns = NULL;
- xen_pfn_t *fbmfns = NULL;
- void *map, *pd;
- int mode, ret = -1;
-
- /* default to native */
- pd = page->pd;
- mode = sizeof(unsigned long) * 8;
-
- if (!protocol) {
- /*
- * Undefined protocol, some guesswork needed.
- *
- * Old frontends which don't set the protocol use
- * one page directory only, thus pd[1] must be zero.
- * pd[1] of the 32bit struct layout and the lower
- * 32 bits of pd[0] of the 64bit struct layout have
- * the same location, so we can check that ...
- */
- uint32_t *ptr32 = NULL;
- uint32_t *ptr64 = NULL;
-#if defined(__i386__)
- ptr32 = (void*)page->pd;
- ptr64 = ((void*)page->pd) + 4;
-#elif defined(__x86_64__)
- ptr32 = ((void*)page->pd) - 4;
- ptr64 = (void*)page->pd;
-#endif
- if (ptr32) {
- if (ptr32[1] == 0) {
- mode = 32;
- pd = ptr32;
- } else {
- mode = 64;
- pd = ptr64;
- }
- }
-#if defined(__x86_64__)
- } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
- /* 64bit dom0, 32bit domU */
- mode = 32;
- pd = ((void*)page->pd) - 4;
-#elif defined(__i386__)
- } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
- /* 32bit dom0, 64bit domU */
- mode = 64;
- pd = ((void*)page->pd) + 4;
-#endif
- }
-
- if (xenfb->pixels) {
- munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE);
- xenfb->pixels = NULL;
- }
-
- xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
- n_fbdirs = xenfb->fbpages * mode / 8;
- n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-
- pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs);
- fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);
-
- xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
- map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
- PROT_READ, n_fbdirs, pgmfns, NULL);
- if (map == NULL)
- goto out;
- xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
- xenforeignmemory_unmap(xen_fmem, map, n_fbdirs);
-
- xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
- PROT_READ, xenfb->fbpages, fbmfns, NULL);
- if (xenfb->pixels == NULL)
- goto out;
-
- ret = 0; /* all is fine */
-
-out:
- g_free(pgmfns);
- g_free(fbmfns);
- return ret;
-}
-
-static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
- int width, int height, int depth,
- size_t fb_len, int offset, int row_stride)
-{
- size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
- size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
- size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz;
- size_t fb_len_max = fb_pages * XC_PAGE_SIZE;
- int max_width, max_height;
-
- if (fb_len_lim > fb_len_max) {
- xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n",
- fb_len_lim, fb_len_max);
- fb_len_lim = fb_len_max;
- }
- if (fb_len_lim && fb_len > fb_len_lim) {
- xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n",
- fb_len, fb_len_lim);
- fb_len = fb_len_lim;
- }
- if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
- xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n",
- depth);
- return -1;
- }
- if (row_stride <= 0 || row_stride > fb_len) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n", row_stride);
- return -1;
- }
- max_width = row_stride / (depth / 8);
- if (width < 0 || width > max_width) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend width %d limited to %d\n",
- width, max_width);
- width = max_width;
- }
- if (offset < 0 || offset >= fb_len) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend offset %d (max %zu)\n",
- offset, fb_len - 1);
- return -1;
- }
- max_height = (fb_len - offset) / row_stride;
- if (height < 0 || height > max_height) {
- xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend height %d limited to %d\n",
- height, max_height);
- height = max_height;
- }
- xenfb->fb_len = fb_len;
- xenfb->row_stride = row_stride;
- xenfb->depth = depth;
- xenfb->width = width;
- xenfb->height = height;
- xenfb->offset = offset;
- xenfb->up_fullscreen = 1;
- xenfb->do_resize = 1;
- xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n",
- width, height, depth, offset, row_stride);
- return 0;
-}
-
-/* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB) \
- for (line = y ; line < (y+h) ; line++) { \
- SRC_T *src = (SRC_T *)(xenfb->pixels \
- + xenfb->offset \
- + (line * xenfb->row_stride) \
- + (x * xenfb->depth / 8)); \
- DST_T *dst = (DST_T *)(data \
- + (line * linesize) \
- + (x * bpp / 8)); \
- int col; \
- const int RSS = 32 - (RSB + GSB + BSB); \
- const int GSS = 32 - (GSB + BSB); \
- const int BSS = 32 - (BSB); \
- const uint32_t RSM = (~0U) << (32 - RSB); \
- const uint32_t GSM = (~0U) << (32 - GSB); \
- const uint32_t BSM = (~0U) << (32 - BSB); \
- const int RDS = 32 - (RDB + GDB + BDB); \
- const int GDS = 32 - (GDB + BDB); \
- const int BDS = 32 - (BDB); \
- const uint32_t RDM = (~0U) << (32 - RDB); \
- const uint32_t GDM = (~0U) << (32 - GDB); \
- const uint32_t BDM = (~0U) << (32 - BDB); \
- for (col = x ; col < (x+w) ; col++) { \
- uint32_t spix = *src; \
- *dst = (((spix << RSS) & RSM & RDM) >> RDS) | \
- (((spix << GSS) & GSM & GDM) >> GDS) | \
- (((spix << BSS) & BSM & BDM) >> BDS); \
- src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8); \
- dst = (DST_T *) ((unsigned long) dst + bpp / 8); \
- } \
- }
-
-
-/*
- * This copies data from the guest framebuffer region, into QEMU's
- * displaysurface. qemu uses 16 or 32 bpp. In case the pv framebuffer
- * uses something else we must convert and copy, otherwise we can
- * supply the buffer directly and no thing here.
- */
-static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
-{
- DisplaySurface *surface = qemu_console_surface(xenfb->c.con);
- int line, oops = 0;
- int bpp = surface_bits_per_pixel(surface);
- int linesize = surface_stride(surface);
- uint8_t *data = surface_data(surface);
-
- if (!is_buffer_shared(surface)) {
- switch (xenfb->depth) {
- case 8:
- if (bpp == 16) {
- BLT(uint8_t, uint16_t, 3, 3, 2, 5, 6, 5);
- } else if (bpp == 32) {
- BLT(uint8_t, uint32_t, 3, 3, 2, 8, 8, 8);
- } else {
- oops = 1;
- }
- break;
- case 24:
- if (bpp == 16) {
- BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5);
- } else if (bpp == 32) {
- BLT(uint32_t, uint32_t, 8, 8, 8, 8, 8, 8);
- } else {
- oops = 1;
- }
- break;
- default:
- oops = 1;
- }
- }
- if (oops) /* should not happen */
- xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
- __FUNCTION__, xenfb->depth, bpp);
-
- dpy_gfx_update(xenfb->c.con, x, y, w, h);
-}
-
-#ifdef XENFB_TYPE_REFRESH_PERIOD
-static int xenfb_queue_full(struct XenFB *xenfb)
-{
- struct xenfb_page *page = xenfb->c.page;
- uint32_t cons, prod;
-
- if (!page)
- return 1;
-
- prod = page->in_prod;
- cons = page->in_cons;
- return prod - cons == XENFB_IN_RING_LEN;
-}
-
-static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
-{
- uint32_t prod;
- struct xenfb_page *page = xenfb->c.page;
-
- prod = page->in_prod;
- /* caller ensures !xenfb_queue_full() */
- xen_mb(); /* ensure ring space available */
- XENFB_IN_RING_REF(page, prod) = *event;
- xen_wmb(); /* ensure ring contents visible */
- page->in_prod = prod + 1;
-
- xen_be_send_notify(&xenfb->c.xendev);
-}
-
-static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
-{
- union xenfb_in_event event;
-
- memset(&event, 0, sizeof(event));
- event.type = XENFB_TYPE_REFRESH_PERIOD;
- event.refresh_period.period = period;
- xenfb_send_event(xenfb, &event);
-}
-#endif
-
-/*
- * Periodic update of display.
- * Also transmit the refresh interval to the frontend.
- *
- * Never ever do any qemu display operations
- * (resize, screen update) outside this function.
- * Our screen might be inactive. When asked for
- * an update we know it is active.
- */
-static void xenfb_update(void *opaque)
-{
- struct XenFB *xenfb = opaque;
- DisplaySurface *surface;
- int i;
-
- if (xenfb->c.xendev.be_state != XenbusStateConnected)
- return;
-
- if (!xenfb->feature_update) {
- /* we don't get update notifications, thus use the
- * sledge hammer approach ... */
- xenfb->up_fullscreen = 1;
- }
-
- /* resize if needed */
- if (xenfb->do_resize) {
- pixman_format_code_t format;
-
- xenfb->do_resize = 0;
- switch (xenfb->depth) {
- case 16:
- case 32:
- /* console.c supported depth -> buffer can be used directly */
- format = qemu_default_pixman_format(xenfb->depth, true);
- surface = qemu_create_displaysurface_from
- (xenfb->width, xenfb->height, format,
- xenfb->row_stride, xenfb->pixels + xenfb->offset);
- break;
- default:
- /* we must convert stuff */
- surface = qemu_create_displaysurface(xenfb->width, xenfb->height);
- break;
- }
- dpy_gfx_replace_surface(xenfb->c.con, surface);
- xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
- xenfb->width, xenfb->height, xenfb->depth,
- is_buffer_shared(surface) ? " (shared)" : "");
- xenfb->up_fullscreen = 1;
- }
-
- /* run queued updates */
- if (xenfb->up_fullscreen) {
- xen_be_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
- xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
- } else if (xenfb->up_count) {
- xen_be_printf(&xenfb->c.xendev, 3, "update: %d rects\n", xenfb->up_count);
- for (i = 0; i < xenfb->up_count; i++)
- xenfb_guest_copy(xenfb,
- xenfb->up_rects[i].x,
- xenfb->up_rects[i].y,
- xenfb->up_rects[i].w,
- xenfb->up_rects[i].h);
- } else {
- xen_be_printf(&xenfb->c.xendev, 3, "update: nothing\n");
- }
- xenfb->up_count = 0;
- xenfb->up_fullscreen = 0;
-}
-
-static void xenfb_update_interval(void *opaque, uint64_t interval)
-{
- struct XenFB *xenfb = opaque;
-
- if (xenfb->feature_update) {
-#ifdef XENFB_TYPE_REFRESH_PERIOD
- if (xenfb_queue_full(xenfb)) {
- return;
- }
- xenfb_send_refresh_period(xenfb, interval);
-#endif
- }
-}
-
-/* QEMU display state changed, so refresh the framebuffer copy */
-static void xenfb_invalidate(void *opaque)
-{
- struct XenFB *xenfb = opaque;
- xenfb->up_fullscreen = 1;
-}
-
-static void xenfb_handle_events(struct XenFB *xenfb)
-{
- uint32_t prod, cons, out_cons;
- struct xenfb_page *page = xenfb->c.page;
-
- prod = page->out_prod;
- out_cons = page->out_cons;
- if (prod - out_cons > XENFB_OUT_RING_LEN) {
- return;
- }
- xen_rmb(); /* ensure we see ring contents up to prod */
- for (cons = out_cons; cons != prod; cons++) {
- union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
- uint8_t type = event->type;
- int x, y, w, h;
-
- switch (type) {
- case XENFB_TYPE_UPDATE:
- if (xenfb->up_count == UP_QUEUE)
- xenfb->up_fullscreen = 1;
- if (xenfb->up_fullscreen)
- break;
- x = MAX(event->update.x, 0);
- y = MAX(event->update.y, 0);
- w = MIN(event->update.width, xenfb->width - x);
- h = MIN(event->update.height, xenfb->height - y);
- if (w < 0 || h < 0) {
- xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
- break;
- }
- if (x != event->update.x ||
- y != event->update.y ||
- w != event->update.width ||
- h != event->update.height) {
- xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
- }
- if (w == xenfb->width && h > xenfb->height / 2) {
- /* scroll detector: updated more than 50% of the lines,
- * don't bother keeping track of the rectangles then */
- xenfb->up_fullscreen = 1;
- } else {
- xenfb->up_rects[xenfb->up_count].x = x;
- xenfb->up_rects[xenfb->up_count].y = y;
- xenfb->up_rects[xenfb->up_count].w = w;
- xenfb->up_rects[xenfb->up_count].h = h;
- xenfb->up_count++;
- }
- break;
-#ifdef XENFB_TYPE_RESIZE
- case XENFB_TYPE_RESIZE:
- if (xenfb_configure_fb(xenfb, xenfb->fb_len,
- event->resize.width,
- event->resize.height,
- event->resize.depth,
- xenfb->fb_len,
- event->resize.offset,
- event->resize.stride) < 0)
- break;
- xenfb_invalidate(xenfb);
- break;
-#endif
- }
- }
- xen_mb(); /* ensure we're done with ring contents */
- page->out_cons = cons;
-}
-
-static int fb_init(struct XenDevice *xendev)
-{
-#ifdef XENFB_TYPE_RESIZE
- xenstore_write_be_int(xendev, "feature-resize", 1);
-#endif
- return 0;
-}
-
-static int fb_initialise(struct XenDevice *xendev)
-{
- struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
- struct xenfb_page *fb_page;
- int videoram;
- int rc;
-
- if (xenstore_read_fe_int(xendev, "videoram", &videoram) == -1)
- videoram = 0;
-
- rc = common_bind(&fb->c);
- if (rc != 0)
- return rc;
-
- fb_page = fb->c.page;
- rc = xenfb_configure_fb(fb, videoram * 1024 * 1024U,
- fb_page->width, fb_page->height, fb_page->depth,
- fb_page->mem_length, 0, fb_page->line_length);
- if (rc != 0)
- return rc;
-
- rc = xenfb_map_fb(fb);
- if (rc != 0)
- return rc;
-
-#if 0 /* handled in xen_init_display() for now */
- if (!fb->have_console) {
- fb->c.ds = graphic_console_init(xenfb_update,
- xenfb_invalidate,
- NULL,
- NULL,
- fb);
- fb->have_console = 1;
- }
-#endif
-
- if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update) == -1)
- fb->feature_update = 0;
- if (fb->feature_update)
- xenstore_write_be_int(xendev, "request-update", 1);
-
- xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
- fb->feature_update, videoram);
- return 0;
-}
-
-static void fb_disconnect(struct XenDevice *xendev)
-{
- struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
-
- /*
- * FIXME: qemu can't un-init gfx display (yet?).
- * Replacing the framebuffer with anonymous shared memory
- * instead. This releases the guest pages and keeps qemu happy.
- */
- xenforeignmemory_unmap(xen_fmem, fb->pixels, fb->fbpages);
- fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
- -1, 0);
- if (fb->pixels == MAP_FAILED) {
- xen_be_printf(xendev, 0,
- "Couldn't replace the framebuffer with anonymous memory errno=%d\n",
- errno);
- }
- common_unbind(&fb->c);
- fb->feature_update = 0;
- fb->bug_trigger = 0;
-}
-
-static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
-{
- struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
-
- /*
- * Set state to Connected *again* once the frontend switched
- * to connected. We must trigger the watch a second time to
- * workaround a frontend bug.
- */
- if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
- xendev->fe_state == XenbusStateConnected &&
- xendev->be_state == XenbusStateConnected) {
- xen_be_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
- xen_be_set_state(xendev, XenbusStateConnected);
- fb->bug_trigger = 1; /* only once */
- }
-}
-
-static void fb_event(struct XenDevice *xendev)
-{
- struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
-
- xenfb_handle_events(xenfb);
- xen_be_send_notify(&xenfb->c.xendev);
-}
-
-/* -------------------------------------------------------------------- */
-
-struct XenDevOps xen_kbdmouse_ops = {
- .size = sizeof(struct XenInput),
- .init = input_init,
- .initialise = input_initialise,
- .connected = input_connected,
- .disconnect = input_disconnect,
- .event = input_event,
-};
-
-struct XenDevOps xen_framebuffer_ops = {
- .size = sizeof(struct XenFB),
- .init = fb_init,
- .initialise = fb_initialise,
- .disconnect = fb_disconnect,
- .event = fb_event,
- .frontend_changed = fb_frontend_changed,
-};
-
-static const GraphicHwOps xenfb_ops = {
- .invalidate = xenfb_invalidate,
- .gfx_update = xenfb_update,
- .update_interval = xenfb_update_interval,
-};
-
-/*
- * FIXME/TODO: Kill this.
- * Temporary needed while DisplayState reorganization is in flight.
- */
-void xen_init_display(int domid)
-{
- struct XenDevice *xfb, *xin;
- struct XenFB *fb;
- struct XenInput *in;
- int i = 0;
-
-wait_more:
- i++;
- main_loop_wait(true);
- xfb = xen_be_find_xendev("vfb", domid, 0);
- xin = xen_be_find_xendev("vkbd", domid, 0);
- if (!xfb || !xin) {
- if (i < 256) {
- usleep(10000);
- goto wait_more;
- }
- xen_be_printf(NULL, 1, "displaystate setup failed\n");
- return;
- }
-
- /* vfb */
- fb = container_of(xfb, struct XenFB, c.xendev);
- fb->c.con = graphic_console_init(NULL, 0, &xenfb_ops, fb);
- fb->have_console = 1;
-
- /* vkbd */
- in = container_of(xin, struct XenInput, c.xendev);
- in->c.con = fb->c.con;
-
- /* retry ->init() */
- xen_be_check_state(xin);
- xen_be_check_state(xfb);
-}