#include "pci.h"
#include "vmware_vga.h"
-#define VERBOSE
-#undef DIRECT_VRAM
+#undef VERBOSE
#define HW_RECT_ACCEL
#define HW_FILL_ACCEL
#define HW_MOUSE_ACCEL
int on;
} cursor;
- target_phys_addr_t vram_base;
-
int index;
int scratch_size;
uint32_t *scratch;
int syncing;
int fb_size;
- ram_addr_t fifo_offset;
+ MemoryRegion fifo_ram;
uint8_t *fifo_ptr;
unsigned int fifo_size;
- target_phys_addr_t fifo_base;
union {
uint32_t *fifo;
- struct __attribute__((__packed__)) {
+ struct QEMU_PACKED {
uint32_t min;
uint32_t max;
uint32_t next_cmd;
struct pci_vmsvga_state_s {
PCIDevice card;
struct vmsvga_state_s chip;
+ MemoryRegion io_bar;
};
#define SVGA_MAGIC 0x900000UL
# define SVGA_IO_BASE SVGA_LEGACY_BASE_PORT
# define SVGA_IO_MUL 1
# define SVGA_FIFO_SIZE 0x10000
-# define SVGA_MEM_BASE 0xe0000000
# 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_MEM_BASE 0xe0000000
# define SVGA_PCI_DEVICE_ID PCI_DEVICE_ID_VMWARE_SVGA
#endif
static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
int x, int y, int w, int h)
{
-#ifndef DIRECT_VRAM
int line;
int bypl;
int width;
for (; line > 0; line --, src += bypl, dst += bypl)
memcpy(dst, src, width);
-#endif
dpy_update(s->vga.ds, x, y, w, h);
}
static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
{
-#ifndef DIRECT_VRAM
- memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, s->bypp * s->width * s->height);
-#endif
-
+ memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr,
+ s->bypp * s->width * s->height);
dpy_update(s->vga.ds, 0, 0, s->width, s->height);
}
-#ifdef DIRECT_VRAM
-# define vmsvga_update_rect_delayed vmsvga_update_rect
-#else
static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
int x, int y, int w, int h)
{
rect->w = w;
rect->h = h;
}
-#endif
static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
{
static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
int x0, int y0, int x1, int y1, int w, int h)
{
-# ifdef DIRECT_VRAM
- uint8_t *vram = ds_get_data(s->ds);
-# else
uint8_t *vram = s->vga.vram_ptr;
-# endif
int bypl = s->bypp * s->width;
int width = s->bypp * w;
int line = h;
uint8_t *ptr[2];
-# ifdef DIRECT_VRAM
- if (s->ds->dpy_copy)
- qemu_console_copy(s->ds, x0, y0, x1, y1, w, h);
- else
-# endif
- {
- if (y1 > y0) {
- ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1);
- ptr[1] = vram + s->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 + s->bypp * x0 + bypl * y0;
- ptr[1] = vram + s->bypp * x1 + bypl * y1;
- for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl)
- memmove(ptr[1], ptr[0], width);
+ if (y1 > y0) {
+ ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1);
+ ptr[1] = vram + s->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 + s->bypp * x0 + bypl * y0;
+ ptr[1] = vram + s->bypp * x1 + bypl * y1;
+ for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) {
+ memmove(ptr[1], ptr[0], width);
}
}
static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
uint32_t c, int x, int y, int w, int h)
{
-# ifdef DIRECT_VRAM
- uint8_t *vram = ds_get_data(s->ds);
-# else
uint8_t *vram = s->vga.vram_ptr;
-# endif
int bypp = s->bypp;
int bypl = bypp * s->width;
int width = bypp * w;
uint8_t *src;
uint8_t col[4];
-# ifdef DIRECT_VRAM
- if (s->ds->dpy_fill)
- s->ds->dpy_fill(s->ds, x, y, w, h, c);
- else
-# endif
- {
- col[0] = c;
- col[1] = c >> 8;
- col[2] = c >> 16;
- col[3] = c >> 24;
-
- if (line --) {
- dst = fst;
- src = col;
- for (column = width; column > 0; column --) {
- *(dst ++) = *(src ++);
- if (src - col == bypp)
- src = col;
- }
- dst = fst;
- for (; line > 0; line --) {
- dst += bypl;
- memcpy(dst, fst, width);
+ col[0] = c;
+ col[1] = c >> 8;
+ col[2] = c >> 16;
+ col[3] = c >> 24;
+
+ if (line--) {
+ dst = fst;
+ src = col;
+ for (column = width; column > 0; column--) {
+ *(dst++) = *(src++);
+ if (src - col == bypp) {
+ src = col;
}
}
+ dst = fst;
+ for (; line > 0; line--) {
+ dst += bypl;
+ memcpy(dst, fst, width);
+ }
}
vmsvga_update_rect_delayed(s, x, y, w, h);
int hot_x;
int hot_y;
uint32_t mask[1024];
- uint32_t image[1024];
+ uint32_t image[4096];
};
#define SVGA_BITMAP_SIZE(w, h) ((((w) + 31) >> 5) * (h))
static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
struct vmsvga_cursor_definition_s *c)
{
- int i;
- for (i = SVGA_BITMAP_SIZE(c->width, c->height) - 1; i >= 0; i --)
- c->mask[i] = ~c->mask[i];
+ 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",
+ __FUNCTION__, c->bpp);
+ cursor_put(qc);
+ qc = cursor_builtin_left_ptr();
+ }
if (s->vga.ds->cursor_define)
- s->vga.ds->cursor_define(c->width, c->height, c->bpp, c->hot_x, c->hot_y,
- (uint8_t *) c->image, (uint8_t *) c->mask);
+ s->vga.ds->cursor_define(qc);
+ cursor_put(qc);
}
#endif
#define CMD(f) le32_to_cpu(s->cmd->f)
-static inline int vmsvga_fifo_empty(struct vmsvga_state_s *s)
+static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
{
+ int num;
if (!s->config || !s->enable)
- return 1;
- return (s->cmd->next_cmd == s->cmd->stop);
+ 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)
static void vmsvga_fifo_run(struct vmsvga_state_s *s)
{
uint32_t cmd, colour;
- int args = 0;
+ int args, len;
int x, y, dx, dy, width, height;
struct vmsvga_cursor_definition_s cursor;
- while (!vmsvga_fifo_empty(s))
+ 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);
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);
vmsvga_fill_rect(s, colour, x, y, width, height);
break;
#else
+ args = 0;
goto badcmd;
#endif
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);
vmsvga_copy_rect(s, x, y, dx, dy, width, height);
break;
#else
+ args = 0;
goto badcmd;
#endif
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.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 (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 ++)
* 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);
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);
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",
__FUNCTION__, cmd);
break;
+
+ rewind:
+ s->cmd->stop = cmd_start;
+ break;
}
+ }
s->syncing = 0;
}
case SVGA_REG_BYTES_PER_LINE:
return ((s->depth + 7) >> 3) * s->new_width;
- case SVGA_REG_FB_START:
- return s->vram_base;
+ case SVGA_REG_FB_START: {
+ struct pci_vmsvga_state_s *pci_vmsvga
+ = container_of(s, struct pci_vmsvga_state_s, chip);
+ return pci_get_bar_addr(&pci_vmsvga->card, 1);
+ }
case SVGA_REG_FB_OFFSET:
return 0x0;
#endif
return caps;
- case SVGA_REG_MEM_START:
- return s->fifo_base;
+ case SVGA_REG_MEM_START: {
+ struct pci_vmsvga_state_s *pci_vmsvga
+ = container_of(s, struct pci_vmsvga_state_s, chip);
+ return pci_get_bar_addr(&pci_vmsvga->card, 2);
+ }
case SVGA_REG_MEM_SIZE:
return s->fifo_size;
s->height = -1;
s->invalidated = 1;
s->vga.invalidate(&s->vga);
- if (s->enable)
+ if (s->enable) {
s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
+ vga_dirty_log_stop(&s->vga);
+ } else {
+ vga_dirty_log_start(&s->vga);
+ }
break;
case SVGA_REG_WIDTH:
}
}
-static void vmsvga_reset(struct vmsvga_state_s *s)
+static void vmsvga_reset(DeviceState *dev)
{
+ struct pci_vmsvga_state_s *pci =
+ DO_UPCAST(struct pci_vmsvga_state_s, card.qdev, dev);
+ struct vmsvga_state_s *s = &pci->chip;
+
s->index = 0;
s->enable = 0;
s->config = 0;
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
- s->depth = ds_get_bits_per_pixel(s->vga.ds);
- s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
s->cursor.on = 0;
s->redraw_fifo_first = 0;
s->redraw_fifo_last = 0;
- switch (s->depth) {
- case 8:
- s->wred = 0x00000007;
- s->wgreen = 0x00000038;
- s->wblue = 0x000000c0;
- break;
- case 15:
- s->wred = 0x0000001f;
- s->wgreen = 0x000003e0;
- s->wblue = 0x00007c00;
- break;
- case 16:
- s->wred = 0x0000001f;
- s->wgreen = 0x000007e0;
- s->wblue = 0x0000f800;
- break;
- case 24:
- s->wred = 0x00ff0000;
- s->wgreen = 0x0000ff00;
- s->wblue = 0x000000ff;
- break;
- case 32:
- s->wred = 0x00ff0000;
- s->wgreen = 0x0000ff00;
- s->wblue = 0x000000ff;
- break;
- }
s->syncing = 0;
+
+ vga_dirty_log_start(&s->vga);
}
static void vmsvga_invalidate_display(void *opaque)
DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
s->height, 32, ds_get_linesize(s->vga.ds), s->vga.vram_ptr);
ppm_save(filename, ds);
- qemu_free(ds);
+ g_free(ds);
}
}
s->vga.text_update(&s->vga, chardata);
}
-#ifdef DIRECT_VRAM
-static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- return *(uint8_t *) (ds_get_data(s->ds) + addr);
- else
- return *(uint8_t *) (s->vram_ptr + addr);
-}
-
-static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- return *(uint16_t *) (ds_get_data(s->ds) + addr);
- else
- return *(uint16_t *) (s->vram_ptr + addr);
-}
-
-static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- return *(uint32_t *) (ds_get_data(s->ds) + addr);
- else
- return *(uint32_t *) (s->vram_ptr + addr);
-}
-
-static void vmsvga_vram_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- *(uint8_t *) (ds_get_data(s->ds) + addr) = value;
- else
- *(uint8_t *) (s->vram_ptr + addr) = value;
-}
-
-static void vmsvga_vram_writew(void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- *(uint16_t *) (ds_get_data(s->ds) + addr) = value;
- else
- *(uint16_t *) (s->vram_ptr + addr) = value;
-}
-
-static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
- struct vmsvga_state_s *s = opaque;
- if (addr < s->fb_size)
- *(uint32_t *) (ds_get_data(s->ds) + addr) = value;
- else
- *(uint32_t *) (s->vram_ptr + addr) = value;
-}
-
-static CPUReadMemoryFunc * const vmsvga_vram_read[] = {
- vmsvga_vram_readb,
- vmsvga_vram_readw,
- vmsvga_vram_readl,
-};
-
-static CPUWriteMemoryFunc * const vmsvga_vram_write[] = {
- vmsvga_vram_writeb,
- vmsvga_vram_writew,
- vmsvga_vram_writel,
-};
-#endif
-
static int vmsvga_post_load(void *opaque, int version_id)
{
struct vmsvga_state_s *s = opaque;
}
};
-static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
+static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
+ MemoryRegion *address_space, MemoryRegion *io)
{
s->scratch_size = SVGA_SCRATCH_SIZE;
- s->scratch = qemu_malloc(s->scratch_size * 4);
+ s->scratch = g_malloc(s->scratch_size * 4);
s->vga.ds = graphic_console_init(vmsvga_update_display,
vmsvga_invalidate_display,
vmsvga_screen_dump,
vmsvga_text_update, s);
- vmsvga_reset(s);
s->fifo_size = SVGA_FIFO_SIZE;
- s->fifo_offset = qemu_ram_alloc(s->fifo_size);
- s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
+ memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size);
+ vmstate_register_ram_global(&s->fifo_ram);
+ s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
vga_common_init(&s->vga, vga_ram_size);
- vga_init(&s->vga);
- vmstate_register(0, &vmstate_vga_common, &s->vga);
+ vga_init(&s->vga, address_space, io, true);
+ vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
- vga_init_vbe(&s->vga);
- rom_add_vga(VGABIOS_FILENAME);
+ s->depth = ds_get_bits_per_pixel(s->vga.ds);
+ s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
+ switch (s->depth) {
+ case 8:
+ s->wred = 0x00000007;
+ s->wgreen = 0x00000038;
+ s->wblue = 0x000000c0;
+ break;
+ case 15:
+ s->wred = 0x0000001f;
+ s->wgreen = 0x000003e0;
+ s->wblue = 0x00007c00;
+ break;
+ case 16:
+ s->wred = 0x0000001f;
+ s->wgreen = 0x000007e0;
+ s->wblue = 0x0000f800;
+ break;
+ case 24:
+ s->wred = 0x00ff0000;
+ s->wgreen = 0x0000ff00;
+ s->wblue = 0x000000ff;
+ break;
+ case 32:
+ s->wred = 0x00ff0000;
+ s->wgreen = 0x0000ff00;
+ s->wblue = 0x000000ff;
+ break;
+ }
}
-static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
-
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
- 1, 4, vmsvga_index_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
- 1, 4, vmsvga_index_write, s);
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
- 1, 4, vmsvga_value_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
- 1, 4, vmsvga_value_write, s);
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
- 1, 4, vmsvga_bios_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
- 1, 4, vmsvga_bios_write, s);
+ 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 pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void vmsvga_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
- ram_addr_t iomemtype;
-
- s->vram_base = addr;
-#ifdef DIRECT_VRAM
- iomemtype = cpu_register_io_memory(vmsvga_vram_read,
- vmsvga_vram_write, s);
-#else
- iomemtype = s->vga.vram_offset | IO_MEM_RAM;
-#endif
- cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
- iomemtype);
+ struct vmsvga_state_s *s = opaque;
- s->vga.map_addr = addr;
- s->vga.map_end = addr + s->vga.vram_size;
- vga_dirty_log_start(&s->vga);
+ switch (addr) {
+ case SVGA_IO_MUL * SVGA_INDEX_PORT:
+ return vmsvga_index_write(s, addr, data);
+ case SVGA_IO_MUL * SVGA_VALUE_PORT:
+ return vmsvga_value_write(s, addr, data);
+ case SVGA_IO_MUL * SVGA_BIOS_PORT:
+ return vmsvga_bios_write(s, addr, data);
+ }
}
-static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
- ram_addr_t iomemtype;
-
- s->fifo_base = addr;
- iomemtype = s->fifo_offset | IO_MEM_RAM;
- cpu_register_physical_memory(s->fifo_base, s->fifo_size,
- iomemtype);
-}
+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,
+ },
+};
static int pci_vmsvga_initfn(PCIDevice *dev)
{
struct pci_vmsvga_state_s *s =
DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
+ MemoryRegion *iomem;
+
+ iomem = &s->chip.vga.vram;
+
+ s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
+ s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */
+ s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */
+
+ memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
+ "vmsvga-io", 0x10);
+ pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
- pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE);
- pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID);
- s->card.config[PCI_COMMAND] = 0x07; /* I/O + Memory */
- pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA);
- s->card.config[0x0c] = 0x08; /* Cache line size */
- s->card.config[0x0d] = 0x40; /* Latency timer */
- s->card.config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
- s->card.config[0x2c] = PCI_VENDOR_ID_VMWARE & 0xff;
- s->card.config[0x2d] = PCI_VENDOR_ID_VMWARE >> 8;
- s->card.config[0x2e] = SVGA_PCI_DEVICE_ID & 0xff;
- s->card.config[0x2f] = SVGA_PCI_DEVICE_ID >> 8;
- s->card.config[0x3c] = 0xff; /* End */
-
- pci_register_bar(&s->card, 0, 0x10,
- PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
- pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
-
- pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
-
- vmsvga_init(&s->chip, VGA_RAM_SIZE);
+ vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev),
+ pci_address_space_io(dev));
+
+ pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+ pci_register_bar(&s->card, 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, pci_address_space(dev));
+ }
return 0;
}
-void pci_vmsvga_init(PCIBus *bus)
+static void vmsvga_class_init(ObjectClass *klass, void *data)
{
- pci_create_simple(bus, -1, "vmware-svga");
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ k->no_hotplug = 1;
+ k->init = pci_vmsvga_initfn;
+ 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;
}
-static PCIDeviceInfo vmsvga_info = {
- .qdev.name = "vmware-svga",
- .qdev.size = sizeof(struct pci_vmsvga_state_s),
- .qdev.vmsd = &vmstate_vmware_vga,
- .init = pci_vmsvga_initfn,
+static TypeInfo vmsvga_info = {
+ .name = "vmware-svga",
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(struct pci_vmsvga_state_s),
+ .class_init = vmsvga_class_init,
};
-static void vmsvga_register(void)
+static void vmsvga_register_types(void)
{
- pci_qdev_register(&vmsvga_info);
+ type_register_static(&vmsvga_info);
}
-device_init(vmsvga_register);
+
+type_init(vmsvga_register_types)