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_mmc.c | 205 | ||||
-rw-r--r-- | common/cmd_sandbox.c | 2 | ||||
-rw-r--r-- | common/cmd_usb.c | 48 | ||||
-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 | ||||
-rw-r--r-- | common/usb.c | 11 | ||||
-rw-r--r-- | common/usb_kbd.c | 10 |
17 files changed, 738 insertions, 418 deletions
diff --git a/common/Makefile b/common/Makefile index c668a2f..94554f2 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 cfd77f8..3a4b32c 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 6b3ea8c..e2dc164 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 5be4467..72477f0 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_mmc.c b/common/cmd_mmc.c index 96478e4..4e28c9d 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -73,6 +73,8 @@ U_BOOT_CMD( static void print_mmcinfo(struct mmc *mmc) { + int i; + printf("Device: %s\n", mmc->cfg->name); printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24); printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff); @@ -92,6 +94,48 @@ static void print_mmcinfo(struct mmc *mmc) printf("Bus Width: %d-bit%s\n", mmc->bus_width, mmc->ddr_mode ? " DDR" : ""); + + puts("Erase Group Size: "); + print_size(((u64)mmc->erase_grp_size) << 9, "\n"); + + if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) { + bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0; + bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR); + + puts("HC WP Group Size: "); + print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n"); + + puts("User Capacity: "); + print_size(mmc->capacity_user, usr_enh ? " ENH" : ""); + if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR) + puts(" WRREL\n"); + else + putc('\n'); + if (usr_enh) { + puts("User Enhanced Start: "); + print_size(mmc->enh_user_start, "\n"); + puts("User Enhanced Size: "); + print_size(mmc->enh_user_size, "\n"); + } + puts("Boot Capacity: "); + print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n"); + puts("RPMB Capacity: "); + print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n"); + + for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) { + bool is_enh = has_enh && + (mmc->part_attr & EXT_CSD_ENH_GP(i)); + if (mmc->capacity_gp[i]) { + printf("GP%i Capacity: ", i+1); + print_size(mmc->capacity_gp[i], + is_enh ? " ENH" : ""); + if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i)) + puts(" WRREL\n"); + else + putc('\n'); + } + } + } } static struct mmc *init_mmc_device(int dev, bool force_init) { @@ -444,6 +488,157 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag, print_mmc_devices('\n'); return CMD_RET_SUCCESS; } + +static int parse_hwpart_user(struct mmc_hwpart_conf *pconf, + int argc, char * const argv[]) +{ + int i = 0; + + memset(&pconf->user, 0, sizeof(pconf->user)); + + while (i < argc) { + if (!strcmp(argv[i], "enh")) { + if (i + 2 >= argc) + return -1; + pconf->user.enh_start = + simple_strtoul(argv[i+1], NULL, 10); + pconf->user.enh_size = + simple_strtoul(argv[i+2], NULL, 10); + i += 3; + } else if (!strcmp(argv[i], "wrrel")) { + if (i + 1 >= argc) + return -1; + pconf->user.wr_rel_change = 1; + if (!strcmp(argv[i+1], "on")) + pconf->user.wr_rel_set = 1; + else if (!strcmp(argv[i+1], "off")) + pconf->user.wr_rel_set = 0; + else + return -1; + i += 2; + } else { + break; + } + } + return i; +} + +static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx, + int argc, char * const argv[]) +{ + int i; + + memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx])); + + if (1 >= argc) + return -1; + pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10); + + i = 1; + while (i < argc) { + if (!strcmp(argv[i], "enh")) { + pconf->gp_part[pidx].enhanced = 1; + i += 1; + } else if (!strcmp(argv[i], "wrrel")) { + if (i + 1 >= argc) + return -1; + pconf->gp_part[pidx].wr_rel_change = 1; + if (!strcmp(argv[i+1], "on")) + pconf->gp_part[pidx].wr_rel_set = 1; + else if (!strcmp(argv[i+1], "off")) + pconf->gp_part[pidx].wr_rel_set = 0; + else + return -1; + i += 2; + } else { + break; + } + } + return i; +} + +static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct mmc *mmc; + struct mmc_hwpart_conf pconf = { }; + enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK; + int i, r, pidx; + + mmc = init_mmc_device(curr_device, false); + if (!mmc) + return CMD_RET_FAILURE; + + if (argc < 1) + return CMD_RET_USAGE; + i = 1; + while (i < argc) { + if (!strcmp(argv[i], "user")) { + i++; + r = parse_hwpart_user(&pconf, argc-i, &argv[i]); + if (r < 0) + return CMD_RET_USAGE; + i += r; + } else if (!strncmp(argv[i], "gp", 2) && + strlen(argv[i]) == 3 && + argv[i][2] >= '1' && argv[i][2] <= '4') { + pidx = argv[i][2] - '1'; + i++; + r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]); + if (r < 0) + return CMD_RET_USAGE; + i += r; + } else if (!strcmp(argv[i], "check")) { + mode = MMC_HWPART_CONF_CHECK; + i++; + } else if (!strcmp(argv[i], "set")) { + mode = MMC_HWPART_CONF_SET; + i++; + } else if (!strcmp(argv[i], "complete")) { + mode = MMC_HWPART_CONF_COMPLETE; + i++; + } else { + return CMD_RET_USAGE; + } + } + + puts("Partition configuration:\n"); + if (pconf.user.enh_size) { + puts("\tUser Enhanced Start: "); + print_size(((u64)pconf.user.enh_start) << 9, "\n"); + puts("\tUser Enhanced Size: "); + print_size(((u64)pconf.user.enh_size) << 9, "\n"); + } else { + puts("\tNo enhanced user data area\n"); + } + if (pconf.user.wr_rel_change) + printf("\tUser partition write reliability: %s\n", + pconf.user.wr_rel_set ? "on" : "off"); + for (pidx = 0; pidx < 4; pidx++) { + if (pconf.gp_part[pidx].size) { + printf("\tGP%i Capacity: ", pidx+1); + print_size(((u64)pconf.gp_part[pidx].size) << 9, + pconf.gp_part[pidx].enhanced ? + " ENH\n" : "\n"); + } else { + printf("\tNo GP%i partition\n", pidx+1); + } + if (pconf.gp_part[pidx].wr_rel_change) + printf("\tGP%i write reliability: %s\n", pidx+1, + pconf.gp_part[pidx].wr_rel_set ? "on" : "off"); + } + + if (!mmc_hwpart_config(mmc, &pconf, mode)) { + if (mode == MMC_HWPART_CONF_COMPLETE) + puts("Partitioning successful, " + "power-cycle to make effective\n"); + return CMD_RET_SUCCESS; + } else { + puts("Failed!\n"); + return CMD_RET_FAILURE; + } +} + #ifdef CONFIG_SUPPORT_EMMC_BOOT static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -601,6 +796,7 @@ static cmd_tbl_t cmd_mmc[] = { U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""), U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""), U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""), + U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""), #ifdef CONFIG_SUPPORT_EMMC_BOOT U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""), U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""), @@ -640,7 +836,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - mmc, 7, 1, do_mmcops, + mmc, 29, 1, do_mmcops, "MMC sub system", "info - display info of the current MMC device\n" "mmc read addr blk# cnt\n" @@ -650,6 +846,13 @@ U_BOOT_CMD( "mmc part - lists available partition on current mmc device\n" "mmc dev [dev] [part] - show or set current mmc device [partition]\n" "mmc list - lists available devices\n" + "mmc hwpartition [args...] - does hardware partitioning\n" + " arguments (sizes in 512-byte blocks):\n" + " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n" + " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n" + " [check|set|complete] - mode, complete set partitioning completed\n" + " WARNING: Partitioning is a write-once setting once it is set to complete.\n" + " Power cycling is required to initialize partitions after set to complete.\n" #ifdef CONFIG_SUPPORT_EMMC_BOOT "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n" " - Set the BOOT_BUS_WIDTH field of the specified device\n" diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 3d9fce7..4286969 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/cmd_usb.c b/common/cmd_usb.c index c192498..27813f0 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -441,6 +441,26 @@ static int do_usb_stop_keyboard(int force) return 0; } +static void do_usb_start(void) +{ + bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); + + if (usb_init() < 0) + return; + +#ifdef CONFIG_USB_STORAGE + /* try to recognize storage devices immediately */ + usb_stor_curr_dev = usb_stor_scan(1); +#endif +#ifdef CONFIG_USB_HOST_ETHER + /* try to recognize ethernet devices immediately */ + usb_ether_curr_dev = usb_host_eth_scan(1); +#endif +#ifdef CONFIG_USB_KEYBOARD + drv_usb_kbd_init(); +#endif +} + /****************************************************************************** * usb command intepreter */ @@ -457,26 +477,20 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 2) return CMD_RET_USAGE; - if ((strncmp(argv[1], "reset", 5) == 0) || - (strncmp(argv[1], "start", 5) == 0)) { - bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start"); + if (strncmp(argv[1], "start", 5) == 0) { + if (usb_started) + return 0; /* Already started */ + printf("starting USB...\n"); + do_usb_start(); + return 0; + } + + if (strncmp(argv[1], "reset", 5) == 0) { + printf("resetting USB...\n"); if (do_usb_stop_keyboard(1) != 0) return 1; usb_stop(); - printf("(Re)start USB...\n"); - if (usb_init() >= 0) { -#ifdef CONFIG_USB_STORAGE - /* try to recognize storage devices immediately */ - usb_stor_curr_dev = usb_stor_scan(1); -#endif -#ifdef CONFIG_USB_HOST_ETHER - /* try to recognize ethernet devices immediately */ - usb_ether_curr_dev = usb_host_eth_scan(1); -#endif -#ifdef CONFIG_USB_KEYBOARD - drv_usb_kbd_init(); -#endif - } + do_usb_start(); return 0; } if (strncmp(argv[1], "stop", 4) == 0) { diff --git a/common/console.c b/common/console.c index 29560c3..fc1963b 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 e66108f..df797fc 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 4ffc5aa..1589ee3 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 e691a51..ad7a46d 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 3ed504d..cc34b8a 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 0000000..74c388a --- /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 589400d..0fb9ba5 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 b444a3e..2c0e8e0 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); } diff --git a/common/usb.c b/common/usb.c index 736cd9f..32e15cd 100644 --- a/common/usb.c +++ b/common/usb.c @@ -59,6 +59,7 @@ int usb_init(void) void *ctrl; struct usb_device *dev; int i, start_index = 0; + int controllers_initialized = 0; int ret; dev_index = 0; @@ -78,6 +79,7 @@ int usb_init(void) ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl); if (ret == -ENODEV) { /* No such device. */ puts("Port not available.\n"); + controllers_initialized++; continue; } @@ -89,6 +91,7 @@ int usb_init(void) * lowlevel init is OK, now scan the bus for devices * i.e. search HUBs and configure them */ + controllers_initialized++; start_index = dev_index; printf("scanning bus %d for devices... ", i); dev = usb_alloc_new_device(ctrl); @@ -110,12 +113,10 @@ int usb_init(void) debug("scan end\n"); /* if we were not able to find at least one working bus, bail out */ - if (!usb_started) { + if (controllers_initialized == 0) puts("USB error: all controllers failed lowlevel init\n"); - return -1; - } - return 0; + return usb_started ? 0 : -1; } /****************************************************************************** @@ -969,6 +970,8 @@ int usb_new_device(struct usb_device *dev) printf("\n Couldn't reset port %i\n", dev->portnr); return 1; } + } else { + usb_reset_root_port(); } #endif diff --git a/common/usb_kbd.c b/common/usb_kbd.c index bc7145e..ecc3085 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -332,7 +332,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) /* We've consumed all queued int packets, create new */ destroy_int_queue(dev, data->intq); data->intq = create_int_queue(dev, data->intpipe, 1, - USB_KBD_BOOT_REPORT_SIZE, data->new); + USB_KBD_BOOT_REPORT_SIZE, data->new, + data->intinterval); } #endif } @@ -453,7 +454,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) debug("USB KBD: enable interrupt pipe...\n"); #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE data->intq = create_int_queue(dev, data->intpipe, 1, - USB_KBD_BOOT_REPORT_SIZE, data->new); + USB_KBD_BOOT_REPORT_SIZE, data->new, + data->intinterval); if (!data->intq) { #else if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize, @@ -542,6 +544,10 @@ int usb_kbd_deregister(int force) data = usb_kbd_dev->privptr; if (stdio_deregister_dev(dev, force) != 0) return 1; +#ifdef CONFIG_CONSOLE_MUX + if (iomux_doenv(stdin, getenv("stdin")) != 0) + return 1; +#endif #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE destroy_int_queue(usb_kbd_dev, data->intq); #endif |