debuggers.hg
changeset 17984:b3d827e63a09
stubdom: PCI passthrough support via PV-PCI
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jul 02 13:54:20 2008 +0100 (2008-07-02) |
parents | dea9d5769d56 |
children | 3a40a6997cc0 |
files | extras/mini-os/include/pcifront.h extras/mini-os/include/posix/sys/mman.h extras/mini-os/kernel.c extras/mini-os/pcifront.c stubdom/Makefile stubdom/libpci.config.h stubdom/libpci.config.mak stubdom/pciutils.patch tools/ioemu/Makefile.target tools/ioemu/hw/pass-through.c tools/ioemu/xenstore.c |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/extras/mini-os/include/pcifront.h Wed Jul 02 13:54:20 2008 +0100 1.3 @@ -0,0 +1,15 @@ 1.4 +#include <types.h> 1.5 +#include <xen/io/pciif.h> 1.6 +struct pcifront_dev; 1.7 +struct pcifront_dev *init_pcifront(char *nodename); 1.8 +void pcifront_scan(struct pcifront_dev *dev, void (*fun)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun)); 1.9 +void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op); 1.10 +void shutdown_pcifront(struct pcifront_dev *dev); 1.11 +int pcifront_conf_read(struct pcifront_dev *dev, 1.12 + unsigned int dom, 1.13 + unsigned int bus, unsigned int slot, unsigned long fun, 1.14 + unsigned int off, unsigned int size, unsigned int *val); 1.15 +int pcifront_conf_write(struct pcifront_dev *dev, 1.16 + unsigned int dom, 1.17 + unsigned int bus, unsigned int slot, unsigned long fun, 1.18 + unsigned int off, unsigned int size, unsigned int val);
2.1 --- a/extras/mini-os/include/posix/sys/mman.h Wed Jul 02 13:37:16 2008 +0100 2.2 +++ b/extras/mini-os/include/posix/sys/mman.h Wed Jul 02 13:54:20 2008 +0100 2.3 @@ -9,6 +9,9 @@ 2.4 #define MAP_PRIVATE 0x02 2.5 #define MAP_ANON 0x20 2.6 2.7 +/* Pages are always resident anyway */ 2.8 +#define MAP_LOCKED 0x0 2.9 + 2.10 #define MAP_FAILED ((void*)0) 2.11 2.12 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
3.1 --- a/extras/mini-os/kernel.c Wed Jul 02 13:37:16 2008 +0100 3.2 +++ b/extras/mini-os/kernel.c Wed Jul 02 13:54:20 2008 +0100 3.3 @@ -40,6 +40,7 @@ 3.4 #include <netfront.h> 3.5 #include <blkfront.h> 3.6 #include <fbfront.h> 3.7 +#include <pcifront.h> 3.8 #include <fs.h> 3.9 #include <xmalloc.h> 3.10 #include <fcntl.h> 3.11 @@ -431,6 +432,27 @@ static void kbdfront_thread(void *p) 3.12 } 3.13 } 3.14 3.15 +static struct pcifront_dev *pci_dev; 3.16 + 3.17 +static void pcifront_thread(void *p) 3.18 +{ 3.19 + void print(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun) 3.20 + { 3.21 + unsigned int vendor, device, rev, class; 3.22 + 3.23 + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x00, 2, &vendor); 3.24 + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x02, 2, &device); 3.25 + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x08, 1, &rev); 3.26 + pcifront_conf_read(pci_dev, domain, bus, slot, fun, 0x0a, 2, &class); 3.27 + 3.28 + printk("%04x:%02x:%02x.%02x %04x: %04x:%04x (rev %02x)\n", domain, bus, slot, fun, class, vendor, device, rev); 3.29 + } 3.30 + 3.31 + pci_dev = init_pcifront(NULL); 3.32 + printk("PCI devices:\n"); 3.33 + pcifront_scan(pci_dev, print); 3.34 +} 3.35 + 3.36 static void fs_thread(void *p) 3.37 { 3.38 init_fs_frontend(); 3.39 @@ -446,6 +468,7 @@ static void fs_thread(void *p) 3.40 create_thread("blkfront", blkfront_thread, si); 3.41 create_thread("fbfront", fbfront_thread, si); 3.42 create_thread("kbdfront", kbdfront_thread, si); 3.43 + create_thread("pcifront", pcifront_thread, si); 3.44 create_thread("fs-frontend", fs_thread, si); 3.45 return 0; 3.46 } 3.47 @@ -524,6 +547,9 @@ void stop_kernel(void) 3.48 if (kbd_dev) 3.49 shutdown_kbdfront(kbd_dev); 3.50 3.51 + if (pci_dev) 3.52 + shutdown_pcifront(pci_dev); 3.53 + 3.54 /* TODO: fs import */ 3.55 3.56 local_irq_disable();
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/extras/mini-os/pcifront.c Wed Jul 02 13:54:20 2008 +0100 4.3 @@ -0,0 +1,278 @@ 4.4 +/* Minimal PCI driver for Mini-OS. 4.5 + * Copyright (c) 2007-2008 Samuel Thibault. 4.6 + * Based on blkfront.c. 4.7 + */ 4.8 + 4.9 +#include <os.h> 4.10 +#include <xenbus.h> 4.11 +#include <events.h> 4.12 +#include <errno.h> 4.13 +#include <gnttab.h> 4.14 +#include <xmalloc.h> 4.15 +#include <wait.h> 4.16 +#include <pcifront.h> 4.17 + 4.18 +#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) 4.19 + 4.20 +DECLARE_WAIT_QUEUE_HEAD(pcifront_queue); 4.21 + 4.22 +struct pcifront_dev { 4.23 + domid_t dom; 4.24 + 4.25 + struct xen_pci_sharedinfo *info; 4.26 + grant_ref_t info_ref; 4.27 + evtchn_port_t evtchn; 4.28 + 4.29 + char *nodename; 4.30 + char *backend; 4.31 + 4.32 + xenbus_event_queue events; 4.33 +}; 4.34 + 4.35 +void pcifront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) 4.36 +{ 4.37 + wake_up(&pcifront_queue); 4.38 +} 4.39 + 4.40 +static void free_pcifront(struct pcifront_dev *dev) 4.41 +{ 4.42 + mask_evtchn(dev->evtchn); 4.43 + 4.44 + free(dev->backend); 4.45 + 4.46 + gnttab_end_access(dev->info_ref); 4.47 + free_page(dev->info); 4.48 + 4.49 + unbind_evtchn(dev->evtchn); 4.50 + 4.51 + free(dev->nodename); 4.52 + free(dev); 4.53 +} 4.54 + 4.55 +struct pcifront_dev *init_pcifront(char *nodename) 4.56 +{ 4.57 + xenbus_transaction_t xbt; 4.58 + char* err; 4.59 + char* message=NULL; 4.60 + int retry=0; 4.61 + char* msg; 4.62 + 4.63 + struct pcifront_dev *dev; 4.64 + 4.65 + if (!nodename) 4.66 + nodename = "device/pci/0"; 4.67 + 4.68 + char path[strlen(nodename) + 1 + 10 + 1]; 4.69 + 4.70 + printk("******************* PCIFRONT for %s **********\n\n\n", nodename); 4.71 + 4.72 + dev = malloc(sizeof(*dev)); 4.73 + memset(dev, 0, sizeof(*dev)); 4.74 + dev->nodename = strdup(nodename); 4.75 + 4.76 + snprintf(path, sizeof(path), "%s/backend-id", nodename); 4.77 + dev->dom = xenbus_read_integer(path); 4.78 + evtchn_alloc_unbound(dev->dom, pcifront_handler, dev, &dev->evtchn); 4.79 + 4.80 + dev->info = (struct xen_pci_sharedinfo*) alloc_page(); 4.81 + memset(dev->info,0,PAGE_SIZE); 4.82 + 4.83 + dev->info_ref = gnttab_grant_access(dev->dom,virt_to_mfn(dev->info),0); 4.84 + 4.85 + dev->events = NULL; 4.86 + 4.87 +again: 4.88 + err = xenbus_transaction_start(&xbt); 4.89 + if (err) { 4.90 + printk("starting transaction\n"); 4.91 + } 4.92 + 4.93 + err = xenbus_printf(xbt, nodename, "pci-op-ref","%u", 4.94 + dev->info_ref); 4.95 + if (err) { 4.96 + message = "writing pci-op-ref"; 4.97 + goto abort_transaction; 4.98 + } 4.99 + err = xenbus_printf(xbt, nodename, 4.100 + "event-channel", "%u", dev->evtchn); 4.101 + if (err) { 4.102 + message = "writing event-channel"; 4.103 + goto abort_transaction; 4.104 + } 4.105 + err = xenbus_printf(xbt, nodename, 4.106 + "magic", XEN_PCI_MAGIC); 4.107 + if (err) { 4.108 + message = "writing magic"; 4.109 + goto abort_transaction; 4.110 + } 4.111 + 4.112 + err = xenbus_printf(xbt, nodename, "state", "%u", 4.113 + 3); /* initialised */ 4.114 + 4.115 + 4.116 + err = xenbus_transaction_end(xbt, 0, &retry); 4.117 + if (retry) { 4.118 + goto again; 4.119 + printk("completing transaction\n"); 4.120 + } 4.121 + 4.122 + goto done; 4.123 + 4.124 +abort_transaction: 4.125 + xenbus_transaction_end(xbt, 1, &retry); 4.126 + goto error; 4.127 + 4.128 +done: 4.129 + 4.130 + snprintf(path, sizeof(path), "%s/backend", nodename); 4.131 + msg = xenbus_read(XBT_NIL, path, &dev->backend); 4.132 + if (msg) { 4.133 + printk("Error %s when reading the backend path %s\n", msg, path); 4.134 + goto error; 4.135 + } 4.136 + 4.137 + printk("backend at %s\n", dev->backend); 4.138 + 4.139 + { 4.140 + char path[strlen(dev->backend) + 1 + 5 + 1]; 4.141 + snprintf(path, sizeof(path), "%s/state", dev->backend); 4.142 + 4.143 + xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); 4.144 + 4.145 + xenbus_wait_for_value(path, "4", &dev->events); 4.146 + 4.147 + xenbus_printf(xbt, nodename, "state", "%u", 4); /* connected */ 4.148 + } 4.149 + unmask_evtchn(dev->evtchn); 4.150 + 4.151 + printk("**************************\n"); 4.152 + 4.153 + return dev; 4.154 + 4.155 +error: 4.156 + free_pcifront(dev); 4.157 + return NULL; 4.158 +} 4.159 + 4.160 +void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun)) 4.161 +{ 4.162 + char path[strlen(dev->backend) + 1 + 5 + 10 + 1]; 4.163 + int i, n; 4.164 + char *s, *msg; 4.165 + unsigned int domain, bus, slot, fun; 4.166 + 4.167 + snprintf(path, sizeof(path), "%s/num_devs", dev->backend); 4.168 + n = xenbus_read_integer(path); 4.169 + 4.170 + for (i = 0; i < n; i++) { 4.171 + snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i); 4.172 + msg = xenbus_read(XBT_NIL, path, &s); 4.173 + if (msg) { 4.174 + printk("Error %s when reading the PCI root name at %s\n", path); 4.175 + continue; 4.176 + } 4.177 + 4.178 + if (sscanf(s, "%x:%x:%x.%x", &domain, &bus, &slot, &fun) != 4) { 4.179 + printk("\"%s\" does not look like a PCI device address\n", s); 4.180 + free(s); 4.181 + continue; 4.182 + } 4.183 + free(s); 4.184 + 4.185 + func(domain, bus, slot, fun); 4.186 + } 4.187 +} 4.188 + 4.189 +void shutdown_pcifront(struct pcifront_dev *dev) 4.190 +{ 4.191 + char* err; 4.192 + char *nodename = dev->nodename; 4.193 + 4.194 + char path[strlen(dev->backend) + 1 + 5 + 1]; 4.195 + 4.196 + printk("close pci: backend at %s\n",dev->backend); 4.197 + 4.198 + snprintf(path, sizeof(path), "%s/state", dev->backend); 4.199 + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */ 4.200 + xenbus_wait_for_value(path, "5", &dev->events); 4.201 + 4.202 + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); 4.203 + xenbus_wait_for_value(path, "6", &dev->events); 4.204 + 4.205 + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); 4.206 + xenbus_wait_for_value(path, "2", &dev->events); 4.207 + 4.208 + xenbus_unwatch_path(XBT_NIL, path); 4.209 + 4.210 + snprintf(path, sizeof(path), "%s/info-ref", nodename); 4.211 + xenbus_rm(XBT_NIL, path); 4.212 + snprintf(path, sizeof(path), "%s/event-channel", nodename); 4.213 + xenbus_rm(XBT_NIL, path); 4.214 + 4.215 + free_pcifront(dev); 4.216 +} 4.217 + 4.218 + 4.219 +void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op) 4.220 +{ 4.221 + dev->info->op = *op; 4.222 + /* Make sure info is written before the flag */ 4.223 + wmb(); 4.224 + set_bit(_XEN_PCIF_active, &dev->info->flags); 4.225 + notify_remote_via_evtchn(dev->evtchn); 4.226 + 4.227 + wait_event(pcifront_queue, !test_bit(_XEN_PCIF_active, &dev->info->flags)); 4.228 + 4.229 + /* Make sure flag is read before info */ 4.230 + rmb(); 4.231 + *op = dev->info->op; 4.232 +} 4.233 + 4.234 +int pcifront_conf_read(struct pcifront_dev *dev, 4.235 + unsigned int dom, 4.236 + unsigned int bus, unsigned int slot, unsigned long fun, 4.237 + unsigned int off, unsigned int size, unsigned int *val) 4.238 +{ 4.239 + struct xen_pci_op op; 4.240 + 4.241 + memset(&op, 0, sizeof(op)); 4.242 + 4.243 + op.cmd = XEN_PCI_OP_conf_read; 4.244 + op.domain = dom; 4.245 + op.bus = bus; 4.246 + op.devfn = PCI_DEVFN(slot, fun); 4.247 + op.offset = off; 4.248 + op.size = size; 4.249 + 4.250 + pcifront_op(dev, &op); 4.251 + 4.252 + if (op.err) 4.253 + return op.err; 4.254 + 4.255 + *val = op.value; 4.256 + 4.257 + return 0; 4.258 +} 4.259 + 4.260 +int pcifront_conf_write(struct pcifront_dev *dev, 4.261 + unsigned int dom, 4.262 + unsigned int bus, unsigned int slot, unsigned long fun, 4.263 + unsigned int off, unsigned int size, unsigned int val) 4.264 +{ 4.265 + struct xen_pci_op op; 4.266 + 4.267 + memset(&op, 0, sizeof(op)); 4.268 + 4.269 + op.cmd = XEN_PCI_OP_conf_write; 4.270 + op.domain = dom; 4.271 + op.bus = bus; 4.272 + op.devfn = PCI_DEVFN(slot, fun); 4.273 + op.offset = off; 4.274 + op.size = size; 4.275 + 4.276 + op.value = val; 4.277 + 4.278 + pcifront_op(dev, &op); 4.279 + 4.280 + return op.err; 4.281 +}
5.1 --- a/stubdom/Makefile Wed Jul 02 13:37:16 2008 +0100 5.2 +++ b/stubdom/Makefile Wed Jul 02 13:54:20 2008 +0100 5.3 @@ -131,16 +131,20 @@ cross-zlib: $(ZLIB_STAMPFILE) 5.4 pciutils-$(LIBPCI_VERSION).tar.bz2: 5.5 $(WGET) http://www.kernel.org/pub/software/utils/pciutils/pciutils-$(LIBPCI_VERSION).tar.bz2 5.6 5.7 +pciutils-$(LIBPCI_VERSION): pciutils-$(LIBPCI_VERSION).tar.bz2 5.8 + tar xjf $< 5.9 + patch -d $@ -p1 < pciutils.patch 5.10 + touch $@ 5.11 + 5.12 LIBPCI_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libpci.a 5.13 .PHONY: cross-libpci 5.14 cross-libpci: $(LIBPCI_STAMPFILE) 5.15 -$(LIBPCI_STAMPFILE): pciutils-$(LIBPCI_VERSION).tar.bz2 $(NEWLIB_STAMPFILE) $(ZLIB_STAMPFILE) 5.16 - tar xjf $< 5.17 +$(LIBPCI_STAMPFILE): pciutils-$(LIBPCI_VERSION) $(NEWLIB_STAMPFILE) $(ZLIB_STAMPFILE) 5.18 ( cd pciutils-$(LIBPCI_VERSION) && \ 5.19 cp ../libpci.config.h lib/config.h && \ 5.20 echo '#define PCILIB_VERSION "$(LIBPCI_VERSION)"' >> lib/config.h && \ 5.21 cp ../libpci.config.mak lib/config.mk && \ 5.22 - $(MAKE) CC="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" lib/libpci.a && \ 5.23 + $(MAKE) CC="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS) -I$(realpath $(MINI_OS)/include)" lib/libpci.a && \ 5.24 $(INSTALL_DATA) lib/libpci.a $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib/ && \ 5.25 $(INSTALL_DIR) $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci && \ 5.26 $(INSTALL_DATA) lib/{config,header,pci,types}.h $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci/ \
6.1 --- a/stubdom/libpci.config.h Wed Jul 02 13:37:16 2008 +0100 6.2 +++ b/stubdom/libpci.config.h Wed Jul 02 13:54:20 2008 +0100 6.3 @@ -1,4 +1,4 @@ 6.4 -#define PCI_OS_STUBDOM 6.5 +#define PCI_OS_MINIOS 6.6 #define PCI_HAVE_STDINT_H 6.7 #define PCI_PATH_IDS_DIR "." 6.8 #define PCI_COMPRESSED_IDS
7.1 --- a/stubdom/libpci.config.mak Wed Jul 02 13:37:16 2008 +0100 7.2 +++ b/stubdom/libpci.config.mak Wed Jul 02 13:54:20 2008 +0100 7.3 @@ -1,2 +1,7 @@ 7.4 LIBZ=-lz 7.5 LDLIBS+=$(LIBZ) 7.6 +PCI_OS_MINIOS=1 7.7 +PCI_HAVE_STDINT_H=1 7.8 +PCI_PATH_IDS_DIR=. 7.9 +PCI_COMPRESSED_IDS=1 7.10 +PCI_IDS=pci.ids.gz
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/stubdom/pciutils.patch Wed Jul 02 13:54:20 2008 +0100 8.3 @@ -0,0 +1,299 @@ 8.4 +diff -urN pciutils-2.2.9.orig/lib/access.c pciutils-2.2.9/lib/access.c 8.5 +--- pciutils-2.2.9.orig/lib/access.c 2007-02-06 11:59:43.000000000 +0000 8.6 ++++ pciutils-2.2.9/lib/access.c 2008-06-30 19:07:09.713187000 +0100 8.7 +@@ -57,6 +57,11 @@ 8.8 + #else 8.9 + NULL, 8.10 + #endif 8.11 ++#ifdef PCI_OS_MINIOS 8.12 ++ &pm_minios, 8.13 ++#else 8.14 ++ NULL, 8.15 ++#endif 8.16 + }; 8.17 + 8.18 + struct pci_access * 8.19 +--- pciutils-2.2.9.orig/lib/pci.h 2006-09-09 13:46:06.000000000 +0100 8.20 ++++ pciutils-2.2.9/lib/pci.h 2008-06-30 18:56:15.350111000 +0100 8.21 +@@ -33,6 +33,7 @@ 8.22 + PCI_ACCESS_NBSD_LIBPCI, /* NetBSD libpci */ 8.23 + PCI_ACCESS_OBSD_DEVICE, /* OpenBSD /dev/pci */ 8.24 + PCI_ACCESS_DUMP, /* Dump file (params: filename) */ 8.25 ++ PCI_ACCESS_MINIOS, /* MiniOS */ 8.26 + PCI_ACCESS_MAX 8.27 + }; 8.28 + 8.29 +@@ -63,6 +64,7 @@ 8.30 + int fd_rw; /* proc: fd opened read-write */ 8.31 + struct pci_dev *cached_dev; /* proc: device the fd is for */ 8.32 + int fd_pos; /* proc: current position */ 8.33 ++ void *minios; 8.34 + }; 8.35 + 8.36 + /* Initialize PCI access */ 8.37 +--- pciutils-2.2.9.orig/lib/internal.h 2006-09-09 11:52:47.000000000 +0100 8.38 ++++ pciutils-2.2.9/lib/internal.h 2008-07-01 10:46:24.968202000 +0100 8.39 +@@ -37,4 +37,4 @@ 8.40 + 8.41 + extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc, 8.42 + pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device, 8.43 +- pm_dump, pm_linux_sysfs; 8.44 ++ pm_dump, pm_linux_sysfs, pm_minios; 8.45 +--- pciutils-2.2.9.orig/lib/Makefile 2007-10-19 13:41:34.000000000 +0100 8.46 ++++ pciutils-2.2.9/lib/Makefile 2008-07-01 12:13:14.400525000 +0100 8.47 +@@ -46,6 +46,12 @@ 8.48 + PCILIB=libpciutils.a 8.49 + endif 8.50 + 8.51 ++ifdef PCI_OS_MINIOS 8.52 ++XEN_ROOT=../../.. 8.53 ++include $(XEN_ROOT)/Config.mk 8.54 ++OBJS += minios.o 8.55 ++endif 8.56 ++ 8.57 + all: $(PCILIB) $(PCILIBPC) 8.58 + 8.59 + $(PCILIB): $(OBJS) 8.60 +--- pciutils-2.2.9.orig/lib/types.h 2007-09-03 09:44:15.000000000 +0100 8.61 ++++ pciutils-2.2.9/lib/types.h 2008-07-01 12:17:08.396156000 +0100 8.62 +@@ -17,9 +17,13 @@ 8.63 + typedef DWORD u32; 8.64 + #elif defined(PCI_HAVE_STDINT_H) 8.65 + #include <stdint.h> 8.66 ++#ifdef PCI_OS_MINIOS 8.67 ++#include <types.h> 8.68 ++#else 8.69 + typedef uint8_t u8; 8.70 + typedef uint16_t u16; 8.71 + typedef uint32_t u32; 8.72 ++#endif 8.73 + #else 8.74 + typedef u_int8_t u8; 8.75 + typedef u_int16_t u16; 8.76 +--- pciutils-2.2.9.orig/lib/minios.c 1970-01-01 01:00:00.000000000 +0100 8.77 ++++ pciutils-2.2.9/lib/minios.c 2008-07-01 12:31:40.554260000 +0100 8.78 +@@ -0,0 +1,113 @@ 8.79 ++/* 8.80 ++ * The PCI Library -- MiniOS PCI frontend access 8.81 ++ * 8.82 ++ * Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008 8.83 ++ * 8.84 ++ * Can be freely distributed and used under the terms of the GNU GPL. 8.85 ++ */ 8.86 ++ 8.87 ++#include <os.h> 8.88 ++#include <pcifront.h> 8.89 ++#include <xenbus.h> 8.90 ++#include "internal.h" 8.91 ++ 8.92 ++static int 8.93 ++minios_detect(struct pci_access *a) 8.94 ++{ 8.95 ++ return 1; 8.96 ++} 8.97 ++ 8.98 ++static void 8.99 ++minios_init(struct pci_access *a) 8.100 ++{ 8.101 ++ a->minios = init_pcifront(NULL); 8.102 ++ if (!a->minios) 8.103 ++ a->warning("minios_init open failed"); 8.104 ++} 8.105 ++ 8.106 ++static void 8.107 ++minios_cleanup(struct pci_access *a) 8.108 ++{ 8.109 ++ if (a->minios) 8.110 ++ shutdown_pcifront(a->minios); 8.111 ++} 8.112 ++ 8.113 ++static void 8.114 ++minios_scan(struct pci_access *a) 8.115 ++{ 8.116 ++ if (!a->minios) 8.117 ++ return; 8.118 ++ 8.119 ++ void func(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun) 8.120 ++ { 8.121 ++ struct pci_dev *d = pci_alloc_dev(a); 8.122 ++ 8.123 ++ d->domain = domain; 8.124 ++ d->bus = bus; 8.125 ++ d->dev = slot; 8.126 ++ d->func = fun; 8.127 ++ 8.128 ++ pci_link_dev(a, d); 8.129 ++ } 8.130 ++ 8.131 ++ pcifront_scan(a->minios, func); 8.132 ++} 8.133 ++ 8.134 ++static int 8.135 ++minios_read(struct pci_dev *d, int pos, byte *buf, int len) 8.136 ++{ 8.137 ++ unsigned int val; 8.138 ++ switch (len) { 8.139 ++ case 1: 8.140 ++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val)) 8.141 ++ return 0; 8.142 ++ * buf = val; 8.143 ++ return 1; 8.144 ++ case 2: 8.145 ++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val)) 8.146 ++ return 0; 8.147 ++ *(u16 *) buf = cpu_to_le16((u16) val); 8.148 ++ return 1; 8.149 ++ case 4: 8.150 ++ if (pcifront_conf_read(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, &val)) 8.151 ++ return 0; 8.152 ++ *(u32 *) buf = cpu_to_le32((u32) val); 8.153 ++ return 1; 8.154 ++ default: 8.155 ++ return pci_generic_block_read(d, pos, buf, len); 8.156 ++ } 8.157 ++} 8.158 ++ 8.159 ++static int 8.160 ++minios_write(struct pci_dev *d, int pos, byte *buf, int len) 8.161 ++{ 8.162 ++ unsigned int val; 8.163 ++ switch (len) { 8.164 ++ case 1: 8.165 ++ val = * buf; 8.166 ++ break; 8.167 ++ case 2: 8.168 ++ val = le16_to_cpu(*(u16 *) buf); 8.169 ++ break; 8.170 ++ case 4: 8.171 ++ val = le32_to_cpu(*(u32 *) buf); 8.172 ++ break; 8.173 ++ default: 8.174 ++ return pci_generic_block_write(d, pos, buf, len); 8.175 ++ } 8.176 ++ return !pcifront_conf_write(d->access->minios, d->domain, d->bus, d->dev, d->func, pos, len, val); 8.177 ++} 8.178 ++ 8.179 ++struct pci_methods pm_minios = { 8.180 ++ "MiniOS-device", 8.181 ++ NULL, /* config */ 8.182 ++ minios_detect, 8.183 ++ minios_init, 8.184 ++ minios_cleanup, 8.185 ++ minios_scan, 8.186 ++ pci_generic_fill_info, 8.187 ++ minios_read, 8.188 ++ minios_write, 8.189 ++ NULL, /* dev_init */ 8.190 ++ NULL /* dev_cleanup */ 8.191 ++}; 8.192 +--- pciutils-2.2.9/lib/generic.c 2007-02-06 12:00:05.000000000 +0000 8.193 ++++ pciutils-2.2.9-mine/lib/generic.c 2008-07-01 19:13:52.289949000 +0100 8.194 +@@ -74,6 +74,19 @@ 8.195 + pci_generic_scan_bus(a, busmap, 0); 8.196 + } 8.197 + 8.198 ++static u32 pci_size(u32 base, u32 maxbase, u32 mask) 8.199 ++{ 8.200 ++ u32 size = mask & maxbase; 8.201 ++ if (!size) 8.202 ++ return 0; 8.203 ++ size = (size & ~(size-1)) - 1; 8.204 ++ 8.205 ++ if (base == maxbase && ((base | size) & mask) != mask) 8.206 ++ return 0; 8.207 ++ 8.208 ++ return size + 1; 8.209 ++} 8.210 ++ 8.211 + int 8.212 + pci_generic_fill_info(struct pci_dev *d, int flags) 8.213 + { 8.214 +@@ -114,23 +127,61 @@ 8.215 + if (!x || x == (u32) ~0) 8.216 + continue; 8.217 + if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) 8.218 +- d->base_addr[i] = x; 8.219 +- else 8.220 ++ { 8.221 ++ d->base_addr[i] = x & PCI_BASE_ADDRESS_IO_MASK; 8.222 ++ if (flags & PCI_FILL_SIZES) 8.223 ++ { 8.224 ++ u32 size; 8.225 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0); 8.226 ++ d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_IO_MASK); 8.227 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x); 8.228 ++ } 8.229 ++ } 8.230 ++ else 8.231 + { 8.232 + if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64) 8.233 +- d->base_addr[i] = x; 8.234 ++ { 8.235 ++ d->base_addr[i] = x & PCI_BASE_ADDRESS_MEM_MASK; 8.236 ++ if (flags & PCI_FILL_SIZES) 8.237 ++ { 8.238 ++ u32 size; 8.239 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0); 8.240 ++ d->size[i] = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4); 8.241 ++ d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_MEM_MASK); 8.242 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x); 8.243 ++ } 8.244 ++ } 8.245 + else if (i >= cnt-1) 8.246 + a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i); 8.247 + else 8.248 + { 8.249 + u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4); 8.250 + #ifdef PCI_HAVE_64BIT_ADDRESS 8.251 +- d->base_addr[i-1] = x | (((pciaddr_t) y) << 32); 8.252 ++ d->base_addr[i-1] = (x | (((pciaddr_t) y) << 32)) & PCI_BASE_ADDRESS_MEM_MASK; 8.253 ++ if (flags & PCI_FILL_SIZES) 8.254 ++ { 8.255 ++ u32 size; 8.256 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0); 8.257 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0); 8.258 ++ d->size[i-1] = pci_size(y, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4) | 8.259 ++ pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), 0xffffffff ); 8.260 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x); 8.261 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, y); 8.262 ++ } 8.263 + #else 8.264 + if (y) 8.265 + a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func); 8.266 + else 8.267 +- d->base_addr[i-1] = x; 8.268 ++ { 8.269 ++ d->base_addr[i-1] = x & PCI_BASE_ADDRESS_MEM_MASK; 8.270 ++ if (flags & PCI_FILL_SIZES) 8.271 ++ { 8.272 ++ u32 size; 8.273 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0); 8.274 ++ d->size[i-1] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4), PCI_BASE_ADDRESS_MEM_MASK); 8.275 ++ pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x); 8.276 ++ } 8.277 ++ } 8.278 + #endif 8.279 + } 8.280 + } 8.281 +@@ -154,10 +205,19 @@ 8.282 + { 8.283 + u32 u = pci_read_long(d, reg); 8.284 + if (u != 0xffffffff) 8.285 +- d->rom_base_addr = u; 8.286 ++ { 8.287 ++ d->rom_base_addr = u; 8.288 ++ if (flags & PCI_FILL_SIZES) 8.289 ++ { 8.290 ++ u32 size; 8.291 ++ pci_write_long(d, reg, ~0); 8.292 ++ d->rom_size = pci_read_long(d, reg); 8.293 ++ pci_write_long(d, reg, u); 8.294 ++ } 8.295 ++ } 8.296 + } 8.297 + } 8.298 +- return flags & ~PCI_FILL_SIZES; 8.299 ++ return flags; 8.300 + } 8.301 + 8.302 + static int
9.1 --- a/tools/ioemu/Makefile.target Wed Jul 02 13:37:16 2008 +0100 9.2 +++ b/tools/ioemu/Makefile.target Wed Jul 02 13:54:20 2008 +0100 9.3 @@ -358,7 +358,7 @@ VL_OBJS+=tap-win32.o 9.4 endif 9.5 9.6 ifdef CONFIG_STUBDOM 9.7 -#CONFIG_PASSTHROUGH=1 9.8 +CONFIG_PASSTHROUGH=1 9.9 else 9.10 ifeq (,$(wildcard /usr/include/pci)) 9.11 $(warning *** pciutils-devl package not found - missing /usr/include/pci)
10.1 --- a/tools/ioemu/hw/pass-through.c Wed Jul 02 13:37:16 2008 +0100 10.2 +++ b/tools/ioemu/hw/pass-through.c Wed Jul 02 13:54:20 2008 +0100 10.3 @@ -515,6 +515,7 @@ struct pt_dev * register_real_device(PCI 10.4 PT_LOG("Error: couldn't locate device in libpci structures\n"); 10.5 return NULL; 10.6 } 10.7 + pci_fill_info(pci_dev, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); 10.8 10.9 if ( e_devfn == PT_VIRT_DEVFN_AUTO ) { 10.10 /*indicate a static assignment(not hotplug), so find a free PCI hot plug slot */
11.1 --- a/tools/ioemu/xenstore.c Wed Jul 02 13:37:16 2008 +0100 11.2 +++ b/tools/ioemu/xenstore.c Wed Jul 02 13:54:20 2008 +0100 11.3 @@ -320,7 +320,7 @@ void xenstore_parse_domain_config(int hv 11.4 11.5 /* get the pci pass-through parameter */ 11.6 if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/num_devs", 11.7 - domid, pci_devid) == -1) 11.8 + hvm_domid, pci_devid) == -1) 11.9 goto out; 11.10 11.11 free(params); 11.12 @@ -331,7 +331,7 @@ void xenstore_parse_domain_config(int hv 11.13 11.14 for ( i = 0; i < num; i++ ) { 11.15 if (pasprintf(&buf, "/local/domain/0/backend/pci/%u/%u/dev-%d", 11.16 - domid, pci_devid, i) != -1) { 11.17 + hvm_domid, pci_devid, i) != -1) { 11.18 free(dev); 11.19 dev = xs_read(xsh, XBT_NULL, buf, &len); 11.20