]> xenbits.xensource.com Git - people/julieng/linux-arm.git/commitdiff
Implementation for registering hostbridge done dev-pci
authorJulien Grall <julien.grall@arm.com>
Wed, 7 Jun 2017 13:55:49 +0000 (14:55 +0100)
committerJulien Grall <julien.grall@linaro.org>
Tue, 14 Nov 2017 17:35:03 +0000 (17:35 +0000)
arch/arm/xen/pci.c
arch/arm64/kernel/pci.c

index 933b6b33fa59dd3371b9be56c901481545d707b0..dda1d7c76407b39acb7413b96283a02847260af8 100644 (file)
@@ -1,14 +1,58 @@
 #include <asm/xen/xen-ops.h>
+#include <linux/acpi.h>
 #include <linux/printk.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <xen/xen.h>
+#include <xen/interface/physdev.h>
+#include <asm/xen/hypercall.h>
 
 void xen_pci_register_host_bridge(struct pci_host_bridge *bridge)
 {
-//     struct physdev_pci_mmcfg_reserved r;
+       struct physdev_pci_mmcfg_reserved harg;
        struct pci_bus *bus = bridge->bus;
+       struct device *dev = bridge->dev.parent;
+       struct resource mmio_res, busr_res;
+       int err;
 
-       printk("============== Register Hostbridge ================\n");
+       /* XXX: Implement ACPI */
+       if (!acpi_disabled)
+               goto err;
 
-       printk("seg %u\n", pci_domain_nr(bus));
+       /*
+        * For convience the resource 0 will always be used to fill the
+        * field 'address' of pci_mmcfg_reserved.
+        */
+       err = of_address_to_resource(dev->of_node, 0, &mmio_res);
+       if (err)
+               goto err;
 
-       while (1);
+       /*
+        * bridge->windows should contain all the resources. However
+        * pci_register_host_register will move all the resources in a
+        * temporary list before calling pcibios_add_bus. So it is not
+        * possible to find the bus-range from that. Use the
+        * of_pci_parse_bus_range instead.
+        */
+       err = of_pci_parse_bus_range(dev->of_node, &busr_res);
+       if (err) {
+               /* XXX: Assume the bus range is 0x00 - 0xff */
+               busr_res.start = 0;
+               busr_res.end = 0xff;
+       }
+
+       harg.address = mmio_res.start;
+       harg.segment = pci_domain_nr(bus);
+       harg.start_bus = busr_res.start;
+       harg.end_bus = busr_res.end;
+       harg.flags = XEN_PCI_MMCFG_RESERVED;
+
+       err = HYPERVISOR_physdev_op(PHYSDEVOP_pci_mmcfg_reserved, &harg);
+       if ( err )
+               goto err;
+
+       return;
+
+err:
+       dev_err(dev, "xen: Failed to register hostbridge - passthrough might fail!\n");
 }
index 179494dc4ce8d1709a1d7f948eb2f4c0eb10c786..1bb41f191e4afb3481531de9eafddc165f0effad 100644 (file)
@@ -213,7 +213,7 @@ void pcibios_add_bus(struct pci_bus *bus)
         * hooked up in another function or check if we are registering
         * the root parent
         */
-       if (xen_initial_domain() && !pci_is_root_bus(bus))
+       if (xen_initial_domain() && pci_is_root_bus(bus))
                xen_pci_register_host_bridge(pci_find_host_bridge(bus));
 }