From: Jan Kiszka <[email protected]>

Recent kernels reject our root-level address-cells and size-cells
presetting - and they are right: We were overruling the the settings of
the base DT which only worked by chance.

But if we cannot set those values anymore, dtc will start complaining
about us relying on undefined cells values - nice. So we need to remove
the ranges property in order to avoid that. Then dtc complains about
that this PCI host controller node is incomplete. So we also remove the
device_type from the static overlay. Even nicer.

Now we only need to add the missing pieces to the dynamic part and
account for the possible address-cells and size-cells values.

Signed-off-by: Jan Kiszka <[email protected]>
---
 driver/pci.c             | 62 ++++++++++++++++++++++++++++++++++--------------
 driver/vpci_template.dts | 14 +++++++----
 2 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/driver/pci.c b/driver/pci.c
index bc02629d..601e2d96 100644
--- a/driver/pci.c
+++ b/driver/pci.c
@@ -302,14 +302,26 @@ static const struct of_device_id gic_of_match[] = {
 
 static bool create_vpci_of_overlay(struct jailhouse_system *config)
 {
+       u32 address_cells, size_cells, gic_address_cells, gic_phandle;
        struct device_node *vpci_node = NULL;
-       u32 gic_address_cells, gic_phandle;
-       struct device_node *gic;
-       struct property *prop;
+       struct device_node *root, *gic;
+       struct property *prop = NULL;
        unsigned int n, cell;
        u64 base_addr;
        u32 *prop_val;
 
+       root = of_find_node_by_path("/");
+       if (!root)
+               return false;
+
+       if (of_property_read_u32(root, "#address-cells", &address_cells) < 0 ||
+           of_property_read_u32(root, "#size-cells", &size_cells) < 0) {
+               of_node_put(root);
+               return false;
+       }
+
+       of_node_put(root);
+
        gic = of_find_matching_node(NULL, gic_of_match);
        if (!gic)
                return false;
@@ -348,6 +360,18 @@ static bool create_vpci_of_overlay(struct jailhouse_system 
*config)
        if (!vpci_node)
                goto out;
 
+       /*
+        * Set only here to suppress warnings of dtc when compiling the
+        * incomplete overlay.
+        */
+       prop = alloc_prop("device_type", 4);
+       if (!prop)
+               goto out;
+       strcpy(prop->value, "pci");
+
+       if (of_changeset_add_property(&overlay_changeset, vpci_node, prop) < 0)
+               goto out;
+
        if (config->platform_info.pci_domain != (u16)-1) {
                prop = alloc_prop("linux,pci-domain", sizeof(u32));
                if (!prop)
@@ -381,22 +405,24 @@ static bool create_vpci_of_overlay(struct 
jailhouse_system *config)
        if (of_changeset_add_property(&overlay_changeset, vpci_node, prop) < 0)
                goto out;
 
-       prop = alloc_prop("reg", sizeof(u32) * 4);
+       prop = alloc_prop("reg", sizeof(u32) * (address_cells + size_cells));
        if (!prop)
                goto out;
 
        /* Set the MMCONFIG base address of the host controller. */
        base_addr = config->platform_info.pci_mmconfig_base;
        prop_val = prop->value;
-       prop_val[0] = cpu_to_be32(base_addr >> 32);
-       prop_val[1] = cpu_to_be32(base_addr);
-       prop_val[2] = 0;
-       prop_val[3] = cpu_to_be32(0x100000);
+       if (address_cells > 1)
+               *prop_val++ = cpu_to_be32(base_addr >> 32);
+       *prop_val++ = cpu_to_be32(base_addr);
+       if (size_cells > 1)
+               *prop_val++ = 0;
+       *prop_val = cpu_to_be32(0x100000);
 
        if (of_changeset_add_property(&overlay_changeset, vpci_node, prop) < 0)
                goto out;
 
-       prop = alloc_prop("ranges", sizeof(u32) * 7);
+       prop = alloc_prop("ranges", sizeof(u32) * (5 + address_cells));
        if (!prop)
                goto out;
 
@@ -406,16 +432,16 @@ static bool create_vpci_of_overlay(struct 
jailhouse_system *config)
         */
        base_addr += 0x100000;
        prop_val = prop->value;
-       prop_val[0] = cpu_to_be32(0x02000000);
-       prop_val[1] = cpu_to_be32(base_addr >> 32);
-       prop_val[2] = cpu_to_be32(base_addr);
-       prop_val[3] = cpu_to_be32(base_addr >> 32);
-       prop_val[4] = cpu_to_be32(base_addr);
-       prop_val[5] = 0;
-       prop_val[6] = cpu_to_be32(count_ivshmem_devices(root_cell) * 0x2000);
+       *prop_val++ = cpu_to_be32(0x02000000);
+       *prop_val++ = cpu_to_be32(base_addr >> 32);
+       *prop_val++ = cpu_to_be32(base_addr);
+       if (address_cells > 1)
+               *prop_val++ = cpu_to_be32(base_addr >> 32);
+       *prop_val++ = cpu_to_be32(base_addr);
+       *prop_val++ = 0;
+       *prop_val = cpu_to_be32(count_ivshmem_devices(root_cell) * 0x2000);
 
-       if (of_changeset_update_property(&overlay_changeset, vpci_node,
-                                        prop) < 0)
+       if (of_changeset_add_property(&overlay_changeset, vpci_node, prop) < 0)
                goto out;
 
        prop = alloc_prop("status", 3);
diff --git a/driver/vpci_template.dts b/driver/vpci_template.dts
index c900dd3a..01f816ae 100644
--- a/driver/vpci_template.dts
+++ b/driver/vpci_template.dts
@@ -3,18 +3,22 @@
        fragment {
                target-path = "/";
                __overlay__ {
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-
                        pci@0 {
                                compatible = "pci-host-ecam-generic";
-                               device_type = "pci";
+                               /*
+                                * added dynamically:
+                                * - device_type = "pci"
+                                * - linux,pci-domain = <...>
+                                * - reg = <...>
+                                * - ranges = <...>
+                                * - interrupt-map = <...>
+                                */
                                bus-range = <0 0>;
                                #address-cells = <3>;
                                #size-cells = <2>;
                                #interrupt-cells = <1>;
                                interrupt-map-mask = <0 0 0 7>;
-                               ranges = <0 0 0 0 0 0 0>;
+                               /* set to "ok" during dynamic update */
                                status = "disabled";
                        };
                };
-- 
2.16.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/e06e6e12b6873d054347d628361bcf446022f5d9.1562179456.git.jan.kiszka%40siemens.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to