summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/board_f.c86
-rw-r--r--common/board_r.c4
-rw-r--r--common/bootstage.c8
-rw-r--r--common/console.c19
-rw-r--r--common/dlmalloc.c23
-rw-r--r--common/hwconfig.c8
-rw-r--r--common/init/handoff.c12
-rw-r--r--common/log_console.c4
-rw-r--r--common/log_syslog.c2
-rw-r--r--common/malloc_simple.c4
-rw-r--r--common/spl/Kconfig58
-rw-r--r--common/spl/Kconfig.tpl2
-rw-r--r--common/spl/Kconfig.vpl2
-rw-r--r--common/spl/Makefile2
-rw-r--r--common/spl/spl.c46
-rw-r--r--common/spl/spl_blk_fs.c9
-rw-r--r--common/spl/spl_ext.c3
-rw-r--r--common/spl/spl_fat.c10
-rw-r--r--common/spl/spl_fit.c9
-rw-r--r--common/spl/spl_mmc.c159
-rw-r--r--common/spl/spl_nand.c4
-rw-r--r--common/spl/spl_net.c3
-rw-r--r--common/spl/spl_nor.c6
-rw-r--r--common/spl/spl_ram.c3
-rw-r--r--common/spl/spl_semihosting.c4
-rw-r--r--common/spl/spl_spi.c4
-rw-r--r--common/spl/spl_upl.c172
-rw-r--r--common/spl/spl_ymodem.c4
28 files changed, 436 insertions, 234 deletions
diff --git a/common/board_f.c b/common/board_f.c
index 29e185137ad..154675d0e40 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -40,6 +40,7 @@
#include <sysreset.h>
#include <timer.h>
#include <trace.h>
+#include <upl.h>
#include <video.h>
#include <watchdog.h>
#include <asm/cache.h>
@@ -304,17 +305,6 @@ static int setup_mon_len(void)
return 0;
}
-static int setup_spl_handoff(void)
-{
-#if CONFIG_IS_ENABLED(HANDOFF)
- gd->spl_handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
- sizeof(struct spl_handoff));
- debug("Found SPL hand-off info %p\n", gd->spl_handoff);
-#endif
-
- return 0;
-}
-
__weak int arch_cpu_init(void)
{
return 0;
@@ -350,7 +340,7 @@ __weak int arch_setup_dest_addr(void)
static int setup_dest_addr(void)
{
- debug("Monitor len: %08lX\n", gd->mon_len);
+ debug("Monitor len: %08x\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
*/
@@ -487,7 +477,7 @@ static int reserve_uboot(void)
gd->relocaddr &= ~(65536 - 1);
#endif
- debug("Reserving %ldk for U-Boot at: %08lx\n",
+ debug("Reserving %dk for U-Boot at: %08lx\n",
gd->mon_len >> 10, gd->relocaddr);
}
@@ -574,12 +564,15 @@ static int reserve_fdt(void)
* section, then it will be relocated with other data.
*/
if (gd->fdt_blob) {
- gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
+ gd->boardf->fdt_size =
+ ALIGN(fdt_totalsize(gd->fdt_blob), 32);
- gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
- gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
+ gd->start_addr_sp = reserve_stack_aligned(
+ gd->boardf->fdt_size);
+ gd->boardf->new_fdt = map_sysmem(gd->start_addr_sp,
+ gd->boardf->fdt_size);
debug("Reserving %lu Bytes for FDT at: %08lx\n",
- gd->fdt_size, gd->start_addr_sp);
+ gd->boardf->fdt_size, gd->start_addr_sp);
}
}
@@ -592,7 +585,7 @@ static int reserve_bootstage(void)
int size = bootstage_get_size();
gd->start_addr_sp = reserve_stack_aligned(size);
- gd->new_bootstage = map_sysmem(gd->start_addr_sp, size);
+ gd->boardf->new_bootstage = map_sysmem(gd->start_addr_sp, size);
debug("Reserving %#x Bytes for bootstage at: %08lx\n", size,
gd->start_addr_sp);
#endif
@@ -623,8 +616,8 @@ static int reserve_bloblist(void)
/* Align to a 4KB boundary for easier reading of addresses */
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
- gd->new_bloblist = map_sysmem(gd->start_addr_sp,
- CONFIG_BLOBLIST_SIZE_RELOC);
+ gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp,
+ CONFIG_BLOBLIST_SIZE_RELOC);
#endif
return 0;
@@ -667,10 +660,10 @@ static int init_post(void)
static int reloc_fdt(void)
{
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
- if (gd->new_fdt) {
- memcpy(gd->new_fdt, gd->fdt_blob,
+ if (gd->boardf->new_fdt) {
+ memcpy(gd->boardf->new_fdt, gd->fdt_blob,
fdt_totalsize(gd->fdt_blob));
- gd->fdt_blob = gd->new_fdt;
+ gd->fdt_blob = gd->boardf->new_fdt;
}
}
@@ -682,15 +675,8 @@ static int reloc_bootstage(void)
#ifdef CONFIG_BOOTSTAGE
if (gd->flags & GD_FLG_SKIP_RELOC)
return 0;
- if (gd->new_bootstage) {
- int size = bootstage_get_size();
-
- debug("Copying bootstage from %p to %p, size %x\n",
- gd->bootstage, gd->new_bootstage, size);
- memcpy(gd->new_bootstage, gd->bootstage, size);
- gd->bootstage = gd->new_bootstage;
- bootstage_relocate();
- }
+ if (gd->boardf->new_bootstage)
+ bootstage_relocate(gd->boardf->new_bootstage);
#endif
return 0;
@@ -707,10 +693,11 @@ static int reloc_bloblist(void)
debug("Not relocating bloblist\n");
return 0;
}
- if (gd->new_bloblist) {
+ if (gd->boardf->new_bloblist) {
debug("Copying bloblist from %p to %p, size %x\n",
- gd->bloblist, gd->new_bloblist, gd->bloblist->total_size);
- return bloblist_reloc(gd->new_bloblist,
+ gd->bloblist, gd->boardf->new_bloblist,
+ gd->bloblist->total_size);
+ return bloblist_reloc(gd->boardf->new_bloblist,
CONFIG_BLOBLIST_SIZE_RELOC);
}
#endif
@@ -810,7 +797,7 @@ static int initf_bootstage(void)
if (ret)
return ret;
if (from_spl) {
- ret = bootstage_stash_default();
+ ret = bootstage_unstash_default();
if (ret && ret != -ENOENT) {
debug("Failed to unstash bootstage: err=%d\n", ret);
return ret;
@@ -859,6 +846,26 @@ __weak int clear_bss(void)
return 0;
}
+static int initf_upl(void)
+{
+ struct upl *upl;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_UPL_IN) || !(gd->flags & GD_FLG_UPL))
+ return 0;
+
+ upl = malloc(sizeof(struct upl));
+ if (upl)
+ ret = upl_read_handoff(upl, oftree_default());
+ if (ret) {
+ printf("UPL handoff: read failure (err=%dE)\n", ret);
+ return ret;
+ }
+ gd_set_upl(upl);
+
+ return 0;
+}
+
static const init_fnc_t init_sequence_f[] = {
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
@@ -868,11 +875,11 @@ static const init_fnc_t init_sequence_f[] = {
trace_early_init,
#endif
initf_malloc,
+ initf_upl,
log_init,
initf_bootstage, /* uses its own timer, so does not need DM */
event_init,
bloblist_maybe_init,
- setup_spl_handoff,
#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
console_record_init,
#endif
@@ -1005,8 +1012,11 @@ static const init_fnc_t init_sequence_f[] = {
void board_init_f(ulong boot_flags)
{
+ struct board_f boardf;
+
gd->flags = boot_flags;
- gd->have_console = 0;
+ gd->flags &= ~GD_FLG_HAVE_CONSOLE;
+ gd->boardf = &boardf;
if (initcall_run_list(init_sequence_f))
hang();
diff --git a/common/board_r.c b/common/board_r.c
index d4ba245ac69..e88b7ea4d8a 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -192,7 +192,7 @@ static int initr_malloc(void)
ulong start;
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
- debug("Pre-reloc malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
+ debug("Pre-reloc malloc() used %#x bytes (%d KB)\n", gd->malloc_ptr,
gd->malloc_ptr / 1024);
#endif
/* The malloc area is immediately below the monitor copy in DRAM */
@@ -521,6 +521,8 @@ static int dm_announce(void)
uclass_count);
if (CONFIG_IS_ENABLED(OF_REAL))
printf(", devicetree: %s", fdtdec_get_srcname());
+ if (CONFIG_IS_ENABLED(UPL))
+ printf(", universal payload active");
printf("\n");
if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE) &&
(gd->fdt_src == FDTSRC_SEPARATE ||
diff --git a/common/bootstage.c b/common/bootstage.c
index b6c268d9f47..49acc9078a6 100644
--- a/common/bootstage.c
+++ b/common/bootstage.c
@@ -54,12 +54,16 @@ struct bootstage_hdr {
u32 next_id; /* Next ID to use for bootstage */
};
-int bootstage_relocate(void)
+int bootstage_relocate(void *to)
{
- struct bootstage_data *data = gd->bootstage;
+ struct bootstage_data *data;
int i;
char *ptr;
+ debug("Copying bootstage from %p to %p\n", gd->bootstage, to);
+ memcpy(to, gd->bootstage, sizeof(struct bootstage_data));
+ data = gd->bootstage = to;
+
/* Figure out where to relocate the strings to */
ptr = (char *)(data + 1);
diff --git a/common/console.c b/common/console.c
index 63f78004fdb..52d6df8150f 100644
--- a/common/console.c
+++ b/common/console.c
@@ -189,6 +189,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
/* Assign the new device (leaving the existing one started) */
stdio_devices[file] = dev;
+#ifndef CONFIG_SPL_BUILD
/*
* Update monitor functions
* (to use the console stuff by other applications)
@@ -206,7 +207,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
break;
}
break;
-
+#endif
default: /* Invalid file ID */
error = -1;
}
@@ -586,7 +587,7 @@ int getchar(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return 0;
- if (!gd->have_console)
+ if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return 0;
ch = console_record_getc();
@@ -607,7 +608,7 @@ int tstc(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return 0;
- if (!gd->have_console)
+ if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return 0;
if (console_record_tstc())
@@ -715,7 +716,7 @@ void putc(const char c)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
- if (!gd->have_console)
+ if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return pre_console_putc(c);
if (gd->flags & GD_FLG_DEVINIT) {
@@ -759,7 +760,7 @@ void puts(const char *s)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
- if (!gd->have_console)
+ if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return pre_console_puts(s);
if (gd->flags & GD_FLG_DEVINIT) {
@@ -793,7 +794,7 @@ void flush(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
- if (!gd->have_console)
+ if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return;
if (gd->flags & GD_FLG_DEVINIT) {
@@ -845,6 +846,8 @@ int console_record_readline(char *str, int maxlen)
{
if (gd->flags & GD_FLG_RECORD_OVF)
return -ENOSPC;
+ if (console_record_isempty())
+ return -ENOENT;
return membuff_readline((struct membuff *)&gd->console_out, str,
maxlen, '\0', false);
@@ -872,7 +875,7 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */
static int ctrlc_was_pressed = 0;
int ctrlc(void)
{
- if (!ctrlc_disabled && gd->have_console) {
+ if (!ctrlc_disabled && (gd->flags & GD_FLG_HAVE_CONSOLE)) {
if (tstc()) {
switch (getchar()) {
case 0x03: /* ^C - Control C */
@@ -1011,7 +1014,7 @@ int console_announce_r(void)
/* Called before relocation - use serial functions */
int console_init_f(void)
{
- gd->have_console = 1;
+ gd->flags |= GD_FLG_HAVE_CONSOLE;
console_update_silent();
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 62e8557daa7..1ac7ce3f43c 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -386,8 +386,8 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/* pad request bytes into a usable size */
#define request2size(req) \
- (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
- (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
+ ((((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
+ (MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
(((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
/* Check if m has acceptable alignment */
@@ -581,6 +581,9 @@ void *sbrk(ptrdiff_t increment)
ulong old = mem_malloc_brk;
ulong new = old + increment;
+ if ((new < mem_malloc_start) || (new > mem_malloc_end))
+ return (void *)MORECORE_FAILURE;
+
/*
* if we are giving memory back make sure we clear it out since
* we set MORECORE_CLEARS to 1
@@ -588,9 +591,6 @@ void *sbrk(ptrdiff_t increment)
if (increment < 0)
memset((void *)new, 0, -increment);
- if ((new < mem_malloc_start) || (new > mem_malloc_end))
- return (void *)MORECORE_FAILURE;
-
mem_malloc_brk = new;
return (void *)old;
@@ -1274,7 +1274,8 @@ Void_t* mALLOc_impl(bytes) size_t bytes;
return NULL;
}
- if ((long)bytes < 0) return NULL;
+ if (bytes > CONFIG_SYS_MALLOC_LEN || (long)bytes < 0)
+ return NULL;
nb = request2size(bytes); /* padded request size; */
@@ -1687,7 +1688,8 @@ Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes;
}
#endif
- if ((long)bytes < 0) return NULL;
+ if (bytes > CONFIG_SYS_MALLOC_LEN || (long)bytes < 0)
+ return NULL;
/* realloc of null is supposed to be same as malloc */
if (oldmem == NULL) return mALLOc_impl(bytes);
@@ -1698,6 +1700,10 @@ Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes;
panic("pre-reloc realloc() is not supported");
}
#endif
+ if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
+ if (--malloc_max_allocs < 0)
+ return NULL;
+ }
newp = oldp = mem2chunk(oldmem);
newsize = oldsize = chunksize(oldp);
@@ -1907,7 +1913,8 @@ Void_t* mEMALIGn_impl(alignment, bytes) size_t alignment; size_t bytes;
mchunkptr remainder; /* spare room at end to split off */
long remainder_size; /* its size */
- if ((long)bytes < 0) return NULL;
+ if (bytes > CONFIG_SYS_MALLOC_LEN || (long)bytes < 0)
+ return NULL;
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
diff --git a/common/hwconfig.c b/common/hwconfig.c
index afaa6cb37ab..25a8cd5bf5d 100644
--- a/common/hwconfig.c
+++ b/common/hwconfig.c
@@ -77,7 +77,13 @@ static const char *__hwconfig(const char *opt, size_t *arglen,
/* if we are passed a buffer use it, otherwise try the environment */
if (!env_hwconfig) {
- if (!(gd->flags & GD_FLG_ENV_READY) && gd->env_valid != ENV_VALID) {
+#if CONFIG_IS_ENABLED(ENV_SUPPORT)
+ if (!(gd->flags & GD_FLG_ENV_READY) &&
+ gd->env_valid != ENV_VALID)
+#else
+ if (true)
+#endif
+ {
printf("WARNING: Calling __hwconfig without a buffer "
"and before environment is ready\n");
return NULL;
diff --git a/common/init/handoff.c b/common/init/handoff.c
index a7cd065fb38..86c020ee0b9 100644
--- a/common/init/handoff.c
+++ b/common/init/handoff.c
@@ -5,6 +5,7 @@
* Copyright 2018 Google, Inc
*/
+#include <bloblist.h>
#include <handoff.h>
#include <asm/global_data.h>
@@ -38,3 +39,14 @@ void handoff_load_dram_banks(struct spl_handoff *ho)
bd->bi_dram[i].size = ho->ram_bank[i].size;
}
}
+
+struct spl_handoff *handoff_get(void)
+{
+ struct spl_handoff *handoff;
+
+ handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+ sizeof(struct spl_handoff));
+ debug("Found SPL hand-off info %p\n", handoff);
+
+ return handoff;
+}
diff --git a/common/log_console.c b/common/log_console.c
index c27101b8fe2..9376baad664 100644
--- a/common/log_console.c
+++ b/common/log_console.c
@@ -38,10 +38,10 @@ static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
printf("%d-", rec->line);
if (fmt & BIT(LOGF_FUNC)) {
if (CONFIG_IS_ENABLED(USE_TINY_PRINTF)) {
- printf("%s()", rec->func);
+ printf("%s()", rec->func ?: "?");
} else {
printf("%*s()", CONFIG_LOGF_FUNC_PAD,
- rec->func);
+ rec->func ?: "?");
}
}
}
diff --git a/common/log_syslog.c b/common/log_syslog.c
index d01bb749c22..0dcb5f7cdea 100644
--- a/common/log_syslog.c
+++ b/common/log_syslog.c
@@ -88,7 +88,7 @@ static int log_syslog_emit(struct log_device *ldev, struct log_rec *rec)
if (fmt & BIT(LOGF_LINE))
append(&ptr, msg_end, "%d-", rec->line);
if (fmt & BIT(LOGF_FUNC))
- append(&ptr, msg_end, "%s()", rec->func);
+ append(&ptr, msg_end, "%s()", rec->func ?: "?");
if (fmt & BIT(LOGF_MSG))
append(&ptr, msg_end, "%s%s",
fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index 4e6d7952b3c..5a8ec538f8f 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -23,7 +23,7 @@ static void *alloc_simple(size_t bytes, int align)
addr = ALIGN(gd->malloc_base + gd->malloc_ptr, align);
new_ptr = addr + bytes - gd->malloc_base;
- log_debug("size=%lx, ptr=%lx, limit=%lx: ", (ulong)bytes, new_ptr,
+ log_debug("size=%lx, ptr=%lx, limit=%x: ", (ulong)bytes, new_ptr,
gd->malloc_limit);
if (new_ptr > gd->malloc_limit) {
log_err("alloc space exhausted\n");
@@ -87,6 +87,6 @@ void free_simple(void *ptr)
void malloc_simple_info(void)
{
- log_info("malloc_simple: %lx bytes used, %lx remain\n", gd->malloc_ptr,
+ log_info("malloc_simple: %x bytes used, %x remain\n", gd->malloc_ptr,
CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr);
}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 6f56ca911c1..3c44e329d62 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -78,6 +78,7 @@ config SPL_MAX_SIZE
hex "Maximum size of the SPL image, excluding BSS"
default 0x30000 if ARCH_MX6 && MX6_OCRAM_256KB
default 0x1b000 if AM33XX && !TI_SECURE_DEVICE
+ default 0xec00 if OMAP34XX
default 0x10000 if ARCH_MX6 && !MX6_OCRAM_256KB
default 0x7fa0 if SUNXI_SRAM_ADDRESS = 0x10000
default 0x7fa0 if SUNXI_SRAM_ADDRESS = 0x20000 && !MACH_SUN50I_H616
@@ -206,7 +207,7 @@ config SPL_BINMAN_SYMBOLS
config SPL_BINMAN_UBOOT_SYMBOLS
bool "Declare binman symbols for U-Boot phases in SPL"
depends on SPL_BINMAN_SYMBOLS
- default n if ARCH_IMX8M || ARCH_IMX9
+ default n if ARCH_IMX8M || ARCH_IMX8ULP || ARCH_IMX9
default y
help
This enables use of symbols in SPL which refer to U-Boot phases,
@@ -261,6 +262,7 @@ config SPL_LDSCRIPT
config SPL_TEXT_BASE
hex "SPL Text Base"
+ default 0x40200000 if OMAP34XX
default 0x402F4000 if AM43XX
default 0x402F0400 if AM33XX
default 0x40301350 if OMAP54XX
@@ -490,24 +492,45 @@ config SPL_DISPLAY_PRINT
the board.
config SPL_SYS_MMCSD_RAW_MODE
- bool
- help
- Support booting from an MMC without a filesystem.
-
-config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
- bool "MMC raw mode: by sector"
+ bool "Use raw reads to locate the next boot phase"
+ depends on SPL_DM_MMC || SPL_MMC
default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \
ARCH_MX6 || ARCH_MX7 || \
ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \
ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
OMAP54XX || AM33XX || AM43XX || \
TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
- select SPL_LOAD_BLOCK if SPL_MMC
- select SPL_SYS_MMCSD_RAW_MODE if SPL_MMC
+ help
+ Support booting from an MMC without a filesystem.
+
+if SPL_SYS_MMCSD_RAW_MODE
+
+choice
+ prompt "Method for locating next phase of boot (e.g. U-Boot)"
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ bool "MMC raw mode: by sector"
+ select SPL_LOAD_BLOCK
help
Use sector number for specifying U-Boot location on MMC/SD in
raw mode.
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+ bool "MMC raw mode: by partition"
+ select SPL_LOAD_BLOCK
+ help
+ Use a partition for loading U-Boot when using MMC/SD in raw mode.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
+ bool "MMC raw mode: by partition type"
+ depends on DOS_PARTITION
+ help
+ Use partition type for specifying U-Boot partition on MMC/SD in
+ raw mode. U-Boot will be loaded from the first partition of this
+ type to be found.
+
+endchoice
+
config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
hex "Address on the MMC to load U-Boot from"
depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
@@ -538,13 +561,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET
If unsure, leave the default.
-config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
- bool "MMC Raw mode: by partition"
- select SPL_LOAD_BLOCK if SPL_MMC
- select SPL_SYS_MMCSD_RAW_MODE if SPL_MMC
- help
- Use a partition for loading U-Boot when using MMC/SD in raw mode.
-
config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
hex "Partition to use to load U-Boot from"
depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
@@ -553,14 +569,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
Partition on the MMC to load U-Boot from when the MMC is being
used in raw mode
-config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
- bool "MMC raw mode: by partition type"
- depends on DOS_PARTITION && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
- help
- Use partition type for specifying U-Boot partition on MMC/SD in
- raw mode. U-Boot will be loaded from the first partition of this
- type to be found.
-
config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE
hex "Partition Type on the MMC to load U-Boot from"
depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
@@ -568,6 +576,8 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE
Partition Type on the MMC to load U-Boot from, when the MMC is being
used in raw mode.
+endif # SPL_SYS_MMCSD_RAW_MODE
+
config SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG
bool "Override eMMC EXT_CSC_PART_CONFIG by user defined partition"
depends on SUPPORT_EMMC_BOOT
diff --git a/common/spl/Kconfig.tpl b/common/spl/Kconfig.tpl
index 4ee3b9b826d..92d4d43ec87 100644
--- a/common/spl/Kconfig.tpl
+++ b/common/spl/Kconfig.tpl
@@ -23,7 +23,7 @@ config TPL_BINMAN_SYMBOLS
config TPL_BINMAN_UBOOT_SYMBOLS
bool "Declare binman symbols for U-Boot phases in TPL"
depends on TPL_BINMAN_SYMBOLS
- default n if ARCH_IMX8M || ARCH_IMX9
+ default n if ARCH_IMX8M || ARCH_IMX8ULP || ARCH_IMX9
default y
help
This enables use of symbols in TPL which refer to U-Boot phases,
diff --git a/common/spl/Kconfig.vpl b/common/spl/Kconfig.vpl
index f1993026bba..d06f36d4ee4 100644
--- a/common/spl/Kconfig.vpl
+++ b/common/spl/Kconfig.vpl
@@ -243,7 +243,7 @@ config VPL_BINMAN_SYMBOLS
config VPL_BINMAN_UBOOT_SYMBOLS
bool "Declare binman symbols for U-Boot phases in VPL"
depends on VPL_BINMAN_SYMBOLS
- default n if ARCH_IMX8M || ARCH_IMX9
+ default n if ARCH_IMX8M || ARCH_IMX8ULP || ARCH_IMX9
default y
help
This enables use of symbols in VPL which refer to U-Boot phases,
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 4809f9c3ec1..137b18428bd 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -37,3 +37,5 @@ obj-$(CONFIG_$(SPL_TPL_)SPI_LOAD) += spl_spi.o
obj-$(CONFIG_$(SPL_TPL_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(SPL_TPL_)USB_SDP_SUPPORT) += spl_sdp.o
endif
+
+obj-$(CONFIG_$(SPL_TPL_)UPL) += spl_upl.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 7794ddccade..5886d2c5121 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -245,7 +245,6 @@ __weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)
return map_sysmem(CONFIG_TEXT_BASE + offset, 0);
}
-#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
{
ulong u_boot_pos = spl_get_image_pos();
@@ -273,7 +272,6 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
spl_image->os = IH_OS_U_BOOT;
spl_image->name = "U-Boot";
}
-#endif
__weak int spl_parse_board_header(struct spl_image_info *spl_image,
const struct spl_boot_device *bootdev,
@@ -308,8 +306,10 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
ret = spl_parse_legacy_header(spl_image, header);
if (ret)
return ret;
- } else {
-#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
+ return 0;
+ }
+
+ if (IS_ENABLED(CONFIG_SPL_PANIC_ON_RAW_IMAGE)) {
/*
* CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the
* code which loads images in SPL cannot guarantee that
@@ -319,10 +319,9 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
* is bad, and thus should be skipped silently.
*/
panic("** no mkimage signature but raw image not supported");
-#endif
+ }
-#if CONFIG_IS_ENABLED(OS_BOOT)
-#if defined(CMD_BOOTI)
+ if (CONFIG_IS_ENABLED(OS_BOOT) && IS_ENABLED(CONFIG_CMD_BOOTI)) {
ulong start, size;
if (!booti_setup((ulong)header, &start, &size, 0)) {
@@ -336,7 +335,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
spl_image->load_addr, spl_image->size);
return 0;
}
-#elif defined(CMD_BOOTZ)
+ } else if (CONFIG_IS_ENABLED(OS_BOOT) && IS_ENABLED(CONFIG_CMD_BOOTZ)) {
ulong start, end;
if (!bootz_setup((ulong)header, &start, &end)) {
@@ -350,22 +349,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
spl_image->load_addr, spl_image->size);
return 0;
}
-#endif
-#endif
+ }
- if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header)))
- return 0;
+ if (!spl_parse_board_header(spl_image, bootdev, (const void *)header,
+ sizeof(*header)))
+ return 0;
-#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
+ if (IS_ENABLED(CONFIG_SPL_RAW_IMAGE_SUPPORT)) {
/* Signature not found - assume u-boot.bin */
debug("mkimage signature not found - ih_magic = %x\n",
- header->ih_magic);
+ header->ih_magic);
spl_set_header_raw_uboot(spl_image);
-#else
+ } else {
/* RAW image not supported, proceed to other boot methods. */
debug("Raw boot image support not enabled, proceeding to other boot methods\n");
return -EINVAL;
-#endif
}
return 0;
@@ -720,7 +718,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
initr_watchdog();
if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
- IS_ENABLED(CONFIG_SPL_ATF))
+ IS_ENABLED(CONFIG_SPL_ATF) || IS_ENABLED(CONFIG_SPL_NET))
dram_init_banksize();
if (CONFIG_IS_ENABLED(PCI) && !(gd->flags & GD_FLG_DM_DEAD)) {
@@ -784,7 +782,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
}
if (CONFIG_IS_ENABLED(SYS_MALLOC_F) &&
!IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIZE))
- debug("SPL malloc() used 0x%lx bytes (%ld KB)\n",
+ debug("SPL malloc() used 0x%x bytes (%d KB)\n",
gd_malloc_ptr(), gd_malloc_ptr() / 1024);
bootstage_mark_name(get_bootstage_id(false), "end phase");
@@ -810,6 +808,14 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
printf(SPL_TPL_PROMPT
"SPL hand-off write failed (err=%d)\n", ret);
}
+ if (CONFIG_IS_ENABLED(UPL_OUT) && (gd->flags & GD_FLG_UPL)) {
+ ret = spl_write_upl_handoff(&spl_image);
+ if (ret) {
+ printf(SPL_TPL_PROMPT
+ "UPL hand-off write failed (err=%d)\n", ret);
+ hang();
+ }
+ }
if (CONFIG_IS_ENABLED(BLOBLIST)) {
ret = bloblist_finish();
if (ret)
@@ -832,7 +838,7 @@ void preloader_console_init(void)
serial_init(); /* serial communications setup */
- gd->have_console = 1;
+ gd->flags |= GD_FLG_HAVE_CONSOLE;
#if CONFIG_IS_ENABLED(BANNER_PRINT)
puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
@@ -895,7 +901,7 @@ ulong spl_relocate_stack_gd(void)
#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_IS_ENABLED(SYS_MALLOC_F)
if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
- debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
+ debug("SPL malloc() before relocation used 0x%x bytes (%d KB)\n",
gd->malloc_ptr, gd->malloc_ptr / 1024);
ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
gd->malloc_base = ptr;
diff --git a/common/spl/spl_blk_fs.c b/common/spl/spl_blk_fs.c
index bc551c5c074..bbf90a9741e 100644
--- a/common/spl/spl_blk_fs.c
+++ b/common/spl/spl_blk_fs.c
@@ -80,11 +80,8 @@ int spl_blk_load_image(struct spl_image_info *spl_image,
return ret;
}
- load.read = spl_fit_read;
- if (IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN))
- spl_set_bl_len(&load, ARCH_DMA_MINALIGN);
- else
- spl_set_bl_len(&load, 1);
- load.priv = &dev;
+ spl_load_init(&load, spl_fit_read, &dev,
+ IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN) ?
+ ARCH_DMA_MINALIGN : 1);
return spl_load(spl_image, bootdev, &load, filesize, 0);
}
diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c
index 76f49a5a8a6..c5478820a9b 100644
--- a/common/spl/spl_ext.c
+++ b/common/spl/spl_ext.c
@@ -51,8 +51,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image,
goto end;
}
- spl_set_bl_len(&load, 1);
- load.read = spl_fit_read;
+ spl_load_init(&load, spl_fit_read, NULL, 1);
err = spl_load(spl_image, bootdev, &load, filelen, 0);
end:
diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c
index bd8aab253a9..fce451b7664 100644
--- a/common/spl/spl_fat.c
+++ b/common/spl/spl_fat.c
@@ -83,12 +83,10 @@ int spl_load_image_fat(struct spl_image_info *spl_image,
size = 0;
}
- load.read = spl_fit_read;
- if (IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN))
- spl_set_bl_len(&load, ARCH_DMA_MINALIGN);
- else
- spl_set_bl_len(&load, 1);
- load.priv = (void *)filename;
+ spl_load_init(&load, spl_fit_read, (void *)filename,
+ IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN) ?
+ ARCH_DMA_MINALIGN : 1);
+
err = spl_load(spl_image, bootdev, &load, size, 0);
end:
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 2a097f4464c..1ad5a69d807 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -12,6 +12,7 @@
#include <memalign.h>
#include <mapmem.h>
#include <spl.h>
+#include <upl.h>
#include <sysinfo.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -336,6 +337,8 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
image_info->entry_point = FDT_ERROR;
}
+ upl_add_image(fit, node, load_addr, length);
+
return 0;
}
@@ -847,6 +850,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
spl_image->entry_point = spl_image->load_addr;
spl_image->flags |= SPL_FIT_FOUND;
+ upl_set_fit_info(map_to_sysmem(ctx.fit), ctx.conf_node,
+ spl_image->entry_point);
return 0;
}
@@ -941,6 +946,10 @@ int spl_load_fit_image(struct spl_image_info *spl_image,
if (ret < 0)
return ret;
}
+ spl_image->flags |= SPL_FIT_FOUND;
+
+ upl_set_fit_info(map_to_sysmem(header), conf_noffset,
+ spl_image->entry_point);
return 0;
}
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index ccab0be4be2..3fd81608e9f 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -46,21 +46,17 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
struct blk_desc *bd = mmc_get_blk_desc(mmc);
struct spl_load_info load;
- load.priv = bd;
- spl_set_bl_len(&load, bd->blksz);
- load.read = h_spl_load_read;
+ spl_load_init(&load, h_spl_load_read, bd, bd->blksz);
ret = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz);
if (ret) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("mmc_load_image_raw_sector: mmc block read error\n");
-#endif
- return -1;
+ return ret;
}
return 0;
}
-static int spl_mmc_get_device_index(u32 boot_device)
+static int spl_mmc_get_device_index(uint boot_device)
{
switch (boot_device) {
case BOOT_DEVICE_MMC1:
@@ -70,40 +66,30 @@ static int spl_mmc_get_device_index(u32 boot_device)
return 1;
}
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf("spl: unsupported mmc boot device.\n");
-#endif
return -ENODEV;
}
-static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
+static int spl_mmc_find_device(struct mmc **mmcp, int mmc_dev)
{
- int err, mmc_dev;
-
- mmc_dev = spl_mmc_get_device_index(boot_device);
- if (mmc_dev < 0)
- return mmc_dev;
+ int ret;
#if CONFIG_IS_ENABLED(DM_MMC)
- err = mmc_init_device(mmc_dev);
+ ret = mmc_init_device(mmc_dev);
#else
- err = mmc_initialize(NULL);
+ ret = mmc_initialize(NULL);
#endif /* DM_MMC */
- if (err) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
- printf("spl: could not initialize mmc. error: %d\n", err);
-#endif
- return err;
+ if (ret) {
+ printf("spl: could not initialize mmc. error: %d\n", ret);
+ return ret;
}
*mmcp = find_mmc_device(mmc_dev);
- err = *mmcp ? 0 : -ENODEV;
- if (err) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ ret = *mmcp ? 0 : -ENODEV;
+ if (ret) {
printf("spl: could not find mmc device %d. error: %d\n",
- mmc_dev, err);
-#endif
- return err;
+ mmc_dev, ret);
+ return ret;
}
return 0;
@@ -116,14 +102,14 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
unsigned long sector)
{
struct disk_partition info;
- int err;
+ int ret;
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
int type_part;
/* Only support MBR so DOS_ENTRY_NUMBERS */
for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
- err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
- if (err)
+ ret = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
+ if (ret)
continue;
if (info.sys_ind ==
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
@@ -133,12 +119,10 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
}
#endif
- err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
- if (err) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ ret = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
+ if (ret) {
puts("spl: partition error\n");
-#endif
- return -1;
+ return ret;
}
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
@@ -164,10 +148,8 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
(void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR);
if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("mmc_load_image_raw_os: mmc block read error\n");
-#endif
- return -1;
+ return -EIO;
}
#endif /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
@@ -205,7 +187,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
struct mmc *mmc,
const char *filename)
{
- int err = -ENOSYS;
+ int ret = -ENOSYS;
__maybe_unused int partition = CONFIG_SYS_MMCSD_FS_BOOT_PARTITION;
@@ -214,8 +196,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
struct disk_partition info;
debug("Checking for the first MBR bootable partition\n");
for (int type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
- err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
- if (err)
+ ret = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
+ if (ret)
continue;
debug("Partition %d is of type %d and bootable=%d\n", type_part, info.sys_ind, info.bootable);
if (info.bootable != 0) {
@@ -233,40 +215,40 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
#ifdef CONFIG_SPL_FS_FAT
if (!spl_start_uboot()) {
- err = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
- partition);
- if (!err)
- return err;
+ ret = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
+ partition);
+ if (!ret)
+ return 0;
}
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
- err = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc),
+ ret = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc),
partition,
filename);
- if (!err)
- return err;
+ if (!ret)
+ return ret;
#endif
#endif
#ifdef CONFIG_SPL_FS_EXT4
if (!spl_start_uboot()) {
- err = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
- partition);
- if (!err)
- return err;
+ ret = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
+ partition);
+ if (!ret)
+ return 0;
}
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
- err = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc),
+ ret = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc),
partition,
filename);
- if (!err)
- return err;
+ if (!ret)
+ return 0;
#endif
#endif
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
- err = -ENOENT;
+ ret = -ENOENT;
#endif
- return err;
+ return ret;
}
#endif
@@ -354,87 +336,82 @@ int spl_mmc_load(struct spl_image_info *spl_image,
unsigned long raw_sect)
{
u32 boot_mode;
- int err = 0;
+ int ret = 0;
__maybe_unused int part = 0;
int mmc_dev;
/* Perform peripheral init only once for an mmc device */
mmc_dev = spl_mmc_get_device_index(bootdev->boot_device);
if (!mmc || spl_mmc_get_mmc_devnum(mmc) != mmc_dev) {
- err = spl_mmc_find_device(&mmc, bootdev->boot_device);
- if (err)
- return err;
+ ret = spl_mmc_find_device(&mmc, mmc_dev);
+ if (ret)
+ return ret;
- err = mmc_init(mmc);
- if (err) {
+ ret = mmc_init(mmc);
+ if (ret) {
mmc = NULL;
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
- printf("spl: mmc init failed with error: %d\n", err);
-#endif
- return err;
+ printf("spl: mmc init failed with error: %d\n", ret);
+ return ret;
}
}
boot_mode = spl_mmc_boot_mode(mmc, bootdev->boot_device);
- err = -EINVAL;
+ ret = -EINVAL;
switch (boot_mode) {
case MMCSD_MODE_EMMCBOOT:
part = spl_mmc_emmc_boot_partition(mmc);
if (CONFIG_IS_ENABLED(MMC_TINY))
- err = mmc_switch_part(mmc, part);
+ ret = mmc_switch_part(mmc, part);
else
- err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+ ret = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
- if (err) {
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ if (ret) {
puts("spl: mmc partition switch failed\n");
-#endif
- return err;
+ return ret;
}
/* Fall through */
case MMCSD_MODE_RAW:
debug("spl: mmc boot mode: raw\n");
if (!spl_start_uboot()) {
- err = mmc_load_image_raw_os(spl_image, bootdev, mmc);
- if (!err)
- return err;
+ ret = mmc_load_image_raw_os(spl_image, bootdev, mmc);
+ if (!ret)
+ return 0;
}
raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
- err = mmc_load_image_raw_partition(spl_image, bootdev,
+ ret = mmc_load_image_raw_partition(spl_image, bootdev,
mmc, raw_part,
raw_sect);
- if (!err)
- return err;
+ if (!ret)
+ return 0;
#endif
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
- err = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
- raw_sect + spl_mmc_raw_uboot_offset(part));
- if (!err)
- return err;
+ ret = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
+ raw_sect +
+ spl_mmc_raw_uboot_offset(part));
+ if (!ret)
+ return 0;
#endif
/* If RAW mode fails, try FS mode. */
#ifdef CONFIG_SYS_MMCSD_FS_BOOT
case MMCSD_MODE_FS:
debug("spl: mmc boot mode: fs\n");
- err = spl_mmc_do_fs_boot(spl_image, bootdev, mmc, filename);
- if (!err)
- return err;
+ ret = spl_mmc_do_fs_boot(spl_image, bootdev, mmc, filename);
+ if (!ret)
+ return 0;
break;
#endif
-#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
default:
puts("spl: mmc: wrong boot mode\n");
-#endif
}
- return err;
+ return ret;
}
int spl_mmc_load_image(struct spl_image_info *spl_image,
diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c
index 5631fa6d563..22883f4e8b9 100644
--- a/common/spl/spl_nand.c
+++ b/common/spl/spl_nand.c
@@ -71,9 +71,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
{
struct spl_load_info load;
- load.priv = &offset;
- spl_set_bl_len(&load, 1);
- load.read = spl_nand_read;
+ spl_load_init(&load, spl_nand_read, &offset, 1);
return spl_load(spl_image, bootdev, &load, 0, offset);
}
diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c
index be7278bb933..2be7b73ed35 100644
--- a/common/spl/spl_net.c
+++ b/common/spl/spl_net.c
@@ -47,8 +47,7 @@ static int spl_net_load_image(struct spl_image_info *spl_image,
return rv;
}
- spl_set_bl_len(&load, 1);
- load.read = spl_net_load_read;
+ spl_load_init(&load, spl_net_load_read, NULL, 1);
return spl_load(spl_image, bootdev, &load, 0, 0);
}
#endif
diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c
index ed76b5e1293..1021d933999 100644
--- a/common/spl/spl_nor.c
+++ b/common/spl/spl_nor.c
@@ -49,8 +49,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
int ret;
debug("Found FIT\n");
- spl_set_bl_len(&load, 1);
- load.read = spl_nor_load_read;
+ spl_load_init(&load, spl_nor_load_read, NULL, 1);
ret = spl_load_simple_fit(spl_image, &load,
CONFIG_SYS_OS_BASE,
@@ -93,8 +92,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
* Load real U-Boot from its location in NOR flash to its
* defined location in SDRAM
*/
- spl_set_bl_len(&load, 1);
- load.read = spl_nor_load_read;
+ spl_load_init(&load, spl_nor_load_read, NULL, 1);
return spl_load(spl_image, bootdev, &load, 0, spl_nor_get_uboot_base());
}
SPL_LOAD_IMAGE_METHOD("NOR", 0, BOOT_DEVICE_NOR, spl_nor_load_image);
diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c
index 5a23841f698..71b7a8374bb 100644
--- a/common/spl/spl_ram.c
+++ b/common/spl/spl_ram.c
@@ -69,8 +69,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
struct spl_load_info load;
debug("Found FIT\n");
- spl_set_bl_len(&load, 1);
- load.read = spl_ram_load_read;
+ spl_load_init(&load, spl_ram_load_read, NULL, 1);
ret = spl_load_simple_fit(spl_image, &load, 0, header);
} else {
ulong u_boot_pos = spl_get_image_pos();
diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c
index 2047248f39b..f36863fe48d 100644
--- a/common/spl/spl_semihosting.c
+++ b/common/spl/spl_semihosting.c
@@ -43,9 +43,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image,
}
len = ret;
- load.read = smh_fit_read;
- spl_set_bl_len(&load, 1);
- load.priv = &fd;
+ spl_load_init(&load, smh_fit_read, &fd, 1);
ret = spl_load(spl_image, bootdev, &load, len, 0);
if (ret)
log_debug("could not read %s: %d\n", filename, ret);
diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
index 8ab4803f7c4..691a431a926 100644
--- a/common/spl/spl_spi.c
+++ b/common/spl/spl_spi.c
@@ -77,9 +77,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
return -ENODEV;
}
- load.priv = flash;
- spl_set_bl_len(&load, 1);
- load.read = spl_spi_fit_read;
+ spl_load_init(&load, spl_spi_fit_read, flash, 1);
#if CONFIG_IS_ENABLED(OS_BOOT)
if (spl_start_uboot()) {
diff --git a/common/spl/spl_upl.c b/common/spl/spl_upl.c
new file mode 100644
index 00000000000..067d437150f
--- /dev/null
+++ b/common/spl/spl_upl.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UPL handoff parsing
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEGORY UCLASS_BOOTSTD
+
+#include <alist.h>
+#include <bloblist.h>
+#include <dm.h>
+#include <image.h>
+#include <mapmem.h>
+#include <serial.h>
+#include <spl.h>
+#include <upl.h>
+#include <video.h>
+#include <asm/global_data.h>
+#include <dm/read.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct upl s_upl;
+
+void upl_set_fit_addr(ulong fit)
+{
+ struct upl *upl = &s_upl;
+
+ upl->fit = fit;
+}
+
+void upl_set_fit_info(ulong fit, int conf_offset, ulong entry_addr)
+{
+ struct upl *upl = &s_upl;
+
+ upl->fit = fit;
+ upl->conf_offset = conf_offset;
+ log_debug("upl: add fit %lx conf %x\n", fit, conf_offset);
+}
+
+int _upl_add_image(int node, ulong load_addr, ulong size, const char *desc)
+{
+ struct upl *upl = &s_upl;
+ struct upl_image img;
+
+ img.load = load_addr;
+ img.size = size;
+ img.offset = node;
+ img.description = desc;
+ if (!alist_add(&upl->image, img))
+ return -ENOMEM;
+ log_debug("upl: add image %s at %lx size %lx\n", desc, load_addr, size);
+
+ return 0;
+}
+
+static int write_serial(struct upl_serial *ser)
+{
+ struct udevice *dev = gd->cur_serial_dev;
+ struct serial_device_info info;
+ struct memregion region;
+ int ret;
+
+ if (!dev)
+ return log_msg_ret("ser", -ENOENT);
+ ret = serial_getinfo(dev, &info);
+ if (ret)
+ return log_msg_ret("inf", ret);
+
+ ser->compatible = ofnode_read_string(dev_ofnode(dev), "compatible");
+ ser->clock_frequency = info.clock;
+ ser->current_speed = gd->baudrate;
+ region.base = info.addr;
+ region.size = info.size;
+ alist_init_struct(&ser->reg, struct memregion);
+ if (!alist_add(&ser->reg, region))
+ return -ENOMEM;
+ ser->reg_io_shift = info.reg_shift;
+ ser->reg_offset = info.reg_offset;
+ ser->reg_io_width = info.reg_width;
+ ser->virtual_reg = 0;
+ ser->access_type = info.addr_space;
+
+ return 0;
+}
+
+static int write_graphics(struct upl_graphics *gra)
+{
+ struct video_uc_plat *plat;
+ struct video_priv *priv;
+ struct memregion region;
+ struct udevice *dev;
+
+ alist_init_struct(&gra->reg, struct memregion);
+ uclass_find_first_device(UCLASS_VIDEO, &dev);
+ if (!dev || !device_active(dev))
+ return log_msg_ret("vid", -ENOENT);
+
+ plat = dev_get_uclass_plat(dev);
+ region.base = plat->base;
+ region.size = plat->size;
+ if (!alist_add(&gra->reg, region))
+ return log_msg_ret("reg", -ENOMEM);
+
+ priv = dev_get_uclass_priv(dev);
+ gra->width = priv->xsize;
+ gra->height = priv->ysize;
+ gra->stride = priv->line_length; /* private field */
+ switch (priv->format) {
+ case VIDEO_RGBA8888:
+ case VIDEO_X8R8G8B8:
+ gra->format = UPLGF_ARGB32;
+ break;
+ case VIDEO_X8B8G8R8:
+ gra->format = UPLGF_ABGR32;
+ break;
+ case VIDEO_X2R10G10B10:
+ log_debug("device '%s': VIDEO_X2R10G10B10 not supported\n",
+ dev->name);
+ return log_msg_ret("for", -EPROTO);
+ case VIDEO_UNKNOWN:
+ log_debug("device '%s': Unknown video format\n", dev->name);
+ return log_msg_ret("for", -EPROTO);
+ }
+
+ return 0;
+}
+
+int spl_write_upl_handoff(struct spl_image_info *spl_image)
+{
+ struct upl *upl = &s_upl;
+ struct abuf buf;
+ ofnode root;
+ void *ptr;
+ int ret;
+
+ log_debug("UPL: Writing handoff - image_count=%d\n", upl->image.count);
+ upl->addr_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1;
+ upl->size_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1;
+ upl->bootmode = UPLBM_DEFAULT;
+ ret = write_serial(&upl->serial);
+ if (ret)
+ return log_msg_ret("ser", ret);
+ ret = write_graphics(&upl->graphics);
+ if (ret && ret != -ENOENT)
+ return log_msg_ret("gra", ret);
+
+ root = ofnode_root();
+ ret = upl_write_handoff(upl, root, true);
+ if (ret)
+ return log_msg_ret("wr", ret);
+
+ ret = oftree_to_fdt(oftree_default(), &buf);
+ if (ret)
+ return log_msg_ret("fdt", ret);
+ log_debug("FDT size %zx\n", abuf_size(&buf));
+
+ ptr = bloblist_add(BLOBLISTT_CONTROL_FDT, abuf_size(&buf), 0);
+ if (!ptr)
+ return log_msg_ret("blo", -ENOENT);
+ memcpy(ptr, abuf_data(&buf), abuf_size(&buf));
+
+ return 0;
+}
+
+void spl_upl_init(void)
+{
+ upl_init(&s_upl);
+}
diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c
index 4c7222af612..2be957134c1 100644
--- a/common/spl/spl_ymodem.c
+++ b/common/spl/spl_ymodem.c
@@ -132,11 +132,9 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image,
struct ymodem_fit_info info;
debug("Found FIT\n");
- load.priv = (void *)&info;
- spl_set_bl_len(&load, 1);
+ spl_load_init(&load, ymodem_read_fit, (void *)&info, 1);
info.buf = buf;
info.image_read = BUF_SIZE;
- load.read = ymodem_read_fit;
ret = spl_load_simple_fit(spl_image, &load, 0, (void *)buf);
size = info.image_read;