diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 8c0c1ff..ecc80c5 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -291,8 +291,6 @@ typedef struct CirrusVGAState { int last_hw_cursor_y_end; int real_vram_size; /* XXX: suppress that */ CPUWriteMemoryFunc **cirrus_linear_write; - uint32_t map_addr; - uint32_t map_end; } CirrusVGAState; typedef struct PCICirrusVGAState { @@ -2641,70 +2639,6 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { cirrus_linear_bitblt_writel, }; - -static void set_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end) -{ - unsigned long i; - struct xen_add_to_physmap xatp; - int rc; - - if (end > begin + VGA_RAM_SIZE) - end = begin + VGA_RAM_SIZE; - - fprintf(logfile,"mapping vram to %lx - %lx\n", begin, end); - - if (!s->vram_mfns) - return; - - xatp.domid = domid; - xatp.space = XENMAPSPACE_mfn; - - for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) { - xatp.idx = s->vram_mfns[i]; - xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i; - rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); - if (rc) { - fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc); - return; - } - } - - (void)xc_domain_pin_memory_cacheattr( - xc_handle, domid, - begin >> TARGET_PAGE_BITS, - end >> TARGET_PAGE_BITS, - XEN_DOMCTL_MEM_CACHEATTR_WB); -} - -static void unset_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end) -{ - if (s->stolen_vram_addr) { - /* We can put it there for xend to save it efficiently */ - set_vram_mapping(s, s->stolen_vram_addr, s->stolen_vram_addr + VGA_RAM_SIZE); - } else { - /* Old image, we have to unmap them completely */ - struct xen_remove_from_physmap xrfp; - unsigned long i; - int rc; - - if (end > begin + VGA_RAM_SIZE) - end = begin + VGA_RAM_SIZE; - - fprintf(logfile,"unmapping vram from %lx - %lx\n", begin, end); - - xrfp.domid = domid; - - for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) { - xrfp.gpfn = (begin >> TARGET_PAGE_BITS) + i; - rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp); - if (rc) { - fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc); - return; - } - } - } -} - void cirrus_restart_acc(CirrusVGAState *s) { set_vram_mapping(s, s->lfb_addr, s->lfb_end); @@ -3168,7 +3102,7 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque) qemu_put_be64s(f, &s->stolen_vram_addr); if (!s->stolen_vram_addr && !vga_acc) /* Old guest: VRAM is not mapped, we have to save it ourselves */ - qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE); + qemu_put_buffer(f, s->vram_ptr, s->vram_size); } static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) @@ -3231,10 +3165,10 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &s->stolen_vram_addr); if (!s->stolen_vram_addr && !vga_acc) { /* Old guest, VRAM is not mapped, we have to restore it ourselves */ - qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); - xen_vga_populate_vram(s->lfb_addr); + qemu_get_buffer(f, s->vram_ptr, s->vram_size); + xen_vga_populate_vram(s->lfb_addr,s->vram_size); } else - xen_vga_vram_map(vga_acc ? s->lfb_addr : s->stolen_vram_addr, 0); + xen_vga_vram_map(vga_acc ? s->lfb_addr : s->stolen_vram_addr,s->vram_size, 0); if (vga_acc) { s->map_addr = s->lfb_addr; @@ -3242,8 +3176,8 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) } } else { /* Old image, we have to populate and restore VRAM ourselves */ - xen_vga_populate_vram(s->lfb_addr); - qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); + xen_vga_populate_vram(s->lfb_addr,s->vram_size); + qemu_get_buffer(f, s->vram_ptr, s->vram_size); if (vga_acc) cirrus_restart_acc(s); } @@ -3382,7 +3316,13 @@ void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, CirrusVGAState *s; s = qemu_mallocz(sizeof(CirrusVGAState)); - + + if ( vga_ram_size != 4*1024*1024 ) + { + fprintf(logfile,"The -videoram option does not work with the cirrus vga model. Video ram set to 4M. \n"); + vga_ram_size=4*1024*1024; + } + vga_common_init((VGAState *)s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0); @@ -3404,7 +3344,7 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, cpu_register_physical_memory(addr, s->vram_size, s->cirrus_linear_io_addr); s->lfb_addr = addr; - s->lfb_end = addr + VGA_RAM_SIZE; + s->lfb_end = addr + s->vram_size; if (s->map_addr && (s->lfb_addr != s->map_addr) && (s->lfb_end != s->map_end)) diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index bd5266a..4c636db 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -194,7 +194,7 @@ QEMUMachine mips_mipssim_machine = { .name = "mipssim", .desc = "MIPS MIPSsim platform", .init = mips_mipssim_init, - .ram_require = BIOS_SIZE + VGA_RAM_SIZE /* unused */, + .ram_require = BIOS_SIZE /* unused */, .nodisk_ok = 1, .max_cpus = 1, }; diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index 399f452..670a1ea 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -285,7 +285,7 @@ QEMUMachine mips_machine = { .name = "mips", .desc = "mips r4k platform", .init = mips_r4k_init, - .ram_require = VGA_RAM_SIZE + BIOS_SIZE, + .ram_require = BIOS_SIZE, .nodisk_ok = 1, .max_cpus = 1, }; diff --git a/hw/pc.c b/hw/pc.c index a31e4ba..e26ab05 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1014,7 +1014,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, } #endif /* !CONFIG_DM */ if (pci_enabled) - pci_xen_platform_init(pci_bus); + pci_xen_platform_init(pci_bus,vga_ram_size); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { @@ -1186,7 +1186,7 @@ QEMUMachine pc_machine = { .name = "pc", .desc = "Standard PC", .init = pc_init_pci, - .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE, + .ram_require = PC_MAX_BIOS_SIZE, .max_cpus = 255, }; @@ -1194,7 +1194,7 @@ QEMUMachine isapc_machine = { .name = "isapc", .desc = "ISA-only PC", .init = pc_init_isa, - .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE, + .ram_require = PC_MAX_BIOS_SIZE, .max_cpus = 1, }; diff --git a/hw/pc.h b/hw/pc.h index 455306d..a600000 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -119,12 +119,6 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; -#ifndef TARGET_SPARC -#define VGA_RAM_SIZE (8192 * 1024) -#else -#define VGA_RAM_SIZE (9 * 1024 * 1024) -#endif - int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c index ede2924..da2a0fa 100644 --- a/hw/ppc_chrp.c +++ b/hw/ppc_chrp.c @@ -334,6 +334,6 @@ QEMUMachine core99_machine = { .name = "mac99", .desc = "Mac99 based PowerMAC", .init = ppc_core99_init, - .ram_require = BIOS_SIZE + VGA_RAM_SIZE, + .ram_require = BIOS_SIZE, .max_cpus = 1, }; diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 75faeb3..510dd6e 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -369,6 +369,6 @@ QEMUMachine heathrow_machine = { .name = "g3bw", .desc = "Heathrow based PowerMAC", .init = ppc_heathrow_init, - .ram_require = BIOS_SIZE + VGA_RAM_SIZE, + .ram_require = BIOS_SIZE, .max_cpus = 1, }; diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 944935d..1e5b3b0 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -761,6 +761,6 @@ QEMUMachine prep_machine = { .name = "prep", .desc = "PowerPC PREP platform", .init = ppc_prep_init, - .ram_require = BIOS_SIZE + VGA_RAM_SIZE, + .ram_require = BIOS_SIZE, .max_cpus = 1, }; diff --git a/hw/sun4u.c b/hw/sun4u.c index a70ad20..216629f 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -587,7 +587,7 @@ QEMUMachine sun4u_machine = { .name = "sun4u", .desc = "Sun4u platform", .init = sun4u_init, - .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, + .ram_require = PROM_SIZE_MAX, .nodisk_ok = 1, .max_cpus = 16, }; @@ -596,7 +596,7 @@ QEMUMachine sun4v_machine = { .name = "sun4v", .desc = "Sun4v platform", .init = sun4v_init, - .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, + .ram_require = PROM_SIZE_MAX, .nodisk_ok = 1, .max_cpus = 16, }; @@ -605,7 +605,7 @@ QEMUMachine niagara_machine = { .name = "Niagara", .desc = "Sun4v platform, Niagara", .init = niagara_init, - .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, + .ram_require = PROM_SIZE_MAX, .nodisk_ok = 1, .max_cpus = 16, }; diff --git a/hw/vga.c b/hw/vga.c index 4a6bd1b..5c1fb13 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -40,6 +40,11 @@ //#define DEBUG_BOCHS_VBE +// PCI 0x04: command(word), 0x06(word): status +#define PCI_COMMAND_IOACCESS 0x0001 +#define PCI_COMMAND_MEMACCESS 0x0002 +#define PCI_COMMAND_BUSMASTER 0x0004 + /* force some bits to zero */ const uint8_t sr_mask[8] = { (uint8_t)~0xfc, @@ -612,6 +617,12 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) if ((val & VBE_DISPI_ENABLED) && !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { int h, shift_control; + + if(s->map_addr != s->lfb_addr || s->map_end != s->lfb_end) { + set_vram_mapping(s, s->lfb_addr, s->lfb_end); + s->map_addr = s->lfb_addr; + s->map_end = s->lfb_end; + } s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = s->vbe_regs[VBE_DISPI_INDEX_XRES]; @@ -2078,6 +2089,71 @@ static CPUWriteMemoryFunc *vga_mem_write[3] = { vga_mem_writel, }; +void unset_vram_mapping(void *opaque, unsigned long begin, unsigned long end) +{ + VGAState *s = (VGAState *) opaque; + if (s->stolen_vram_addr) { + /* We can put it there for xend to save it efficiently */ + set_vram_mapping(s, s->stolen_vram_addr, s->stolen_vram_addr + s->vram_size); + } else { + /* Old image, we have to unmap them completely */ + struct xen_remove_from_physmap xrfp; + unsigned long i; + int rc; + + if (end > begin + s->vram_size) + end = begin + s->vram_size; + + fprintf(logfile,"unmapping vram from %lx - %lx\n", begin, end); + + xrfp.domid = domid; + + for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) { + xrfp.gpfn = (begin >> TARGET_PAGE_BITS) + i; + rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp); + if (rc) { + fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc); + return; + } + } + } +} + +void set_vram_mapping(void *opaque, unsigned long begin, unsigned long end) +{ + unsigned long i; + struct xen_add_to_physmap xatp; + int rc; + VGAState *s = (VGAState *) opaque; + + if (end > begin + s->vram_size) + end = begin + s->vram_size; + + fprintf(logfile,"mapping vram to %lx - %lx\n", begin, end); + + if (!s->vram_mfns) + return; + + xatp.domid = domid; + xatp.space = XENMAPSPACE_mfn; + + for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) { + xatp.idx = s->vram_mfns[i]; + xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i; + rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); + if (rc) { + fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc); + return; + } + } + + (void)xc_domain_pin_memory_cacheattr( + xc_handle, domid, + begin >> TARGET_PAGE_BITS, + end >> TARGET_PAGE_BITS, + XEN_DOMCTL_MEM_CACHEATTR_WB); +} + static void vga_save(QEMUFile *f, void *opaque) { VGAState *s = opaque; @@ -2125,10 +2201,12 @@ static void vga_save(QEMUFile *f, void *opaque) #endif vram_size = s->vram_size; qemu_put_be32s(f, &vram_size); + qemu_put_be32(f, s->map_addr); + qemu_put_be32(f, s->map_end); qemu_put_be64s(f, &s->stolen_vram_addr); - if (!s->stolen_vram_addr) - /* Old guest: VRAM is not mapped, we have to save it ourselves */ - qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE); + if (!s->stolen_vram_addr && !s->map_addr) + /* Old guest: VRAM is not mapped, we have to save it ourselves */ + qemu_put_buffer(f, s->vram_ptr, vram_size); } static int vga_load(QEMUFile *f, void *opaque, int version_id) @@ -2140,7 +2218,7 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) int i; #endif - if (version_id > 4) + if (version_id > 5) return -EINVAL; if (s->pci_dev && version_id >= 2) { @@ -2188,13 +2266,21 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) #endif if (version_id >= 3) { /* people who restore old images may be lucky ... */ - qemu_get_be32s(f, &vram_size); - if (vram_size != s->vram_size) - return -EINVAL; + qemu_get_be32s(f, &vram_size); + if (vram_size != s->vram_size) + return -EINVAL; + if (version_id >= 5) { + qemu_get_be32s(f, &s->map_addr); + qemu_get_be32s(f, &s->map_end); + } if (version_id >= 4) { - qemu_get_be64s(f, &s->stolen_vram_addr); - if (s->stolen_vram_addr) - xen_vga_vram_map(s->stolen_vram_addr, 0); + qemu_get_be64s(f, &s->stolen_vram_addr); + if (s->stolen_vram_addr || s->map_addr) { + xen_vga_vram_map(s->map_addr ? s->map_addr : s->stolen_vram_addr,s->vram_size, 0); + } else { + qemu_get_buffer(f, s->vram_ptr, s->vram_size); + xen_vga_populate_vram(s->lfb_addr,s->vram_size); + } } /* Old guest, VRAM is not mapped, we have to restore it ourselves */ if (!s->stolen_vram_addr) @@ -2220,6 +2306,18 @@ static void vga_map(PCIDevice *pci_dev, int region_num, cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); } else { cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); + s->lfb_addr = addr; + s->lfb_end = addr + size; +#ifdef CONFIG_BOCHS_VBE + s->vbe_regs[VBE_DISPI_INDEX_LFB_ADDRESS_H] = s->lfb_addr >> 16; + s->vbe_regs[VBE_DISPI_INDEX_LFB_ADDRESS_L] = s->lfb_addr & 0xFFFF; + s->vbe_regs[VBE_DISPI_INDEX_VIDEO_MEMORY_64K] = s->vram_size >> 16; +#endif + + fprintf(stderr, "vga s->lfb_addr = %lx s->lfb_end = %lx \n", (unsigned long) s->lfb_addr,(unsigned long) s->lfb_end); + + if (size != s->vram_size) + fprintf(stderr, "vga map with size %x != %x\n", size, s->vram_size); } } @@ -2357,7 +2455,7 @@ void vga_bios_init(VGAState *s) static VGAState *xen_vga_state; /* When loading old images we have to populate the video ram ourselves */ -void xen_vga_populate_vram(uint64_t vram_addr) +void xen_vga_populate_vram(uint64_t vram_addr, uint32_t vga_ram_size) { unsigned long nr_pfn; struct xen_remove_from_physmap xrfp; @@ -2368,7 +2466,7 @@ void xen_vga_populate_vram(uint64_t vram_addr) fprintf(logfile, "populating video RAM at %llx\n", (unsigned long long)vram_addr); - nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS; + nr_pfn = vga_ram_size >> TARGET_PAGE_BITS; pfn_list = malloc(sizeof(*pfn_list) * nr_pfn); @@ -2381,7 +2479,7 @@ void xen_vga_populate_vram(uint64_t vram_addr) } free(pfn_list); - xen_vga_vram_map(vram_addr, 0); + xen_vga_vram_map(vram_addr, vga_ram_size, 0); /* Unmap them from the guest for now. */ xrfp.domid = domid; @@ -2396,7 +2494,7 @@ void xen_vga_populate_vram(uint64_t vram_addr) } /* Called once video memory has been allocated in the GPFN space */ -void xen_vga_vram_map(uint64_t vram_addr, int copy) +void xen_vga_vram_map(uint64_t vram_addr, uint32_t vga_ram_size, int copy) { unsigned long nr_pfn; xen_pfn_t *pfn_list; @@ -2407,7 +2505,7 @@ void xen_vga_vram_map(uint64_t vram_addr, int copy) fprintf(logfile, "mapping video RAM from %llx\n", (unsigned long long)vram_addr); - nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS; + nr_pfn = vga_ram_size >> TARGET_PAGE_BITS; pfn_list = malloc(sizeof(*pfn_list) * nr_pfn); @@ -2431,11 +2529,12 @@ void xen_vga_vram_map(uint64_t vram_addr, int copy) } if (copy) - memcpy(vram, xen_vga_state->vram_ptr, VGA_RAM_SIZE); + memcpy(vram, xen_vga_state->vram_ptr, vga_ram_size); + if (xen_vga_state->vram_mfns) { /* In case this function is called more than once */ free(xen_vga_state->vram_mfns); - munmap(xen_vga_state->vram_ptr, VGA_RAM_SIZE); + munmap(xen_vga_state->vram_ptr, vga_ram_size); } else { qemu_free(xen_vga_state->vram_ptr); } @@ -2451,7 +2550,7 @@ void xen_vga_vram_map(uint64_t vram_addr, int copy) } /* Called at boot time when the BIOS has allocated video RAM */ -void xen_vga_stolen_vram_addr(uint64_t stolen_vram_addr) +void xen_vga_stolen_vram_addr(uint64_t stolen_vram_addr, uint32_t vga_ram_size) { fprintf(logfile, "stolen video RAM at %llx\n", (unsigned long long)stolen_vram_addr); @@ -2459,7 +2558,7 @@ void xen_vga_stolen_vram_addr(uint64_t stolen_vram_addr) xen_vga_state->stolen_vram_addr = stolen_vram_addr; /* And copy from the initialization value */ - xen_vga_vram_map(stolen_vram_addr, 1); + xen_vga_vram_map(stolen_vram_addr, vga_ram_size, 1); } /* when used on xen environment, the vga_ram_base is not used */ @@ -2527,7 +2626,7 @@ static void vga_init(VGAState *s) { int vga_io_memory; - register_savevm("vga", 0, 4, vga_save, vga_load, s); + register_savevm("vga", 0, 5, vga_save, vga_load, s); register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); @@ -2608,6 +2707,12 @@ int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, if (!d) return -1; s = &d->vga_state; + + if ( vga_ram_size > 16*1024*1024 ) + { + fprintf(logfile,"The stdvga/VBE device model has no use for more than 16 Megs of vram. Video ram set to 16M. \n"); + vga_ram_size=16*1024*1024; + } vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); vga_init(s); @@ -2618,9 +2723,14 @@ int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, pci_conf[0x01] = 0x12; pci_conf[0x02] = 0x11; pci_conf[0x03] = 0x11; + pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS /* | PCI_COMMAND_BUSMASTER */; pci_conf[0x0a] = 0x00; // VGA controller pci_conf[0x0b] = 0x03; pci_conf[0x0e] = 0x00; // header_type + pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */ + pci_conf[0x2d] = 0x58; + pci_conf[0x2e] = 0x01; /* subsystem device */ + pci_conf[0x2f] = 0x00; /* XXX: vga_ram_size must be a power of two */ pci_register_io_region(&d->dev, 0, vga_ram_size, diff --git a/hw/vga_int.h b/hw/vga_int.h index 8e4ec93..013b999 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -28,38 +28,41 @@ #define ST01_DISP_ENABLE 0x01 /* bochs VBE support */ -//#define CONFIG_BOCHS_VBE - -#define VBE_DISPI_MAX_XRES 1600 -#define VBE_DISPI_MAX_YRES 1200 -#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 - -#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_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 CONFIG_BOCHS_VBE + +#define VBE_DISPI_MAX_XRES 2560 +#define VBE_DISPI_MAX_YRES 1600 +#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_VIDEO_MEMORY_64K 0xa +#define VBE_DISPI_INDEX_LFB_ADDRESS_H 0xb +#define VBE_DISPI_INDEX_LFB_ADDRESS_L 0xc +#define VBE_DISPI_INDEX_NB 0xd + +#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_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 0xF1000000 #ifdef CONFIG_BOCHS_VBE @@ -108,6 +111,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s); unsigned int bios_size; \ uint32_t lfb_addr; \ uint32_t lfb_end; \ + uint32_t map_addr; \ + uint32_t map_end; \ PCIDevice *pci_dev; \ uint32_t latch; \ uint8_t sr_index; \ diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c index b85388e..976e7e7 100644 --- a/hw/xen_machine_fv.c +++ b/hw/xen_machine_fv.c @@ -288,7 +288,7 @@ QEMUMachine xenfv_machine = { "xenfv", "Xen Fully-virtualized PC", xen_init_fv, - (VGA_RAM_SIZE + BIOS_SIZE) | RAMSIZE_FIXED, + BIOS_SIZE | RAMSIZE_FIXED, .max_cpus = 1, }; diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c index 9c4e33d..2255247 100644 --- a/hw/xen_machine_pv.c +++ b/hw/xen_machine_pv.c @@ -77,7 +77,7 @@ QEMUMachine xenpv_machine = { "xenpv", "Xen Para-virtualized PC", xen_init_pv, - (VGA_RAM_SIZE + BIOS_SIZE) | RAMSIZE_FIXED, + BIOS_SIZE | RAMSIZE_FIXED, .max_cpus = 1, }; diff --git a/hw/xen_platform.c b/hw/xen_platform.c index 84a2b19..6341389 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -46,6 +46,7 @@ typedef struct PCIXenPlatformState PCIDevice pci_dev; uint8_t platform_flags; uint64_t vga_stolen_ram; + uint32_t vga_ram_size; } PCIXenPlatformState; /* We throttle access to dom0 syslog, to avoid DOS attacks. This is @@ -185,6 +186,8 @@ static uint32_t xen_platform_ioport_readl(void *opaque, uint32_t addr) switch (addr) { case 4: /* VGA stolen memory address */ return d->vga_stolen_ram; + case 8: + return d->vga_ram_size; default: return ~0u; } @@ -200,7 +203,7 @@ static void xen_platform_ioport_writel(void *opaque, uint32_t addr, uint32_t val switch (addr) { case 4: /* VGA stolen memory address */ d->vga_stolen_ram = val; - xen_vga_stolen_vram_addr(val); + xen_vga_stolen_vram_addr(val,d->vga_ram_size); break; default: break; @@ -429,7 +432,7 @@ int xen_pci_load(QEMUFile *f, void *opaque, int version_id) return 0; } -void pci_xen_platform_init(PCIBus *bus) +void pci_xen_platform_init(PCIBus *bus, uint32_t vga_ram_size) { PCIXenPlatformState *d; struct pci_config_header *pch; @@ -460,6 +463,8 @@ void pci_xen_platform_init(PCIBus *bus) /* reserve 16MB mmio address for share memory*/ pci_register_io_region(&d->pci_dev, 1, 0x1000000, PCI_ADDRESS_SPACE_MEM_PREFETCH, platform_mmio_map); + + d->vga_ram_size = vga_ram_size; xen_platform_ioport_writeb(d, 0, 0); diff --git a/hw/xen_platform.h b/hw/xen_platform.h index 5bf16f8..ad276b6 100644 --- a/hw/xen_platform.h +++ b/hw/xen_platform.h @@ -3,6 +3,6 @@ #include "pci.h" -void pci_xen_platform_init(PCIBus *bus); +void pci_xen_platform_init(PCIBus *bus, uint32_t vga_ram_size); #endif diff --git a/qemu-xen.h b/qemu-xen.h index 44467a3..16d8316 100644 --- a/qemu-xen.h +++ b/qemu-xen.h @@ -20,10 +20,12 @@ void timeoffset_get(void); /* xen_platform.c */ #ifndef QEMU_TOOL -void pci_xen_platform_init(PCIBus *bus); -void xen_vga_stolen_vram_addr(uint64_t vram_addr); -void xen_vga_populate_vram(uint64_t vram_addr); -void xen_vga_vram_map(uint64_t vram_addr, int copy); +void pci_xen_platform_init(PCIBus *bus, uint32_t vga_ram_size); +void xen_vga_stolen_vram_addr(uint64_t vram_addr, uint32_t size); +void xen_vga_populate_vram(uint64_t vram_addr, uint32_t size); +void xen_vga_vram_map(uint64_t vram_addr, uint32_t size, int copy); +void set_vram_mapping(void *opaque, unsigned long begin, unsigned long end); +void unset_vram_mapping(void *opaque, unsigned long begin, unsigned long end); #endif void ide_unplug_harddisks(void); diff --git a/vl.c b/vl.c index ae9170d..d613cc7 100644 --- a/vl.c +++ b/vl.c @@ -186,7 +186,6 @@ DriveInfo drives_table[MAX_DRIVES+1]; int nb_drives; /* point to the block driver where the snapshots are managed */ static BlockDriverState *bs_snapshots; -static int vga_ram_size; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; static DisplayState display_state; int nographic; @@ -201,7 +200,9 @@ static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ int cirrus_vga_enabled = 1; int vmsvga_enabled = 0; +static int vga_ram_size = 4 * 1024 * 1024; #ifdef TARGET_SPARC +vga_ram_size += 1024 * 1024; int graphic_width = 1024; int graphic_height = 768; int graphic_depth = 8; @@ -8407,6 +8408,7 @@ static void help(int exitcode) #ifdef TARGET_I386 "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n" " (default is CL-GD5446 PCI VGA)\n" + "-videoram set amount of memory available to virtual video adapter\n" "-no-acpi disable ACPI\n" #endif #ifdef CONFIG_CURSES @@ -8501,6 +8503,7 @@ enum { QEMU_OPTION_g, QEMU_OPTION_vga, QEMU_OPTION_std_vga, + QEMU_OPTION_videoram, QEMU_OPTION_echr, QEMU_OPTION_monitor, QEMU_OPTION_domainname, @@ -8613,6 +8616,7 @@ static const QEMUOption qemu_options[] = { #endif { "localtime", 0, QEMU_OPTION_localtime }, { "std-vga", 0, QEMU_OPTION_std_vga }, + { "videoram", HAS_ARG, QEMU_OPTION_videoram }, { "vga", HAS_ARG, QEMU_OPTION_vga }, { "echr", HAS_ARG, QEMU_OPTION_echr }, { "monitor", HAS_ARG, QEMU_OPTION_monitor }, @@ -9032,7 +9036,6 @@ int main(int argc, char **argv) cpu_model = NULL; initrd_filename = NULL; ram_size = 0; - vga_ram_size = VGA_RAM_SIZE; #ifdef CONFIG_GDBSTUB use_gdbstub = 0; gdbstub_port = DEFAULT_GDBSTUB_PORT; @@ -9399,6 +9402,16 @@ int main(int argc, char **argv) case QEMU_OPTION_vga: select_vgahw (optarg); break; + case QEMU_OPTION_videoram: + { + char *ptr; + vga_ram_size = strtol(optarg,&ptr,10); + vga_ram_size *= 1024 * 1024; +#ifdef TARGET_SPARC + vga_ram_size += (1024 * 1024); +#endif + } + break; case QEMU_OPTION_g: { const char *p; @@ -9823,7 +9836,15 @@ int main(int argc, char **argv) #endif /* init the memory */ - phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED; + + /* If we're on cirrus, set vga_ram_size to 4M whatever the videoram option might have set it to */ + if ( cirrus_vga_enabled && vga_ram_size != 4 * 1024 * 1024 ) + { + fprintf(stderr,"-videoram option does not work with cirrus vga device model. Videoram set to 4M.\n"); + vga_ram_size = 4 * 1024 * 1024; + } + + phys_ram_size = (machine->ram_require + vga_ram_size) & ~RAMSIZE_FIXED; if (machine->ram_require & RAMSIZE_FIXED) { if (ram_size > 0) { diff --git a/xenfbfront.c b/xenfbfront.c index 3a67ada..69fa494 100644 --- a/xenfbfront.c +++ b/xenfbfront.c @@ -24,6 +24,8 @@ static char *kbd_path, *fb_path; static unsigned char linux2scancode[KEY_MAX + 1]; +extern uint32_t vga_ram_size; + int xenfb_connect_vkbd(const char *path) { kbd_path = strdup(path); @@ -74,7 +76,7 @@ static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, in fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); } else { ds->data = xs->nonshared_vram; - fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE); + fbfront_resize(fb_dev, w, h, linesize, ds->depth, vga_ram_size); } } @@ -248,8 +250,8 @@ int xenfb_pv_display_init(DisplayState *ds) create_thread("kbdfront", kbdfront_thread, (void*) xs); - ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); - memset(ds->data, 0, VGA_RAM_SIZE); + ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, vga_ram_size); + memset(ds->data, 0, vga_ram_size); ds->opaque = xs; ds->depth = 32; ds->bgr = 0; @@ -271,7 +273,7 @@ int xenfb_pv_display_start(void *data) int kbd_fd, fb_fd; int offset = 0; unsigned long *mfns; - int n = VGA_RAM_SIZE / PAGE_SIZE; + int n = vga_ram_size / PAGE_SIZE; int i; if (!fb_path || !kbd_path) @@ -296,7 +298,7 @@ int xenfb_pv_display_start(void *data) if (ds->shared_buf) { offset = (void*) ds->data - xs->vga_vram; } else { - offset = VGA_RAM_SIZE; + offset = vga_ram_size; ds->data = xs->nonshared_vram; } if (offset)