@@ -179,7 +179,8 @@ int qemu_devtree_setprop_string(void *fdt, const char *node_path,
}
const void *qemu_devtree_getprop(void *fdt, const char *node_path,
- const char *property, int *lenp)
+ const char *property, int *lenp,
+ Error **errp)
{
int len;
const void *r;
@@ -190,20 +191,30 @@ const void *qemu_devtree_getprop(void *fdt, const char *node_path,
if (!r) {
fprintf(stderr, "%s: Couldn't get %s/%s: %s\n", __func__,
node_path, property, fdt_strerror(*lenp));
- exit(1);
+ /* FIXME: Be smarter */
+ error_set(errp, QERR_UNDEFINED_ERROR);
+ return NULL;
}
return r;
}
uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
- const char *property, int offset)
+ const char *property, int offset,
+ Error **errp)
{
int len;
- const uint32_t *p = qemu_devtree_getprop(fdt, node_path, property, &len);
+ const uint32_t *p = qemu_devtree_getprop(fdt, node_path, property, &len,
+ errp);
+ if (errp && *errp) {
+ return 0;
+ }
if (len < (offset+1)*4) {
- fprintf(stderr, "%s: %s/%s not long enough to hold %d properties\n",
- __func__, node_path, property, offset+1);
- exit(1);
+ fprintf(stderr, "%s: %s/%s not long enough to hold %d properties "
+ "(length = %d)\n", __func__, node_path, property,
+ offset+1, len);
+ /* FIXME: Be smarter */
+ error_set(errp, QERR_UNDEFINED_ERROR);
+ return 0;
}
return be32_to_cpu(p[offset]);
}
@@ -14,6 +14,9 @@
#ifndef __DEVICE_TREE_H__
#define __DEVICE_TREE_H__
+#include "qemu-common.h"
+#include "qerror.h"
+
void *create_device_tree(int *sizep);
void *load_device_tree(const char *filename_path, int *sizep);
@@ -29,9 +32,11 @@ int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
const char *property,
const char *target_node_path);
const void *qemu_devtree_getprop(void *fdt, const char *node_path,
- const char *property, int *lenp);
+ const char *property, int *lenp,
+ Error **errp);
uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
- const char *property, int offset);
+ const char *property, int offset,
+ Error **errp);
uint32_t qemu_devtree_get_phandle(void *fdt, const char *path);
uint32_t qemu_devtree_alloc_phandle(void *fdt);
int qemu_devtree_nop_node(void *fdt, const char *node_path);
@@ -221,6 +221,8 @@ static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo)
void *fdt = NULL;
char *filename;
int size, rc;
+ Error *errp = NULL;
+
uint32_t acells, scells, hival;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
@@ -237,8 +239,10 @@ static int load_dtb(target_phys_addr_t addr, const struct arm_boot_info *binfo)
}
g_free(filename);
- acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells", 0);
- scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells", 0);
+ acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells", 0, &errp);
+ scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells", 0, &errp);
+ assert_no_error(errp);
+
if (acells == 0 || scells == 0) {
fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
return -1;
Rather than exit(1) on fail return an Error*. Clients can then handle errors as they wish. Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com> --- device_tree.c | 25 ++++++++++++++++++------- device_tree.h | 9 +++++++-- hw/arm_boot.c | 8 ++++++-- 3 files changed, 31 insertions(+), 11 deletions(-)