Add VGA acceleration support for cirrus logic device model

Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Asit Mallick  <asit.k.mallick@intel.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-09-23 13:30:54 +01:00
1 parent 2b3f9eda6b
commit 0c4708b64f
6 files changed
+284 -24

No files matched your search

+18 -6
View File
@@ -231,6 +231,8 @@ typedef struct CirrusVGAState {
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 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
{
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 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
} 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 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
/* 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);
}
+4 -3
View File
@@ -385,6 +385,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
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 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
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);
}
+4 -1
View File
@@ -1568,6 +1568,8 @@ void vga_update_display(void)
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 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
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 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
/* 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;
+2
View File
@@ -54,6 +54,8 @@
#include "exec-all.h"
#include "vl.h"
void *shared_vram;
shared_iopage_t *shared_page = NULL;
extern int reset_requested;
+240 -7
View File
@@ -134,6 +134,7 @@ int pci_enabled = 1;
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 @@ int full_screen = 0;
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 @@ void help(void)
"-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 @@ enum {
QEMU_OPTION_serial,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
QEMU_OPTION_vgaacc,
};
typedef struct QEMUOption {
@@ -2327,6 +2336,7 @@ const QEMUOption qemu_options[] = {
{ "pci", 0, QEMU_OPTION_pci },
{ "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
{ "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
{ NULL },
};
@@ -2343,6 +2353,177 @@ static uint8_t *signal_stack;
#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)
{
#ifdef CONFIG_GDBSTUB
@@ -2366,8 +2547,9 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
/* init the memory */
phys_ram_size = ram_size + vga_ram_size + bios_size;
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)
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;
nr_pages = ram_size/PAGE_SIZE;
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 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
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]));
+16 -7
View File
@@ -383,7 +383,6 @@ static int setup_guest(int xc_handle,
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 @@ static int setup_guest(int xc_handle,
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 @@ static int setup_guest(int xc_handle,
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 )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.