diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 2 | ||||
-rw-r--r-- | common/board_f.c | 8 | ||||
-rw-r--r-- | common/bootm.c | 150 | ||||
-rw-r--r-- | common/bootm_os.c | 29 | ||||
-rw-r--r-- | common/cmd_sandbox.c | 2 | ||||
-rw-r--r-- | common/console.c | 46 | ||||
-rw-r--r-- | common/edid.c | 12 | ||||
-rw-r--r-- | common/image-fit.c | 10 | ||||
-rw-r--r-- | common/image.c | 4 | ||||
-rw-r--r-- | common/lcd.c | 313 | ||||
-rw-r--r-- | common/lcd_console.c | 211 | ||||
-rw-r--r-- | common/memsize.c | 31 | ||||
-rw-r--r-- | common/spl/spl_nor.c | 64 |
13 files changed, 488 insertions, 394 deletions
diff --git a/common/Makefile b/common/Makefile index c668a2fd5b..94554f2939 100644 --- a/common/Makefile +++ b/common/Makefile @@ -196,7 +196,7 @@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o obj-$(CONFIG_I2C_EDID) += edid.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o -obj-$(CONFIG_LCD) += lcd.o +obj-$(CONFIG_LCD) += lcd.o lcd_console.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_MODEM_SUPPORT) += modem.o diff --git a/common/board_f.c b/common/board_f.c index cfd77f8653..3a4b32c29d 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -985,6 +985,11 @@ static init_fnc_t init_sequence_f[] = { INIT_FUNC_WATCHDOG_RESET reloc_fdt, setup_reloc, +#ifdef CONFIG_X86 + copy_uboot_to_ram, + clear_bss, + do_elf_reloc_fixups, +#endif #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) jump_to_copy, #endif @@ -1044,9 +1049,6 @@ void board_init_f(ulong boot_flags) */ static init_fnc_t init_sequence_f_r[] = { init_cache_f_r, - copy_uboot_to_ram, - clear_bss, - do_elf_reloc_fixups, NULL, }; diff --git a/common/bootm.c b/common/bootm.c index 6b3ea8c61b..e2dc16486b 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -264,103 +264,122 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, return 0; } -#endif /* USE_HOSTCC */ +#endif /* USE_HOSTC */ /** - * decomp_image() - decompress the operating system + * print_decomp_msg() - Print a suitable decompression/loading message * - * @comp: Compression algorithm that is used (IH_COMP_...) - * @load: Destination load address in U-Boot memory - * @image_start Image start address (where we are decompressing from) * @type: OS type (IH_OS_...) - * @load_bug: Place to decompress to - * @image_buf: Address to decompress from - * @return 0 if OK, -ve on error (BOOTM_ERR_...) + * @comp_type: Compression type being used (IH_COMP_...) + * @is_xip: true if the load address matches the image start */ -static int decomp_image(int comp, ulong load, ulong image_start, int type, - void *load_buf, void *image_buf, ulong image_len, - ulong *load_end) +static void print_decomp_msg(int comp_type, int type, bool is_xip) { - const char *type_name = genimg_get_type_name(type); - __attribute__((unused)) uint unc_len = CONFIG_SYS_BOOTM_LEN; + const char *name = genimg_get_type_name(type); + + if (comp_type == IH_COMP_NONE) + printf(" %s %s ... ", is_xip ? "XIP" : "Loading", name); + else + printf(" Uncompressing %s ... ", name); +} + +/** + * handle_decomp_error() - display a decompression error + * + * This function tries to produce a useful message. In the case where the + * uncompressed size is the same as the available space, we can assume that + * the image is too large for the buffer. + * + * @comp_type: Compression type being used (IH_COMP_...) + * @uncomp_size: Number of bytes uncompressed + * @unc_len: Amount of space available for decompression + * @ret: Error code to report + * @return BOOTM_ERR_RESET, indicating that the board must be reset + */ +static int handle_decomp_error(int comp_type, size_t uncomp_size, + size_t unc_len, int ret) +{ + const char *name = genimg_get_comp_name(comp_type); + + if (uncomp_size >= unc_len) + printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n"); + else + printf("%s: uncompress error %d\n", name, ret); + + /* + * The decompression routines are now safe, so will not write beyond + * their bounds. Probably it is not necessary to reset, but maintain + * the current behaviour for now. + */ + printf("Must RESET board to recover\n"); +#ifndef USE_HOSTCC + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); +#endif + + return BOOTM_ERR_RESET; +} + +int bootm_decomp_image(int comp, ulong load, ulong image_start, int type, + void *load_buf, void *image_buf, ulong image_len, + uint unc_len, ulong *load_end) +{ + int ret = 0; *load_end = load; + print_decomp_msg(comp, type, load == image_start); + + /* + * Load the image to the right place, decompressing if needed. After + * this, image_len will be set to the number of uncompressed bytes + * loaded, ret will be non-zero on error. + */ switch (comp) { case IH_COMP_NONE: - if (load == image_start) { - printf(" XIP %s ... ", type_name); - } else { - printf(" Loading %s ... ", type_name); + if (load == image_start) + break; + if (image_len <= unc_len) memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); - } - *load_end = load + image_len; + else + ret = 1; break; #ifdef CONFIG_GZIP - case IH_COMP_GZIP: - printf(" Uncompressing %s ... ", type_name); - if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) { - puts("GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover\n"); - return BOOTM_ERR_RESET; - } - - *load_end = load + image_len; + case IH_COMP_GZIP: { + ret = gunzip(load_buf, unc_len, image_buf, &image_len); break; + } #endif /* CONFIG_GZIP */ #ifdef CONFIG_BZIP2 - case IH_COMP_BZIP2: - printf(" Uncompressing %s ... ", type_name); + case IH_COMP_BZIP2: { + uint size = unc_len; + /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len, + ret = BZ2_bzBuffToBuffDecompress(load_buf, &size, image_buf, image_len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); - if (i != BZ_OK) { - printf("BUNZIP2: uncompress or overwrite error %d - must RESET board to recover\n", - i); - return BOOTM_ERR_RESET; - } - - *load_end = load + unc_len; + image_len = size; break; + } #endif /* CONFIG_BZIP2 */ #ifdef CONFIG_LZMA case IH_COMP_LZMA: { SizeT lzma_len = unc_len; - int ret; - - printf(" Uncompressing %s ... ", type_name); ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, image_buf, image_len); - unc_len = lzma_len; - if (ret != SZ_OK) { - printf("LZMA: uncompress or overwrite error %d - must RESET board to recover\n", - ret); - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); - return BOOTM_ERR_RESET; - } - *load_end = load + unc_len; + image_len = lzma_len; break; } #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: { size_t size = unc_len; - int ret; - - printf(" Uncompressing %s ... ", type_name); ret = lzop_decompress(image_buf, image_len, load_buf, &size); - if (ret != LZO_E_OK) { - printf("LZO: uncompress or overwrite error %d - must RESET board to recover\n", - ret); - return BOOTM_ERR_RESET; - } - - *load_end = load + size; + image_len = size; break; } #endif /* CONFIG_LZO */ @@ -369,6 +388,10 @@ static int decomp_image(int comp, ulong load, ulong image_start, int type, return BOOTM_ERR_UNIMPLEMENTED; } + if (ret) + return handle_decomp_error(comp, image_len, unc_len, ret); + *load_end = load + image_len; + puts("OK\n"); return 0; @@ -390,8 +413,9 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, load_buf = map_sysmem(load, 0); image_buf = map_sysmem(os.image_start, image_len); - err = decomp_image(os.comp, load, os.image_start, os.type, load_buf, - image_buf, image_len, load_end); + err = bootm_decomp_image(os.comp, load, os.image_start, os.type, + load_buf, image_buf, image_len, + CONFIG_SYS_BOOTM_LEN, load_end); if (err) { bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return err; @@ -882,9 +906,11 @@ static int bootm_host_load_image(const void *fit, int req_image_type) /* Allow the image to expand by a factor of 4, should be safe */ load_buf = malloc((1 << 20) + len * 4); - ret = decomp_image(imape_comp, 0, data, image_type, load_buf, - (void *)data, len, &load_end); + ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf, + (void *)data, len, CONFIG_SYS_BOOTM_LEN, + &load_end); free(load_buf); + if (ret && ret != BOOTM_ERR_UNIMPLEMENTED) return ret; diff --git a/common/bootm_os.c b/common/bootm_os.c index 5be4467a1c..72477f0b81 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -404,6 +404,32 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[], } #endif +#ifdef CONFIG_BOOTM_OPENRTOS +static int do_bootm_openrtos(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + void (*entry_point)(void); + + if (flag != BOOTM_STATE_OS_GO) + return 0; + + entry_point = (void (*)(void))images->ep; + + printf("## Transferring control to OpenRTOS (at address %08lx) ...\n", + (ulong)entry_point); + + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + /* + * OpenRTOS Parameters: + * None + */ + (*entry_point)(); + + return 1; +} +#endif + static boot_os_fn *boot_os[] = { [IH_OS_U_BOOT] = do_bootm_standalone, #ifdef CONFIG_BOOTM_LINUX @@ -434,6 +460,9 @@ static boot_os_fn *boot_os[] = { #ifdef CONFIG_INTEGRITY [IH_OS_INTEGRITY] = do_bootm_integrity, #endif +#ifdef CONFIG_BOOTM_OPENRTOS + [IH_OS_OPENRTOS] = do_bootm_openrtos, +#endif }; /* Allow for arch specific config before we boot */ diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 3d9fce7e55..428696982e 100644 --- a/common/cmd_sandbox.c +++ b/common/cmd_sandbox.c @@ -117,7 +117,7 @@ U_BOOT_CMD( "load hostfs - <addr> <filename> [<bytes> <offset>] - " "load a file from host\n" "sb ls hostfs - <filename> - list files on host\n" - "sb save hostfs - <filename> <addr> <bytes> [<offset>] - " + "sb save hostfs - <addr> <filename> <bytes> [<offset>] - " "save a file to host\n" "sb bind <dev> [<filename>] - bind \"host\" device to file\n" "sb info [<dev>] - show device binding & info\n" diff --git a/common/console.c b/common/console.c index 29560c3ebe..fc1963b2a9 100644 --- a/common/console.c +++ b/common/console.c @@ -199,6 +199,20 @@ static void console_putc(int file, const char c) } } +#ifdef CONFIG_PRE_CONSOLE_BUFFER +static void console_putc_noserial(int file, const char c) +{ + int i; + struct stdio_dev *dev; + + for (i = 0; i < cd_count[file]; i++) { + dev = console_devices[file][i]; + if (dev->putc != NULL && strcmp(dev->name, "serial") != 0) + dev->putc(dev, c); + } +} +#endif + static void console_puts(int file, const char *s) { int i; @@ -236,6 +250,14 @@ static inline void console_putc(int file, const char c) stdio_devices[file]->putc(stdio_devices[file], c); } +#ifdef CONFIG_PRE_CONSOLE_BUFFER +static inline void console_putc_noserial(int file, const char c) +{ + if (strcmp(stdio_devices[file]->name, "serial") != 0) + stdio_devices[file]->putc(stdio_devices[file], c); +} +#endif + static inline void console_puts(int file, const char *s) { stdio_devices[file]->puts(stdio_devices[file], s); @@ -382,6 +404,9 @@ int tstc(void) return serial_tstc(); } +#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0 +#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1 + #ifdef CONFIG_PRE_CONSOLE_BUFFER #define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ) @@ -398,7 +423,7 @@ static void pre_console_puts(const char *s) pre_console_putc(*s++); } -static void print_pre_console_buffer(void) +static void print_pre_console_buffer(int flushpoint) { unsigned long i = 0; char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR; @@ -407,12 +432,20 @@ static void print_pre_console_buffer(void) i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ; while (i < gd->precon_buf_idx) - putc(buffer[CIRC_BUF_IDX(i++)]); + switch (flushpoint) { + case PRE_CONSOLE_FLUSHPOINT1_SERIAL: + putc(buffer[CIRC_BUF_IDX(i++)]); + break; + case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL: + console_putc_noserial(stdout, + buffer[CIRC_BUF_IDX(i++)]); + break; + } } #else static inline void pre_console_putc(const char c) {} static inline void pre_console_puts(const char *s) {} -static inline void print_pre_console_buffer(void) {} +static inline void print_pre_console_buffer(int flushpoint) {} #endif void putc(const char c) @@ -441,6 +474,7 @@ void putc(const char c) fputc(stdout, c); } else { /* Send directly to the handler */ + pre_console_putc(c); serial_putc(c); } } @@ -472,6 +506,7 @@ void puts(const char *s) fputs(stdout, s); } else { /* Send directly to the handler */ + pre_console_puts(s); serial_puts(s); } } @@ -679,7 +714,7 @@ int console_init_f(void) gd->flags |= GD_FLG_SILENT; #endif - print_pre_console_buffer(); + print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL); return 0; } @@ -794,6 +829,7 @@ done: if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) return 0; #endif + print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); return 0; } @@ -869,7 +905,7 @@ int console_init_r(void) if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) return 0; #endif - + print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); return 0; } diff --git a/common/edid.c b/common/edid.c index e66108f24a..df797fcdd5 100644 --- a/common/edid.c +++ b/common/edid.c @@ -12,6 +12,7 @@ #include <common.h> #include <edid.h> +#include <errno.h> #include <linux/ctype.h> #include <linux/string.h> @@ -29,6 +30,17 @@ int edid_check_info(struct edid1_info *edid_info) return 0; } +int edid_check_checksum(u8 *edid_block) +{ + u8 checksum = 0; + int i; + + for (i = 0; i < 128; i++) + checksum += edid_block[i]; + + return (checksum == 0) ? 0 : -EINVAL; +} + int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin, unsigned int *hmax, unsigned int *vmin, unsigned int *vmax) diff --git a/common/image-fit.c b/common/image-fit.c index 4ffc5aaa51..1589ee3e4f 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1518,6 +1518,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr, size_t size; int type_ok, os_ok; ulong load, data, len; + uint8_t os; const char *prop_name; int ret; @@ -1612,10 +1613,15 @@ int fit_image_load(bootm_headers_t *images, ulong addr, (image_type == IH_TYPE_KERNEL && fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD)); + os_ok = image_type == IH_TYPE_FLATDT || - fit_image_check_os(fit, noffset, IH_OS_LINUX); + fit_image_check_os(fit, noffset, IH_OS_LINUX) || + fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); if (!type_ok || !os_ok) { - printf("No Linux %s %s Image\n", genimg_get_arch_name(arch), + fit_image_get_os(fit, noffset, &os); + printf("No %s %s %s Image\n", + genimg_get_os_name(os), + genimg_get_arch_name(arch), genimg_get_type_name(image_type)); bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); return -EIO; diff --git a/common/image.c b/common/image.c index e691a51789..ad7a46d08d 100644 --- a/common/image.c +++ b/common/image.c @@ -120,6 +120,10 @@ static const table_entry_t uimage_os[] = { { IH_OS_SOLARIS, "solaris", "Solaris", }, { IH_OS_SVR4, "svr4", "SVR4", }, #endif +#if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC) + { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", }, +#endif + { -1, "", "", }, }; diff --git a/common/lcd.c b/common/lcd.c index 3ed504df50..cc34b8aee4 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -73,45 +73,13 @@ #define CONFIG_LCD_ALIGNMENT PAGE_SIZE #endif -/* By default we scroll by a single line */ -#ifndef CONFIG_CONSOLE_SCROLL_LINES -#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) || \ - (LCD_BPP == LCD_COLOR32) -# define COLOR_MASK(c) (c) -#else +#if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \ + (LCD_BPP != LCD_COLOR32) # error Unsupported LCD BPP. #endif DECLARE_GLOBAL_DATA_PTR; -static void lcd_drawchars(ushort x, ushort y, uchar *str, int count); -static inline void lcd_putc_xy(ushort x, ushort y, uchar c); - static int lcd_init(void *lcdbase); static void *lcd_logo(void); @@ -125,10 +93,6 @@ int lcd_line_length; char lcd_is_enabled = 0; -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 */ @@ -166,217 +130,16 @@ void lcd_set_flush_dcache(int flush) /*----------------------------------------------------------------------*/ -static void console_scrollup(void) -{ - const int rows = CONFIG_CONSOLE_SCROLL_LINES; - - /* Copy up rows ignoring those that will be overwritten */ - memcpy(CONSOLE_ROW_FIRST, - lcd_console_address + CONSOLE_ROW_SIZE * rows, - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); - - /* Clear the last rows */ -#if (LCD_BPP != LCD_COLOR32) - memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, - COLOR_MASK(lcd_color_bg), - CONSOLE_ROW_SIZE * rows); -#else - u32 *ppix = lcd_console_address + - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows; - u32 i; - for (i = 0; - i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix); - i++) { - *ppix++ = COLOR_MASK(lcd_color_bg); - } -#endif - lcd_sync(); - console_row -= rows; -} - -/*----------------------------------------------------------------------*/ - -static inline void console_back(void) -{ - if (--console_col < 0) { - console_col = CONSOLE_COLS-1 ; - if (--console_row < 0) - console_row = 0; - } - - lcd_putc_xy(console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, ' '); -} - -/*----------------------------------------------------------------------*/ - -static inline void console_newline(void) -{ - console_col = 0; - - /* Check if we need to scroll the terminal */ - if (++console_row >= CONSOLE_ROWS) - console_scrollup(); - else - lcd_sync(); -} - -/*----------------------------------------------------------------------*/ - static void lcd_stub_putc(struct stdio_dev *dev, const char c) { lcd_putc(c); } -void lcd_putc(const char c) -{ - if (!lcd_is_enabled) { - serial_putc(c); - - return; - } - - switch (c) { - case '\r': - console_col = 0; - - return; - case '\n': - console_newline(); - - return; - case '\t': /* Tab (8 chars alignment) */ - console_col += 8; - console_col &= ~7; - - if (console_col >= CONSOLE_COLS) - console_newline(); - - return; - case '\b': - console_back(); - - return; - default: - lcd_putc_xy(console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, c); - if (++console_col >= CONSOLE_COLS) - console_newline(); - } -} - -/*----------------------------------------------------------------------*/ - static void lcd_stub_puts(struct stdio_dev *dev, const char *s) { lcd_puts(s); } -void lcd_puts(const char *s) -{ - if (!lcd_is_enabled) { - serial_puts(s); - - return; - } - - while (*s) - lcd_putc(*s++); - - lcd_sync(); -} - -/*----------------------------------------------------------------------*/ - -void lcd_printf(const char *fmt, ...) -{ - va_list args; - char buf[CONFIG_SYS_PBSIZE]; - - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - - lcd_puts(buf); -} - -/************************************************************************/ -/* ** Low-Level Graphics Routines */ -/************************************************************************/ - -static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) -{ - uchar *dest; - ushort row; - -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - y += BMP_LOGO_HEIGHT; -#endif - -#if LCD_BPP == LCD_MONOCHROME - ushort off = x * (1 << LCD_BPP) % 8; -#endif - - dest = (uchar *)(lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP)/8); - - for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { - uchar *s = str; - int i; -#if LCD_BPP == LCD_COLOR16 - ushort *d = (ushort *)dest; -#elif LCD_BPP == LCD_COLOR32 - u32 *d = (u32 *)dest; -#else - uchar *d = dest; -#endif - -#if LCD_BPP == LCD_MONOCHROME - uchar rest = *d & -(1 << (8 - off)); - uchar sym; -#endif - for (i = 0; i < count; ++i) { - uchar c, bits; - - c = *s++; - bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; - -#if LCD_BPP == LCD_MONOCHROME - sym = (COLOR_MASK(lcd_color_fg) & bits) | - (COLOR_MASK(lcd_color_bg) & ~bits); - - *d++ = rest | (sym >> off); - rest = sym << (8-off); -#elif LCD_BPP == LCD_COLOR8 - for (c = 0; c < 8; ++c) { - *d++ = (bits & 0x80) ? - lcd_color_fg : lcd_color_bg; - bits <<= 1; - } -#elif LCD_BPP == LCD_COLOR16 - for (c = 0; c < 8; ++c) { - *d++ = (bits & 0x80) ? - lcd_color_fg : lcd_color_bg; - bits <<= 1; - } -#elif LCD_BPP == LCD_COLOR32 - for (c = 0; c < 8; ++c) { - *d++ = (bits & 0x80) ? - lcd_color_fg : lcd_color_bg; - bits <<= 1; - } -#endif - } -#if LCD_BPP == LCD_MONOCHROME - *d = rest | (*d & ((1 << (8 - off)) - 1)); -#endif - } -} - -static inline void lcd_putc_xy(ushort x, ushort y, uchar c) -{ - lcd_drawchars(x, y, &c, 1); -} - /************************************************************************/ /** Small utility to check that you got the colours right */ /************************************************************************/ @@ -455,11 +218,9 @@ int drv_lcd_init(void) /*----------------------------------------------------------------------*/ void lcd_clear(void) { -#if LCD_BPP == LCD_MONOCHROME - /* Setting the palette */ - lcd_initcolregs(); - -#elif LCD_BPP == LCD_COLOR8 + short console_rows, console_cols; + int bg_color; +#if LCD_BPP == LCD_COLOR8 /* Setting the palette */ lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0); lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0); @@ -475,9 +236,11 @@ void lcd_clear(void) #ifndef CONFIG_SYS_WHITE_ON_BLACK lcd_setfgcolor(CONSOLE_COLOR_BLACK); lcd_setbgcolor(CONSOLE_COLOR_WHITE); + bg_color = CONSOLE_COLOR_WHITE; #else lcd_setfgcolor(CONSOLE_COLOR_WHITE); lcd_setbgcolor(CONSOLE_COLOR_BLACK); + bg_color = CONSOLE_COLOR_BLACK; #endif /* CONFIG_SYS_WHITE_ON_BLACK */ #ifdef LCD_TEST_PATTERN @@ -485,25 +248,27 @@ void lcd_clear(void) #else /* set framebuffer to background color */ #if (LCD_BPP != LCD_COLOR32) - memset((char *)lcd_base, - COLOR_MASK(lcd_color_bg), - lcd_line_length * panel_info.vl_row); + memset((char *)lcd_base, bg_color, lcd_line_length * panel_info.vl_row); #else u32 *ppix = lcd_base; u32 i; for (i = 0; i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix); i++) { - *ppix++ = COLOR_MASK(lcd_color_bg); + *ppix++ = bg_color; } #endif #endif /* Paint the logo and retrieve LCD base address */ debug("[LCD] Drawing the logo...\n"); - lcd_console_address = lcd_logo(); - - console_col = 0; - console_row = 0; +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) + console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT); + console_rows /= VIDEO_FONT_HEIGHT; +#else + console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT; +#endif + console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH; + lcd_init_console(lcd_logo(), console_rows, console_cols); lcd_sync(); } @@ -546,11 +311,11 @@ static int lcd_init(void *lcdbase) lcd_enable(); /* Initialize the console */ - console_col = 0; + lcd_set_col(0); #ifdef CONFIG_LCD_INFO_BELOW_LOGO - console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT; + lcd_set_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT); #else - console_row = 1; /* leave 1 blank line below logo */ + lcd_set_row(1); /* leave 1 blank line below logo */ #endif return 0; @@ -597,6 +362,11 @@ static void lcd_setfgcolor(int color) lcd_color_fg = color; } +int lcd_getfgcolor(void) +{ + return lcd_color_fg; +} + /*----------------------------------------------------------------------*/ static void lcd_setbgcolor(int color) @@ -604,6 +374,11 @@ static void lcd_setbgcolor(int color) lcd_color_bg = color; } +int lcd_getbgcolor(void) +{ + return lcd_color_bg; +} + /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ @@ -685,11 +460,7 @@ void bitmap_plot(int x, int y) *(cmap + BMP_LOGO_OFFSET) = lut_entry; cmap++; #else /* !CONFIG_ATMEL_LCD */ -#ifdef CONFIG_SYS_INVERT_COLORS - *cmap++ = 0xffff - colreg; -#else *cmap++ = colreg; -#endif #endif /* CONFIG_ATMEL_LCD */ } @@ -967,11 +738,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) ( ((cte.red) << 8) & 0xf800) | ( ((cte.green) << 3) & 0x07e0) | ( ((cte.blue) >> 3) & 0x001f) ; -#ifdef CONFIG_SYS_INVERT_COLORS - *cmap = 0xffff - colreg; -#else *cmap = colreg; -#endif #if defined(CONFIG_MPC823) cmap--; #else @@ -1108,8 +875,8 @@ static void *lcd_logo(void) bitmap_plot(0, 0); #ifdef CONFIG_LCD_INFO - console_col = LCD_INFO_X / VIDEO_FONT_WIDTH; - console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT; + lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH); + lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT); lcd_show_board_info(); #endif /* CONFIG_LCD_INFO */ @@ -1144,12 +911,6 @@ static int on_splashimage(const char *name, const char *value, enum env_op op, U_BOOT_ENV_CALLBACK(splashimage, on_splashimage); #endif -void lcd_position_cursor(unsigned col, unsigned row) -{ - console_col = min_t(short, col, CONSOLE_COLS - 1); - console_row = min_t(short, row, CONSOLE_ROWS - 1); -} - int lcd_get_pixel_width(void) { return panel_info.vl_col; @@ -1160,16 +921,6 @@ int lcd_get_pixel_height(void) return panel_info.vl_row; } -int lcd_get_screen_rows(void) -{ - return CONSOLE_ROWS; -} - -int lcd_get_screen_columns(void) -{ - return CONSOLE_COLS; -} - #if defined(CONFIG_LCD_DT_SIMPLEFB) static int lcd_dt_simplefb_configure_node(void *blob, int off) { diff --git a/common/lcd_console.c b/common/lcd_console.c new file mode 100644 index 0000000000..74c388a0ca --- /dev/null +++ b/common/lcd_console.c @@ -0,0 +1,211 @@ +/* + * (C) Copyright 2001-2014 + * DENX Software Engineering -- wd@denx.de + * Compulab Ltd - http://compulab.co.il/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <lcd.h> +#include <video_font.h> /* Get font data, width and height */ + +#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length) +#define CONSOLE_ROW_FIRST lcd_console_address +#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows) + +static short console_curr_col; +static short console_curr_row; +static short console_cols; +static short console_rows; +static void *lcd_console_address; + +void lcd_init_console(void *address, int rows, int cols) +{ + console_curr_col = 0; + console_curr_row = 0; + console_cols = cols; + console_rows = rows; + lcd_console_address = address; +} + +void lcd_set_col(short col) +{ + console_curr_col = col; +} + +void lcd_set_row(short row) +{ + console_curr_row = row; +} + +void lcd_position_cursor(unsigned col, unsigned row) +{ + console_curr_col = min_t(short, col, console_cols - 1); + console_curr_row = min_t(short, row, console_rows - 1); +} + +int lcd_get_screen_rows(void) +{ + return console_rows; +} + +int lcd_get_screen_columns(void) +{ + return console_cols; +} + +static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) +{ + uchar *dest; + ushort row; + int fg_color, bg_color; + + dest = (uchar *)(lcd_console_address + + y * lcd_line_length + x * NBITS(LCD_BPP) / 8); + + for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { + uchar *s = str; + int i; +#if LCD_BPP == LCD_COLOR16 + ushort *d = (ushort *)dest; +#elif LCD_BPP == LCD_COLOR32 + u32 *d = (u32 *)dest; +#else + uchar *d = dest; +#endif + + fg_color = lcd_getfgcolor(); + bg_color = lcd_getbgcolor(); + for (i = 0; i < count; ++i) { + uchar c, bits; + + c = *s++; + bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + + for (c = 0; c < 8; ++c) { + *d++ = (bits & 0x80) ? fg_color : bg_color; + bits <<= 1; + } + } + } +} + +static inline void lcd_putc_xy(ushort x, ushort y, uchar c) +{ + lcd_drawchars(x, y, &c, 1); +} + +static void console_scrollup(void) +{ + const int rows = CONFIG_CONSOLE_SCROLL_LINES; + int bg_color = lcd_getbgcolor(); + + /* Copy up rows ignoring those that will be overwritten */ + memcpy(CONSOLE_ROW_FIRST, + lcd_console_address + CONSOLE_ROW_SIZE * rows, + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); + + /* Clear the last rows */ +#if (LCD_BPP != LCD_COLOR32) + memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, + bg_color, CONSOLE_ROW_SIZE * rows); +#else + u32 *ppix = lcd_console_address + + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows; + u32 i; + for (i = 0; + i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix); + i++) { + *ppix++ = bg_color; + } +#endif + lcd_sync(); + console_curr_row -= rows; +} + +static inline void console_back(void) +{ + if (--console_curr_col < 0) { + console_curr_col = console_cols - 1; + if (--console_curr_row < 0) + console_curr_row = 0; + } + + lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH, + console_curr_row * VIDEO_FONT_HEIGHT, ' '); +} + +static inline void console_newline(void) +{ + console_curr_col = 0; + + /* Check if we need to scroll the terminal */ + if (++console_curr_row >= console_rows) + console_scrollup(); + else + lcd_sync(); +} + +void lcd_putc(const char c) +{ + if (!lcd_is_enabled) { + serial_putc(c); + + return; + } + + switch (c) { + case '\r': + console_curr_col = 0; + + return; + case '\n': + console_newline(); + + return; + case '\t': /* Tab (8 chars alignment) */ + console_curr_col += 8; + console_curr_col &= ~7; + + if (console_curr_col >= console_cols) + console_newline(); + + return; + case '\b': + console_back(); + + return; + default: + lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH, + console_curr_row * VIDEO_FONT_HEIGHT, c); + if (++console_curr_col >= console_cols) + console_newline(); + } +} + +void lcd_puts(const char *s) +{ + if (!lcd_is_enabled) { + serial_puts(s); + + return; + } + + while (*s) + lcd_putc(*s++); + + lcd_sync(); +} + +void lcd_printf(const char *fmt, ...) +{ + va_list args; + char buf[CONFIG_SYS_PBSIZE]; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + + lcd_puts(buf); +} diff --git a/common/memsize.c b/common/memsize.c index 589400d3b1..0fb9ba57b6 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -33,43 +33,46 @@ long get_ram_size(long *base, long maxsize) long size; int i = 0; - for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { + for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { addr = base + cnt; /* pointer arith! */ - sync (); + sync(); save[i++] = *addr; - sync (); + sync(); *addr = ~cnt; } addr = base; - sync (); + sync(); save[i] = *addr; - sync (); + sync(); *addr = 0; - sync (); + sync(); if ((val = *addr) != 0) { - /* Restore the original data before leaving the function. - */ - sync (); + /* Restore the original data before leaving the function. */ + sync(); *addr = save[i]; for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; - sync (); + sync(); *addr = save[--i]; } return (0); } - for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { + for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ val = *addr; *addr = save[--i]; if (val != ~cnt) { - size = cnt * sizeof (long); - /* Restore the original data before leaving the function. + size = cnt * sizeof(long); + /* + * Restore the original data + * before leaving the function. */ - for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) { + for (cnt <<= 1; + cnt < maxsize / sizeof(long); + cnt <<= 1) { addr = base + cnt; *addr = save[--i]; } diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index b444a3ea2b..2c0e8e00dd 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -15,37 +15,51 @@ void spl_nor_load_image(void) */ spl_image.flags |= SPL_COPY_PAYLOAD_ONLY; - if (spl_start_uboot()) { - /* - * Load real U-Boot from its location in NOR flash to its - * defined location in SDRAM - */ - spl_parse_image_header( - (const struct image_header *)CONFIG_SYS_UBOOT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_start_uboot()) { + struct image_header *header; - memcpy((void *)spl_image.load_addr, - (void *)(CONFIG_SYS_UBOOT_BASE + - sizeof(struct image_header)), - spl_image.size); - } else { /* * Load Linux from its location in NOR flash to its defined * location in SDRAM */ - spl_parse_image_header( - (const struct image_header *)CONFIG_SYS_OS_BASE); + header = (const struct image_header *)CONFIG_SYS_OS_BASE; - memcpy((void *)spl_image.load_addr, - (void *)(CONFIG_SYS_OS_BASE + - sizeof(struct image_header)), - spl_image.size); + if (image_get_os(header) == IH_OS_LINUX) { + /* happy - was a Linux */ - /* - * Copy DT blob (fdt) to SDRAM. Passing pointer to flash - * doesn't work (16 KiB should be enough for DT) - */ - memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, - (void *)(CONFIG_SYS_FDT_BASE), - (16 << 10)); + spl_parse_image_header(header); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_OS_BASE + + sizeof(struct image_header)), + spl_image.size); + + /* + * Copy DT blob (fdt) to SDRAM. Passing pointer to + * flash doesn't work (16 KiB should be enough for DT) + */ + memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, + (void *)(CONFIG_SYS_FDT_BASE), + (16 << 10)); + + return; + } else { + puts("The Expected Linux image was not found.\n" + "Please check your NOR configuration.\n" + "Trying to start u-boot now...\n"); + } } +#endif + + /* + * Load real U-Boot from its location in NOR flash to its + * defined location in SDRAM + */ + spl_parse_image_header( + (const struct image_header *)CONFIG_SYS_UBOOT_BASE); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)), + spl_image.size); } |