summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig3
-rw-r--r--common/board_f.c84
-rw-r--r--common/board_r.c14
-rw-r--r--common/bootstage.c8
-rw-r--r--common/cli_hush_modern.c2
-rw-r--r--common/cli_hush_upstream.c150
-rw-r--r--common/console.c19
-rw-r--r--common/dlmalloc.c23
-rw-r--r--common/flash.c2
-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/Kconfig56
-rw-r--r--common/spl/Makefile2
-rw-r--r--common/spl/spl.c55
-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.c163
-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
30 files changed, 551 insertions, 291 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 83c81edac20..e1b8557e0cb 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -986,7 +986,8 @@ config ANDROID_AB_BACKUP_OFFSET
help
If non-zero, a backup bootloader message starting at this offset in
the partition will tried in the event that the primary one (starting
- at offset 0) fails its checksum.
+ at offset 0) fails its checksum. The offset is in bytes and must be
+ multiple of the block size.
endmenu
diff --git a/common/board_f.c b/common/board_f.c
index 30d7fbf498f..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
@@ -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..4faaa202421 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -22,6 +22,7 @@
#include <hang.h>
#include <image.h>
#include <irq_func.h>
+#include <lmb.h>
#include <log.h>
#include <net.h>
#include <asm/cache.h>
@@ -192,7 +193,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 */
@@ -510,6 +511,14 @@ int initr_mem(void)
}
#endif
+static int initr_lmb(void)
+{
+ if (CONFIG_IS_ENABLED(LMB))
+ return lmb_init();
+ else
+ return 0;
+}
+
static int dm_announce(void)
{
int device_count;
@@ -521,6 +530,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 ||
@@ -610,6 +621,7 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_CLOCKS
set_cpu_clk_info, /* Setup clock information */
#endif
+ initr_lmb,
#ifdef CONFIG_EFI_LOADER
efi_memory_init,
#endif
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/cli_hush_modern.c b/common/cli_hush_modern.c
index cd88c9de8ab..deb61c3389d 100644
--- a/common/cli_hush_modern.c
+++ b/common/cli_hush_modern.c
@@ -25,7 +25,7 @@
/*
* BusyBox Version: UPDATE THIS WHEN PULLING NEW UPSTREAM REVISION!
*/
-#define BB_VER "1.35.0.git7d1c7d833785"
+#define BB_VER "1.37.0.git23da5c4b716b"
/*
* Define hush features by the names used upstream.
diff --git a/common/cli_hush_upstream.c b/common/cli_hush_upstream.c
index 7874b399d14..ab5aa5f9b36 100644
--- a/common/cli_hush_upstream.c
+++ b/common/cli_hush_upstream.c
@@ -1651,12 +1651,22 @@ static int dup_CLOEXEC(int fd, int avoid_fd)
newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
if (newfd >= 0) {
if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
- fcntl(newfd, F_SETFD, FD_CLOEXEC);
+ close_on_exec_on(newfd);
} else { /* newfd < 0 */
if (errno == EBUSY)
goto repeat;
if (errno == EINTR)
goto repeat;
+ if (errno != EBADF) {
+ /* "echo >&9999" gets EINVAL trying to save fd 1 to above 9999.
+ * We could try saving it _below_ 9999 instead (how?), but
+ * this probably means that dup2(9999,1) to effectuate >&9999
+ * would also not work: fd 9999 can't exist.
+ * (This differs from "echo >&99" where saving works, but
+ * subsequent dup2(99,1) fails if fd 99 is not open).
+ */
+ bb_perror_msg("fcntl(%d,F_DUPFD,%d)", fd, avoid_fd + 1);
+ }
}
return newfd;
}
@@ -1677,7 +1687,7 @@ static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
xfunc_die();
}
if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
- fcntl(newfd, F_SETFD, FD_CLOEXEC);
+ close_on_exec_on(newfd);
close(fd);
return newfd;
}
@@ -5851,6 +5861,15 @@ static struct pipe *parse_stream(char **pstring,
}
o_free_and_set_NULL(&ctx.word);
done_pipe(&ctx, PIPE_SEQ);
+
+ /* Do we sit inside of any if's, loops or case's? */
+ if (HAS_KEYWORDS
+ IF_HAS_KEYWORDS(&& (ctx.ctx_res_w != RES_NONE || ctx.old_flag != 0))
+ ) {
+ syntax_error_unterm_str("compound statement");
+ goto parse_error_exitcode1;
+ }
+
pi = ctx.list_head;
/* If we got nothing... */
/* (this makes bare "&" cmd a no-op.
@@ -5873,7 +5892,7 @@ static struct pipe *parse_stream(char **pstring,
// *heredoc_cnt_ptr = heredoc_cnt;
debug_leave();
debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
- debug_printf_parse("parse_stream return %p\n", pi);
+ debug_printf_parse("parse_stream return %p: EOF\n", pi);
return pi;
}
@@ -8384,10 +8403,16 @@ static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
if (sq) for (; sq[i].orig_fd >= 0; i++) {
/* If we collide with an already moved fd... */
if (fd == sq[i].moved_to) {
- sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
- debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
- if (sq[i].moved_to < 0) /* what? */
- xfunc_die();
+ moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
+ debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, moved_to);
+ if (moved_to < 0) {
+ /* "echo 2>/dev/tty 10>&9999" testcase:
+ * We move fd 2 to 10, then discover we need to move fd 10
+ * (and not hit 9999) and the latter fails.
+ */
+ return NULL; /* fcntl failed */
+ }
+ sq[i].moved_to = moved_to;
return sq;
}
if (fd == sq[i].orig_fd) {
@@ -8401,7 +8426,7 @@ static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
moved_to = dup_CLOEXEC(fd, avoid_fd);
debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
if (moved_to < 0 && errno != EBADF)
- xfunc_die();
+ return NULL; /* fcntl failed (not because fd is closed) */
return append_squirrel(sq, i, fd, moved_to);
}
@@ -8434,6 +8459,8 @@ static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
*/
static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
{
+ struct squirrel *new_squirrel;
+
if (avoid_fd < 9) /* the important case here is that it can be -1 */
avoid_fd = 9;
@@ -8497,7 +8524,10 @@ static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
}
/* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
- *sqp = add_squirrel(*sqp, fd, avoid_fd);
+ new_squirrel = add_squirrel(*sqp, fd, avoid_fd);
+ if (!new_squirrel)
+ return -1; /* redirect error */
+ *sqp = new_squirrel;
return 0; /* "we did not close fd" */
}
@@ -8568,8 +8598,11 @@ static int internally_opened_fd(int fd, struct squirrel *sq)
return 0;
}
-/* squirrel != NULL means we squirrel away copies of stdin, stdout,
- * and stderr if they are redirected. */
+/* sqp != NULL means we squirrel away copies of stdin, stdout,
+ * and stderr if they are redirected.
+ * If redirection fails, return 1. This will make caller
+ * skip command execution and restore already created redirect fds.
+ */
static int setup_redirects(struct command *prog, struct squirrel **sqp)
{
struct redir_struct *redir;
@@ -8580,7 +8613,8 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
if (redir->rd_type == REDIRECT_HEREDOC2) {
/* "rd_fd<<HERE" case */
- save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp);
+ if (save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp) < 0)
+ return 1;
/* for REDIRECT_HEREDOC2, rd_filename holds _contents_
* of the heredoc */
debug_printf_redir("set heredoc '%s'\n",
@@ -8600,7 +8634,7 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
* "cmd > <file" (2nd redirect starts too early)
*/
syntax_error("invalid redirect");
- continue;
+ return 1;
}
mode = redir_table[redir->rd_type].mode;
p = expand_string_to_string(redir->rd_filename,
@@ -8615,7 +8649,9 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
*/
return 1;
}
- if (newfd == redir->rd_fd && sqp) {
+ if (newfd == redir->rd_fd && sqp
+ && sqp != ERR_PTR /* not a redirect in "exec" */
+ ) {
/* open() gave us precisely the fd we wanted.
* This means that this fd was not busy
* (not opened to anywhere).
@@ -8637,6 +8673,8 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
/* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
+ if (closed < 0)
+ return 1; /* error */
if (newfd == REDIRFD_CLOSE) {
/* "N>&-" means "close me" */
if (!closed) {
@@ -8650,13 +8688,16 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
* and second redirect closes 3! Restore code then closes 3 again.
*/
} else {
- /* if newfd is a script fd or saved fd, simulate EBADF */
+ /* if newfd is a script fd or saved fd, do not allow to use it */
if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) {
- //errno = EBADF;
- //bb_perror_msg_and_die("can't duplicate file descriptor");
- newfd = -1; /* same effect as code above */
+ bb_error_msg("fd#%d is not open", newfd);
+ return 1;
+ }
+ if (dup2(newfd, redir->rd_fd) < 0) {
+ /* "echo >&99" testcase */
+ bb_perror_msg("dup2(%d,%d)", newfd, redir->rd_fd);
+ return 1;
}
- xdup2(newfd, redir->rd_fd);
if (redir->rd_dup == REDIRFD_TO_FILE)
/* "rd_fd > FILE" */
close(newfd);
@@ -9731,6 +9772,7 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
return rcode;
}
#endif
+#endif /* !__U_BOOT__ */
/* Start all the jobs, but don't wait for anything to finish.
* See checkjobs().
@@ -9758,6 +9800,38 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
* backgrounded: cmd & { list } &
* subshell: ( list ) [&]
*/
+static void set_G_ifs(void)
+{
+ /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
+ * Result should be 3 lines: q w e, qwe, q w e
+ */
+ if (G.ifs_whitespace != G.ifs)
+ free(G.ifs_whitespace);
+ G.ifs = get_local_var_value("IFS");
+ if (G.ifs) {
+ char *p;
+ G.ifs_whitespace = (char*)G.ifs;
+ p = skip_whitespace(G.ifs);
+ if (*p) {
+ /* Not all $IFS is whitespace */
+ char *d;
+ int len = p - G.ifs;
+ p = skip_non_whitespace(p);
+ G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
+ d = mempcpy(G.ifs_whitespace, G.ifs, len);
+ while (*p) {
+ if (isspace(*p))
+ *d++ = *p;
+ p++;
+ }
+ *d = '\0';
+ }
+ } else {
+ G.ifs = defifs;
+ G.ifs_whitespace = (char*)G.ifs;
+ }
+}
+#ifndef __U_BOOT__
#if !ENABLE_HUSH_MODE_X
#define redirect_and_varexp_helper(command, sqp, argv_expanded) \
redirect_and_varexp_helper(command, sqp)
@@ -9810,34 +9884,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
debug_enter();
- /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
- * Result should be 3 lines: q w e, qwe, q w e
- */
- if (G.ifs_whitespace != G.ifs)
- free(G.ifs_whitespace);
- G.ifs = get_local_var_value("IFS");
- if (G.ifs) {
- char *p;
- G.ifs_whitespace = (char*)G.ifs;
- p = skip_whitespace(G.ifs);
- if (*p) {
- /* Not all $IFS is whitespace */
- char *d;
- int len = p - G.ifs;
- p = skip_non_whitespace(p);
- G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
- d = mempcpy(G.ifs_whitespace, G.ifs, len);
- while (*p) {
- if (isspace(*p))
- *d++ = *p;
- p++;
- }
- *d = '\0';
- }
- } else {
- G.ifs = defifs;
- G.ifs_whitespace = (char*)G.ifs;
- }
+ set_G_ifs();
#ifndef __U_BOOT__
IF_HUSH_JOB(pi->pgrp = -1;)
@@ -10362,6 +10409,8 @@ static int run_list(struct pipe *pi)
debug_enter();
#endif /* !__U_BOOT__ */
+ set_G_ifs();
+
#if ENABLE_HUSH_LOOPS
/* Check syntax for "for" */
{
@@ -11377,7 +11426,7 @@ int hush_main(int argc, char **argv)
G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
if (G_interactive_fd < 0) {
/* try to dup to any fd */
- G_interactive_fd = dup(STDIN_FILENO);
+ G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
if (G_interactive_fd < 0) {
/* give up */
G_interactive_fd = 0;
@@ -11387,8 +11436,6 @@ int hush_main(int argc, char **argv)
}
debug_printf("interactive_fd:%d\n", G_interactive_fd);
if (G_interactive_fd) {
- close_on_exec_on(G_interactive_fd);
-
if (G_saved_tty_pgrp) {
/* If we were run as 'hush &', sleep until we are
* in the foreground (tty pgrp == our pgrp).
@@ -11463,9 +11510,6 @@ int hush_main(int argc, char **argv)
G_interactive_fd = 0;
}
}
- if (G_interactive_fd) {
- close_on_exec_on(G_interactive_fd);
- }
install_special_sighandlers();
#else
/* We have interactiveness code disabled */
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/flash.c b/common/flash.c
index 24ddc8bee72..226646c6868 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -8,7 +8,7 @@
#include <flash.h>
#include <log.h>
-#include <uuid.h>
+#include <u-boot/uuid.h>
#include <linux/string.h>
#include <mtd/cfi_flash.h>
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 c08ff064493..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
@@ -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/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..c13b2b8f714 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;
@@ -713,16 +711,16 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
if (CONFIG_IS_ENABLED(SOC_INIT))
spl_soc_init();
- if (CONFIG_IS_ENABLED(BOARD_INIT))
- spl_board_init();
-
if (IS_ENABLED(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT))
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 (IS_ENABLED(CONFIG_SPL_LMB))
+ lmb_init();
+
if (CONFIG_IS_ENABLED(PCI) && !(gd->flags & GD_FLG_DM_DEAD)) {
ret = pci_init();
if (ret)
@@ -730,6 +728,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
/* Don't fail. We still can try other boot methods. */
}
+ if (CONFIG_IS_ENABLED(BOARD_INIT))
+ spl_board_init();
+
bootcount_inc();
/* Dump driver model states to aid analysis */
@@ -784,7 +785,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 +811,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 +841,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 +904,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..1337596eca0 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
@@ -318,8 +300,8 @@ int default_spl_mmc_emmc_boot_partition(struct mmc *mmc)
* which is the first physical partition (0).
*/
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
- if (part == 7)
- part = 0;
+ if (part == EMMC_BOOT_PART_USER)
+ part = EMMC_HWPART_DEFAULT;
#endif
return part;
}
@@ -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;