summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig10
-rw-r--r--common/autoboot.c11
-rw-r--r--common/bloblist.c209
-rw-r--r--common/board_f.c93
-rw-r--r--common/board_r.c6
-rw-r--r--common/cli.c8
-rw-r--r--common/command.c14
-rw-r--r--common/console.c12
-rw-r--r--common/cyclic.c10
-rw-r--r--common/init/handoff.c10
-rw-r--r--common/memsize.c75
-rw-r--r--common/spl/Kconfig45
-rw-r--r--common/spl/spl_fit.c98
-rw-r--r--common/spl/spl_imx_container.c13
-rw-r--r--common/splash_source.c7
-rw-r--r--common/stdio.c18
-rw-r--r--common/update.c6
-rw-r--r--common/usb_onboard_hub.c14
18 files changed, 445 insertions, 214 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 2a167ec3ad3..345be4b8ca1 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -78,7 +78,7 @@ config SYS_PBSIZE
config DISABLE_CONSOLE
bool "Add functionality to disable console completely"
help
- Disable console (in & out).
+ Disable console (in & out).
config IDENT_STRING
string "Board specific string to be added to uboot version string"
@@ -425,7 +425,7 @@ config LOGF_FUNC_PAD
config LOG_SYSLOG
bool "Log output to syslog server"
- depends on NET || NET_LWIP
+ depends on NET
help
Enables a log driver which broadcasts log records via UDP port 514
to syslog servers.
@@ -884,9 +884,9 @@ config AVB_VERIFY
help
This option enables compilation of bootloader-dependent operations,
used by Android Verified Boot 2.0 library (libavb). Includes:
- * Helpers to process strings in order to build OS bootargs.
- * Helpers to access MMC, similar to drivers/fastboot/fb_mmc.c.
- * Helpers to alloc/init/free avb ops.
+ * Helpers to process strings in order to build OS bootargs.
+ * Helpers to access MMC, similar to drivers/fastboot/fb_mmc.c.
+ * Helpers to alloc/init/free avb ops.
if AVB_VERIFY
diff --git a/common/autoboot.c b/common/autoboot.c
index 1783ef92c94..4b80ddb5b28 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -316,15 +316,6 @@ static int passwd_abort_key(uint64_t etime)
}
/**
- * flush_stdin() - drops all pending characters from stdin
- */
-static void flush_stdin(void)
-{
- while (tstc())
- (void)getchar();
-}
-
-/**
* fallback_to_sha256() - check whether we should fall back to sha256
* password checking
*
@@ -354,7 +345,7 @@ static int abortboot_key_sequence(int bootdelay)
uint64_t etime = endtick(bootdelay);
if (IS_ENABLED(CONFIG_AUTOBOOT_FLUSH_STDIN))
- flush_stdin();
+ console_flush_stdin();
# ifdef CONFIG_AUTOBOOT_PROMPT
/*
* CONFIG_AUTOBOOT_PROMPT includes the %d for all boards.
diff --git a/common/bloblist.c b/common/bloblist.c
index d5fa62249a9..846c8047f74 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -43,6 +43,7 @@ static struct tag_name {
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
{ BLOBLISTT_TPM_EVLOG, "TPM event log defined by TCG EFI" },
{ BLOBLISTT_TPM_CRB_BASE, "TPM Command Response Buffer address" },
+ { BLOBLISTT_FDT_OVERLAY, "DT overlay" },
/* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" },
@@ -96,6 +97,19 @@ static inline uint rec_tag(struct bloblist_rec *rec)
BLOBLISTR_TAG_SHIFT;
}
+static inline void void_blob(struct bloblist_rec *rec)
+{
+ if (rec_tag(rec) == BLOBLISTT_VOID)
+ return;
+ rec->tag_and_hdr_size = BLOBLISTT_VOID |
+ sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
+}
+
+static inline struct bloblist_rec *rec_from_blob(void *blob)
+{
+ return (blob - sizeof(struct bloblist_rec));
+}
+
static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr,
struct bloblist_rec *rec)
{
@@ -222,6 +236,19 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
return 0;
}
+static int bloblist_get_blob_data_offset(uint tag)
+{
+ switch (tag) {
+ case BLOBLISTT_FDT_OVERLAY:
+ return sizeof(struct dto_blob_hdr);
+ /*
+ * return the data offset if it is not following the blob
+ * header immediately.
+ */
+ }
+ return 0;
+}
+
void *bloblist_find(uint tag, int size)
{
void *blob = NULL;
@@ -248,6 +275,44 @@ void *bloblist_get_blob(uint tag, int *sizep)
return (void *)rec + rec_hdr_size(rec);
}
+int bloblist_apply_blobs(uint tag, int (*func)(void **data, int size))
+{
+ struct bloblist_hdr *hdr = gd->bloblist;
+ struct bloblist_rec *rec;
+
+ if (!func || !hdr)
+ return -ENOENT;
+
+ foreach_rec(rec, hdr) {
+ /* Apply all blobs with the specified tag */
+ if (rec_tag(rec) == tag) {
+ int ret;
+ int tag = rec_tag(rec);
+ void *blob = (void *)rec + rec_hdr_size(rec);
+ int dat_off = bloblist_get_blob_data_offset(tag);
+
+ blob += dat_off;
+ ret = func(&blob, rec->size - dat_off);
+ if (ret) {
+ log_err("Failed to apply blob with tag %d\n",
+ tag);
+ return ret;
+ }
+
+ rec = rec_from_blob(blob - dat_off);
+ if (!rec) {
+ log_err("Blob corrupted\n");
+ return -ENOENT;
+ }
+
+ /* Mark applied blob record as void */
+ void_blob(rec);
+ }
+ }
+
+ return 0;
+}
+
void *bloblist_add(uint tag, int size, int align_log2)
{
struct bloblist_rec *rec;
@@ -322,7 +387,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
next_ofs = bloblist_blob_end_ofs(hdr, rec);
if (next_ofs != hdr->used_size) {
memmove((void *)hdr + next_ofs + expand_by,
- (void *)hdr + next_ofs, new_alloced - next_ofs);
+ (void *)hdr + next_ofs, hdr->used_size - next_ofs);
}
hdr->used_size = new_alloced;
@@ -383,6 +448,7 @@ int bloblist_new(ulong addr, uint size, uint flags, uint align_log2)
hdr->align_log2 = align_log2 ? align_log2 : BLOBLIST_BLOB_ALIGN_LOG2;
hdr->chksum = 0;
gd->bloblist = hdr;
+ gd->flags |= GD_FLG_BLOBLIST_HANDOFF;
return 0;
}
@@ -410,6 +476,7 @@ int bloblist_check(ulong addr, uint size)
return log_msg_ret("Bad checksum", -EIO);
}
gd->bloblist = hdr;
+ gd->flags |= GD_FLG_BLOBLIST_HANDOFF;
return 0;
}
@@ -511,90 +578,88 @@ int __weak xferlist_from_boot_arg(ulong __always_unused *addr)
return -ENOENT;
}
-int bloblist_init(void)
+bool bloblist_exists(void)
{
- bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED);
- int ret = 0;
- ulong addr = 0, size;
+ int ret;
+ ulong addr = 0;
/* Check if a valid transfer list passed in */
- if (!xferlist_from_boot_arg(&addr)) {
- size = bloblist_get_total_size();
- } else {
- /*
- * If U-Boot is not in the first phase, an existing bloblist must
- * be at a fixed address.
- */
- bool from_addr = fixed && !xpl_is_first_phase();
-
- /*
- * If Firmware Handoff is mandatory but no transfer list is
- * observed, report it as an error.
- */
- if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
- return -ENOENT;
-
- ret = -ENOENT;
+ if (!xferlist_from_boot_arg(&addr))
+ goto found;
- if (xpl_prev_phase() == PHASE_TPL &&
- !IS_ENABLED(CONFIG_TPL_BLOBLIST))
- from_addr = false;
- if (fixed)
- addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
- CONFIG_BLOBLIST_ADDR);
- size = CONFIG_BLOBLIST_SIZE;
-
- if (from_addr)
- ret = bloblist_check(addr, size);
-
- if (ret)
- log_warning("Bloblist at %lx not found (err=%d)\n",
- addr, ret);
- else
- /* Get the real size */
- size = gd->bloblist->total_size;
- }
+ /*
+ * If Firmware Handoff is mandatory but no transfer list is
+ * observed, report it as an error.
+ */
+ if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
+ return false;
- if (ret) {
- /*
- * If we don't have a bloblist from a fixed address, or the one
- * in the fixed address is not valid. we must allocate the
- * memory for it now.
- */
- if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
- void *ptr = memalign(BLOBLIST_ALIGN, size);
+ /*
+ * We have checked for a valid transfer list being passed. At this
+ * point, if we do not have a fixed address for the bloblist, we cannot
+ * be provided with one.
+ */
+ if (xpl_is_first_phase() || !IS_ENABLED(CONFIG_BLOBLIST_FIXED))
+ return false;
- if (!ptr)
- return log_msg_ret("alloc", -ENOMEM);
- addr = map_to_sysmem(ptr);
- } else if (!fixed) {
- return log_msg_ret("BLOBLIST_FIXED is not enabled",
- ret);
- }
- log_debug("Creating new bloblist size %lx at %lx\n", size,
- addr);
- ret = bloblist_new(addr, size, 0, 0);
- } else {
- log_debug("Found existing bloblist size %lx at %lx\n", size,
- addr);
- }
+ /*
+ * Check for a valid list as the configured address.
+ */
+ addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
+ CONFIG_BLOBLIST_ADDR);
+ ret = bloblist_check(addr, CONFIG_BLOBLIST_SIZE);
+ if (!ret)
+ goto found;
- if (ret)
- return log_msg_ret("ini", ret);
- gd->flags |= GD_FLG_BLOBLIST_READY;
+ log_debug("Bloblist at %lx not found (err=%d)\n", addr, ret);
+ return false;
+found:
#ifdef DEBUG
bloblist_show_stats();
bloblist_show_list();
#endif
-
- return 0;
+ return true;
}
-int bloblist_maybe_init(void)
+int bloblist_init(void)
{
- if (CONFIG_IS_ENABLED(BLOBLIST) && !(gd->flags & GD_FLG_BLOBLIST_READY))
- return bloblist_init();
+ int ret;
+ ulong addr = 0, size = CONFIG_BLOBLIST_SIZE;
+
+ if (gd->flags & GD_FLG_BLOBLIST_HANDOFF) {
+ log_debug("Found existing bloblist size %x at %p\n",
+ gd->bloblist->total_size, gd->bloblist);
+ return 0;
+ }
+
+ /*
+ * If Firmware Handoff is mandatory but no transfer list has been
+ * observed by fdtdec_setup, report it as an error.
+ */
+ if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
+ return -ENOENT;
+
+ /*
+ * If we don't have an existing bloblist, we either need
+ * to allocate one now, or initialize the fixed address
+ * space as a bloblist.
+ */
+ if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
+ void *ptr = memalign(BLOBLIST_ALIGN, size);
+
+ if (!ptr)
+ return log_msg_ret("alloc", -ENOMEM);
+ addr = map_to_sysmem(ptr);
+ } else
+ addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
+ CONFIG_BLOBLIST_ADDR);
+
+ log_debug("Creating new bloblist size %lx at %lx\n", size,
+ addr);
+ ret = bloblist_new(addr, size, 0, 0);
+ if (ret)
+ return log_msg_ret("ini", ret);
return 0;
}
@@ -622,7 +687,9 @@ int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist)
return ret;
if (rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
- gd->bloblist = NULL; /* Reset the gd bloblist pointer */
+ /* Remove this bloblist from gd */
+ gd->bloblist = NULL;
+ gd->flags &= ~GD_FLG_BLOBLIST_HANDOFF;
return -EIO;
}
diff --git a/common/board_f.c b/common/board_f.c
index 11ad5779115..85b888d4bb8 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -31,6 +31,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
+#include <memtop.h>
#include <os.h>
#include <post.h>
#include <relocate.h>
@@ -50,6 +51,7 @@
#include <dm/root.h>
#include <linux/errno.h>
#include <linux/log2.h>
+#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -222,11 +224,11 @@ static int show_dram_config(void)
debug("\nRAM Configuration:\n");
for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- size += gd->bd->bi_dram[i].size;
+ size += gd->dram[i].size;
debug("Bank #%d: %llx ", i,
- (unsigned long long)(gd->bd->bi_dram[i].start));
+ (unsigned long long)(gd->dram[i].start));
#ifdef DEBUG
- print_size(gd->bd->bi_dram[i].size, "\n");
+ print_size(gd->dram[i].size, "\n");
#endif
}
debug("\nDRAM: ");
@@ -244,8 +246,8 @@ static int show_dram_config(void)
__weak int dram_init_banksize(void)
{
- gd->bd->bi_dram[0].start = gd->ram_base;
- gd->bd->bi_dram[0].size = get_effective_memsize();
+ gd->dram[0].start = gd->ram_base;
+ gd->dram[0].size = get_effective_memsize();
return 0;
}
@@ -308,6 +310,9 @@ __weak int mach_cpu_init(void)
/* Get the top of usable RAM */
__weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
{
+ if (CONFIG_IS_ENABLED(RELOC_ADDR_TOP))
+ return gd->ram_top;
+
#if defined(CFG_SYS_SDRAM_BASE) && CFG_SYS_SDRAM_BASE > 0
/*
* Detect whether we have so much RAM that it goes past the end of our
@@ -328,14 +333,34 @@ __weak int arch_setup_dest_addr(void)
return 0;
}
-static int setup_dest_addr(void)
+static int setup_ram_base(void)
+{
+#ifdef CFG_SYS_SDRAM_BASE
+ gd->ram_base = CFG_SYS_SDRAM_BASE;
+#endif
+ return 0;
+}
+
+static int setup_ram_config(void)
{
debug("Monitor len: %08x\n", gd->mon_len);
- /*
- * Ram is setup, size stored in gd !!
- */
- debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size);
-#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
+
+ if (CONFIG_IS_ENABLED(RELOC_ADDR_TOP)) {
+ int i;
+ phys_addr_t top;
+
+ gd->ram_size = 0;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ top = get_mem_top(gd->dram[i].start, gd->dram[i].size,
+ ALIGN(gd->mon_len, SZ_1M),
+ (void *)gd->fdt_blob);
+ gd->ram_top = max(top, gd->ram_top);
+ gd->ram_size += gd->dram[i].size;
+ }
+ } else {
+ gd->ram_top = gd->ram_base + get_effective_memsize();
+ }
+ gd->ram_top = board_get_usable_ram_top(gd->mon_len);
/*
* Subtract specified amount of memory to hide so that it won't
* get "touched" at all by U-Boot. By fixing up gd->ram_size
@@ -346,17 +371,30 @@ static int setup_dest_addr(void)
* memory size from the SDRAM controller setup will have to
* get fixed.
*/
+#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
+ gd->ram_top -= CONFIG_SYS_MEM_TOP_HIDE;
gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
#endif
-#ifdef CFG_SYS_SDRAM_BASE
- gd->ram_base = CFG_SYS_SDRAM_BASE;
-#endif
- gd->ram_top = gd->ram_base + get_effective_memsize();
- gd->ram_top = board_get_usable_ram_top(gd->mon_len);
+
+ debug("Ram top: %08llx\n", (unsigned long long)gd->ram_top);
+ debug("Ram size: %08llx\n", (unsigned long long)gd->ram_size);
+
+ return 0;
+}
+
+static int setup_dest_addr(void)
+{
+ int ret;
+
gd->relocaddr = gd->ram_top;
- debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
+ debug("Reloc addr: %08llX\n", (unsigned long long)gd->relocaddr);
- return arch_setup_dest_addr();
+ ret = arch_setup_dest_addr();
+ if (ret)
+ return ret;
+
+ gd->initial_relocaddr = gd->relocaddr;
+ return 0;
}
#ifdef CFG_PRAM
@@ -813,7 +851,16 @@ static int initf_dm(void)
return 0;
bootstage_start(BOOTSTAGE_ID_ACCUM_DM_F, "dm_f");
- ret = dm_init_and_scan(true);
+
+ /*
+ * If SKIP_EARLY_DM is set then we just create an empty device
+ * model, the serial port will still be bound later through
+ * serial_find_console_or_panic() via /chosen/stdout-path
+ */
+ if (!CONFIG_IS_ENABLED(SKIP_EARLY_DM))
+ ret = dm_init_and_scan(true);
+ else
+ ret = dm_init(false);
if (ret)
return ret;
@@ -885,7 +932,9 @@ static void initcall_run_f(void)
INITCALL(log_init);
INITCALL(initf_bootstage); /* uses its own timer, so does not need DM */
INITCALL(event_init);
- INITCALL(bloblist_maybe_init);
+#if CONFIG_IS_ENABLED(BLOBLIST)
+ INITCALL(bloblist_init);
+#endif
INITCALL(setup_spl_handoff);
#if CONFIG_IS_ENABLED(CONSOLE_RECORD_INIT_F)
INITCALL(console_record_init);
@@ -959,6 +1008,9 @@ static void initcall_run_f(void)
* - monitor code
* - board info struct
*/
+ INITCALL(setup_ram_base);
+ INITCALL(dram_init_banksize);
+ INITCALL(setup_ram_config);
INITCALL(setup_dest_addr);
#if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \
!CONFIG_IS_ENABLED(OF_INITIAL_DTB_READONLY)
@@ -986,7 +1038,6 @@ static void initcall_run_f(void)
INITCALL(reserve_bloblist);
INITCALL(reserve_arch);
INITCALL(reserve_stacks);
- INITCALL(dram_init_banksize);
INITCALL(show_dram_config);
WATCHDOG_RESET();
INITCALL(setup_bdinfo);
diff --git a/common/board_r.c b/common/board_r.c
index 5d37345ca09..a397e20959d 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -495,7 +495,7 @@ static int initr_boot_led_on(void)
return 0;
}
-#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP)
+#if CONFIG_IS_ENABLED(NET)
static int initr_net(void)
{
puts("Net: ");
@@ -687,7 +687,7 @@ static void initcall_run_r(void)
INITCALL(initr_flash);
#endif
WATCHDOG_RESET();
-#if CONFIG_IS_ENABLED(PPC) || CONFIG_IS_ENABLED(M68K) || CONFIG_IS_ENABLED(X86)
+#if IS_ENABLED(CONFIG_PPC) || CONFIG_IS_ENABLED(M68K) || CONFIG_IS_ENABLED(X86)
/* initialize higher level parts of CPU like time base and timers */
INITCALL(cpu_init_r);
#endif
@@ -760,7 +760,7 @@ static void initcall_run_r(void)
#if CONFIG_IS_ENABLED(PCI_ENDPOINT)
INITCALL(pci_ep_init);
#endif
-#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP)
+#if CONFIG_IS_ENABLED(NET)
WATCHDOG_RESET();
INITCALL(initr_net);
#endif
diff --git a/common/cli.c b/common/cli.c
index 4694a35cd0e..87ce0e4d144 100644
--- a/common/cli.c
+++ b/common/cli.c
@@ -138,11 +138,9 @@ int run_command_list(const char *cmd, int len, int flag)
#endif
}
if (need_buff) {
- buff = malloc(len + 1);
+ buff = memdup_nul(cmd, len);
if (!buff)
return 1;
- memcpy(buff, cmd, len);
- buff[len] = '\0';
}
#ifdef CONFIG_HUSH_PARSER
if (use_hush_old()) {
@@ -295,6 +293,10 @@ err:
void cli_loop(void)
{
bootstage_mark(BOOTSTAGE_ID_ENTER_CLI_LOOP);
+
+ if (IS_ENABLED(CONFIG_CMDLINE_FLUSH_STDIN))
+ console_flush_stdin();
+
#if CONFIG_IS_ENABLED(HUSH_PARSER)
if (gd->flags & GD_FLG_HUSH_MODERN_PARSER)
parse_and_run_file();
diff --git a/common/command.c b/common/command.c
index 0f9dd06d72b..eb2c2123534 100644
--- a/common/command.c
+++ b/common/command.c
@@ -367,11 +367,15 @@ int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
int i, j, k, len, seplen, argc;
int cnt;
char last_char;
-#ifdef CONFIG_CMDLINE_PS_SUPPORT
- const char *ps_prompt = env_get("PS1");
-#else
- const char *ps_prompt = CONFIG_SYS_PROMPT;
-#endif
+ const char *ps_prompt;
+
+ if (IS_ENABLED(CONFIG_CMDLINE_PS_SUPPORT)) {
+ ps_prompt = env_get("PS1");
+
+ if (!ps_prompt)
+ ps_prompt = CONFIG_SYS_PROMPT;
+ } else
+ ps_prompt = CONFIG_SYS_PROMPT;
if (strcmp(prompt, ps_prompt) != 0)
return 0; /* not in normal console */
diff --git a/common/console.c b/common/console.c
index 22e554cf203..54d1249422d 100644
--- a/common/console.c
+++ b/common/console.c
@@ -643,6 +643,15 @@ int tstc(void)
return serial_tstc();
}
+/**
+ * console_flush_stdin() - drops all pending characters from stdin
+ */
+void console_flush_stdin(void)
+{
+ while (tstc())
+ (void)getchar();
+}
+
#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
@@ -914,8 +923,7 @@ int confirm_yesno(void)
char str_input[5];
/* Flush input */
- while (tstc())
- getchar();
+ console_flush_stdin();
i = 0;
while (i < sizeof(str_input)) {
str_input[i] = getchar();
diff --git a/common/cyclic.c b/common/cyclic.c
index ec952a01ee1..573e715587d 100644
--- a/common/cyclic.c
+++ b/common/cyclic.c
@@ -41,7 +41,7 @@ static bool cyclic_is_registered(const struct cyclic_info *cyclic)
}
void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func,
- uint64_t delay_us, const char *name)
+ u64 delay_us, const char *name)
{
cyclic_unregister(cyclic);
@@ -67,26 +67,28 @@ static void cyclic_run(void)
{
struct cyclic_info *cyclic;
struct hlist_node *tmp;
- uint64_t now, cpu_time;
+ u64 now, after, cpu_time;
/* Prevent recursion */
if (gd->flags & GD_FLG_CYCLIC_RUNNING)
return;
gd->flags |= GD_FLG_CYCLIC_RUNNING;
+ now = get_timer_us(0);
hlist_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) {
/*
* Check if this cyclic function needs to get called, e.g.
* do not call the cyclic func too often
*/
- now = get_timer_us(0);
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);
+ after = get_timer_us(0);
cyclic->run_cnt++;
- cpu_time = get_timer_us(0) - now;
+ cpu_time = after - now;
cyclic->cpu_time_us += cpu_time;
+ now = after;
/* Check if cpu-time exceeds max allowed time */
if ((cpu_time > CONFIG_CYCLIC_MAX_CPU_TIME_US) &&
diff --git a/common/init/handoff.c b/common/init/handoff.c
index a7cd065fb38..a4d9d14393b 100644
--- a/common/init/handoff.c
+++ b/common/init/handoff.c
@@ -12,14 +12,13 @@ DECLARE_GLOBAL_DATA_PTR;
void handoff_save_dram(struct spl_handoff *ho)
{
- struct bd_info *bd = gd->bd;
int i;
ho->ram_size = gd->ram_size;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- ho->ram_bank[i].start = bd->bi_dram[i].start;
- ho->ram_bank[i].size = bd->bi_dram[i].size;
+ ho->ram_bank[i].start = gd->dram[i].start;
+ ho->ram_bank[i].size = gd->dram[i].size;
}
}
@@ -30,11 +29,10 @@ void handoff_load_dram_size(struct spl_handoff *ho)
void handoff_load_dram_banks(struct spl_handoff *ho)
{
- struct bd_info *bd = gd->bd;
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- bd->bi_dram[i].start = ho->ram_bank[i].start;
- bd->bi_dram[i].size = ho->ram_bank[i].size;
+ gd->dram[i].start = ho->ram_bank[i].start;
+ gd->dram[i].size = ho->ram_bank[i].size;
}
}
diff --git a/common/memsize.c b/common/memsize.c
index 1abf3fc47d7..fd22f85a164 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -127,6 +127,81 @@ long get_ram_size(long *base, long maxsize)
return (maxsize);
}
+/**
+ * probe_ram_size_by_alias() - Detect RAM size using known alias addresses
+ * @checks: Array of RAM alias probe descriptors, terminated by a NULL
+ * @probe_addr entry
+ *
+ * Probe RAM size by writing a test pattern to each @probe_addr and checking
+ * whether the same pattern does not appear at the corresponding @alias_addr.
+ * This is useful on systems where address wrap-around does not alias to the
+ * base of memory in a linear way, so get_ram_size() cannot be used directly.
+ * It is also useful on systems where the base of the physical memory cannot
+ * be safely accessed, so get_ram_size() cannot be used at all.
+ *
+ * Return: The size associated with the first matching entry, or 0 if no match
+ * is found.
+ */
+long probe_ram_size_by_alias(const struct ram_alias_check *checks)
+{
+ long save[2];
+ long pat;
+ int dcache_en = 0;
+ long ret = 0;
+
+ if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+ dcache_en = dcache_status();
+
+ while (checks->probe_addr && !ret) {
+ volatile long *d = checks->probe_addr;
+ volatile long *s = checks->alias_addr;
+
+ save[0] = *s;
+ save[1] = *d;
+ /* Ensure s is written and not cached */
+ if (dcache_en)
+ dcache_flush_invalidate(s);
+
+ pat = ~save[0];
+ *d = pat;
+ sync();
+ if (dcache_en)
+ dcache_flush_invalidate(d);
+
+ /*
+ * Make sure the test pattern is observable at the probe
+ * address before checking whether it is also visible through
+ * the alias address.
+ */
+ if (*d != pat) {
+ *d = save[1];
+ sync();
+ if (dcache_en)
+ dcache_flush_invalidate(d);
+ checks++;
+ continue;
+ }
+
+ if (*s != pat)
+ ret = checks->size;
+
+ /* Restore content */
+ *d = save[1];
+ sync();
+ if (dcache_en)
+ dcache_flush_invalidate(d);
+
+ *s = save[0];
+ sync();
+ if (dcache_en)
+ dcache_flush_invalidate(s);
+
+ checks++;
+ }
+
+ return ret;
+}
+
phys_size_t __weak get_effective_memsize(void)
{
phys_size_t ram_size = gd->ram_size;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index a21b71ad5d1..0618f42c941 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -220,7 +220,7 @@ source "common/spl/Kconfig.nxp"
config HANDOFF
bool "Pass hand-off information from SPL to U-Boot proper"
- depends on BLOBLIST
+ depends on BLOBLIST_FIXED
help
It is useful to be able to pass information from SPL to U-Boot
proper to preserve state that is known in SPL and is needed in U-Boot.
@@ -541,7 +541,7 @@ config SPL_SYS_MMCSD_RAW_MODE
ARCH_MX6 || ARCH_MX7 || \
ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA_GEN5 || \
ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
- OMAP54XX || AM33XX || AM43XX || \
+ OMAP44XX || OMAP54XX || AM33XX || AM43XX || \
TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
help
Support booting from an MMC without a filesystem.
@@ -585,7 +585,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
default 0x100 if ARCH_UNIPHIER
default 0x0 if ARCH_MVEBU
default 0x200 if ARCH_SOCFPGA_GEN5 || ARCH_AT91
- default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
+ default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \
OMAP54XX || AM33XX || AM43XX || ARCH_K3
default 0x4000 if ARCH_ROCKCHIP
default 0x822 if TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
@@ -1151,7 +1151,7 @@ config SPL_DM_SPI_FLASH
config SPL_NET
bool "Support networking"
- depends on NET
+ depends on NET_LEGACY
select SPL_USE_TINY_PRINTF_POINTER_SUPPORT if SPL_USE_TINY_PRINTF
help
Enable support for network devices (such as Ethernet) in SPL.
@@ -1160,6 +1160,9 @@ config SPL_NET
the network stack uses a number of environment variables. See also
SPL_ETH.
+config SPL_NET_LEGACY
+ def_bool y if SPL_NET
+
config SPL_NET_VCI_STRING
string "BOOTP Vendor Class Identifier string sent by SPL"
depends on SPL_NET
@@ -1318,10 +1321,10 @@ config SPL_PCI
config SPL_PCI_ENDPOINT
bool "Support for PCI endpoint drivers"
help
- Enable this configuration option to support configurable PCI
- endpoints at SPL. This should be enabled if the platform has
- a PCI controllers that can operate in endpoint mode (as a device
- connected to PCI host or bridge).
+ Enable this configuration option to support configurable PCI
+ endpoints at SPL. This should be enabled if the platform has
+ a PCI controllers that can operate in endpoint mode (as a device
+ connected to PCI host or bridge).
config SPL_PCH
bool "Support PCH drivers"
@@ -1549,18 +1552,18 @@ config SPL_SPI_FLASH_TINY
depends on !SPI_FLASH_BAR
default y if SPI_FLASH
help
- Enable lightweight SPL SPI Flash support that supports just reading
- data/images from flash. No support to write/erase flash. Enable
- this if you have SPL size limitations and don't need full
- fledged SPI flash support.
+ Enable lightweight SPL SPI Flash support that supports just reading
+ data/images from flash. No support to write/erase flash. Enable
+ this if you have SPL size limitations and don't need full
+ fledged SPI flash support.
config SPL_SPI_FLASH_SFDP_SUPPORT
bool "SFDP table parsing support for SPI NOR flashes"
depends on !SPI_FLASH_BAR && !SPL_SPI_FLASH_TINY
help
- Enable support for parsing and auto discovery of parameters for
- SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
- tables as per JESD216 standard in SPL.
+ Enable support for parsing and auto discovery of parameters for
+ SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
+ tables as per JESD216 standard in SPL.
config SPL_SPI_FLASH_MTD
bool "Support for SPI flash MTD drivers in SPL"
@@ -1581,22 +1584,22 @@ config SYS_SPI_U_BOOT_OFFS
default 0x0
depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
help
- Address within SPI-Flash from where the u-boot payload is fetched
- from.
+ Address within SPI-Flash from where the u-boot payload is fetched
+ from.
config SYS_SPI_KERNEL_OFFS
hex "Falcon mode: address of kernel payload in SPI flash"
depends on SPL_SPI_FLASH_SUPPORT && SPL_OS_BOOT
help
- Address within SPI-Flash from where the kernel payload is fetched
- in falcon boot.
+ Address within SPI-Flash from where the kernel payload is fetched
+ in falcon boot.
config SYS_SPI_ARGS_OFFS
hex "Falcon mode: address of args payload in SPI flash"
depends on SPL_SPI_FLASH_SUPPORT && SPL_OS_BOOT_ARGS
help
- Address within SPI-Flash from where the args payload (usually the
- dtb) is fetched in falcon boot.
+ Address within SPI-Flash from where the args payload (usually the
+ dtb) is fetched in falcon boot.
config SYS_SPI_ARGS_SIZE
hex "Falcon mode: size of args payload in SPI flash"
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 46ebcabe56a..18bff7b8d4a 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -204,6 +204,9 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
* If the FIT node does not contain a "load" (address) property,
* the image gets loaded to the address pointed to by the
* load_addr member in this struct, if load_addr is not 0
+ * @max_size: maximum number of bytes that may be written to the
+ * destination; an image whose data exceeds this is rejected
+ * before it is read from the device
*
* Return: 0 on success, -EBADSLT if this image is not the correct phase
* (for CONFIG_BOOTMETH_VBE_SIMPLE_FW), or another negative error number on
@@ -211,7 +214,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
*/
static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
const struct spl_fit_info *ctx, int node,
- struct spl_image_info *image_info)
+ struct spl_image_info *image_info, ulong max_size)
{
int offset;
size_t length;
@@ -291,6 +294,23 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
return 0;
}
+ /*
+ * data-size is excluded from the configuration signature (it
+ * is in exc_prop[] in image-fit-sig.c), so it stays attacker
+ * controlled even after fit_config_verify() succeeds. The
+ * image hash is only verified after the device read below, so
+ * an oversized value has to be rejected here.
+ *
+ * Bail out before get_aligned_image_size() runs on a hostile
+ * len: that helper does its arithmetic in int and would
+ * invoke signed-integer overflow on a value close to or above
+ * INT_MAX. The block-aligned check further down is the
+ * mathematically binding one, since size is len rounded up to
+ * the device block length.
+ */
+ if ((ulong)len > max_size)
+ goto too_big;
+
if (spl_decompression_enabled() &&
(image_comp == IH_COMP_GZIP || image_comp == IH_COMP_LZMA))
src_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR, ARCH_DMA_MINALIGN), len);
@@ -302,6 +322,15 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
size = get_aligned_image_size(info, length, offset);
read_offset = fit_offset + get_aligned_image_offset(info,
offset);
+
+ /*
+ * info->read() transfers the block-aligned size into the
+ * destination, so this is the bound that actually matters;
+ * len was rejected above only to keep this computation safe.
+ */
+ if (size > max_size)
+ goto too_big;
+
log_debug("reading from offset %x / %lx size %lx to %p: ",
offset, read_offset, size, src_ptr);
@@ -372,6 +401,11 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
upl_add_image(fit, node, load_addr, length);
return 0;
+
+too_big:
+ printf("%s: FIT image too large (data-size %u, max %lu)\n",
+ __func__, (u32)len, max_size);
+ return -EFBIG;
}
static bool os_takes_devicetree(uint8_t os)
@@ -427,7 +461,8 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
spl_image->fdt_addr = map_sysmem(image_info.load_addr, size);
memcpy(spl_image->fdt_addr, gd->fdt_blob, size);
} else {
- ret = load_simple_fit(info, offset, ctx, node, &image_info);
+ ret = load_simple_fit(info, offset, ctx, node, &image_info,
+ CONFIG_SYS_BOOTM_LEN);
if (ret < 0)
return ret;
@@ -479,7 +514,8 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
}
image_info.load_addr = (ulong)tmpbuffer;
ret = load_simple_fit(info, offset, ctx, node,
- &image_info);
+ &image_info,
+ CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ);
if (ret == -EBADSLT)
continue;
else if (ret < 0)
@@ -687,7 +723,8 @@ static int spl_fit_load_fpga(struct spl_fit_info *ctx,
warn_deprecated("'fpga' property in config node. Use 'loadables'");
/* Load the image and set up the fpga_image structure */
- ret = load_simple_fit(info, offset, ctx, node, &fpga_image);
+ ret = load_simple_fit(info, offset, ctx, node, &fpga_image,
+ CONFIG_SYS_BOOTM_LEN);
if (ret) {
printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
return ret;
@@ -775,7 +812,7 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx)
if (ctx->conf_node < 0)
return -EINVAL;
- if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) {
+ if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
printf("## Checking hash(es) for config %s ... ",
fit_get_name(ctx->fit, ctx->conf_node, NULL));
if (fit_config_verify(ctx->fit, ctx->conf_node))
@@ -849,7 +886,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
}
/* Load the image and set up the spl_image structure */
- ret = load_simple_fit(info, offset, &ctx, node, spl_image);
+ ret = load_simple_fit(info, offset, &ctx, node, spl_image,
+ CONFIG_SYS_BOOTM_LEN);
if (ret)
return ret;
@@ -890,7 +928,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
continue;
image_info.load_addr = 0;
- ret = load_simple_fit(info, offset, &ctx, node, &image_info);
+ ret = load_simple_fit(info, offset, &ctx, node, &image_info,
+ CONFIG_SYS_BOOTM_LEN);
if (ret < 0 && ret != -EBADSLT) {
printf("%s: can't load image loadables index %d (ret = %d)\n",
__func__, index, ret);
@@ -955,22 +994,12 @@ int spl_load_fit_image(struct spl_image_info *spl_image,
int idx, conf_noffset;
int ret;
-#ifdef CONFIG_SPL_FIT_SIGNATURE
- images.verify = 1;
-#endif
+ images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE);
+
ret = fit_image_load(&images, virt_to_phys((void *)header),
- NULL, &fit_uname_config,
- IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1,
- FIT_LOAD_OPTIONAL, &fw_data, &fw_len);
- if (ret >= 0) {
- printf("DEPRECATED: 'standalone = ' property.");
- printf("Please use either 'firmware =' or 'kernel ='\n");
- } else {
- ret = fit_image_load(&images, virt_to_phys((void *)header),
- NULL, &fit_uname_config, IH_ARCH_DEFAULT,
- IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL,
- &fw_data, &fw_len);
- }
+ NULL, &fit_uname_config, IH_ARCH_DEFAULT,
+ IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL,
+ &fw_data, &fw_len);
if (ret < 0) {
ret = fit_image_load(&images, virt_to_phys((void *)header),
@@ -993,21 +1022,21 @@ int spl_load_fit_image(struct spl_image_info *spl_image,
debug(PHASE_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n",
spl_image->name, spl_image->load_addr, spl_image->size);
-#ifdef CONFIG_SPL_FIT_SIGNATURE
- images.verify = 1;
-#endif
+ images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE);
+
ret = fit_image_load(&images, virt_to_phys((void *)header), NULL,
&fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT,
-1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len);
if (ret >= 0) {
- spl_image->fdt_addr = (void *)dt_data;
-
if (spl_image->os == IH_OS_U_BOOT) {
/* HACK: U-Boot expects FDT at a specific address */
- fdt_hack = spl_image->load_addr + spl_image->size;
- fdt_hack = (fdt_hack + 3) & ~3;
- debug("Relocating FDT to %p\n", spl_image->fdt_addr);
- memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len);
+ fdt_hack = ALIGN(spl_image->load_addr + spl_image->size, 8);
+ debug("Relocating FDT to %p\n", (void *)fdt_hack);
+ memcpy(map_sysmem(fdt_hack, dt_len),
+ map_sysmem(dt_data, 0), dt_len);
+ spl_image->fdt_addr = (void *)fdt_hack;
+ } else {
+ spl_image->fdt_addr = (void *)dt_data;
}
}
@@ -1021,10 +1050,9 @@ int spl_load_fit_image(struct spl_image_info *spl_image,
FIT_LOADABLE_PROP, idx,
NULL), uname;
idx++) {
-#ifdef CONFIG_SPL_FIT_SIGNATURE
- images.verify = 1;
-#endif
- ret = fit_image_load(&images, (ulong)header,
+ images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE);
+
+ ret = fit_image_load(&images, virt_to_phys((void *)header),
&uname, &fit_uname_config,
IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
FIT_LOAD_OPTIONAL_NON_ZERO,
diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c
index 79d021f81dc..57cd75b9b5e 100644
--- a/common/spl/spl_imx_container.c
+++ b/common/spl/spl_imx_container.c
@@ -88,6 +88,7 @@ static int read_auth_container(struct spl_image_info *spl_image,
struct spl_load_info *info, ulong offset)
{
struct container_hdr *container = NULL;
+ struct container_hdr *authhdr;
u16 length;
int i, size, ret = 0;
@@ -140,15 +141,19 @@ static int read_auth_container(struct spl_image_info *spl_image,
}
}
+ authhdr = container;
+
#ifdef CONFIG_AHAB_BOOT
- ret = ahab_auth_cntr_hdr(container, length);
- if (ret)
+ authhdr = ahab_auth_cntr_hdr(authhdr, length);
+ if (!authhdr) {
+ ret = -EINVAL;
goto end_auth;
+ }
#endif
- for (i = 0; i < container->num_images; i++) {
+ for (i = 0; i < authhdr->num_images; i++) {
struct boot_img_t *image = read_auth_image(spl_image, info,
- container, i,
+ authhdr, i,
offset);
if (!image) {
diff --git a/common/splash_source.c b/common/splash_source.c
index 0710e302ba1..e02f9be05e4 100644
--- a/common/splash_source.c
+++ b/common/splash_source.c
@@ -159,12 +159,12 @@ static int splash_select_fs_dev(struct splash_location *location)
res = -ENODEV;
break;
default:
- printf("Error: unsupported location storage.\n");
+ printf("Error: %s: unsupported location storage.\n", __func__);
return -ENODEV;
}
if (res)
- printf("Error: could not access storage.\n");
+ printf("Error: %s: could not access storage.\n", __func__);
return res;
}
@@ -284,7 +284,8 @@ static int splash_load_fs(struct splash_location *location, ulong bmp_load_addr)
res = fs_size(splash_file, &bmp_size);
if (res) {
- printf("Error (%d): cannot determine file size\n", res);
+ printf("Error: %s: cannot determine file size (%d)\n",
+ __func__, res);
goto out;
}
diff --git a/common/stdio.c b/common/stdio.c
index fc965944209..038e576147b 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -217,27 +217,11 @@ struct stdio_dev *stdio_get_by_name(const char *name)
return NULL;
}
-struct stdio_dev *stdio_clone(struct stdio_dev *dev)
-{
- struct stdio_dev *_dev;
-
- if (!dev)
- return NULL;
-
- _dev = calloc(1, sizeof(struct stdio_dev));
- if (!_dev)
- return NULL;
-
- memcpy(_dev, dev, sizeof(struct stdio_dev));
-
- return _dev;
-}
-
int stdio_register_dev(struct stdio_dev *dev, struct stdio_dev **devp)
{
struct stdio_dev *_dev;
- _dev = stdio_clone(dev);
+ _dev = memdup(dev, sizeof(*dev));
if (!_dev)
return -ENODEV;
list_add_tail(&_dev->list, &devs.list);
diff --git a/common/update.c b/common/update.c
index 0bafffede9e..06e53cbd402 100644
--- a/common/update.c
+++ b/common/update.c
@@ -32,7 +32,7 @@ static uchar *saved_prot_info;
#endif
static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
{
- int rv;
+ int rv, ret;
ulong saved_timeout_msecs;
int saved_timeout_count;
char *saved_netretry, *saved_bootfile;
@@ -54,9 +54,9 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
/* download the update file */
image_load_addr = addr;
copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name));
- rv = net_loop(TFTPGET);
+ ret = net_loop(TFTPGET);
- if (rv < 0)
+ if (ret < 0)
rv = 1;
else
flush_cache(addr, net_boot_file_size);
diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 6fc34489a98..0684f7bfd47 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -262,6 +262,12 @@ static int usb_onboard_hub_remove(struct udevice *dev)
return ret;
}
+static const struct onboard_hub_data corechips_sl6341_data = {
+ .reset_us = 10000,
+ .num_supplies = 2,
+ .supply_names = { "vdd1v1-supply", "vdd3v3-supply" },
+};
+
static const struct onboard_hub_data usb2514_data = {
.power_on_delay_us = 500,
.reset_us = 1,
@@ -285,7 +291,13 @@ static const struct onboard_hub_data usbhx3_data = {
static const struct udevice_id usb_onboard_hub_ids[] = {
/* Use generic usbVID,PID dt-bindings (usb-device.yaml) */
- { .compatible = "usb424,2514", /* USB2514B USB 2.0 */
+ { .compatible = "usb3431,6241", /* Corechips SL6341 USB 2.0 */
+ .data = (ulong)&corechips_sl6341_data,
+ }, {
+ .compatible = "usb3431,6341", /* Corechips SL6341 USB 3.0 */
+ .data = (ulong)&corechips_sl6341_data,
+ }, {
+ .compatible = "usb424,2514", /* USB2514B USB 2.0 */
.data = (ulong)&usb2514_data,
}, {
.compatible = "usb424,2744", /* USB2744 USB 2.0 */