On Mon, 13 Apr 2015, Manish Jaggi wrote: > Add ARM PCI Support > --------------- > a) Place holder functions are added for pci_conf_read/write calls. > b) Macros dev_is_pci, pci_to_dev are implemented in > drivers/passthrough/pci/arm code > > Signed-off-by: Manish Jaggi <manish.ja...@caviumnetworks.com> > --- > xen/arch/arm/Makefile | 1 + > xen/arch/arm/pci.c | 60 +++++++++++++++++++++++ > xen/drivers/passthrough/arm/Makefile | 1 + > xen/drivers/passthrough/arm/pci.c | 88 > ++++++++++++++++++++++++++++++++++ > xen/drivers/passthrough/arm/smmu.c | 1 - > xen/drivers/passthrough/pci.c | 9 ++-- > xen/include/asm-arm/device.h | 33 +++++++++---- > xen/include/asm-arm/domain.h | 3 ++ > xen/include/asm-arm/pci.h | 7 +-- > 9 files changed, 186 insertions(+), 17 deletions(-) > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index 935999e..aaf5d88 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -39,6 +39,7 @@ obj-y += device.o > obj-y += decode.o > obj-y += processor.o > obj-y += smc.o > +obj-$(HAS_PCI) += pci.o > #obj-bin-y += ....o > diff --git a/xen/arch/arm/pci.c b/xen/arch/arm/pci.c > new file mode 100644 > index 0000000..9438f41 > --- /dev/null > +++ b/xen/arch/arm/pci.c > @@ -0,0 +1,60 @@ > +#include <xen/pci.h> > + > +void _pci_conf_write( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg, uint32_t data, int bytes) > +{ > +} > + > +uint32_t _pci_conf_read( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg, int bytes) > +{ > + return 0; > +}
I guess that they are going to be implemented with platform specific code? Although I thought that the mmcfg stuff is somewhat standard across architectures. > +uint8_t pci_conf_read8( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg) > +{ > + return (uint8_t)_pci_conf_read(seg, bus, dev, func, reg, 1); > +} > + > +uint16_t pci_conf_read16( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg) > +{ > + return (uint8_t)_pci_conf_read(seg, bus, dev, func, reg, 2); > +} > + > +uint32_t pci_conf_read32( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg) > +{ > + return (uint8_t)_pci_conf_read(seg, bus, dev, func, reg, 4); > +} > + > +void pci_conf_write8( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg, uint8_t data) > +{ > + _pci_conf_write(seg, bus, dev, func, reg, data, 1); > +} > + > +void pci_conf_write16( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg, uint16_t data) > +{ > + _pci_conf_write(seg, bus, dev, func, reg, data, 2); > +} > + > +void pci_conf_write32( > + uint32_t seg, uint32_t bus, uint32_t dev, uint32_t func, > + uint32_t reg, uint32_t data) > +{ > + _pci_conf_write(seg, bus, dev, func, reg, data, 4); > +} > + > +void arch_pci_ro_device(int seg, int bdf) > +{ > +} This is also missing an implementation. Maybe you should add /* TODO */ here too > diff --git a/xen/drivers/passthrough/arm/Makefile > b/xen/drivers/passthrough/arm/Makefile > index f4cd26e..1a41549 100644 > --- a/xen/drivers/passthrough/arm/Makefile > +++ b/xen/drivers/passthrough/arm/Makefile > @@ -1,2 +1,3 @@ > obj-y += iommu.o > obj-y += smmu.o > +obj-$(HAS_PCI) += pci.o > diff --git a/xen/drivers/passthrough/arm/pci.c > b/xen/drivers/passthrough/arm/pci.c > new file mode 100644 > index 0000000..07a5a78 > --- /dev/null > +++ b/xen/drivers/passthrough/arm/pci.c > @@ -0,0 +1,88 @@ > +/* > + * PCI helper functions for arm for passthrough support. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, > USA. > + * > + * Copyright (C) 2015 Cavium Networks > + * > + * Author: Manish Jaggi <manish.ja...@cavium.com> > + */ > +#include <xen/pci.h> > +#include <asm/device.h> > +#include <xen/sched.h> > + > +int _dump_pci_devices(struct pci_seg *pseg, void *arg) > +{ > + struct pci_dev *pdev; > + > + printk("==== segment %04x ====\n", pseg->nr); > + > + list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) > + { > + printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ", > + pseg->nr, pdev->bus, > + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), > + pdev->domain ? pdev->domain->domain_id : -1, > + (pdev->node != NUMA_NO_NODE) ? pdev->node : -1); > + printk(">\n"); > + } > + > + return 0; > +} > + > +struct device* pci_to_dev(struct pci_dev *pci) > +{ > + if(!pci->arch.dev) > + { > + device_t *dev; > + dev = xzalloc (struct device); > + pci->arch.dev = dev; > + dev->class = DEVICE_PCI; > + dev->type = DEV_ENUMERATED; > + } > + return pci->arch.dev; > +} There must be a better place to initialize pci->arch.dev than here > +struct pci_dev* to_pci_dev(struct device *dev) > +{ > + if(dev->class == DEVICE_PCI) > + return dev->pci_dev; > + return NULL; > +} > + > +int dev_is_pci(struct device *dev) > +{ > + if(dev->class == DEVICE_PCI) > + return 1; > + return 0; > +} > + > + > +int pci_clean_dpci_irqs(struct domain *d) > +{ > + /* This is a placeholder function */ > + return 0; > +} > + > +struct pci_dev* pci_alloc_msix(struct pci_dev *pdev, struct pci_seg *pseg, > + u8 bus, u8 devfn) > +{ > + /* This is a placeholder function. It is implemented only on x86 */ > + return 0; > +} > + > +void pci_cleanup_msi(struct pci_dev *pdev) > +{ > + /* This is a placeholder function. It is implemented only on x86 */ > +} Although they are just placeholders for now, you are planning to implement them on ARM, right? > diff --git a/xen/drivers/passthrough/arm/smmu.c > b/xen/drivers/passthrough/arm/smmu.c > index 8a9b58b..1406261 100644 > --- a/xen/drivers/passthrough/arm/smmu.c > +++ b/xen/drivers/passthrough/arm/smmu.c > @@ -183,7 +183,6 @@ static void __iomem *devm_ioremap_resource(struct device > *dev, > * Xen: PCI functions > * TODO: It should be implemented when PCI will be supported > */ > -#define to_pci_dev(dev) (NULL) > static inline int pci_for_each_dma_alias(struct pci_dev *pdev, > int (*fn) (struct pci_dev *pdev, > u16 alias, void *data), > diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c > index 004aba9..68c292b 100644 > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -1252,9 +1252,12 @@ static int assign_device(struct domain *d, u16 seg, u8 > bus, u8 devfn) > /* Prevent device assign if mem paging or mem sharing have been > * enabled for this domain */ > if ( unlikely(!need_iommu(d) && > - (d->arch.hvm_domain.mem_sharing_enabled || > - d->mem_event->paging.ring_page || > - p2m_get_hostp2m(d)->global_logdirty)) ) > + (d->mem_event->paging.ring_page > +#ifdef CONFIG_X86 > + || d->arch.hvm_domain.mem_sharing_enabled || > + p2m_get_hostp2m(d)->global_logdirty > +#endif > + )) ) > return -EXDEV; > if ( !spin_trylock(&pcidevs_lock) ) > diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h > index a72f7c9..009ff0a 100644 > --- a/xen/include/asm-arm/device.h > +++ b/xen/include/asm-arm/device.h > @@ -6,6 +6,17 @@ > enum device_type > { > DEV_DT, > + DEV_ENUMERATED, > +}; > + > +enum device_class > +{ > + DEVICE_SERIAL, > + DEVICE_IOMMU, > + DEVICE_GIC, > + DEVICE_PCI, > + /* Use for error */ > + DEVICE_UNKNOWN, > }; > struct dev_archdata { > @@ -16,28 +27,30 @@ struct dev_archdata { > struct device > { > enum device_type type; > + enum device_class class; > #ifdef HAS_DEVICE_TREE > struct dt_device_node *of_node; /* Used by drivers imported from Linux > */ > #endif > struct dev_archdata archdata; > +#ifdef HAS_PCI > + void *pci_dev; > +#endif > }; > typedef struct device device_t; > #include <xen/device_tree.h> > -/* TODO: Correctly implement dev_is_pci when PCI is supported on ARM */ > -#define dev_is_pci(dev) ((void)(dev), 0) > #define dev_is_dt(dev) ((dev->type == DEV_DT) > -enum device_class > -{ > - DEVICE_SERIAL, > - DEVICE_IOMMU, > - DEVICE_GIC, > - /* Use for error */ > - DEVICE_UNKNOWN, > -}; > +struct pci_dev; > +device_t* pci_to_dev(struct pci_dev *pci); > +#ifndef HAS_PCI > +#define to_pci_dev(dev) (NULL) > +#else > +struct pci_dev* to_pci_dev(device_t *dev); > +#endif > +int dev_is_pci(device_t *dev); > struct device_desc { > /* Device name */ > diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h > index 9e0419e..41ae847 100644 > --- a/xen/include/asm-arm/domain.h > +++ b/xen/include/asm-arm/domain.h > @@ -42,6 +42,8 @@ struct vtimer { > uint64_t cval; > }; > +#define has_arch_pdevs(d) (!list_empty(&(d)->arch.pdev_list)) > + > struct arch_domain > { > #ifdef CONFIG_ARM_64 > @@ -56,6 +58,7 @@ struct arch_domain > xen_pfn_t *grant_table_gpfn; > struct io_handler io_handlers; > + struct list_head pdev_list; > /* Continuable domain_relinquish_resources(). */ > enum { > RELMEM_not_started, > diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h > index de13359..b8ec882 100644 > --- a/xen/include/asm-arm/pci.h > +++ b/xen/include/asm-arm/pci.h > @@ -1,7 +1,8 @@ > -#ifndef __X86_PCI_H__ > -#define __X86_PCI_H__ > +#ifndef __ARM_PCI_H__ > +#define __ARM_PCI_H__ > struct arch_pci_dev { > + void *dev; > }; > -#endif /* __X86_PCI_H__ */ > +#endif /* __ARM_PCI_H__ */ > -- > 1.7.9.5 > _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel