[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Add VGA acceleration support for cirrus logic device model
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 8a757f283fb8013e220bd89848d78fdbd2362195 # Parent 94c6fc048d8ed548b552be415f23c68162f30ab0 Add VGA acceleration support for cirrus logic device model Signed-off-by: Xiaofeng Ling <xiaofeng.ling@xxxxxxxxx> Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> Signed-off-by: Asit Mallick <asit.k.mallick@xxxxxxxxx> diff -r 94c6fc048d8e -r 8a757f283fb8 tools/ioemu/hw/cirrus_vga.c --- a/tools/ioemu/hw/cirrus_vga.c Fri Sep 23 11:52:43 2005 +++ b/tools/ioemu/hw/cirrus_vga.c Fri Sep 23 12:30:54 2005 @@ -231,6 +231,8 @@ int cirrus_linear_io_addr; int cirrus_linear_bitblt_io_addr; int cirrus_mmio_io_addr; + unsigned long cirrus_lfb_addr; + unsigned long cirrus_lfb_end; uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -2447,6 +2449,10 @@ { unsigned mode; + extern void unset_vram_mapping(unsigned long addr, unsigned long end); + extern void set_vram_mapping(unsigned long addr, unsigned long end); + extern int vga_accelerate; + if ((s->sr[0x17] & 0x44) == 0x44) { goto generic_io; } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { @@ -2454,17 +2460,21 @@ } else { if ((s->gr[0x0B] & 0x14) == 0x14) { goto generic_io; - } else if (s->gr[0x0B] & 0x02) { - goto generic_io; - } - - mode = s->gr[0x05] & 0x7; - if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { + } else if (s->gr[0x0B] & 0x02) { + goto generic_io; + } + + mode = s->gr[0x05] & 0x7; + if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { + if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) + set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end); s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; s->cirrus_linear_write[1] = cirrus_linear_mem_writew; s->cirrus_linear_write[2] = cirrus_linear_mem_writel; } else { generic_io: + if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) + unset_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end); s->cirrus_linear_write[0] = cirrus_linear_writeb; s->cirrus_linear_write[1] = cirrus_linear_writew; s->cirrus_linear_write[2] = cirrus_linear_writel; @@ -3058,6 +3068,8 @@ /* XXX: add byte swapping apertures */ cpu_register_physical_memory(addr, s->vram_size, s->cirrus_linear_io_addr); + s->cirrus_lfb_addr = addr; + s->cirrus_lfb_end = addr + VGA_RAM_SIZE; cpu_register_physical_memory(addr + 0x1000000, 0x400000, s->cirrus_linear_bitblt_io_addr); } diff -r 94c6fc048d8e -r 8a757f283fb8 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Fri Sep 23 11:52:43 2005 +++ b/tools/ioemu/hw/pc.c Fri Sep 23 12:30:54 2005 @@ -385,6 +385,7 @@ unsigned long bios_offset, vga_bios_offset; int bios_size, isa_bios_size; PCIBus *pci_bus; + extern void * shared_vram; linux_boot = (kernel_filename != NULL); @@ -511,14 +512,14 @@ if (cirrus_vga_enabled) { if (pci_enabled) { pci_cirrus_vga_init(pci_bus, - ds, phys_ram_base + ram_size, ram_size, + ds, shared_vram, ram_size, vga_ram_size); } else { - isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, + isa_cirrus_vga_init(ds, shared_vram, ram_size, vga_ram_size); } } else { - vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, + vga_initialize(pci_bus, ds, shared_vram, ram_size, vga_ram_size); } diff -r 94c6fc048d8e -r 8a757f283fb8 tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Fri Sep 23 11:52:43 2005 +++ b/tools/ioemu/hw/vga.c Fri Sep 23 12:30:54 2005 @@ -1568,6 +1568,8 @@ s->graphic_mode = graphic_mode; full_update = 1; } + + full_update = 1; switch(graphic_mode) { case GMODE_TEXT: vga_draw_text(s, full_update); @@ -1848,6 +1850,7 @@ unsigned long vga_ram_offset, int vga_ram_size) { int i, j, v, b; + extern void* shared_vram; for(i = 0;i < 256; i++) { v = 0; @@ -1876,7 +1879,7 @@ /* qemu's vga mem is not detached from phys_ram_base and can cause DM abort * when guest write vga mem, so allocate a new one */ - s->vram_ptr = qemu_mallocz(vga_ram_size); + s->vram_ptr = shared_vram; s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; diff -r 94c6fc048d8e -r 8a757f283fb8 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Fri Sep 23 11:52:43 2005 +++ b/tools/ioemu/target-i386-dm/helper2.c Fri Sep 23 12:30:54 2005 @@ -54,6 +54,8 @@ #include "exec-all.h" #include "vl.h" +void *shared_vram; + shared_iopage_t *shared_page = NULL; extern int reset_requested; diff -r 94c6fc048d8e -r 8a757f283fb8 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Fri Sep 23 11:52:43 2005 +++ b/tools/ioemu/vl.c Fri Sep 23 12:30:54 2005 @@ -134,6 +134,7 @@ int prep_enabled = 0; int rtc_utc = 1; int cirrus_vga_enabled = 1; +int vga_accelerate = 1; int graphic_width = 800; int graphic_height = 600; int graphic_depth = 15; @@ -141,6 +142,12 @@ TextConsole *vga_console; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; int xc_handle; +unsigned long *vgapage_array; +unsigned long *freepage_array; +unsigned long free_pages; +void *vtop_table; +unsigned long toptab; +unsigned long vgaram_pages; /***********************************************************/ /* x86 ISA bus support */ @@ -2162,6 +2169,7 @@ "-isa simulate an ISA-only system (default is PCI system)\n" "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n" " (default is CL-GD5446 PCI VGA)\n" + "-vgaacc [0|1] 1 to accelerate CL-GD5446 speed, default is 1\n" #endif "-loadvm file start right away with a saved state (loadvm in monitor)\n" "\n" @@ -2251,6 +2259,7 @@ QEMU_OPTION_serial, QEMU_OPTION_loadvm, QEMU_OPTION_full_screen, + QEMU_OPTION_vgaacc, }; typedef struct QEMUOption { @@ -2327,6 +2336,7 @@ { "pci", 0, QEMU_OPTION_pci }, { "nic-pcnet", 0, QEMU_OPTION_nic_pcnet }, { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, + { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc }, { NULL }, }; @@ -2342,6 +2352,177 @@ #define NET_IF_TUN 0 #define NET_IF_USER 1 #define NET_IF_DUMMY 2 + +#include <xg_private.h> + +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) + +#ifdef __i386__ +#define _LEVEL_3_ 0 +#else +#define _LEVEL_3_ 1 +#endif + +#if _LEVEL_3_ +#define L3_PROT (_PAGE_PRESENT) +#define L1_PAGETABLE_ENTRIES 512 +#else +#define L1_PAGETABLE_ENTRIES 1024 +#endif + +inline int +get_vl2_table(unsigned long count, unsigned long start) +{ +#if _LEVEL_3_ + return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3; +#else + return 0; +#endif +} + +int +setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end) +{ + l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; + l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL; + unsigned long l1tab; + unsigned long ppt_alloc = 0; + unsigned long count; + int i = 0; +#if _LEVEL_3_ + l3_pgentry_t *vl3tab = NULL; + unsigned long l2tab; + if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + toptab >> PAGE_SHIFT)) == NULL ) + goto error_out; + for (i = 0; i < 4 ; i++) { + l2tab = vl3tab[i] & PAGE_MASK; + vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + l2tab >> PAGE_SHIFT); + if(vl2tab[i] == NULL) + goto error_out; + } + munmap(vl3tab, PAGE_SIZE); + vl3tab = NULL; +#else + if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + toptab >> PAGE_SHIFT)) == NULL ) + goto error_out; +#endif + + for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) + { + if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) + { + vl2_table = vl2tab[get_vl2_table(count, v_start)]; + vl2e = &vl2_table[l2_table_offset( + v_start + (count << PAGE_SHIFT))]; + + l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT; + if ( vl1tab != NULL ) + munmap(vl1tab, PAGE_SIZE); + + if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + l1tab >> PAGE_SHIFT)) == NULL ) + { + goto error_out; + } + memset(vl1tab, 0, PAGE_SIZE); + vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))]; + *vl2e = l1tab | L2_PROT; + } + + *vl1e = (mem_page_array[count] << PAGE_SHIFT) | L1_PROT; + vl1e++; + } +error_out: + if(vl1tab) munmap(vl1tab, PAGE_SIZE); + for(i = 0; i < 4; i++) + if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE); + return ppt_alloc; +} + +void +unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long v_start, unsigned long v_end) +{ + l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; + l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL; + unsigned long l1tab; + unsigned long count; + int i = 0; +#if _LEVEL_3_ + l3_pgentry_t *vl3tab = NULL; + unsigned long l2tab; + if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + toptab >> PAGE_SHIFT)) == NULL ) + goto error_out; + for (i = 0; i < 4 ; i ++){ + l2tab = vl3tab[i] & PAGE_MASK; + vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + l2tab >> PAGE_SHIFT); + if(vl2tab[i] == NULL) + goto error_out; + } + munmap(vl3tab, PAGE_SIZE); + vl3tab = NULL; +#else + if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + toptab >> PAGE_SHIFT)) == NULL ) + goto error_out; +#endif + + for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){ + if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) + { + vl2_table = vl2tab[get_vl2_table(count, v_start)]; + vl2e = &vl2_table[l2_table_offset(v_start + (count << PAGE_SHIFT))]; + l1tab = *vl2e & PAGE_MASK; + + if(l1tab == 0) + continue; + if ( vl1tab != NULL ) + munmap(vl1tab, PAGE_SIZE); + + if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + l1tab >> PAGE_SHIFT)) == NULL ) + { + goto error_out; + } + vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))]; + *vl2e = 0; + } + + *vl1e = 0; + vl1e++; + } +error_out: + if(vl1tab) munmap(vl1tab, PAGE_SIZE); + for(i = 0; i < 4; i++) + if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE); +} + +void set_vram_mapping(unsigned long addr, unsigned long end) +{ + end = addr + VGA_RAM_SIZE; + setup_mapping(xc_handle, domid, toptab, + vgapage_array, freepage_array, addr, end); +} + +void unset_vram_mapping(unsigned long addr, unsigned long end) +{ + end = addr + VGA_RAM_SIZE; + /* FIXME Flush the shadow page */ + unsetup_mapping(xc_handle, domid, toptab, addr, end); +} int main(int argc, char **argv) { @@ -2366,8 +2547,9 @@ char serial_devices[MAX_SERIAL_PORTS][128]; int serial_device_index; const char *loadvm = NULL; - unsigned long nr_pages, *page_array; + unsigned long nr_pages, extra_pages, ram_pages, *page_array; extern void *shared_page; + extern void *shared_vram; /* change the qemu-dm to daemon, just like bochs dm */ // daemon(0, 0); @@ -2674,6 +2856,17 @@ case QEMU_OPTION_cirrusvga: cirrus_vga_enabled = 1; break; + case QEMU_OPTION_vgaacc: + { + const char *p; + p = optarg; + vga_accelerate = strtol(p, (char **)&p, 0); + if (*p != '\0') { + fprintf(stderr, "qemu: invalid vgaacc option\n"); + exit(1); + } + break; + } case QEMU_OPTION_std_vga: cirrus_vga_enabled = 0; break; @@ -2803,12 +2996,25 @@ /* init the memory */ phys_ram_size = ram_size + vga_ram_size + bios_size; - #define PAGE_SHIFT 12 - #define PAGE_SIZE (1 << PAGE_SHIFT) - - nr_pages = ram_size/PAGE_SIZE; + ram_pages = ram_size/PAGE_SIZE; + vgaram_pages = (vga_ram_size -1)/PAGE_SIZE + 1; + free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES; + extra_pages = vgaram_pages + free_pages; + xc_handle = xc_interface_open(); - + + xc_dominfo_t info; + xc_domain_getinfo(xc_handle, domid, 1, &info); + + nr_pages = info.nr_pages + extra_pages; + + if ( xc_domain_setmaxmem(xc_handle, domid, + (nr_pages) * PAGE_SIZE/1024 ) != 0) + { + perror("set maxmem"); + exit(-1); + } + if ( (page_array = (unsigned long *) malloc(nr_pages * sizeof(unsigned long))) == NULL) { @@ -2816,6 +3022,12 @@ exit(-1); } + if (xc_domain_memory_increase_reservation(xc_handle, domid, + extra_pages , 0, 0, NULL) != 0) { + perror("increase reservation"); + exit(-1); + } + if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages ) { perror("xc_get_pfn_list"); @@ -2825,15 +3037,36 @@ if ((phys_ram_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE, page_array, - nr_pages - 1)) == 0) { + ram_pages - 1)) == 0) { perror("xc_map_foreign_batch"); exit(-1); } shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ|PROT_WRITE, - page_array[nr_pages - 1]); - + page_array[ram_pages - 1]); + + vgapage_array = &page_array[nr_pages - vgaram_pages]; + + if ((shared_vram = xc_map_foreign_batch(xc_handle, domid, + PROT_READ|PROT_WRITE, + vgapage_array, + vgaram_pages)) == 0) { + perror("xc_map_foreign_batch vgaram "); + exit(-1); + } + + + + memset(shared_vram, 0, vgaram_pages * PAGE_SIZE); + toptab = page_array[ram_pages] << PAGE_SHIFT; + + vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ|PROT_WRITE, + page_array[ram_pages]); + + freepage_array = &page_array[nr_pages - extra_pages]; + fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1), (page_array[nr_pages - 1])); diff -r 94c6fc048d8e -r 8a757f283fb8 tools/libxc/xc_vmx_build.c --- a/tools/libxc/xc_vmx_build.c Fri Sep 23 11:52:43 2005 +++ b/tools/libxc/xc_vmx_build.c Fri Sep 23 12:30:54 2005 @@ -383,7 +383,6 @@ l2tab = page_array[ppt_alloc++] << PAGE_SHIFT; ctxt->ctrlreg[3] = l2tab; - /* Initialise the page tables. */ if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, l2tab >> PAGE_SHIFT)) == NULL ) @@ -415,23 +414,35 @@ munmap(vl1tab, PAGE_SIZE); munmap(vl2tab, PAGE_SIZE); #else - /* here l3tab means pdpt, only 4 entry is used */ l3tab = page_array[ppt_alloc++] << PAGE_SHIFT; ctxt->ctrlreg[3] = l3tab; - /* Initialise the page tables. */ if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, l3tab >> PAGE_SHIFT)) == NULL ) goto error_out; memset(vl3tab, 0, PAGE_SIZE); + /* Fill in every PDPT entry. */ + for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ ) + { + l2tab = page_array[ppt_alloc++] << PAGE_SHIFT; + if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ|PROT_WRITE, + l2tab >> PAGE_SHIFT)) == NULL ) + goto error_out; + memset(vl2tab, 0, PAGE_SIZE); + munmap(vl2tab, PAGE_SIZE); + vl3tab[i] = l2tab | L3_PROT; + } + vl3e = &vl3tab[l3_table_offset(dsi.v_start)]; for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ ) { - if (!(count % (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){ - l2tab = page_array[ppt_alloc++] << PAGE_SHIFT; + if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){ + l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)] + & PAGE_MASK; if (vl2tab != NULL) munmap(vl2tab, PAGE_SIZE); @@ -441,8 +452,6 @@ l2tab >> PAGE_SHIFT)) == NULL ) goto error_out; - memset(vl2tab, 0, PAGE_SIZE); - *vl3e++ = l2tab | L3_PROT; vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count << PAGE_SHIFT))]; } if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |