xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Liwei <xieliwei@gmail.com>
To: Gennady Marchenko <gennady.marchenko@gmail.com>
Cc: xen-devel <xen-devel@lists.xensource.com>, xen-users@lists.xensource.com
Subject: Re: Xen, ustable and VGA passthrough
Date: Fri, 20 May 2011 14:08:20 +0800	[thread overview]
Message-ID: <BANLkTimWhPxQUaB0PMbC7bhaZ1PnUDBBDw@mail.gmail.com> (raw)
In-Reply-To: <BANLkTim7Ly7FB1V7GMZLyH=-wVMSdjzY8A@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1299 bytes --]

Hello Gennady!
    Wasn't planning on posting the patch until it works. Also not sure
if it'll end up destroying stuff so, do take care! Not my fault if
unfortunate stuff happens!
    The patch was hastily created on a separate Ubuntu machine with
the source partition mounted, so I couldn't do a compile test nor am I
sure if all the changes I made are in the patch. Tell me if it doesn't
compile after applying the patch, I probably missed a file or two.
    Patch is based on the original VGA passthrough patches posted by
Weidong, modified to account for the ROMBIOS code being moved to its
own file. It includes the claim cycle patch for secondary graphics
card passthrough as well.
    Remember to place your graphics card's firmware into
tools/firmware/vgabios/ after each "make clean".

Regards,
Liwei


On 20 May 2011 08:11, Gennady Marchenko <gennady.marchenko@gmail.com> wrote:
> Hi Liwei!
> Some days ago you post a report to xen-devel about your tries to run your
> vga in pt mode on xen unstable.So could you share the last patched sources
> are you tried to work?
> Because I can't apply several patch to current unstable could you share it
> please?
> I'm already have done about IGD but can't PT the primary ati 5450 at all :(
> Best wishes,
> Gennady.

[-- Attachment #2: vga-pt-xen42-xieliwei.patch --]
[-- Type: application/octet-stream, Size: 10613 bytes --]

--- tools/firmware/hvmloader/acpi/dsdt.asl.orig	2011-05-05 21:18:46.318462147 +0000
+++ tools/firmware/hvmloader/acpi/dsdt.asl	2011-05-02 12:47:44.000000000 +0000
@@ -167,18 +167,46 @@
                     DWordMemory(
                         ResourceProducer, PosDecode, MinFixed, MaxFixed,
                         Cacheable, ReadWrite,
                         0x00000000,
                         0x000A0000,
                         0x000BFFFF,
                         0x00000000,
                         0x00020000)
 
+                    /* reserve MMIO BARs of gfx for 1:1 mapping */
+                    DWordMemory(
+                        ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                        Cacheable, ReadWrite,
+                        0x00000000,
+                        0xE0000000,
+                        0xEFFFFFFF,
+                        0x00000000,
+                        0x10000000)
+
+                    DWordMemory(
+                        ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                        NonCacheable, ReadWrite,
+                        0x00000000,
+                        0xC0000000,
+                        0xC1FFFFFF,
+                        0x00000000,
+                        0x02000000)
+
+                    DWordMemory(
+                        ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                        NonCacheable, ReadWrite,
+                        0x00000000,
+                        0xC2000000,
+                        0xC2FFFFFF,
+                        0x00000000,
+                        0x01000000)
+
                     DWordMemory(
                         ResourceProducer, PosDecode, MinFixed, MaxFixed,
                         Cacheable, ReadWrite,
                         0x00000000,
                         0xF0000000,
                         0xF4FFFFFF,
                         0x00000000,
                         0x05000000,
                         ,, _Y01)
--- tools/firmware/hvmloader/hvmloader.c.orig	2011-05-05 21:18:46.314526582 +0000
+++ tools/firmware/hvmloader/hvmloader.c	2011-05-02 15:28:34.000000000 +0000
@@ -28,8 +28,9 @@
 #include <xen/version.h>
 #include <xen/hvm/params.h>
 
 #define ROM_INCLUDE_VGABIOS
+#define ROM_INCLUDE_PTVGABIOS
 #define ROM_INCLUDE_ETHERBOOT
 #include "roms.inc"
 
 asm (
@@ -113,8 +114,11 @@
 unsigned long pci_mem_end = PCI_MEM_END;
 
 enum virtual_vga virtual_vga = VGA_none;
 
+/* virtual BDF of pass-throughed gfx */
+uint8_t gfx_bdf;
+
 static void init_hypercalls(void)
 {
     uint32_t eax, ebx, ecx, edx;
     unsigned long i;
@@ -432,10 +436,12 @@
         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);
+        memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
+               vgabios_pt, sizeof(vgabios_pt));
+        *(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS + sizeof(vgabios_pt)) = gfx_bdf;
+        vgabios_sz = round_option_rom(sizeof(vgabios_pt) + 1);
         break;
     default:
         printf("No emulated VGA adaptor ...\n");
         break;
--- tools/firmware/hvmloader/Makefile.orig	2011-05-05 21:18:46.314526582 +0000
+++ tools/firmware/hvmloader/Makefile	2011-05-02 14:33:47.000000000 +0000
@@ -55,8 +55,9 @@
 CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.debug.bin
 else
 CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
 endif
+PTVGA_ROM     := ../vgabios/vgabios-pt.bin
 
 .PHONY: all
 all: subdirs-all
 	$(MAKE) hvmloader
@@ -93,8 +94,13 @@
 	echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new
 	sh ./mkhex vgabios_cirrusvga $(CIRRUSVGA_ROM) >> $@.new
 	echo "#endif" >> $@.new
 endif
+ifneq ($(PTVGA_ROM),)
+	echo "#ifdef ROM_INCLUDE_PTVGABIOS" >> $@.new
+	sh ./mkhex vgabios_pt $(PTVGA_ROM) >> $@.new
+	echo "#endif" >> $@.new
+endif
 
 	echo "#ifdef ROM_INCLUDE_ETHERBOOT" >> $@.new
 	cat ../etherboot/eb-roms.h >> $@.new
 	echo "#endif" >> $@.new
--- tools/ioemu-remote/hw/pass-through.c.orig	2011-05-05 21:18:44.914414545 +0000
+++ tools/ioemu-remote/hw/pass-through.c	2011-05-03 00:40:39.323043803 +0000
@@ -843,8 +843,77 @@
         .grp_size = 0,
     },
 };
 
+#define PCI_HEADER_TYPE_ADDR        0x0e
+#define PCI_BRIDGE_FLAG             0x01
+
+#define PCI_CLASS_CODE_ADDR_0       0x09
+#define PCI_CLASS_CODE_ADDR_1       0x0a
+#define PCI_CLASS_CODE_ADDR_2       0x0b
+#define PCI_CLASS_CODE_DATA_0       0x060000
+#define PCI_CLASS_CODE_DATA_1       0x0600
+#define PCI_CLASS_CODE_DATA_2       0x06
+
+#define PCI_SECOND_BUS_NUMBER_ADDR  0x19
+
+#define PCI_BRIDGE_CONTROL_ADDR     0x3e
+#define PCI_BRIDGE_VGA_ENABLE       0x18
+
+#define PCI_GRAPHIC_CONTROL_ADDR    0x52
+#define PCI_HOST_BRIDGE_IGD_VGA_DISABLE 0x02
+
+/*
+ * Claim vga cycle for the graphics card pass-through
+ */
+static uint32_t gfx_claim_vga_cycle(struct pci_access *pci_access,
+       uint32_t bus, uint32_t devfn, uint32_t func)
+{
+    struct pci_dev *pci_dev;
+
+    for ( pci_dev = pci_access->devices; pci_dev != NULL; pci_dev = pci_dev->next )
+    {
+        /* Check whether this is a ordinary bridge */
+        if ( pci_read_byte(pci_dev, PCI_HEADER_TYPE_ADDR) == PCI_BRIDGE_FLAG )
+        {
+            unsigned sec_bus_num = pci_read_byte(pci_dev, PCI_SECOND_BUS_NUMBER_ADDR);
+            unsigned ubrg = pci_read_byte(pci_dev, PCI_BRIDGE_CONTROL_ADDR);
+
+            PT_LOG("bridge for bus %d, previous bridge control is %x\n", sec_bus_num, ubrg);
+            PT_LOG("bus=0x%d, dev=0x%x, func=0x%x\n",pci_dev->bus,pci_dev->dev,pci_dev->func);
+
+            if ( sec_bus_num == bus ) /* VGA device's bridge */
+                ubrg |= PCI_BRIDGE_VGA_ENABLE;
+            else /* Other device's bridge */
+                ubrg &= ~PCI_BRIDGE_VGA_ENABLE;
+
+            pci_write_byte(pci_dev, PCI_BRIDGE_CONTROL_ADDR, ubrg);
+            PT_LOG("bridge for bus %d, updated bridge control is %x\n", sec_bus_num, ubrg);
+        }
+    }
+
+    for ( pci_dev = pci_access->devices; pci_dev != NULL; pci_dev = pci_dev->next )
+    {
+        /* Check host bridge */
+        if ( pci_read_word(pci_dev, PCI_CLASS_CODE_ADDR_1) == PCI_CLASS_CODE_DATA_1 )
+        {
+            unsigned uigd = pci_read_byte(pci_dev, PCI_GRAPHIC_CONTROL_ADDR);
+
+            PT_LOG("previous igd control is %x\n", uigd);
+
+            if ( bus == 0 )
+                uigd &= ~PCI_HOST_BRIDGE_IGD_VGA_DISABLE;
+            else
+                uigd |= PCI_HOST_BRIDGE_IGD_VGA_DISABLE;
+
+            pci_write_byte(pci_dev, PCI_GRAPHIC_CONTROL_ADDR, uigd);
+            PT_LOG("updated igd control is %x\n", uigd);
+        }
+    }
+
+    return 0;
+}
+
 static int token_value(char *token)
 {
     return strtol(token, NULL, 16);
 }
@@ -3242,8 +3311,10 @@
     return 0;
 }
 
 /* read BAR */
+static int gfx_first_read_BAR[7] = {1, 1, 1, 1, 1, 1, 1};
+
 static int pt_bar_reg_read(struct pt_dev *ptdev,
         struct pt_reg_tbl *cfg_entry,
         uint32_t *value, uint32_t valid_mask)
 {
@@ -3264,8 +3335,19 @@
 
     /* use fixed-up value from kernel sysfs */
     *value = ptdev->pci_dev->base_addr[index];
 
+    if ( ptdev->pci_dev->device_class == 0x300 )
+    {
+        if ( gfx_first_read_BAR[index] == 1 )
+        {
+            gfx_first_read_BAR[index] = 0;
+            PT_LOG("first read BARs of gfx\n");
+            return 0;
+        }
+    }
+
+
     /* set emulate mask depend on BAR flag */
     switch (ptdev->bases[index].bar_flag)
     {
     case PT_BAR_FLAG_MEM:
@@ -4252,8 +4334,15 @@
         return NULL;
     }
 
 
+    if ( pci_dev->device_class == 0x0300 )
+    {
+        rc = gfx_claim_vga_cycle(pci_access, r_bus, r_dev, r_func);
+        if ( rc != 0 )
+            return NULL;
+    }
+
     /* reinitialize each config register to be emulated */
     rc = pt_config_init(assigned_device);
     if ( rc < 0 ) {
         return NULL;
--- tools/firmware/hvmloader/rombios.c.orig	2011-05-05 21:18:46.306458208 +0000
+++ tools/firmware/hvmloader/rombios.c	2011-05-02 15:35:04.000000000 +0000
@@ -41,8 +41,11 @@
 #define ROMBIOS_SIZE           0x00010000
 #define ROMBIOS_MAXOFFSET      0x0000FFFF
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
+/* virtual BDF of pass-throughed gfx declared in hvmloader.c*/
+extern uint8_t gfx_bdf;
+
 /*
  * Set up an empty TSS area for virtual 8086 mode to use. 
  * The only important thing is that it musn't have any bits set 
  * in the interrupt redirection bitmap, so all zeros will do.
@@ -151,8 +154,44 @@
             else if ( (vendor_id == 0x1013) && (device_id == 0xb8) )
                 virtual_vga = VGA_cirrus;
             else if ( virtual_vga == VGA_none )
                 virtual_vga = VGA_pt;
+                gfx_bdf = devfn;
+
+                /* Make vBAR=pBAR */
+                printf("Make vBAR = pBAR of assigned gfx\n");
+                for ( bar = 0; bar < 7; bar++ )
+                {
+                    bar_reg = PCI_BASE_ADDRESS_0 + 4*bar;
+                    if ( bar == 6 )
+                            bar_reg = PCI_ROM_ADDRESS;
+                    /* When first time read, it will return physical address */
+                    bar_data = pci_readl(devfn, bar_reg);
+                    pci_writel(devfn, bar_reg, bar_data);
+
+                    /* Now enable the memory or I/O mapping. */
+                    cmd = pci_readw(devfn, PCI_COMMAND);
+                    if ( (bar_reg == PCI_ROM_ADDRESS) ||
+                             ((bar_data & PCI_BASE_ADDRESS_SPACE) ==
+                              PCI_BASE_ADDRESS_SPACE_MEMORY) )
+                          cmd |= PCI_COMMAND_MEMORY;
+                    else
+                          cmd |= PCI_COMMAND_IO;
+                    cmd |= PCI_COMMAND_MASTER;
+                    pci_writew(devfn, PCI_COMMAND, cmd);
+               }
+
+                /* Map the interrupt. */
+                pin = pci_readb(devfn, PCI_INTERRUPT_PIN);
+                if ( pin != 0 )
+                {
+                    /* This is the barber's pole mapping used by Xen. */
+                    link = ((pin - 1) + (devfn >> 3)) & 3;
+                    isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link);
+                    pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq);
+                }
+                continue;
+
             break;
         case 0x0680:
             /* PIIX4 ACPI PM. Special device with special PCI config space. */
             ASSERT((vendor_id == 0x8086) && (device_id == 0x7113));

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

       reply	other threads:[~2011-05-20  6:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <BANLkTim7Ly7FB1V7GMZLyH=-wVMSdjzY8A@mail.gmail.com>
2011-05-20  6:08 ` Liwei [this message]
2011-05-21 15:58   ` Xen, ustable and VGA passthrough Gennady Marchenko
2011-05-22 11:28     ` Pavel Matěja
2011-05-23 13:20     ` Liwei
2011-05-22 12:00   ` Pavel Matěja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BANLkTimWhPxQUaB0PMbC7bhaZ1PnUDBBDw@mail.gmail.com \
    --to=xieliwei@gmail.com \
    --cc=gennady.marchenko@gmail.com \
    --cc=xen-devel@lists.xensource.com \
    --cc=xen-users@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).