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
next parent 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).