#ifndef EMBED_STDVGA
DisplayState *ds;
int vram_size;
+ ram_addr_t vram_offset;
#endif
uint8_t *vram;
+ target_phys_addr_t vram_base;
int index;
int scratch_size;
#ifdef VERBOSE
# define GUEST_OS_BASE 0x5001
static const char *vmsvga_guest_id[] = {
- [0x00 ... 0x15] = "an unknown OS",
[0x00] = "Dos",
[0x01] = "Windows 3.1",
[0x02] = "Windows 95",
[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
int x, int y, int w, int h)
{
#ifndef DIRECT_VRAM
- int line = h;
- int bypl = s->bypp * s->width;
- int width = s->bypp * w;
- int start = s->bypp * x + bypl * y;
- uint8_t *src = s->vram + start;
- uint8_t *dst = s->ds->data + start;
+ int line;
+ int bypl;
+ int width;
+ int start;
+ uint8_t *src;
+ uint8_t *dst;
+
+ if (x + w > s->width) {
+ fprintf(stderr, "%s: update width too large x: %d, w: %d\n",
+ __FUNCTION__, x, w);
+ x = MIN(x, s->width);
+ w = s->width - x;
+ }
+
+ if (y + h > s->height) {
+ fprintf(stderr, "%s: update height too large y: %d, h: %d\n",
+ __FUNCTION__, y, h);
+ y = MIN(y, s->height);
+ h = s->height - y;
+ }
+
+ line = h;
+ bypl = s->bypp * s->width;
+ width = s->bypp * w;
+ start = s->bypp * x + bypl * y;
+ src = s->vram + start;
+ dst = ds_get_data(s->ds) + start;
for (; line > 0; line --, src += bypl, dst += bypl)
memcpy(dst, src, width);
static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
{
#ifndef DIRECT_VRAM
- memcpy(s->ds->data, s->vram, s->bypp * s->width * s->height);
+ memcpy(ds_get_data(s->ds), s->vram, s->bypp * s->width * s->height);
#endif
dpy_update(s->ds, 0, 0, s->width, s->height);
int x0, int y0, int x1, int y1, int w, int h)
{
# ifdef DIRECT_VRAM
- uint8_t *vram = s->ds->data;
+ uint8_t *vram = ds_get_data(s->ds);
# else
uint8_t *vram = s->vram;
# endif
# ifdef DIRECT_VRAM
if (s->ds->dpy_copy)
- s->ds->dpy_copy(s->ds, x0, y0, x1, y1, w, h);
+ qemu_console_copy(s->ds, x0, y0, x1, y1, w, h);
else
# endif
{
uint32_t c, int x, int y, int w, int h)
{
# ifdef DIRECT_VRAM
- uint8_t *vram = s->ds->data;
+ uint8_t *vram = ds_get_data(s->ds);
# else
uint8_t *vram = s->vram;
# endif
}
#endif
+#define CMD(f) le32_to_cpu(s->cmd->f)
+
static inline int vmsvga_fifo_empty(struct vmsvga_state_s *s)
{
if (!s->config || !s->enable)
return (s->cmd->next_cmd == s->cmd->stop);
}
-static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
+static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
{
- uint32_t cmd = s->fifo[s->cmd->stop >> 2];
- s->cmd->stop += 4;
- if (s->cmd->stop >= s->cmd->max)
+ 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;
vmsvga_fifo_read(s);
cursor.bpp = vmsvga_fifo_read(s);
for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args ++)
- cursor.mask[args] = vmsvga_fifo_read(s);
+ 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(s);
+ cursor.image[args] = vmsvga_fifo_read_raw(s);
#ifdef HW_MOUSE_ACCEL
vmsvga_cursor_define(s, &cursor);
break;
return ((s->depth + 7) >> 3) * s->new_width;
case SVGA_REG_FB_START:
- return SVGA_MEM_BASE;
+ return s->vram_base;
case SVGA_REG_FB_OFFSET:
return 0x0;
return caps;
case SVGA_REG_MEM_START:
- return SVGA_MEM_BASE + s->vram_size - SVGA_FIFO_SIZE;
+ return s->vram_base + s->vram_size - SVGA_FIFO_SIZE;
case SVGA_REG_MEM_SIZE:
return SVGA_FIFO_SIZE;
if (value) {
s->fifo = (uint32_t *) &s->vram[s->vram_size - SVGA_FIFO_SIZE];
/* Check range and alignment. */
- if ((s->cmd->min | s->cmd->max |
- s->cmd->next_cmd | s->cmd->stop) & 3)
+ if ((CMD(min) | CMD(max) |
+ CMD(next_cmd) | CMD(stop)) & 3)
break;
- if (s->cmd->min < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo)
+ if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo)
break;
- if (s->cmd->max > SVGA_FIFO_SIZE)
+ if (CMD(max) > SVGA_FIFO_SIZE)
break;
- if (s->cmd->max < s->cmd->min + 10 * 1024)
+ if (CMD(max) < CMD(min) + 10 * 1024)
break;
}
s->config = !!value;
s->guest = value;
#ifdef VERBOSE
if (value >= GUEST_OS_BASE && value < GUEST_OS_BASE +
- sizeof(vmsvga_guest_id) / sizeof(*vmsvga_guest_id))
+ ARRAY_SIZE(vmsvga_guest_id))
printf("%s: guest runs %s.\n", __FUNCTION__,
vmsvga_guest_id[value - GUEST_OS_BASE]);
#endif
if (s->new_width != s->width || s->new_height != s->height) {
s->width = s->new_width;
s->height = s->new_height;
- dpy_resize(s->ds, s->width, s->height);
+ qemu_console_resize(s->ds, s->width, s->height);
s->invalidated = 1;
}
}
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
- s->depth = s->ds->depth ? s->ds->depth : 24;
+ s->depth = 24;
s->bypp = (s->depth + 7) >> 3;
s->cursor.on = 0;
s->redraw_fifo_first = 0;
}
if (s->depth == 32) {
- ppm_save(filename, s->vram, s->width, s->height, s->ds->linesize);
+ DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
+ s->height, 32, ds_get_linesize(s->ds), s->vram);
+ ppm_save(filename, ds);
+ qemu_free(ds);
}
}
+static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
+{
+ struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
+
+ if (s->text_update)
+ s->text_update(opaque, chardata);
+}
+
#ifdef DIRECT_VRAM
static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- return *(uint8_t *) (s->ds->data + addr);
+ return *(uint8_t *) (ds_get_data(s->ds) + addr);
else
return *(uint8_t *) (s->vram + addr);
}
static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- return *(uint16_t *) (s->ds->data + addr);
+ return *(uint16_t *) (ds_get_data(s->ds) + addr);
else
return *(uint16_t *) (s->vram + addr);
}
static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- return *(uint32_t *) (s->ds->data + addr);
+ return *(uint32_t *) (ds_get_data(s->ds) + addr);
else
return *(uint32_t *) (s->vram + addr);
}
uint32_t value)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- *(uint8_t *) (s->ds->data + addr) = value;
+ *(uint8_t *) (ds_get_data(s->ds) + addr) = value;
else
*(uint8_t *) (s->vram + addr) = value;
}
uint32_t value)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- *(uint16_t *) (s->ds->data + addr) = value;
+ *(uint16_t *) (ds_get_data(s->ds) + addr) = value;
else
*(uint16_t *) (s->vram + addr) = value;
}
uint32_t value)
{
struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque;
- addr -= SVGA_MEM_BASE;
if (addr < s->fb_size)
- *(uint32_t *) (s->ds->data + addr) = value;
+ *(uint32_t *) (ds_get_data(s->ds) + addr) = value;
else
*(uint32_t *) (s->vram + addr) = value;
}
return 0;
}
-static void vmsvga_init(struct vmsvga_state_s *s, DisplayState *ds,
+static void vmsvga_init(struct vmsvga_state_s *s,
uint8_t *vga_ram_base, unsigned long vga_ram_offset,
int vga_ram_size)
{
- int iomemtype;
- s->ds = ds;
s->vram = vga_ram_base;
s->vram_size = vga_ram_size;
+ s->vram_offset = vga_ram_offset;
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = (uint32_t *) qemu_malloc(s->scratch_size * 4);
vmsvga_reset(s);
-#ifdef DIRECT_VRAM
- iomemtype = cpu_register_io_memory(0, vmsvga_vram_read,
- vmsvga_vram_write, s);
-#else
- iomemtype = vga_ram_offset | IO_MEM_RAM;
-#endif
- cpu_register_physical_memory(SVGA_MEM_BASE, vga_ram_size,
- iomemtype);
-
- graphic_console_init(ds, vmsvga_update_display,
- vmsvga_invalidate_display, vmsvga_screen_dump, s);
-
#ifdef EMBED_STDVGA
- vga_common_init((VGAState *) s, ds,
+ vga_common_init((VGAState *) s,
vga_ram_base, vga_ram_offset, vga_ram_size);
vga_init((VGAState *) s);
#endif
+
+ s->ds = graphic_console_init(vmsvga_update_display,
+ vmsvga_invalidate_display,
+ vmsvga_screen_dump,
+ vmsvga_text_update, s);
+
+#ifdef CONFIG_BOCHS_VBE
+ /* XXX: use optimized standard vga accesses */
+ cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+ vga_ram_size, vga_ram_offset);
+#endif
}
static void pci_vmsvga_save(QEMUFile *f, void *opaque)
1, 4, vmsvga_bios_write, s);
}
-#define PCI_VENDOR_ID_VMWARE 0x15ad
-#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
-#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
-#define PCI_DEVICE_ID_VMWARE_NET 0x0720
-#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
-#define PCI_DEVICE_ID_VMWARE_IDE 0x1729
-#define PCI_CLASS_BASE_DISPLAY 0x03
-#define PCI_CLASS_SUB_VGA 0x00
+static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
+ uint32_t addr, uint32_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->vram_base = addr;
+#ifdef DIRECT_VRAM
+ iomemtype = cpu_register_io_memory(0, vmsvga_vram_read,
+ vmsvga_vram_write, s);
+#else
+ iomemtype = s->vram_offset | IO_MEM_RAM;
+#endif
+ cpu_register_physical_memory(s->vram_base, s->vram_size,
+ iomemtype);
+}
+
#define PCI_CLASS_HEADERTYPE_00h 0x00
-void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
+void pci_vmsvga_init(PCIBus *bus, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
struct pci_vmsvga_state_s *s;
s = (struct pci_vmsvga_state_s *)
pci_register_device(bus, "QEMUware SVGA",
sizeof(struct pci_vmsvga_state_s), -1, 0, 0);
- s->card.config[PCI_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff;
- s->card.config[PCI_VENDOR_ID + 1] = PCI_VENDOR_ID_VMWARE >> 8;
- s->card.config[PCI_DEVICE_ID] = SVGA_PCI_DEVICE_ID & 0xff;
- s->card.config[PCI_DEVICE_ID + 1] = SVGA_PCI_DEVICE_ID >> 8;
+ 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 */
- s->card.config[PCI_CLASS_DEVICE] = PCI_CLASS_SUB_VGA;
- s->card.config[0x0b] = PCI_CLASS_BASE_DISPLAY;
+ 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[0x0e] = PCI_CLASS_HEADERTYPE_00h;
- s->card.config[0x10] = ((SVGA_IO_BASE >> 0) & 0xff) | 1;
- s->card.config[0x11] = (SVGA_IO_BASE >> 8) & 0xff;
- s->card.config[0x12] = (SVGA_IO_BASE >> 16) & 0xff;
- s->card.config[0x13] = (SVGA_IO_BASE >> 24) & 0xff;
- s->card.config[0x18] = (SVGA_MEM_BASE >> 0) & 0xff;
- s->card.config[0x19] = (SVGA_MEM_BASE >> 8) & 0xff;
- s->card.config[0x1a] = (SVGA_MEM_BASE >> 16) & 0xff;
- s->card.config[0x1b] = (SVGA_MEM_BASE >> 24) & 0xff;
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;
pci_register_io_region(&s->card, 0, 0x10,
PCI_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
+ pci_register_io_region(&s->card, 1, vga_ram_size,
+ PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_vmsvga_map_mem);
- vmsvga_init(&s->chip, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+ vmsvga_init(&s->chip, vga_ram_base, vga_ram_offset, vga_ram_size);
register_savevm("vmware_vga", 0, 0, pci_vmsvga_save, pci_vmsvga_load, s);
}