diff -r 5d7e7a250267 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/firmware/hvmloader/config.h Thu Aug 27 16:54:24 2009 +0800 @@ -15,7 +15,7 @@ #define PCI_ISA_IRQ_MASK 0x0c20U /* ISA IRQs 5,10,11 are PCI connected */ /* MMIO hole: Hardcoded defaults, which can be dynamically expanded. */ -#define PCI_MEM_START 0xf0000000 +#define PCI_MEM_START 0xe0000000 #define PCI_MEM_END 0xfc000000 extern unsigned long pci_mem_start, pci_mem_end; diff -r 5d7e7a250267 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 28 14:41:22 2009 +0800 @@ -113,7 +113,7 @@ unsigned long pci_mem_start = PCI_MEM_ST unsigned long pci_mem_start = PCI_MEM_START; unsigned long pci_mem_end = PCI_MEM_END; -static enum { VGA_none, VGA_std, VGA_cirrus } virtual_vga = VGA_none; +static enum { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga = VGA_none; static void init_hypercalls(void) { @@ -212,8 +212,10 @@ static void pci_setup(void) case 0x0300: if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) virtual_vga = VGA_std; - if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) + else if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) virtual_vga = VGA_cirrus; + else + virtual_vga = VGA_pt; break; case 0x0680: /* PIIX4 ACPI PM. Special device with special PCI config space. */ @@ -684,6 +686,11 @@ int main(void) memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_stdvga, sizeof(vgabios_stdvga)); vgabios_sz = round_option_rom(sizeof(vgabios_stdvga)); + break; + case VGA_pt: + printf("Loading VGABIOS of passthroughed gfx ...\n"); + vgabios_sz = + round_option_rom((*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); break; default: printf("No emulated VGA adaptor ...\n"); diff -r 5d7e7a250267 tools/libxc/ia64/xc_ia64_hvm_build.c --- a/tools/libxc/ia64/xc_ia64_hvm_build.c Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Thu Aug 27 16:54:24 2009 +0800 @@ -1109,7 +1109,9 @@ int xc_hvm_build_target_mem(int xc_handl uint32_t domid, int memsize, int target, - const char *image_name) + const char *image_name, + int gfx_passthru) + { /* XXX:PoD isn't supported yet */ return xc_hvm_build(xc_handle, domid, target, image_name); diff -r 5d7e7a250267 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/libxc/xc_hvm_build.c Thu Aug 27 16:54:24 2009 +0800 @@ -64,6 +64,67 @@ static void build_hvm_info(void *hvm_inf for ( i = 0, sum = 0; i < hvm_info->length; i++ ) sum += ((uint8_t *)hvm_info)[i]; hvm_info->checksum = -sum; +} + +static int init_vgabios(int xc_handle, uint32_t dom, + unsigned char *buffer, uint32_t bios_size) +{ + char *va_bios = NULL; + uint32_t va_size = 0; + + va_size = bios_size + bios_size % XC_PAGE_SIZE; + va_bios = xc_map_foreign_range(xc_handle, dom, va_size, + PROT_READ | PROT_WRITE, 0xC0); + if ( !va_bios ) + { + IPRINTF("Unable to map vga bios!\n"); + return -1; + } + + if ( buffer != NULL ) + memcpy(va_bios, buffer, bios_size); + else + memset(va_bios, 0, bios_size); + + munmap(va_bios, va_size); + return 0; +} + +static int setup_vga_pt(int xc_handle, uint32_t dom) +{ + int rc = 0; + unsigned char *bios = NULL; + int bios_size = 0; + char *c = NULL; + char checksum = 0; + + /* Allocated 64K for the vga bios */ + if (!(bios = malloc(64 * 1024))) + return -1; + +#ifdef __linux__ + bios_size = xc_get_vgabios(bios, 64 * 1024); +#else + bios_size = 0; +#endif /* __linux__ */ + + if (bios_size == 0) + { + IPRINTF("vga bios size is 0!\n"); + rc = -1; + goto error; + } + + /* Adjust the bios checksum */ + for ( c = (char*)bios; c < ((char*)bios + bios_size); c++ ) + checksum += *c; + if (checksum) + bios[bios_size - 1] -= checksum; + + init_vgabios(xc_handle, dom, bios, bios_size); +error: + free(bios); + return rc; } static int loadelfimage( @@ -381,7 +442,8 @@ int xc_hvm_build_target_mem(int xc_handl uint32_t domid, int memsize, int target, - const char *image_name) + const char *image_name, + int gfx_passthru) { char *image; int sts; @@ -392,6 +454,11 @@ int xc_hvm_build_target_mem(int xc_handl return -1; sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, image_size); + + if ( gfx_passthru ) + sts |= setup_vga_pt(xc_handle, domid); + else + sts |= init_vgabios(xc_handle, domid, NULL, 0x800); free(image); diff -r 5d7e7a250267 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/libxc/xc_linux.c Thu Aug 27 16:54:24 2009 +0800 @@ -638,6 +638,56 @@ err: return gnt; } +int xc_get_vgabios(unsigned char *buf, + int len) +{ + int mem; + uint32_t start, size = 0; + uint16_t magic = 0; + + start = 0xC0000; + if (len < size) + return 0; + if ((mem = open("/dev/mem", O_RDONLY)) < 0) + return 0; + + /* + ** Check if it a real bios extension. + ** The magic number is 0xAA55. + */ + if (start != lseek(mem, start, SEEK_SET)) + goto out; + if (read(mem, &magic, 2) != 2) + goto out; + if (magic != 0xAA55) + goto out; + /* Find the size of the rom extension */ + if (start != lseek(mem, start, SEEK_SET)) + goto out; + if (lseek(mem, 2, SEEK_CUR) != (start + 2)) + goto out; + if (read(mem, &size, 1) != 1) + goto out; + /* This size is in 512K */ + size *= 512; + + /* + ** Set the file to the begining of the rombios, + ** to start the copy. + */ + if (start != lseek(mem, start, SEEK_SET)) + { + size = 0; + goto out; + } + if (size != read(mem, buf, size)) + size = 0; + +out: + close(mem); + return size; +} + /* * Local variables: * mode: C diff -r 5d7e7a250267 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/libxc/xenctrl.h Thu Aug 27 16:54:24 2009 +0800 @@ -1285,4 +1285,6 @@ int xc_tmem_restore(int xc_handle, int d int xc_tmem_restore(int xc_handle, int dom, int fd); int xc_tmem_restore_extra(int xc_handle, int dom, int fd); +int xc_get_vgabios(unsigned char *bios, int len); + #endif /* XENCTRL_H */ diff -r 5d7e7a250267 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/libxc/xenguest.h Thu Aug 27 16:54:24 2009 +0800 @@ -135,7 +135,8 @@ int xc_hvm_build_target_mem(int xc_handl uint32_t domid, int memsize, int target, - const char *image_name); + const char *image_name, + int gfx_passthru); int xc_hvm_build_mem(int xc_handle, uint32_t domid, diff -r 5d7e7a250267 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Aug 27 16:54:24 2009 +0800 @@ -894,21 +894,21 @@ static PyObject *pyxc_hvm_build(XcObject int i; #endif char *image; - int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1; + int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1, gfx_passthru = 0; static char *kwd_list[] = { "domid", "memsize", "image", "target", "vcpus", "acpi", - "apic", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list, + "apic", "gfx_passthru", NULL }; + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiiii", kwd_list, &dom, &memsize, &image, &target, &vcpus, - &acpi, &apic) ) + &acpi, &apic, &gfx_passthru) ) return NULL; if ( target == -1 ) target = memsize; if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize, - target, image) != 0 ) + target, image, gfx_passthru) != 0 ) return pyxc_error_to_exception(); #if !defined(__ia64__) diff -r 5d7e7a250267 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/python/xen/xend/XendConfig.py Thu Aug 27 16:54:24 2009 +0800 @@ -175,6 +175,7 @@ XENAPI_PLATFORM_CFG_TYPES = { 'pci_msitranslate': int, 'pci_power_mgmt': int, 'xen_platform_pci': int, + "gfx_passthru": int, } # Xen API console 'other_config' keys. diff -r 5d7e7a250267 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/python/xen/xend/image.py Thu Aug 27 16:54:24 2009 +0800 @@ -786,7 +786,7 @@ class HVMImageHandler(ImageHandler): self.apic = int(vmConfig['platform'].get('apic', 0)) self.acpi = int(vmConfig['platform'].get('acpi', 0)) self.guest_os_type = vmConfig['platform'].get('guest_os_type') - + self.gfx_passthru = int(vmConfig['platform'].get('gfx_passthru', 0)) # Return a list of cmd line args to the device models based on the # xm config file @@ -807,7 +807,7 @@ class HVMImageHandler(ImageHandler): dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', - 'acpi', 'usb', 'usbdevice' ] + 'acpi', 'usb', 'usbdevice', 'gfx_passthru' ] for a in dmargs: v = vmConfig['platform'].get(a) @@ -901,6 +901,7 @@ class HVMImageHandler(ImageHandler): log.debug("vcpus = %d", self.vm.getVCpuCount()) log.debug("acpi = %d", self.acpi) log.debug("apic = %d", self.apic) + log.debug("gfx_passthru = %d", self.gfx_passthru) rc = xc.hvm_build(domid = self.vm.getDomid(), image = self.loader, @@ -908,7 +909,8 @@ class HVMImageHandler(ImageHandler): target = mem_mb, vcpus = self.vm.getVCpuCount(), acpi = self.acpi, - apic = self.apic) + apic = self.apic, + gfx_passthru = self.gfx_passthru) rc['notes'] = { 'SUSPEND_CANCEL': 1 } rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(), diff -r 5d7e7a250267 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Wed Aug 26 18:28:44 2009 +0800 +++ b/tools/python/xen/xm/create.py Thu Aug 27 16:54:24 2009 +0800 @@ -546,6 +546,10 @@ gopts.var('sdl', val='', gopts.var('sdl', val='', fn=set_value, default=None, use="""Should the device model use SDL?""") + +gopts.var('gfx_passthru', val='', + fn=set_value, default=None, + use="""Passthrough graphics card?""") gopts.var('opengl', val='', fn=set_value, default=None, @@ -957,7 +961,8 @@ def configure_hvm(config_image, vals): 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet', 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check', 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate', - 'vpt_align', 'pci_power_mgmt', 'xen_platform_pci' ] + 'vpt_align', 'pci_power_mgmt', 'xen_platform_pci', + 'gfx_passthru' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: