@@ -8,13 +8,50 @@
#include <xen/lib.h>
#include <xen/errno.h>
#include <xen/sched.h>
+#include <xen/guest_access.h>
#include <asm/hypercall.h>
+extern void acpi_setup_smmu_for_test(struct domain *d, u16 seg, u8 bus, u8 devfn);
+
int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
{
- gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: not implemented\n", cmd);
- return -ENOSYS;
+ int ret = 0;
+
+ switch (cmd )
+ {
+ case PHYSDEVOP_pci_device_add: {
+ struct physdev_pci_device_add add;
+ struct pci_dev_info pdev_info;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&add, arg, 1) != 0 )
+ break;
+
+ pdev_info.is_extfn = !!(add.flags & XEN_PCI_DEV_EXTFN);
+ if ( add.flags & XEN_PCI_DEV_VIRTFN )
+ {
+ pdev_info.is_virtfn = 1;
+ pdev_info.physfn.bus = add.physfn.bus;
+ pdev_info.physfn.devfn = add.physfn.devfn;
+ }
+ else
+ pdev_info.is_virtfn = 0;
+
+ gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: domain:%d seg:%d bus:%d \
+ devfn:%d\n", cmd, hardware_domain->domain_id, add.seg, \
+ add.bus, add.devfn);
+ acpi_setup_smmu_for_test(hardware_domain, add.seg, add.bus, add.devfn);
+ break;
+ }
+
+ default:
+ gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: not implemented\n", cmd);
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
}
/*
@@ -46,6 +46,7 @@
#include <asm/io.h>
#include <asm/platform.h>
#include <xen/acpi.h>
+#include <acpi/acpi_iort.h>
typedef paddr_t phys_addr_t;
typedef paddr_t dma_addr_t;
@@ -3410,3 +3411,38 @@ ACPI_DEVICE_START(asmmuv3, "ARM SMMU V3", DEVICE_IOMMU)
ACPI_DEVICE_END
#endif
+
+void acpi_setup_smmu_for_test(struct domain *d, u16 seg, u8 bus, u8 devfn)
+{
+ struct pci_dev pci_device;
+ struct device *device;
+ struct arm_smmu_device *smmu;
+
+ arm_smmu_iommu_domain_init(d);
+ memset(&pci_device, 0, sizeof(struct pci_dev));
+ device = &(pci_device.dev);
+
+ pci_device.domain = d;
+ *(u16*) &pci_device.seg = seg;
+ *(u8*) &pci_device.bus = bus;
+ *(u8*) &pci_device.devfn = devfn;
+
+ pci_device.dev.type = DEV_PCI;
+ printk("%d %d %d \n",pci_device.seg,pci_device.bus,pci_device.devfn);
+
+ iort_iommu_configure(device);
+
+ if (device->iommu_fwspec) {
+ printk("num-ids: %d\n", device->iommu_fwspec->num_ids);
+ printk("fwnode: 0x%p\n", device->iommu_fwspec->iommu_fwnode);
+ smmu = arm_smmu_get_by_fwnode( device->iommu_fwspec->iommu_fwnode);
+ printk("smmu-device-node: 0x%p\n",smmu);
+ arm_smmu_assign_dev(d, 0, device, 0);
+ } else {
+ printk("Failed to initialize fw_spec\n");
+ }
+
+
+ printk("%s called %d\n", __func__, __LINE__);
+}
+
@@ -8,6 +8,7 @@ enum device_type
{
DEV_DT,
DEV_ACPI,
+ DEV_PCI,
};
struct dev_archdata {
@@ -32,8 +33,8 @@ 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)
+#define dev_is_pci(dev) (dev->type == DEV_PCI)
+#define dev_is_dt(dev) (dev->type == DEV_DT)
enum device_class
{