The sequential-write functions currently complain if there is not enough space in the tree for a new addition. For the Python bindings we want to automatically expand the tree when space gets too low. Add a function that returns the current number of free bytes. Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> --- Changes in v3: None Changes in v2: None libfdt/fdt_sw.c | 13 ++++++++----- libfdt/libfdt.h | 8 ++++++++ tests/sw_states.c | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c index 178b365..2b15aa8 100644 --- a/libfdt/fdt_sw.c +++ b/libfdt/fdt_sw.c @@ -126,15 +126,18 @@ static int fdt_sw_probe_struct_(void *fdt) * Allowed functions: none */ +int fdt_free_space(void *fdt) +{ + return fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) + - fdt_size_dt_strings(fdt) - fdt_size_dt_struct(fdt); +} + static void *fdt_grab_space_(void *fdt, size_t len) { int offset = fdt_size_dt_struct(fdt); - int spaceleft; - - spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) - - fdt_size_dt_strings(fdt); + int spaceleft = fdt_free_space(fdt); - if ((offset + len < offset) || (offset + len > spaceleft)) + if ((len < 0) || (len > spaceleft)) return NULL; fdt_set_size_dt_struct(fdt, offset + len); diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index c99d28f..ca03575 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -1331,6 +1331,14 @@ int fdt_nop_node(void *fdt, int nodeoffset); int fdt_create(void *buf, int bufsize); int fdt_resize(void *fdt, void *buf, int bufsize); + +/** + * fdt_free_space - return the amount of free space in the tree + * + * This returns the number of bytes available for adding new content to a + * sequence-write tree. The value is >= 0. + */ +int fdt_free_space(void *fdt); int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); int fdt_finish_reservemap(void *fdt); int fdt_begin_node(void *fdt, const char *name); diff --git a/tests/sw_states.c b/tests/sw_states.c index 2fd471d..0ce6f41 100644 --- a/tests/sw_states.c +++ b/tests/sw_states.c @@ -30,6 +30,7 @@ #include "testdata.h" #define SPACE 65536 +#define ALIGN4(x) ALIGN(x, 4) #define CHECK_OK(code) \ do { \ @@ -49,8 +50,17 @@ FAIL(#code ": %s", fdt_strerror(err)); \ } while (0) +#define CHECK_SPACE_USED(used) \ + do { \ + expected -= used; \ + space = fdt_free_space(fdt); \ + if (space != expected) \ + FAIL("Space %d, expected %d", space, expected); \ + } while (0) + int main(int argc, char *argv[]) { + int space, expected; void *fdt = NULL; int err; @@ -84,8 +94,14 @@ int main(int argc, char *argv[]) CHECK_BADSTATE(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1)); CHECK_BADSTATE(fdt_finish_reservemap(fdt)); + expected = fdt_free_space(fdt); + CHECK_OK(fdt_begin_node(fdt, "")); + CHECK_SPACE_USED(sizeof(struct fdt_node_header) + ALIGN4(sizeof(""))); CHECK_OK(fdt_property_string(fdt, "compatible", "test_tree1")); + CHECK_SPACE_USED(sizeof(struct fdt_property) + + ALIGN4(sizeof("compatible")) + + sizeof("test_tree1")); CHECK_OK(fdt_property_u32(fdt, "prop-int", TEST_VALUE_1)); CHECK_OK(fdt_property_u64(fdt, "prop-int64", TEST_VALUE64_1)); CHECK_OK(fdt_property_string(fdt, "prop-str", TEST_STRING_1)); -- 2.18.0.rc1.244.gcf134e6275-goog -- To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html