aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig47
-rw-r--r--common/Makefile1
-rw-r--r--common/board_f.c49
-rw-r--r--common/board_r.c4
-rw-r--r--common/cli_readline.c9
-rw-r--r--common/console.c66
-rw-r--r--common/cyclic.c139
-rw-r--r--common/dfu.c2
-rw-r--r--common/lcd.c10
-rw-r--r--common/memsize.c20
-rw-r--r--common/menu.c15
-rw-r--r--common/spl/Kconfig3
-rw-r--r--common/spl/spl.c21
-rw-r--r--common/spl/spl_fit.c8
-rw-r--r--common/spl/spl_sata.c2
-rw-r--r--common/spl/spl_usb.c2
-rw-r--r--common/stdio.c8
-rw-r--r--common/usb_kbd.c2
-rw-r--r--common/usb_storage.c10
-rw-r--r--common/xyzModem.c42
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;