diff options
author | Wolfgang Denk <wd@denx.de> | 2008-03-25 00:12:54 +0100 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2008-03-25 00:12:54 +0100 |
commit | b38d7fc2f1d27957a810950f07c27f2be353f50f (patch) | |
tree | b947276514cda8100cfef630f624e563378cbca3 | |
parent | 55774b512fdf63c0516d441cc5da7c54bbffb7f2 (diff) | |
parent | 47310715f4316a3677b206acf9f83adb7949ecd1 (diff) | |
download | u-boot-imx-b38d7fc2f1d27957a810950f07c27f2be353f50f.zip u-boot-imx-b38d7fc2f1d27957a810950f07c27f2be353f50f.tar.gz u-boot-imx-b38d7fc2f1d27957a810950f07c27f2be353f50f.tar.bz2 |
Merge branch 'master' of /home/wd/git/u-boot/master/
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | common/cmd_fdt.c | 113 | ||||
-rw-r--r-- | drivers/mtd/cfi_flash.c | 40 | ||||
-rw-r--r-- | include/configs/TQM5200.h | 21 | ||||
-rw-r--r-- | include/libfdt.h | 32 | ||||
-rw-r--r-- | libfdt/fdt.c | 46 | ||||
-rw-r--r-- | libfdt/fdt_ro.c | 277 | ||||
-rw-r--r-- | libfdt/fdt_rw.c | 34 | ||||
-rw-r--r-- | libfdt/libfdt_internal.h | 7 | ||||
-rw-r--r-- | post/board/lwmon5/watchdog.c | 43 |
10 files changed, 389 insertions, 229 deletions
@@ -1946,6 +1946,11 @@ Configuration Settings: is useful, if some of the configured banks are only optionally available. +- CONFIG_FLASH_SHOW_PROGRESS + If defined (must be an integer), print out countdown + digits and dots. Recommended value: 45 (9..1) for 80 + column displays, 15 (3..1) for 40 column displays. + - CFG_RX_ETH_BUFFER: Defines the number of ethernet receive buffers. On some ethernet controllers it is recommended to set this value diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 9cd22ee..14c3fa0 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -260,7 +260,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /******************************************************************** * Remove a property/node ********************************************************************/ - } else if (argv[1][0] == 'r') { + } else if ((argv[1][0] == 'r') && (argv[1][1] == 'm')) { int nodeoffset; /* node offset from libfdt */ int err; @@ -296,6 +296,111 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return err; } } + + /******************************************************************** + * Display header info + ********************************************************************/ + } else if (argv[1][0] == 'h') { + u32 version = fdt_version(fdt); + printf("magic:\t\t\t0x%x\n", fdt_magic(fdt)); + printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(fdt), fdt_totalsize(fdt)); + printf("off_dt_struct:\t\t0x%x\n", fdt_off_dt_struct(fdt)); + printf("off_dt_strings:\t\t0x%x\n", fdt_off_dt_strings(fdt)); + printf("off_mem_rsvmap:\t\t0x%x\n", fdt_off_mem_rsvmap(fdt)); + printf("version:\t\t%d\n", version); + printf("last_comp_version:\t%d\n", fdt_last_comp_version(fdt)); + if (version >= 2) + printf("boot_cpuid_phys:\t0x%x\n", + fdt_boot_cpuid_phys(fdt)); + if (version >= 3) + printf("size_dt_strings:\t0x%x\n", + fdt_size_dt_strings(fdt)); + if (version >= 17) + printf("size_dt_struct:\t\t0x%x\n", + fdt_size_dt_struct(fdt)); + printf("number mem_rsv:\t\t0x%x\n", fdt_num_mem_rsv(fdt)); + printf("\n"); + + /******************************************************************** + * Set boot cpu id + ********************************************************************/ + } else if ((argv[1][0] == 'b') && (argv[1][1] == 'o') && + (argv[1][2] == 'o')) { + unsigned long tmp = simple_strtoul(argv[2], NULL, 16); + fdt_set_boot_cpuid_phys(fdt, tmp); + + /******************************************************************** + * memory command + ********************************************************************/ + } else if ((argv[1][0] == 'm') && (argv[1][1] == 'e')) { + uint64_t addr, size; + int err; +#ifdef CFG_64BIT_STRTOUL + addr = simple_strtoull(argv[2], NULL, 16); + size = simple_strtoull(argv[3], NULL, 16); +#else + addr = simple_strtoul(argv[2], NULL, 16); + size = simple_strtoul(argv[3], NULL, 16); +#endif + err = fdt_fixup_memory(fdt, addr, size); + if (err < 0) + return err; + + /******************************************************************** + * mem reserve commands + ********************************************************************/ + } else if ((argv[1][0] == 'r') && (argv[1][1] == 's')) { + if (argv[2][0] == 'p') { + uint64_t addr, size; + int total = fdt_num_mem_rsv(fdt); + int j, err; + printf("index\t\t start\t\t size\n"); + printf("-------------------------------" + "-----------------\n"); + for (j = 0; j < total; j++) { + err = fdt_get_mem_rsv(fdt, j, &addr, &size); + if (err < 0) { + printf("libfdt fdt_get_mem_rsv(): %s\n", + fdt_strerror(err)); + return err; + } + printf(" %x\t%08x%08x\t%08x%08x\n", j, + (u32)(addr >> 32), + (u32)(addr & 0xffffffff), + (u32)(size >> 32), + (u32)(size & 0xffffffff)); + } + } else if (argv[2][0] == 'a') { + uint64_t addr, size; + int err; +#ifdef CFG_64BIT_STRTOUL + addr = simple_strtoull(argv[3], NULL, 16); + size = simple_strtoull(argv[4], NULL, 16); +#else + addr = simple_strtoul(argv[3], NULL, 16); + size = simple_strtoul(argv[4], NULL, 16); +#endif + err = fdt_add_mem_rsv(fdt, addr, size); + + if (err < 0) { + printf("libfdt fdt_add_mem_rsv(): %s\n", + fdt_strerror(err)); + return err; + } + } else if (argv[2][0] == 'd') { + unsigned long idx = simple_strtoul(argv[3], NULL, 16); + int err = fdt_del_mem_rsv(fdt, idx); + + if (err < 0) { + printf("libfdt fdt_del_mem_rsv(): %s\n", + fdt_strerror(err)); + return err; + } + } else { + /* Unrecognized command */ + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } } #ifdef CONFIG_OF_BOARD_SETUP /* Call the board-specific fixup routine */ @@ -689,6 +794,12 @@ U_BOOT_CMD( "fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n" "fdt mknode <path> <node> - Create a new node after <path>\n" "fdt rm <path> [<prop>] - Delete the node or <property>\n" + "fdt header - Display header info\n" + "fdt bootcpu <id> - Set boot cpuid\n" + "fdt memory <addr> <size> - Add/Update memory node\n" + "fdt rsvmem print - Show current mem reserves\n" + "fdt rsvmem add <addr> <size> - Add a mem reserve\n" + "fdt rsvmem delete <index> - Delete a mem reserves\n" "fdt chosen - Add/update the /chosen branch in the tree\n" #ifdef CONFIG_OF_HAS_UBOOT_ENV "fdt env - Add/replace the /u-boot-env branch in the tree\n" diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 439c950..f04c72d 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1180,6 +1180,27 @@ void flash_print_info (flash_info_t * info) } /*----------------------------------------------------------------------- + * This is used in a few places in write_buf() to show programming + * progress. Making it a function is nasty because it needs to do side + * effect updates to digit and dots. Repeated code is nasty too, so + * we define it once here. + */ +#ifdef CONFIG_FLASH_SHOW_PROGRESS +#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \ + dots -= dots_sub; \ + if ((scale > 0) && (dots <= 0)) { \ + if ((digit % 5) == 0) \ + printf ("%d", digit / 5); \ + else \ + putc ('.'); \ + digit--; \ + dots += scale; \ + } +#else +#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) +#endif + +/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout @@ -1192,10 +1213,23 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) int aln; cfiword_t cword; int i, rc; - #ifdef CFG_FLASH_USE_BUFFER_WRITE int buffered_size; #endif +#ifdef CONFIG_FLASH_SHOW_PROGRESS + int digit = CONFIG_FLASH_SHOW_PROGRESS; + int scale = 0; + int dots = 0; + + /* + * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes. + */ + if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) { + scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) / + CONFIG_FLASH_SHOW_PROGRESS); + } +#endif + /* get lower aligned address */ wp = (addr & ~(info->portwidth - 1)); @@ -1219,6 +1253,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) return rc; wp += i; + FLASH_SHOW_PROGRESS(scale, dots, digit, i); } /* handle the aligned part */ @@ -1248,6 +1283,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) wp += i; src += i; cnt -= i; + FLASH_SHOW_PROGRESS(scale, dots, digit, i); } #else while (cnt >= info->portwidth) { @@ -1259,8 +1295,10 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) return rc; wp += info->portwidth; cnt -= info->portwidth; + FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth); } #endif /* CFG_FLASH_USE_BUFFER_WRITE */ + if (cnt == 0) { return (0); } diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 9a0e9b8..b36c826 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -252,12 +252,22 @@ "setup=tftp 200000 cam5200/setup.img; autoscr 200000\0" #endif +#if defined(CONFIG_TQM5200_B) +#define ENV_FLASH_LAYOUT \ + "fdt_addr=FC100000\0" \ + "kernel_addr=FC140000\0" \ + "ramdisk_addr=FC600000\0" +#else /* !CONFIG_TQM5200_B */ +#define ENV_FLASH_LAYOUT \ + "fdt_addr=FC0A0000\0" \ + "kernel_addr=FC0C0000\0" \ + "ramdisk_addr=FC300000\0" +#endif + #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ "console=ttyPSC0\0" \ - "fdt_addr=FC0A0000\0" \ - "kernel_addr=FC0C0000\0" \ - "ramdisk_addr=FC300000\0" \ + ENV_FLASH_LAYOUT \ "kernel_addr_r=400000\0" \ "fdt_addr_r=600000\0" \ "rootpath=/opt/eldk/ppc_6xx\0" \ @@ -400,8 +410,9 @@ # if defined(CONFIG_TQM5200_B) # if defined(CFG_LOWBOOT) # define MTDPARTS_DEFAULT "mtdparts=TQM5200-0:1m(firmware)," \ - "1536k(kernel)," \ - "3584k(small-fs)," \ + "256k(dtb)," \ + "2304k(kernel)," \ + "2560k(small-fs)," \ "2m(initrd)," \ "8m(misc)," \ "16m(big-fs)" diff --git a/include/libfdt.h b/include/libfdt.h index 6c05236..beeacb2 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -131,6 +131,12 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); /**********************************************************************/ +/* Traversal functions */ +/**********************************************************************/ + +int fdt_next_node(const void *fdt, int offset, int *depth); + +/**********************************************************************/ /* General functions */ /**********************************************************************/ @@ -846,6 +852,32 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); int fdt_del_mem_rsv(void *fdt, int n); /** + * fdt_set_name - change the name of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * @name: name to give the node + * + * fdt_set_name() replaces the name (including unit address, if any) + * of the given node with the given string. NOTE: this function can't + * efficiently check if the new name is unique amongst the given + * node's siblings; results are undefined if this function is invoked + * with a name equal to one of the given node's siblings. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob + * to contain the new name + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_set_name(void *fdt, int nodeoffset, const char *name); + +/** * fdt_setprop - create or change a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 586a361..bd91712 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -129,6 +129,47 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) return tag; } +int fdt_next_node(const void *fdt, int offset, int *depth) +{ + int nextoffset = 0; + uint32_t tag; + + if (offset >= 0) { + tag = fdt_next_tag(fdt, offset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + } + + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_PROP: + case FDT_NOP: + break; + + case FDT_BEGIN_NODE: + if (depth) + (*depth)++; + break; + + case FDT_END_NODE: + if (depth) + (*depth)--; + break; + + case FDT_END: + return -FDT_ERR_NOTFOUND; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag != FDT_BEGIN_NODE); + + return offset; +} + const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; @@ -143,10 +184,7 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) int fdt_move(const void *fdt, void *buf, int bufsize) { - int err = fdt_check_header(fdt); - - if (err) - return err; + CHECK_HEADER(fdt); if (fdt_totalsize(fdt) > bufsize) return -FDT_ERR_NOSPACE; diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 12a37d5..63fa129 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -55,17 +55,10 @@ #include "libfdt_internal.h" -#define CHECK_HEADER(fdt) \ - { \ - int err; \ - if ((err = fdt_check_header(fdt)) != 0) \ - return err; \ - } - static int nodename_eq(const void *fdt, int offset, const char *s, int len) { - const char *p = fdt_offset_ptr(fdt, offset, len+1); + const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); if (! p) /* short match */ @@ -104,50 +97,24 @@ int fdt_num_mem_rsv(const void *fdt) return i; } -int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, +int fdt_subnode_offset_namelen(const void *fdt, int offset, const char *name, int namelen) { - int level = 0; - uint32_t tag; - int offset, nextoffset; + int depth; CHECK_HEADER(fdt); - tag = fdt_next_tag(fdt, parentoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADOFFSET; - - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_END: - return -FDT_ERR_TRUNCATED; - - case FDT_BEGIN_NODE: - level++; - if (level != 1) - continue; - if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen)) - /* Found it! */ - return offset; - break; - - case FDT_END_NODE: - level--; - break; - - case FDT_PROP: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (level >= 0); + for (depth = 0; + offset >= 0; + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth < 0) + return -FDT_ERR_NOTFOUND; + else if ((depth == 1) + && nodename_eq(fdt, offset, name, namelen)) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error */ } int fdt_subnode_offset(const void *fdt, int parentoffset, @@ -307,76 +274,61 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { - uint32_t tag; - int p = 0, overflow = 0; - int offset, nextoffset, namelen; + int pdepth = 0, p = 0; + int offset, depth, namelen; const char *name; CHECK_HEADER(fdt); - tag = fdt_next_tag(fdt, 0, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADSTRUCTURE; - if (buflen < 2) return -FDT_ERR_NOSPACE; - buf[0] = '/'; - p = 1; - while (nextoffset <= nodeoffset) { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - switch (tag) { - case FDT_END: - return -FDT_ERR_BADOFFSET; + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (pdepth < depth) + continue; /* overflowed buffer */ - case FDT_BEGIN_NODE: - name = fdt_get_name(fdt, offset, &namelen); - if (!name) - return namelen; - if (overflow || ((p + namelen + 1) > buflen)) { - overflow++; - break; - } + while (pdepth > depth) { + do { + p--; + } while (buf[p-1] != '/'); + pdepth--; + } + + name = fdt_get_name(fdt, offset, &namelen); + if (!name) + return namelen; + if ((p + namelen + 1) <= buflen) { memcpy(buf + p, name, namelen); p += namelen; buf[p++] = '/'; - break; - - case FDT_END_NODE: - if (overflow) { - overflow--; - break; - } - do { - p--; - } while (buf[p-1] != '/'); - break; + pdepth++; + } - case FDT_PROP: - case FDT_NOP: - break; + if (offset == nodeoffset) { + if (pdepth < (depth + 1)) + return -FDT_ERR_NOSPACE; - default: - return -FDT_ERR_BADSTRUCTURE; + if (p > 1) /* special case so that root path is "/", not "" */ + p--; + buf[p] = '\0'; + return p; } } - if (overflow) - return -FDT_ERR_NOSPACE; + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; - if (p > 1) /* special case so that root path is "/", not "" */ - p--; - buf[p] = '\0'; - return p; + return offset; /* error from fdt_next_node() */ } int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int supernodedepth, int *nodedepth) { - int level = -1; - uint32_t tag; - int offset, nextoffset = 0; + int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; CHECK_HEADER(fdt); @@ -384,38 +336,29 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - switch (tag) { - case FDT_END: - return -FDT_ERR_BADOFFSET; - - case FDT_BEGIN_NODE: - level++; - if (level == supernodedepth) - supernodeoffset = offset; - break; - - case FDT_END_NODE: - level--; - break; + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth == supernodedepth) + supernodeoffset = offset; - case FDT_PROP: - case FDT_NOP: - break; + if (offset == nodeoffset) { + if (nodedepth) + *nodedepth = depth; - default: - return -FDT_ERR_BADSTRUCTURE; + if (supernodedepth > depth) + return -FDT_ERR_NOTFOUND; + else + return supernodeoffset; } - } while (offset < nodeoffset); + } - if (nodedepth) - *nodedepth = level; + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; - if (supernodedepth > level) - return -FDT_ERR_NOTFOUND; - return supernodeoffset; + return offset; /* error from fdt_next_node() */ } int fdt_node_depth(const void *fdt, int nodeoffset) @@ -443,51 +386,27 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const char *propname, const void *propval, int proplen) { - uint32_t tag; - int offset, nextoffset; + int offset; const void *val; int len; CHECK_HEADER(fdt); - if (startoffset >= 0) { - tag = fdt_next_tag(fdt, startoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADOFFSET; - } else { - nextoffset = 0; - } - /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't * find what we want, we scan over them again making our way * to the next node. Still it's the easiest to implement * approach; performance can come later. */ - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_BEGIN_NODE: - val = fdt_getprop(fdt, offset, propname, &len); - if (val - && (len == proplen) - && (memcmp(val, propval, len) == 0)) - return offset; - break; - - case FDT_PROP: - case FDT_END: - case FDT_END_NODE: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (tag != FDT_END); + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + val = fdt_getprop(fdt, offset, propname, &len); + if (val && (len == proplen) + && (memcmp(val, propval, len) == 0)) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error from fdt_next_node() */ } int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) @@ -534,50 +453,24 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible) { - uint32_t tag; - int offset, nextoffset; - int err; + int offset, err; CHECK_HEADER(fdt); - if (startoffset >= 0) { - tag = fdt_next_tag(fdt, startoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADOFFSET; - } else { - nextoffset = 0; - } - /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_BEGIN_NODE: - err = fdt_node_check_compatible(fdt, offset, - compatible); - if ((err < 0) - && (err != -FDT_ERR_NOTFOUND)) - return err; - else if (err == 0) - return offset; - break; - - case FDT_PROP: - case FDT_END: - case FDT_END_NODE: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (tag != FDT_END); + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + err = fdt_node_check_compatible(fdt, offset, compatible); + if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) + return err; + else if (err == 0) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error from fdt_next_node() */ } diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 6673f8e..0df472b 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -69,10 +69,8 @@ static int _blocks_misordered(const void *fdt, static int rw_check_header(void *fdt) { - int err; + CHECK_HEADER(fdt); - if ((err = fdt_check_header(fdt))) - return err; if (fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), @@ -252,6 +250,30 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len, return 0; } +int fdt_set_name(void *fdt, int nodeoffset, const char *name) +{ + char *namep; + int oldlen, newlen; + int err; + + if ((err = rw_check_header(fdt))) + return err; + + namep = (char *)fdt_get_name(fdt, nodeoffset, &oldlen); + if (!namep) + return oldlen; + + newlen = strlen(name); + + err = _blob_splice_struct(fdt, namep, ALIGN(oldlen+1, FDT_TAGSIZE), + ALIGN(newlen+1, FDT_TAGSIZE)); + if (err) + return err; + + memcpy(namep, name, newlen+1); + return 0; +} + int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len) { @@ -309,7 +331,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); - } while (tag == FDT_PROP); + } while ((tag == FDT_PROP) || (tag == FDT_NOP)); nh = _fdt_offset_ptr_w(fdt, offset); nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; @@ -375,9 +397,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) int newsize; void *tmp; - err = fdt_check_header(fdt); - if (err) - return err; + CHECK_HEADER(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 1e60936..52e1b8d 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -58,6 +58,13 @@ #define memeq(p, q, n) (memcmp((p), (q), (n)) == 0) #define streq(p, q) (strcmp((p), (q)) == 0) +#define CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = fdt_check_header(fdt)) != 0) \ + return err; \ + } + uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); int _fdt_node_end_offset(void *fdt, int nodeoffset); diff --git a/post/board/lwmon5/watchdog.c b/post/board/lwmon5/watchdog.c index 8348346..48ff687 100644 --- a/post/board/lwmon5/watchdog.c +++ b/post/board/lwmon5/watchdog.c @@ -24,7 +24,8 @@ #include <common.h> -/* This test verifies if the reason of last reset was an abnormal voltage +/* + * This test verifies if the reason of last reset was an abnormal voltage * condition, than it performs watchdog test, measuing time required to * trigger watchdog reset. */ @@ -55,7 +56,8 @@ static void watchdog_magic_write(uint value) int sysmon1_post_test(int flags) { if (gpio_read_in_bit(CFG_GPIO_SYSMON_STATUS)) { - /* 3.1. GPIO62 is low + /* + * 3.1. GPIO62 is low * Assuming system voltage failure. */ post_log("Abnormal voltage detected (GPIO62)\n"); @@ -67,11 +69,14 @@ int sysmon1_post_test(int flags) int lwmon5_watchdog_post_test(int flags) { + ulong time; + /* On each reset scratch register 1 should be tested, * but first test GPIO62: */ if (!(flags & POST_MANUAL) && sysmon1_post_test(flags)) { - /* 3.1. GPIO62 is low + /* + * 3.1. GPIO62 is low * Assuming system voltage failure. */ /* 3.1.1. Set scratch register 1 to 0x0000xxxx */ @@ -81,12 +86,12 @@ int lwmon5_watchdog_post_test(int flags) } if (watchdog_magic_read() != CFG_WATCHDOG_MAGIC) { - /* 3.2. Scratch register 1 differs from magic value 0x1248xxxx + /* + * 3.2. Scratch register 1 differs from magic value 0x1248xxxx * Assuming PowerOn */ int ints; ulong base; - ulong time; /* 3.2.1. Set magic value to scratch register */ watchdog_magic_write(CFG_WATCHDOG_MAGIC); @@ -104,28 +109,28 @@ int lwmon5_watchdog_post_test(int flags) if (ints) enable_interrupts (); - /* 3.2.5. Reset didn't happen. - Set 0x0000xxxx + /* + * 3.2.5. Reset didn't happen. - Set 0x0000xxxx * into scratch register 1 */ watchdog_magic_write(0); /* 3.2.6. Mark test as failed. */ post_log("hw watchdog time : %u ms, failed ", time); return 2; - } else { - /* 3.3. Scratch register matches magic value 0x1248xxxx - * Assume this is watchdog-initiated reset - */ - ulong time; - /* 3.3.1. So, the test succeed, save measured time to syslog. */ - time = in_be32((void *)CFG_WATCHDOG_TIME_ADDR); - post_log("hw watchdog time : %u ms, passed ", time); - /* 3.3.2. Set scratch register 1 to 0x0000xxxx */ - watchdog_magic_write(0); - return 0; } - return -1; -} + /* + * 3.3. Scratch register matches magic value 0x1248xxxx + * Assume this is watchdog-initiated reset + */ + /* 3.3.1. So, the test succeed, save measured time to syslog. */ + time = in_be32((void *)CFG_WATCHDOG_TIME_ADDR); + post_log("hw watchdog time : %u ms, passed ", time); + /* 3.3.2. Set scratch register 1 to 0x0000xxxx */ + watchdog_magic_write(0); + + return 0; +} #endif /* CONFIG_POST & CFG_POST_WATCHDOG */ #endif /* CONFIG_POST */ |