[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [qemu-xen-unstable] passthrough: graphics passthrough cleanup
commit b2ea6374ccd134f225f0ca728c836928fb8ae25c Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Date: Thu Aug 19 17:45:33 2010 +0100 passthrough: graphics passthrough cleanup This patch as originally titled Calpella/Sandybridge IGD passthrough. In this revision, I have separated cleanup portion of the patch from Calpella/Sandybridge portion. This cleanup portion incorporates inputs from Stephano and proposed patch from Isaku. The main changes are consolidating graphics passthrough specific code into pt-graphics.c and removal of hardcoded intercepts for host bridge (device 00:00.0) accesses in pci.c. Signed-off-by: Allen Kay [allen.m.kay@xxxxxxxxx<mailto:allen.m.kay@xxxxxxxxx>] Signed-off-by: Isaku Yamahata [yamahata@xxxxxxxxxxxxx] --- hw/pass-through.c | 215 +++++++----------------------------------------- hw/pass-through.h | 14 ++- hw/pc.c | 4 + hw/pci.c | 31 +------ hw/pci.h | 6 +- hw/piix_pci.c | 9 ++- hw/pt-graphics.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++ xen-hooks.mak | 2 +- 8 files changed, 303 insertions(+), 218 deletions(-) diff --git a/hw/pass-through.c b/hw/pass-through.c index 5a76e8d..f6ae4b2 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -1865,50 +1865,6 @@ static int pt_dev_is_virtfn(struct pci_dev *dev) return rc; } -/* - * register VGA resources for the domain with assigned gfx - */ -static int register_vga_regions(struct pt_dev *real_device) -{ - int ret = 0; - - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, - 0x3B0, 0xC, DPCI_ADD_MAPPING); - - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, - 0x3C0, 0x20, DPCI_ADD_MAPPING); - - ret |= xc_domain_memory_mapping(xc_handle, domid, - 0xa0000 >> XC_PAGE_SHIFT, - 0xa0000 >> XC_PAGE_SHIFT, - 0x20, - DPCI_ADD_MAPPING); - - return ret; -} - -/* - * unregister VGA resources for the domain with assigned gfx - */ -static int unregister_vga_regions(struct pt_dev *real_device) -{ - int ret = 0; - - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, - 0x3B0, 0xC, DPCI_REMOVE_MAPPING); - - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, - 0x3C0, 0x20, DPCI_REMOVE_MAPPING); - - ret |= xc_domain_memory_mapping(xc_handle, domid, - 0xa0000 >> XC_PAGE_SHIFT, - 0xa0000 >> XC_PAGE_SHIFT, - 0x20, - DPCI_REMOVE_MAPPING); - - return ret; -} - static int pt_register_regions(struct pt_dev *assigned_device) { int i = 0; @@ -1970,17 +1926,7 @@ static int pt_register_regions(struct pt_dev *assigned_device) PT_LOG("Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n", (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr)); } - - if ( gfx_passthru && (pci_dev->device_class == 0x0300) ) - { - ret = register_vga_regions(assigned_device); - if ( ret != 0 ) - { - PT_LOG("VGA region mapping failed\n"); - return ret; - } - } - + register_vga_regions(assigned_device); return 0; } @@ -2029,13 +1975,7 @@ static void pt_unregister_regions(struct pt_dev *assigned_device) } } - - if ( gfx_passthru && (assigned_device->pci_dev->device_class == 0x0300) ) - { - ret = unregister_vga_regions(assigned_device); - if ( ret != 0 ) - PT_LOG("VGA region unmapping failed\n"); - } + unregister_vga_regions(assigned_device); } static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap) @@ -2097,46 +2037,51 @@ static uint32_t find_ext_cap_offset(struct pci_dev *pci_dev, uint32_t cap) return 0; } -u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr) +static void pci_access_init(void) { - struct pci_dev *pci_dev; - u8 val; + struct pci_access *pci_access; - pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); - if ( !pci_dev ) - return 0; + if (dpci_infos.pci_access) + return; - val = pci_read_byte(pci_dev, addr); - pci_free_dev(pci_dev); - return val; + /* Initialize libpci */ + pci_access = pci_alloc(); + if ( pci_access == NULL ) { + PT_LOG("Error: pci_access is NULL\n"); + return; + } + pci_init(pci_access); + pci_scan_bus(pci_access); + dpci_infos.pci_access = pci_access; } -u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr) +u32 pt_pci_host_read(int bus, int dev, int fn, u32 addr, int len) { + struct pci_dev *pci_dev; - u16 val; + u32 val = -1; + pci_access_init(); pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); if ( !pci_dev ) return 0; - val = pci_read_word(pci_dev, addr); - pci_free_dev(pci_dev); + pci_read_block(pci_dev, addr, (u8 *) &val, len); return val; } -u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr) +int pt_pci_host_write(int bus, int dev, int fn, u32 addr, u32 val, int len) { struct pci_dev *pci_dev; - u32 val; + int ret = 0; + pci_access_init(); pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); if ( !pci_dev ) return 0; - val = pci_read_long(pci_dev, addr); - pci_free_dev(pci_dev); - return val; + ret = pci_write_block(pci_dev, addr, (u8 *) &val, len); + return ret; } /* parse BAR */ @@ -4200,92 +4145,6 @@ static int pt_pmcsr_reg_restore(struct pt_dev *ptdev, return 0; } -static int get_vgabios(unsigned char *buf) -{ - int fd; - uint32_t bios_size = 0; - uint32_t start = 0xC0000; - uint16_t magic = 0; - - if ( (fd = open("/dev/mem", O_RDONLY)) < 0 ) - { - PT_LOG("Error: Can't open /dev/mem: %s\n", strerror(errno)); - return 0; - } - - /* - * Check if it a real bios extension. - * The magic number is 0xAA55. - */ - if ( start != lseek(fd, start, SEEK_SET) ) - goto out; - if ( read(fd, &magic, 2) != 2 ) - goto out; - if ( magic != 0xAA55 ) - goto out; - - /* Find the size of the rom extension */ - if ( start != lseek(fd, start, SEEK_SET) ) - goto out; - if ( lseek(fd, 2, SEEK_CUR) != (start + 2) ) - goto out; - if ( read(fd, &bios_size, 1) != 1 ) - goto out; - - /* This size is in 512 bytes */ - bios_size *= 512; - - /* - * Set the file to the begining of the rombios, - * to start the copy. - */ - if ( start != lseek(fd, start, SEEK_SET) ) - goto out; - - if ( bios_size != read(fd, buf, bios_size)) - bios_size = 0; - -out: - close(fd); - return bios_size; -} - -static int setup_vga_pt(void) -{ - unsigned char *bios = NULL; - int bios_size = 0; - char *c = NULL; - char checksum = 0; - int rc = 0; - - /* Allocated 64K for the vga bios */ - if ( !(bios = malloc(64 * 1024)) ) - return -1; - - bios_size = get_vgabios(bios); - if ( bios_size == 0 || bios_size > 64 * 1024) - { - PT_LOG("vga bios size (0x%x) is invalid!\n", bios_size); - rc = -1; - goto out; - } - - /* Adjust the bios checksum */ - for ( c = (char*)bios; c < ((char*)bios + bios_size); c++ ) - checksum += *c; - if ( checksum ) - { - bios[bios_size - 1] -= checksum; - PT_LOG("vga bios checksum is adjusted!\n"); - } - - cpu_physical_memory_rw(0xc0000, bios, bios_size, 1); - -out: - free(bios); - return rc; -} - static struct pt_dev * register_real_device(PCIBus *e_bus, const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev, uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access, @@ -4387,16 +4246,13 @@ static struct pt_dev * register_real_device(PCIBus *e_bus, pt_register_regions(assigned_device); /* Setup VGA bios for passthroughed gfx */ - if ( gfx_passthru && (assigned_device->pci_dev->device_class == 0x0300) ) + if ( setup_vga_pt(assigned_device) < 0 ) { - rc = setup_vga_pt(); - if ( rc < 0 ) - { - PT_LOG("Setup VGA BIOS of passthroughed gfx failed!\n"); - return NULL; - } + PT_LOG("Setup VGA BIOS of passthroughed gfx failed!\n"); + return NULL; } + /* reinitialize each config register to be emulated */ rc = pt_config_init(assigned_device); if ( rc < 0 ) { @@ -4548,19 +4404,8 @@ int power_on_php_devfn(int devfn) { struct php_dev *php_dev = &dpci_infos.php_devs[devfn]; struct pt_dev *pt_dev; - struct pci_access *pci_access; - if (!dpci_infos.pci_access) { - /* Initialize libpci */ - pci_access = pci_alloc(); - if ( pci_access == NULL ) { - PT_LOG("Error: pci_access is NULL\n"); - return -1; - } - pci_init(pci_access); - pci_scan_bus(pci_access); - dpci_infos.pci_access = pci_access; - } + pci_access_init(); pt_dev = register_real_device(dpci_infos.e_bus, diff --git a/hw/pass-through.h b/hw/pass-through.h index f8a0c73..e59eb52 100644 --- a/hw/pass-through.h +++ b/hw/pass-through.h @@ -406,10 +406,16 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base) } uint8_t pci_intx(struct pt_dev *ptdev); - -u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr); -u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr); -u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr); +u32 pt_pci_host_read(int bus, int dev, int fn, u32 addr, int len); +int pt_pci_host_write(int bus, int dev, int fn, u32 addr, u32 val, int len); +void intel_pch_init(PCIBus *bus); +int register_vga_regions(struct pt_dev *real_device); +int unregister_vga_regions(struct pt_dev *real_device); +int setup_vga_pt(struct pt_dev *real_device); +PCIBus *intel_pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, + uint16_t did, const char *name, uint16_t revision); +void igd_pci_write(PCIDevice *pci_dev, int config_addr, uint32_t val, int len); +uint32_t igd_pci_read(PCIDevice *pci_dev, int config_addr, int len); #endif /* __PASSTHROUGH_H__ */ diff --git a/hw/pc.c b/hw/pc.c index 9375951..4c9a164 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -42,6 +42,10 @@ #include "virtio-console.h" #include "hpet_emul.h" +#ifdef CONFIG_PASSTHROUGH +#include "pass-through.h" +#endif + /* output Bochs bios info messages */ //#define DEBUG_BIOS diff --git a/hw/pci.c b/hw/pci.c index b07e5ea..ffa2c6f 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -96,7 +96,7 @@ PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, return bus; } -static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq) +PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq) { PCIBus *bus; bus = qemu_mallocz(sizeof(PCIBus)); @@ -598,7 +598,7 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len) PCIBus *s = opaque; PCIDevice *pci_dev; int config_addr, bus_num; - uint32_t val; + uint32_t val = 0; bus_num = (addr >> 16) & 0xff; while (s && s->bus_num != bus_num) @@ -624,27 +624,6 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len) } config_addr = addr & 0xff; -#ifdef CONFIG_PASSTHROUGH - /* host bridge reads for IGD passthrough */ - if ( igd_passthru && pci_dev->devfn == 0x00 ) { - val = pci_dev->config_read(pci_dev, config_addr, len); - - if ( config_addr == 0x00 && len == 4 ) - val = pt_pci_host_read_long(0, 0, 0, 0x00); - else if ( config_addr == 0x02 ) // Device ID - val = pt_pci_host_read_word(0, 0, 0, 0x02); - else if ( config_addr == 0x52 ) // GMCH Graphics Control Register - val = pt_pci_host_read_word(0, 0, 0, 0x52); - else if ( config_addr == 0xa0 ) // GMCH Top of Memory Register - val = pt_pci_host_read_word(0, 0, 0, 0xa0); - goto done_config_read; - } else if ( igd_passthru && pci_dev->devfn == 0x10 && - config_addr == 0xfc ) { // read on IGD device - val = 0; // use SMI to communicate with the system BIOS - goto done_config_read; - } -#endif - val = pci_dev->config_read(pci_dev, config_addr, len); done_config_read: @@ -897,7 +876,7 @@ typedef struct { PCIBus *bus; } PCIBridge; -static void pci_bridge_write_config(PCIDevice *d, +void pci_bridge_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { PCIBridge *s = (PCIBridge *)d; @@ -935,7 +914,7 @@ PCIDevice *pci_find_device(int bus_num, int slot, int function) } PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, - pci_map_irq_fn map_irq, const char *name) + uint8_t rid, pci_map_irq_fn map_irq, const char *name) { PCIBridge *s; s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge), @@ -948,7 +927,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, s->dev.config[0x05] = 0x00; s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error s->dev.config[0x07] = 0x00; // status = fast devsel - s->dev.config[0x08] = 0x00; // revision + s->dev.config[0x08] = rid; // revision s->dev.config[0x09] = 0x00; // programming i/f pci_config_set_class(s->dev.config, PCI_CLASS_BRIDGE_PCI); s->dev.config[0x0D] = 0x10; // latency_timer diff --git a/hw/pci.h b/hw/pci.h index de5a4e1..f232bbe 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -254,7 +254,7 @@ int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp); void pci_info(void); PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, - pci_map_irq_fn map_irq, const char *name); + uint8_t rid, pci_map_irq_fn map_irq, const char *name); #define NR_PCI_FUNC 8 #define NR_PCI_DEV 32 @@ -341,5 +341,9 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, /* pass-through.c */ int pt_init(PCIBus *e_bus); +void pci_bridge_write_config(PCIDevice *d, + uint32_t address, uint32_t val, int len); +PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq); + #endif diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 49d72b2..9c5dcf1 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -25,7 +25,9 @@ #include "hw.h" #include "pc.h" #include "pci.h" - +#ifdef CONFIG_PASSTHROUGH +#include "pass-through.h" +#endif static void i440fx_set_irq(qemu_irq *pic, int irq_num, int level); static void piix3_write_config(PCIDevice *d, @@ -206,8 +208,13 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s); register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s); +#ifdef CONFIG_PASSTHROUGH + d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, + igd_pci_read, igd_pci_write); +#else d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, NULL, NULL); +#endif pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441); diff --git a/hw/pt-graphics.c b/hw/pt-graphics.c new file mode 100644 index 0000000..ce0c4a6 --- /dev/null +++ b/hw/pt-graphics.c @@ -0,0 +1,240 @@ +/* + * graphics passthrough + */ + +#include "pass-through.h" +#include "pci/header.h" +#include "pci/pci.h" + +#include <unistd.h> +#include <sys/ioctl.h> +#include <assert.h> + +extern int gfx_passthru; +extern int igd_passthru; + +static int pch_map_irq(PCIDevice *pci_dev, int irq_num) +{ + PT_LOG("pch_map_irq called\n"); + return irq_num; +} + +void intel_pch_init(PCIBus *bus) +{ + uint16_t vid, did; + uint8_t rid; + + if ( !gfx_passthru ) + return; + + vid = pt_pci_host_read(0, 0x1f, 0, 0, 2); + did = pt_pci_host_read(0, 0x1f, 0, 2, 2); + rid = pt_pci_host_read(0, 0x1f, 0, 8, 1); + + pci_bridge_init(bus, PCI_DEVFN(0x1f, 0), vid, did, rid, + pch_map_irq, "intel_bridge_1f"); +} + +void igd_pci_write(PCIDevice *pci_dev, int config_addr, uint32_t val, int len) +{ + assert(pci_dev->devfn == 0x00); + if ( !igd_passthru ) { + pci_default_write_config(pci_dev, config_addr, val, len); + return; + } + + switch (config_addr) + { + case 0x58: // PAVPC Offset + pt_pci_host_write(0, 0, 0, config_addr, val, len); + PT_LOG("pci_config_write: %x:%x.%x: addr=%x len=%x val=%x\n", + pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), + PCI_FUNC(pci_dev->devfn), config_addr, len, val); + break; + default: + pci_default_write_config(pci_dev, config_addr, val, len); + } +} + +uint32_t igd_pci_read(PCIDevice *pci_dev, int config_addr, int len) +{ + uint32_t val; + + assert(pci_dev->devfn == 0x00); + if ( !igd_passthru ) { + return pci_default_read_config(pci_dev, config_addr, len); + } + + switch (config_addr) + { + case 0x00: /* vendor id */ + case 0x02: /* device id */ + case 0x52: /* processor graphics control register */ + case 0xa0: /* top of memory */ + case 0xb0: /* ILK: BSM: should read from dev 2 offset 0x5c */ + case 0x58: /* SNB: PAVPC Offset */ + case 0xa4: /* SNB: graphics base of stolen memory */ + case 0xa8: /* SNB: base of GTT stolen memory */ + val = pt_pci_host_read(0, PCI_SLOT(pci_dev->devfn), + 0, config_addr, len); + PT_LOG("pci_config_read: %x:%x.%x: addr=%x len=%x val=%x\n", + pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), + PCI_FUNC(pci_dev->devfn), config_addr, len, val); + break; + default: + val = pci_default_read_config(pci_dev, config_addr, len); + } + return val; +} + +/* + * register VGA resources for the domain with assigned gfx + */ +int register_vga_regions(struct pt_dev *real_device) +{ + int ret = 0; + + if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 ) + return ret; + + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, + 0x3B0, 0xC, DPCI_ADD_MAPPING); + + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, + 0x3C0, 0x20, DPCI_ADD_MAPPING); + + ret |= xc_domain_memory_mapping(xc_handle, domid, + 0xa0000 >> XC_PAGE_SHIFT, + 0xa0000 >> XC_PAGE_SHIFT, + 0x20, + DPCI_ADD_MAPPING); + + if ( ret != 0 ) + PT_LOG("VGA region mapping failed\n"); + + return ret; +} + +/* + * unregister VGA resources for the domain with assigned gfx + */ +int unregister_vga_regions(struct pt_dev *real_device) +{ + u32 igd_opregion, igd_bsm; + int ret = 0; + + if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 ) + return ret; + + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, + 0x3B0, 0xC, DPCI_REMOVE_MAPPING); + + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, + 0x3C0, 0x20, DPCI_REMOVE_MAPPING); + + ret |= xc_domain_memory_mapping(xc_handle, domid, + 0xa0000 >> XC_PAGE_SHIFT, + 0xa0000 >> XC_PAGE_SHIFT, + 20, + DPCI_REMOVE_MAPPING); + + igd_opregion = pt_pci_host_read(0, 2, 0, 0xfc, 4); + ret |= xc_domain_memory_mapping(xc_handle, domid, + igd_opregion >> XC_PAGE_SHIFT, + igd_opregion >> XC_PAGE_SHIFT, + 2, + DPCI_REMOVE_MAPPING); + + if ( ret != 0 ) + PT_LOG("VGA region unmapping failed\n"); + + return ret; +} + +static int get_vgabios(unsigned char *buf) +{ + int fd; + uint32_t bios_size = 0; + uint32_t start = 0xC0000; + uint16_t magic = 0; + + if ( (fd = open("/dev/mem", O_RDONLY)) < 0 ) + { + PT_LOG("Error: Can't open /dev/mem: %s\n", strerror(errno)); + return 0; + } + + /* + * Check if it a real bios extension. + * The magic number is 0xAA55. + */ + if ( start != lseek(fd, start, SEEK_SET) ) + goto out; + if ( read(fd, &magic, 2) != 2 ) + goto out; + if ( magic != 0xAA55 ) + goto out; + + /* Find the size of the rom extension */ + if ( start != lseek(fd, start, SEEK_SET) ) + goto out; + if ( lseek(fd, 2, SEEK_CUR) != (start + 2) ) + goto out; + if ( read(fd, &bios_size, 1) != 1 ) + goto out; + + /* This size is in 512 bytes */ + bios_size *= 512; + + /* + * Set the file to the begining of the rombios, + * to start the copy. + */ + if ( start != lseek(fd, start, SEEK_SET) ) + goto out; + + if ( bios_size != read(fd, buf, bios_size)) + bios_size = 0; + +out: + close(fd); + return bios_size; +} + +int setup_vga_pt(struct pt_dev *real_device) +{ + unsigned char *bios = NULL; + int bios_size = 0; + char *c = NULL; + char checksum = 0; + int rc = 0; + + if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 ) + return rc; + + /* Allocated 64K for the vga bios */ + if ( !(bios = malloc(64 * 1024)) ) + return -1; + + bios_size = get_vgabios(bios); + if ( bios_size == 0 || bios_size > 64 * 1024) + { + PT_LOG("vga bios size (0x%x) is invalid!\n", bios_size); + rc = -1; + goto out; + } + + /* Adjust the bios checksum */ + for ( c = (char*)bios; c < ((char*)bios + bios_size); c++ ) + checksum += *c; + if ( checksum ) + { + bios[bios_size - 1] -= checksum; + PT_LOG("vga bios checksum is adjusted!\n"); + } + + cpu_physical_memory_rw(0xc0000, bios, bios_size, 1); +out: + free(bios); + return rc; +} diff --git a/xen-hooks.mak b/xen-hooks.mak index 211416e..93f4402 100644 --- a/xen-hooks.mak +++ b/xen-hooks.mak @@ -61,7 +61,7 @@ CONFIG_PASSTHROUGH=1 endif ifdef CONFIG_PASSTHROUGH -OBJS+= pass-through.o pt-msi.o +OBJS+= pass-through.o pt-msi.o pt-graphics.o LIBS += -lpci CFLAGS += -DCONFIG_PASSTHROUGH $(info === PCI passthrough capability has been enabled ===) -- generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |