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 }; --- 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=$(CURDIR)/../../.. +include $(XEN_ROOT)/Config.mk +OBJS += minios.o +endif + all: $(PCILIB) $(PCILIBPC) $(PCILIB): $(OBJS) --- pciutils-2.2.9.orig/lib/types.h 2009-07-14 18:18:59.000000000 +0200 +++ pciutils-2.2.9/lib/types.h 2009-07-14 18:19:16.000000000 +0200 @@ -20,10 +20,12 @@ typedef DWORD u32; typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; +typedef uint64_t u64; #else typedef u_int8_t u8; typedef u_int16_t u16; typedef u_int32_t u32; +typedef u_int64_t u64; #endif #ifdef PCI_HAVE_64BIT_ADDRESS --- 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,106 @@ +/* + * The PCI Library -- MiniOS PCI frontend access + * + * Samuel Thibault , 2008 + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include +#include +#include +#include "internal.h" + +static int +minios_detect(struct pci_access *a) +{ + return 1; +} + +static void +minios_init(struct pci_access *a) +{ +} + +static void +minios_cleanup(struct pci_access *a) +{ + shutdown_pcifront(NULL); +} + +static void +minios_scan(struct pci_access *a) +{ + 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(NULL, 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(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val)) + return 0; + * buf = val; + return 1; + case 2: + if (pcifront_conf_read(NULL, 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(NULL, 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(NULL, 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 diff -uNpbE -uNpbEr pciutils-2.2.9.orig/lib/sysdep.h pciutils-2.2.9/lib/sysdep.h --- pciutils-2.2.9.orig/lib/sysdep.h 2007-02-06 12:00:18.000000000 +0000 +++ pciutils-2.2.9/lib/sysdep.h 2009-07-22 16:26:30.000000000 +0100 @@ -32,6 +32,10 @@ typedef u16 word; #else +#ifdef PCI_OS_MINIOS +#include +#endif + #ifdef PCI_OS_LINUX #include #define BYTE_ORDER __BYTE_ORDER