diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/board_f.c | 86 | ||||
-rw-r--r-- | common/board_r.c | 4 | ||||
-rw-r--r-- | common/bootstage.c | 8 | ||||
-rw-r--r-- | common/console.c | 19 | ||||
-rw-r--r-- | common/dlmalloc.c | 23 | ||||
-rw-r--r-- | common/hwconfig.c | 8 | ||||
-rw-r--r-- | common/init/handoff.c | 12 | ||||
-rw-r--r-- | common/log_console.c | 4 | ||||
-rw-r--r-- | common/log_syslog.c | 2 | ||||
-rw-r--r-- | common/malloc_simple.c | 4 | ||||
-rw-r--r-- | common/spl/Kconfig | 58 | ||||
-rw-r--r-- | common/spl/Kconfig.tpl | 2 | ||||
-rw-r--r-- | common/spl/Kconfig.vpl | 2 | ||||
-rw-r--r-- | common/spl/Makefile | 2 | ||||
-rw-r--r-- | common/spl/spl.c | 46 | ||||
-rw-r--r-- | common/spl/spl_blk_fs.c | 9 | ||||
-rw-r--r-- | common/spl/spl_ext.c | 3 | ||||
-rw-r--r-- | common/spl/spl_fat.c | 10 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 9 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 159 | ||||
-rw-r--r-- | common/spl/spl_nand.c | 4 | ||||
-rw-r--r-- | common/spl/spl_net.c | 3 | ||||
-rw-r--r-- | common/spl/spl_nor.c | 6 | ||||
-rw-r--r-- | common/spl/spl_ram.c | 3 | ||||
-rw-r--r-- | common/spl/spl_semihosting.c | 4 | ||||
-rw-r--r-- | common/spl/spl_spi.c | 4 | ||||
-rw-r--r-- | common/spl/spl_upl.c | 172 | ||||
-rw-r--r-- | common/spl/spl_ymodem.c | 4 |
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; |