From: Ruslan Ruslichenko <[email protected]>

The patch registers FDT compatibility handlers and
QOM aliases of memory subsystem, so that memory
regions can be created from a device tree model.

The alias 'qemu:system-memory' could be used to attach
subregion to root address space.
The system memory can also be attached to another
container with other priority, which may be used
for implementing secure memory structures.

Also 'qemu-memory-region' types can be used to create
new memory regions.

Signed-off-by: Ruslan Ruslichenko <[email protected]>
---
 system/memory.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/system/memory.c b/system/memory.c
index 81e6846c60..66b5f6a484 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -4120,3 +4120,102 @@ static void memory_register_types(void)
 }
 
 type_init(memory_register_types)
+
+static int sysmem_fdt_init(char *node_path, FDTMachineInfo *fdti,
+                           void *priv)
+{
+    int priority = 0;
+    uint32_t container_phandle;
+    MemoryRegion *container;
+    char container_node_path[DT_PATH_LENGTH];
+    Error *errp = NULL;
+
+    fdt_init_set_opaque(fdti, node_path, OBJECT(get_system_memory()));
+
+    /* allow to set system_memory region as subregion */
+    container_phandle = qemu_fdt_getprop_cell(fdti->fdt, node_path,
+                                            "container",
+                                            0, &errp);
+    if (!errp) {
+        /*
+         * TBD: move reg_info work to fdt_generic_util.c
+         */
+        int sc = 0;
+        sc = qemu_fdt_getprop_cell(fdti->fdt, node_path, "#address-cells",
+                                    0, &errp);
+        if (!errp && sc) {
+            error_report("can't change sysmem address");
+            return -1;
+        }
+
+        if (errp) {
+            error_free(errp); errp = NULL;
+        }
+
+        sc = qemu_fdt_getprop_cell(fdti->fdt, node_path,
+                                    "#size-cells", 0, &errp);
+        if (!errp && sc) {
+            error_report("can't change sysmem size");
+            return -1;
+        }
+
+        error_free(errp); errp = NULL;
+        /* Check for custom "#priority-cells" extension */
+        sc = qemu_fdt_getprop_cell(fdti->fdt, node_path,
+                                    "#priority-cells", 0, &errp);
+        if (errp) {
+            /* priotity is optional */
+            priority = 0;
+            error_free(errp); errp = NULL;
+        } else if (sc) {
+            priority = qemu_fdt_getprop_cell(fdti->fdt, node_path,
+                                    "reg", 0, &errp);
+            if (errp) {
+                error_report("failed to read priority from reg");
+                error_free(errp);
+                return -1;
+            }
+        }
+
+        if (qemu_devtree_get_node_by_phandle(fdti->fdt, container_node_path,
+                                             container_phandle)) {
+            error_report("failed to get contaier node");
+            return -1;
+        }
+
+        while (!fdt_init_has_opaque(fdti, container_node_path)) {
+            fdt_init_yield(fdti);
+        }
+
+        container = MEMORY_REGION(fdt_init_get_opaque(fdti,
+                                                      container_node_path));
+
+        memory_region_add_subregion_overlap(container, 0,
+                                            get_system_memory(), priority);
+    } else {
+        /* container is optional property */
+        error_free(errp);
+        errp = NULL;
+    }
+
+    return 0;
+}
+
+
+fdt_register_compatibility(sysmem_fdt_init, "compatible:qemu:system-memory");
+
+static const TypeInfo fdt_qom_aliases[] = {
+    {   .name = "qemu-memory-region",       .parent = "memory-region"  },
+    {   .name = "simple-bus",               .parent = "memory-region"  },
+};
+
+static void fdt_memory_types(void)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(fdt_qom_aliases); ++i) {
+        type_register_static(&fdt_qom_aliases[i]);
+    }
+}
+
+type_init(fdt_memory_types)
-- 
2.43.0


Reply via email to