Browse Source

libfdt: Export accessors for header fields

This patch adds exported accessor macros for the various flat device
tree header fields to libfdt.h.  This necessitates moving some of the
byte-swapping functions.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
main
David Gibson 18 years ago
parent
commit
ede25deae6
  1. 2
      fdt.c
  2. 16
      fdt_ro.c
  3. 41
      fdt_sw.c
  4. 12
      libfdt.h
  5. 5
      libfdt_env.h
  6. 2
      libfdt_internal.h
  7. 2
      tests/dumptrees.c
  8. 12
      tests/tests.h

2
fdt.c

@ -27,7 +27,7 @@ void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int len)
{ {
void *p; void *p;


p = (void *)fdt + fdt32_to_cpu(fdt->off_dt_struct) + offset; p = (void *)fdt + fdt_off_dt_struct(fdt) + offset;


if (p + len < p) if (p + len < p)
return NULL; return NULL;

16
fdt_ro.c

@ -25,19 +25,15 @@


static int check_header(const struct fdt_header *fdt) static int check_header(const struct fdt_header *fdt)
{ {
uint32_t magic = fdt32_to_cpu(fdt->magic); if (fdt_magic(fdt) == FDT_MAGIC) {
uint32_t version = fdt32_to_cpu(fdt->version);
uint32_t last_comp_version = fdt32_to_cpu(fdt->last_comp_version);

if (magic == FDT_MAGIC) {
/* Complete tree */ /* Complete tree */
if (version < FDT_FIRST_SUPPORTED_VERSION) if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return FDT_ERR_BADVERSION; return FDT_ERR_BADVERSION;
if (last_comp_version > FDT_LAST_SUPPORTED_VERSION) if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
return FDT_ERR_BADVERSION; return FDT_ERR_BADVERSION;
} else if (magic == SW_MAGIC) { } else if (fdt_magic(fdt) == SW_MAGIC) {
/* Unfinished sequential-write blob */ /* Unfinished sequential-write blob */
if (SW_SIZE_DT_STRUCT(fdt) == 0) if (sw_size_dt_struct(fdt) == 0)
return FDT_ERR_BADSTATE; return FDT_ERR_BADSTATE;
} else { } else {
return FDT_ERR_BADMAGIC; return FDT_ERR_BADMAGIC;
@ -73,7 +69,7 @@ static int offset_streq(const struct fdt_header *fdt, int offset,


char *fdt_string(const struct fdt_header *fdt, int stroffset) char *fdt_string(const struct fdt_header *fdt, int stroffset)
{ {
return (char *)fdt + fdt32_to_cpu(fdt->off_dt_strings) + stroffset; return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
} }


int fdt_property_offset(const struct fdt_header *fdt, int nodeoffset, int fdt_property_offset(const struct fdt_header *fdt, int nodeoffset,

41
fdt_sw.c

@ -25,24 +25,23 @@


static int check_header_sw(struct fdt_header *fdt) static int check_header_sw(struct fdt_header *fdt)
{ {
if (fdt32_to_cpu(fdt->magic) != SW_MAGIC) if (fdt_magic(fdt) != SW_MAGIC)
return FDT_ERR_BADMAGIC; return FDT_ERR_BADMAGIC;
return 0; return 0;
} }


static void *grab_space(struct fdt_header *fdt, int len) static void *grab_space(struct fdt_header *fdt, int len)
{ {
int off_dt_struct = fdt32_to_cpu(fdt->off_dt_struct); int offset = sw_size_dt_struct(fdt);
int offset = fdt32_to_cpu(SW_SIZE_DT_STRUCT(fdt));
int spaceleft; int spaceleft;


spaceleft = fdt32_to_cpu(fdt->totalsize) - off_dt_struct spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- fdt32_to_cpu(fdt->size_dt_strings); - fdt_size_dt_strings(fdt);


if ((offset + len < offset) || (offset + len > spaceleft)) if ((offset + len < offset) || (offset + len > spaceleft))
return NULL; return NULL;


SW_SIZE_DT_STRUCT(fdt) = cpu_to_fdt32(offset + len); fdt->version = cpu_to_fdt32(offset + len);
return fdt_offset_ptr(fdt, offset, len); return fdt_offset_ptr(fdt, offset, len);
} }


@ -74,11 +73,11 @@ int fdt_add_reservemap_entry(struct fdt_header *fdt, uint64_t addr, uint64_t siz


if (err) if (err)
return err; return err;
if (SW_SIZE_DT_STRUCT(fdt)) if (sw_size_dt_struct(fdt))
return FDT_ERR_BADSTATE; return FDT_ERR_BADSTATE;


offset = fdt32_to_cpu(fdt->off_dt_struct); offset = fdt_off_dt_struct(fdt);
if ((offset + sizeof(*re)) > fdt32_to_cpu(fdt->totalsize)) if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
return FDT_ERR_NOSPACE; return FDT_ERR_NOSPACE;


re = (struct fdt_reserve_entry *)((void *)fdt + offset); re = (struct fdt_reserve_entry *)((void *)fdt + offset);
@ -131,9 +130,8 @@ int fdt_end_node(struct fdt_header *fdt)


static int find_add_string(struct fdt_header *fdt, const char *s) static int find_add_string(struct fdt_header *fdt, const char *s)
{ {
int totalsize = fdt32_to_cpu(fdt->totalsize); char *strtab = (char *)fdt + fdt_totalsize(fdt);
char *strtab = (char *)fdt + totalsize; int strtabsize = fdt_size_dt_strings(fdt);
int strtabsize = fdt32_to_cpu(fdt->size_dt_strings);
int len = strlen(s) + 1; int len = strlen(s) + 1;
int struct_top, offset; int struct_top, offset;


@ -149,9 +147,8 @@ static int find_add_string(struct fdt_header *fdt, const char *s)


/* Add it */ /* Add it */
offset = -strtabsize - len; offset = -strtabsize - len;
struct_top = fdt32_to_cpu(fdt->off_dt_struct) struct_top = fdt_off_dt_struct(fdt) + sw_size_dt_struct(fdt);
+ fdt32_to_cpu(SW_SIZE_DT_STRUCT(fdt)); if (fdt_totalsize(fdt) + offset < struct_top)
if (totalsize + offset < struct_top)
return 0; /* no more room :( */ return 0; /* no more room :( */


memcpy(strtab + offset, s, len); memcpy(strtab + offset, s, len);
@ -188,7 +185,7 @@ int fdt_finish(struct fdt_header *fdt)
int err = check_header_sw(fdt); int err = check_header_sw(fdt);
char *p = (char *)fdt; char *p = (char *)fdt;
uint32_t *end; uint32_t *end;
int oldstroffset, newstroffset, strsize; int oldstroffset, newstroffset;
uint32_t tag; uint32_t tag;
int offset, nextoffset; int offset, nextoffset;


@ -202,11 +199,9 @@ int fdt_finish(struct fdt_header *fdt)
*end = cpu_to_fdt32(FDT_END); *end = cpu_to_fdt32(FDT_END);


/* Relocate the string table */ /* Relocate the string table */
strsize = fdt32_to_cpu(fdt->size_dt_strings); oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
oldstroffset = fdt32_to_cpu(fdt->totalsize) - strsize; newstroffset = fdt_off_dt_struct(fdt) + sw_size_dt_struct(fdt);
newstroffset = fdt32_to_cpu(fdt->off_dt_struct) memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
+ fdt32_to_cpu(SW_SIZE_DT_STRUCT(fdt));
memmove(p + newstroffset, p + oldstroffset, strsize);
fdt->off_dt_strings = fdt32_to_cpu(newstroffset); fdt->off_dt_strings = fdt32_to_cpu(newstroffset);


/* Walk the structure, correcting string offsets */ /* Walk the structure, correcting string offsets */
@ -221,14 +216,14 @@ int fdt_finish(struct fdt_header *fdt)
return FDT_ERR_BADSTRUCTURE; return FDT_ERR_BADSTRUCTURE;


nameoff = fdt32_to_cpu(prop->nameoff); nameoff = fdt32_to_cpu(prop->nameoff);
nameoff += strsize; nameoff += fdt_size_dt_strings(fdt);
prop->nameoff = cpu_to_fdt32(nameoff); prop->nameoff = cpu_to_fdt32(nameoff);
} }
offset = nextoffset; offset = nextoffset;
} }


/* Finally, adjust the header */ /* Finally, adjust the header */
fdt->totalsize = cpu_to_fdt32(newstroffset + strsize); fdt->totalsize = cpu_to_fdt32(newstroffset + fdt_size_dt_strings(fdt));
fdt->version = cpu_to_fdt32(FDT_LAST_SUPPORTED_VERSION); fdt->version = cpu_to_fdt32(FDT_LAST_SUPPORTED_VERSION);
fdt->last_comp_version= cpu_to_fdt32(FDT_FIRST_SUPPORTED_VERSION); fdt->last_comp_version= cpu_to_fdt32(FDT_FIRST_SUPPORTED_VERSION);
fdt->magic = cpu_to_fdt32(FDT_MAGIC); fdt->magic = cpu_to_fdt32(FDT_MAGIC);

12
libfdt.h

@ -20,6 +20,7 @@
*/ */


#include <fdt.h> #include <fdt.h>
#include <libfdt_env.h>


#define FDT_FIRST_SUPPORTED_VERSION 0x10 #define FDT_FIRST_SUPPORTED_VERSION 0x10
#define FDT_LAST_SUPPORTED_VERSION 0x10 #define FDT_LAST_SUPPORTED_VERSION 0x10
@ -42,7 +43,16 @@


#define FDT_ERR_MAX 13 #define FDT_ERR_MAX 13


/* Offset handling functions */ #define fdt_magic(fdt) (fdt32_to_cpu(fdt)->magic)
#define fdt_totalsize(fdt) (fdt32_to_cpu(fdt)->totalsize)
#define fdt_off_dt_struct(fdt) (fdt32_to_cpu(fdt)->off_dt_struct)
#define fdt_off_dt_strings(fdt) (fdt32_to_cpu(fdt)->off_dt_strings)
#define fdt_off_mem_rsvmap(fdt) (fdt32_to_cpu(fdt)->off_mem_rsvmap)
#define fdt_version(fdt) (fdt32_to_cpu(fdt)->version)
#define fdt_last_comp_version(fdt) (fdt32_to_cpu(fdt)->last_comp_version)
#define fdt_boot_cpuid_phys(fdt) (fdt32_to_cpu(fdt)->boot_cpuid_phys)
#define fdt_size_dt_strings(fdt) (fdt32_to_cpu(fdt)->size_dt_strings)

void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int checklen); void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int checklen);


#define fdt_offset_ptr_typed(fdt, offset, var) \ #define fdt_offset_ptr_typed(fdt, offset, var) \

5
libfdt_env.h

@ -1,3 +1,6 @@
#ifndef _LIBFDT_ENV_H
#define _LIBFDT_ENV_H

#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -16,4 +19,4 @@
#define cpu_to_fdt64(x) (bswap_64((x))) #define cpu_to_fdt64(x) (bswap_64((x)))
#endif #endif


#include "libfdt.h" #endif /* _LIBFDT_ENV_H */

2
libfdt_internal.h

@ -35,6 +35,6 @@ struct fdt_property *_fdt_getprop(const struct fdt_header *fdt, int nodeoffset,
#define PTR_ERROR(code) (void *)(-(code)) #define PTR_ERROR(code) (void *)(-(code))


#define SW_MAGIC (~FDT_MAGIC) #define SW_MAGIC (~FDT_MAGIC)
#define SW_SIZE_DT_STRUCT(fdt) ((fdt)->version) #define sw_size_dt_struct(fdt) (fdt32_to_cpu(((fdt)->version)))


#endif /* _LIBFDT_INTERNAL_H */ #endif /* _LIBFDT_INTERNAL_H */

2
tests/dumptrees.c

@ -4,8 +4,8 @@
#include <fcntl.h> #include <fcntl.h>


#include <fdt.h> #include <fdt.h>
#include <libfdt_env.h>


#include "tests.h"
#include "testdata.h" #include "testdata.h"


struct { struct {

12
tests/tests.h

@ -37,18 +37,6 @@ void test_init(int argc, char *argv[]);


#define streq(s1, s2) (strcmp((s1),(s2)) == 0) #define streq(s1, s2) (strcmp((s1),(s2)) == 0)


#if __BYTE_ORDER == __BIG_ENDIAN
#define fdt32_to_cpu(x) (x)
#define cpu_to_fdt32(x) (x)
#define fdt64_to_cpu(x) (x)
#define cpu_to_fdt64(x) (x)
#else
#define fdt32_to_cpu(x) (bswap_32((x)))
#define cpu_to_fdt32(x) (bswap_32((x)))
#define fdt64_to_cpu(x) (bswap_64((x)))
#define cpu_to_fdt64(x) (bswap_64((x)))
#endif

/* Each test case must define this function */ /* Each test case must define this function */
void cleanup(void); void cleanup(void);



Loading…
Cancel
Save