diff options
44 files changed, 521 insertions, 270 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/board/bmw/m48t59y.c b/board/bmw/m48t59y.c index d72c861..a1a85d0 100644 --- a/board/bmw/m48t59y.c +++ b/board/bmw/m48t59y.c @@ -278,7 +278,7 @@ void m48_watchdog_arm(int usec) /* * U-Boot RTC support. */ -void +int rtc_get( struct rtc_time *tmp ) { m48_tod_get(&tmp->tm_year, @@ -295,6 +295,8 @@ rtc_get( struct rtc_time *tmp ) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); #endif + + return 0; } void diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index a0fac7f..5264baf 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -170,9 +170,9 @@ long int initdram (int board_type) /* ------------------------------------------------------------------------- */ /* stubs so we can print dates w/o any nvram RTC.*/ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { - return; + return 0; } void rtc_set (struct rtc_time *tmp) { diff --git a/board/etin/debris/phantom.c b/board/etin/debris/phantom.c index 18ab500..263da6b 100644 --- a/board/etin/debris/phantom.c +++ b/board/etin/debris/phantom.c @@ -182,7 +182,7 @@ static int get_century_flag(void) return flag; } -void rtc_get( struct rtc_time *tmp) +int rtc_get( struct rtc_time *tmp) { if (phantom_flag < 0) phantom_flag = get_phantom_flag(); @@ -250,6 +250,8 @@ void rtc_get( struct rtc_time *tmp) tmp->tm_yday = 0; tmp->tm_isdst= 0; } + + return 0; } void rtc_set( struct rtc_time *tmp ) diff --git a/board/mousse/m48t59y.c b/board/mousse/m48t59y.c index 37a6244..2c1e6cf 100644 --- a/board/mousse/m48t59y.c +++ b/board/mousse/m48t59y.c @@ -278,7 +278,7 @@ void m48_watchdog_arm(int usec) /* * U-Boot RTC support. */ -void +int rtc_get( struct rtc_time *tmp ) { m48_tod_get(&tmp->tm_year, @@ -295,6 +295,8 @@ rtc_get( struct rtc_time *tmp ) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); #endif + + return 0; } void 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/cpu/s3c44b0/cpu.c b/cpu/s3c44b0/cpu.c index 5d50b3c..eae6adb 100644 --- a/cpu/s3c44b0/cpu.c +++ b/cpu/s3c44b0/cpu.c @@ -155,7 +155,7 @@ int dcache_status (void) #define HEX2BCD(x) ((((x) / 10) << 4) + (x) % 10) #endif -void rtc_get (struct rtc_time* tm) +int rtc_get (struct rtc_time* tm) { RTCCON |= 1; tm->tm_year = BCD2HEX(BCDYEAR); @@ -184,6 +184,8 @@ void rtc_get (struct rtc_time* tm) tm->tm_year += 1900; else tm->tm_year += 2000; + + return 0; } void rtc_set (struct rtc_time* tm) 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/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c index 5755a20..ce4f171 100644 --- a/drivers/rtc/bfin_rtc.c +++ b/drivers/rtc/bfin_rtc.c @@ -85,7 +85,7 @@ void rtc_set(struct rtc_time *tmp) } /* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ -void rtc_get(struct rtc_time *tmp) +int rtc_get(struct rtc_time *tmp) { uint32_t cur_rtc_stat; int time_in_sec; @@ -95,7 +95,7 @@ void rtc_get(struct rtc_time *tmp) if (tmp == NULL) { puts("Error getting the date/time\n"); - return; + return -1; } wait_for_complete(); @@ -112,6 +112,8 @@ void rtc_get(struct rtc_time *tmp) /* Calculate the total number of seconds since epoch */ time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day); to_tm(time_in_sec, tmp); + + return 0; } #endif diff --git a/drivers/rtc/ds12887.c b/drivers/rtc/ds12887.c index 84fecf0..57a446d 100644 --- a/drivers/rtc/ds12887.c +++ b/drivers/rtc/ds12887.c @@ -88,7 +88,7 @@ static unsigned char bin2bcd (unsigned int n) /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; @@ -150,6 +150,8 @@ else tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/ds1302.c b/drivers/rtc/ds1302.c index 55af130..3a856c8 100644 --- a/drivers/rtc/ds1302.c +++ b/drivers/rtc/ds1302.c @@ -253,9 +253,10 @@ rtc_reset(void) /* TODO */ } -void +int rtc_get(struct rtc_time *tmp) { + int rel = 0; struct ds1302_st bbclk; if(!ds1302_initted) rtc_init(); @@ -265,6 +266,7 @@ rtc_get(struct rtc_time *tmp) if (bbclk.CH) { printf("ds1302: rtc_get: Clock was halted, clock probably " "corrupt\n"); + rel = -1; } tmp->tm_sec=10*bbclk.sec10+bbclk.sec; @@ -281,6 +283,8 @@ rtc_get(struct rtc_time *tmp) DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); + + return rel; } void diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c index 89e433d..1c8ac7f 100644 --- a/drivers/rtc/ds1306.c +++ b/drivers/rtc/ds1306.c @@ -91,7 +91,7 @@ static void init_spi (void); /* ------------------------------------------------------------------------- */ /* read clock time from DS1306 and return it in *tmp */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { volatile immap_t *immap = (immap_t *) CFG_IMMR; unsigned char spi_byte; /* Data Byte */ @@ -141,6 +141,8 @@ void rtc_get (struct rtc_time *tmp) debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } /* ------------------------------------------------------------------------- */ @@ -304,7 +306,7 @@ static unsigned char rtc_read (unsigned char reg); static void rtc_write (unsigned char reg, unsigned char val); /* read clock time from DS1306 and return it in *tmp */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { unsigned char sec, min, hour, mday, wday, mon, year; @@ -349,6 +351,8 @@ void rtc_get (struct rtc_time *tmp) debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } /* ------------------------------------------------------------------------- */ diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c index c882d79..b20f193 100644 --- a/drivers/rtc/ds1307.c +++ b/drivers/rtc/ds1307.c @@ -83,8 +83,9 @@ static unsigned bcd2bin (uchar c); /* * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon, year; sec = rtc_read (RTC_SEC_REG_ADDR); @@ -104,6 +105,7 @@ void rtc_get (struct rtc_time *tmp) /* clear the CH flag */ rtc_write (RTC_SEC_REG_ADDR, rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH); + rel = -1; } tmp->tm_sec = bcd2bin (sec & 0x7F); @@ -119,6 +121,8 @@ void rtc_get (struct rtc_time *tmp) DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c index c636ac5..50ab446 100644 --- a/drivers/rtc/ds1337.c +++ b/drivers/rtc/ds1337.c @@ -84,8 +84,9 @@ static unsigned bcd2bin (uchar c); /* * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon_cent, year, control, status; control = rtc_read (RTC_CTL_REG_ADDR); @@ -107,6 +108,7 @@ void rtc_get (struct rtc_time *tmp) /* clear the OSF flag */ rtc_write (RTC_STAT_REG_ADDR, rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF); + rel = -1; } tmp->tm_sec = bcd2bin (sec & 0x7F); @@ -122,6 +124,8 @@ void rtc_get (struct rtc_time *tmp) DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c index e773dd9..f6bb296 100644 --- a/drivers/rtc/ds1374.c +++ b/drivers/rtc/ds1374.c @@ -107,8 +107,8 @@ static void rtc_write_raw (uchar reg, uchar val); /* * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tm){ - +int rtc_get (struct rtc_time *tm){ + int rel = 0; unsigned long time1, time2; unsigned int limit; unsigned char tmp; @@ -138,18 +138,23 @@ void rtc_get (struct rtc_time *tm){ if (time1 != time2) { printf("can't get consistent time from rtc chip\n"); + rel = -1; } DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1); to_tm(time1, tm); /* To Gregorian Date */ - if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) + if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) { printf ("### Warning: RTC oscillator has stopped\n"); + rel = -1; + } DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); + + return rel; } /* diff --git a/drivers/rtc/ds1556.c b/drivers/rtc/ds1556.c index 4365cfb..2c496f5 100644 --- a/drivers/rtc/ds1556.c +++ b/drivers/rtc/ds1556.c @@ -69,7 +69,7 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get( struct rtc_time *tmp ) +int rtc_get( struct rtc_time *tmp ) { uchar sec, min, hour; uchar mday, wday, mon, year; @@ -118,6 +118,7 @@ void rtc_get( struct rtc_time *tmp ) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); #endif + return 0; } void rtc_set( struct rtc_time *tmp ) diff --git a/drivers/rtc/ds164x.c b/drivers/rtc/ds164x.c index bff22b9..5943f87 100644 --- a/drivers/rtc/ds164x.c +++ b/drivers/rtc/ds164x.c @@ -70,7 +70,7 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get( struct rtc_time *tmp ) +int rtc_get( struct rtc_time *tmp ) { uchar sec, min, hour; uchar mday, wday, mon, year; @@ -115,6 +115,8 @@ void rtc_get( struct rtc_time *tmp ) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); #endif + + return 0; } void rtc_set( struct rtc_time *tmp ) diff --git a/drivers/rtc/ds174x.c b/drivers/rtc/ds174x.c index 5f85a68..81a9cb3 100644 --- a/drivers/rtc/ds174x.c +++ b/drivers/rtc/ds174x.c @@ -65,7 +65,7 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get( struct rtc_time *tmp ) +int rtc_get( struct rtc_time *tmp ) { uchar sec, min, hour; uchar mday, wday, mon, year; @@ -142,6 +142,8 @@ void rtc_set( struct rtc_time *tmp ) /* unlock clock registers after read */ rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_WRITE )); + + return 0; } void rtc_reset (void) diff --git a/drivers/rtc/ds3231.c b/drivers/rtc/ds3231.c index fe11b86..95cb186 100644 --- a/drivers/rtc/ds3231.c +++ b/drivers/rtc/ds3231.c @@ -86,8 +86,9 @@ static unsigned bcd2bin (uchar c); /* * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon_cent, year, control, status; control = rtc_read (RTC_CTL_REG_ADDR); @@ -109,6 +110,7 @@ void rtc_get (struct rtc_time *tmp) /* clear the OSF flag */ rtc_write (RTC_STAT_REG_ADDR, rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF); + rel = -1; } tmp->tm_sec = bcd2bin (sec & 0x7F); @@ -124,6 +126,8 @@ void rtc_get (struct rtc_time *tmp) DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } diff --git a/drivers/rtc/isl1208.c b/drivers/rtc/isl1208.c index d872802..3d46fd0 100644 --- a/drivers/rtc/isl1208.c +++ b/drivers/rtc/isl1208.c @@ -73,8 +73,9 @@ static unsigned bcd2bin (uchar c); * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon, year, status; status = rtc_read (RTC_STAT_REG_ADDR); @@ -94,6 +95,7 @@ void rtc_get (struct rtc_time *tmp) printf ("### Warning: RTC oscillator has stopped\n"); rtc_write(RTC_STAT_REG_ADDR, rtc_read(RTC_STAT_REG_ADDR) &~ (RTC_STAT_BIT_BAT|RTC_STAT_BIT_RTCF)); + rel = -1; } tmp->tm_sec = bcd2bin (sec & 0x7F); @@ -109,6 +111,8 @@ void rtc_get (struct rtc_time *tmp) DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } /* diff --git a/drivers/rtc/m41t11.c b/drivers/rtc/m41t11.c index 81da33a..fce00d9 100644 --- a/drivers/rtc/m41t11.c +++ b/drivers/rtc/m41t11.c @@ -96,14 +96,16 @@ static unsigned char bin2bcd (unsigned int n) #define M41T11_STORAGE_SZ (64-REG_CNT) -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar data[RTC_REG_CNT]; i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT); if( data[RTC_SEC_ADDR] & 0x80 ){ printf( "m41t11 RTC Clock stopped!!!\n" ); + rel = -1; } tmp->tm_sec = bcd2bin (data[RTC_SEC_ADDR] & 0x7F); tmp->tm_min = bcd2bin (data[RTC_MIN_ADDR] & 0x7F); @@ -120,6 +122,7 @@ void rtc_get (struct rtc_time *tmp) i2c_read(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, ¢, M41T11_YEAR_SIZE); if( !(data[RTC_HOUR_ADDR] & 0x80) ){ printf( "m41t11 RTC: cann't keep track of years without CEB set\n" ); + rel = -1; } if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){ /*century flip store off new year*/ @@ -136,6 +139,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/m41t60.c b/drivers/rtc/m41t60.c index 7c80143..8a32ea0 100644 --- a/drivers/rtc/m41t60.c +++ b/drivers/rtc/m41t60.c @@ -170,12 +170,12 @@ static uchar *rtc_validate(void) return data; } -void rtc_get(struct rtc_time *tmp) +int rtc_get(struct rtc_time *tmp) { uchar const *const data = rtc_validate(); if (!data) - return; + return -1; tmp->tm_sec = bcd2bin(data[RTC_SEC] & 0x7F); tmp->tm_min = bcd2bin(data[RTC_MIN] & 0x7F); @@ -190,6 +190,8 @@ void rtc_get(struct rtc_time *tmp) debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } void rtc_set(struct rtc_time *tmp) diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c index 2bdca3b..cf2a957 100644 --- a/drivers/rtc/m41t62.c +++ b/drivers/rtc/m41t62.c @@ -64,7 +64,7 @@ #define M41T62_FEATURE_HT (1 << 0) #define M41T62_FEATURE_BL (1 << 1) -void rtc_get(struct rtc_time *tm) +int rtc_get(struct rtc_time *tm) { u8 buf[M41T62_DATETIME_REG_SIZE]; @@ -92,6 +92,8 @@ void rtc_get(struct rtc_time *tm) __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + + return 0; } void rtc_set(struct rtc_time *tm) diff --git a/drivers/rtc/m48t35ax.c b/drivers/rtc/m48t35ax.c index 0a0ffa8..be29279 100644 --- a/drivers/rtc/m48t35ax.c +++ b/drivers/rtc/m48t35ax.c @@ -42,7 +42,7 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, cent_day, date, month, year; uchar ccr; /* Clock control register */ @@ -83,6 +83,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/max6900.c b/drivers/rtc/max6900.c index c75a8e0..e9979f2 100644 --- a/drivers/rtc/max6900.c +++ b/drivers/rtc/max6900.c @@ -63,7 +63,7 @@ static unsigned char bin2bcd (unsigned int n) /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, cent, year; int retry = 1; @@ -103,6 +103,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index ab377ed..70f7017 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -57,7 +57,7 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; /* here check if rtc can be accessed */ @@ -101,6 +101,8 @@ void rtc_get (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c index 27386e5..d235d10 100644 --- a/drivers/rtc/mcfrtc.c +++ b/drivers/rtc/mcfrtc.c @@ -39,7 +39,7 @@ #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) #define STARTOFTIME 1970 -void rtc_get(struct rtc_time *tmp) +int rtc_get(struct rtc_time *tmp) { volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE); @@ -64,6 +64,8 @@ void rtc_get(struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif + + return 0; } void rtc_set(struct rtc_time *tmp) diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c index bacdb5b..5981399 100644 --- a/drivers/rtc/mk48t59.c +++ b/drivers/rtc/mk48t59.c @@ -135,7 +135,7 @@ void nvram_write(short dest, const void *src, size_t count) /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { uchar save_ctrl_a; uchar sec, min, hour, mday, wday, mon, year; @@ -183,6 +183,8 @@ void rtc_get (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/mpc5xxx.c b/drivers/rtc/mpc5xxx.c index 216386a..a6555f5 100644 --- a/drivers/rtc/mpc5xxx.c +++ b/drivers/rtc/mpc5xxx.c @@ -55,7 +55,7 @@ typedef struct rtc5200 { /***************************************************************************** * get time *****************************************************************************/ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800); ulong time, date, time2; @@ -81,6 +81,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } /***************************************************************************** diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c index 8d10c0e..057547b 100644 --- a/drivers/rtc/mpc8xx.c +++ b/drivers/rtc/mpc8xx.c @@ -35,7 +35,7 @@ /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { volatile immap_t *immr = (immap_t *)CFG_IMMR; ulong tim; @@ -47,6 +47,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c index 2d73d5d..c384975 100644 --- a/drivers/rtc/pcf8563.c +++ b/drivers/rtc/pcf8563.c @@ -41,8 +41,9 @@ static unsigned bcd2bin(uchar c); /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon_cent, year; sec = rtc_read (0x02); @@ -65,6 +66,7 @@ void rtc_get (struct rtc_time *tmp) if (sec & 0x80) { puts ("### Warning: RTC Low Voltage - date/time not reliable\n"); + rel = -1; } tmp->tm_sec = bcd2bin (sec & 0x7F); @@ -80,6 +82,8 @@ void rtc_get (struct rtc_time *tmp) debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/rs5c372.c b/drivers/rtc/rs5c372.c index 3d1346e..1c9b752 100644 --- a/drivers/rtc/rs5c372.c +++ b/drivers/rtc/rs5c372.c @@ -166,7 +166,7 @@ rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf) /* * Get the current time from the RTC */ -void +int rtc_get (struct rtc_time *tmp) { unsigned char buf[RS5C372_RAM_SIZE]; @@ -176,7 +176,7 @@ rtc_get (struct rtc_time *tmp) rs5c372_enable(); if (!setup_done) - return; + return -1; memset(buf, 0, sizeof(buf)); @@ -184,12 +184,12 @@ rtc_get (struct rtc_time *tmp) ret = rs5c372_readram(buf, RS5C372_RAM_SIZE); if (ret != 0) { printf("%s: failed\n", __FUNCTION__); - return; + return -1; } rs5c372_convert_to_time(tmp, buf); - return; + return 0; } /* diff --git a/drivers/rtc/rx8025.c b/drivers/rtc/rx8025.c index 9122f12..64eafe5 100644 --- a/drivers/rtc/rx8025.c +++ b/drivers/rtc/rx8025.c @@ -96,8 +96,9 @@ static unsigned bcd2bin (uchar c); /* * Get the current time from the RTC */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { + int rel = 0; uchar sec, min, hour, mday, wday, mon, year, ctl2; uchar buf[16]; @@ -118,14 +119,20 @@ void rtc_get (struct rtc_time *tmp) /* dump status */ ctl2 = rtc_read(RTC_CTL2_REG_ADDR); - if (ctl2 & RTC_CTL2_BIT_PON) + if (ctl2 & RTC_CTL2_BIT_PON) { printf("RTC: power-on detected\n"); + rel = -1; + } - if (ctl2 & RTC_CTL2_BIT_VDET) + if (ctl2 & RTC_CTL2_BIT_VDET) { printf("RTC: voltage drop detected\n"); + rel = -1; + } - if (!(ctl2 & RTC_CTL2_BIT_XST)) + if (!(ctl2 & RTC_CTL2_BIT_XST)) { printf("RTC: oscillator stop detected\n"); + rel = -1; + } tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); @@ -140,6 +147,8 @@ void rtc_get (struct rtc_time *tmp) DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + return rel; } /* diff --git a/drivers/rtc/s3c24x0_rtc.c b/drivers/rtc/s3c24x0_rtc.c index 7f8b4fa..358aef7 100644 --- a/drivers/rtc/s3c24x0_rtc.c +++ b/drivers/rtc/s3c24x0_rtc.c @@ -70,7 +70,7 @@ static unsigned char bin2bcd (unsigned int n) /* ------------------------------------------------------------------------- */ -void rtc_get (struct rtc_time *tmp) +int rtc_get (struct rtc_time *tmp) { S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC(); uchar sec, min, hour, mday, wday, mon, year; @@ -131,6 +131,8 @@ void rtc_get (struct rtc_time *tmp) tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif + + return 0; } void rtc_set (struct rtc_time *tmp) diff --git a/drivers/rtc/x1205.c b/drivers/rtc/x1205.c index 319f051..0e18139 100644 --- a/drivers/rtc/x1205.c +++ b/drivers/rtc/x1205.c @@ -104,7 +104,7 @@ static void rtc_write(int reg, u8 val) * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch * Epoch is initialized as 2000. Time is set to UTC. */ -void rtc_get(struct rtc_time *tm) +int rtc_get(struct rtc_time *tm) { u8 buf[8]; @@ -130,6 +130,8 @@ void rtc_get(struct rtc_time *tm) __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + + return 0; } void rtc_set(struct rtc_time *tm) 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/include/rtc.h b/include/rtc.h index 15f3571..2995144 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -52,7 +52,7 @@ struct rtc_time { int tm_isdst; }; -void rtc_get (struct rtc_time *); +int rtc_get (struct rtc_time *); void rtc_set (struct rtc_time *); void rtc_reset (void); 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/dspic.c b/post/board/lwmon5/dspic.c index 65b96bc..dbaa074 100644 --- a/post/board/lwmon5/dspic.c +++ b/post/board/lwmon5/dspic.c @@ -97,8 +97,9 @@ int dspic_post_test(int flags) if (data == -1) { post_log("dsPIC : failed read system error\n"); ret = 1; - } else { + } else if (data != 0) { post_log("dsPIC SYS-ERROR code: 0x%04X\n", data); + ret = 1; } return ret; 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 */ diff --git a/post/drivers/rtc.c b/post/drivers/rtc.c index 7d4f9b8..e3da5e6 100644 --- a/post/drivers/rtc.c +++ b/post/drivers/rtc.c @@ -28,6 +28,8 @@ * * The Real Time Clock (RTC) operation is verified by this test. * The following features are verified: + * o) RTC Power Fault + * This is verified by analyzing the rtc_get() return status. * o) Time uniformity * This is verified by reading RTC in polling within * a short period of time. @@ -96,6 +98,10 @@ int rtc_post_test (int flags) unsigned int ynl = 1999; unsigned int yl = 2000; unsigned int skipped = 0; + int reliable; + + /* Time reliability */ + reliable = rtc_get (&svtm); /* Time uniformity */ if (rtc_post_skip (&diff) != 0) { @@ -176,6 +182,15 @@ int rtc_post_test (int flags) } rtc_post_restore (&svtm, skipped); + /* If come here, then RTC operates correcty, check the correctness + * of the time it reports. + */ + if (reliable < 0) { + post_log ("RTC Time is not reliable! Power fault? \n"); + + return -1; + } + return 0; } |