* THE SOFTWARE.
*/
#include "hw.h"
+#include "loader.h"
#include "console.h"
#include "pci.h"
#include "vmware_vga.h"
int syncing;
int fb_size;
+ ram_addr_t fifo_offset;
+ uint8_t *fifo_ptr;
+ unsigned int fifo_size;
+ target_phys_addr_t fifo_base;
+
union {
uint32_t *fifo;
struct __attribute__((__packed__)) {
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))
cursor.height = y = vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
cursor.bpp = vmsvga_fifo_read(s);
+
+ if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
+ SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
+ args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
+ goto badcmd;
+ }
+
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 ++)
return 0x0;
case SVGA_REG_VRAM_SIZE:
- return s->vga.vram_size - SVGA_FIFO_SIZE;
+ return s->vga.vram_size;
case SVGA_REG_FB_SIZE:
return s->fb_size;
return caps;
case SVGA_REG_MEM_START:
- return s->vram_base + s->vga.vram_size - SVGA_FIFO_SIZE;
+ return s->fifo_base;
case SVGA_REG_MEM_SIZE:
- return SVGA_FIFO_SIZE;
+ return s->fifo_size;
case SVGA_REG_CONFIG_DONE:
return s->config;
s->height = -1;
s->invalidated = 1;
s->vga.invalidate(&s->vga);
- if (s->enable)
- s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
+ 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:
case SVGA_REG_CONFIG_DONE:
if (value) {
- s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
+ s->fifo = (uint32_t *) s->fifo_ptr;
/* Check range and alignment. */
if ((CMD(min) | CMD(max) |
CMD(next_cmd) | CMD(stop)) & 3)
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
- s->depth = 24;
- s->bypp = (s->depth + 7) >> 3;
+ 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;
break;
}
s->syncing = 0;
+
+ vga_dirty_log_start(&s->vga);
}
static void vmsvga_invalidate_display(void *opaque)
s->invalidated = 1;
if (s->config)
- s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
+ s->fifo = (uint32_t *) s->fifo_ptr;
return 0;
}
-const VMStateDescription vmstate_vmware_vga_internal = {
+static const VMStateDescription vmstate_vmware_vga_internal = {
.name = "vmware_vga_internal",
.version_id = 0,
.minimum_version_id = 0,
}
};
-const VMStateDescription vmstate_vmware_vga = {
+static const VMStateDescription vmstate_vmware_vga = {
.name = "vmware_vga",
.version_id = 0,
.minimum_version_id = 0,
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = qemu_malloc(s->scratch_size * 4);
- vmsvga_reset(s);
+ s->vga.ds = graphic_console_init(vmsvga_update_display,
+ vmsvga_invalidate_display,
+ vmsvga_screen_dump,
+ vmsvga_text_update, 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);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
vmstate_register(0, &vmstate_vga_common, &s->vga);
- s->vga.ds = graphic_console_init(vmsvga_update_display,
- vmsvga_invalidate_display,
- vmsvga_screen_dump,
- vmsvga_text_update, s);
+ vga_init_vbe(&s->vga);
-#ifdef CONFIG_BOCHS_VBE
- /* XXX: use optimized standard vga accesses */
- cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- vga_ram_size, s->vga.vram_offset);
-#endif
+ rom_add_vga(VGABIOS_FILENAME);
+
+ vmsvga_reset(s);
}
static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
#endif
cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
iomemtype);
+
+ s->vga.map_addr = addr;
+ s->vga.map_end = addr + s->vga.vram_size;
+ vga_dirty_log_restart(&s->vga);
+}
+
+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 int pci_vmsvga_initfn(PCIDevice *dev)
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_COMMAND] = PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER; /* 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 */
+ s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
+ s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */
+ s->card.config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
+ s->card.config[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff;
+ s->card.config[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_VMWARE >> 8;
+ s->card.config[PCI_SUBSYSTEM_ID] = SVGA_PCI_DEVICE_ID & 0xff;
+ s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8;
+ s->card.config[PCI_INTERRUPT_LINE] = 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);
- vmstate_register(0, &vmstate_vmware_vga, s);
return 0;
}
void pci_vmsvga_init(PCIBus *bus)
{
- pci_create_simple(bus, -1, "QEMUware SVGA");
+ pci_create_simple(bus, -1, "vmware-svga");
}
static PCIDeviceInfo vmsvga_info = {
- .qdev.name = "QEMUware SVGA",
+ .qdev.name = "vmware-svga",
.qdev.size = sizeof(struct pci_vmsvga_state_s),
+ .qdev.vmsd = &vmstate_vmware_vga,
.init = pci_vmsvga_initfn,
};