diff --git a/ChangeLog b/ChangeLog index 44fe27a04..0008fc46b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-22 Leif Lindholm + + Add grub_fdt_create_empty_tree() and grub_fdt_set_prop64(). + 2013-12-22 Vladimir Serbinenko Add module loading and parsing boot time checkpoints. diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c index 651e9d3cc..907a7bff6 100644 --- a/grub-core/lib/fdt.c +++ b/grub-core/lib/fdt.c @@ -431,3 +431,32 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, grub_memcpy (prop + 3, val, len); return 0; } + +int +grub_fdt_create_empty_tree (void *fdt, unsigned int size) +{ + struct grub_fdt_empty_tree *et; + + if (size < GRUB_FDT_EMPTY_TREE_SZ) + return -1; + + grub_memset (fdt, 0, size); + et = fdt; + + et->empty_node.tree_end = grub_cpu_to_be32_compile_time (FDT_END); + et->empty_node.node_end = grub_cpu_to_be32_compile_time (FDT_END_NODE); + et->empty_node.node_start = grub_cpu_to_be32_compile_time (FDT_BEGIN_NODE); + ((struct grub_fdt_empty_tree *) fdt)->header.off_mem_rsvmap = + grub_cpu_to_be32 (ALIGN_UP (sizeof (grub_fdt_header_t), 8)); + + grub_fdt_set_off_dt_strings (fdt, sizeof (*et)); + grub_fdt_set_off_dt_struct (fdt, + sizeof (et->header) + sizeof (et->empty_rsvmap)); + grub_fdt_set_version (fdt, FDT_SUPPORTED_VERSION); + grub_fdt_set_last_comp_version (fdt, FDT_SUPPORTED_VERSION); + grub_fdt_set_size_dt_struct (fdt, sizeof (et->empty_node)); + grub_fdt_set_totalsize (fdt, size); + grub_fdt_set_magic (fdt, FDT_MAGIC); + + return 0; +} diff --git a/include/grub/fdt.h b/include/grub/fdt.h index a2721926b..301699830 100644 --- a/include/grub/fdt.h +++ b/include/grub/fdt.h @@ -36,6 +36,19 @@ typedef struct { grub_uint32_t size_dt_struct; } grub_fdt_header_t; +struct grub_fdt_empty_tree { + grub_fdt_header_t header; + grub_uint64_t empty_rsvmap[2]; + struct { + grub_uint32_t node_start; + grub_uint8_t name[1]; + grub_uint32_t node_end; + grub_uint32_t tree_end; + } empty_node; +}; + +#define GRUB_FDT_EMPTY_TREE_SZ sizeof (struct grub_fdt_empty_tree) + #define grub_fdt_get_header(fdt, field) \ grub_be_to_cpu32(((const grub_fdt_header_t *)(fdt))->field) #define grub_fdt_set_header(fdt, field, value) \ @@ -82,6 +95,7 @@ typedef struct { #define grub_fdt_set_size_dt_struct(fdt, value) \ grub_fdt_set_header(fdt, size_dt_struct, value) +int grub_fdt_create_empty_tree (void *fdt, unsigned int size); int grub_fdt_check_header (void *fdt, unsigned int size); int grub_fdt_check_header_nosize (void *fdt); int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, @@ -97,4 +111,10 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 4); \ }) +#define grub_fdt_set_prop64(fdt, nodeoffset, name, val) \ +({ \ + grub_uint64_t _val = grub_cpu_to_be64(val); \ + grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \ +}) + #endif /* ! GRUB_FDT_HEADER */