Merge branch 'master' of git://www.denx.de/git/u-boot-fdt

This commit is contained in:
Wolfgang Denk 2008-06-11 22:30:47 +02:00
commit cdeb62e20d
19 changed files with 160 additions and 732 deletions

9
README
View File

@ -350,7 +350,7 @@ The following options need to be configured:
expect it to be in bytes, others in MB. expect it to be in bytes, others in MB.
Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes. Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes.
CONFIG_OF_LIBFDT / CONFIG_OF_FLAT_TREE CONFIG_OF_LIBFDT
New kernel versions are expecting firmware settings to be New kernel versions are expecting firmware settings to be
passed using flattened device trees (based on open firmware passed using flattened device trees (based on open firmware
@ -361,13 +361,6 @@ The following options need to be configured:
* Adds the "fdt" command * Adds the "fdt" command
* The bootm command automatically updates the fdt * The bootm command automatically updates the fdt
CONFIG_OF_FLAT_TREE
* Deprecated, see CONFIG_OF_LIBFDT
* Original ft_build.c-based support
* Automatically modifies the dft as part of the bootm command
* The environment variable "disable_of", when set,
disables this functionality.
OF_CPU - The proper name of the cpus node. OF_CPU - The proper name of the cpus node.
OF_SOC - The proper name of the soc node. OF_SOC - The proper name of the soc node.
OF_TBCLK - The timebase frequency. OF_TBCLK - The timebase frequency.

View File

@ -31,10 +31,7 @@
#include <common.h> #include <common.h>
#include <74xx_7xx.h> #include <74xx_7xx.h>
#if defined(CONFIG_OF_FLAT_TREE) #include <fdt_support.h>
#include <ft_build.h>
extern void ft_cpu_setup (void *blob, bd_t *bd);
#endif
#undef DEBUG #undef DEBUG
@ -89,19 +86,11 @@ long int initdram (int board_type)
return dram_size (board_type); return dram_size (board_type);
} }
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) #if defined(CONFIG_OF_BOARD_SETUP)
void void
ft_board_setup (void *blob, bd_t *bd) ft_board_setup(void *blob, bd_t *bd)
{ {
u32 *p; ft_cpu_setup(blob, bd);
int len; fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
ft_cpu_setup (blob, bd);
p = ft_get_prop (blob, "/memory/reg", &len);
if (p != NULL) {
*p++ = cpu_to_be32 (bd->bi_memstart);
*p = cpu_to_be32 (bd->bi_memsize);
}
} }
#endif #endif

View File

@ -30,10 +30,6 @@
#include <pci.h> #include <pci.h>
#include <asm/m8260_pci.h> #include <asm/m8260_pci.h>
#endif #endif
#if CONFIG_OF_FLAT_TREE
#include <ft_build.h>
#include <image.h>
#endif
#if 0 #if 0
#define deb_printf(fmt,arg...) \ #define deb_printf(fmt,arg...) \

View File

@ -119,7 +119,6 @@ COBJS-y += env_nowhere.o
COBJS-y += exports.o COBJS-y += exports.o
COBJS-y += flash.o COBJS-y += flash.o
COBJS-y += fpga.o COBJS-y += fpga.o
COBJS-y += ft_build.o
COBJS-y += hush.o COBJS-y += hush.o
COBJS-y += kgdb.o COBJS-y += kgdb.o
COBJS-y += lcd.o COBJS-y += lcd.o

View File

@ -45,6 +45,11 @@ static int fdt_valid(void);
static int fdt_parse_prop(char **newval, int count, char *data, int *len); static int fdt_parse_prop(char **newval, int count, char *data, int *len);
static int fdt_print(const char *pathp, char *prop, int depth); static int fdt_print(const char *pathp, char *prop, int depth);
/*
* The working_fdt points to our working flattened device tree.
*/
struct fdt_header *working_fdt;
/* /*
* Flattened Device Tree command, see the help for parameter definitions. * Flattened Device Tree command, see the help for parameter definitions.
*/ */
@ -62,7 +67,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/* /*
* Set the address [and length] of the fdt. * Set the address [and length] of the fdt.
*/ */
fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
if (!fdt_valid()) { if (!fdt_valid()) {
return 1; return 1;
@ -75,15 +80,15 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* Optional new length * Optional new length
*/ */
len = simple_strtoul(argv[3], NULL, 16); len = simple_strtoul(argv[3], NULL, 16);
if (len < fdt_totalsize(fdt)) { if (len < fdt_totalsize(working_fdt)) {
printf ("New length %d < existing length %d, " printf ("New length %d < existing length %d, "
"ignoring.\n", "ignoring.\n",
len, fdt_totalsize(fdt)); len, fdt_totalsize(working_fdt));
} else { } else {
/* /*
* Open in place with a new length. * Open in place with a new length.
*/ */
err = fdt_open_into(fdt, fdt, len); err = fdt_open_into(working_fdt, working_fdt, len);
if (err != 0) { if (err != 0) {
printf ("libfdt fdt_open_into(): %s\n", printf ("libfdt fdt_open_into(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
@ -92,9 +97,9 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
} }
/******************************************************************** /********************************************************************
* Move the fdt * Move the working_fdt
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'm') && (argv[1][1] == 'o')) { } else if (strncmp(argv[1], "mo", 2) == 0) {
struct fdt_header *newaddr; struct fdt_header *newaddr;
int len; int len;
int err; int err;
@ -107,7 +112,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/* /*
* Set the address and length of the fdt. * Set the address and length of the fdt.
*/ */
fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
if (!fdt_valid()) { if (!fdt_valid()) {
return 1; return 1;
} }
@ -119,13 +124,13 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* current length. * current length.
*/ */
if (argc <= 4) { if (argc <= 4) {
len = fdt_totalsize(fdt); len = fdt_totalsize(working_fdt);
} else { } else {
len = simple_strtoul(argv[4], NULL, 16); len = simple_strtoul(argv[4], NULL, 16);
if (len < fdt_totalsize(fdt)) { if (len < fdt_totalsize(working_fdt)) {
printf ("New length 0x%X < existing length " printf ("New length 0x%X < existing length "
"0x%X, aborting.\n", "0x%X, aborting.\n",
len, fdt_totalsize(fdt)); len, fdt_totalsize(working_fdt));
return 1; return 1;
} }
} }
@ -133,18 +138,18 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/* /*
* Copy to the new location. * Copy to the new location.
*/ */
err = fdt_open_into(fdt, newaddr, len); err = fdt_open_into(working_fdt, newaddr, len);
if (err != 0) { if (err != 0) {
printf ("libfdt fdt_open_into(): %s\n", printf ("libfdt fdt_open_into(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
return 1; return 1;
} }
fdt = newaddr; working_fdt = newaddr;
/******************************************************************** /********************************************************************
* Make a new node * Make a new node
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'm') && (argv[1][1] == 'k')) { } else if (strncmp(argv[1], "mk", 2) == 0) {
char *pathp; /* path */ char *pathp; /* path */
char *nodep; /* new node to add */ char *nodep; /* new node to add */
int nodeoffset; /* node offset from libfdt */ int nodeoffset; /* node offset from libfdt */
@ -161,7 +166,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
pathp = argv[2]; pathp = argv[2];
nodep = argv[3]; nodep = argv[3];
nodeoffset = fdt_path_offset (fdt, pathp); nodeoffset = fdt_path_offset (working_fdt, pathp);
if (nodeoffset < 0) { if (nodeoffset < 0) {
/* /*
* Not found or something else bad happened. * Not found or something else bad happened.
@ -170,7 +175,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
fdt_strerror(nodeoffset)); fdt_strerror(nodeoffset));
return 1; return 1;
} }
err = fdt_add_subnode(fdt, nodeoffset, nodep); err = fdt_add_subnode(working_fdt, nodeoffset, nodep);
if (err < 0) { if (err < 0) {
printf ("libfdt fdt_add_subnode(): %s\n", printf ("libfdt fdt_add_subnode(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
@ -178,7 +183,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
} }
/******************************************************************** /********************************************************************
* Set the value of a property in the fdt. * Set the value of a property in the working_fdt.
********************************************************************/ ********************************************************************/
} else if (argv[1][0] == 's') { } else if (argv[1][0] == 's') {
char *pathp; /* path */ char *pathp; /* path */
@ -206,7 +211,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
return ret; return ret;
} }
nodeoffset = fdt_path_offset (fdt, pathp); nodeoffset = fdt_path_offset (working_fdt, pathp);
if (nodeoffset < 0) { if (nodeoffset < 0) {
/* /*
* Not found or something else bad happened. * Not found or something else bad happened.
@ -216,7 +221,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
return 1; return 1;
} }
ret = fdt_setprop(fdt, nodeoffset, prop, data, len); ret = fdt_setprop(working_fdt, nodeoffset, prop, data, len);
if (ret < 0) { if (ret < 0) {
printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret));
return 1; return 1;
@ -259,7 +264,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/******************************************************************** /********************************************************************
* Remove a property/node * Remove a property/node
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'r') && (argv[1][1] == 'm')) { } else if (strncmp(argv[1], "rm", 2) == 0) {
int nodeoffset; /* node offset from libfdt */ int nodeoffset; /* node offset from libfdt */
int err; int err;
@ -267,7 +272,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* Get the path. The root node is an oddball, the offset * Get the path. The root node is an oddball, the offset
* is zero and has no name. * is zero and has no name.
*/ */
nodeoffset = fdt_path_offset (fdt, argv[2]); nodeoffset = fdt_path_offset (working_fdt, argv[2]);
if (nodeoffset < 0) { if (nodeoffset < 0) {
/* /*
* Not found or something else bad happened. * Not found or something else bad happened.
@ -281,14 +286,14 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* otherwise delete the node. * otherwise delete the node.
*/ */
if (argc > 3) { if (argc > 3) {
err = fdt_delprop(fdt, nodeoffset, argv[3]); err = fdt_delprop(working_fdt, nodeoffset, argv[3]);
if (err < 0) { if (err < 0) {
printf("libfdt fdt_delprop(): %s\n", printf("libfdt fdt_delprop(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
return err; return err;
} }
} else { } else {
err = fdt_del_node(fdt, nodeoffset); err = fdt_del_node(working_fdt, nodeoffset);
if (err < 0) { if (err < 0) {
printf("libfdt fdt_del_node(): %s\n", printf("libfdt fdt_del_node(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
@ -300,38 +305,43 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
* Display header info * Display header info
********************************************************************/ ********************************************************************/
} else if (argv[1][0] == 'h') { } else if (argv[1][0] == 'h') {
u32 version = fdt_version(fdt); u32 version = fdt_version(working_fdt);
printf("magic:\t\t\t0x%x\n", fdt_magic(fdt)); printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt));
printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(fdt), fdt_totalsize(fdt)); printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(working_fdt),
printf("off_dt_struct:\t\t0x%x\n", fdt_off_dt_struct(fdt)); fdt_totalsize(working_fdt));
printf("off_dt_strings:\t\t0x%x\n", fdt_off_dt_strings(fdt)); printf("off_dt_struct:\t\t0x%x\n",
printf("off_mem_rsvmap:\t\t0x%x\n", fdt_off_mem_rsvmap(fdt)); fdt_off_dt_struct(working_fdt));
printf("off_dt_strings:\t\t0x%x\n",
fdt_off_dt_strings(working_fdt));
printf("off_mem_rsvmap:\t\t0x%x\n",
fdt_off_mem_rsvmap(working_fdt));
printf("version:\t\t%d\n", version); printf("version:\t\t%d\n", version);
printf("last_comp_version:\t%d\n", fdt_last_comp_version(fdt)); printf("last_comp_version:\t%d\n",
fdt_last_comp_version(working_fdt));
if (version >= 2) if (version >= 2)
printf("boot_cpuid_phys:\t0x%x\n", printf("boot_cpuid_phys:\t0x%x\n",
fdt_boot_cpuid_phys(fdt)); fdt_boot_cpuid_phys(working_fdt));
if (version >= 3) if (version >= 3)
printf("size_dt_strings:\t0x%x\n", printf("size_dt_strings:\t0x%x\n",
fdt_size_dt_strings(fdt)); fdt_size_dt_strings(working_fdt));
if (version >= 17) if (version >= 17)
printf("size_dt_struct:\t\t0x%x\n", printf("size_dt_struct:\t\t0x%x\n",
fdt_size_dt_struct(fdt)); fdt_size_dt_struct(working_fdt));
printf("number mem_rsv:\t\t0x%x\n", fdt_num_mem_rsv(fdt)); printf("number mem_rsv:\t\t0x%x\n",
fdt_num_mem_rsv(working_fdt));
printf("\n"); printf("\n");
/******************************************************************** /********************************************************************
* Set boot cpu id * Set boot cpu id
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'b') && (argv[1][1] == 'o') && } else if (strncmp(argv[1], "boo", 3) == 0) {
(argv[1][2] == 'o')) {
unsigned long tmp = simple_strtoul(argv[2], NULL, 16); unsigned long tmp = simple_strtoul(argv[2], NULL, 16);
fdt_set_boot_cpuid_phys(fdt, tmp); fdt_set_boot_cpuid_phys(working_fdt, tmp);
/******************************************************************** /********************************************************************
* memory command * memory command
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'm') && (argv[1][1] == 'e')) { } else if (strncmp(argv[1], "me", 2) == 0) {
uint64_t addr, size; uint64_t addr, size;
int err; int err;
#ifdef CFG_64BIT_STRTOUL #ifdef CFG_64BIT_STRTOUL
@ -341,23 +351,23 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
addr = simple_strtoul(argv[2], NULL, 16); addr = simple_strtoul(argv[2], NULL, 16);
size = simple_strtoul(argv[3], NULL, 16); size = simple_strtoul(argv[3], NULL, 16);
#endif #endif
err = fdt_fixup_memory(fdt, addr, size); err = fdt_fixup_memory(working_fdt, addr, size);
if (err < 0) if (err < 0)
return err; return err;
/******************************************************************** /********************************************************************
* mem reserve commands * mem reserve commands
********************************************************************/ ********************************************************************/
} else if ((argv[1][0] == 'r') && (argv[1][1] == 's')) { } else if (strncmp(argv[1], "rs", 2) == 0) {
if (argv[2][0] == 'p') { if (argv[2][0] == 'p') {
uint64_t addr, size; uint64_t addr, size;
int total = fdt_num_mem_rsv(fdt); int total = fdt_num_mem_rsv(working_fdt);
int j, err; int j, err;
printf("index\t\t start\t\t size\n"); printf("index\t\t start\t\t size\n");
printf("-------------------------------" printf("-------------------------------"
"-----------------\n"); "-----------------\n");
for (j = 0; j < total; j++) { for (j = 0; j < total; j++) {
err = fdt_get_mem_rsv(fdt, j, &addr, &size); err = fdt_get_mem_rsv(working_fdt, j, &addr, &size);
if (err < 0) { if (err < 0) {
printf("libfdt fdt_get_mem_rsv(): %s\n", printf("libfdt fdt_get_mem_rsv(): %s\n",
fdt_strerror(err)); fdt_strerror(err));
@ -379,7 +389,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
addr = simple_strtoul(argv[3], NULL, 16); addr = simple_strtoul(argv[3], NULL, 16);
size = simple_strtoul(argv[4], NULL, 16); size = simple_strtoul(argv[4], NULL, 16);
#endif #endif
err = fdt_add_mem_rsv(fdt, addr, size); err = fdt_add_mem_rsv(working_fdt, addr, size);
if (err < 0) { if (err < 0) {
printf("libfdt fdt_add_mem_rsv(): %s\n", printf("libfdt fdt_add_mem_rsv(): %s\n",
@ -388,7 +398,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
} }
} else if (argv[2][0] == 'd') { } else if (argv[2][0] == 'd') {
unsigned long idx = simple_strtoul(argv[3], NULL, 16); unsigned long idx = simple_strtoul(argv[3], NULL, 16);
int err = fdt_del_mem_rsv(fdt, idx); int err = fdt_del_mem_rsv(working_fdt, idx);
if (err < 0) { if (err < 0) {
printf("libfdt fdt_del_mem_rsv(): %s\n", printf("libfdt fdt_del_mem_rsv(): %s\n",
@ -403,12 +413,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
} }
#ifdef CONFIG_OF_BOARD_SETUP #ifdef CONFIG_OF_BOARD_SETUP
/* Call the board-specific fixup routine */ /* Call the board-specific fixup routine */
else if (argv[1][0] == 'b') else if (strncmp(argv[1], "boa", 3) == 0)
ft_board_setup(fdt, gd->bd); ft_board_setup(working_fdt, gd->bd);
#endif #endif
/* Create a chosen node */ /* Create a chosen node */
else if (argv[1][0] == 'c') else if (argv[1][0] == 'c')
fdt_chosen(fdt, 0, 0, 1); fdt_chosen(working_fdt, 0, 0, 1);
else { else {
/* Unrecognized command */ /* Unrecognized command */
printf ("Usage:\n%s\n", cmdtp->usage); printf ("Usage:\n%s\n", cmdtp->usage);
@ -424,12 +434,12 @@ static int fdt_valid(void)
{ {
int err; int err;
if (fdt == NULL) { if (working_fdt == NULL) {
printf ("The address of the fdt is invalid (NULL).\n"); printf ("The address of the fdt is invalid (NULL).\n");
return 0; return 0;
} }
err = fdt_check_header(fdt); err = fdt_check_header(working_fdt);
if (err == 0) if (err == 0)
return 1; /* valid */ return 1; /* valid */
@ -439,17 +449,19 @@ static int fdt_valid(void)
* Be more informative on bad version. * Be more informative on bad version.
*/ */
if (err == -FDT_ERR_BADVERSION) { if (err == -FDT_ERR_BADVERSION) {
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { if (fdt_version(working_fdt) <
FDT_FIRST_SUPPORTED_VERSION) {
printf (" - too old, fdt $d < %d", printf (" - too old, fdt $d < %d",
fdt_version(fdt), fdt_version(working_fdt),
FDT_FIRST_SUPPORTED_VERSION); FDT_FIRST_SUPPORTED_VERSION);
fdt = NULL; working_fdt = NULL;
} }
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { if (fdt_last_comp_version(working_fdt) >
FDT_LAST_SUPPORTED_VERSION) {
printf (" - too new, fdt $d > %d", printf (" - too new, fdt $d > %d",
fdt_version(fdt), fdt_version(working_fdt),
FDT_LAST_SUPPORTED_VERSION); FDT_LAST_SUPPORTED_VERSION);
fdt = NULL; working_fdt = NULL;
} }
return 0; return 0;
} }
@ -645,7 +657,7 @@ static void print_data(const void *data, int len)
/****************************************************************************/ /****************************************************************************/
/* /*
* Recursively print (a portion of) the fdt. The depth parameter * Recursively print (a portion of) the working_fdt. The depth parameter
* determines how deeply nested the fdt is printed. * determines how deeply nested the fdt is printed.
*/ */
static int fdt_print(const char *pathp, char *prop, int depth) static int fdt_print(const char *pathp, char *prop, int depth)
@ -661,7 +673,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
int level = 0; /* keep track of nesting level */ int level = 0; /* keep track of nesting level */
const struct fdt_property *fdt_prop; const struct fdt_property *fdt_prop;
nodeoffset = fdt_path_offset (fdt, pathp); nodeoffset = fdt_path_offset (working_fdt, pathp);
if (nodeoffset < 0) { if (nodeoffset < 0) {
/* /*
* Not found or something else bad happened. * Not found or something else bad happened.
@ -675,7 +687,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
* Print only the given property and then return. * Print only the given property and then return.
*/ */
if (prop) { if (prop) {
nodep = fdt_getprop (fdt, nodeoffset, prop, &len); nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len);
if (len == 0) { if (len == 0) {
/* no property value */ /* no property value */
printf("%s %s\n", pathp, prop); printf("%s %s\n", pathp, prop);
@ -697,10 +709,10 @@ static int fdt_print(const char *pathp, char *prop, int depth)
* print the node and all subnodes. * print the node and all subnodes.
*/ */
while(level >= 0) { while(level >= 0) {
tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset);
switch(tag) { switch(tag) {
case FDT_BEGIN_NODE: case FDT_BEGIN_NODE:
pathp = fdt_get_name(fdt, nodeoffset, NULL); pathp = fdt_get_name(working_fdt, nodeoffset, NULL);
if (level <= depth) { if (level <= depth) {
if (pathp == NULL) if (pathp == NULL)
pathp = "/* NULL pointer error */"; pathp = "/* NULL pointer error */";
@ -724,9 +736,9 @@ static int fdt_print(const char *pathp, char *prop, int depth)
} }
break; break;
case FDT_PROP: case FDT_PROP:
fdt_prop = fdt_offset_ptr(fdt, nodeoffset, fdt_prop = fdt_offset_ptr(working_fdt, nodeoffset,
sizeof(*fdt_prop)); sizeof(*fdt_prop));
pathp = fdt_string(fdt, pathp = fdt_string(working_fdt,
fdt32_to_cpu(fdt_prop->nameoff)); fdt32_to_cpu(fdt_prop->nameoff));
len = fdt32_to_cpu(fdt_prop->len); len = fdt32_to_cpu(fdt_prop->len);
nodep = fdt_prop->data; nodep = fdt_prop->data;

View File

@ -35,11 +35,6 @@
*/ */
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
/*
* fdt points to our working device tree.
*/
struct fdt_header *fdt;
/** /**
* fdt_find_and_setprop: Find a node and set it's property * fdt_find_and_setprop: Find a node and set it's property

View File

@ -1,471 +0,0 @@
/*
* OF flat tree builder
* Written by: Pantelis Antoniou <pantelis.antoniou@gmail.com>
* Updated by: Matthew McClintock <msm@freescale.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <malloc.h>
#include <environment.h>
#ifdef CONFIG_OF_FLAT_TREE
#include <asm/errno.h>
#include <stddef.h>
#include <ft_build.h>
#include <linux/ctype.h>
#undef DEBUG
/* align addr on a size boundary - adjust address up if needed -- Cort */
#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1)))
#ifndef CONFIG_OF_BOOT_CPU
#define CONFIG_OF_BOOT_CPU 0
#endif
#define SIZE_OF_RSVMAP_ENTRY (2*sizeof(u64))
static void ft_put_word(struct ft_cxt *cxt, u32 v)
{
memmove(cxt->p + sizeof(u32), cxt->p, cxt->p_end - cxt->p);
*(u32 *) cxt->p = cpu_to_be32(v);
cxt->p += sizeof(u32);
cxt->p_end += sizeof(u32);
}
static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
{
int aligned_size = ((u8 *)_ALIGN((unsigned long)cxt->p + sz,
sizeof(u32))) - cxt->p;
memmove(cxt->p + aligned_size, cxt->p, cxt->p_end - cxt->p);
/* make sure the last bytes are zeroed */
memset(cxt->p + aligned_size - (aligned_size % sizeof(u32)), 0,
(aligned_size % sizeof(u32)));
memcpy(cxt->p, data, sz);
cxt->p += aligned_size;
cxt->p_end += aligned_size;
}
void ft_begin_node(struct ft_cxt *cxt, const char *name)
{
ft_put_word(cxt, OF_DT_BEGIN_NODE);
ft_put_bin(cxt, name, strlen(name) + 1);
}
void ft_end_node(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_END_NODE);
}
void ft_nop(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_NOP);
}
static int lookup_string(struct ft_cxt *cxt, const char *name)
{
u8 *p;
p = cxt->p;
while (p < cxt->p_end) {
if (strcmp((char *)p, name) == 0)
return p - cxt->p;
p += strlen((char *)p) + 1;
}
return -1;
}
void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz)
{
int off = 0;
off = lookup_string(cxt, name);
if (off == -1) {
memcpy(cxt->p_end, name, strlen(name) + 1);
off = cxt->p_end - cxt->p;
cxt->p_end += strlen(name) + 1;
}
/* now put offset from beginning of *STRUCTURE* */
/* will be fixed up at the end */
ft_put_word(cxt, OF_DT_PROP);
ft_put_word(cxt, sz);
ft_put_word(cxt, off);
ft_put_bin(cxt, data, sz);
}
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
{
ft_prop(cxt, name, str, strlen(str) + 1);
}
void ft_prop_int(struct ft_cxt *cxt, const char *name, int val)
{
u32 v = cpu_to_be32((u32) val);
ft_prop(cxt, name, &v, sizeof(u32));
}
/* pick up and start working on a tree in place */
void ft_init_cxt(struct ft_cxt *cxt, void *blob)
{
struct boot_param_header *bph = blob;
memset(cxt, 0, sizeof(*cxt));
cxt->bph = bph;
bph->boot_cpuid_phys = CONFIG_OF_BOOT_CPU;
/* find beginning and end of reserve map table (zeros in last entry) */
cxt->p_rsvmap = (u8 *)bph + bph->off_mem_rsvmap;
while ( ((uint64_t *)cxt->p_rsvmap)[0] != 0 &&
((uint64_t *)cxt->p_rsvmap)[1] != 0 ) {
cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY;
}
cxt->p_start = (u8 *)bph + bph->off_dt_struct;
cxt->p_end = (u8 *)bph + bph->totalsize;
cxt->p = (u8 *)bph + bph->off_dt_strings;
}
/* add a reserver physical area to the rsvmap */
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physstart, u64 physend)
{
memmove(cxt->p_rsvmap + SIZE_OF_RSVMAP_ENTRY, cxt->p_rsvmap,
cxt->p_end - cxt->p_rsvmap);
((u64 *)cxt->p_rsvmap)[0] = cpu_to_be64(physstart);
((u64 *)cxt->p_rsvmap)[1] = cpu_to_be64(physend);
((u64 *)cxt->p_rsvmap)[2] = 0;
((u64 *)cxt->p_rsvmap)[3] = 0;
cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY;
cxt->p_start += SIZE_OF_RSVMAP_ENTRY;
cxt->p += SIZE_OF_RSVMAP_ENTRY;
cxt->p_end += SIZE_OF_RSVMAP_ENTRY;
}
void ft_end_tree(struct ft_cxt *cxt)
{
ft_put_word(cxt, OF_DT_END);
}
/* update the boot param header with correct values */
void ft_finalize_tree(struct ft_cxt *cxt) {
struct boot_param_header *bph = cxt->bph;
bph->totalsize = cxt->p_end - (u8 *)bph;
bph->off_dt_struct = cxt->p_start - (u8 *)bph;
bph->off_dt_strings = cxt->p - (u8 *)bph;
bph->dt_strings_size = cxt->p_end - cxt->p;
}
static int is_printable_string(const void *data, int len)
{
const char *s = data;
const char *ss;
/* zero length is not */
if (len == 0)
return 0;
/* must terminate with zero */
if (s[len - 1] != '\0')
return 0;
ss = s;
while (*s && isprint(*s))
s++;
/* not zero, or not done yet */
if (*s != '\0' || (s + 1 - ss) < len)
return 0;
return 1;
}
static void print_data(const void *data, int len)
{
int i;
const u8 *s;
/* no data, don't print */
if (len == 0)
return;
if (is_printable_string(data, len)) {
puts(" = \"");
puts(data);
puts("\"");
return;
}
switch (len) {
case 1: /* byte */
printf(" = <%02x>", (*(u8 *) data) & 0xff);
break;
case 2: /* half-word */
printf(" = <%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
break;
case 4: /* word */
printf(" = <%x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
break;
case 8: /* double-word */
printf(" = <%qx>", be64_to_cpu(*(uint64_t *) data));
break;
default: /* anything else... hexdump */
printf(" = [");
for (i = 0, s = data; i < len; i++)
printf("%02x%s", s[i], i < len - 1 ? " " : "");
printf("]");
break;
}
}
void ft_dump_blob(const void *bphp)
{
const struct boot_param_header *bph = bphp;
const uint64_t *p_rsvmap = (const uint64_t *)
((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
const u32 *p_struct = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_struct));
const u32 *p_strings = (const u32 *)
((const char *)bph + be32_to_cpu(bph->off_dt_strings));
u32 tag;
const u32 *p;
const char *s, *t;
int depth, sz, shift;
int i;
uint64_t addr, size;
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
/* not valid tree */
return;
}
depth = 0;
shift = 4;
for (i = 0;; i++) {
addr = be64_to_cpu(p_rsvmap[i * 2]);
size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
if (addr == 0 && size == 0)
break;
printf("/memreserve/ %qx %qx;\n", addr, size);
}
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
if (tag == OF_DT_BEGIN_NODE) {
s = (const char *)p;
p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);
printf("%*s%s {\n", depth * shift, "", s);
depth++;
continue;
}
if (tag == OF_DT_END_NODE) {
depth--;
printf("%*s};\n", depth * shift, "");
continue;
}
if (tag == OF_DT_NOP) {
printf("%*s[NOP]\n", depth * shift, "");
continue;
}
if (tag != OF_DT_PROP) {
fprintf(stderr, "%*s ** Unknown tag 0x%08x at 0x%x\n",
depth * shift, "", tag, --p);
break;
}
sz = be32_to_cpu(*p++);
s = (const char *)p_strings + be32_to_cpu(*p++);
t = (const char *)p;
p = (const u32 *)_ALIGN((unsigned long)p + sz, 4);
printf("%*s%s", depth * shift, "", s);
print_data(t, sz);
printf(";\n");
}
}
void ft_backtrack_node(struct ft_cxt *cxt)
{
int i = 4;
while (be32_to_cpu(*(u32 *) (cxt->p - i)) != OF_DT_END_NODE)
i += 4;
memmove (cxt->p - i, cxt->p, cxt->p_end - cxt->p);
cxt->p_end -= i;
cxt->p -= i;
}
void *ft_get_prop(void *bphp, const char *propname, int *szp)
{
struct boot_param_header *bph = bphp;
uint32_t *p_struct =
(uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
uint32_t *p_strings =
(uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
uint32_t version = be32_to_cpu(bph->version);
uint32_t tag;
uint32_t *p;
char *s, *t;
char *ss;
int sz;
static char path[256], prop[256];
path[0] = '\0';
p = p_struct;
while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {
if (tag == OF_DT_BEGIN_NODE) {
s = (char *)p;
p = (uint32_t *) _ALIGN((unsigned long)p + strlen(s) +
1, 4);
strcat(path, s);
strcat(path, "/");
continue;
}
if (tag == OF_DT_END_NODE) {
path[strlen(path) - 1] = '\0';
ss = strrchr(path, '/');
if (ss != NULL)
ss[1] = '\0';
continue;
}
if (tag == OF_DT_NOP)
continue;
if (tag != OF_DT_PROP)
break;
sz = be32_to_cpu(*p++);
s = (char *)p_strings + be32_to_cpu(*p++);
if (version < 0x10 && sz >= 8)
p = (uint32_t *) _ALIGN((unsigned long)p, 8);
t = (char *)p;
p = (uint32_t *) _ALIGN((unsigned long)p + sz, 4);
strcpy(prop, path);
strcat(prop, s);
if (strcmp(prop, propname) == 0) {
*szp = sz;
return t;
}
}
return NULL;
}
/********************************************************************/
void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end)
{
u32 *p;
int len;
struct ft_cxt cxt;
ulong clock;
/* disable OF tree; booting old kernel */
if (getenv("disable_of") != NULL) {
memcpy(blob, bd, sizeof(*bd));
return;
}
#ifdef DEBUG
printf ("recieved oftree\n");
ft_dump_blob(blob);
#endif
ft_init_cxt(&cxt, blob);
if (initrd_start && initrd_end)
ft_add_rsvmap(&cxt, initrd_start, initrd_end - initrd_start + 1);
/* back into root */
ft_backtrack_node(&cxt);
ft_begin_node(&cxt, "chosen");
ft_prop_str(&cxt, "name", "chosen");
ft_prop_str(&cxt, "bootargs", getenv("bootargs"));
ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */
if (initrd_start && initrd_end) {
ft_prop_int(&cxt, "linux,initrd-start", initrd_start);
ft_prop_int(&cxt, "linux,initrd-end", initrd_end);
}
#ifdef OF_STDOUT_PATH
ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH);
#endif
ft_end_node(&cxt);
ft_end_node(&cxt); /* end root */
ft_end_tree(&cxt);
ft_finalize_tree(&cxt);
#ifdef CONFIG_PPC
clock = bd->bi_intfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
#ifdef OF_TBCLK
clock = OF_TBCLK;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(clock);
#endif
#endif /* __powerpc__ */
#ifdef CONFIG_OF_BOARD_SETUP
ft_board_setup(blob, bd);
#endif
/* in case the size changed in the platform code */
ft_finalize_tree(&cxt);
#ifdef DEBUG
printf("final OF-tree\n");
ft_dump_blob(blob);
#endif
}
#endif

View File

@ -44,8 +44,9 @@
#include <74xx_7xx.h> #include <74xx_7xx.h>
#include <asm/cache.h> #include <asm/cache.h>
#if defined(CONFIG_OF_FLAT_TREE) #if defined(CONFIG_OF_LIBFDT)
#include <ft_build.h> #include <libfdt.h>
#include <fdt_support.h>
#endif #endif
#ifdef CONFIG_AMIGAONEG3SE #ifdef CONFIG_AMIGAONEG3SE
@ -301,29 +302,19 @@ watchdog_reset(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
#ifdef CONFIG_OF_FLAT_TREE #ifdef CONFIG_OF_LIBFDT
void void ft_cpu_setup(void *blob, bd_t *bd)
ft_cpu_setup (void *blob, bd_t *bd)
{ {
u32 *p; do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
ulong clock; "timebase-frequency", bd->bi_busfreq / 4, 1);
int len; do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
"bus-frequency", bd->bi_busfreq, 1);
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
"clock-frequency", bd->bi_intfreq, 1);
clock = bd->bi_busfreq; fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
p = ft_get_prop (blob, "/cpus/" OF_CPU "/bus-frequency", &len); fdt_fixup_ethernet(blob, bd);
if (p != NULL)
*p = cpu_to_be32 (clock);
#if defined(CONFIG_TSI108_ETH)
p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6200/address", &len);
memcpy (p, bd->bi_enetaddr, 6);
#endif
#if defined(CONFIG_HAS_ETH1)
p = ft_get_prop (blob, "/" OF_TSI "/ethernet@6600/address", &len);
memcpy (p, bd->bi_enet1addr, 6);
#endif
} }
#endif #endif
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -33,8 +33,9 @@
#include <pci.h> #include <pci.h>
#include <asm/io.h> #include <asm/io.h>
#include <tsi108.h> #include <tsi108.h>
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_LIBFDT)
#include <ft_build.h> #include <libfdt.h>
#include <fdt_support.h>
#endif #endif
struct pci_controller local_hose; struct pci_controller local_hose;
@ -162,20 +163,24 @@ void pci_init_board (void)
return; return;
} }
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_LIBFDT)
void void ft_pci_setup(void *blob, bd_t *bd)
ft_pci_setup (void *blob, bd_t *bd)
{ {
u32 *p; int nodeoffset;
int len; int tmp[2];
const char *path;
p = (u32 *)ft_get_prop (blob, "/" OF_TSI "/pci@1000/bus-range", &len); nodeoffset = fdt_path_offset(blob, "/aliases");
if (p != NULL) { if (nodeoffset >= 0) {
p[0] = local_hose.first_busno; path = fdt_getprop(blob, nodeoffset, "pci", NULL);
p[1] = local_hose.last_busno; if (path) {
tmp[0] = cpu_to_be32(local_hose.first_busno);
tmp[1] = cpu_to_be32(local_hose.last_busno);
do_fixup_by_path(blob, path, "bus-range",
&tmp, sizeof(tmp), 1);
}
} }
} }
#endif #endif /* CONFIG_OF_LIBFDT */
#endif /* CONFIG_TSI108_PCI */ #endif /* CONFIG_TSI108_PCI */

View File

@ -58,6 +58,7 @@
#define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_BOARD_EARLY_INIT_R
#define CONFIG_MISC_INIT_R #define CONFIG_MISC_INIT_R
#define CONFIG_HAS_ETH0
#define CONFIG_HAS_ETH1 #define CONFIG_HAS_ETH1
#define CONFIG_ENV_OVERWRITE #define CONFIG_ENV_OVERWRITE
@ -75,7 +76,7 @@
#define CFG_PROMPT_HUSH_PS2 "> " #define CFG_PROMPT_HUSH_PS2 "> "
/* Pass open firmware flat tree */ /* Pass open firmware flat tree */
#define CONFIG_OF_FLAT_TREE 1 #define CONFIG_OF_LIBFDT 1
#define CONFIG_OF_BOARD_SETUP 1 #define CONFIG_OF_BOARD_SETUP 1
#define OF_CPU "PowerPC,7448@0" #define OF_CPU "PowerPC,7448@0"

View File

@ -590,8 +590,8 @@ typedef unsigned int led_id_t;
/*****************************************************************************/ /*****************************************************************************/
/* pass open firmware flat tree */ /* pass open firmware flattened device tree */
#define CONFIG_OF_FLAT_TREE 1 #define CONFIG_OF_LIBFDT 1
#define OF_CPU "PowerPC,MPC870@0" #define OF_CPU "PowerPC,MPC870@0"
#define OF_TBCLK (MPC8XX_HZ / 16) #define OF_TBCLK (MPC8XX_HZ / 16)

View File

@ -1,71 +0,0 @@
/*
* OF Flat tree builder
*
*/
#ifndef FT_BUILD_H
#define FT_BUILD_H
#include <linux/types.h>
#include <asm/u-boot.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
#define OF_DT_END_NODE 0x2 /* End node */
#define OF_DT_PROP 0x3 /* Property: name off, size,
* content */
#define OF_DT_NOP 0x4 /* nop */
#define OF_DT_END 0x9
#define OF_DT_VERSION 0x10
struct boot_param_header {
u32 magic; /* magic word OF_DT_HEADER */
u32 totalsize; /* total size of DT block */
u32 off_dt_struct; /* offset to structure */
u32 off_dt_strings; /* offset to strings */
u32 off_mem_rsvmap; /* offset to memory reserve map */
u32 version; /* format version */
u32 last_comp_version; /* last compatible version */
/* version 2 fields below */
u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
/* version 3 fields below */
u32 dt_strings_size; /* size of the DT strings block */
};
struct ft_cxt {
struct boot_param_header *bph;
u8 *p_rsvmap;
u8 *p_start; /* pointer to beginning of dt_struct */
u8 *p_end; /* pointer to end of dt_strings */
u8 *p; /* pointer to end of dt_struct and beginning of dt_strings */
};
void ft_begin_node(struct ft_cxt *cxt, const char *name);
void ft_init_cxt(struct ft_cxt *cxt, void *blob);
void ft_end_node(struct ft_cxt *cxt);
void ft_end_tree(struct ft_cxt *cxt);
void ft_finalize_tree(struct ft_cxt *cxt);
void ft_nop(struct ft_cxt *cxt);
void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz);
void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
void ft_prop_int(struct ft_cxt *cxt, const char *name, int val);
void ft_begin(struct ft_cxt *cxt, void *blob, int max_size);
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end);
void ft_dump_blob(const void *bphp);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_get_prop(void *bphp, const char *propname, int *szp);
#ifdef CONFIG_OF_BOARD_SETUP
void ft_board_setup(void *blob, bd_t *bd);
void ft_cpu_setup(void *blob, bd_t *bd);
void ft_pci_setup(void *blob, bd_t *bd);
#endif
#endif

View File

@ -31,7 +31,7 @@
#include <stddef.h> #include <stddef.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
extern struct fdt_header *fdt; /* Pointer to the working fdt */ extern struct fdt_header *working_fdt; /* Pointer to the working fdt */
#define fdt32_to_cpu(x) __be32_to_cpu(x) #define fdt32_to_cpu(x) __be32_to_cpu(x)
#define cpu_to_fdt32(x) __cpu_to_be32(x) #define cpu_to_fdt32(x) __cpu_to_be32(x)

View File

@ -750,7 +750,7 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
*of_flat_tree = (char *)of_start; *of_flat_tree = (char *)of_start;
} else { } else {
*of_flat_tree = fdt_blob; *of_flat_tree = fdt_blob;
lmb_reserve(lmb, (ulong)fdt, of_len); lmb_reserve(lmb, (ulong)working_fdt, of_len);
} }
return 0; return 0;

View File

@ -133,16 +133,23 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
return tag; return tag;
} }
int _fdt_check_node_offset(const void *fdt, int offset)
{
if ((offset < 0) || (offset % FDT_TAGSIZE)
|| (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
return -FDT_ERR_BADOFFSET;
return offset;
}
int fdt_next_node(const void *fdt, int offset, int *depth) int fdt_next_node(const void *fdt, int offset, int *depth)
{ {
int nextoffset = 0; int nextoffset = 0;
uint32_t tag; uint32_t tag;
if (offset >= 0) { if (offset >= 0)
tag = fdt_next_tag(fdt, offset, &nextoffset); if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
if (tag != FDT_BEGIN_NODE) return nextoffset;
return -FDT_ERR_BADOFFSET;
}
do { do {
offset = nextoffset; offset = nextoffset;

View File

@ -161,16 +161,12 @@ int fdt_path_offset(const void *fdt, const char *path)
const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
{ {
const struct fdt_node_header *nh; const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
int err; int err;
if ((err = fdt_check_header(fdt)) != 0) if (((err = fdt_check_header(fdt)) != 0)
goto fail; || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
goto fail;
err = -FDT_ERR_BADOFFSET;
nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
goto fail;
if (len) if (len)
*len = strlen(nh->name); *len = strlen(nh->name);
@ -193,17 +189,11 @@ const struct fdt_property *fdt_get_property(const void *fdt,
int offset, nextoffset; int offset, nextoffset;
int err; int err;
if ((err = fdt_check_header(fdt)) != 0) if (((err = fdt_check_header(fdt)) != 0)
goto fail; || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
goto fail;
err = -FDT_ERR_BADOFFSET;
if (nodeoffset % FDT_TAGSIZE)
goto fail;
tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
if (tag != FDT_BEGIN_NODE)
goto fail;
nextoffset = err;
do { do {
offset = nextoffset; offset = nextoffset;

View File

@ -176,8 +176,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
struct fdt_reserve_entry *re; struct fdt_reserve_entry *re;
int err; int err;
if ((err = rw_check_header(fdt))) RW_CHECK_HEADER(fdt);
return err;
re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
err = _blob_splice_mem_rsv(fdt, re, 0, 1); err = _blob_splice_mem_rsv(fdt, re, 0, 1);
@ -194,8 +193,8 @@ int fdt_del_mem_rsv(void *fdt, int n)
struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
int err; int err;
if ((err = rw_check_header(fdt))) RW_CHECK_HEADER(fdt);
return err;
if (n >= fdt_num_mem_rsv(fdt)) if (n >= fdt_num_mem_rsv(fdt))
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
@ -227,15 +226,13 @@ static int _resize_property(void *fdt, int nodeoffset, const char *name, int len
static int _add_property(void *fdt, int nodeoffset, const char *name, int len, static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
struct fdt_property **prop) struct fdt_property **prop)
{ {
uint32_t tag;
int proplen; int proplen;
int nextoffset; int nextoffset;
int namestroff; int namestroff;
int err; int err;
tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
if (tag != FDT_BEGIN_NODE) return nextoffset;
return -FDT_ERR_BADOFFSET;
namestroff = _find_add_string(fdt, name); namestroff = _find_add_string(fdt, name);
if (namestroff < 0) if (namestroff < 0)
@ -260,8 +257,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
int oldlen, newlen; int oldlen, newlen;
int err; int err;
if ((err = rw_check_header(fdt))) RW_CHECK_HEADER(fdt);
return err;
namep = (char *)fdt_get_name(fdt, nodeoffset, &oldlen); namep = (char *)fdt_get_name(fdt, nodeoffset, &oldlen);
if (!namep) if (!namep)
@ -284,8 +280,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
struct fdt_property *prop; struct fdt_property *prop;
int err; int err;
if ((err = rw_check_header(fdt))) RW_CHECK_HEADER(fdt);
return err;
err = _resize_property(fdt, nodeoffset, name, len, &prop); err = _resize_property(fdt, nodeoffset, name, len, &prop);
if (err == -FDT_ERR_NOTFOUND) if (err == -FDT_ERR_NOTFOUND)
@ -456,11 +451,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
int fdt_pack(void *fdt) int fdt_pack(void *fdt)
{ {
int mem_rsv_size; int mem_rsv_size;
int err;
err = rw_check_header(fdt); RW_CHECK_HEADER(fdt);
if (err)
return err;
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
* sizeof(struct fdt_reserve_entry); * sizeof(struct fdt_reserve_entry);

View File

@ -55,13 +55,21 @@
#include "libfdt_internal.h" #include "libfdt_internal.h"
static int check_header_sw(void *fdt) static int sw_check_header(void *fdt)
{ {
if (fdt_magic(fdt) != SW_MAGIC) if (fdt_magic(fdt) != SW_MAGIC)
return -FDT_ERR_BADMAGIC; return -FDT_ERR_BADMAGIC;
/* FIXME: should check more details about the header state */
return 0; return 0;
} }
#define SW_CHECK_HEADER(fdt) \
{ \
int err; \
if ((err = sw_check_header(fdt)) != 0) \
return err; \
}
static void *grab_space(void *fdt, int len) static void *grab_space(void *fdt, int len)
{ {
int offset = fdt_size_dt_struct(fdt); int offset = fdt_size_dt_struct(fdt);
@ -102,11 +110,10 @@ int fdt_create(void *buf, int bufsize)
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
{ {
struct fdt_reserve_entry *re; struct fdt_reserve_entry *re;
int err = check_header_sw(fdt);
int offset; int offset;
if (err) SW_CHECK_HEADER(fdt);
return err;
if (fdt_size_dt_struct(fdt)) if (fdt_size_dt_struct(fdt))
return -FDT_ERR_BADSTATE; return -FDT_ERR_BADSTATE;
@ -131,11 +138,9 @@ int fdt_finish_reservemap(void *fdt)
int fdt_begin_node(void *fdt, const char *name) int fdt_begin_node(void *fdt, const char *name)
{ {
struct fdt_node_header *nh; struct fdt_node_header *nh;
int err = check_header_sw(fdt);
int namelen = strlen(name) + 1; int namelen = strlen(name) + 1;
if (err) SW_CHECK_HEADER(fdt);
return err;
nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE)); nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
if (! nh) if (! nh)
@ -149,10 +154,8 @@ int fdt_begin_node(void *fdt, const char *name)
int fdt_end_node(void *fdt) int fdt_end_node(void *fdt)
{ {
uint32_t *en; uint32_t *en;
int err = check_header_sw(fdt);
if (err) SW_CHECK_HEADER(fdt);
return err;
en = grab_space(fdt, FDT_TAGSIZE); en = grab_space(fdt, FDT_TAGSIZE);
if (! en) if (! en)
@ -188,11 +191,9 @@ static int find_add_string(void *fdt, const char *s)
int fdt_property(void *fdt, const char *name, const void *val, int len) int fdt_property(void *fdt, const char *name, const void *val, int len)
{ {
struct fdt_property *prop; struct fdt_property *prop;
int err = check_header_sw(fdt);
int nameoff; int nameoff;
if (err) SW_CHECK_HEADER(fdt);
return err;
nameoff = find_add_string(fdt, name); nameoff = find_add_string(fdt, name);
if (nameoff == 0) if (nameoff == 0)
@ -211,15 +212,13 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
int fdt_finish(void *fdt) int fdt_finish(void *fdt)
{ {
int err = check_header_sw(fdt);
char *p = (char *)fdt; char *p = (char *)fdt;
uint32_t *end; uint32_t *end;
int oldstroffset, newstroffset; int oldstroffset, newstroffset;
uint32_t tag; uint32_t tag;
int offset, nextoffset; int offset, nextoffset;
if (err) SW_CHECK_HEADER(fdt);
return err;
/* Add terminator */ /* Add terminator */
end = grab_space(fdt, sizeof(*end)); end = grab_space(fdt, sizeof(*end));

View File

@ -66,6 +66,7 @@
} }
uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
int _fdt_check_node_offset(const void *fdt, int offset);
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
int _fdt_node_end_offset(void *fdt, int nodeoffset); int _fdt_node_end_offset(void *fdt, int nodeoffset);