[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.