diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 47 | ||||
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/board_f.c | 49 | ||||
-rw-r--r-- | common/board_r.c | 4 | ||||
-rw-r--r-- | common/cli_readline.c | 9 | ||||
-rw-r--r-- | common/console.c | 66 | ||||
-rw-r--r-- | common/cyclic.c | 139 | ||||
-rw-r--r-- | common/dfu.c | 2 | ||||
-rw-r--r-- | common/lcd.c | 10 | ||||
-rw-r--r-- | common/memsize.c | 20 | ||||
-rw-r--r-- | common/menu.c | 15 | ||||
-rw-r--r-- | common/spl/Kconfig | 3 | ||||
-rw-r--r-- | common/spl/spl.c | 21 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 8 | ||||
-rw-r--r-- | common/spl/spl_sata.c | 2 | ||||
-rw-r--r-- | common/spl/spl_usb.c | 2 | ||||
-rw-r--r-- | common/stdio.c | 8 | ||||
-rw-r--r-- | common/usb_kbd.c | 2 | ||||
-rw-r--r-- | common/usb_storage.c | 10 | ||||
-rw-r--r-- | common/xyzModem.c | 42 |
20 files changed, 421 insertions, 39 deletions
diff --git a/common/Kconfig b/common/Kconfig index ebee856e56..6591acd2fd 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -186,6 +186,12 @@ config PRE_CON_BUF_ADDR We should consider removing this option and allocating the memory in board_init_f_init_reserve() instead. +config CONSOLE_FLUSH_SUPPORT + bool "Enable console flush support" + default y + help + This enables compilation of flush() function for console flush support. + config CONSOLE_MUX bool "Enable console multiplexing" default y if DM_VIDEO || VIDEO || LCD @@ -545,6 +551,26 @@ config DISPLAY_BOARDINFO_LATE menu "Start-up hooks" +config CYCLIC + bool "General-purpose cyclic execution mechanism" + help + This enables a general-purpose cyclic execution infrastructure, + to allow "small" (run-time wise) functions to be executed at + a specified frequency. Things like LED blinking or watchdog + triggering are examples for such tasks. + +if CYCLIC + +config CYCLIC_MAX_CPU_TIME_US + int "Sets the max allowed time for a cyclic function in us" + default 1000 + help + The max allowed time for a cyclic function in us. If a functions + takes longer than this duration this function will get unregistered + automatically. + +endif # CYCLIC + config EVENT bool "General-purpose event-handling mechanism" default y if SANDBOX @@ -671,6 +697,27 @@ config ID_EEPROM A number of different systems and vendors enable a vendor-specified EEPROM that contains various identifying features. +config SYS_EEPROM_BUS_NUM + int "I2C bus number of the system identifier EEPROM" + depends on ID_EEPROM + default 0 + +choice + prompt "EEPROM starts with 'CCID' or 'NXID'" + depends on ID_EEPROM && (PPC || ARCH_LS1021A || FSL_LAYERSCAPE) + default SYS_I2C_EEPROM_NXID + help + Specify if the Freescale / NXP ID EEPROM starts with 'CCID' or 'NXID' + ASCII literal string. + +config SYS_I2C_EEPROM_CCID + bool "EEPROM starts with 'CCID'" + +config SYS_I2C_EEPROM_NXID + bool "EEPROM starts with 'NXID'" + +endchoice + config PCI_INIT_R bool "Enumerate PCI buses during init" depends on PCI diff --git a/common/Makefile b/common/Makefile index 2ed8672c3a..1d56c9f289 100644 --- a/common/Makefile +++ b/common/Makefile @@ -84,6 +84,7 @@ obj-y += malloc_simple.o endif endif +obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o diff --git a/common/board_f.c b/common/board_f.c index 18e2246733..3df4efeeff 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -16,6 +16,7 @@ #include <console.h> #include <cpu.h> #include <cpu_func.h> +#include <cyclic.h> #include <display_options.h> #include <dm.h> #include <env.h> @@ -56,6 +57,7 @@ #include <asm/sections.h> #include <dm/root.h> #include <linux/errno.h> +#include <linux/log2.h> /* * Pointer to initial global data area @@ -113,14 +115,14 @@ static int init_func_watchdog_init(void) hw_watchdog_init(); puts(" Watchdog enabled\n"); # endif - WATCHDOG_RESET(); + schedule(); return 0; } int init_func_watchdog_reset(void) { - WATCHDOG_RESET(); + schedule(); return 0; } @@ -215,6 +217,36 @@ static int announce_dram_init(void) return 0; } +/* + * From input size calculate its nearest rounded unit scale (multiply of 2^10) + * and value in calculated unit scale multiplied by 10 (as fractional fixed + * point number with one decimal digit), which is human natural format, + * same what uses print_size() function for displaying. Mathematically it is: + * round_nearest(val * 2^scale) = size * 10; where: 10 <= val < 10240. + * + * For example for size=87654321 we calculate scale=20 and val=836 which means + * that input has natural human format 83.6 M (mega = 2^20). + */ +#define compute_size_scale_val(size, scale, val) do { \ + scale = ilog2(size) / 10 * 10; \ + val = (10 * size + ((1ULL << scale) >> 1)) >> scale; \ + if (val == 10240) { val = 10; scale += 10; } \ +} while (0) + +/* + * Check if the sizes in their natural units written in decimal format with + * one fraction number are same. + */ +static int sizes_near(unsigned long long size1, unsigned long long size2) +{ + unsigned int size1_scale, size1_val, size2_scale, size2_val; + + compute_size_scale_val(size1, size1_scale, size1_val); + compute_size_scale_val(size2, size2_scale, size2_val); + + return size1_scale == size2_scale && size1_val == size2_val; +} + static int show_dram_config(void) { unsigned long long size; @@ -231,7 +263,11 @@ static int show_dram_config(void) } debug("\nDRAM: "); - print_size(size, ""); + print_size(gd->ram_size, ""); + if (!sizes_near(gd->ram_size, size)) { + printf(" (effective "); + print_size(size, ")"); + } board_add_ram_info(0); putc('\n'); @@ -304,7 +340,7 @@ __weak int mach_cpu_init(void) } /* Get the top of usable RAM */ -__weak ulong board_get_usable_ram_top(ulong total_size) +__weak phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #if defined(CONFIG_SYS_SDRAM_BASE) && CONFIG_SYS_SDRAM_BASE > 0 /* @@ -327,7 +363,7 @@ static int setup_dest_addr(void) /* * Ram is setup, size stored in gd !! */ - debug("Ram size: %08lX\n", (ulong)gd->ram_size); + debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size); #if CONFIG_VAL(SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't @@ -347,7 +383,7 @@ static int setup_dest_addr(void) gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; - debug("Ram top: %08lX\n", (ulong)gd->ram_top); + debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top); #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core @@ -828,6 +864,7 @@ static const init_fnc_t init_sequence_f[] = { initf_malloc, log_init, initf_bootstage, /* uses its own timer, so does not need DM */ + cyclic_init, event_init, #ifdef CONFIG_BLOBLIST bloblist_init, diff --git a/common/board_r.c b/common/board_r.c index 56eb60fa27..50670b5615 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -13,6 +13,7 @@ #include <api.h> #include <bootstage.h> #include <cpu_func.h> +#include <cyclic.h> #include <display_options.h> #include <exports.h> #ifdef CONFIG_MTD_NOR_FLASH @@ -340,7 +341,7 @@ static int initr_flash(void) /* * Compute and print flash CRC if flashchecksum is set to 'y' * - * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + * NOTE: Maybe we should add some schedule()? XXX */ if (env_get_yesno("flashchecksum") == 1) { const uchar *flash_base = (const uchar *)CONFIG_SYS_FLASH_BASE; @@ -611,6 +612,7 @@ static init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + cyclic_init, log_init, initr_bootstage, /* Needs malloc() but has its own timer */ #if defined(CONFIG_CONSOLE_RECORD) diff --git a/common/cli_readline.c b/common/cli_readline.c index e86ee73faf..f6e2bcdece 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -72,8 +72,13 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) #define getcmd_getch() getchar() #define getcmd_cbeep() getcmd_putch('\a') +#ifdef CONFIG_SPL_BUILD +#define HIST_MAX 3 +#define HIST_SIZE 32 +#else #define HIST_MAX 20 #define HIST_SIZE CONFIG_SYS_CBSIZE +#endif static int hist_max; static int hist_add_idx; @@ -269,7 +274,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, while (!tstc()) { /* while no incoming data */ if (get_ticks() >= etime) return -2; /* timed out */ - WATCHDOG_RESET(); + schedule(); } first = 0; } @@ -590,7 +595,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, for (;;) { if (bootretry_tstc_timeout()) return -2; /* timed out */ - WATCHDOG_RESET(); /* Trigger watchdog, if needed */ + schedule(); /* Trigger watchdog, if needed */ c = getchar(); diff --git a/common/console.c b/common/console.c index e783f309bf..0c9bf66c3f 100644 --- a/common/console.c +++ b/common/console.c @@ -199,6 +199,7 @@ static int console_setfile(int file, struct stdio_dev * dev) case stdout: gd->jt->putc = putc; gd->jt->puts = puts; + STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush); gd->jt->printf = printf; break; } @@ -364,6 +365,19 @@ static void console_puts(int file, const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void console_flush(int file) +{ + int i; + struct stdio_dev *dev; + + for_each_console_dev(i, file, dev) { + if (dev->flush != NULL) + dev->flush(dev); + } +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -413,6 +427,14 @@ static inline void console_puts(int file, const char *s) stdio_devices[file]->puts(stdio_devices[file], s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static inline void console_flush(int file) +{ + if (stdio_devices[file]->flush) + stdio_devices[file]->flush(stdio_devices[file]); +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -480,7 +502,7 @@ int fgetc(int file) * Effectively poll for input wherever it may be available. */ for (;;) { - WATCHDOG_RESET(); + schedule(); if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { /* * Upper layer may have already called tstc() so @@ -526,6 +548,14 @@ void fputs(int file, const char *s) console_puts(file, s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file) +{ + if (file < MAX_FILES) + console_flush(file); +} +#endif + int fprintf(int file, const char *fmt, ...) { va_list args; @@ -740,6 +770,40 @@ void puts(const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void) +{ + if (!gd) + return; + + /* sandbox can send characters to stdout before it has a console */ + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { + os_flush(); + return; + } + + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) + return; + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) + return; + + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) + return; + + if (!gd->have_console) + return; + + if (gd->flags & GD_FLG_DEVINIT) { + /* Send to the standard output */ + fflush(stdout); + } else { + /* Send directly to the handler */ + serial_flush(); + } +} +#endif + #ifdef CONFIG_CONSOLE_RECORD int console_record_init(void) { diff --git a/common/cyclic.c b/common/cyclic.c new file mode 100644 index 0000000000..b3c180bd1a --- /dev/null +++ b/common/cyclic.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese <sr@denx.de> + */ + +#include <cyclic.h> +#include <log.h> +#include <malloc.h> +#include <time.h> +#include <linux/errno.h> +#include <linux/list.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +void hw_watchdog_reset(void); + +struct list_head *cyclic_get_list(void) +{ + return &gd->cyclic->cyclic_list; +} + +struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, + const char *name, void *ctx) +{ + struct cyclic_info *cyclic; + + if (!gd->cyclic->cyclic_ready) { + pr_debug("Cyclic IF not ready yet\n"); + return NULL; + } + + cyclic = calloc(1, sizeof(struct cyclic_info)); + if (!cyclic) { + pr_debug("Memory allocation error\n"); + return NULL; + } + + /* Store values in struct */ + cyclic->func = func; + cyclic->ctx = ctx; + cyclic->name = strdup(name); + cyclic->delay_us = delay_us; + cyclic->start_time_us = timer_get_us(); + list_add_tail(&cyclic->list, &gd->cyclic->cyclic_list); + + return cyclic; +} + +int cyclic_unregister(struct cyclic_info *cyclic) +{ + list_del(&cyclic->list); + free(cyclic); + + return 0; +} + +void cyclic_run(void) +{ + struct cyclic_info *cyclic, *tmp; + uint64_t now, cpu_time; + + /* Prevent recursion */ + if (gd->cyclic->cyclic_running) + return; + + gd->cyclic->cyclic_running = true; + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) { + /* + * Check if this cyclic function needs to get called, e.g. + * do not call the cyclic func too often + */ + now = timer_get_us(); + if (time_after_eq64(now, cyclic->next_call)) { + /* Call cyclic function and account it's cpu-time */ + cyclic->next_call = now + cyclic->delay_us; + cyclic->func(cyclic->ctx); + cyclic->run_cnt++; + cpu_time = timer_get_us() - now; + cyclic->cpu_time_us += cpu_time; + + /* Check if cpu-time exceeds max allowed time */ + if (cpu_time > CONFIG_CYCLIC_MAX_CPU_TIME_US) { + pr_err("cyclic function %s took too long: %lldus vs %dus max, disabling\n", + cyclic->name, cpu_time, + CONFIG_CYCLIC_MAX_CPU_TIME_US); + + /* Unregister this cyclic function */ + cyclic_unregister(cyclic); + } + } + } + gd->cyclic->cyclic_running = false; +} + +void schedule(void) +{ + /* The HW watchdog is not integrated into the cyclic IF (yet) */ + if (IS_ENABLED(CONFIG_HW_WATCHDOG)) + hw_watchdog_reset(); + + /* + * schedule() might get called very early before the cyclic IF is + * ready. Make sure to only call cyclic_run() when it's initalized. + */ + if (gd && gd->cyclic && gd->cyclic->cyclic_ready) + cyclic_run(); +} + +int cyclic_uninit(void) +{ + struct cyclic_info *cyclic, *tmp; + + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) + cyclic_unregister(cyclic); + gd->cyclic->cyclic_ready = false; + + return 0; +} + +int cyclic_init(void) +{ + int size = sizeof(struct cyclic_drv); + + gd->cyclic = (struct cyclic_drv *)malloc(size); + if (!gd->cyclic) + return -ENOMEM; + + memset(gd->cyclic, '\0', size); + INIT_LIST_HEAD(&gd->cyclic->cyclic_list); + gd->cyclic->cyclic_ready = true; + + return 0; +} diff --git a/common/dfu.c b/common/dfu.c index 16bd1ba588..96190889ab 100644 --- a/common/dfu.c +++ b/common/dfu.c @@ -101,7 +101,7 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) if (dfu_reinit_needed) goto exit; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(usbctrl_index); } exit: diff --git a/common/lcd.c b/common/lcd.c index 0898bc025d..a462b22a47 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -294,9 +294,9 @@ void lcd_logo_plot(int x, int y) BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); if (bpix < 12) { - WATCHDOG_RESET(); + schedule(); lcd_logo_set_cmap(); - WATCHDOG_RESET(); + schedule(); for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { memcpy(fb, bmap, BMP_LOGO_WIDTH); @@ -320,7 +320,7 @@ void lcd_logo_plot(int x, int y) } } - WATCHDOG_RESET(); + schedule(); lcd_sync(); } #else @@ -459,7 +459,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) byte_width = width * 2; for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { if (bpix != 16) { fb_put_byte(&fb, &bmap); @@ -488,7 +488,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if defined(CONFIG_BMP_16BPP) case 16: for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) fb_put_word(&fb, &bmap); diff --git a/common/memsize.c b/common/memsize.c index d5d13d51bf..3c80ad2c83 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -94,11 +94,23 @@ long get_ram_size(long *base, long maxsize) phys_size_t __weak get_effective_memsize(void) { -#ifndef CONFIG_VERY_BIG_RAM - return gd->ram_size; + phys_size_t ram_size = gd->ram_size; + + /* + * Check for overflow and limit ram size to some representable value. + * It is required that ram_base + ram_size must be representable by + * phys_size_t type and must be aligned by direct access, therefore + * calculate it from last 4kB sector which should work as alignment + * on any platform. + */ + if (gd->ram_base + ram_size < gd->ram_base) + ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base; + +#ifndef CONFIG_MAX_MEM_MAPPED + return ram_size; #else /* limit stack to what we can reasonable map */ - return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? - CONFIG_MAX_MEM_MAPPED : gd->ram_size); + return ((ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : ram_size); #endif } diff --git a/common/menu.c b/common/menu.c index 3e876b55b3..8fe00965c0 100644 --- a/common/menu.c +++ b/common/menu.c @@ -435,7 +435,7 @@ void bootmenu_autoboot_loop(struct bootmenu_data *menu, printf("Hit any key to stop autoboot: %d ", menu->delay); for (i = 0; i < 100; ++i) { if (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); continue; } @@ -483,7 +483,7 @@ void bootmenu_loop(struct bootmenu_data *menu, if (tstc()) { c = getchar(); } else { - WATCHDOG_RESET(); + schedule(); mdelay(10); if (tstc()) c = getchar(); @@ -492,7 +492,7 @@ void bootmenu_loop(struct bootmenu_data *menu, } } else { while (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); } c = getchar(); @@ -548,4 +548,13 @@ void bootmenu_loop(struct bootmenu_data *menu, /* ^C was pressed */ if (c == 0x3) *key = KEY_QUIT; + + if (c == '+') + *key = KEY_PLUS; + + if (c == '-') + *key = KEY_MINUS; + + if (c == ' ') + *key = KEY_SPACE; } diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 70d97815f0..f2422d28f9 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -40,6 +40,7 @@ config SPL_SIZE_LIMIT hex "Maximum size of SPL image" default 0x11000 if ARCH_MX6 && !MX6_OCRAM_256KB default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB + default 0x30000 if ARCH_MVEBU && ARMADA_32BIT default 0x0 help Specifies the maximum length of the U-Boot SPL image. @@ -792,7 +793,6 @@ config SPL_DM_MAILBOX config SPL_MMC bool "Support MMC" depends on MMC - select HAVE_BLOCK_DEVICE help Enable support for MMC (Multimedia Card) within SPL. This enables the MMC protocol implementation and allows any enabled drivers to @@ -1318,7 +1318,6 @@ config SPL_THERMAL config SPL_USB_HOST bool "Support USB host drivers" - select HAVE_BLOCK_DEVICE help Enable access to USB (Universal Serial Bus) host devices so that SPL can load U-Boot from a connected USB peripheral, such as a USB diff --git a/common/spl/spl.c b/common/spl/spl.c index 29e0898f03..828f72f30b 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -116,6 +116,11 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) { return 1; } + +int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc) +{ + return 1; +} #endif /* Weak default function for arch/board-specific fixups to the spl_image_info */ @@ -391,6 +396,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image, #endif #if CONFIG_IS_ENABLED(OS_BOOT) +#if defined(CMD_BOOTI) + ulong start, size; + + if (!booti_setup((ulong)header, &start, &size, 0)) { + spl_image->name = "Linux"; + spl_image->os = IH_OS_LINUX; + spl_image->load_addr = start; + spl_image->entry_point = start; + spl_image->size = size; + debug(SPL_TPL_PROMPT + "payload Image, load addr: 0x%lx size: %d\n", + spl_image->load_addr, spl_image->size); + return 0; + } +#elif defined(CMD_BOOTZ) ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { @@ -405,6 +425,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image, return 0; } #endif +#endif if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header))) return 0; diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index a35be52965..c1ed31e367 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -10,7 +10,7 @@ #include <gzip.h> #include <image.h> #include <log.h> -#include <malloc.h> +#include <memalign.h> #include <mapmem.h> #include <spl.h> #include <sysinfo.h> @@ -429,7 +429,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, * depending on how the overlay is stored, so * don't fail yet if the allocation failed. */ - tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ); + size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ; + + tmpbuffer = malloc_cache_aligned(size); if (!tmpbuffer) debug("%s: unable to allocate space for overlays\n", __func__); @@ -537,7 +539,7 @@ static void *spl_get_fit_load_buffer(size_t size) { void *buf; - buf = malloc(size); + buf = malloc_cache_aligned(size); if (!buf) { pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size); pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n"); diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 1351d78612..6c36f2ca66 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -71,7 +71,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ scsi_scan(false); - stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0); if (!stor_dev) return -ENODEV; diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c index ccf01c8276..479e2dc182 100644 --- a/common/spl/spl_usb.c +++ b/common/spl/spl_usb.c @@ -41,7 +41,7 @@ int spl_usb_load(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev); if (!stor_dev) return -ENODEV; diff --git a/common/stdio.c b/common/stdio.c index 92161a0df8..13083842cb 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -87,6 +87,13 @@ static void stdio_serial_puts(struct stdio_dev *dev, const char *s) serial_puts(s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void stdio_serial_flush(struct stdio_dev *dev) +{ + serial_flush(); +} +#endif + static int stdio_serial_getc(struct stdio_dev *dev) { return serial_getc(); @@ -112,6 +119,7 @@ static void drv_system_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.putc = stdio_serial_putc; dev.puts = stdio_serial_puts; + STDIO_DEV_ASSIGN_FLUSH(&dev, stdio_serial_flush); dev.getc = stdio_serial_getc; dev.tstc = stdio_serial_tstc; stdio_register (&dev); diff --git a/common/usb_kbd.c b/common/usb_kbd.c index d385bea532..4cbc9acb73 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -446,7 +446,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev) data = usb_kbd_dev->privptr; while (data->usb_in_pointer == data->usb_out_pointer) { - WATCHDOG_RESET(); + schedule(); usb_kbd_poll_for_event(usb_kbd_dev); } diff --git a/common/usb_storage.c b/common/usb_storage.c index eaa31374ef..e59c819bac 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -144,7 +144,7 @@ int usb_stor_info(void) #if CONFIG_IS_ENABLED(BLK) struct udevice *dev; - for (blk_first_device(IF_TYPE_USB, &dev); + for (blk_first_device(UCLASS_USB, &dev); dev; blk_next_device(&dev)) { struct blk_desc *desc = dev_get_uclass_plat(dev); @@ -219,7 +219,7 @@ static int usb_stor_probe_device(struct usb_device *udev) snprintf(str, sizeof(str), "lun%d", lun); ret = blk_create_devicef(udev->dev, "usb_storage_blk", str, - IF_TYPE_USB, usb_max_devs, 512, 0, + UCLASS_USB, usb_max_devs, 512, 0, &dev); if (ret) { debug("Cannot bind driver\n"); @@ -279,7 +279,7 @@ static int usb_stor_probe_device(struct usb_device *udev) blkdev = &usb_dev_desc[usb_max_devs]; memset(blkdev, '\0', sizeof(struct blk_desc)); - blkdev->if_type = IF_TYPE_USB; + blkdev->uclass_id = UCLASS_USB; blkdev->devnum = usb_max_devs; blkdev->part_type = PART_TYPE_UNKNOWN; blkdev->target = 0xff; @@ -1577,8 +1577,8 @@ U_BOOT_DRIVER(usb_storage_blk) = { }; #else U_BOOT_LEGACY_BLK(usb) = { - .if_typename = "usb", - .if_type = IF_TYPE_USB, + .uclass_idname = "usb", + .uclass_id = UCLASS_USB, .max_devs = USB_MAX_STOR_DEV, .desc = usb_dev_desc, }; diff --git a/common/xyzModem.c b/common/xyzModem.c index ece25acb18..fb319f7119 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -26,6 +26,7 @@ #include <stdarg.h> #include <u-boot/crc.h> #include <watchdog.h> +#include <env.h> /* Assumption - run xyzModem protocol over the console port */ @@ -50,6 +51,8 @@ static struct int len, mode, total_retries; int total_SOH, total_STX, total_CAN; bool crc_mode, at_eof, tx_ack; + bool first_xmodem_packet; + ulong initial_time, timeout; unsigned long file_length, read_length; } xyz; @@ -65,7 +68,7 @@ CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) { ulong now = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (!tstc ()) { if (get_timer(now) > xyzModem_CHAR_TIMEOUT) @@ -409,6 +412,19 @@ xyzModem_get_hdr (void) return 0; } +static +ulong +xyzModem_get_initial_timeout (void) +{ + /* timeout is in seconds, non-positive timeout value is infinity */ +#if CONFIG_IS_ENABLED(ENV_SUPPORT) + const char *timeout_str = env_get("loadxy_timeout"); + if (timeout_str) + return 1000 * simple_strtol(timeout_str, NULL, 10); +#endif + return 1000 * CONFIG_CMD_LOADXY_TIMEOUT; +} + int xyzModem_stream_open (connection_info_t * info, int *err) { @@ -439,18 +455,28 @@ xyzModem_stream_open (connection_info_t * info, int *err) xyz.total_CAN = 0; xyz.read_length = 0; xyz.file_length = 0; + xyz.first_xmodem_packet = false; + xyz.initial_time = get_timer(0); + xyz.timeout = xyzModem_get_initial_timeout(); CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); if (xyz.mode == xyzModem_xmodem) { /* X-modem doesn't have an information header - exit here */ + xyz.first_xmodem_packet = true; xyz.next_blk = 1; return 0; } - while (retries-- > 0) + while (!(xyz.timeout && get_timer(xyz.initial_time) > xyz.timeout)) { + if (--retries <= 0) + { + retries = xyzModem_MAX_RETRIES; + crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + xyz.crc_mode = true; + } stat = xyzModem_get_hdr (); if (stat == 0) { @@ -503,9 +529,19 @@ xyzModem_stream_read (char *buf, int size, int *err) retries = xyzModem_MAX_RETRIES; while (retries-- > 0) { + if (xyz.first_xmodem_packet && xyz.timeout && + get_timer(xyz.initial_time) > xyz.timeout) + { + *err = xyzModem_timeout; + xyz.len = -1; + return total; + } + stat = xyzModem_get_hdr (); if (stat == 0) { + if (xyz.mode == xyzModem_xmodem && xyz.first_xmodem_packet) + xyz.first_xmodem_packet = false; if (xyz.blk == xyz.next_blk) { xyz.tx_ack = true; @@ -583,7 +619,7 @@ xyzModem_stream_read (char *buf, int size, int *err) xyz.total_retries++; ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); } - if (stat < 0) + if (stat < 0 && (!xyz.first_xmodem_packet || stat != xyzModem_timeout)) { *err = stat; xyz.len = -1; |