# 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
|