Skip to content

Commit

Permalink
Added flattened device tree parser tool for testing. Added checks for…
Browse files Browse the repository at this point in the history
… FDT header.
  • Loading branch information
dgarske committed Jan 4, 2024
1 parent ad680fe commit 3812c30
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 63 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ tools/uart-flash-server/ufserver
tools/unit-tests/unit-parser
tools/bin-assemble/bin-assemble
tools/elf-parser/elf-parser
tools/fdt-parser/fdt-parser
tools/tpm/rot
tools/tpm/pcr_read
tools/tpm/pcr_reset
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ utilsclean: clean
$(Q)$(MAKE) -C tools/delta -s clean
$(Q)$(MAKE) -C tools/bin-assemble -s clean
$(Q)$(MAKE) -C tools/elf-parser -s clean
$(Q)$(MAKE) -C tools/fdt-parser -s clean
$(Q)$(MAKE) -C tools/check_config -s clean
$(Q)$(MAKE) -C tools/test-expect-version -s clean
$(Q)$(MAKE) -C tools/test-update-server -s clean
Expand Down Expand Up @@ -313,6 +314,10 @@ elf-parser:
@$(MAKE) -C tools/elf-parser -s clean
@$(MAKE) -C tools/elf-parser

fdt-parser:
@$(MAKE) -C tools/fdt-parser -s clean
@$(MAKE) -C tools/fdt-parser

config: FORCE
$(MAKE) -C config

Expand Down
7 changes: 7 additions & 0 deletions hal/nxp_t1024.c
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,13 @@ int hal_dts_fixup(void* dts_addr)
int off, i;
uint32_t *reg;

/* verify the FTD is valid */
off = fdt_check_header(dts_addr);
if (off != 0) {
wolfBoot_printf("FDT: Invalid header! %d\n", off);
return off;
}

/* display FTD information */
wolfBoot_printf("FDT: Version %d, Size %d\n",
fdt_version(fdt), fdt_totalsize(fdt));
Expand Down
48 changes: 29 additions & 19 deletions include/fdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,8 @@ extern "C" {

#include <stdint.h>

#ifdef BIG_ENDIAN_ORDER
#define FDT_MAGIC 0xD00DFEEDUL
#else
#define FDT_MAGIC 0xEDFE0DD0UL
#endif
#define FDT_SW_MAGIC (~FDT_MAGIC)
#define FDT_SW_MAGIC (uint32_t)(~FDT_MAGIC) /* marker for run-time creation/edit of FDT */

struct fdt_header {
uint32_t magic;
Expand Down Expand Up @@ -79,35 +75,31 @@ struct fdt_property {
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))

#define FDT_FIRST_SUPPORTED_VERSION 0x10
#define FDT_LAST_SUPPORTED_VERSION 0x11

#define FDT_BEGIN_NODE 0x00000001UL
#define FDT_END_NODE 0x00000002UL
#define FDT_PROP 0x00000003UL
#define FDT_NOP 0x00000004UL
#define FDT_END 0x00000009UL

#define FDT_ERR_NOTFOUND 1
#define FDT_ERR_NOSPACE 3
#define FDT_ERR_BADMAGIC 1
#define FDT_ERR_BADVERSION 2
#define FDT_ERR_BADSTRUCTURE 3
#define FDT_ERR_BADOFFSET 4
#define FDT_ERR_BADSTATE 5
#define FDT_ERR_NOTFOUND 6
#define FDT_ERR_NOSPACE 7
#define FDT_ERR_TRUNCATED 8
#define FDT_ERR_BADVERSION 10
#define FDT_ERR_BADSTRUCTURE 11
#define FDT_ERR_INTERNAL 13
#define FDT_ERR_INTERNAL 9


uint32_t cpu_to_fdt32(uint32_t x);
uint64_t cpu_to_fdt64(uint64_t x);
uint32_t fdt32_to_cpu(uint32_t x);
uint64_t fdt64_to_cpu(uint64_t x);

int fdt_next_node(const void *fdt, int offset, int *depth);
const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp);
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len);

int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str);
int fdt_fixup_val(void* fdt, int off, const char* node, const char* name, uint32_t val);
int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name, uint64_t val);
int fdt_find_devtype(void* fdt, int startoff, const char* node);

#define fdt_get_header(fdt, field) (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
Expand All @@ -132,9 +124,27 @@ int fdt_find_devtype(void* fdt, int startoff, const char* node);
#define fdt_set_size_dt_strings(fdt, val) (fdt_set_header(fdt, size_dt_strings, (val)))
#define fdt_set_size_dt_struct(fdt, val) (fdt_set_header(fdt, size_dt_struct, (val)))

int fdt_check_header(const void *fdt);
int fdt_next_node(const void *fdt, int offset, int *depth);
int fdt_first_property_offset(const void *fdt, int nodeoffset);
int fdt_next_property_offset(const void *fdt, int offset);
const struct fdt_property *fdt_get_property_by_offset(const void *fdt, int offset, int *lenp);

const char *fdt_get_name(const void *fdt, int nodeoffset, int *len);
const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);

const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp);
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len);

int fdt_find_devtype(void* fdt, int startoff, const char* node);
int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible);
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible);

/* helpers to fix/append a property to a node */
int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str);
int fdt_fixup_val(void* fdt, int off, const char* node, const char* name, uint32_t val);
int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name, uint64_t val);

#ifdef __cplusplus
}
#endif
Expand Down
111 changes: 68 additions & 43 deletions src/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,25 @@

#if defined(MMU) && !defined(BUILD_LOADER_STAGE1)

#include <wolfssl/wolfcrypt/settings.h> /* for wolfCrypt hash/sign routines */

#include "fdt.h"
#include "hal.h"
#include "printf.h"
#include "string.h"

#define WOLFSSL_MISC_INCLUDED /* allow misc.c code to be inlined */
#include <wolfcrypt/src/misc.c> /* for ByteReverseWord32 and ByteReverseWord64 */

uint32_t cpu_to_fdt32(uint32_t x)
{
#ifdef BIG_ENDIAN_ORDER
return x;
#else
return ByteReverseWord32(x);
return (uint32_t)__builtin_bswap32(x);
#endif
}
uint64_t cpu_to_fdt64(uint64_t x)
{
#ifdef BIG_ENDIAN_ORDER
return x;
#else
return ByteReverseWord64(x);
return (uint64_t)__builtin_bswap64(x);
#endif
}

Expand All @@ -58,18 +53,38 @@ uint32_t fdt32_to_cpu(uint32_t x)
#ifdef BIG_ENDIAN_ORDER
return x;
#else
return ByteReverseWord32(x);
return (uint32_t)__builtin_bswap32(x);
#endif
}
uint64_t fdt64_to_cpu(uint64_t x)
{
#ifdef BIG_ENDIAN_ORDER
return x;
#else
return ByteReverseWord64(x);
return (uint64_t)__builtin_bswap64(x);
#endif
}

int fdt_check_header(const void *fdt)
{
if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
}
else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
/* Unfinished sequential-write blob */
if (fdt_size_dt_struct(fdt) == 0)
return -FDT_ERR_BADSTATE;
}
else {
return -FDT_ERR_BADMAGIC;
}
return 0;
}

static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
{
return (const char*)fdt + fdt_off_dt_struct(fdt) + offset;
Expand Down Expand Up @@ -259,9 +274,8 @@ int fdt_next_property_offset(const void *fdt, int offset)
return fdt_next_property_(fdt, offset);
}

static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
int offset,
int *lenp)
const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
int offset, int *lenp)
{
int err;
const struct fdt_property *prop;
Expand All @@ -279,6 +293,28 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
return prop;
}

const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
{
int err;
const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
int namelen = 0;
const char* name = NULL;

err = fdt_check_header(fdt);
if (err == 0) {
err = fdt_check_node_offset_(fdt, nodeoffset);
if (err >= 0) {
name = nh->name;
namelen = strlen(nh->name);
}
}
if (err < 0)
namelen = err;
if (len)
*len = namelen;
return name;
}

const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
{
const char *s = (const char*)fdt + fdt_off_dt_strings(fdt) + stroffset;
Expand All @@ -304,7 +340,7 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
offset = fdt_next_property_offset(fdt, offset))
{
const struct fdt_property *prop =
fdt_get_property_by_offset_(fdt, offset, lenp);
fdt_get_property_by_offset(fdt, offset, lenp);
if (!prop) {
offset = -FDT_ERR_INTERNAL;
break;
Expand Down Expand Up @@ -475,41 +511,30 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
return 0;
}

int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
int len, void **prop_data)
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val,
int len)
{
int err;
int err = 0;
void *prop_data;
struct fdt_property *prop;

err = fdt_totalsize(fdt);
if (err < 0) {
return err;
}
err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
if (err == -FDT_ERR_NOTFOUND) {
err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
err = fdt_totalsize(fdt); /* confirm size in header */
if (err > 0) {
err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
if (err == -FDT_ERR_NOTFOUND) {
err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
}
}
if (err) {
return err;
else {
err = FDT_ERR_BADSTRUCTURE;
}
*prop_data = prop->data;
return 0;
}

int fdt_setprop(void *fdt, int nodeoffset, const char *name,
const void *val, int len)
{
int err;
void *prop_data;

err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
if (err) {
return err;
}
if (len) {
memcpy(prop_data, val, len);
if (err == 0) {
prop_data = prop->data;
if (len > 0) {
memcpy(prop_data, val, len);
}
}
return 0;
return err;
}

const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
Expand Down Expand Up @@ -559,7 +584,7 @@ int fdt_fixup_val(void* fdt, int off, const char* node, const char* name,
int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name,
uint64_t val)
{
wolfBoot_printf("FDT: Set %s (%d), %s=%llu\n", node, off, name, val);
wolfBoot_printf("FDT: Set %s (%d), %s=%lu\n", node, off, name, val);
val = cpu_to_fdt64(val);
fdt_setprop(fdt, off, name, &val, sizeof(val));
return off;
Expand Down
6 changes: 5 additions & 1 deletion src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,11 @@ int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
*/
int wolfBoot_get_dts_size(void *dts_addr)
{
return fdt_totalsize(dts_addr);
int ret = fdt_check_header(dts_addr);
if (ret == 0) {
ret = fdt_totalsize(dts_addr);
}
return ret;
}

#endif /* MMU */
Expand Down
18 changes: 18 additions & 0 deletions tools/fdt-parser/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-include ../../.config
-include ../../tools/config.mk
-include ../../options.mk

CC=gcc
CFLAGS=-Wall -g -ggdb
CFLAGS+=-I../../include -DMMU -DPRINTF_ENABLED
EXE=fdt-parser

LIBS=

all: $(EXE)

$(EXE):
$(CC) -o $@ $(CFLAGS) $(LIBS) fdt-parser.c ../../src/fdt.c

clean:
rm -f *.o $(EXE)
Loading

0 comments on commit 3812c30

Please sign in to comment.