X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=device_tree.c;h=296278e12ae01020e7c0b8564587a7fa4d2dcf16;hb=061b51e9195670e9d190cdec46fabcb3c77763fb;hp=6e0632083094de0550643573527648422e9c24a4;hpb=776efef32439a31cb13a6acfe8aab833687745ad;p=mirror_qemu.git diff --git a/device_tree.c b/device_tree.c index 6e06320830..296278e12a 100644 --- a/device_tree.c +++ b/device_tree.c @@ -18,8 +18,8 @@ #endif #include "qapi/error.h" -#include "qemu-common.h" #include "qemu/error-report.h" +#include "qemu/option.h" #include "qemu/bswap.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" @@ -29,7 +29,7 @@ #include -#define FDT_MAX_SIZE 0x10000 +#define FDT_MAX_SIZE 0x100000 void *create_device_tree(int *sizep) { @@ -91,7 +91,7 @@ void *load_device_tree(const char *filename_path, int *sizep) /* First allocate space in qemu for device tree */ fdt = g_malloc0(dt_size); - dt_file_load_size = load_image(filename_path, fdt); + dt_file_load_size = load_image_size(filename_path, fdt, dt_size); if (dt_file_load_size < 0) { error_report("Unable to open device tree file '%s'", filename_path); @@ -140,14 +140,16 @@ static void read_fstree(void *fdt, const char *dirname) const char *parent_node; if (strstr(dirname, root_dir) != dirname) { - error_setg(&error_fatal, "%s: %s must be searched within %s", - __func__, dirname, root_dir); + error_report("%s: %s must be searched within %s", + __func__, dirname, root_dir); + exit(1); } parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)]; d = opendir(dirname); if (!d) { - error_setg(&error_fatal, "%s cannot open %s", __func__, dirname); + error_report("%s cannot open %s", __func__, dirname); + exit(1); } while ((de = readdir(d)) != NULL) { @@ -161,7 +163,8 @@ static void read_fstree(void *fdt, const char *dirname) tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name); if (lstat(tmpnam, &st) < 0) { - error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam); + error_report("%s cannot lstat %s", __func__, tmpnam); + exit(1); } if (S_ISREG(st.st_mode)) { @@ -169,8 +172,9 @@ static void read_fstree(void *fdt, const char *dirname) gsize len; if (!g_file_get_contents(tmpnam, &val, &len, NULL)) { - error_setg(&error_fatal, "%s not able to extract info from %s", - __func__, tmpnam); + error_report("%s not able to extract info from %s", + __func__, tmpnam); + exit(1); } if (strlen(parent_node) > 0) { @@ -205,9 +209,9 @@ void *load_device_tree_from_sysfs(void) host_fdt = create_device_tree(&host_fdt_size); read_fstree(host_fdt, SYSFS_DT_BASEDIR); if (fdt_check_header(host_fdt)) { - error_setg(&error_fatal, - "%s host device tree extracted into memory is invalid", - __func__); + error_report("%s host device tree extracted into memory is invalid", + __func__); + exit(1); } return host_fdt; } @@ -228,6 +232,61 @@ static int findnode_nofail(void *fdt, const char *node_path) return offset; } +char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp) +{ + char *prefix = g_strdup_printf("%s@", name); + unsigned int path_len = 16, n = 0; + GSList *path_list = NULL, *iter; + const char *iter_name; + int offset, len, ret; + char **path_array; + + offset = fdt_next_node(fdt, -1, NULL); + + while (offset >= 0) { + iter_name = fdt_get_name(fdt, offset, &len); + if (!iter_name) { + offset = len; + break; + } + if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) { + char *path; + + path = g_malloc(path_len); + while ((ret = fdt_get_path(fdt, offset, path, path_len)) + == -FDT_ERR_NOSPACE) { + path_len += 16; + path = g_realloc(path, path_len); + } + path_list = g_slist_prepend(path_list, path); + n++; + } + offset = fdt_next_node(fdt, offset, NULL); + } + g_free(prefix); + + if (offset < 0 && offset != -FDT_ERR_NOTFOUND) { + error_setg(errp, "%s: abort parsing dt for %s node units: %s", + __func__, name, fdt_strerror(offset)); + for (iter = path_list; iter; iter = iter->next) { + g_free(iter->data); + } + g_slist_free(path_list); + return NULL; + } + + path_array = g_new(char *, n + 1); + path_array[n--] = NULL; + + for (iter = path_list; iter; iter = iter->next) { + path_array[n--] = iter->data; + } + + g_slist_free(path_list); + + return path_array; +} + char **qemu_fdt_node_path(void *fdt, const char *name, char *compat, Error **errp) {