Samuel Thibault
2008-Jul-02 13:58 UTC
[Xen-devel] [PATCH] minios: PIRQ and MSI/MSI-X support
minios: PIRQ and MSI/MSI-X support Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r 095f95d287b1 extras/mini-os/events.c --- a/extras/mini-os/events.c Wed Jul 02 13:53:00 2008 +0100 +++ b/extras/mini-os/events.c Wed Jul 02 14:56:37 2008 +0100 @@ -136,6 +136,23 @@ return op.port; } +evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data) +{ + evtchn_bind_pirq_t op; + + /* Try to bind the pirq to a port */ + op.pirq = pirq; + op.flags = will_share ? BIND_PIRQ__WILL_SHARE : 0; + + if ( HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &op) != 0 ) + { + printk("Failed to bind physical IRQ %d\n", pirq); + return -1; + } + bind_evtchn(op.port, handler, data); + return op.port; +} + #if defined(__x86_64__) char irqstack[2 * STACK_SIZE]; diff -r 095f95d287b1 extras/mini-os/include/events.h --- a/extras/mini-os/include/events.h Wed Jul 02 13:53:00 2008 +0100 +++ b/extras/mini-os/include/events.h Wed Jul 02 14:56:37 2008 +0100 @@ -27,6 +27,7 @@ /* prototypes */ int do_event(evtchn_port_t port, struct pt_regs *regs); evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data); +evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data); evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler, void *data); void unbind_evtchn(evtchn_port_t port); diff -r 095f95d287b1 extras/mini-os/include/pcifront.h --- a/extras/mini-os/include/pcifront.h Wed Jul 02 13:53:00 2008 +0100 +++ b/extras/mini-os/include/pcifront.h Wed Jul 02 14:56:37 2008 +0100 @@ -2,9 +2,8 @@ #include <xen/io/pciif.h> struct pcifront_dev; struct pcifront_dev *init_pcifront(char *nodename); +void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op); void pcifront_scan(struct pcifront_dev *dev, void (*fun)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun)); -void pcifront_op(struct pcifront_dev *dev, struct xen_pci_op *op); -void shutdown_pcifront(struct pcifront_dev *dev); int pcifront_conf_read(struct pcifront_dev *dev, unsigned int dom, unsigned int bus, unsigned int slot, unsigned long fun, @@ -13,3 +12,17 @@ unsigned int dom, unsigned int bus, unsigned int slot, unsigned long fun, unsigned int off, unsigned int size, unsigned int val); +int pcifront_enable_msi(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun); +int pcifront_disable_msi(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun); +int pcifront_enable_msix(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun, + struct xen_msix_entry *entries, int n); +int pcifront_disable_msix(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun); +void shutdown_pcifront(struct pcifront_dev *dev); diff -r 095f95d287b1 extras/mini-os/pcifront.c --- a/extras/mini-os/pcifront.c Wed Jul 02 13:53:00 2008 +0100 +++ b/extras/mini-os/pcifront.c Wed Jul 02 14:56:37 2008 +0100 @@ -276,3 +276,91 @@ return op.err; } + +int pcifront_enable_msi(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun) +{ + struct xen_pci_op op; + + memset(&op, 0, sizeof(op)); + + op.cmd = XEN_PCI_OP_enable_msi; + op.domain = dom; + op.bus = bus; + op.devfn = PCI_DEVFN(slot, fun); + + pcifront_op(dev, &op); + + if (op.err) + return op.err; + else + return op.value; +} + +int pcifront_disable_msi(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun) +{ + struct xen_pci_op op; + + memset(&op, 0, sizeof(op)); + + op.cmd = XEN_PCI_OP_disable_msi; + op.domain = dom; + op.bus = bus; + op.devfn = PCI_DEVFN(slot, fun); + + pcifront_op(dev, &op); + + return op.err; +} + +int pcifront_enable_msix(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun, + struct xen_msix_entry *entries, int n) +{ + struct xen_pci_op op; + + if (n > SH_INFO_MAX_VEC) + return XEN_PCI_ERR_op_failed; + + memset(&op, 0, sizeof(op)); + + op.cmd = XEN_PCI_OP_enable_msix; + op.domain = dom; + op.bus = bus; + op.devfn = PCI_DEVFN(slot, fun); + op.value = n; + + memcpy(op.msix_entries, entries, n * sizeof(*entries)); + + pcifront_op(dev, &op); + + if (op.err) + return op.err; + + memcpy(entries, op.msix_entries, n * sizeof(*entries)); + + return 0; +} + + +int pcifront_disable_msix(struct pcifront_dev *dev, + unsigned int dom, + unsigned int bus, unsigned int slot, unsigned long fun) +{ + struct xen_pci_op op; + + memset(&op, 0, sizeof(op)); + + op.cmd = XEN_PCI_OP_disable_msix; + op.domain = dom; + op.bus = bus; + op.devfn = PCI_DEVFN(slot, fun); + + pcifront_op(dev, &op); + + return op.err; +} _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel