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
