does).
tested by jca@ (riscv64)
ok patrick@
-/* $OpenBSD: fdt.c,v 1.7 2022/11/05 18:56:09 patrick Exp $ */
+/* $OpenBSD: fdt.c,v 1.8 2023/02/13 16:16:03 kettenis Exp $ */
/*
* Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
void *skip_props(uint32_t *);
void *skip_node_name(uint32_t *);
void *skip_node(void *);
+void *skip_nops(uint32_t *);
void *fdt_parent_node_recurse(void *, void *);
static int tree_inited = 0;
fdt_check_head(void *fdt)
{
struct fdt_head *fh;
- uint32_t *ptr;
+ uint32_t *ptr, *tok;
fh = fdt;
ptr = (uint32_t *)fdt;
if (betoh32(fh->fh_version) > FDT_CODE_VERSION)
return 0;
- if (betoh32(*(ptr + (betoh32(fh->fh_struct_off) / 4))) !=
- FDT_NODE_BEGIN)
+ tok = skip_nops(ptr + (betoh32(fh->fh_struct_off) / 4));
+ if (betoh32(*tok) != FDT_NODE_BEGIN)
return 0;
/* check for end signature on version 17 blob */
/*
* Utility functions for skipping parts of tree.
*/
+
+void *
+skip_nops(uint32_t *ptr)
+{
+ while (betoh32(*ptr) == FDT_NOP)
+ ptr++;
+
+ return ptr;
+}
+
void *
skip_property(uint32_t *ptr)
{
/* move forward by magic + size + nameid + rounded up property size */
ptr += 3 + roundup(size, sizeof(uint32_t)) / sizeof(uint32_t);
- return ptr;
+ return skip_nops(ptr);
}
void *
skip_node_name(uint32_t *ptr)
{
/* skip name, aligned to 4 bytes, this is NULL term., so must add 1 */
- return ptr + roundup(strlen((char *)ptr) + 1,
+ ptr += roundup(strlen((char *)ptr) + 1,
sizeof(uint32_t)) / sizeof(uint32_t);
+
+ return skip_nops(ptr);
}
/*
while (betoh32(*ptr) == FDT_NODE_BEGIN)
ptr = skip_node(ptr);
- return (ptr + 1);
+ return skip_nops(ptr + 1);
}
/*
ptr = node;
if (node == NULL) {
- ptr = (uint32_t *)tree.tree;
+ ptr = skip_nops((uint32_t *)tree.tree);
return (betoh32(*ptr) == FDT_NODE_BEGIN) ? ptr : NULL;
}
if (betoh32(*ptr) != FDT_NODE_END)
return NULL;
- if (betoh32(*(ptr + 1)) != FDT_NODE_BEGIN)
+ ptr = skip_nops(ptr + 1);
+
+ if (betoh32(*ptr) != FDT_NODE_BEGIN)
return NULL;
- return (ptr + 1);
+ return ptr;
}
/*
-/* $OpenBSD: fdt.c,v 1.9 2022/11/05 18:56:09 patrick Exp $ */
+/* $OpenBSD: fdt.c,v 1.10 2023/02/13 16:16:03 kettenis Exp $ */
/*
* Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
void *skip_props(uint32_t *);
void *skip_node_name(uint32_t *);
void *skip_node(void *);
+void *skip_nops(uint32_t *);
void *fdt_parent_node_recurse(void *, void *);
static int tree_inited = 0;
fdt_check_head(void *fdt)
{
struct fdt_head *fh;
- uint32_t *ptr;
+ uint32_t *ptr, *tok;
fh = fdt;
ptr = (uint32_t *)fdt;
if (betoh32(fh->fh_version) > FDT_CODE_VERSION)
return 0;
- if (betoh32(*(ptr + (betoh32(fh->fh_struct_off) / 4))) !=
- FDT_NODE_BEGIN)
+ tok = skip_nops(ptr + (betoh32(fh->fh_struct_off) / 4));
+ if (betoh32(*tok) != FDT_NODE_BEGIN)
return 0;
/* check for end signature on version 17 blob */
/*
* Utility functions for skipping parts of tree.
*/
+
+void *
+skip_nops(uint32_t *ptr)
+{
+ while (betoh32(*ptr) == FDT_NOP)
+ ptr++;
+
+ return ptr;
+}
+
void *
skip_property(uint32_t *ptr)
{
/* move forward by magic + size + nameid + rounded up property size */
ptr += 3 + roundup(size, sizeof(uint32_t)) / sizeof(uint32_t);
- return ptr;
+ return skip_nops(ptr);
}
void *
skip_node_name(uint32_t *ptr)
{
/* skip name, aligned to 4 bytes, this is NULL term., so must add 1 */
- return ptr + roundup(strlen((char *)ptr) + 1,
+ ptr += roundup(strlen((char *)ptr) + 1,
sizeof(uint32_t)) / sizeof(uint32_t);
+
+ return skip_nops(ptr);
}
/*
while (betoh32(*ptr) == FDT_NODE_BEGIN)
ptr = skip_node(ptr);
- return (ptr + 1);
+ return skip_nops(ptr + 1);
}
/*
ptr = node;
if (node == NULL) {
- ptr = (uint32_t *)tree.tree;
+ ptr = skip_nops((uint32_t *)tree.tree);
return (betoh32(*ptr) == FDT_NODE_BEGIN) ? ptr : NULL;
}
if (betoh32(*ptr) != FDT_NODE_END)
return NULL;
- if (betoh32(*(ptr + 1)) != FDT_NODE_BEGIN)
+ ptr = skip_nops(ptr + 1);
+
+ if (betoh32(*ptr) != FDT_NODE_BEGIN)
return NULL;
- return (ptr + 1);
+ return ptr;
}
/*
-/* $OpenBSD: fdt.c,v 1.3 2022/11/05 18:56:09 patrick Exp $ */
+/* $OpenBSD: fdt.c,v 1.4 2023/02/13 16:16:03 kettenis Exp $ */
/*
* Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
void *skip_props(uint32_t *);
void *skip_node_name(uint32_t *);
void *skip_node(void *);
+void *skip_nops(uint32_t *);
void *fdt_parent_node_recurse(void *, void *);
static int tree_inited = 0;
fdt_check_head(void *fdt)
{
struct fdt_head *fh;
- uint32_t *ptr;
+ uint32_t *ptr, *tok;
fh = fdt;
ptr = (uint32_t *)fdt;
if (betoh32(fh->fh_version) > FDT_CODE_VERSION)
return 0;
- if (betoh32(*(ptr + (betoh32(fh->fh_struct_off) / 4))) !=
- FDT_NODE_BEGIN)
+ tok = skip_nops(ptr + (betoh32(fh->fh_struct_off) / 4));
+ if (betoh32(*tok) != FDT_NODE_BEGIN)
return 0;
/* check for end signature on version 17 blob */
/*
* Utility functions for skipping parts of tree.
*/
+
+void *
+skip_nops(uint32_t *ptr)
+{
+ while (betoh32(*ptr) == FDT_NOP)
+ ptr++;
+
+ return ptr;
+}
+
void *
skip_property(uint32_t *ptr)
{
/* move forward by magic + size + nameid + rounded up property size */
ptr += 3 + roundup(size, sizeof(uint32_t)) / sizeof(uint32_t);
- return ptr;
+ return skip_nops(ptr);
}
void *
skip_node_name(uint32_t *ptr)
{
/* skip name, aligned to 4 bytes, this is NULL term., so must add 1 */
- return ptr + roundup(strlen((char *)ptr) + 1,
+ ptr += roundup(strlen((char *)ptr) + 1,
sizeof(uint32_t)) / sizeof(uint32_t);
+
+ return skip_nops(ptr);
}
/*
while (betoh32(*ptr) == FDT_NODE_BEGIN)
ptr = skip_node(ptr);
- return (ptr + 1);
+ return skip_nops(ptr + 1);
}
/*
ptr = node;
if (node == NULL) {
- ptr = (uint32_t *)tree.tree;
+ ptr = skip_nops((uint32_t *)tree.tree);
return (betoh32(*ptr) == FDT_NODE_BEGIN) ? ptr : NULL;
}
if (betoh32(*ptr) != FDT_NODE_END)
return NULL;
- if (betoh32(*(ptr + 1)) != FDT_NODE_BEGIN)
+ ptr = skip_nops(ptr + 1);
+
+ if (betoh32(*ptr) != FDT_NODE_BEGIN)
return NULL;
- return (ptr + 1);
+ return ptr;
}
/*