aboutsummaryrefslogtreecommitdiffstats
path: root/stubdom/pciutils.patch
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-02 13:54:20 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-02 13:54:20 +0100
commitde4e0840642f41b2a0feef8a97afc360c734bb2b (patch)
tree8dff9dc8e7b57d0bd762cc2dd213fd6ca8600a25 /stubdom/pciutils.patch
parentdac6f79804f05cde83ebd877939b66b71ee8cdf8 (diff)
downloadxen-de4e0840642f41b2a0feef8a97afc360c734bb2b.tar.gz
xen-de4e0840642f41b2a0feef8a97afc360c734bb2b.tar.bz2
xen-de4e0840642f41b2a0feef8a97afc360c734bb2b.zip
stubdom: PCI passthrough support via PV-PCI
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'stubdom/pciutils.patch')
-rw-r--r--stubdom/pciutils.patch299
1 files changed, 299 insertions, 0 deletions
diff --git a/stubdom/pciutils.patch b/stubdom/pciutils.patch
new file mode 100644
index 0000000000..189b7ff719
--- /dev/null
+++ b/stubdom/pciutils.patch
@@ -0,0 +1,299 @@
+diff -urN pciutils-2.2.9.orig/lib/access.c pciutils-2.2.9/lib/access.c
+--- pciutils-2.2.9.orig/lib/access.c 2007-02-06 11:59:43.000000000 +0000
++++ pciutils-2.2.9/lib/access.c 2008-06-30 19:07:09.713187000 +0100
+@@ -57,6 +57,11 @@
+ #else
+ NULL,
+ #endif
++#ifdef PCI_OS_MINIOS
++ &pm_minios,
++#else
++ NULL,
++#endif
+ };
+
+ struct pci_access *
+--- pciutils-2.2.9.orig/lib/pci.h 2006-09-09 13:46:06.000000000 +0100
++++ pciutils-2.2.9/lib/pci.h 2008-06-30 18:56:15.350111000 +0100
+@@ -33,6 +33,7 @@
+ PCI_ACCESS_NBSD_LIBPCI, /* NetBSD libpci */
+ PCI_ACCESS_OBSD_DEVICE, /* OpenBSD /dev/pci */
+ PCI_ACCESS_DUMP, /* Dump file (params: filename) */
++ PCI_ACCESS_MINIOS, /* MiniOS */
+ PCI_ACCESS_MAX
+ };
+
+@@ -63,6 +64,7 @@
+ int fd_rw; /* proc: fd opened read-write */
+ struct pci_dev *cached_dev; /* proc: device the fd is for */
+ int fd_pos; /* proc: current position */
++ void *minios;
+ };
+
+ /* Initialize PCI access */
+--- pciutils-2.2.9.orig/lib/internal.h 2006-09-09 11:52:47.000000000 +0100
++++ pciutils-2.2.9/lib/internal.h 2008-07-01 10:46:24.968202000 +0100
+@@ -37,4 +37,4 @@
+
+ extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
+ pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
+- pm_dump, pm_linux_sysfs;
++ pm_dump, pm_linux_sysfs, pm_minios;
+--- pciutils-2.2.9.orig/lib/Makefile 2007-10-19 13:41:34.000000000 +0100
++++ pciutils-2.2.9/lib/Makefile 2008-07-01 12:13:14.400525000 +0100
+@@ -46,6 +46,12 @@
+ PCILIB=libpciutils.a
+ endif
+
++ifdef PCI_OS_MINIOS
++XEN_ROOT=../../..
++include $(XEN_ROOT)/Config.mk
++OBJS += minios.o
++endif
++
+ all: $(PCILIB) $(PCILIBPC)
+
+ $(PCILIB): $(OBJS)
+--- pciutils-2.2.9.orig/lib/types.h 2007-09-03 09:44:15.000000000 +0100
++++ pciutils-2.2.9/lib/types.h 2008-07-01 12:17:08.396156000 +0100
+@@ -17,9 +17,13 @@
+ typedef DWORD u32;
+ #elif defined(PCI_HAVE_STDINT_H)
+ #include <stdint.h>
++#ifdef PCI_OS_MINIOS
++#include <types.h>
++#else
+ typedef uint8_t u8;
+ typedef uint16_t u16;
+ typedef uint32_t u32;
++#endif
+ #else
+ typedef u_int8_t u8;
+ typedef u_int16_t u16;
+--- pciutils-2.2.9.orig/lib/minios.c 1970-01-01 01:00:00.000000000 +0100
++++ pciutils-2.2.9/lib/minios.c 2008-07-01 12:31:40.554260000 +0100
+@@ -0,0 +1,113 @@
++/*
++ * The PCI Library -- MiniOS PCI frontend access
++ *
++ * Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008
++ *
++ * Can be freely distributed and used under the terms of the GNU GPL.
++ */
++
++#include <os.h>
++#include <pcifront.h>
++#include <xenbus.h>
++#include "internal.h"
++
++static int
++minios_detect(struct pci_access *a)
++{
++ return 1;
++}
++
++static void
++minios_init(struct pci_access *a)
++{
++ a->minios = init_pcifront(NULL);
++ if (!a->minios)
++ a->warning("minios_init open failed");
++}
++
++static void
++minios_cleanup(struct pci_access *a)
++{
++ if (a->minios)
++ shutdown_pcifront(a->minios);
++}
++
++static void
++minios_scan(struct pci_access *a)
++{
++ if (!a->minios)
++ return;
++
++ void func(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun)
++ {
++ struct pci_dev *d = pci_alloc_dev(a);
++
++ d->domain = domain;
++ d->bus = bus;
++ d->dev = slot;
++ d->func = fun;
++
++ pci_link_dev(a, d);
++ }
++
++ pcifront_scan(a->minios, func);
++}
++
++static int
++minios_read(struct pci_dev *d, int pos, byte *buf, int len)
++{
++ unsigned int val;
++ switch (len) {
++ case 1:
++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val))
++ return 0;
++ * buf = val;
++ return 1;
++ case 2:
++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val))
++ return 0;
++ *(u16 *) buf = cpu_to_le16((u16) val);
++ return 1;
++ case 4:
++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val))
++ return 0;
++ *(u32 *) buf = cpu_to_le32((u32) val);
++ return 1;
++ default:
++ return pci_generic_block_read(d, pos, buf, len);
++ }
++}
++
++static int
++minios_write(struct pci_dev *d, int pos, byte *buf, int len)
++{
++ unsigned int val;
++ switch (len) {
++ case 1:
++ val = * buf;
++ break;
++ case 2:
++ val = le16_to_cpu(*(u16 *) buf);
++ break;
++ case 4:
++ val = le32_to_cpu(*(u32 *) buf);
++ break;
++ default:
++ return pci_generic_block_write(d, pos, buf, len);
++ }
++ return !pcifront_conf_write(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, val);
++}
++
++struct pci_methods pm_minios = {
++ "MiniOS-device",
++ NULL, /* config */
++ minios_detect,
++ minios_init,
++ minios_cleanup,
++ minios_scan,
++ pci_generic_fill_info,
++ minios_read,
++ minios_write,
++ NULL, /* dev_init */
++ NULL /* dev_cleanup */
++};
+--- pciutils-2.2.9/lib/generic.c 2007-02-06 12:00:05.000000000 +0000
++++ pciutils-2.2.9-mine/lib/generic.c 2008-07-01 19:13:52.289949000 +0100
+@@ -74,6 +74,19 @@
+ pci_generic_scan_bus(a, busmap, 0);
+ }
+
++static u32 pci_size(u32 base, u32 maxbase, u32 mask)
++{
++ u32 size = mask & maxbase;
++ if (!size)
++ return 0;
++ size = (size & ~(size-1)) - 1;
++
++ if (base == maxbase && ((base | size) & mask) != mask)
++ return 0;
++
++ return size + 1;
++}
++
+ int
+ pci_generic_fill_info(struct pci_dev *d, int flags)
+ {
+@@ -114,23 +127,61 @@
+ if (!x || x == (u32) ~0)
+ continue;
+ if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+- d->base_addr[i] = x;
+- else
++ {
++ d->base_addr[i] = x & PCI_BASE_ADDRESS_IO_MASK;
++ if (flags & PCI_FILL_SIZES)
++ {
++ u32 size;
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
++ d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_IO_MASK);
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
++ }
++ }
++ else
+ {
+ if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
+- d->base_addr[i] = x;
++ {
++ d->base_addr[i] = x & PCI_BASE_ADDRESS_MEM_MASK;
++ if (flags & PCI_FILL_SIZES)
++ {
++ u32 size;
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
++ d->size[i] = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
++ d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_MEM_MASK);
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
++ }
++ }
+ else if (i >= cnt-1)
+ a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
+ else
+ {
+ u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
+ #ifdef PCI_HAVE_64BIT_ADDRESS
+- d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
++ d->base_addr[i-1] = (x | (((pciaddr_t) y) << 32)) & PCI_BASE_ADDRESS_MEM_MASK;
++ if (flags & PCI_FILL_SIZES)
++ {
++ u32 size;
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
++ d->size[i-1] = pci_size(y, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4) |
++ pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), 0xffffffff );
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, y);
++ }
+ #else
+ if (y)
+ a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
+ else
+- d->base_addr[i-1] = x;
++ {
++ d->base_addr[i-1] = x & PCI_BASE_ADDRESS_MEM_MASK;
++ if (flags & PCI_FILL_SIZES)
++ {
++ u32 size;
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
++ d->size[i-1] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4), PCI_BASE_ADDRESS_MEM_MASK);
++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
++ }
++ }
+ #endif
+ }
+ }
+@@ -154,10 +205,19 @@
+ {
+ u32 u = pci_read_long(d, reg);
+ if (u != 0xffffffff)
+- d->rom_base_addr = u;
++ {
++ d->rom_base_addr = u;
++ if (flags & PCI_FILL_SIZES)
++ {
++ u32 size;
++ pci_write_long(d, reg, ~0);
++ d->rom_size = pci_read_long(d, reg);
++ pci_write_long(d, reg, u);
++ }
++ }
+ }
+ }
+- return flags & ~PCI_FILL_SIZES;
++ return flags;
+ }
+
+ static int