WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [qemu-xen-unstable] passthrough: basic graphics passthro

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] passthrough: basic graphics passthrough support
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Fri, 18 Sep 2009 09:05:24 -0700
Delivery-date: Fri, 18 Sep 2009 09:05:25 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
commit f09a5ba89434bb3f28172640354258d1d6cd8579
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Fri Sep 18 16:41:42 2009 +0100

    passthrough: basic graphics passthrough support
    
    basic gfx passthrough support:
      - add a vga type for gfx passthrough
      - retrieve VGA bios from host 0xC0000, then load it to guest 0xC0000
      - register/unregister legacy VGA I/O ports and MMIOs for passthroughed gfx
    
    Signed-off-by: Ben Lin <ben.y.lin@xxxxxxxxx>
    Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
    Acked-by: Jean Guyader <jean.guyader@xxxxxxxxxx>
    Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 hw/pass-through.c |  157 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 sysemu.h          |    1 +
 vl.c              |   13 ++++-
 3 files changed, 170 insertions(+), 1 deletions(-)

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 8d80755..a97368a 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -93,6 +93,8 @@
 #include <unistd.h>
 #include <sys/ioctl.h>
 
+extern int gfx_passthru;
+
 struct php_dev {
     struct pt_dev *pt_dev;
     uint8_t valid;
@@ -1781,12 +1783,57 @@ 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;
     uint32_t bar_data = 0;
     struct pci_dev *pci_dev = assigned_device->pci_dev;
     PCIDevice *d = &assigned_device->dev;
+    int ret;
 
     /* Register PIO/MMIO BARs */
     for ( i = 0; i < PCI_BAR_ENTRIES; i++ )
@@ -1842,6 +1889,16 @@ static int pt_register_regions(struct pt_dev 
*assigned_device)
             (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;
+        }
+    }
+
     return 0;
 }
 
@@ -1891,6 +1948,12 @@ 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");
+    }
 }
 
 static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
@@ -4013,6 +4076,89 @@ 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;
+
+    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,
@@ -4123,6 +4269,17 @@ static struct pt_dev * register_real_device(PCIBus 
*e_bus,
     /* Handle real device's MMIO/PIO BARs */
     pt_register_regions(assigned_device);
 
+    /* Setup VGA bios for passthroughed gfx */
+    if ( gfx_passthru && (assigned_device->pci_dev->device_class == 0x0300) )
+    {
+        rc = setup_vga_pt();
+        if ( rc < 0 )
+        {
+            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 ) {
diff --git a/sysemu.h b/sysemu.h
index fb44005..d4e7514 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -85,6 +85,7 @@ extern int bios_size;
 extern int cirrus_vga_enabled;
 extern int std_vga_enabled;
 extern int vmsvga_enabled;
+extern int gfx_passthru;
 extern int graphic_width;
 extern int graphic_height;
 extern int graphic_depth;
diff --git a/vl.c b/vl.c
index 4a331f8..e916561 100644
--- a/vl.c
+++ b/vl.c
@@ -213,6 +213,7 @@ static int rtc_date_offset = -1; /* -1 means no change */
 int cirrus_vga_enabled = 1;
 int std_vga_enabled = 0;
 int vmsvga_enabled = 0;
+int gfx_passthru = 0;
 #ifdef TARGET_SPARC
 int graphic_width = 1024;
 int graphic_height = 768;
@@ -4042,7 +4043,7 @@ static void help(int exitcode)
 #endif
 #endif
            "-portrait       rotate graphical output 90 deg left (only PXA 
LCD)\n"
-           "-vga [std|cirrus|vmware|none]\n"
+           "-vga [std|cirrus|vmware|passthrough|none]\n"
            "                select video card type\n"
            "-full-screen    start in full screen\n"
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
@@ -4269,6 +4270,7 @@ enum {
     /* Xen tree: */
     QEMU_OPTION_disable_opengl,
     QEMU_OPTION_direct_pci,
+    QEMU_OPTION_gfx_passthru,
     QEMU_OPTION_pci_emulation,
     QEMU_OPTION_vncunused,
     QEMU_OPTION_videoram,
@@ -4447,6 +4449,7 @@ static const QEMUOption qemu_options[] = {
 #endif
     { "acpi", 0, QEMU_OPTION_acpi }, /* deprecated, for xend compatibility */
     { "direct_pci", HAS_ARG, QEMU_OPTION_direct_pci },
+    { "gfx_passthru", 0, QEMU_OPTION_gfx_passthru},
     { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
     { "vncunused", 0, QEMU_OPTION_vncunused },
     { "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
@@ -4623,6 +4626,11 @@ static void select_vgahw (const char *p)
         cirrus_vga_enabled = 0;
         std_vga_enabled = 0;
         vmsvga_enabled = 1;
+    } else if (strstart(p, "passthrough", &opts)) {
+        cirrus_vga_enabled = 0;
+        std_vga_enabled = 0;
+        vmsvga_enabled = 0;
+        gfx_passthru = 1;
     } else if (strstart(p, "none", &opts)) {
         cirrus_vga_enabled = 0;
         std_vga_enabled = 0;
@@ -5485,6 +5493,9 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_runas:
                 run_as = optarg;
                 break;
+            case QEMU_OPTION_gfx_passthru:
+                select_vgahw("passthrough");
+                break;
             }
         }
     }
--
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] passthrough: basic graphics passthrough support, Ian Jackson <=