From 46d1d5dd43e4d7c78f1fd6a5ee958d7b8a8626eb Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sat, 5 Jan 2013 09:45:48 +0000 Subject: common/lcd.c: cleanup use of global variables lcd_color_fg and lcd_color_bg had to be declared in board specific code, but were not actually used there; in addition, we have getter / setter functions for these, which were not used either. Get rid of the global variables, and use the getter function where needed (so far no setter calls are needed). Signed-off-by: Wolfgang Denk Cc: Alessandro Rubini Cc: Anatolij Gustschin Cc: Bo Shen Cc: Haavard Skinnemoen Cc: Kyungmin Park Cc: Marek Vasut Cc: Minkyu Kang Cc: Nikita Kiryanov Cc: Simon Glass Cc: Stelian Pop Cc: Tom Warren Acked-by: Simon Glass Acked-by: Jeroen Hofstee [agust: also fixed cm_t35 board while rebasing] Signed-off-by: Anatolij Gustschin --- common/lcd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index 590bbb9..b09e45f 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -99,6 +99,9 @@ static int lcd_getbgcolor(void); static void lcd_setfgcolor(int color); static void lcd_setbgcolor(int color); +static int lcd_color_fg; +static int lcd_color_bg; + char lcd_is_enabled = 0; static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ @@ -534,12 +537,10 @@ static void lcd_setbgcolor(int color) /*----------------------------------------------------------------------*/ -#ifdef NOT_USED_SO_FAR -static int lcd_getfgcolor(void) +int lcd_getfgcolor(void) { return lcd_color_fg; } -#endif /* NOT_USED_SO_FAR */ /*----------------------------------------------------------------------*/ -- cgit v1.1 From f1d205a19cc89ae5a840cd45115201847dd5b73a Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Tue, 22 Jan 2013 10:44:11 +0000 Subject: common/lcd.c: cleanup use of global variables console_col, console_row, lcd_line_length, lcd_console_address had to be declared in board / driver specific code, but were not actually used there on many boards. Get rid of the global variables. for completeness, the ack of Bo Shen is for the atmel part Cc: Alessandro Rubini Cc: Anatolij Gustschin Cc: Bo Shen Cc: Kyungmin Park Cc: Marek Vasut Cc: Minkyu Kang Cc: Nikita Kiryanov Cc: Simon Glass Cc: Stelian Pop Cc: Tom Warren Acked-by: Bo Shen Signed-off-by: Jeroen Hofstee [agust: rebased and fixed cm_t35 board] Signed-off-by: Anatolij Gustschin --- common/lcd.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index b09e45f..874f182 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -101,9 +101,15 @@ static void lcd_setbgcolor(int color); static int lcd_color_fg; static int lcd_color_bg; +int lcd_line_length; char lcd_is_enabled = 0; +static short console_col; +static short console_row; + +static void *lcd_console_address; + static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ -- cgit v1.1 From 00a0ca5986c13d24ebbc5000cc1b7a1cdac0ba4b Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Tue, 22 Jan 2013 10:44:12 +0000 Subject: common/lcd.c: remove global lcd_base lcd_base is available as gd->fb_base as well, there is no need to keep a seperate copy. For completeness the ack of Bo Shen is for the atmel part. Cc: Alessandro Rubini Cc: Anatolij Gustschin Cc: Bo Shen Cc: Haavard Skinnemoen Cc: Kyungmin Park Cc: Marek Vasut Cc: Minkyu Kang Cc: Nikita Kiryanov Cc: Simon Glass Cc: Stelian Pop Cc: Tom Warren Acked-by: Bo Shen Signed-off-by: Jeroen Hofstee [agust: also fix cm_t35 board while rebasing] Signed-off-by: Anatolij Gustschin --- common/lcd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index 874f182..eceb8ad 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -109,6 +109,7 @@ static short console_col; static short console_row; static void *lcd_console_address; +static void *lcd_base; /* Start of framebuffer memory */ static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ -- cgit v1.1 From 6b035141f6459df01065f455cbf9c1928f2db16a Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sat, 12 Jan 2013 12:07:56 +0000 Subject: common/lcd: cosmetic: clean up a bit - Make the brackets of the function calls more consistent - Remove really unnecessary brackets - Removes the extern from the function definitions - Remove curly brackets from single line statements - Remove lcd_setmem proto since it is already in common.h - Cleanup comments, remove useless comments - Remove NOT_USED_SO_FAR ifdef - Cleanup coding style cc: Anatolij Gustschin Signed-off-by: Jeroen Hofstee [agust: rebased the original patch] Signed-off-by: Anatolij Gustschin --- common/lcd.c | 84 +++++++++++++++++++++++------------------------------------- 1 file changed, 32 insertions(+), 52 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index eceb8ad..bd7155f 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -85,15 +85,13 @@ DECLARE_GLOBAL_DATA_PTR; -ulong lcd_setmem (ulong addr); - static void lcd_drawchars(ushort x, ushort y, uchar *str, int count); static inline void lcd_puts_xy(ushort x, ushort y, uchar *s); static inline void lcd_putc_xy(ushort x, ushort y, uchar c); static int lcd_init(void *lcdbase); -static void *lcd_logo (void); +static void *lcd_logo(void); static int lcd_getbgcolor(void); static void lcd_setfgcolor(int color); @@ -113,13 +111,6 @@ static void *lcd_base; /* Start of framebuffer memory */ static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ - -#ifdef NOT_USED_SO_FAR -static void lcd_getcolreg(ushort regno, - ushort *red, ushort *green, ushort *blue); -static int lcd_getfgcolor(void); -#endif /* NOT_USED_SO_FAR */ - /************************************************************************/ /* Flush LCD activity to the caches */ @@ -158,7 +149,7 @@ static void console_scrollup(void) /* Clear the last rows */ memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, COLOR_MASK(lcd_color_bg), - CONSOLE_ROW_SIZE * rows); + CONSOLE_ROW_SIZE * rows); lcd_sync(); console_row -= rows; @@ -170,9 +161,8 @@ static inline void console_back(void) { if (--console_col < 0) { console_col = CONSOLE_COLS-1 ; - if (--console_row < 0) { + if (--console_row < 0) console_row = 0; - } } lcd_putc_xy(console_col * VIDEO_FONT_WIDTH, @@ -183,16 +173,13 @@ static inline void console_back(void) static inline void console_newline(void) { - ++console_row; console_col = 0; /* Check if we need to scroll the terminal */ - if (console_row >= CONSOLE_ROWS) { - /* Scroll everything up */ + if (++console_row >= CONSOLE_ROWS) console_scrollup(); - } else { + else lcd_sync(); - } } /*----------------------------------------------------------------------*/ @@ -244,9 +231,9 @@ void lcd_puts(const char *s) return; } - while (*s) { + while (*s) lcd_putc(*s++); - } + lcd_sync(); } @@ -293,7 +280,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) #endif #if LCD_BPP == LCD_MONOCHROME - uchar rest = *d & -(1 << (8-off)); + uchar rest = *d & -(1 << (8 - off)); uchar sym; #endif for (i = 0; i < count; ++i) { @@ -323,7 +310,7 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) #endif } #if LCD_BPP == LCD_MONOCHROME - *d = rest | (*d & ((1 << (8-off)) - 1)); + *d = rest | (*d & ((1 << (8 - off)) - 1)); #endif } } @@ -350,7 +337,7 @@ static inline void lcd_putc_xy(ushort x, ushort y, uchar c) #define N_BLK_VERT 2 #define N_BLK_HOR 3 -static int test_colors[N_BLK_HOR*N_BLK_VERT] = { +static int test_colors[N_BLK_HOR * N_BLK_VERT] = { CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN, }; @@ -371,7 +358,7 @@ static void test_pattern(void) for (v = 0; v < v_max; ++v) { uchar iy = v / v_step; for (h = 0; h < h_max; ++h) { - uchar ix = N_BLK_HOR * iy + (h/h_step); + uchar ix = N_BLK_HOR * iy + h / h_step; *pix++ = test_colors[ix]; } } @@ -389,12 +376,12 @@ int lcd_get_size(int *line_length) return *line_length * panel_info.vl_row; } -int drv_lcd_init (void) +int drv_lcd_init(void) { struct stdio_dev lcddev; int rc; - lcd_base = (void *)(gd->fb_base); + lcd_base = (void *) gd->fb_base; lcd_get_size(&lcd_line_length); @@ -409,7 +396,7 @@ int drv_lcd_init (void) lcddev.putc = lcd_putc; /* 'putc' function */ lcddev.puts = lcd_puts; /* 'puts' function */ - rc = stdio_register (&lcddev); + rc = stdio_register(&lcddev); return (rc == 0) ? 1 : rc; } @@ -448,11 +435,11 @@ void lcd_clear(void) /* set framebuffer to background color */ memset((char *)lcd_base, COLOR_MASK(lcd_getbgcolor()), - lcd_line_length*panel_info.vl_row); + lcd_line_length * panel_info.vl_row); #endif /* Paint the logo and retrieve LCD base address */ debug("[LCD] Drawing the logo...\n"); - lcd_console_address = lcd_logo (); + lcd_console_address = lcd_logo(); console_col = 0; console_row = 0; @@ -482,7 +469,7 @@ static int lcd_init(void *lcdbase) lcd_ctrl_init(lcdbase); lcd_is_enabled = 1; lcd_clear(); - lcd_enable (); + lcd_enable(); /* Initialize the console */ console_col = 0; @@ -523,7 +510,8 @@ ulong lcd_setmem(ulong addr) /* Allocate pages for the frame buffer. */ addr -= size; - debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr); + debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", + size >> 10, addr); return addr; } @@ -556,8 +544,6 @@ static int lcd_getbgcolor(void) return lcd_color_bg; } -/*----------------------------------------------------------------------*/ - /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ @@ -574,13 +560,11 @@ static inline ushort *configuration_get_cmap(void) return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); #elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) return panel_info.cmap; -#else -#if defined(CONFIG_LCD_LOGO) +#elif defined(CONFIG_LCD_LOGO) return bmp_logo_palette; #else return NULL; #endif -#endif } #ifdef CONFIG_LCD_LOGO @@ -653,7 +637,7 @@ void bitmap_plot(int x, int y) for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { memcpy(fb, bmap, BMP_LOGO_WIDTH); bmap += BMP_LOGO_WIDTH; - fb += panel_info.vl_col; + fb += panel_info.vl_col; } } else { /* true color mode */ @@ -744,12 +728,11 @@ static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) *fb++ = c; cnt--; } - (*fbp) = fb; + *fbp = fb; } /* - * Do not call this function directly, must be called from - * lcd_display_bitmap. + * Do not call this function directly, must be called from lcd_display_bitmap. */ static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, int x_off, int y_off) @@ -876,8 +859,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; - if (!bmp || !((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { + if (!bmp || !(bmp->header.signature[0] == 'B' && + bmp->header.signature[1] == 'M')) { printf("Error: no valid bmp image at %lx\n", bmp_image); return 1; @@ -890,7 +873,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) bpix = NBITS(panel_info.vl_bpix); - if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 32)) { + if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) { printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", bpix, bmp_bpix); @@ -958,7 +941,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif - padded_width = (width&0x3) ? ((width&~0x3)+4) : (width); + padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width); #ifdef CONFIG_SPLASH_SCREEN_ALIGN splash_align_axis(&x, pwidth, width); @@ -970,7 +953,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) if ((y + height) > panel_info.vl_row) height = panel_info.vl_row - y; - bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset); + bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset); fb = (uchar *) (lcd_base + (y + height - 1) * lcd_line_length + x * bpix / 8); @@ -1005,7 +988,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } } bmap += (padded_width - width); - fb -= (byte_width + lcd_line_length); + fb -= byte_width + lcd_line_length; } break; @@ -1017,7 +1000,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) fb_put_word(&fb, &bmap); bmap += (padded_width - width) * 2; - fb -= (width * 2 + lcd_line_length); + fb -= width * 2 + lcd_line_length; } break; #endif /* CONFIG_BMP_16BPP */ @@ -1031,7 +1014,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) *(fb++) = *(bmap++); *(fb++) = *(bmap++); } - fb -= (lcd_line_length + width * (bpix / 8)); + fb -= lcd_line_length + width * (bpix / 8); } break; #endif /* CONFIG_BMP_32BPP */ @@ -1106,7 +1089,7 @@ static void *lcd_logo(void) return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length); #else return (void *)lcd_base; -#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */ +#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */ } #ifdef CONFIG_SPLASHIMAGE_GUARD @@ -1158,6 +1141,3 @@ int lcd_get_screen_columns(void) { return CONSOLE_COLS; } - -/************************************************************************/ -/************************************************************************/ -- cgit v1.1 From a5796c51ce87870cde39c0b9cd29ac775d0fb514 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Sat, 12 Jan 2013 12:07:59 +0000 Subject: common/lcd.c: move the macro's to the c file Hide the console macros since some reference global data which is no longer present. cc: Anatolij Gustschin Signed-off-by: Jeroen Hofstee --- common/lcd.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index bd7155f..92debaf 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -83,6 +83,34 @@ #define CONFIG_CONSOLE_SCROLL_LINES 1 #endif +/************************************************************************/ +/* ** CONSOLE DEFINITIONS & FUNCTIONS */ +/************************************************************************/ +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) +# define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \ + / VIDEO_FONT_HEIGHT) +#else +# define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT) +#endif + +#define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH) +#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length) +#define CONSOLE_ROW_FIRST lcd_console_address +#define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE) +#define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \ + - CONSOLE_ROW_SIZE) +#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) +#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) + +#if LCD_BPP == LCD_MONOCHROME +# define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \ + (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7) +#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) +# define COLOR_MASK(c) (c) +#else +# error Unsupported LCD BPP. +#endif + DECLARE_GLOBAL_DATA_PTR; static void lcd_drawchars(ushort x, ushort y, uchar *str, int count); -- cgit v1.1 From 317461c1db97abef243964ae4c7cc7d3485ec73f Mon Sep 17 00:00:00 2001 From: Andre Renaud Date: Wed, 13 Feb 2013 17:48:00 +0000 Subject: Fix bitmap offsets for non 8-bit LCDs Currently bitmap logos don't interpret the X coordinate correctly if the bpp is anything other than 8. Signed-off-by: Andre Renaud --- common/lcd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index 92debaf..195f1de 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -611,15 +611,16 @@ void bitmap_plot(int x, int y) immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; cpm8xx_t *cp = &(immr->im_cpm); #endif + unsigned bpix = NBITS(panel_info.vl_bpix); debug("Logo: width %d height %d colors %d cmap %d\n", BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS, ARRAY_SIZE(bmp_logo_palette)); bmap = &bmp_logo_bitmap[0]; - fb = (uchar *)(lcd_base + y * lcd_line_length + x); + fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); - if (NBITS(panel_info.vl_bpix) < 12) { + if (bpix < 12) { /* Leave room for default color map * default case: generic system with no cmap (most likely 16bpp) * cmap was set to the source palette, so no change is done. @@ -670,7 +671,7 @@ void bitmap_plot(int x, int y) } else { /* true color mode */ u16 col16; - fb16 = (ushort *)(lcd_base + y * lcd_line_length + x); + fb16 = (ushort *)fb; for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { for (j = 0; j < BMP_LOGO_WIDTH; j++) { col16 = bmp_logo_palette[(bmap[j]-16)]; -- cgit v1.1 From fc9d64ffcd94c1e22675830eae13956cc4fd822d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 23 Mar 2013 14:50:40 +0000 Subject: menu: Add support for user defined item choice function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Selecting menu items is currently done in menu_interactive_choice() by reading the user input strings from standard input. Extend menu_interactive_choice() to support user defined function for selecting menu items. This function and its argument can be specified when creating the menu. Signed-off-by: Pali Rohár Signed-off-by: Anatolij Gustschin --- common/cmd_pxe.c | 3 ++- common/menu.c | 42 +++++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'common') diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index ee75db9..2dbd49c 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) /* * Create a menu and add items for all the labels. */ - m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print); + m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print, + NULL, NULL); if (!m) return NULL; diff --git a/common/menu.c b/common/menu.c index 6b2a2db..322b75e 100644 --- a/common/menu.c +++ b/common/menu.c @@ -47,6 +47,8 @@ struct menu { char *title; int prompt; void (*item_data_print)(void *); + char *(*item_choice)(void *); + void *item_choice_data; struct list_head items; }; @@ -204,18 +206,26 @@ static inline int menu_interactive_choice(struct menu *m, void **choice) menu_display(m); - readret = readline_into_buffer("Enter choice: ", cbuf, - m->timeout / 10); + if (!m->item_choice) { + readret = readline_into_buffer("Enter choice: ", cbuf, + m->timeout / 10); - if (readret >= 0) { - choice_item = menu_item_by_key(m, cbuf); - - if (!choice_item) { - printf("%s not found\n", cbuf); - m->timeout = 0; + if (readret >= 0) { + choice_item = menu_item_by_key(m, cbuf); + if (!choice_item) + printf("%s not found\n", cbuf); + } else { + return menu_default_choice(m, choice); } - } else - return menu_default_choice(m, choice); + } else { + char *key = m->item_choice(m->item_choice_data); + + if (key) + choice_item = menu_item_by_key(m, key); + } + + if (!choice_item) + m->timeout = 0; } *choice = choice_item->data; @@ -348,11 +358,19 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data) * what must be entered to select an item, the item_data_print function should * make it obvious what the key for each entry is. * + * item_choice - If not NULL, will be called when asking the user to choose an + * item. Returns a key string corresponding to the choosen item or NULL if + * no item has been selected. + * + * item_choice_data - Will be passed as the argument to the item_choice function + * * Returns a pointer to the menu if successful, or NULL if there is * insufficient memory available to create the menu. */ struct menu *menu_create(char *title, int timeout, int prompt, - void (*item_data_print)(void *)) + void (*item_data_print)(void *), + char *(*item_choice)(void *), + void *item_choice_data) { struct menu *m; @@ -365,6 +383,8 @@ struct menu *menu_create(char *title, int timeout, int prompt, m->prompt = prompt; m->timeout = timeout; m->item_data_print = item_data_print; + m->item_choice = item_choice; + m->item_choice_data = item_choice_data; if (title) { m->title = strdup(title); -- cgit v1.1 From 6a3439fdadb7b98e72883b90eb717a04cd748e44 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 23 Mar 2013 14:52:04 +0000 Subject: menu: export menu_default_choice() function Checking the default menu item and obtaining its data can be useful in custom menu code. Export menu_default_choice() function which serves this purpose. Signed-off-by: Anatolij Gustschin --- common/menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/menu.c b/common/menu.c index 322b75e..64b461a 100644 --- a/common/menu.c +++ b/common/menu.c @@ -176,7 +176,7 @@ static inline struct menu_item *menu_item_by_key(struct menu *m, * Set *choice to point to the default item's data, if any default item was * set, and returns 1. If no default item was set, returns -ENOENT. */ -static inline int menu_default_choice(struct menu *m, void **choice) +int menu_default_choice(struct menu *m, void **choice) { if (m->default_item) { *choice = m->default_item->data; -- cgit v1.1 From e7abe919673994e8040aba0273ceb9a5b2609806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 23 Mar 2013 14:53:08 +0000 Subject: New command bootmenu: ANSI terminal boot menu support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "bootmenu" command uses U-Boot menu interfaces and provides a simple mechanism for creating menus with several boot items. When running this command the menu will be assembled as defined by a set of environment variables which contain a title and command key-value pairs. The "Up" and "Down" keys are used for navigation through the items. Current active menu item is highlighted and can be selected using the "Enter" key. The command interprets and generates various ANSI escape sequencies, so for proper menu rendering and item selection the used terminal should support them. Signed-off-by: Pali Rohár [agust: various fixes and documentation updates] Signed-off-by: Anatolij Gustschin --- common/Makefile | 1 + common/cmd_bootmenu.c | 517 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 518 insertions(+) create mode 100644 common/cmd_bootmenu.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index 1abf4ea..f631311 100644 --- a/common/Makefile +++ b/common/Makefile @@ -75,6 +75,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o +COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o diff --git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c new file mode 100644 index 0000000..a3cbffa --- /dev/null +++ b/common/cmd_bootmenu.c @@ -0,0 +1,517 @@ +/* + * (C) Copyright 2011-2013 Pali Rohár + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +/* maximum bootmenu entries */ +#define MAX_COUNT 99 + +/* maximal size of bootmenu env + * 9 = strlen("bootmenu_") + * 2 = strlen(MAX_COUNT) + * 1 = NULL term + */ +#define MAX_ENV_SIZE (9 + 2 + 1) + +struct bootmenu_entry { + unsigned short int num; /* unique number 0 .. MAX_COUNT */ + char key[3]; /* key identifier of number */ + char *title; /* title of entry */ + char *command; /* hush command of entry */ + struct bootmenu_data *menu; /* this bootmenu */ + struct bootmenu_entry *next; /* next menu entry (num+1) */ +}; + +struct bootmenu_data { + int delay; /* delay for autoboot */ + int active; /* active menu entry */ + int count; /* total count of menu entries */ + struct bootmenu_entry *first; /* first menu entry */ +}; + +enum bootmenu_key { + KEY_NONE = 0, + KEY_UP, + KEY_DOWN, + KEY_SELECT, +}; + +static char *bootmenu_getoption(unsigned short int n) +{ + char name[MAX_ENV_SIZE] = "bootmenu_"; + + if (n > MAX_COUNT) + return NULL; + + sprintf(name + 9, "%d", n); + return getenv(name); +} + +static void bootmenu_print_entry(void *data) +{ + struct bootmenu_entry *entry = data; + int reverse = (entry->menu->active == entry->num); + + /* + * Move cursor to line where the entry will be drown (entry->num) + * First 3 lines contain bootmenu header + 1 empty line + */ + printf(ANSI_CURSOR_POSITION, entry->num + 4, 1); + + puts(" "); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + puts(entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +static void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int i, c; + + if (menu->delay > 0) { + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + printf(" Hit any key to stop autoboot: %2d ", menu->delay); + } + + while (menu->delay > 0) { + for (i = 0; i < 100; ++i) { + if (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + continue; + } + + menu->delay = -1; + c = getc(); + + switch (c) { + case '\e': + *esc = 1; + *key = KEY_NONE; + break; + case '\r': + *key = KEY_SELECT; + break; + default: + *key = KEY_NONE; + break; + } + + break; + } + + if (menu->delay < 0) + break; + + --menu->delay; + printf("\b\b\b%2d ", menu->delay); + } + + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + + if (menu->delay == 0) + *key = KEY_SELECT; +} + +static void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int c; + + while (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + } + + c = getc(); + + switch (*esc) { + case 0: + /* First char of ANSI escape sequence '\e' */ + if (c == '\e') { + *esc = 1; + *key = KEY_NONE; + } + break; + case 1: + /* Second char of ANSI '[' */ + if (c == '[') { + *esc = 2; + *key = KEY_NONE; + } else { + *esc = 0; + } + break; + case 2: + case 3: + /* Third char of ANSI (number '1') - optional */ + if (*esc == 2 && c == '1') { + *esc = 3; + *key = KEY_NONE; + break; + } + + *esc = 0; + + /* ANSI 'A' - key up was pressed */ + if (c == 'A') + *key = KEY_UP; + /* ANSI 'B' - key down was pressed */ + else if (c == 'B') + *key = KEY_DOWN; + /* other key was pressed */ + else + *key = KEY_NONE; + + break; + } + + /* enter key was pressed */ + if (c == '\r') + *key = KEY_SELECT; +} + +static char *bootmenu_choice_entry(void *data) +{ + struct bootmenu_data *menu = data; + struct bootmenu_entry *iter; + enum bootmenu_key key = KEY_NONE; + int esc = 0; + int i; + + while (1) { + if (menu->delay >= 0) { + /* Autoboot was not stopped */ + bootmenu_autoboot_loop(menu, &key, &esc); + } else { + /* Some key was pressed, so autoboot was stopped */ + bootmenu_loop(menu, &key, &esc); + } + + switch (key) { + case KEY_UP: + if (menu->active > 0) + --menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (menu->active < menu->count - 1) + ++menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + iter = menu->first; + for (i = 0; i < menu->active; ++i) + iter = iter->next; + return iter->key; + default: + break; + } + } + + /* never happens */ + debug("bootmenu: this should not happen"); + return NULL; +} + +static void bootmenu_destroy(struct bootmenu_data *menu) +{ + struct bootmenu_entry *iter = menu->first; + struct bootmenu_entry *next; + + while (iter) { + next = iter->next; + free(iter->title); + free(iter->command); + free(iter); + iter = next; + } + free(menu); +} + +static struct bootmenu_data *bootmenu_create(int delay) +{ + unsigned short int i = 0; + const char *option; + struct bootmenu_data *menu; + struct bootmenu_entry *iter = NULL; + + int len; + char *sep; + struct bootmenu_entry *entry; + + menu = malloc(sizeof(struct bootmenu_data)); + if (!menu) + return NULL; + + menu->delay = delay; + menu->active = 0; + menu->first = NULL; + + while ((option = bootmenu_getoption(i))) { + sep = strchr(option, '='); + if (!sep) { + printf("Invalid bootmenu entry: %s\n", option); + break; + } + + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + len = sep-option; + entry->title = malloc(len + 1); + if (!entry->title) { + free(entry); + goto cleanup; + } + memcpy(entry->title, option, len); + entry->title[len] = 0; + + len = strlen(sep + 1); + entry->command = malloc(len + 1); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + memcpy(entry->command, sep + 1, len); + entry->command[len] = 0; + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; + + if (i == MAX_COUNT - 1) + break; + } + + /* Add U-Boot console entry at the end */ + if (i <= MAX_COUNT - 1) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + entry->title = strdup("U-Boot console"); + if (!entry->title) { + free(entry); + goto cleanup; + } + + entry->command = strdup(""); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; + } + + menu->count = i; + return menu; + +cleanup: + bootmenu_destroy(menu); + return NULL; +} + +static void bootmenu_show(int delay) +{ + int init = 0; + void *choice = NULL; + char *title = NULL; + char *command = NULL; + struct menu *menu; + struct bootmenu_data *bootmenu; + struct bootmenu_entry *iter; + char *option, *sep; + + /* If delay is 0 do not create menu, just run first entry */ + if (delay == 0) { + option = bootmenu_getoption(0); + if (!option) { + puts("bootmenu option 0 was not found\n"); + return; + } + sep = strchr(option, '='); + if (!sep) { + puts("bootmenu option 0 is invalid\n"); + return; + } + run_command(sep+1, 0); + return; + } + + bootmenu = bootmenu_create(delay); + if (!bootmenu) + return; + + menu = menu_create(NULL, bootmenu->delay, 1, bootmenu_print_entry, + bootmenu_choice_entry, bootmenu); + if (!menu) { + bootmenu_destroy(bootmenu); + return; + } + + for (iter = bootmenu->first; iter; iter = iter->next) { + if (!menu_item_add(menu, iter->key, iter)) + goto cleanup; + } + + /* Default menu entry is always first */ + menu_default_set(menu, "0"); + + puts(ANSI_CURSOR_HIDE); + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + + init = 1; + + if (menu_get_choice(menu, &choice)) { + iter = choice; + title = strdup(iter->title); + command = strdup(iter->command); + } + +cleanup: + menu_destroy(menu); + bootmenu_destroy(bootmenu); + + if (init) { + puts(ANSI_CURSOR_SHOW); + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + } + + if (title && command) { + debug("Starting entry '%s'\n", title); + free(title); + run_command(command, 0); + free(command); + } + +#ifdef CONFIG_POSTBOOTMENU + run_command(CONFIG_POSTBOOTMENU, 0); +#endif +} + +void menu_display_statusline(struct menu *m) +{ + struct bootmenu_entry *entry; + struct bootmenu_data *menu; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + menu = entry->menu; + + printf(ANSI_CURSOR_POSITION, 1, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot Boot Menu ***"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, 3, 1); + puts(ANSI_CLEAR_LINE); + + /* First 3 lines are bootmenu header + 2 empty lines between entries */ + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, menu->count + 6, 1); + puts(" Press UP/DOWN to move, ENTER to select"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, menu->count + 7, 1); + puts(ANSI_CLEAR_LINE); +} + +#ifdef CONFIG_MENU_SHOW +int menu_show(int bootdelay) +{ + bootmenu_show(bootdelay); + return -1; /* -1 - abort boot and run monitor code */ +} +#endif + +int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + char *delay_str = NULL; + int delay = 10; + +#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) + delay = CONFIG_BOOTDELAY; +#endif + + if (argc >= 2) + delay_str = argv[1]; + + if (!delay_str) + delay_str = getenv("bootmenu_delay"); + + if (delay_str) + delay = (int)simple_strtol(delay_str, NULL, 10); + + bootmenu_show(delay); + return 0; +} + +U_BOOT_CMD( + bootmenu, 2, 1, do_bootmenu, + "ANSI terminal bootmenu", + "[delay]\n" + " - show ANSI terminal bootmenu with autoboot delay" +); -- cgit v1.1 From 1d3dea12e21275eab5af1b50ef4a3be89cfffc15 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 29 Mar 2013 14:00:13 +0100 Subject: video: bcm2835: fix build issues After merging LCD patches for v2013.04 the bcm2835 video driver building is broken due to removal of many global variables. Fix the driver. Signed-off-by: Anatolij Gustschin Cc: Stephen Warren --- common/lcd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index b98eea6..edae835 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -493,6 +493,18 @@ static int lcd_init(void *lcdbase) debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); lcd_ctrl_init(lcdbase); + + /* + * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores + * the 'lcdbase' argument and uses custom lcd base address + * by setting up gd->fb_base. Check for this condition and fixup + * 'lcd_base' address. + */ + if ((unsigned long)lcdbase != gd->fb_base) + lcd_base = (void *)gd->fb_base; + + debug("[LCD] Using LCD frambuffer at %p\n", lcd_base); + lcd_get_size(&lcd_line_length); lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; lcd_is_enabled = 1; -- cgit v1.1 From 472d546054dadacca91530bad42ad06f6408124e Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 1 Apr 2013 11:29:11 -0700 Subject: Consolidate bool type 'bool' is defined in random places. This patch consolidates them into a single header file include/linux/types.h, using stdbool.h introduced in C99. All other #define, typedef and enum are removed. They are all consistent with true = 1, false = 0. Replace FALSE, False with false. Replace TRUE, True with true. Skip *.py, *.php, lib/* files. Signed-off-by: York Sun --- common/bedbug.c | 75 ++++++++++++++++----------------- common/cmd_bedbug.c | 4 +- common/cmd_fdc.c | 117 +++++++++++++++++++++++++--------------------------- common/cmd_scsi.c | 18 ++++---- common/dlmalloc.c | 2 +- common/dlmalloc.src | 2 +- 6 files changed, 107 insertions(+), 111 deletions(-) (limited to 'common') diff --git a/common/bedbug.c b/common/bedbug.c index 60109cf..42ecf61 100644 --- a/common/bedbug.c +++ b/common/bedbug.c @@ -72,7 +72,7 @@ int downstring __P ((char *)); * F_INSTR - output raw instruction. * F_LINENO - show line # info if available. * - * Returns TRUE if the area was successfully disassembled or FALSE if + * Returns true if the area was successfully disassembled or false if * a problem was encountered with accessing the memory. */ @@ -137,8 +137,8 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) { #ifdef USE_SOURCE_CODE if (ctx.flags & F_LINENO) { - if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename, - funcname, &line_no) == TRUE) && + if ((line_info_from_addr ((Elf32_Word) ctx.virtual, + filename, funcname, &line_no) == true) && ((line_no != last_line_no) || (strcmp (last_funcname, funcname) != 0))) { print_source_line (filename, funcname, line_no, pfunc); @@ -154,15 +154,15 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, #ifdef USE_SOURCE_CODE if (ctx.flags & F_SYMBOL) { if ((symname = - symbol_name_from_addr ((Elf32_Word) ctx.virtual, - TRUE, 0)) != 0) { + symbol_name_from_addr((Elf32_Word) ctx.virtual, + true, 0)) != 0) { cursym = symname; symoffset = 0; } else { if ((cursym == 0) && ((symname = - symbol_name_from_addr ((Elf32_Word) ctx.virtual, - FALSE, &symoffset)) != 0)) { + symbol_name_from_addr((Elf32_Word) ctx.virtual, + false, &symoffset)) != 0)) { cursym = symname; } else { symoffset += 4; @@ -205,7 +205,8 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, } if (((ctx.flags & F_SIMPLE) == 0) || - (ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) { + (ctx.op->hfunc == 0) || + ((*ctx.op->hfunc) (&ctx) == false)) { sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name); ctx.datalen += 8; print_operands (&ctx); @@ -214,7 +215,7 @@ int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, (*pfunc) (ctx.data); } - return TRUE; + return true; } /* disppc */ @@ -364,10 +365,10 @@ int print_operands (struct ppc_ctx *ctx) * value The address of an unsigned long to be filled in * with the value of the operand if it is found. This * will only be filled in if the function returns - * TRUE. This may be passed as 0 if the value is + * true. This may be passed as 0 if the value is * not required. * - * Returns TRUE if the operand was found or FALSE if it was not. + * Returns true if the operand was found or false if it was not. */ int get_operand_value (struct opcode *op, unsigned long instr, @@ -379,7 +380,7 @@ int get_operand_value (struct opcode *op, unsigned long instr, /*------------------------------------------------------------*/ if (field > n_operands) { - return FALSE; /* bad operand ?! */ + return false; /* bad operand ?! */ } /* Walk through the operands and list each in order */ @@ -393,10 +394,10 @@ int get_operand_value (struct opcode *op, unsigned long instr, if (value) { *value = (instr >> opr->shift) & ((1 << opr->bits) - 1); } - return TRUE; + return true; } - return FALSE; + return false; } /* operand_value */ @@ -649,7 +650,7 @@ int tbr_value (char *name) * Arguments: * ctx A pointer to the disassembler context record. * - * Returns TRUE if the simpler form was printed or FALSE if it was not. + * Returns true if the simpler form was printed or false if it was not. */ int handle_bc (struct ppc_ctx *ctx) @@ -669,33 +670,33 @@ int handle_bc (struct ppc_ctx *ctx) /*------------------------------------------------------------*/ - if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE) - return FALSE; + if (get_operand_value(ctx->op, ctx->instr, O_BO, &bo) == false) + return false; - if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE) - return FALSE; + if (get_operand_value(ctx->op, ctx->instr, O_BI, &bi) == false) + return false; if ((bo == 12) && (bi == 0)) { ctx->op = &blt; sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); ctx->datalen += 8; print_operands (ctx); - return TRUE; + return true; } else if ((bo == 4) && (bi == 10)) { ctx->op = =⃥ sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); ctx->datalen += 8; print_operands (ctx); - return TRUE; + return true; } else if ((bo == 16) && (bi == 0)) { ctx->op = &bdnz; sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); ctx->datalen += 8; print_operands (ctx); - return TRUE; + return true; } - return FALSE; + return false; } /* handle_blt */ @@ -719,7 +720,7 @@ int handle_bc (struct ppc_ctx *ctx) * pfunc The address of a function to call to print the output. * * - * Returns TRUE if it was able to output the line info, or false if it was + * Returns true if it was able to output the line info, or false if it was * not. */ @@ -734,7 +735,7 @@ int print_source_line (char *filename, char *funcname, sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no); (*pfunc) (out_buf); - return TRUE; + return true; } /* print_source_line */ @@ -1039,14 +1040,14 @@ int downstring (char *s) * Arguments: * nextaddr The address (to be filled in) of the next * instruction to execute. This will only be a valid - * address if TRUE is returned. + * address if true is returned. * * step_over A flag indicating how to compute addresses for * branch statements: - * TRUE = Step over the branch (next) - * FALSE = step into the branch (step) + * true = Step over the branch (next) + * false = step into the branch (step) * - * Returns TRUE if it was able to compute the address. Returns FALSE if + * Returns true if it was able to compute the address. Returns false if * it has a problem reading the current instruction or one of the registers. */ @@ -1075,7 +1076,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, if (nextaddr == 0 || regs == 0) { printf ("find_next_address: bad args"); - return FALSE; + return false; } pc = regs->nip & 0xfffffffc; @@ -1083,7 +1084,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, if ((op = find_opcode (instr)) == (struct opcode *) 0) { printf ("find_next_address: can't parse opcode 0x%lx", instr); - return FALSE; + return false; } ctr = regs->ctr; @@ -1100,7 +1101,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, !get_operand_value (op, instr, O_BI, &bi) || !get_operand_value (op, instr, O_AA, &aa) || !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; + return false; if ((addr & (1 << 13)) != 0) addr = addr - (1 << 14); @@ -1116,7 +1117,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, if (!get_operand_value (op, instr, O_LI, &addr) || !get_operand_value (op, instr, O_AA, &aa) || !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; + return false; if ((addr & (1 << 23)) != 0) addr = addr - (1 << 24); @@ -1130,7 +1131,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, if (!get_operand_value (op, instr, O_BO, &bo) || !get_operand_value (op, instr, O_BI, &bi) || !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; + return false; addr = ctr; aa = 1; @@ -1143,7 +1144,7 @@ int find_next_address (unsigned char *nextaddr, int step_over, if (!get_operand_value (op, instr, O_BO, &bo) || !get_operand_value (op, instr, O_BI, &bi) || !get_operand_value (op, instr, O_LK, &lk)) - return FALSE; + return false; addr = lr; aa = 1; @@ -1227,12 +1228,12 @@ int find_next_address (unsigned char *nextaddr, int step_over, step = next = pc + 4; } - if (step_over == TRUE) + if (step_over == true) *(unsigned long *) nextaddr = next; else *(unsigned long *) nextaddr = step; - return TRUE; + return true; } /* find_next_address */ diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c index 9791423..77b6e3e 100644 --- a/common/cmd_bedbug.c +++ b/common/cmd_bedbug.c @@ -292,7 +292,7 @@ int do_bedbug_step (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (!find_next_address ((unsigned char *) &addr, FALSE, bug_ctx.regs)) + if (!find_next_address((unsigned char *) &addr, false, bug_ctx.regs)) return 1; if (bug_ctx.set) @@ -323,7 +323,7 @@ int do_bedbug_next (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (!find_next_address ((unsigned char *) &addr, TRUE, bug_ctx.regs)) + if (!find_next_address((unsigned char *) &addr, true, bug_ctx.regs)) return 1; if (bug_ctx.set) diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 66e0ef0..dfa3690 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -39,13 +39,6 @@ #define PRINTF(fmt,args...) #endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - /*#if defined(CONFIG_CMD_DATE) */ /*#include */ /*#endif */ @@ -214,9 +207,9 @@ int wait_for_fdc_int(void) timeout--; udelay(10); if(timeout==0) /* timeout occured */ - return FALSE; + return false; } - return TRUE; + return true; } /* reads a byte from the FIFO of the FDC and checks direction and RQM bit @@ -244,7 +237,7 @@ int fdc_need_more_output(void) c=(unsigned char)read_fdc_byte(); printf("Error: more output: %x\n",c); } - return TRUE; + return true; } @@ -260,10 +253,10 @@ int write_fdc_byte(unsigned char val) udelay(10); fdc_need_more_output(); if(timeout==0) /* timeout occured */ - return FALSE; + return false; } write_fdc_reg(FDC_FIFO,val); - return TRUE; + return true; } /* sets up all FDC commands and issues it to the FDC. If @@ -344,9 +337,9 @@ int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) } for(i=0;icmdlen;i++) { /* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */ - if(write_fdc_byte(pCMD->cmd[i])==FALSE) { + if (write_fdc_byte(pCMD->cmd[i]) == false) { PRINTF("Error: timeout while issue cmd%d\n",i); - return FALSE; + return false; } } timeout=FDC_TIME_OUT; @@ -355,12 +348,12 @@ int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) timeout--; if(timeout==0) { PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR)); - return FALSE; + return false; } } pCMD->result[i]=(unsigned char)read_fdc_byte(); } - return TRUE; + return true; } /* selects the drive assigned in the cmd structur and @@ -391,9 +384,10 @@ void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD) int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) { pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) - return FALSE; - while(wait_for_fdc_int()!=TRUE); + if (fdc_issue_cmd(pCMD, pFG) == false) + return false; + while (wait_for_fdc_int() != true); + pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; return(fdc_issue_cmd(pCMD,pFG)); } @@ -403,9 +397,10 @@ int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) { pCMD->cmd[COMMAND]=FDC_CMD_SEEK; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) - return FALSE; - while(wait_for_fdc_int()!=TRUE); + if (fdc_issue_cmd(pCMD, pFG) == false) + return false; + while (wait_for_fdc_int() != true); + pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; return(fdc_issue_cmd(pCMD,pFG)); } @@ -421,7 +416,7 @@ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) for(i=0;i<7;i++) { pCMD->result[i]=(unsigned char)read_fdc_byte(); } - return TRUE; + return true; } /* reads data from FDC, seek commands are issued automatic */ @@ -440,18 +435,18 @@ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT retriesrw=0; retriescal=0; offset=0; - if(fdc_seek(pCMD,pFG)==FALSE) { + if (fdc_seek(pCMD, pFG) == false) { stop_fdc_drive(pCMD); if (flags) enable_interrupts(); - return FALSE; + return false; } if((pCMD->result[STATUS_0]&0x20)!=0x20) { printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]); stop_fdc_drive(pCMD); if (flags) enable_interrupts(); - return FALSE; + return false; } /* now determine the next seek point */ /* lastblk=pCMD->blnr + blocks; */ @@ -466,11 +461,11 @@ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT retryrw: len=sect_size * readblk; pCMD->cmd[COMMAND]=FDC_CMD_READ; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + if (fdc_issue_cmd(pCMD, pFG) == false) { stop_fdc_drive(pCMD); if (flags) enable_interrupts(); - return FALSE; + return false; } for (i=0;iFDC_RW_RETRIES */ }/* if output */ timeout--; - }while(TRUE); + } while (true); } /* for len */ /* the last sector of a track or all data has been read, * we need to get the results */ @@ -530,22 +525,22 @@ retryrw: readblk=blocks; retrycal: /* a seek is necessary */ - if(fdc_seek(pCMD,pFG)==FALSE) { + if (fdc_seek(pCMD, pFG) == false) { stop_fdc_drive(pCMD); if (flags) enable_interrupts(); - return FALSE; + return false; } if((pCMD->result[STATUS_0]&0x20)!=0x20) { PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]); stop_fdc_drive(pCMD); - return FALSE; + return false; } - }while(TRUE); /* start over */ + } while (true); /* start over */ stop_fdc_drive(pCMD); /* switch off drive */ if (flags) enable_interrupts(); - return TRUE; + return true; } /* Scan all drives and check if drive is present and disk is inserted */ @@ -559,20 +554,20 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) pCMD->drive=drives; select_fdc_drive(pCMD); pCMD->blnr=0; /* set to the 1st block */ - if(fdc_recalibrate(pCMD,pFG)==FALSE) + if (fdc_recalibrate(pCMD, pFG) == false) continue; if((pCMD->result[STATUS_0]&0x10)==0x10) continue; /* ok drive connected check for disk */ state|=(1<blnr=pFG->size; /* set to the last block */ - if(fdc_seek(pCMD,pFG)==FALSE) + if (fdc_seek(pCMD, pFG) == false) continue; pCMD->blnr=0; /* set to the 1st block */ - if(fdc_recalibrate(pCMD,pFG)==FALSE) + if (fdc_recalibrate(pCMD, pFG) == false) continue; pCMD->cmd[COMMAND]=FDC_CMD_READ_ID; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) + if (fdc_issue_cmd(pCMD, pFG) == false) continue; state|=(0x10<name : ""); } pCMD->flags=state; - return TRUE; + return true; } @@ -611,9 +606,9 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) write_fdc_reg(FDC_CCR,pFG->rate); /* then initialize the DSR */ write_fdc_reg(FDC_DSR,pFG->rate); - if(wait_for_fdc_int()==FALSE) { + if (wait_for_fdc_int() == false) { PRINTF("Time Out after writing CCR\n"); - return FALSE; + return false; } /* now issue sense Interrupt and status command * assuming only one drive present (drive 0) */ @@ -621,7 +616,7 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) for(i=0;i<4;i++) { /* issue sense interrupt for all 4 possible drives */ pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + if (fdc_issue_cmd(pCMD, pFG) == false) { PRINTF("Sense Interrupt for drive %d failed\n",i); } } @@ -629,24 +624,24 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) pCMD->drive=drive; select_fdc_drive(pCMD); pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + if (fdc_issue_cmd(pCMD, pFG) == false) { PRINTF(" configure timeout\n"); stop_fdc_drive(pCMD); - return FALSE; + return false; } /* issue specify command */ pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY; - if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + if (fdc_issue_cmd(pCMD, pFG) == false) { PRINTF(" specify timeout\n"); stop_fdc_drive(pCMD); - return FALSE; + return false; } /* then, we clear the reset in the DOR */ /* fdc_check_drive(pCMD,pFG); */ /* write_fdc_reg(FDC_DOR,0x04); */ - return TRUE; + return true; } #if defined(CONFIG_CMD_FDOS) @@ -664,30 +659,30 @@ int fdc_fdos_init (int drive) FDC_COMMAND_STRUCT *pCMD = &cmd; /* setup FDC and scan for drives */ - if(fdc_setup(drive,pCMD,pFG)==FALSE) { + if (fdc_setup(drive, pCMD, pFG) == false) { printf("\n** Error in setup FDC **\n"); - return FALSE; + return false; } - if(fdc_check_drive(pCMD,pFG)==FALSE) { + if (fdc_check_drive(pCMD, pFG) == false) { printf("\n** Error in check_drives **\n"); - return FALSE; + return false; } if((pCMD->flags&(1<flags&(0x10<drive=drive; /* read first block */ pCMD->blnr=0; - return TRUE; + return true; } /************************************************************************** * int fdc_fdos_seek @@ -747,11 +742,11 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_USAGE; } /* setup FDC and scan for drives */ - if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) { + if (fdc_setup(boot_drive, pCMD, pFG) == false) { printf("\n** Error in setup FDC **\n"); return 1; } - if(fdc_check_drive(pCMD,pFG)==FALSE) { + if (fdc_check_drive(pCMD, pFG) == false) { printf("\n** Error in check_drives **\n"); return 1; } @@ -769,7 +764,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) pCMD->drive=boot_drive; /* read first block */ pCMD->blnr=0; - if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) { + if (fdc_read_data((unsigned char *)addr, 1, pCMD, pFG) == false) { printf("\nRead error:"); for(i=0;i<7;i++) printf("result%d: 0x%02X\n",i,pCMD->result[i]); @@ -801,7 +796,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) nrofblk++; printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr); pCMD->blnr=0; - if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) { + if (fdc_read_data((unsigned char *)addr, nrofblk, pCMD, pFG) == false) { /* read image block */ printf("\nRead error:"); for(i=0;i<7;i++) diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 266bfa6..13b3d99 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -110,7 +110,7 @@ void scsi_scan(int mode) scsi_dev_desc[i].vendor[0]=0; scsi_dev_desc[i].product[0]=0; scsi_dev_desc[i].revision[0]=0; - scsi_dev_desc[i].removable=FALSE; + scsi_dev_desc[i].removable = false; scsi_dev_desc[i].if_type=IF_TYPE_SCSI; scsi_dev_desc[i].dev=i; scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN; @@ -125,7 +125,7 @@ void scsi_scan(int mode) pccb->pdata=(unsigned char *)&tempbuff; pccb->datalen=512; scsi_setup_inquiry(pccb); - if(scsi_exec(pccb)!=TRUE) { + if (scsi_exec(pccb) != true) { if(pccb->contr_stat==SCSI_SEL_TIME_OUT) { debug ("Selection timeout ID %d\n",pccb->target); continue; /* selection timeout => assuming no device present */ @@ -139,7 +139,7 @@ void scsi_scan(int mode) continue; /* skip unknown devices */ } if((modi&0x80)==0x80) /* drive is removable */ - scsi_dev_desc[scsi_max_devs].removable=TRUE; + scsi_dev_desc[scsi_max_devs].removable=true; /* get info for this device */ scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0], &tempbuff[8], 8); @@ -152,8 +152,8 @@ void scsi_scan(int mode) pccb->datalen=0; scsi_setup_test_unit_ready(pccb); - if(scsi_exec(pccb)!=TRUE) { - if(scsi_dev_desc[scsi_max_devs].removable==TRUE) { + if (scsi_exec(pccb) != true) { + if (scsi_dev_desc[scsi_max_devs].removable == true) { scsi_dev_desc[scsi_max_devs].type=perq; goto removable; } @@ -404,7 +404,7 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) debug("scsi_read_ext: startblk " LBAF ", blccnt %x buffer %lx\n", start, smallblks, buf_addr); - if(scsi_exec(pccb)!=TRUE) { + if (scsi_exec(pccb) != true) { scsi_print_error(pccb); blkcnt-=blks; break; @@ -458,7 +458,7 @@ static ulong scsi_write(int device, ulong blknr, } debug("%s: startblk " LBAF ", blccnt %x buffer %lx\n", __func__, start, smallblks, buf_addr); - if (scsi_exec(pccb) != TRUE) { + if (scsi_exec(pccb) != true) { scsi_print_error(pccb); blkcnt -= blks; break; @@ -521,7 +521,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz) pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ pccb->datalen = 8; - if (scsi_exec(pccb) != TRUE) + if (scsi_exec(pccb) != true) return 1; *capacity = ((lbaint_t)pccb->pdata[0] << 24) | @@ -547,7 +547,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz) pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ pccb->datalen = 16; - if (scsi_exec(pccb) != TRUE) + if (scsi_exec(pccb) != true) return 1; *capacity = ((uint64_t)pccb->pdata[0] << 56) | diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 2a9d169..3c70d5d 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -201,7 +201,7 @@ MORECORE_FAILURE (default: -1) The value returned upon failure of MORECORE. MORECORE_CLEARS (default 1) - True (1) if the routine mapped to MORECORE zeroes out memory (which + true (1) if the routine mapped to MORECORE zeroes out memory (which holds for sbrk). DEFAULT_TRIM_THRESHOLD DEFAULT_TOP_PAD diff --git a/common/dlmalloc.src b/common/dlmalloc.src index 32a38bc..d86acff 100644 --- a/common/dlmalloc.src +++ b/common/dlmalloc.src @@ -198,7 +198,7 @@ MORECORE_FAILURE (default: -1) The value returned upon failure of MORECORE. MORECORE_CLEARS (default 1) - True (1) if the routine mapped to MORECORE zeroes out memory (which + true (1) if the routine mapped to MORECORE zeroes out memory (which holds for sbrk). DEFAULT_TRIM_THRESHOLD DEFAULT_TOP_PAD -- cgit v1.1 From 60d7d5a63189c9f77a190c9965861dc15482c2d0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 22 Mar 2013 11:26:21 +0000 Subject: env: fix potential stack overflow in environment functions Most of the various environment functions create CONFIG_ENV_SIZE buffers on the stack. At least on ARM and PPC which have 4KB stacks, this can overflow the stack if we have large environment sizes. So move all the buffers off the stack to static buffers. Signed-off-by: Rob Herring --- common/env_dataflash.c | 15 +++++++-------- common/env_eeprom.c | 13 +++++++------ common/env_fat.c | 11 ++++++----- common/env_mmc.c | 13 +++++++------ common/env_nand.c | 23 ++++++++++++----------- common/env_nvram.c | 26 ++++++++++++++++---------- common/env_onenand.c | 13 +++++++------ common/env_sf.c | 23 ++++++++++++----------- 8 files changed, 74 insertions(+), 63 deletions(-) (limited to 'common') diff --git a/common/env_dataflash.c b/common/env_dataflash.c index 38c9615..0591b99 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -30,6 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; env_t *env_ptr; char *env_name_spec = "dataflash"; +static char env_buf[CONFIG_ENV_SIZE]; uchar env_get_char_spec(int index) { @@ -42,11 +43,9 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - char buf[CONFIG_ENV_SIZE]; + read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, env_buf); - read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf); - - env_import(buf, 1); + env_import(env_buf, 1); } #ifdef CONFIG_ENV_OFFSET_REDUND @@ -55,20 +54,20 @@ void env_relocate_spec(void) int saveenv(void) { - env_t env_new; + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res; - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); return write_dataflash(CONFIG_ENV_ADDR, - (unsigned long)&env_new, + (unsigned long)env_new, CONFIG_ENV_SIZE); } diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 45c935b..b136f04 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -38,6 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; env_t *env_ptr; +static char env_buf[CONFIG_ENV_SIZE]; char *env_name_spec = "EEPROM"; int env_eeprom_bus = -1; @@ -111,7 +112,7 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - char buf[CONFIG_ENV_SIZE]; + char *buf = env_buf; unsigned int off = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND @@ -126,7 +127,7 @@ void env_relocate_spec(void) int saveenv(void) { - env_t env_new; + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res; int rc; @@ -138,13 +139,13 @@ int saveenv(void) BUG_ON(env_ptr != NULL); - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 1) { @@ -152,11 +153,11 @@ int saveenv(void) off_red = CONFIG_ENV_OFFSET; } - env_new.flags = ACTIVE_FLAG; + env_new->flags = ACTIVE_FLAG; #endif rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR, - off, (uchar *)&env_new, CONFIG_ENV_SIZE); + off, (uchar *)env_new, CONFIG_ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND if (rc == 0) { diff --git a/common/env_fat.c b/common/env_fat.c index c0f18ab..dd7139d 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -37,6 +37,7 @@ char *env_name_spec = "FAT"; env_t *env_ptr; +static char env_buf[CONFIG_ENV_SIZE]; DECLARE_GLOBAL_DATA_PTR; @@ -52,7 +53,7 @@ int env_init(void) #ifdef CONFIG_CMD_SAVEENV int saveenv(void) { - env_t env_new; + env_t *env_new = env_buf; ssize_t len; char *res; block_dev_desc_t *dev_desc = NULL; @@ -60,7 +61,7 @@ int saveenv(void) int part = FAT_ENV_PART; int err; - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -95,8 +96,8 @@ int saveenv(void) return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); - err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); + err = file_fat_write(FAT_ENV_FILE, (void *)env_new, sizeof(env_t)); if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); @@ -110,7 +111,7 @@ int saveenv(void) void env_relocate_spec(void) { - char buf[CONFIG_ENV_SIZE]; + char *buf = env_buf; block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; diff --git a/common/env_mmc.c b/common/env_mmc.c index 02bd5ae..f568013 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -40,6 +40,8 @@ env_t *env_ptr = &environment; env_t *env_ptr; #endif /* ENV_IS_EMBEDDED */ +DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE); + DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_ENV_OFFSET) @@ -112,7 +114,7 @@ static inline int write_env(struct mmc *mmc, unsigned long size, int saveenv(void) { - ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); @@ -127,7 +129,7 @@ int saveenv(void) goto fini; } - res = (char *)&env_new->data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -135,7 +137,7 @@ int saveenv(void) goto fini; } - env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) { puts("failed\n"); @@ -169,7 +171,6 @@ static inline int read_env(struct mmc *mmc, unsigned long size, void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) - ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; int ret; @@ -184,12 +185,12 @@ void env_relocate_spec(void) goto fini; } - if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) { + if (read_env(mmc, CONFIG_ENV_SIZE, offset, env_buf)) { ret = 1; goto fini; } - env_import(buf, 1); + env_import(env_buf, 1); ret = 0; fini: diff --git a/common/env_nand.c b/common/env_nand.c index 5b69889..8cc2055 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -64,6 +64,8 @@ env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST; env_t *env_ptr; #endif /* ENV_IS_EMBEDDED */ +DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE); + DECLARE_GLOBAL_DATA_PTR; /* @@ -173,7 +175,7 @@ static unsigned char env_flags; int saveenv(void) { - env_t env_new; + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res; int ret = 0; @@ -185,14 +187,14 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); - env_new.flags = ++env_flags; /* increase the serial */ + env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new->flags = ++env_flags; /* increase the serial */ if (gd->env_valid == 1) { puts("Erasing redundant NAND...\n"); @@ -201,7 +203,7 @@ int saveenv(void) return 1; puts("Writing to redundant NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new); + ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)env_new); } else { puts("Erasing NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET; @@ -209,7 +211,7 @@ int saveenv(void) return 1; puts("Writing to NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new); + ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new); } if (ret) { puts("FAILED!\n"); @@ -226,7 +228,7 @@ int saveenv(void) int saveenv(void) { int ret = 0; - ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res; nand_erase_options_t nand_erase_options; @@ -238,7 +240,7 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new->data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -404,7 +406,6 @@ void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int ret; - ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); @@ -420,13 +421,13 @@ void env_relocate_spec(void) } #endif - ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf); + ret = readenv(CONFIG_ENV_OFFSET, (u_char *)env_buf); if (ret) { set_default_env("!readenv() failed"); return; } - env_import(buf, 1); + env_import(env_buf, 1); #endif /* ! ENV_IS_EMBEDDED */ } #endif /* CONFIG_ENV_OFFSET_REDUND */ diff --git a/common/env_nvram.c b/common/env_nvram.c index eab0e7b..ff74a6c 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -60,6 +60,10 @@ env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR; char *env_name_spec = "NVRAM"; #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE +static char env_buf[CONFIG_ENV_SIZE]; +#endif + +#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE uchar env_get_char_spec(int index) { uchar c; @@ -72,36 +76,38 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - char buf[CONFIG_ENV_SIZE]; + char *buf; #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) + buf = env_buf; nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); #else - memcpy(buf, (void *)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); + buf = (void *)CONFIG_ENV_ADDR; #endif env_import(buf, 1); } int saveenv(void) { - env_t env_new; +#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE + env_t *env_new = (env_t *)env_buf; +#else + env_t *env_new = (env_t *)CONFIG_ENV_ADDR; +#endif ssize_t len; char *res; int rcode = 0; - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE - nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); -#else - if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL) - rcode = 1; + nvram_write(CONFIG_ENV_ADDR, env_new, CONFIG_ENV_SIZE); #endif return rcode; } @@ -115,7 +121,7 @@ int env_init(void) { #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) ulong crc; - uchar data[ENV_SIZE]; + uchar *data = env_buf; nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong)); nvram_read(data, CONFIG_ENV_ADDR + sizeof(ulong), ENV_SIZE); diff --git a/common/env_onenand.c b/common/env_onenand.c index faa903d..6fd5613 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -42,6 +42,8 @@ char *env_name_spec = "OneNAND"; #define ONENAND_MAX_ENV_SIZE CONFIG_ENV_SIZE #define ONENAND_ENV_SIZE(mtd) (ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE) +static char env_buf[CONFIG_ENV_SIZE]; + DECLARE_GLOBAL_DATA_PTR; void env_relocate_spec(void) @@ -56,8 +58,7 @@ void env_relocate_spec(void) char *buf = (char *)&environment; #else loff_t env_addr = CONFIG_ENV_ADDR; - char onenand_env[ONENAND_MAX_ENV_SIZE]; - char *buf = (char *)&onenand_env[0]; + char *buf = env_buf; #endif /* ENV_IS_EMBEDDED */ #ifndef ENV_IS_EMBEDDED @@ -81,7 +82,7 @@ void env_relocate_spec(void) int saveenv(void) { - env_t env_new; + env_t *env_new = env_buf; ssize_t len; char *res; struct mtd_info *mtd = &onenand_mtd; @@ -94,13 +95,13 @@ int saveenv(void) .callback = NULL, }; - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); instr.len = CONFIG_ENV_SIZE; #ifdef CONFIG_ENV_ADDR_FLEX @@ -119,7 +120,7 @@ int saveenv(void) } if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, - (u_char *)&env_new)) { + (u_char *)env_new)) { printf("OneNAND: write failed at 0x%llx\n", instr.addr); return 2; } diff --git a/common/env_sf.c b/common/env_sf.c index d9e9085..9a592ba 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -58,11 +58,12 @@ DECLARE_GLOBAL_DATA_PTR; char *env_name_spec = "SPI Flash"; static struct spi_flash *env_flash; +static char env_buf[CONFIG_ENV_SIZE]; #if defined(CONFIG_ENV_OFFSET_REDUND) int saveenv(void) { - env_t env_new; + env_t *env_new = (env_t *)env_buf; ssize_t len; char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; @@ -78,14 +79,14 @@ int saveenv(void) } } - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); - env_new.flags = ACTIVE_FLAG; + env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new->flags = ACTIVE_FLAG; if (gd->env_valid == 1) { env_new_offset = CONFIG_ENV_OFFSET_REDUND; @@ -125,7 +126,7 @@ int saveenv(void) puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_new_offset, - CONFIG_ENV_SIZE, &env_new); + CONFIG_ENV_SIZE, env_new); if (ret) goto done; @@ -137,7 +138,7 @@ int saveenv(void) } ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), - sizeof(env_new.flags), &flag); + sizeof(env_new->flags), &flag); if (ret) goto done; @@ -243,7 +244,7 @@ int saveenv(void) u32 saved_size, saved_offset, sector = 1; char *res, *saved_buffer = NULL; int ret = 1; - env_t env_new; + env_t *env_new = (env_t *)env_buf; ssize_t len; if (!env_flash) { @@ -276,13 +277,13 @@ int saveenv(void) sector++; } - res = (char *)&env_new.data; + res = (char *)env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); goto done; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, @@ -292,7 +293,7 @@ int saveenv(void) puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, - CONFIG_ENV_SIZE, &env_new); + CONFIG_ENV_SIZE, env_new); if (ret) goto done; @@ -315,7 +316,7 @@ int saveenv(void) void env_relocate_spec(void) { - char buf[CONFIG_ENV_SIZE]; + char *buf = env_buf; int ret; env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, -- cgit v1.1 From 9fd383724cf49b5fd787c62169569d870857d611 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 1 Apr 2013 11:50:28 +0000 Subject: mmc: don't allow extra cmdline arguments The "mmc rescan" command takes no arguments. However, executing "mmc rescan 1" succeeds, leading the user to believe that MMC device 1 has been rescanned. In fact, the "current" MMC device has been rescanned, and the current device may well not be 1. Add error-checking to the "mmc" command to explicitly reject any extra command-line arguments so that it's more obvious when U-Boot isn't doing what the user thought they asked it to. Signed-off-by: Stephen Warren --- common/cmd_mmc.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 8c53a10..9f3d6c5 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -164,8 +164,12 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (strcmp(argv[1], "rescan") == 0) { - struct mmc *mmc = find_mmc_device(curr_device); + struct mmc *mmc; + if (argc != 2) + return CMD_RET_USAGE; + + mmc = find_mmc_device(curr_device); if (!mmc) { printf("no mmc device at slot %x\n", curr_device); return 1; @@ -179,8 +183,12 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } else if (strncmp(argv[1], "part", 4) == 0) { block_dev_desc_t *mmc_dev; - struct mmc *mmc = find_mmc_device(curr_device); + struct mmc *mmc; + + if (argc != 2) + return CMD_RET_USAGE; + mmc = find_mmc_device(curr_device); if (!mmc) { printf("no mmc device at slot %x\n", curr_device); return 1; @@ -196,6 +204,8 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) puts("get mmc type error!\n"); return 1; } else if (strcmp(argv[1], "list") == 0) { + if (argc != 2) + return CMD_RET_USAGE; print_mmc_devices('\n'); return 0; } else if (strcmp(argv[1], "dev") == 0) { -- cgit v1.1 From cd0f4fa1ca2901312ae78bc27d4edc8286fcbf1d Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 5 Apr 2013 14:55:21 -0400 Subject: Revert "env: fix potential stack overflow in environment functions" Wolfgang requested this be reverted and Rob agreed after further discussion. This was a symptom of a larger problem we need to deal with. This reverts commit 60d7d5a63189c9f77a190c9965861dc15482c2d0. Signed-off-by: Tom Rini --- common/env_dataflash.c | 15 ++++++++------- common/env_eeprom.c | 13 ++++++------- common/env_fat.c | 11 +++++------ common/env_mmc.c | 13 ++++++------- common/env_nand.c | 23 +++++++++++------------ common/env_nvram.c | 26 ++++++++++---------------- common/env_onenand.c | 13 ++++++------- common/env_sf.c | 23 +++++++++++------------ 8 files changed, 63 insertions(+), 74 deletions(-) (limited to 'common') diff --git a/common/env_dataflash.c b/common/env_dataflash.c index 0591b99..38c9615 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -30,7 +30,6 @@ DECLARE_GLOBAL_DATA_PTR; env_t *env_ptr; char *env_name_spec = "dataflash"; -static char env_buf[CONFIG_ENV_SIZE]; uchar env_get_char_spec(int index) { @@ -43,9 +42,11 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, env_buf); + char buf[CONFIG_ENV_SIZE]; - env_import(env_buf, 1); + read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf); + + env_import(buf, 1); } #ifdef CONFIG_ENV_OFFSET_REDUND @@ -54,20 +55,20 @@ void env_relocate_spec(void) int saveenv(void) { - env_t *env_new = (env_t *)env_buf; + env_t env_new; ssize_t len; char *res; - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); return write_dataflash(CONFIG_ENV_ADDR, - (unsigned long)env_new, + (unsigned long)&env_new, CONFIG_ENV_SIZE); } diff --git a/common/env_eeprom.c b/common/env_eeprom.c index b136f04..45c935b 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -38,7 +38,6 @@ DECLARE_GLOBAL_DATA_PTR; env_t *env_ptr; -static char env_buf[CONFIG_ENV_SIZE]; char *env_name_spec = "EEPROM"; int env_eeprom_bus = -1; @@ -112,7 +111,7 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - char *buf = env_buf; + char buf[CONFIG_ENV_SIZE]; unsigned int off = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND @@ -127,7 +126,7 @@ void env_relocate_spec(void) int saveenv(void) { - env_t *env_new = (env_t *)env_buf; + env_t env_new; ssize_t len; char *res; int rc; @@ -139,13 +138,13 @@ int saveenv(void) BUG_ON(env_ptr != NULL); - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 1) { @@ -153,11 +152,11 @@ int saveenv(void) off_red = CONFIG_ENV_OFFSET; } - env_new->flags = ACTIVE_FLAG; + env_new.flags = ACTIVE_FLAG; #endif rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR, - off, (uchar *)env_new, CONFIG_ENV_SIZE); + off, (uchar *)&env_new, CONFIG_ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND if (rc == 0) { diff --git a/common/env_fat.c b/common/env_fat.c index dd7139d..c0f18ab 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -37,7 +37,6 @@ char *env_name_spec = "FAT"; env_t *env_ptr; -static char env_buf[CONFIG_ENV_SIZE]; DECLARE_GLOBAL_DATA_PTR; @@ -53,7 +52,7 @@ int env_init(void) #ifdef CONFIG_CMD_SAVEENV int saveenv(void) { - env_t *env_new = env_buf; + env_t env_new; ssize_t len; char *res; block_dev_desc_t *dev_desc = NULL; @@ -61,7 +60,7 @@ int saveenv(void) int part = FAT_ENV_PART; int err; - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -96,8 +95,8 @@ int saveenv(void) return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); - err = file_fat_write(FAT_ENV_FILE, (void *)env_new, sizeof(env_t)); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); @@ -111,7 +110,7 @@ int saveenv(void) void env_relocate_spec(void) { - char *buf = env_buf; + char buf[CONFIG_ENV_SIZE]; block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; diff --git a/common/env_mmc.c b/common/env_mmc.c index f568013..02bd5ae 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -40,8 +40,6 @@ env_t *env_ptr = &environment; env_t *env_ptr; #endif /* ENV_IS_EMBEDDED */ -DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE); - DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_ENV_OFFSET) @@ -114,7 +112,7 @@ static inline int write_env(struct mmc *mmc, unsigned long size, int saveenv(void) { - env_t *env_new = (env_t *)env_buf; + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); @@ -129,7 +127,7 @@ int saveenv(void) goto fini; } - res = (char *)env_new->data; + res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -137,7 +135,7 @@ int saveenv(void) goto fini; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) { puts("failed\n"); @@ -171,6 +169,7 @@ static inline int read_env(struct mmc *mmc, unsigned long size, void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; int ret; @@ -185,12 +184,12 @@ void env_relocate_spec(void) goto fini; } - if (read_env(mmc, CONFIG_ENV_SIZE, offset, env_buf)) { + if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) { ret = 1; goto fini; } - env_import(env_buf, 1); + env_import(buf, 1); ret = 0; fini: diff --git a/common/env_nand.c b/common/env_nand.c index 8cc2055..5b69889 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -64,8 +64,6 @@ env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST; env_t *env_ptr; #endif /* ENV_IS_EMBEDDED */ -DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE); - DECLARE_GLOBAL_DATA_PTR; /* @@ -175,7 +173,7 @@ static unsigned char env_flags; int saveenv(void) { - env_t *env_new = (env_t *)env_buf; + env_t env_new; ssize_t len; char *res; int ret = 0; @@ -187,14 +185,14 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); - env_new->flags = ++env_flags; /* increase the serial */ + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = ++env_flags; /* increase the serial */ if (gd->env_valid == 1) { puts("Erasing redundant NAND...\n"); @@ -203,7 +201,7 @@ int saveenv(void) return 1; puts("Writing to redundant NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)env_new); + ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new); } else { puts("Erasing NAND...\n"); nand_erase_options.offset = CONFIG_ENV_OFFSET; @@ -211,7 +209,7 @@ int saveenv(void) return 1; puts("Writing to NAND... "); - ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new); + ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new); } if (ret) { puts("FAILED!\n"); @@ -228,7 +226,7 @@ int saveenv(void) int saveenv(void) { int ret = 0; - env_t *env_new = (env_t *)env_buf; + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; nand_erase_options_t nand_erase_options; @@ -240,7 +238,7 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)env_new->data; + res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); @@ -406,6 +404,7 @@ void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int ret; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); @@ -421,13 +420,13 @@ void env_relocate_spec(void) } #endif - ret = readenv(CONFIG_ENV_OFFSET, (u_char *)env_buf); + ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf); if (ret) { set_default_env("!readenv() failed"); return; } - env_import(env_buf, 1); + env_import(buf, 1); #endif /* ! ENV_IS_EMBEDDED */ } #endif /* CONFIG_ENV_OFFSET_REDUND */ diff --git a/common/env_nvram.c b/common/env_nvram.c index ff74a6c..eab0e7b 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -60,10 +60,6 @@ env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR; char *env_name_spec = "NVRAM"; #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE -static char env_buf[CONFIG_ENV_SIZE]; -#endif - -#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE uchar env_get_char_spec(int index) { uchar c; @@ -76,38 +72,36 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - char *buf; + char buf[CONFIG_ENV_SIZE]; #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) - buf = env_buf; nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); #else - buf = (void *)CONFIG_ENV_ADDR; + memcpy(buf, (void *)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE); #endif env_import(buf, 1); } int saveenv(void) { -#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE - env_t *env_new = (env_t *)env_buf; -#else - env_t *env_new = (env_t *)CONFIG_ENV_ADDR; -#endif + env_t env_new; ssize_t len; char *res; int rcode = 0; - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE - nvram_write(CONFIG_ENV_ADDR, env_new, CONFIG_ENV_SIZE); + nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); +#else + if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL) + rcode = 1; #endif return rcode; } @@ -121,7 +115,7 @@ int env_init(void) { #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE) ulong crc; - uchar *data = env_buf; + uchar data[ENV_SIZE]; nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong)); nvram_read(data, CONFIG_ENV_ADDR + sizeof(ulong), ENV_SIZE); diff --git a/common/env_onenand.c b/common/env_onenand.c index 6fd5613..faa903d 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -42,8 +42,6 @@ char *env_name_spec = "OneNAND"; #define ONENAND_MAX_ENV_SIZE CONFIG_ENV_SIZE #define ONENAND_ENV_SIZE(mtd) (ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE) -static char env_buf[CONFIG_ENV_SIZE]; - DECLARE_GLOBAL_DATA_PTR; void env_relocate_spec(void) @@ -58,7 +56,8 @@ void env_relocate_spec(void) char *buf = (char *)&environment; #else loff_t env_addr = CONFIG_ENV_ADDR; - char *buf = env_buf; + char onenand_env[ONENAND_MAX_ENV_SIZE]; + char *buf = (char *)&onenand_env[0]; #endif /* ENV_IS_EMBEDDED */ #ifndef ENV_IS_EMBEDDED @@ -82,7 +81,7 @@ void env_relocate_spec(void) int saveenv(void) { - env_t *env_new = env_buf; + env_t env_new; ssize_t len; char *res; struct mtd_info *mtd = &onenand_mtd; @@ -95,13 +94,13 @@ int saveenv(void) .callback = NULL, }; - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); instr.len = CONFIG_ENV_SIZE; #ifdef CONFIG_ENV_ADDR_FLEX @@ -120,7 +119,7 @@ int saveenv(void) } if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, - (u_char *)env_new)) { + (u_char *)&env_new)) { printf("OneNAND: write failed at 0x%llx\n", instr.addr); return 2; } diff --git a/common/env_sf.c b/common/env_sf.c index 9a592ba..d9e9085 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -58,12 +58,11 @@ DECLARE_GLOBAL_DATA_PTR; char *env_name_spec = "SPI Flash"; static struct spi_flash *env_flash; -static char env_buf[CONFIG_ENV_SIZE]; #if defined(CONFIG_ENV_OFFSET_REDUND) int saveenv(void) { - env_t *env_new = (env_t *)env_buf; + env_t env_new; ssize_t len; char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; @@ -79,14 +78,14 @@ int saveenv(void) } } - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); - env_new->flags = ACTIVE_FLAG; + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { env_new_offset = CONFIG_ENV_OFFSET_REDUND; @@ -126,7 +125,7 @@ int saveenv(void) puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, env_new_offset, - CONFIG_ENV_SIZE, env_new); + CONFIG_ENV_SIZE, &env_new); if (ret) goto done; @@ -138,7 +137,7 @@ int saveenv(void) } ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), - sizeof(env_new->flags), &flag); + sizeof(env_new.flags), &flag); if (ret) goto done; @@ -244,7 +243,7 @@ int saveenv(void) u32 saved_size, saved_offset, sector = 1; char *res, *saved_buffer = NULL; int ret = 1; - env_t *env_new = (env_t *)env_buf; + env_t env_new; ssize_t len; if (!env_flash) { @@ -277,13 +276,13 @@ int saveenv(void) sector++; } - res = (char *)env_new->data; + res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); goto done; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, @@ -293,7 +292,7 @@ int saveenv(void) puts("Writing to SPI flash..."); ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, - CONFIG_ENV_SIZE, env_new); + CONFIG_ENV_SIZE, &env_new); if (ret) goto done; @@ -316,7 +315,7 @@ int saveenv(void) void env_relocate_spec(void) { - char *buf = env_buf; + char buf[CONFIG_ENV_SIZE]; int ret; env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, -- cgit v1.1 From a6142706f578e6246bc987ae8ac343f506d3ad35 Mon Sep 17 00:00:00 2001 From: York Sun Date: Thu, 4 Apr 2013 11:52:53 +0000 Subject: common/cmd_test: Avoid macro expansion cmd_test.c adds "true" and "false" as new commands. We need to avoid macro expansion for U_BOOT_CMD. Signed-off-by: York Sun --- common/cmd_test.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'common') diff --git a/common/cmd_test.c b/common/cmd_test.c index d4ec186..acc0ecf 100644 --- a/common/cmd_test.c +++ b/common/cmd_test.c @@ -21,6 +21,15 @@ * MA 02111-1307 USA */ +/* + * Define _STDBOOL_H here to avoid macro expansion of true and false. + * If the future code requires macro true or false, remove this define + * and undef true and false before U_BOOT_CMD. This define and comment + * shall be removed if change to U_BOOT_CMD is made to take string + * instead of stringifying it. + */ +#define _STDBOOL_H + #include #include -- cgit v1.1 From 381c6e2c90ed083281649e74e461a303c1ffab47 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Sun, 7 Apr 2013 22:13:32 +0000 Subject: cmd_sf: include header file common.h before div64.h The header file div64.h includes which defines the phys_addr_t according to the macro CONFIG_PHYS_64BIT, while the macro CONFIG_PHYS_64BIT is included in common.h which comes after div64.h, so in order to get consistent type definition for phys_addr_t, common.h should be included before div64.h, Or else, the parameters of phys_addr_t type will be passed wrongly when CONFIG_PHYS_64BIT is defined. Signed-off-by: Mingkai Hu --- common/cmd_sf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 3f0d414..0a17782 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -5,8 +5,8 @@ * Licensed under the GPL-2 or later. */ -#include #include +#include #include #include -- cgit v1.1 From c39d6a0ea57d57b53bd7fb8933874e1640e47888 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 14 Mar 2013 05:32:50 +0000 Subject: nand: Extend nand_(read|write)_skip_bad with *actual and limit parameters We make these two functions take a size_t pointer to how much space was used on NAND to read or write the buffer (when reads/writes happen) so that bad blocks can be accounted for. We also make them take an loff_t limit on how much data can be read or written. This means that we can now catch the case of when writing to a partition would exceed the partition size due to bad blocks. To do this we also need to make check_skip_len count not just complete blocks used but partial ones as well. All callers of nand_(read|write)_skip_bad are adjusted to call these with the most sensible limits available. The changes were started by Pantelis and finished by Tom. Signed-off-by: Pantelis Antoniou Signed-off-by: Tom Rini --- common/cmd_nand.c | 53 +++++++++++++++++++++++++++++++---------------------- common/env_nand.c | 3 ++- 2 files changed, 33 insertions(+), 23 deletions(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 32348f3..110c78c 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -137,7 +137,8 @@ static inline int str2long(const char *p, ulong *num) return *p != '\0' && *endptr == '\0'; } -static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size) +static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, + loff_t *maxsize) { #ifdef CONFIG_CMD_MTDPARTS struct mtd_device *dev; @@ -160,6 +161,7 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size) *off = part->offset; *size = part->size; + *maxsize = part->size; *idx = dev->id->num; ret = set_dev(*idx); @@ -173,10 +175,11 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size) #endif } -static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize) +static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *size, + loff_t *maxsize) { if (!str2off(arg, off)) - return get_part(arg, idx, off, maxsize); + return get_part(arg, idx, off, size, maxsize); if (*off >= nand_info[*idx].size) { puts("Offset exceeds device limit\n"); @@ -184,36 +187,35 @@ static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize) } *maxsize = nand_info[*idx].size - *off; + *size = *maxsize; return 0; } static int arg_off_size(int argc, char *const argv[], int *idx, - loff_t *off, loff_t *size) + loff_t *off, loff_t *size, loff_t *maxsize) { int ret; - loff_t maxsize = 0; if (argc == 0) { *off = 0; *size = nand_info[*idx].size; + *maxsize = *size; goto print; } - ret = arg_off(argv[0], idx, off, &maxsize); + ret = arg_off(argv[0], idx, off, size, maxsize); if (ret) return ret; - if (argc == 1) { - *size = maxsize; + if (argc == 1) goto print; - } if (!str2off(argv[1], size)) { printf("'%s' is not a number\n", argv[1]); return -1; } - if (*size > maxsize) { + if (*size > *maxsize) { puts("Size exceeds partition or device limit\n"); return -1; } @@ -307,7 +309,8 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) if (argc < 3) goto usage; - if (arg_off(argv[2], &idx, &addr, &maxsize)) { + /* We don't care about size, or maxsize. */ + if (arg_off(argv[2], &idx, &addr, &maxsize, &maxsize)) { puts("Offset or partition name expected\n"); return 1; } @@ -426,7 +429,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, ret = 0; ulong addr; - loff_t off, size; + loff_t off, size, maxsize; char *cmd, *s; nand_info_t *nand; #ifdef CONFIG_SYS_NAND_QUIET @@ -551,7 +554,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("\nNAND %s: ", cmd); /* skip first two or three arguments, look for offset and size */ - if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0) + if (arg_off_size(argc - o, argv + o, &dev, &off, &size, + &maxsize) != 0) return 1; nand = &nand_info[dev]; @@ -619,7 +623,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (s && !strcmp(s, ".raw")) { raw = 1; - if (arg_off(argv[3], &dev, &off, &size)) + if (arg_off(argv[3], &dev, &off, &size, &maxsize)) return 1; if (argc > 4 && !str2long(argv[4], &pagecount)) { @@ -635,7 +639,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) rwsize = pagecount * (nand->writesize + nand->oobsize); } else { if (arg_off_size(argc - 3, argv + 3, &dev, - &off, &size) != 0) + &off, &size, &maxsize) != 0) return 1; rwsize = size; @@ -645,9 +649,11 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) ret = nand_read_skip_bad(nand, off, &rwsize, + NULL, maxsize, (u_char *)addr); else ret = nand_write_skip_bad(nand, off, &rwsize, + NULL, maxsize, (u_char *)addr, 0); #ifdef CONFIG_CMD_NAND_TRIMFFS } else if (!strcmp(s, ".trimffs")) { @@ -655,8 +661,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Unknown nand command suffix '%s'\n", s); return 1; } - ret = nand_write_skip_bad(nand, off, &rwsize, - (u_char *)addr, + ret = nand_write_skip_bad(nand, off, &rwsize, NULL, + maxsize, (u_char *)addr, WITH_DROP_FFS); #endif #ifdef CONFIG_CMD_NAND_YAFFS @@ -665,8 +671,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Unknown nand command suffix '%s'.\n", s); return 1; } - ret = nand_write_skip_bad(nand, off, &rwsize, - (u_char *)addr, + ret = nand_write_skip_bad(nand, off, &rwsize, NULL, + maxsize, (u_char *)addr, WITH_INLINE_OOB); #endif } else if (!strcmp(s, ".oob")) { @@ -775,7 +781,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (s && !strcmp(s, ".allexcept")) allexcept = 1; - if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) + if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size, + &maxsize) < 0) return 1; if (!nand_unlock(&nand_info[dev], off, size, allexcept)) { @@ -873,7 +880,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); cnt = nand->writesize; - r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr); + r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size, + (u_char *)addr); if (r) { puts("** Read error\n"); bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ); @@ -905,7 +913,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); - r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr); + r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size, + (u_char *)addr); if (r) { puts("** Read error\n"); bootstage_error(BOOTSTAGE_ID_NAND_READ); diff --git a/common/env_nand.c b/common/env_nand.c index 5b69889..b745822 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -281,7 +281,8 @@ int readenv(size_t offset, u_char *buf) } else { char_ptr = &buf[amount_loaded]; if (nand_read_skip_bad(&nand_info[0], offset, - &len, char_ptr)) + &len, NULL, + nand_info[0].size, char_ptr)) return 1; offset += blocksize; -- cgit v1.1 From c4df2f41005063cf1d1dcddeed4bd7f12a5dff77 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 14 Mar 2013 05:32:51 +0000 Subject: cmd_nand.c: Fix CONFIG_CMD_NAND_YAFFS The flag changed from WITH_INLINE_OOB to WITH_YAFFS_OOB by accident in 418396e. Signed-off-by: Tom Rini --- common/cmd_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 110c78c..e9d3d3c 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -673,7 +673,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, - WITH_INLINE_OOB); + WITH_YAFFS_OOB); #endif } else if (!strcmp(s, ".oob")) { /* out-of-band data */ -- cgit v1.1 From 3d38910151e3d069a164190763c7b03d11f1eec4 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Tue, 9 Apr 2013 14:06:51 +0000 Subject: Do not call board_early_init_f() twice Apparently due to a missed rebase conflict resolution board_early_init_f() is included twice in the list of initialization functions. Leave only the first occurrence. . built and boot an Exynos 5250 target Signed-off-by: Vadim Bendebury --- common/board_f.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'common') diff --git a/common/board_f.c b/common/board_f.c index 29b49c3..7698891 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -788,9 +788,6 @@ static init_fnc_t init_sequence_f[] = { /* TODO: can we rename this to timer_init()? */ init_timebase, #endif -#if defined(CONFIG_BOARD_EARLY_INIT_F) - board_early_init_f, -#endif #ifdef CONFIG_ARM timer_init, /* initialize timer */ #endif -- cgit v1.1 From 71829067500a5447e5149ba43a0dbbb7166df757 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Mon, 8 Apr 2013 10:32:47 +0000 Subject: ubi: Expose a few simple functions from the cmd_ubi Part, Read, and Write functionality that will be used by env_ubi. Signed-off-by: Joe Hershberger --- common/cmd_ubi.c | 150 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 83 insertions(+), 67 deletions(-) (limited to 'common') diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 35b1d31..41fbae7 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -263,7 +263,7 @@ out_err: return err; } -static int ubi_volume_write(char *volume, void *buf, size_t size) +int ubi_volume_write(char *volume, void *buf, size_t size) { int err = 1; int rsvd_bytes = 0; @@ -308,12 +308,10 @@ static int ubi_volume_write(char *volume, void *buf, size_t size) ubi_gluebi_updated(vol); } - printf("%d bytes written to volume %s\n", size, volume); - return 0; } -static int ubi_volume_read(char *volume, char *buf, size_t size) +int ubi_volume_read(char *volume, char *buf, size_t size) { int err, lnum, off, len, tbuf_size; void *tbuf; @@ -325,8 +323,6 @@ static int ubi_volume_read(char *volume, char *buf, size_t size) if (vol == NULL) return ENODEV; - printf("Read %d bytes from volume %s to %p\n", size, volume, buf); - if (vol->updating) { printf("updating"); return EBUSY; @@ -431,26 +427,82 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev, return 0; } -static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +int ubi_part(char *part_name, const char *vid_header_offset) { - size_t size = 0; - ulong addr = 0; int err = 0; - - if (argc < 2) - return CMD_RET_USAGE; + char mtd_dev[16]; + struct mtd_device *dev; + struct part_info *part; + u8 pnum; if (mtdparts_init() != 0) { printf("Error initializing mtdparts!\n"); return 1; } +#ifdef CONFIG_CMD_UBIFS + /* + * Automatically unmount UBIFS partition when user + * changes the UBI device. Otherwise the following + * UBIFS commands will crash. + */ + if (ubifs_is_mounted()) + cmd_ubifs_umount(); +#endif + + /* todo: get dev number for NAND... */ + ubi_dev.nr = 0; + + /* + * Call ubi_exit() before re-initializing the UBI subsystem + */ + if (ubi_initialized) { + ubi_exit(); + del_mtd_partitions(ubi_dev.mtd_info); + } + + /* + * Search the mtd device number where this partition + * is located + */ + if (find_dev_and_part(part_name, &dev, &pnum, &part)) { + printf("Partition %s not found!\n", part_name); + return 1; + } + sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num); + ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev); + if (IS_ERR(ubi_dev.mtd_info)) { + printf("Partition %s not found on device %s!\n", part_name, + mtd_dev); + return 1; + } + + ubi_dev.selected = 1; + + strcpy(ubi_dev.part_name, part_name); + err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, + vid_header_offset); + if (err) { + printf("UBI init error %d\n", err); + ubi_dev.selected = 0; + return err; + } + + ubi = ubi_devices[0]; + + return 0; +} + +static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + size_t size = 0; + ulong addr = 0; + + if (argc < 2) + return CMD_RET_USAGE; + if (strcmp(argv[1], "part") == 0) { - char mtd_dev[16]; - struct mtd_device *dev; - struct part_info *part; const char *vid_header_offset = NULL; - u8 pnum; /* Print current partition */ if (argc == 2) { @@ -467,58 +519,10 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) if (argc < 3) return CMD_RET_USAGE; -#ifdef CONFIG_CMD_UBIFS - /* - * Automatically unmount UBIFS partition when user - * changes the UBI device. Otherwise the following - * UBIFS commands will crash. - */ - if (ubifs_is_mounted()) - cmd_ubifs_umount(); -#endif - - /* todo: get dev number for NAND... */ - ubi_dev.nr = 0; - - /* - * Call ubi_exit() before re-initializing the UBI subsystem - */ - if (ubi_initialized) { - ubi_exit(); - del_mtd_partitions(ubi_dev.mtd_info); - } - - /* - * Search the mtd device number where this partition - * is located - */ - if (find_dev_and_part(argv[2], &dev, &pnum, &part)) { - printf("Partition %s not found!\n", argv[2]); - return 1; - } - sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num); - ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev); - if (IS_ERR(ubi_dev.mtd_info)) { - printf("Partition %s not found on device %s!\n", argv[2], mtd_dev); - return 1; - } - - ubi_dev.selected = 1; - if (argc > 3) vid_header_offset = argv[3]; - strcpy(ubi_dev.part_name, argv[2]); - err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, - vid_header_offset); - if (err) { - printf("UBI init error %d\n", err); - ubi_dev.selected = 0; - return err; - } - - ubi = ubi_devices[0]; - return 0; + return ubi_part(argv[2], vid_header_offset); } if ((strcmp(argv[1], "part") != 0) && (!ubi_dev.selected)) { @@ -571,6 +575,8 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) } if (strncmp(argv[1], "write", 5) == 0) { + int ret; + if (argc < 5) { printf("Please see usage\n"); return 1; @@ -579,7 +585,13 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) addr = simple_strtoul(argv[2], NULL, 16); size = simple_strtoul(argv[4], NULL, 16); - return ubi_volume_write(argv[3], (void *)addr, size); + ret = ubi_volume_write(argv[3], (void *)addr, size); + if (!ret) { + printf("%d bytes written to volume %s\n", size, + argv[3]); + } + + return ret; } if (strncmp(argv[1], "read", 4) == 0) { @@ -597,8 +609,12 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) argc--; } - if (argc == 3) + if (argc == 3) { + printf("Read %d bytes from volume %s to %lx\n", size, + argv[3], addr); + return ubi_volume_read(argv[3], (char *)addr, size); + } } printf("Please see usage\n"); -- cgit v1.1 From 147162dac6506d2ed96ba5869772f87fb1f49a0b Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Mon, 8 Apr 2013 10:32:49 +0000 Subject: ubi: ubifs: Turn off verbose prints The prints are out of control. SILENCE! Signed-off-by: Joe Hershberger --- common/cmd_ubi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'common') diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 41fbae7..5ba4feb 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -23,6 +23,9 @@ #include #include +#undef ubi_msg +#define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__) + #define DEV_TYPE_NONE 0 #define DEV_TYPE_NAND 1 #define DEV_TYPE_ONENAND 2 -- cgit v1.1 From a7eb1d66c704c884584bf00548cfdf68abfe68bb Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Mon, 8 Apr 2013 10:32:50 +0000 Subject: mtd: Make mtdparts work with pre-reloc env The env in UBI needs to look up the mtd partition as part of relocation, which happens before relocation. Make the mtdparts code capable of working on the default env to start with. The code tries to set values in the env as well, but again, the env isn't there yet, so add a check to setenv to not allow sets before the env is relocated. Signed-off-by: Joe Hershberger --- common/cmd_mtdparts.c | 23 +++++++++++++++++++++-- common/cmd_nvedit.c | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 5192dee..1c35f9d 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -106,6 +106,8 @@ #include #endif +DECLARE_GLOBAL_DATA_PTR; + /* special size referring to all the remaining space in a partition */ #define SIZE_REMAINING 0xFFFFFFFF @@ -1537,6 +1539,7 @@ static int parse_mtdparts(const char *const mtdparts) const char *p = mtdparts; struct mtd_device *dev; int err = 1; + char tmp_parts[MTDPARTS_MAXLEN]; debug("\n---parse_mtdparts---\nmtdparts = %s\n\n", p); @@ -1547,7 +1550,12 @@ static int parse_mtdparts(const char *const mtdparts) } /* re-read 'mtdparts' variable, mtd_devices_init may be updating env */ - p = getenv("mtdparts"); + if (gd->flags & GD_FLG_ENV_READY) { + p = getenv("mtdparts"); + } else { + p = tmp_parts; + getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN); + } if (strncmp(p, "mtdparts=", 9) != 0) { printf("mtdparts variable doesn't start with 'mtdparts='\n"); @@ -1705,6 +1713,7 @@ int mtdparts_init(void) const char *current_partition; int ids_changed; char tmp_ep[PARTITION_MAXLEN]; + char tmp_parts[MTDPARTS_MAXLEN]; debug("\n---mtdparts_init---\n"); if (!initialized) { @@ -1718,7 +1727,17 @@ int mtdparts_init(void) /* get variables */ ids = getenv("mtdids"); - parts = getenv("mtdparts"); + /* + * The mtdparts variable tends to be long. If we need to access it + * before the env is relocated, then we need to use our own stack + * buffer. gd->env_buf will be too small. + */ + if (gd->flags & GD_FLG_ENV_READY) { + parts = getenv("mtdparts"); + } else { + parts = tmp_parts; + getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN); + } current_partition = getenv("partition"); /* save it for later parsing, cannot rely on current partition pointer diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 947d6c4..fab8694 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -273,6 +273,10 @@ int setenv(const char *varname, const char *varvalue) { const char * const argv[4] = { "setenv", varname, varvalue, NULL }; + /* before import into hashtable */ + if (!(gd->flags & GD_FLG_ENV_READY)) + return 1; + if (varvalue == NULL || varvalue[0] == '\0') return _do_env_set(0, 2, (char * const *)argv); else -- cgit v1.1 From 2b74433f365fa677a60431a80e524b5d8d04e995 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Mon, 8 Apr 2013 10:32:51 +0000 Subject: env: Add support for UBI environment UBI is a better place for the environment on NAND devices because it handles wear-leveling and bad blocks. Gluebi is needed in Linux to access the env as an MTD partition. Signed-off-by: Joe Hershberger --- common/Makefile | 1 + common/cmd_nvedit.c | 3 +- common/env_ubi.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 common/env_ubi.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index f631311..0e0fff1 100644 --- a/common/Makefile +++ b/common/Makefile @@ -66,6 +66,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o +COBJS-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o # command diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index fab8694..afa128e 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -62,9 +62,10 @@ DECLARE_GLOBAL_DATA_PTR; !defined(CONFIG_ENV_IS_IN_ONENAND) && \ !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ !defined(CONFIG_ENV_IS_IN_REMOTE) && \ + !defined(CONFIG_ENV_IS_IN_UBI) && \ !defined(CONFIG_ENV_IS_NOWHERE) # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\ -SPI_FLASH|NVRAM|MMC|FAT|REMOTE} or CONFIG_ENV_IS_NOWHERE +SPI_FLASH|NVRAM|MMC|FAT|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE #endif /* diff --git a/common/env_ubi.c b/common/env_ubi.c new file mode 100644 index 0000000..0c592a6 --- /dev/null +++ b/common/env_ubi.c @@ -0,0 +1,103 @@ +/* + * (c) Copyright 2012 by National Instruments, + * Joe Hershberger + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + +#include +#include +#include +#include +#include +#include +#undef crc32 + +char *env_name_spec = "UBI"; + +env_t *env_ptr; + +DECLARE_GLOBAL_DATA_PTR; + +int env_init(void) +{ + /* use default */ + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 1; + + return 0; +} + +#ifdef CONFIG_CMD_SAVEENV +int saveenv(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); + ssize_t len; + char *res; + + res = (char *)&env_new->data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { + printf("\n** Cannot find mtd partition \"%s\"\n", + CONFIG_ENV_UBI_PART); + return 1; + } + + env_new->crc = crc32(0, env_new->data, ENV_SIZE); + + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, + CONFIG_ENV_SIZE)) { + printf("\n** Unable to write env to %s:%s **\n", + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); + return 1; + } + + puts("done\n"); + return 0; +} +#endif /* CONFIG_CMD_SAVEENV */ + +void env_relocate_spec(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); + + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { + printf("\n** Cannot find mtd partition \"%s\"\n", + CONFIG_ENV_UBI_PART); + set_default_env(NULL); + return; + } + + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf, + CONFIG_ENV_SIZE)) { + printf("\n** Unable to read env from %s:%s **\n", + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); + set_default_env(NULL); + return; + } + + env_import(buf, 1); +} -- cgit v1.1 From 785881f775252940185e10fbb2d5299c9ffa6bce Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Mon, 8 Apr 2013 10:32:52 +0000 Subject: env: Add redundant env support to UBI env Allow the user to specify two UBI volumes to use for the environment Signed-off-by: Joe Hershberger --- common/env_ubi.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'common') diff --git a/common/env_ubi.c b/common/env_ubi.c index 0c592a6..1ed8b02 100644 --- a/common/env_ubi.c +++ b/common/env_ubi.c @@ -47,6 +47,58 @@ int env_init(void) } #ifdef CONFIG_CMD_SAVEENV +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT +static unsigned char env_flags; + +int saveenv(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); + ssize_t len; + char *res; + + res = (char *)&env_new->data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { + printf("\n** Cannot find mtd partition \"%s\"\n", + CONFIG_ENV_UBI_PART); + return 1; + } + + env_new->crc = crc32(0, env_new->data, ENV_SIZE); + env_new->flags = ++env_flags; /* increase the serial */ + + if (gd->env_valid == 1) { + puts("Writing to redundant UBI... "); + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND, + (void *)env_new, CONFIG_ENV_SIZE)) { + printf("\n** Unable to write env to %s:%s **\n", + CONFIG_ENV_UBI_PART, + CONFIG_ENV_UBI_VOLUME_REDUND); + return 1; + } + } else { + puts("Writing to UBI... "); + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, + (void *)env_new, CONFIG_ENV_SIZE)) { + printf("\n** Unable to write env to %s:%s **\n", + CONFIG_ENV_UBI_PART, + CONFIG_ENV_UBI_VOLUME); + return 1; + } + } + + puts("done\n"); + + gd->env_valid = gd->env_valid == 2 ? 1 : 2; + + return 0; +} +#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); @@ -78,8 +130,72 @@ int saveenv(void) puts("done\n"); return 0; } +#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ #endif /* CONFIG_CMD_SAVEENV */ +#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT +void env_relocate_spec(void) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE); + ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE); + int crc1_ok = 0, crc2_ok = 0; + env_t *ep, *tmp_env1, *tmp_env2; + + tmp_env1 = (env_t *)env1_buf; + tmp_env2 = (env_t *)env2_buf; + + if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { + printf("\n** Cannot find mtd partition \"%s\"\n", + CONFIG_ENV_UBI_PART); + set_default_env(NULL); + return; + } + + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, + CONFIG_ENV_SIZE)) { + printf("\n** Unable to read env from %s:%s **\n", + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); + } + + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2, + CONFIG_ENV_SIZE)) { + printf("\n** Unable to read redundant env from %s:%s **\n", + CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); + } + + crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc; + crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc; + + if (!crc1_ok && !crc2_ok) { + set_default_env("!bad CRC"); + return; + } else if (crc1_ok && !crc2_ok) { + gd->env_valid = 1; + } else if (!crc1_ok && crc2_ok) { + gd->env_valid = 2; + } else { + /* both ok - check serial */ + if (tmp_env1->flags == 255 && tmp_env2->flags == 0) + gd->env_valid = 2; + else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) + gd->env_valid = 1; + else if (tmp_env1->flags > tmp_env2->flags) + gd->env_valid = 1; + else if (tmp_env2->flags > tmp_env1->flags) + gd->env_valid = 2; + else /* flags are equal - almost impossible */ + gd->env_valid = 1; + } + + if (gd->env_valid == 1) + ep = tmp_env1; + else + ep = tmp_env2; + + env_flags = ep->flags; + env_import((char *)ep, 0); +} +#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ void env_relocate_spec(void) { ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); @@ -101,3 +217,4 @@ void env_relocate_spec(void) env_import(buf, 1); } +#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ -- cgit v1.1