diff options
Diffstat (limited to 'common')
94 files changed, 2601 insertions, 1286 deletions
diff --git a/common/Kconfig b/common/Kconfig index 5e3070e9253..17539079f90 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -424,7 +424,7 @@ config LOGF_FUNC_PAD config LOG_SYSLOG bool "Log output to syslog server" - depends on NET + depends on NET || NET_LWIP help Enables a log driver which broadcasts log records via UDP port 514 to syslog servers. @@ -626,9 +626,18 @@ config CYCLIC if CYCLIC +config SPL_CYCLIC + bool "General-purpose cyclic execution mechanism (SPL)" + help + This enables a general-purpose cyclic execution infrastructure in SPL, + to allow "small" (run-time wise) functions to be executed at + a specified frequency. Things like LED blinking or watchdog + triggering are examples for such tasks. + config CYCLIC_MAX_CPU_TIME_US int "Sets the max allowed time for a cyclic function in us" - default 1000 + default 100000 if SANDBOX # sandbox video is quite slow + default 5000 help The max allowed time for a cyclic function in us. If a functions takes longer than this duration this function will get unregistered @@ -718,6 +727,13 @@ config BOARD_EARLY_INIT_R relocation. With this option, U-Boot calls board_early_init_r() in the post-relocation init sequence. +config BOARD_INIT + bool "Call board-specific init board_init() during init-calls" + default y if ARM || RISCV || SANDBOX + help + Some boards need an board_init() function called during the initcall + phase of startup. + config BOARD_POSTCLK_INIT bool "Call board_postclk_init" help @@ -836,11 +852,20 @@ config HASH and the algorithms it supports are defined in common/hash.c. See also CMD_HASH for command-line access. +config HASH_CRC8 + bool "Make crc8 available via the hash API" + depends on HASH && CRC8 + help + Most times, the crc8() function is called directly. To make it also + available via the hash API, e.g. in hash_block(), enable this + option. + config AVB_VERIFY bool "Build Android Verified Boot operations" depends on LIBAVB depends on MMC depends on PARTITION_UUIDS + depends on FASTBOOT help This option enables compilation of bootloader-dependent operations, used by Android Verified Boot 2.0 library (libavb). Includes: @@ -896,6 +921,19 @@ config STACKPROTECTOR Enable stack smash detection through compiler's stack-protector canary logic +config MMU_PGPROT + bool "Enable RO, RW and RX mappings" + help + U-Boot maps all pages as RWX. If selected pages will + be marked as RO(.rodata), RX(.text), RW(.data) right after + we relocate. Since code sections needs to be page aligned + the final binary size will increase. The mappings can be dumped + using the 'meminfo' command. + + Enabling this feature can expose bugs in U-Boot where we have + code that violates read-only permissions for example. Use this + feature with caution. + config SPL_STACKPROTECTOR bool "Stack Protector buffer overflow detection for SPL" depends on STACKPROTECTOR && SPL @@ -918,6 +956,9 @@ config BOARD_RNG_SEED new seed for use on subsequent boots, and whether or not the kernel should account any entropy from the given seed. + Default seed size (64 bytes) can be overridden by a decimal + environment variable rng_seed_size. + endmenu menu "Update support" @@ -925,6 +966,7 @@ menu "Update support" config UPDATE_COMMON bool select DFU_WRITE_ALT + imply CMD_TFTPBOOT config UPDATE_TFTP bool "Auto-update using fitImage via TFTP" @@ -977,7 +1019,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 @@ -1024,14 +1067,16 @@ if BLOBLIST choice prompt "Bloblist location" + default BLOBLIST_FIXED if SANDBOX + default BLOBLIST_ALLOC help Select the location of the bloblist, via various means. config BLOBLIST_FIXED bool "Place bloblist at a fixed address in memory" help - Select this to used a fixed memory address for the bloblist. If the - bloblist exists at this address from a previous phase, it used as is. + Select this to use a fixed memory address for the bloblist. If the + bloblist exists at this address from a previous phase, it is used as is. If not it is created at this address in U-Boot. config BLOBLIST_ALLOC @@ -1041,11 +1086,21 @@ config BLOBLIST_ALLOC specify a fixed address on systems where this is unknown or can change at runtime. +config BLOBLIST_PASSAGE_MANDATORY + bool "Use bloblist in-place mandatorily" + help + By default U-Boot will use a bloblist in the incoming standard passage. + This option controls whether U-Boot tries to load a static bloblist or + allocate one if a valid incoming bloblist does not exist. + Select this option to mark incoming standard passage as mandatory and + U-Boot will report an error when a valid incoming bloblist does not + exist. + endchoice config BLOBLIST_ADDR hex "Address of bloblist" - default 0xb000 if SANDBOX + default 0x100 if SANDBOX depends on BLOBLIST_FIXED help Sets the address of the bloblist, set up by the first part of U-Boot @@ -1055,17 +1110,18 @@ config BLOBLIST_ADDR config BLOBLIST_SIZE hex "Size of bloblist" + default 0x0 if BLOBLIST_PASSAGE_MANDATORY default 0x400 help Sets the size of the bloblist in bytes. This must include all overhead (alignment, bloblist header, record header). The bloblist is set up in the first part of U-Boot to run (TPL, SPL or U-Boot - proper), and this sane bloblist is used for subsequent phases. + proper), and this same bloblist is used for subsequent phases. config BLOBLIST_SIZE_RELOC hex "Size of bloblist after relocation" default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC - default 0x0 if BLOBLIST_PASSAGE + default 0x20000 if (ARM && EFI_LOADER && GENERATE_ACPI_TABLE) help Sets the size of the bloblist in bytes after relocation. Since U-Boot has a lot more memory available then, it is possible to use a larger diff --git a/common/Makefile b/common/Makefile index e9835473420..35991562a12 100644 --- a/common/Makefile +++ b/common/Makefile @@ -4,9 +4,10 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # core -ifndef CONFIG_SPL_BUILD +ifndef CONFIG_XPL_BUILD obj-y += init/ obj-y += main.o +obj-y += memtop.o obj-y += exports.o obj-y += cli_getch.o cli_simple.o cli_readline.o obj-$(CONFIG_HUSH_OLD_PARSER) += cli_hush.o @@ -42,12 +43,12 @@ obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_UPDATE_COMMON) += update.o obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o -endif # !CONFIG_SPL_BUILD +endif # !CONFIG_XPL_BUILD -obj-$(CONFIG_$(SPL_TPL_)BOOTSTAGE) += bootstage.o -obj-$(CONFIG_$(SPL_TPL_)BLOBLIST) += bloblist.o +obj-$(CONFIG_$(PHASE_)BOOTSTAGE) += bootstage.o +obj-$(CONFIG_$(PHASE_)BLOBLIST) += bloblist.o -ifdef CONFIG_SPL_BUILD +ifdef CONFIG_XPL_BUILD ifdef CONFIG_SPL_DFU obj-$(CONFIG_DFU_OVER_USB) += dfu.o endif @@ -58,31 +59,23 @@ obj-$(CONFIG_SPL_USB_STORAGE) += usb_storage.o obj-$(CONFIG_SPL_MUSB_NEW) += usb.o obj-$(CONFIG_SPL_SPLASH_SCREEN) += splash.o obj-$(CONFIG_SPL_SPLASH_SOURCE) += splash_source.o -endif # CONFIG_SPL_BUILD +endif # CONFIG_XPL_BUILD #others obj-$(CONFIG_DDR_SPD) += ddr_spd.o obj-$(CONFIG_SPD_EEPROM) += ddr_spd.o obj-$(CONFIG_HWCONFIG) += hwconfig.o obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o -ifdef CONFIG_SPL_BUILD -ifdef CONFIG_TPL_BUILD -obj-$(CONFIG_TPL_SERIAL) += console.o -else -obj-$(CONFIG_SPL_SERIAL) += console.o -endif -else -obj-y += console.o -endif # CONFIG_SPL_BUILD +obj-$(CONFIG_$(PHASE_)SERIAL) += console.o obj-$(CONFIG_CROS_EC) += cros_ec.o obj-y += dlmalloc.o -obj-$(CONFIG_$(SPL_TPL_)SYS_MALLOC_F) += malloc_simple.o +obj-$(CONFIG_$(PHASE_)SYS_MALLOC_F) += malloc_simple.o -obj-$(CONFIG_CYCLIC) += cyclic.o -obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o +obj-$(CONFIG_$(PHASE_)CYCLIC) += cyclic.o +obj-$(CONFIG_$(PHASE_)EVENT) += event.o -obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o +obj-$(CONFIG_$(PHASE_)HASH) += hash.o obj-$(CONFIG_IO_TRACE) += iotrace.o obj-y += memsize.o obj-y += stdio.o @@ -96,15 +89,15 @@ obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_getch.o cli_simple.o cli_readline.o obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += cli_getch.o cli_simple.o cli_readline.o obj-$(CONFIG_DFU_OVER_USB) += dfu.o obj-y += command.o -obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o -obj-$(CONFIG_$(SPL_TPL_)LOG_CONSOLE) += log_console.o -obj-$(CONFIG_$(SPL_TPL_)LOG_SYSLOG) += log_syslog.o +obj-$(CONFIG_$(PHASE_)LOG) += log.o +obj-$(CONFIG_$(PHASE_)LOG_CONSOLE) += log_console.o +obj-$(CONFIG_$(PHASE_)LOG_SYSLOG) += log_syslog.o obj-y += s_record.o obj-$(CONFIG_CMD_LOADB) += xyzModem.o -obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o +obj-$(CONFIG_$(PHASE_)YMODEM_SUPPORT) += xyzModem.o -obj-$(CONFIG_$(SPL_TPL_)AVB_VERIFY) += avb_verify.o -obj-$(CONFIG_$(SPL_TPL_)STACKPROTECTOR) += stackprot.o +obj-$(CONFIG_$(PHASE_)AVB_VERIFY) += avb_verify.o +obj-$(CONFIG_$(PHASE_)STACKPROTECTOR) += stackprot.o obj-$(CONFIG_SCP03) += scp03.o obj-$(CONFIG_QFW) += qfw.o diff --git a/common/autoboot.c b/common/autoboot.c index 6f0aeae6bf3..0a254498d40 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -4,13 +4,14 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include <common.h> +#include <config.h> #include <autoboot.h> #include <bootretry.h> #include <cli.h> #include <command.h> #include <console.h> #include <env.h> +#include <errno.h> #include <fdtdec.h> #include <hash.h> #include <log.h> @@ -185,10 +186,15 @@ static int passwd_abort_sha256(uint64_t etime) ret = hash_parse_string(algo_name, sha_env_str, sha_env); if (ret) { printf("Hash %s not supported!\n", algo_name); + free(presskey); return 0; } sha = malloc_cache_aligned(SHA256_SUM_LEN); + if (!sha) { + free(presskey); + return -ENOMEM; + } size = SHA256_SUM_LEN; /* * We don't know how long the stop-string is, so we need to diff --git a/common/bloblist.c b/common/bloblist.c index ad06d7a1795..6e4f020d7c4 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -6,7 +6,6 @@ #define LOG_CATEGORY LOGC_BLOBLIST -#include <common.h> #include <bloblist.h> #include <display_options.h> #include <log.h> @@ -224,13 +223,26 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, void *bloblist_find(uint tag, int size) { + void *blob = NULL; + int blob_size; + + blob = bloblist_get_blob(tag, &blob_size); + + if (size && size != blob_size) + return NULL; + + return blob; +} + +void *bloblist_get_blob(uint tag, int *sizep) +{ struct bloblist_rec *rec; rec = bloblist_findrec(tag); if (!rec) return NULL; - if (size && size != rec->size) - return NULL; + + *sizep = rec->size; return (void *)rec + rec_hdr_size(rec); } @@ -476,6 +488,9 @@ int bloblist_reloc(void *to, uint to_size) { struct bloblist_hdr *hdr; + if (!to_size) + return 0; + if (to_size < gd->bloblist->total_size) return -ENOSPC; @@ -490,8 +505,7 @@ int bloblist_reloc(void *to, uint to_size) /* * Weak default function for getting bloblist from boot args. */ -int __weak xferlist_from_boot_arg(ulong __always_unused addr, - ulong __always_unused size) +int __weak xferlist_from_boot_arg(ulong __always_unused *addr) { return -ENOENT; } @@ -499,38 +513,46 @@ int __weak xferlist_from_boot_arg(ulong __always_unused addr, int bloblist_init(void) { bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); - int ret = -ENOENT; - ulong addr, size; - /* - * If U-Boot is not in the first phase, an existing bloblist must be - * at a fixed address. - */ - bool from_addr = fixed && !u_boot_first_phase(); - /* - * If U-Boot is in the first phase that an arch custom routine should - * install the bloblist passed from previous loader to this fixed - * address. - */ - bool from_boot_arg = fixed && u_boot_first_phase(); + int ret = 0; + ulong addr = 0, size; + + /* Check if a valid transfer list passed in */ + if (!xferlist_from_boot_arg(&addr)) { + size = bloblist_get_total_size(); + } else { + /* + * If U-Boot is not in the first phase, an existing bloblist must + * be at a fixed address. + */ + bool from_addr = fixed && !xpl_is_first_phase(); - if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) - from_addr = false; - if (fixed) - addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, - CONFIG_BLOBLIST_ADDR); - size = CONFIG_BLOBLIST_SIZE; + /* + * If Firmware Handoff is mandatory but no transfer list is + * observed, report it as an error. + */ + if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY)) + return -ENOENT; - if (from_boot_arg) - ret = xferlist_from_boot_arg(addr, size); - else if (from_addr) - ret = bloblist_check(addr, size); + ret = -ENOENT; - if (ret) - log_warning("Bloblist at %lx not found (err=%d)\n", - addr, ret); - else - /* Get the real size */ - size = gd->bloblist->total_size; + if (xpl_prev_phase() == PHASE_TPL && + !IS_ENABLED(CONFIG_TPL_BLOBLIST)) + from_addr = false; + if (fixed) + addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, + CONFIG_BLOBLIST_ADDR); + size = CONFIG_BLOBLIST_SIZE; + + if (from_addr) + ret = bloblist_check(addr, size); + + if (ret) + log_warning("Bloblist at %lx not found (err=%d)\n", + addr, ret); + else + /* Get the real size */ + size = gd->bloblist->total_size; + } if (ret) { /* @@ -555,6 +577,7 @@ int bloblist_init(void) log_debug("Found existing bloblist size %lx at %lx\n", size, addr); } + if (ret) return log_msg_ret("ini", ret); gd->flags |= GD_FLG_BLOBLIST_READY; @@ -575,10 +598,29 @@ int bloblist_maybe_init(void) return 0; } -int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig) +int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist) { - if (rzero || rsig != (BLOBLIST_MAGIC | BLOBLIST_REGCONV_VER) || - rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) { + u64 version = BLOBLIST_REGCONV_VER; + ulong sigval; + int ret; + + if ((IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_SPL_BUILD)) || + (IS_ENABLED(CONFIG_SPL_64BIT) && IS_ENABLED(CONFIG_SPL_BUILD))) { + sigval = ((BLOBLIST_MAGIC & ((1ULL << BLOBLIST_REGCONV_SHIFT_64) - 1)) | + ((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_64)); + } else { + sigval = ((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_32) - 1)) | + ((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32)); + } + + if (rzero || rsig != sigval) + return -EIO; + + ret = bloblist_check(xlist, 0); + if (ret) + return ret; + + if (rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) { gd->bloblist = NULL; /* Reset the gd bloblist pointer */ return -EIO; } diff --git a/common/board_f.c b/common/board_f.c index 039d6d712d0..bff465d9cb2 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -9,7 +9,7 @@ * Marius Groeger <mgroeger@sysgo.de> */ -#include <common.h> +#include <config.h> #include <bloblist.h> #include <bootstage.h> #include <clock_legacy.h> @@ -38,8 +38,10 @@ #include <spl.h> #include <status_led.h> #include <sysreset.h> +#include <time.h> #include <timer.h> #include <trace.h> +#include <upl.h> #include <video.h> #include <watchdog.h> #include <asm/cache.h> @@ -253,7 +255,7 @@ static int show_dram_config(void) print_size(gd->ram_size, ""); if (!sizes_near(gd->ram_size, size)) { - printf(" (effective "); + printf(" (total "); print_size(size, ")"); } board_add_ram_info(0); @@ -350,7 +352,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 !! */ @@ -407,7 +409,7 @@ __weak int arch_reserve_mmu(void) static int reserve_video_from_videoblob(void) { - if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() > PHASE_SPL) { + if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && xpl_phase() > PHASE_SPL) { struct video_handoff *ho; int ret = 0; @@ -475,6 +477,13 @@ static int reserve_trace(void) static int reserve_uboot(void) { + /* + * This should be the first place GD_FLG_SKIP_RELOC is read from. + * Set GD_FLG_SKIP_RELOC flag if CONFIG_SKIP_RELOCATE is enabled. + */ + if (CONFIG_IS_ENABLED(SKIP_RELOCATE)) + gd->flags |= GD_FLG_SKIP_RELOC; + if (!(gd->flags & GD_FLG_SKIP_RELOC)) { /* * reserve memory for U-Boot code, data & bss @@ -487,7 +496,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); } @@ -511,9 +520,9 @@ static unsigned long reserve_stack_aligned(size_t size) static int reserve_noncached(void) { /* - * The value of gd->start_addr_sp must match the value of malloc_start - * calculated in board_r.c:initr_malloc(), which is passed to - * dlmalloc.c:mem_malloc_init() and then used by + * The value of gd->start_addr_sp must match the value of + * mem_malloc_start calculated in board_r.c:initr_malloc(), which is + * passed to dlmalloc.c:mem_malloc_init() and then used by * cache.c:noncached_init() * * These calculations must match the code in cache.c:noncached_init() @@ -574,12 +583,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); } } @@ -589,10 +601,10 @@ static int reserve_fdt(void) static int reserve_bootstage(void) { #ifdef CONFIG_BOOTSTAGE - int size = bootstage_get_size(); + int size = bootstage_get_size(true); 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 @@ -620,11 +632,14 @@ static int reserve_stacks(void) static int reserve_bloblist(void) { #ifdef CONFIG_BLOBLIST + ulong size = bloblist_get_total_size(); + + if (size < CONFIG_BLOBLIST_SIZE_RELOC) + size = CONFIG_BLOBLIST_SIZE_RELOC; + /* 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->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - size, 0x1000); + gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp, size); #endif return 0; @@ -644,13 +659,6 @@ __weak int arch_setup_bdinfo(void) int setup_bdinfo(void) { - struct bd_info *bd = gd->bd; - - if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) { - bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */ - bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ - } - return arch_setup_bdinfo(); } @@ -667,10 +675,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 +690,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,11 +708,15 @@ static int reloc_bloblist(void) debug("Not relocating bloblist\n"); return 0; } - if (gd->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, - CONFIG_BLOBLIST_SIZE_RELOC); + if (gd->boardf->new_bloblist) { + ulong size = bloblist_get_total_size(); + + if (size < CONFIG_BLOBLIST_SIZE_RELOC) + size = CONFIG_BLOBLIST_SIZE_RELOC; + + debug("Copying bloblist from %p to %p, size %lx\n", + gd->bloblist, gd->boardf->new_bloblist, size); + return bloblist_reloc(gd->boardf->new_bloblist, size); } #endif @@ -756,7 +761,7 @@ static int setup_reloc(void) return 0; } -#ifdef CONFIG_OF_BOARD_FIXUP +#if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) static int fix_fdt(void) { return board_fix_fdt((void *)gd->fdt_blob); @@ -810,10 +815,7 @@ static int initf_bootstage(void) if (ret) return ret; if (from_spl) { - const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, - CONFIG_BOOTSTAGE_STASH_SIZE); - - ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); + ret = bootstage_unstash_default(); if (ret && ret != -ENOENT) { debug("Failed to unstash bootstage: err=%d\n", ret); return ret; @@ -827,21 +829,26 @@ static int initf_bootstage(void) static int initf_dm(void) { -#if defined(CONFIG_DM) && CONFIG_IS_ENABLED(SYS_MALLOC_F) int ret; + if (!CONFIG_IS_ENABLED(SYS_MALLOC_F)) + return 0; + bootstage_start(BOOTSTAGE_ID_ACCUM_DM_F, "dm_f"); ret = dm_init_and_scan(true); - bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_F); if (ret) return ret; + ret = dm_autoprobe(); + if (ret) + return ret; + bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_F); + if (IS_ENABLED(CONFIG_TIMER_EARLY)) { ret = dm_timer_init(); if (ret) return ret; } -#endif return 0; } @@ -862,80 +869,106 @@ __weak int clear_bss(void) return 0; } -static const init_fnc_t init_sequence_f[] = { - setup_mon_len, -#ifdef CONFIG_OF_CONTROL - fdtdec_setup, +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 void initcall_run_f(void) +{ + /* + * Please do not add logic to this function (variables, if (), etc.). + * For simplicity it should remain an ordered list of function calls. + */ + INITCALL(setup_mon_len); +#if CONFIG_IS_ENABLED(OF_CONTROL) + INITCALL(fdtdec_setup); #endif -#ifdef CONFIG_TRACE_EARLY - trace_early_init, +#if CONFIG_IS_ENABLED(TRACE_EARLY) + INITCALL(trace_early_init); #endif - initf_malloc, - 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, + INITCALL(initf_malloc); + INITCALL(initf_upl); + INITCALL(log_init); + INITCALL(initf_bootstage); /* uses its own timer, so does not need DM */ + INITCALL(event_init); + INITCALL(bloblist_maybe_init); + INITCALL(setup_spl_handoff); +#if CONFIG_IS_ENABLED(CONSOLE_RECORD_INIT_F) + INITCALL(console_record_init); #endif - INITCALL_EVENT(EVT_FSP_INIT_F), - arch_cpu_init, /* basic arch cpu dependent setup */ - mach_cpu_init, /* SoC/machine dependent CPU setup */ - initf_dm, -#if defined(CONFIG_BOARD_EARLY_INIT_F) - board_early_init_f, + INITCALL_EVT(EVT_FSP_INIT_F); + INITCALL(arch_cpu_init); /* basic arch cpu dependent setup */ + INITCALL(mach_cpu_init); /* SoC/machine dependent CPU setup */ + INITCALL(initf_dm); +#if CONFIG_IS_ENABLED(BOARD_EARLY_INIT_F) + INITCALL(board_early_init_f); #endif #if defined(CONFIG_PPC) || defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K) /* get CPU and bus clocks according to the environment variable */ - get_clocks, /* get CPU and bus clocks (etc.) */ + INITCALL(get_clocks); /* get CPU and bus clocks (etc.) */ #endif #if !defined(CONFIG_M68K) || (defined(CONFIG_M68K) && !defined(CONFIG_MCFTMR)) - timer_init, /* initialize timer */ + INITCALL(timer_init); /* initialize timer */ #endif -#if defined(CONFIG_BOARD_POSTCLK_INIT) - board_postclk_init, +#if CONFIG_IS_ENABLED(BOARD_POSTCLK_INIT) + INITCALL(board_postclk_init); #endif - env_init, /* initialize environment */ - init_baud_rate, /* initialze baudrate settings */ - serial_init, /* serial communications setup */ - console_init_f, /* stage 1 init of console */ - display_options, /* say that we are here */ - display_text_info, /* show debugging info if required */ - checkcpu, -#if defined(CONFIG_SYSRESET) - print_resetinfo, + INITCALL(env_init); /* initialize environment */ + INITCALL(init_baud_rate); /* initialze baudrate settings */ + INITCALL(serial_init); /* serial communications setup */ + INITCALL(console_init_f); /* stage 1 init of console */ + INITCALL(display_options); /* say that we are here */ + INITCALL(display_text_info); /* show debugging info if required */ + INITCALL(checkcpu); +#if CONFIG_IS_ENABLED(SYSRESET) + INITCALL(print_resetinfo); #endif -#if defined(CONFIG_DISPLAY_CPUINFO) - print_cpuinfo, /* display cpu info (and speed) */ + /* display cpu info (and speed) */ +#if CONFIG_IS_ENABLED(DISPLAY_CPUINFO) + INITCALL(print_cpuinfo); #endif -#if defined(CONFIG_DTB_RESELECT) - embedded_dtb_select, +#if CONFIG_IS_ENABLED(DTB_RESELECT) + INITCALL(embedded_dtb_select); #endif -#if defined(CONFIG_DISPLAY_BOARDINFO) - show_board_info, +#if CONFIG_IS_ENABLED(DISPLAY_BOARDINFO) + INITCALL(show_board_info); #endif - INIT_FUNC_WATCHDOG_INIT - INITCALL_EVENT(EVT_MISC_INIT_F), - INIT_FUNC_WATCHDOG_RESET + WATCHDOG_INIT(); + INITCALL_EVT(EVT_MISC_INIT_F); + WATCHDOG_RESET(); #if CONFIG_IS_ENABLED(SYS_I2C_LEGACY) - init_func_i2c, + INITCALL(init_func_i2c); #endif - announce_dram_init, - dram_init, /* configure available RAM banks */ -#ifdef CONFIG_POST - post_init_f, + INITCALL(announce_dram_init); + INITCALL(dram_init); /* configure available RAM banks */ +#if CONFIG_IS_ENABLED(POST) + INITCALL(post_init_f); #endif - INIT_FUNC_WATCHDOG_RESET + WATCHDOG_RESET(); #if defined(CFG_SYS_DRAM_TEST) - testdram, + INITCALL(testdram); #endif /* CFG_SYS_DRAM_TEST */ - INIT_FUNC_WATCHDOG_RESET - -#ifdef CONFIG_POST - init_post, + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(POST) + INITCALL(init_post); #endif - INIT_FUNC_WATCHDOG_RESET + WATCHDOG_RESET(); /* * Now that we have DRAM mapped and working, we can * relocate the code and continue running from DRAM. @@ -948,42 +981,51 @@ static const init_fnc_t init_sequence_f[] = { * - monitor code * - board info struct */ - setup_dest_addr, -#ifdef CONFIG_OF_BOARD_FIXUP - fix_fdt, + INITCALL(setup_dest_addr); +#if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \ + !CONFIG_IS_ENABLED(OF_INITIAL_DTB_READONLY) + INITCALL(fix_fdt); #endif #ifdef CFG_PRAM - reserve_pram, + INITCALL(reserve_pram); #endif - reserve_round_4k, - setup_relocaddr_from_bloblist, - arch_reserve_mmu, - reserve_video, - reserve_trace, - reserve_uboot, - reserve_malloc, - reserve_board, - reserve_global_data, - reserve_fdt, - reserve_bootstage, - reserve_bloblist, - reserve_arch, - reserve_stacks, - dram_init_banksize, - show_dram_config, - INIT_FUNC_WATCHDOG_RESET - setup_bdinfo, - display_new_sp, - INIT_FUNC_WATCHDOG_RESET - reloc_fdt, - reloc_bootstage, - reloc_bloblist, - setup_reloc, -#if defined(CONFIG_X86) || defined(CONFIG_ARC) - copy_uboot_to_ram, - do_elf_reloc_fixups, + INITCALL(reserve_round_4k); + INITCALL(setup_relocaddr_from_bloblist); + INITCALL(arch_reserve_mmu); + INITCALL(reserve_video); + INITCALL(reserve_trace); + INITCALL(reserve_uboot); + INITCALL(reserve_malloc); + INITCALL(reserve_board); + INITCALL(reserve_global_data); + INITCALL(reserve_fdt); +#if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \ + CONFIG_IS_ENABLED(OF_INITIAL_DTB_READONLY) + INITCALL(reloc_fdt); + INITCALL(fix_fdt); #endif - clear_bss, + INITCALL(reserve_bootstage); + INITCALL(reserve_bloblist); + INITCALL(reserve_arch); + INITCALL(reserve_stacks); + INITCALL(dram_init_banksize); + INITCALL(show_dram_config); + WATCHDOG_RESET(); + INITCALL(setup_bdinfo); + INITCALL(display_new_sp); + WATCHDOG_RESET(); +#if !CONFIG_IS_ENABLED(OF_BOARD_FIXUP) || \ + !CONFIG_IS_ENABLED(INITIAL_DTB_READONLY) + INITCALL(reloc_fdt); +#endif + INITCALL(reloc_bootstage); + INITCALL(reloc_bloblist); + INITCALL(setup_reloc); +#if CONFIG_IS_ENABLED(X86) || CONFIG_IS_ENABLED(ARC) + INITCALL(copy_uboot_to_ram); + INITCALL(do_elf_reloc_fixups); +#endif + INITCALL(clear_bss); /* * Deregister all cyclic functions before relocation, so that * gd->cyclic_list does not contain any references to pre-relocation @@ -993,20 +1035,21 @@ static const init_fnc_t init_sequence_f[] = { * This should happen as late as possible so that the window where a * watchdog device is not serviced is as small as possible. */ - cyclic_unregister_all, -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) - jump_to_copy, + INITCALL(cyclic_unregister_all); +#if !CONFIG_IS_ENABLED(ARM) && !CONFIG_IS_ENABLED(SANDBOX) + INITCALL(jump_to_copy); #endif - NULL, -}; +} 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(); + initcall_run_f(); #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \ @@ -1020,8 +1063,8 @@ void board_init_f(ulong boot_flags) /* * For now this code is only used on x86. * - * init_sequence_f_r is the list of init functions which are run when - * U-Boot is executing from Flash with a semi-limited 'C' environment. + * Run init functions which are run when U-Boot is executing from Flash with a + * semi-limited 'C' environment. * The following limitations must be considered when implementing an * '_f_r' function: * - 'static' variables are read-only @@ -1034,18 +1077,16 @@ void board_init_f(ulong boot_flags) * NOTE: At present only x86 uses this route, but it is intended that * all archs will move to this when generic relocation is implemented. */ -static const init_fnc_t init_sequence_f_r[] = { -#if !CONFIG_IS_ENABLED(X86_64) - init_cache_f_r, +static void initcall_run_f_r(void) +{ +#if CONFIG_IS_ENABLED(X86_64) + INITCALL(init_cache_f_r); #endif - - NULL, -}; +} void board_init_f_r(void) { - if (initcall_run_list(init_sequence_f_r)) - hang(); + initcall_run_f_r(); /* * The pre-relocation drivers may be using memory that has now gone diff --git a/common/board_info.c b/common/board_info.c index f4c385add90..dc26e1a33dd 100644 --- a/common/board_info.c +++ b/common/board_info.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0+ -#include <common.h> #include <dm.h> #include <init.h> #include <sysinfo.h> @@ -19,9 +18,9 @@ static const struct to_show { const char *name; enum sysinfo_id id; } to_show[] = { - { "Manufacturer", SYSINFO_ID_BOARD_MANUFACTURER}, - { "Prior-stage version", SYSINFO_ID_PRIOR_STAGE_VERSION }, - { "Prior-stage date", SYSINFO_ID_PRIOR_STAGE_DATE }, + { "Manufacturer", SYSID_BOARD_MANUFACTURER}, + { "Prior-stage version", SYSID_PRIOR_STAGE_VERSION }, + { "Prior-stage date", SYSID_PRIOR_STAGE_DATE }, { /* sentinel */ } }; @@ -40,7 +39,7 @@ static int try_sysinfo(void) if (ret) return ret; - ret = sysinfo_get_str(dev, SYSINFO_ID_BOARD_MODEL, sizeof(str), str); + ret = sysinfo_get_str(dev, SYSID_BOARD_MODEL, sizeof(str), str); if (ret) return ret; printf("Model: %s\n", str); diff --git a/common/board_r.c b/common/board_r.c index da0b80f24ff..65ff5fb595c 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -9,7 +9,7 @@ * Marius Groeger <mgroeger@sysgo.de> */ -#include <common.h> +#include <config.h> #include <api.h> #include <bootstage.h> #include <cpu_func.h> @@ -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> @@ -31,6 +32,7 @@ #include <command.h> #include <console.h> #include <dm.h> +#include <efi_loader.h> #include <env.h> #include <env_internal.h> #include <fdtdec.h> @@ -39,6 +41,7 @@ #include <initcall.h> #include <kgdb.h> #include <irq_func.h> +#include <led.h> #include <malloc.h> #include <mapmem.h> #include <miiphy.h> @@ -61,10 +64,8 @@ #include <dm/ofnode.h> #include <linux/compiler.h> #include <linux/err.h> -#include <efi_loader.h> #include <wdt.h> #include <asm-generic/gpio.h> -#include <efi_loader.h> #include <relocate.h> DECLARE_GLOBAL_DATA_PTR; @@ -151,6 +152,15 @@ static int initr_reloc_global_data(void) */ gd->env_addr += gd->reloc_off; #endif + + /* + * For CONFIG_OF_EMBED case the FDT is embedded into ELF, available by + * __dtb_dt_begin. After U-Boot ELF self-relocation to RAM top address + * it is worth to update fdt_blob in global_data + */ + if (IS_ENABLED(CONFIG_OF_EMBED)) + fdtdec_setup_embed(); + #ifdef CONFIG_EFI_LOADER /* * On the ARM architecture gd is mapped to a fixed register (r9 or x18). @@ -159,8 +169,29 @@ static int initr_reloc_global_data(void) */ efi_save_gd(); - efi_runtime_relocate(gd->relocaddr, NULL); + if (!(gd->flags & GD_FLG_SKIP_RELOC)) + efi_runtime_relocate(gd->relocaddr, NULL); + #endif + /* + * We are done with all relocations change the permissions of the binary + * NOTE: __start_rodata etc are defined in arm64 linker scripts and + * sections.h. If you want to add support for your platform you need to + * add the symbols on your linker script, otherwise they will point to + * random addresses. + * + */ + if (IS_ENABLED(CONFIG_MMU_PGPROT)) { + pgprot_set_attrs((phys_addr_t)(uintptr_t)(__start_rodata), + (size_t)(uintptr_t)(__end_rodata - __start_rodata), + MMU_ATTR_RO); + pgprot_set_attrs((phys_addr_t)(uintptr_t)(__start_data), + (size_t)(uintptr_t)(__end_data - __start_data), + MMU_ATTR_RW); + pgprot_set_attrs((phys_addr_t)(uintptr_t)(__text_start), + (size_t)(uintptr_t)(__text_end - __text_start), + MMU_ATTR_RX); + } return 0; } @@ -192,7 +223,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 */ @@ -202,8 +233,7 @@ static int initr_malloc(void) */ start = gd->relocaddr - TOTAL_MALLOC_LEN; gd_set_malloc_start(start); - mem_malloc_init((ulong)map_sysmem(start, TOTAL_MALLOC_LEN), - TOTAL_MALLOC_LEN); + mem_malloc_init(start, TOTAL_MALLOC_LEN); return 0; } @@ -230,8 +260,7 @@ static int initr_dm(void) oftree_reset(); - /* Save the pre-reloc driver model and start a new one */ - gd->dm_root_f = gd->dm_root; + /* Drop the pre-reloc driver model and start a new one */ gd->dm_root = NULL; #ifdef CONFIG_TIMER gd->timer = NULL; @@ -242,7 +271,7 @@ static int initr_dm(void) if (ret) return ret; - return 0; + return dm_autoprobe(); } #endif @@ -288,13 +317,10 @@ static int initr_announce(void) return 0; } -static int initr_binman(void) +static int __maybe_unused initr_binman(void) { int ret; - if (!CONFIG_IS_ENABLED(BINMAN_FDT)) - return 0; - ret = binman_init(); if (ret) printf("binman_init failed:%d\n", ret); @@ -460,19 +486,30 @@ static int initr_malloc_bootparams(void) } #endif -#if defined(CONFIG_LED_STATUS) static int initr_status_led(void) { -#if defined(CONFIG_LED_STATUS_BOOT) - status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_BLINKING); -#else status_led_init(); -#endif + return 0; } -#endif -#ifdef CONFIG_CMD_NET +static int initr_boot_led_blink(void) +{ + status_led_boot_blink(); + + led_boot_blink(); + + return 0; +} + +static int initr_boot_led_on(void) +{ + led_boot_on(); + + return 0; +} + +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) static int initr_net(void) { puts("Net: "); @@ -511,6 +548,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; @@ -522,6 +567,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 || @@ -556,21 +603,24 @@ static int run_main_loop(void) } /* - * Over time we hope to remove these functions with code fragments and - * stub functions, and instead call the relevant function directly. - * - * We also hope to remove most of the driver-related init and do it if/when - * the driver is later used. + * Over time we hope to remove most of the driver-related init and do it + * if/when the driver is later used. * * TODO: perhaps reset the watchdog in the initcall function after each call? */ -static init_fnc_t init_sequence_r[] = { - initr_trace, - initr_reloc, - event_init, + +static void initcall_run_r(void) +{ + /* + * Please do not add logic to this function (variables, if (), etc.). + * For simplicity it should remain an ordered list of function calls. + */ + INITCALL(initr_trace); + INITCALL(initr_reloc); + INITCALL(event_init); /* TODO: could x86/PPC have this also perhaps? */ -#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) - initr_caches, +#if CONFIG_IS_ENABLED(ARM) || CONFIG_IS_ENABLED(RISCV) + INITCALL(initr_caches); /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR. * A temporary mapping of IFC high region is since removed, * so environmental variables in NOR flash is not available @@ -578,29 +628,29 @@ static init_fnc_t init_sequence_r[] = { * region. */ #endif - initr_reloc_global_data, -#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) - initr_unlock_ram_in_cache, + INITCALL(initr_reloc_global_data); +#if CONFIG_IS_ENABLED(SYS_INIT_RAM_LOCK) && CONFIG_IS_ENABLED(E500) + INITCALL(initr_unlock_ram_in_cache); #endif - initr_barrier, - initr_malloc, - log_init, - initr_bootstage, /* Needs malloc() but has its own timer */ -#if defined(CONFIG_CONSOLE_RECORD) - console_record_init, + INITCALL(initr_barrier); + INITCALL(initr_malloc); + INITCALL(log_init); + INITCALL(initr_bootstage); /* Needs malloc() but has its own timer */ +#if CONFIG_IS_ENABLED(CONSOLE_RECORD) + INITCALL(console_record_init); #endif -#ifdef CONFIG_SYS_NONCACHED_MEMORY - noncached_init, +#if CONFIG_IS_ENABLED(SYS_HAS_NONCACHED_MEMORY) + INITCALL(noncached_init); #endif - initr_of_live, -#ifdef CONFIG_DM - initr_dm, + INITCALL(initr_of_live); +#if CONFIG_IS_ENABLED(DM) + INITCALL(initr_dm); #endif -#ifdef CONFIG_ADDR_MAP - init_addr_map, +#if CONFIG_IS_ENABLED(ADDR_MAP) + INITCALL(init_addr_map); #endif -#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) || defined(CONFIG_SANDBOX) - board_init, /* Setup chipselects */ +#if CONFIG_IS_ENABLED(BOARD_INIT) + INITCALL(board_init); /* Setup chipselects */ #endif /* * TODO: printing of the clock inforamtion of the board is now @@ -608,139 +658,141 @@ static init_fnc_t init_sequence_r[] = { * davinci SOC's is added. Remove this check once all the board * implement this. */ -#ifdef CONFIG_CLOCKS - set_cpu_clk_info, /* Setup clock information */ +#if CONFIG_IS_ENABLED(CLOCKS) + INITCALL(set_cpu_clk_info); #endif -#ifdef CONFIG_EFI_LOADER - efi_memory_init, + INITCALL(initr_lmb); +#if CONFIG_IS_ENABLED(EFI_LOADER) + INITCALL(efi_memory_init); +#endif +#if CONFIG_IS_ENABLED(BINMAN_FDT) + INITCALL(initr_binman); #endif - initr_binman, -#ifdef CONFIG_FSP_VERSION2 - arch_fsp_init_r, +#if CONFIG_IS_ENABLED(FSP_VERSION2) + INITCALL(arch_fsp_init_r); #endif - initr_dm_devices, - stdio_init_tables, - serial_initialize, - initr_announce, - dm_announce, + INITCALL(initr_dm_devices); + INITCALL(stdio_init_tables); + INITCALL(serial_initialize); + INITCALL(initr_announce); + INITCALL(dm_announce); #if CONFIG_IS_ENABLED(WDT) - initr_watchdog, + INITCALL(initr_watchdog); #endif - INIT_FUNC_WATCHDOG_RESET - arch_initr_trap, -#if defined(CONFIG_BOARD_EARLY_INIT_R) - board_early_init_r, + WATCHDOG_RESET(); + INITCALL(arch_initr_trap); +#if CONFIG_IS_ENABLED(BOARD_EARLY_INIT_R) + INITCALL(board_early_init_r); #endif - INIT_FUNC_WATCHDOG_RESET -#ifdef CONFIG_POST - post_output_backlog, + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(POST) + INITCALL(post_output_backlog); #endif - INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT) + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(PCI_INIT_R) && CONFIG_IS_ENABLED(SYS_EARLY_PCI_INIT) /* * Do early PCI configuration _before_ the flash gets initialised, * because PCU resources are crucial for flash access on some boards. */ - pci_init, + INITCALL(pci_init); #endif -#ifdef CONFIG_ARCH_EARLY_INIT_R - arch_early_init_r, +#if CONFIG_IS_ENABLED(ARCH_EARLY_INIT_R) + INITCALL(arch_early_init_r); #endif - power_init_board, -#ifdef CONFIG_MTD_NOR_FLASH - initr_flash, + INITCALL(power_init_board); +#if CONFIG_IS_ENABLED(MTD_NOR_FLASH) + INITCALL(initr_flash); #endif - INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(PPC) || CONFIG_IS_ENABLED(M68K) || CONFIG_IS_ENABLED(X86) /* initialize higher level parts of CPU like time base and timers */ - cpu_init_r, + INITCALL(cpu_init_r); #endif -#ifdef CONFIG_EFI_LOADER - efi_init_early, +#if CONFIG_IS_ENABLED(EFI_LOADER) + INITCALL(efi_init_early); #endif -#ifdef CONFIG_CMD_NAND - initr_nand, +#if CONFIG_IS_ENABLED(CMD_NAND) + INITCALL(initr_nand); #endif -#ifdef CONFIG_CMD_ONENAND - initr_onenand, +#if CONFIG_IS_ENABLED(CMD_ONENAND) + INITCALL(initr_onenand); #endif -#ifdef CONFIG_MMC - initr_mmc, +#if CONFIG_IS_ENABLED(MMC) + INITCALL(initr_mmc); #endif -#ifdef CONFIG_XEN - xen_init, +#if CONFIG_IS_ENABLED(XEN) + INITCALL(xen_init); #endif -#ifdef CONFIG_PVBLOCK - initr_pvblock, +#if CONFIG_IS_ENABLED(PVBLOCK) + INITCALL(initr_pvblock); #endif - initr_env, -#ifdef CONFIG_SYS_MALLOC_BOOTPARAMS - initr_malloc_bootparams, + INITCALL(initr_env); +#if CONFIG_IS_ENABLED(SYS_MALLOC_BOOTPARAMS) + INITCALL(initr_malloc_bootparams); #endif - INIT_FUNC_WATCHDOG_RESET - cpu_secondary_init_r, -#if defined(CONFIG_ID_EEPROM) - mac_read_from_eeprom, + WATCHDOG_RESET(); + INITCALL(cpu_secondary_init_r); +#if CONFIG_IS_ENABLED(ID_EEPROM) + INITCALL(mac_read_from_eeprom); #endif - INITCALL_EVENT(EVT_SETTINGS_R), - INIT_FUNC_WATCHDOG_RESET -#if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT) + INITCALL_EVT(EVT_SETTINGS_R); + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(PCI_INIT_R) && !CONFIG_IS_ENABLED(SYS_EARLY_PCI_INIT) /* * Do pci configuration */ - pci_init, + INITCALL(pci_init); #endif - stdio_add_devices, - jumptable_init, -#ifdef CONFIG_API - api_init, + INITCALL(stdio_add_devices); + INITCALL(jumptable_init); +#if CONFIG_IS_ENABLED(API) + INITCALL(api_init); #endif - console_init_r, /* fully init console as a device */ -#ifdef CONFIG_DISPLAY_BOARDINFO_LATE - console_announce_r, - show_board_info, + INITCALL(console_init_r); /* fully init console as a device */ +#if CONFIG_IS_ENABLED(DISPLAY_BOARDINFO_LATE) + INITCALL(console_announce_r); + INITCALL(show_board_info); #endif -#ifdef CONFIG_ARCH_MISC_INIT - arch_misc_init, /* miscellaneous arch-dependent init */ + /* miscellaneous arch-dependent init */ +#if CONFIG_IS_ENABLED(ARCH_MISC_INIT) + INITCALL(arch_misc_init); #endif -#ifdef CONFIG_MISC_INIT_R - misc_init_r, /* miscellaneous platform-dependent init */ + /* miscellaneous platform-dependent init */ +#if CONFIG_IS_ENABLED(MISC_INIT_R) + INITCALL(misc_init_r); #endif - INIT_FUNC_WATCHDOG_RESET -#ifdef CONFIG_CMD_KGDB - kgdb_init, + WATCHDOG_RESET(); +#if CONFIG_IS_ENABLED(CMD_KGDB) + INITCALL(kgdb_init); #endif - interrupt_init, + INITCALL(interrupt_init); #if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K) - timer_init, /* initialize timer */ -#endif -#if defined(CONFIG_LED_STATUS) - initr_status_led, + INITCALL(timer_init); /* initialize timer */ #endif + INITCALL(initr_status_led); + INITCALL(initr_boot_led_blink); /* PPC has a udelay(20) here dating from 2002. Why? */ -#ifdef CONFIG_BOARD_LATE_INIT - board_late_init, +#if CONFIG_IS_ENABLED(BOARD_LATE_INIT) + INITCALL(board_late_init); #endif -#ifdef CONFIG_BITBANGMII - bb_miiphy_init, +#if CONFIG_IS_ENABLED(PCI_ENDPOINT) + INITCALL(pci_ep_init); #endif -#ifdef CONFIG_PCI_ENDPOINT - pci_ep_init, +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) + WATCHDOG_RESET(); + INITCALL(initr_net); #endif -#ifdef CONFIG_CMD_NET - INIT_FUNC_WATCHDOG_RESET - initr_net, +#if CONFIG_IS_ENABLED(POST) + INITCALL(initr_post); #endif -#ifdef CONFIG_POST - initr_post, -#endif - INIT_FUNC_WATCHDOG_RESET - INITCALL_EVENT(EVT_LAST_STAGE_INIT), + WATCHDOG_RESET(); + INITCALL_EVT(EVT_LAST_STAGE_INIT); #if defined(CFG_PRAM) - initr_mem, + INITCALL(initr_mem); #endif - run_main_loop, -}; + INITCALL(initr_boot_led_on); + INITCALL(run_main_loop); +} void board_init_r(gd_t *new_gd, ulong dest_addr) { @@ -767,8 +819,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) #endif gd->flags &= ~GD_FLG_LOG_READY; - if (initcall_run_list(init_sequence_r)) - hang(); + initcall_run_r(); /* NOTREACHED - run_main_loop() does not return */ hang(); diff --git a/common/bootstage.c b/common/bootstage.c index 0e6d80718fd..4532100acea 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -3,7 +3,6 @@ * Copyright (c) 2011, Google Inc. All rights reserved. */ - /* * This module records the progress of boot and arbitrary commands, and * permits accurate timestamping of each. @@ -11,7 +10,6 @@ #define LOG_CATEGORY LOGC_BOOT -#include <common.h> #include <bootstage.h> #include <hang.h> #include <log.h> @@ -56,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); @@ -247,6 +249,8 @@ static uint32_t print_time_record(struct bootstage_record *rec, uint32_t prev) printf("%11s", ""); print_grouped_ull(rec->time_us, BOOTSTAGE_DIGITS); } else { + if (prev > rec->time_us) + prev = 0; print_grouped_ull(rec->time_us, BOOTSTAGE_DIGITS); print_grouped_ull(rec->time_us - prev, BOOTSTAGE_DIGITS); } @@ -255,13 +259,6 @@ static uint32_t print_time_record(struct bootstage_record *rec, uint32_t prev) return rec->time_us; } -static int h_compare_record(const void *r1, const void *r2) -{ - const struct bootstage_record *rec1 = r1, *rec2 = r2; - - return rec1->time_us > rec2->time_us ? 1 : -1; -} - #ifdef CONFIG_OF_LIBFDT /** * Add all bootstage timings to a device tree. @@ -340,16 +337,13 @@ void bootstage_report(void) prev = print_time_record(rec, 0); - /* Sort records by increasing time */ - qsort(data->record, data->rec_count, sizeof(*rec), h_compare_record); - for (i = 1, rec++; i < data->rec_count; i++, rec++) { if (rec->id && !rec->start_us) prev = print_time_record(rec, prev); } if (data->rec_count > RECORD_COUNT) printf("Overflowed internal boot id table by %d entries\n" - "Please increase CONFIG_(SPL_TPL_)BOOTSTAGE_RECORD_COUNT\n", + "Please increase CONFIG_(PHASE_)BOOTSTAGE_RECORD_COUNT\n", data->rec_count - RECORD_COUNT); puts("\nAccumulated time:\n"); @@ -471,7 +465,7 @@ int bootstage_unstash(const void *base, int size) if (data->rec_count + hdr->count > RECORD_COUNT) { debug("%s: Bootstage has %d records, we have space for %d\n" - "Please increase CONFIG_(SPL_)BOOTSTAGE_RECORD_COUNT\n", + "Please increase CONFIG_(PHASE_)BOOTSTAGE_RECORD_COUNT\n", __func__, hdr->count, RECORD_COUNT - data->rec_count); return -ENOSPC; } @@ -487,7 +481,7 @@ int bootstage_unstash(const void *base, int size) for (rec = data->record + data->next_id, i = 0; i < hdr->count; i++, rec++) { rec->name = ptr; - if (spl_phase() == PHASE_SPL) + if (xpl_phase() == PHASE_SPL) rec->name = strdup(ptr); /* Assume no data corruption here */ @@ -502,6 +496,7 @@ int bootstage_unstash(const void *base, int size) return 0; } +#if IS_ENABLED(CONFIG_BOOTSTAGE_STASH) int _bootstage_stash_default(void) { return bootstage_stash(map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, 0), @@ -515,18 +510,21 @@ int _bootstage_unstash_default(void) return bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); } +#endif -int bootstage_get_size(void) +int bootstage_get_size(bool add_strings) { - struct bootstage_data *data = gd->bootstage; - struct bootstage_record *rec; int size; - int i; size = sizeof(struct bootstage_data); - for (rec = data->record, i = 0; i < data->rec_count; - i++, rec++) - size += strlen(rec->name) + 1; + if (add_strings) { + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec; + int i; + + for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) + size += strlen(rec->name) + 1; + } return size; } diff --git a/common/bouncebuf.c b/common/bouncebuf.c index 934b83f7ec3..b2f87e4d939 100644 --- a/common/bouncebuf.c +++ b/common/bouncebuf.c @@ -5,7 +5,6 @@ * Copyright (C) 2012 Marek Vasut <marex@denx.de> */ -#include <common.h> #include <cpu_func.h> #include <log.h> #include <malloc.h> diff --git a/common/button_cmd.c b/common/button_cmd.c index 8642c26735c..72dac1f9ef6 100644 --- a/common/button_cmd.c +++ b/common/button_cmd.c @@ -8,7 +8,7 @@ #include <command.h> #include <env.h> #include <log.h> -#include <vsprintf.h> +#include <stdio.h> /* Some sane limit "just in case" */ #define MAX_BTN_CMDS 32 diff --git a/common/cli.c b/common/cli.c index 1c33daf1149..4694a35cd0e 100644 --- a/common/cli.c +++ b/common/cli.c @@ -10,7 +10,6 @@ #define pr_fmt(fmt) "cli: %s: " fmt, __func__ -#include <common.h> #include <ansi.h> #include <bootstage.h> #include <cli.h> diff --git a/common/cli_getch.c b/common/cli_getch.c index 0ee79087774..a5ed6eb6fcf 100644 --- a/common/cli_getch.c +++ b/common/cli_getch.c @@ -6,8 +6,10 @@ * Copyright 2022 Google LLC */ -#include <common.h> #include <cli.h> +#include <stdio.h> +#include <string.h> +#include <linux/errno.h> /** * enum cli_esc_state_t - indicates what to do with an escape character diff --git a/common/cli_hush.c b/common/cli_hush.c index 9cda97f30e3..7bd6943d3ed 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -75,7 +75,6 @@ #define __U_BOOT__ #ifdef __U_BOOT__ -#include <common.h> /* readline */ #include <env.h> #include <malloc.h> /* malloc, free, realloc*/ #include <linux/ctype.h> /* isalpha, isdigit */ @@ -733,7 +732,6 @@ static int builtin_jobs(struct child_prog *child) return EXIT_SUCCESS; } - /* built-in 'pwd' handler */ static int builtin_pwd(struct child_prog *dummy) { @@ -785,7 +783,6 @@ static int builtin_set(struct child_prog *child) return EXIT_SUCCESS; } - /* Built-in 'shift' handler */ static int builtin_shift(struct child_prog *child) { @@ -1031,8 +1028,10 @@ static void get_user_input(struct in_str *i) puts("\nTimeout waiting for command\n"); # ifdef CONFIG_RESET_TO_RETRY do_reset(NULL, 0, 0, NULL); -# else -# error "This currently only works with CONFIG_RESET_TO_RETRY enabled" +# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) + strcpy(console_buffer, "run bootcmd\n"); +# else +# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" # endif } #endif @@ -1733,7 +1732,6 @@ static int run_pipe_real(struct pipe *pi) pseudo_exec(child); } - /* put our child in the process group whose leader is the first process in this pipe */ if (pi->pgrp < 0) { @@ -3410,7 +3408,6 @@ int hush_main(int argc, char * const *argv) last_return_code=EXIT_SUCCESS; - if (argv[0] && argv[0][0] == '-') { debug_printf("\nsourcing /etc/profile\n"); if ((input = fopen("/etc/profile", "r")) != NULL) { @@ -3631,7 +3628,13 @@ static char *make_string(char **inp, int *nonnull) noeval = 1; for (n = 0; inp[n]; n++) { p = insert_var_value_sub(inp[n], noeval); - str = xrealloc(str, (len + strlen(p) + (2 * nonnull[n]))); + char *new_str = xrealloc(str, (len + strlen(p) + (2 * nonnull[n]))); + if (!new_str) { + free(str); + if (p != inp[n]) free(p); + return NULL; + } + str = new_str; if (n) { strcat(str, " "); } else { 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 ca40bbb2cd8..748ef60ac90 100644 --- a/common/cli_hush_upstream.c +++ b/common/cli_hush_upstream.c @@ -392,7 +392,6 @@ #define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST) #define BASH_READ_D ENABLE_HUSH_BASH_COMPAT - /* Build knobs */ #define LEAK_HUNTING 0 #define BUILD_AS_NOMMU 0 @@ -413,7 +412,6 @@ */ #define ENABLE_HUSH_DOLLAR_OPS 1 - #if BUILD_AS_NOMMU # undef BB_MMU # undef USE_FOR_NOMMU @@ -519,7 +517,6 @@ typedef struct nommu_save_t { } nommu_save_t; #endif - enum { RES_NONE = 0, #if ENABLE_HUSH_IF @@ -829,7 +826,6 @@ struct function { }; #endif - /* set -/+o OPT support. (TODO: make it optional) * bash supports the following opts: * allexport off @@ -1118,7 +1114,6 @@ struct globals *ptr_to_globals; } while (0) #endif /* !__U_BOOT__ */ - #ifndef __U_BOOT__ /* Function prototypes for builtins */ static int builtin_cd(char **argv) FAST_FUNC; @@ -1416,7 +1411,6 @@ static void debug_print_strings(const char *prefix, char **vv) # define debug_print_strings(prefix, vv) ((void)0) #endif - /* Leak hunting. Use hush_leaktool.sh for post-processing. */ #if LEAK_HUNTING @@ -1449,7 +1443,6 @@ static void xxfree(void *ptr) # define free(p) xxfree(p) #endif - /* Syntax and runtime errors. They always abort scripts. * In interactive use they usually discard unparsed and/or unexecuted commands * and return to the prompt. @@ -1658,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; } @@ -1684,12 +1687,11 @@ 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; } - /* Manipulating HFILEs */ static HFILE *hfopen(const char *name) { @@ -1882,7 +1884,6 @@ static void restore_G_args(save_arg_t *sv, char **argv) } #endif /* !__U_BOOT__ */ - #ifndef __U_BOOT__ /* Basic theory of signal handling in shell * ======================================== @@ -2331,7 +2332,6 @@ static int check_and_run_traps(void) return last_sig; } - static const char *get_cwd(int force) { if (force || G.cwd == NULL) { @@ -2653,7 +2653,6 @@ static int unset_local_var(const char *name) } #endif - #ifndef __U_BOOT__ /* * Helpers for "var1=val1 var2=val2 cmd" feature @@ -2728,7 +2727,6 @@ static void set_vars_and_save_old(char **strings) free(strings); } - /* * Unicode helper */ @@ -2909,8 +2907,10 @@ static void get_user_input(struct in_str *i) puts("\nTimeout waiting for command\n"); # ifdef CONFIG_RESET_TO_RETRY do_reset(NULL, 0, 0, NULL); -# else -# error "This currently only works with CONFIG_RESET_TO_RETRY enabled" +# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) + strcpy(console_buffer, "run bootcmd\n"); +# else +# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" # endif } # endif @@ -3236,7 +3236,6 @@ static void setup_string_in_str(struct in_str *i, const char *s) i->p = s; } - /* * o_string support */ @@ -3997,7 +3996,6 @@ static void free_pipe_list(struct pipe *pi) } } - /*** Parsing routines ***/ #ifndef debug_print_tree @@ -4648,7 +4646,6 @@ static int done_word(struct parse_context *ctx) return 0; } - #ifndef __U_BOOT__ /* Peek ahead in the input to find out if we have a "&n" construct, * as in "2>&1", that represents duplicating a file descriptor. @@ -4958,7 +4955,6 @@ static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, return heredoc_cnt; } - static int run_list(struct pipe *pi); #if BB_MMU #define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \ @@ -5175,7 +5171,6 @@ static int add_till_double_quote(o_string *dest, struct in_str *input) } } - /* Process `cmd` - copy contents until "`" is seen. Complicated by * \` quoting. * "Within the backquoted style of command substitution, backslash @@ -5868,6 +5863,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. @@ -5890,7 +5894,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; } @@ -6477,7 +6481,6 @@ static struct pipe *parse_stream(char **pstring, } } - /*** Execution routines ***/ /* Expansion can recurse, need forward decls: */ @@ -7778,7 +7781,6 @@ static char **expand_assignments(char **argv, int count) return p; } - static void switch_off_special_sigs(unsigned mask) { unsigned sig = 0; @@ -8297,7 +8299,6 @@ static int process_command_subs(o_string *dest, const char *s) } #endif /* ENABLE_HUSH_TICK */ - static void setup_heredoc(struct redir_struct *redir) { struct fd_pair pair; @@ -8404,10 +8405,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) { @@ -8421,7 +8428,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); } @@ -8454,6 +8461,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; @@ -8517,7 +8526,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" */ } @@ -8588,8 +8600,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; @@ -8600,7 +8615,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", @@ -8620,7 +8636,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, @@ -8635,7 +8651,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). @@ -8657,6 +8675,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) { @@ -8670,13 +8690,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); @@ -9006,7 +9029,6 @@ static int run_function(const struct function *funcp, char **argv) } #endif /* ENABLE_HUSH_FUNCTIONS */ - #ifndef __U_BOOT__ #if BB_MMU #define exec_builtin(to_free, x, argv) \ @@ -9042,7 +9064,6 @@ static void exec_builtin(char ***to_free, } #endif /* !__U_BOOT__ */ - #ifndef __U_BOOT__ static void execvp_or_die(char **argv) NORETURN; static void execvp_or_die(char **argv) @@ -9753,6 +9774,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(). @@ -9780,6 +9802,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) @@ -9832,34 +9886,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;) @@ -10384,6 +10411,8 @@ static int run_list(struct pipe *pi) debug_enter(); #endif /* !__U_BOOT__ */ + set_G_ifs(); + #if ENABLE_HUSH_LOOPS /* Check syntax for "for" */ { @@ -10839,7 +10868,6 @@ static int run_and_free_list(struct pipe *pi) return rcode; } - #ifndef __U_BOOT__ static void install_sighandlers(unsigned mask) { @@ -11400,7 +11428,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; @@ -11410,8 +11438,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). @@ -11486,9 +11512,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 */ @@ -11524,8 +11547,6 @@ int hush_main(int argc, char **argv) hush_exit(G.last_exitcode); } - - /* * Built-ins */ @@ -13004,7 +13025,6 @@ static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM) if (l < (unsigned long)p) l = (unsigned long)p; free(p); - # if 0 /* debug */ { struct mallinfo mi = mallinfo(); diff --git a/common/cli_readline.c b/common/cli_readline.c index cf4339d0e50..4e6797a1944 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -8,7 +8,6 @@ * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com> */ -#include <common.h> #include <bootretry.h> #include <cli.h> #include <command.h> @@ -16,6 +15,7 @@ #include <malloc.h> #include <time.h> #include <watchdog.h> +#include <linux/errno.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; @@ -73,7 +73,7 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) #define getcmd_getch() getchar() #define getcmd_cbeep() getcmd_putch('\a') -#ifdef CONFIG_SPL_BUILD +#ifdef CONFIG_XPL_BUILD #define HIST_MAX 3 #define HIST_SIZE 32 #else diff --git a/common/cli_simple.c b/common/cli_simple.c index f89ba92d1b0..266c444334e 100644 --- a/common/cli_simple.c +++ b/common/cli_simple.c @@ -8,7 +8,6 @@ * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com> */ -#include <common.h> #include <bootretry.h> #include <cli.h> #include <command.h> diff --git a/common/command.c b/common/command.c index af8ffdba8f8..0f9dd06d72b 100644 --- a/common/command.c +++ b/common/command.c @@ -8,7 +8,7 @@ * Command Processor Table */ -#include <common.h> +#include <config.h> #include <compiler.h> #include <command.h> #include <console.h> @@ -16,6 +16,7 @@ #include <image.h> #include <log.h> #include <mapmem.h> +#include <time.h> #include <asm/global_data.h> #include <linux/ctype.h> @@ -483,7 +484,7 @@ int cmd_get_data_size(const char *arg, int default_size) case 'q': if (MEM_SUPPORT_64BIT_DATA) return 8; - /* no break */ + fallthrough; default: return CMD_DATA_SIZE_ERR; } diff --git a/common/console.c b/common/console.c index aa3053bc441..48586fd2166 100644 --- a/common/console.c +++ b/common/console.c @@ -4,7 +4,8 @@ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it */ -#include <common.h> +#define LOG_CATEGORY LOGC_CONSOLE + #include <console.h> #include <debug_uart.h> #include <display_options.h> @@ -100,7 +101,7 @@ static void console_record_putc(const char c) if (!(gd->flags & GD_FLG_RECORD)) return; if (gd->console_out.start && - !membuff_putbyte((struct membuff *)&gd->console_out, c)) + !membuf_putbyte((struct membuf *)&gd->console_out, c)) gd->flags |= GD_FLG_RECORD_OVF; } @@ -111,7 +112,7 @@ static void console_record_puts(const char *s) if (gd->console_out.start) { int len = strlen(s); - if (membuff_put((struct membuff *)&gd->console_out, s, len) != + if (membuf_put((struct membuf *)&gd->console_out, s, len) != len) gd->flags |= GD_FLG_RECORD_OVF; } @@ -124,7 +125,7 @@ static int console_record_getc(void) if (!gd->console_in.start) return -1; - return membuff_getbyte((struct membuff *)&gd->console_in); + return membuf_getbyte((struct membuf *)&gd->console_in); } static int console_record_tstc(void) @@ -132,7 +133,7 @@ static int console_record_tstc(void) if (!(gd->flags & GD_FLG_RECORD)) return 0; if (gd->console_in.start) { - if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) + if (membuf_peekbyte((struct membuf *)&gd->console_in) != -1) return 1; } return 0; @@ -190,6 +191,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_XPL_BUILD /* * Update monitor functions * (to use the console stuff by other applications) @@ -206,8 +208,8 @@ static int console_setfile(int file, struct stdio_dev * dev) gd->jt->printf = printf; break; } +#endif break; - default: /* Invalid file ID */ error = -1; } @@ -357,6 +359,24 @@ void console_puts_select_stderr(bool serial_only, const char *s) console_puts_select(stderr, serial_only, s); } +int console_printf_select_stderr(bool serial_only, const char *fmt, ...) +{ + char buf[CONFIG_SYS_PBSIZE]; + va_list args; + int ret; + + va_start(args, fmt); + + /* For this to work, buf must be larger than anything we ever want to + * print. + */ + ret = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + console_puts_select_stderr(serial_only, buf); + + return ret; +} + static void console_puts(int file, const char *s) { int i; @@ -587,7 +607,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(); @@ -608,7 +628,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()) @@ -716,7 +736,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) { @@ -743,11 +763,7 @@ void puts(const char *s) } if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) { - while (*s) { - int ch = *s++; - - printch(ch); - } + printascii(s); return; } @@ -760,7 +776,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) { @@ -794,7 +810,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) { @@ -812,14 +828,14 @@ int console_record_init(void) { int ret; - ret = membuff_new((struct membuff *)&gd->console_out, - gd->flags & GD_FLG_RELOC ? - CONFIG_CONSOLE_RECORD_OUT_SIZE : - CONFIG_CONSOLE_RECORD_OUT_SIZE_F); + ret = membuf_new((struct membuf *)&gd->console_out, + gd->flags & GD_FLG_RELOC ? + CONFIG_CONSOLE_RECORD_OUT_SIZE : + CONFIG_CONSOLE_RECORD_OUT_SIZE_F); if (ret) return ret; - ret = membuff_new((struct membuff *)&gd->console_in, - CONFIG_CONSOLE_RECORD_IN_SIZE); + ret = membuf_new((struct membuf *)&gd->console_in, + CONFIG_CONSOLE_RECORD_IN_SIZE); /* Start recording from the beginning */ gd->flags |= GD_FLG_RECORD; @@ -829,8 +845,8 @@ int console_record_init(void) void console_record_reset(void) { - membuff_purge((struct membuff *)&gd->console_out); - membuff_purge((struct membuff *)&gd->console_in); + membuf_purge((struct membuf *)&gd->console_out); + membuf_purge((struct membuf *)&gd->console_in); gd->flags &= ~GD_FLG_RECORD_OVF; } @@ -846,24 +862,26 @@ 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, + return membuf_readline((struct membuf *)&gd->console_out, str, maxlen, '\0', false); } int console_record_avail(void) { - return membuff_avail((struct membuff *)&gd->console_out); + return membuf_avail((struct membuf *)&gd->console_out); } bool console_record_isempty(void) { - return membuff_isempty((struct membuff *)&gd->console_out); + return membuf_isempty((struct membuf *)&gd->console_out); } int console_in_puts(const char *str) { - return membuff_put((struct membuff *)&gd->console_in, str, strlen(str)); + return membuf_put((struct membuf *)&gd->console_in, str, strlen(str)); } #endif @@ -873,7 +891,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 */ @@ -942,11 +960,6 @@ struct stdio_dev *console_search_dev(int flags, const char *name) struct stdio_dev *dev; dev = stdio_get_by_name(name); -#ifdef CONFIG_VIDCONSOLE_AS_LCD - if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_NAME)) - dev = stdio_get_by_name("vidconsole"); -#endif - if (dev && (dev->flags & flags)) return dev; @@ -1012,7 +1025,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(); @@ -1154,12 +1167,6 @@ done: if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET)) stdio_print_current_devices(); -#ifdef CONFIG_VIDCONSOLE_AS_LCD - if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_NAME)) - printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n", - CONFIG_VIDCONSOLE_AS_NAME); -#endif - if (IS_ENABLED(CONFIG_SYS_CONSOLE_ENV_OVERWRITE)) { /* set the environment variables (will overwrite previous env settings) */ for (i = 0; i < MAX_FILES; i++) @@ -1240,3 +1247,37 @@ int console_init_r(void) } #endif /* CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) */ + +int console_remove_by_name(const char *name) +{ + int err = 0; + +#if CONFIG_IS_ENABLED(CONSOLE_MUX) + int fnum; + + log_debug("removing console device %s\n", name); + for (fnum = 0; fnum < MAX_FILES; fnum++) { + struct stdio_dev **src, **dest; + int i; + + log_debug("file %d: %d devices: ", fnum, cd_count[fnum]); + src = console_devices[fnum]; + dest = src; + for (i = 0; i < cd_count[fnum]; i++, src++) { + struct stdio_dev *sdev = *src; + int ret = 0; + + if (!strcmp(sdev->name, name)) + ret = stdio_deregister_dev(sdev, true); + else + *dest++ = *src; + if (ret && !err) + err = ret; + } + cd_count[fnum] = dest - console_devices[fnum]; + log_debug("now %d\n", cd_count[fnum]); + } +#endif /* CONSOLE_MUX */ + + return err; +} diff --git a/common/cros_ec.c b/common/cros_ec.c index 249d1f19411..9ccc8fa16cd 100644 --- a/common/cros_ec.c +++ b/common/cros_ec.c @@ -8,7 +8,6 @@ * Software Foundation. */ -#include <common.h> #include <cros_ec.h> #include <dm.h> #include <errno.h> diff --git a/common/cyclic.c b/common/cyclic.c index a49bfc88f5c..b695f092f52 100644 --- a/common/cyclic.c +++ b/common/cyclic.c @@ -15,6 +15,8 @@ #include <linux/errno.h> #include <linux/list.h> #include <asm/global_data.h> +#include <u-boot/schedule.h> +#include <uthread.h> DECLARE_GLOBAL_DATA_PTR; @@ -26,37 +28,25 @@ struct hlist_head *cyclic_get_list(void) return (struct hlist_head *)&gd->cyclic_list; } -struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, - const char *name, void *ctx) +void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, + uint64_t delay_us, const char *name) { - struct cyclic_info *cyclic; - - cyclic = calloc(1, sizeof(struct cyclic_info)); - if (!cyclic) { - pr_debug("Memory allocation error\n"); - return NULL; - } + memset(cyclic, 0, sizeof(*cyclic)); /* Store values in struct */ cyclic->func = func; - cyclic->ctx = ctx; - cyclic->name = strdup(name); + cyclic->name = name; cyclic->delay_us = delay_us; - cyclic->start_time_us = timer_get_us(); + cyclic->start_time_us = get_timer_us(0); hlist_add_head(&cyclic->list, cyclic_get_list()); - - return cyclic; } -int cyclic_unregister(struct cyclic_info *cyclic) +void cyclic_unregister(struct cyclic_info *cyclic) { hlist_del(&cyclic->list); - free(cyclic); - - return 0; } -void cyclic_run(void) +static void cyclic_run(void) { struct cyclic_info *cyclic; struct hlist_node *tmp; @@ -72,13 +62,13 @@ void cyclic_run(void) * Check if this cyclic function needs to get called, e.g. * do not call the cyclic func too often */ - now = timer_get_us(); + now = get_timer_us(0); if (time_after_eq64(now, cyclic->next_call)) { /* Call cyclic function and account it's cpu-time */ cyclic->next_call = now + cyclic->delay_us; - cyclic->func(cyclic->ctx); + cyclic->func(cyclic); cyclic->run_cnt++; - cpu_time = timer_get_us() - now; + cpu_time = get_timer_us(0) - now; cyclic->cpu_time_us += cpu_time; /* Check if cpu-time exceeds max allowed time */ @@ -111,6 +101,8 @@ void schedule(void) */ if (gd) cyclic_run(); + + uthread_schedule(); } int cyclic_unregister_all(void) diff --git a/common/ddr_spd.c b/common/ddr_spd.c index 58dc9b3781b..2f6eb99bf0c 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -3,8 +3,8 @@ * Copyright 2008-2014 Freescale Semiconductor, Inc. */ -#include <common.h> #include <ddr_spd.h> +#include <stdio.h> /* used for ddr1 and ddr2 spd */ static int diff --git a/common/dfu.c b/common/dfu.c index 0d154e8d4c4..1af8194139c 100644 --- a/common/dfu.c +++ b/common/dfu.c @@ -10,7 +10,6 @@ * Lukasz Majewski <l.majewski@samsung.com> */ -#include <common.h> #include <command.h> #include <log.h> #include <watchdog.h> diff --git a/common/dlmalloc.c b/common/dlmalloc.c index a0616217d49..cc4d3a0a028 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -12,11 +12,12 @@ #define DEBUG #endif -#include <common.h> #include <log.h> #include <asm/global_data.h> #include <malloc.h> +#include <mapmem.h> +#include <string.h> #include <asm/io.h> #include <valgrind/memcheck.h> @@ -54,7 +55,6 @@ static inline void MALLOC_COPY(void *dest, const void *src, size_t sz) { memcpy( Thanks to Martin Fong and others for supplying this. */ - #ifdef WIN32 #define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \ @@ -156,7 +156,6 @@ void* findRegion (void* start_address, unsigned long size) } - void* wsbrk (long size) { void* tmp; @@ -237,13 +236,10 @@ gAllocatedSize)) #endif - - /* Type declarations */ - struct malloc_chunk { INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ @@ -271,7 +267,6 @@ typedef struct malloc_chunk* mchunkptr; An allocated chunk looks like this: - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk, if allocated | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -285,7 +280,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - Where "chunk" is the front of the chunk for the purpose of most of the malloc code, but "mem" is the pointer that is returned to the user. "Nextchunk" is the beginning of the next contiguous chunk. @@ -394,22 +388,18 @@ 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 */ #define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0) - - - /* Physical chunk operations */ - /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ #define PREV_INUSE 0x1 @@ -422,7 +412,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define SIZE_BITS (PREV_INUSE|IS_MMAPPED) - /* Ptr to next physical malloc_chunk. */ #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) )) @@ -432,14 +421,10 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define prev_chunk(p)\ ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) )) - /* Treat space at ptr + offset as a chunk */ #define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) - - - /* Dealing with use bits */ @@ -476,9 +461,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define clear_inuse_bit_at_offset(p, s)\ (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE)) - - - /* Dealing with size fields */ @@ -499,10 +481,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) - - - - /* Bins @@ -556,7 +534,6 @@ typedef struct malloc_chunk* mbinptr; #define top (av_[2]) /* The topmost chunk */ #define last_remainder (bin_at(1)) /* remainder from last split */ - /* Because top initially points to its own bin with initial zero size, thus forcing extension on the first malloc request, @@ -606,6 +583,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 @@ -613,9 +593,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; @@ -623,9 +600,9 @@ void *sbrk(ptrdiff_t increment) void mem_malloc_init(ulong start, ulong size) { - mem_malloc_start = start; - mem_malloc_end = start + size; - mem_malloc_brk = start; + mem_malloc_start = (ulong)map_sysmem(start, size); + mem_malloc_end = mem_malloc_start + size; + mem_malloc_brk = mem_malloc_start; #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT malloc_init(); @@ -672,8 +649,6 @@ void mem_malloc_init(ulong start, ulong size) #define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH) - - /* To help compensate for the large number of bins, a one-level index structure is used for bin-by-bin searching. `binblocks' is a @@ -695,10 +670,6 @@ void mem_malloc_init(ulong start, ulong size) #define mark_binblock(ii) (binblocks_w = (mbinptr)(binblocks_r | idx2binblock(ii))) #define clear_binblock(ii) (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii)))) - - - - /* Other static bookkeeping data */ /* variables holding tunable values */ @@ -771,7 +742,6 @@ static void malloc_init(void) #ifdef DEBUG - /* These routines make a number of assertions about the states of data structures that should be true at all times. If any @@ -800,7 +770,6 @@ static void do_check_chunk(p) mchunkptr p; } - #if __STD_C static void do_check_free_chunk(mchunkptr p) #else @@ -886,13 +855,11 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; /* ... and alignment */ assert(aligned_OK(chunk2mem(p))); - /* ... and was allocated at front of an available chunk */ assert(prev_inuse(p)); } - #define check_free_chunk(P) do_check_free_chunk(P) #define check_inuse_chunk(P) do_check_inuse_chunk(P) #define check_chunk(P) do_check_chunk(P) @@ -904,13 +871,10 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; #define check_malloced_chunk(P,N) #endif - - /* Macro-based internal utilities */ - /* Linking chunks in bin lists. Call these only with variables, not arbitrary expressions, as arguments. @@ -921,7 +885,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; putting it ahead of others of same size. */ - #define frontlink(P, S, IDX, BK, FD) \ { \ if (S < MAX_SMALLBIN_SIZE) \ @@ -951,7 +914,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; } \ } - /* take a chunk off a list */ #define unlink(P, BK, FD) \ @@ -975,10 +937,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; #define clear_last_remainder \ (last_remainder->fd = last_remainder->bk = last_remainder) - - - - /* Routines dealing with mmap(). */ #if HAVE_MMAP @@ -1220,12 +1178,8 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb; assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0); } - - - /* Main public routines */ - /* Malloc Algorthim: @@ -1276,7 +1230,6 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb; contiguous memory. Thus, it should be safe to intersperse mallocs with other sbrk calls. - All allocations are made from the the `lowest' part of any found chunk. (The implementation invariant is that prev_inuse is always true of any allocated chunk; i.e., that each allocated @@ -1323,7 +1276,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; */ @@ -1515,7 +1469,6 @@ Void_t* mALLOc_impl(bytes) size_t bytes; } } - /* Try to use top chunk */ /* Require that there be a remainder, ensuring top always exists */ @@ -1546,9 +1499,6 @@ Void_t* mALLOc_impl(bytes) size_t bytes; } - - - /* free() algorithm : @@ -1570,7 +1520,6 @@ Void_t* mALLOc_impl(bytes) size_t bytes; */ - STATIC_IF_MCHECK #if __STD_C void fREe_impl(Void_t* mem) @@ -1666,17 +1615,12 @@ void fREe_impl(mem) Void_t* mem; unlink(next, bck, fwd); } - set_head(p, sz | PREV_INUSE); set_foot(p, sz); if (!islr) frontlink(p, sz, idx, bck, fwd); } - - - - /* Realloc algorithm: @@ -1709,10 +1653,8 @@ void fREe_impl(mem) Void_t* mem; and allowing it would also allow too many other incorrect usages of realloc to be sensible. - */ - STATIC_IF_MCHECK #if __STD_C Void_t* rEALLOc_impl(Void_t* oldmem, size_t bytes) @@ -1748,7 +1690,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); @@ -1759,11 +1702,14 @@ 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); - nb = request2size(bytes); #if HAVE_MMAP @@ -1911,7 +1857,6 @@ Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes; VALGRIND_MAKE_MEM_DEFINED(oldmem, bytes); } - split: /* split off extra room in old or expanded chunk */ if (newsize - nb >= MINSIZE) /* split off remainder */ @@ -1935,9 +1880,6 @@ Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes; return chunk2mem(newp); } - - - /* memalign algorithm: @@ -1956,7 +1898,6 @@ Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes; */ - STATIC_IF_MCHECK #if __STD_C Void_t* mEMALIGn_impl(size_t alignment, size_t bytes) @@ -1974,7 +1915,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)) { @@ -2105,9 +2047,6 @@ Void_t* mEMALIGn_impl(alignment, bytes) size_t alignment; size_t bytes; } - - - /* valloc just invokes memalign with alignment argument equal to the page size of the system (or as near to this as can @@ -2128,7 +2067,6 @@ Void_t* vALLOc(bytes) size_t bytes; that will accommodate request */ - #if __STD_C Void_t* pvALLOc(size_t bytes) #else @@ -2157,7 +2095,6 @@ Void_t* cALLOc_impl(n, elem_size) size_t n; size_t elem_size; INTERNAL_SIZE_T sz = n * elem_size; - /* check if expand_top called, in which case don't need to clear */ #if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT) #if MORECORE_CLEARS @@ -2183,7 +2120,6 @@ Void_t* cALLOc_impl(n, elem_size) size_t n; size_t elem_size; /* Two optional cases in which clearing not necessary */ - #if HAVE_MMAP if (chunk_is_mmapped(p)) return mem; #endif @@ -2224,7 +2160,6 @@ void cfree(mem) Void_t *mem; } #endif - #ifdef MCHECK_HEAP_PROTECTION #include "mcheck_core.inc.h" #if !__STD_C @@ -2309,7 +2244,6 @@ enum mcheck_status mprobe(void *__ptr) { return mcheck_mprobe(__ptr); } // mcheck API } #endif - /* Malloc_trim gives memory back to the system (via negative @@ -2389,8 +2323,6 @@ int malloc_trim(pad) size_t pad; } } - - /* malloc_usable_size: @@ -2424,9 +2356,6 @@ size_t malloc_usable_size(mem) Void_t* mem; } } - - - /* Utility to update current_mallinfo for malloc_stats and mallinfo() */ #ifdef DEBUG @@ -2469,8 +2398,6 @@ static void malloc_update_mallinfo(void) } #endif /* DEBUG */ - - /* malloc_stats: @@ -2515,9 +2442,6 @@ struct mallinfo mALLINFo(void) } #endif /* DEBUG */ - - - /* mallopt: diff --git a/common/edid.c b/common/edid.c index 556c4e3434b..e5aa4ca494f 100644 --- a/common/edid.c +++ b/common/edid.c @@ -9,7 +9,6 @@ * Copyright (C) Nalin Dahyabhai <bigfun@pobox.com> */ -#include <common.h> #include <edid.h> #include <errno.h> #include <fdtdec.h> @@ -17,6 +16,199 @@ #include <linux/ctype.h> #include <linux/string.h> +#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD) +#define TIMING(c, ha, hfp, hbp, hsl, va, vfp, vbp, vsl, f) \ + .pixelclock = { (c), (c), (c) }, \ + .hactive = { (ha), (ha), (ha) }, \ + .hfront_porch = { (hfp), (hfp), (hfp) }, \ + .hback_porch = { (hbp), (hbp), (hbp) }, \ + .hsync_len = { (hsl), (hsl), (hsl) }, \ + .vactive = { (va), (va), (va) }, \ + .vfront_porch = { (vfp), (vfp), (vfp) }, \ + .vback_porch = { (vbp), (vbp), (vbp) }, \ + .vsync_len = { (vsl), (vsl), (vsl) }, \ + .flags = (f) + +static const struct display_timing dmt_timings[] = { + { TIMING(31500000, 640, 32, 64, 96, 350, 32, 3, 60, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(31500000, 640, 32, 64, 96, 400, 1, 3, 41, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(35500000, 720, 36, 72, 108, 400, 1, 3, 42, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(25175000, 640, 16, 96, 48, 480, 10, 2, 33, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(31500000, 640, 24, 40, 128, 480, 9, 3, 28, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(31500000, 640, 16, 64, 120, 480, 1, 3, 16, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(36000000, 640, 56, 56, 80, 480, 1, 3, 25, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(36000000, 800, 24, 72, 128, 600, 1, 2, 22, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(40000000, 800, 40, 128, 88, 600, 1, 4, 23, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(50000000, 800, 56, 120, 64, 600, 37, 6, 23, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(49500000, 800, 16, 80, 160, 600, 1, 3, 21, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(56250000, 800, 32, 64, 152, 600, 1, 3, 27, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(73250000, 800, 48, 32, 80, 600, 3, 4, 29, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(33750000, 848, 16, 112, 112, 480, 6, 8, 23, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(44900000, 1024, 8, 176, 56, 768, 0, 8, 41, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(65000000, 1024, 24, 136, 160, 768, 3, 6, 29, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(75000000, 1024, 24, 136, 144, 768, 3, 6, 29, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(78750000, 1024, 16, 96, 176, 768, 1, 3, 28, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(94500000, 1024, 48, 96, 208, 768, 1, 3, 36, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(115500000, 1024, 48, 32, 80, 768, 3, 4, 38, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(108000000, 1152, 64, 128, 256, 864, 1, 3, 32, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(74250000, 1280, 110, 40, 220, 720, 5, 5, 20, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(68250000, 1280, 48, 32, 80, 768, 3, 7, 12, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(79500000, 1280, 64, 128, 192, 768, 3, 7, 20, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(102250000, 1280, 80, 128, 208, 768, 3, 7, 27, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(117500000, 1280, 80, 136, 216, 768, 3, 7, 31, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(140250000, 1280, 48, 32, 80, 768, 3, 7, 35, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(71000000, 1280, 48, 32, 80, 800, 3, 6, 14, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(83500000, 1280, 72, 128, 200, 800, 3, 6, 22, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(106500000, 1280, 80, 128, 208, 800, 3, 6, 29, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(122500000, 1280, 80, 136, 216, 800, 3, 6, 34, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(146250000, 1280, 48, 32, 80, 800, 3, 6, 38, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(108000000, 1280, 96, 112, 312, 960, 1, 3, 36, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(148500000, 1280, 64, 160, 224, 960, 1, 3, 47, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(175500000, 1280, 48, 32, 80, 960, 3, 4, 50, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(108000000, 1280, 48, 112, 248, 1024, 1, 3, 38, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(135000000, 1280, 16, 144, 248, 1024, 1, 3, 38, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(157500000, 1280, 64, 160, 224, 1024, 1, 3, 44, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(187250000, 1280, 48, 32, 80, 1024, 3, 7, 50, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(85500000, 1360, 64, 112, 256, 768, 3, 6, 18, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(148250000, 1360, 48, 32, 80, 768, 3, 5, 37, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(85500000, 1366, 70, 143, 213, 768, 3, 3, 24, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(72000000, 1366, 14, 56, 64, 768, 1, 3, 28, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(101000000, 1400, 48, 32, 80, 1050, 3, 4, 23, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(121750000, 1400, 88, 144, 232, 1050, 3, 4, 32, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(156000000, 1400, 104, 144, 248, 1050, 3, 4, 42, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(179500000, 1400, 104, 152, 256, 1050, 3, 4, 48, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(208000000, 1400, 48, 32, 80, 1050, 3, 4, 55, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(88750000, 1440, 48, 32, 80, 900, 3, 6, 17, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(106500000, 1440, 80, 152, 232, 900, 3, 6, 25, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(136750000, 1440, 96, 152, 248, 900, 3, 6, 33, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(157000000, 1440, 104, 152, 256, 900, 3, 6, 39, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(182750000, 1440, 48, 32, 80, 900, 3, 6, 44, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(108000000, 1600, 24, 80, 96, 900, 1, 3, 96, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(162000000, 1600, 64, 192, 304, 1200, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(175500000, 1600, 64, 192, 304, 1200, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(189000000, 1600, 64, 192, 304, 1200, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(202500000, 1600, 64, 192, 304, 1200, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(229500000, 1600, 64, 192, 304, 1200, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(268250000, 1600, 48, 32, 80, 1200, 3, 4, 64, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(119000000, 1680, 48, 32, 80, 1050, 3, 6, 21, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(146250000, 1680, 104, 176, 280, 1050, 3, 6, 30, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(187000000, 1680, 120, 176, 296, 1050, 3, 6, 40, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(214750000, 1680, 128, 176, 304, 1050, 3, 6, 46, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(245500000, 1680, 48, 32, 80, 1050, 3, 6, 53, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(204750000, 1792, 128, 200, 328, 1344, 1, 3, 46, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(261000000, 1792, 96, 216, 352, 1344, 1, 3, 69, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(333250000, 1792, 48, 32, 80, 1344, 3, 4, 72, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(218250000, 1856, 96, 224, 352, 1392, 1, 3, 43, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(288000000, 1856, 128, 224, 352, 1392, 1, 3, 104, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(356500000, 1856, 48, 32, 80, 1392, 3, 4, 75, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(148500000, 1920, 88, 44, 148, 1080, 4, 5, 36, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(154000000, 1920, 48, 32, 80, 1200, 3, 6, 26, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(193250000, 1920, 136, 200, 336, 1200, 3, 6, 36, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(245250000, 1920, 136, 208, 344, 1200, 3, 6, 46, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(281250000, 1920, 144, 208, 352, 1200, 3, 6, 53, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(317000000, 1920, 48, 32, 80, 1200, 3, 6, 62, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(234000000, 1920, 128, 208, 344, 1440, 1, 3, 56, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(297000000, 1920, 144, 224, 352, 1440, 1, 3, 56, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(380500000, 1920, 48, 32, 80, 1440, 3, 4, 78, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(162000000, 2048, 26, 80, 96, 1152, 1, 3, 44, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(268500000, 2560, 48, 32, 80, 1600, 3, 6, 37, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(348500000, 2560, 192, 280, 472, 1600, 3, 6, 49, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(443250000, 2560, 208, 280, 488, 1600, 3, 6, 63, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(505250000, 2560, 208, 280, 488, 1600, 3, 6, 73, + DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_HIGH) }, + { TIMING(552750000, 2560, 48, 32, 80, 1600, 3, 6, 85, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(556744000, 4096, 8, 32, 40, 2160, 48, 8, 6, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, + { TIMING(556188000, 4096, 8, 32, 40, 2160, 48, 8, 6, + DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, +}; +#endif + int edid_check_info(struct edid1_info *edid_info) { if ((edid_info == NULL) || (edid_info->version == 0)) @@ -169,11 +361,11 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) return false; } -static bool edid_find_valid_timing(void *buf, int count, - struct display_timing *timing, - bool (*mode_valid)(void *priv, - const struct display_timing *timing), - void *mode_valid_priv) +static bool edid_find_valid_detailed_timing(void *buf, int count, + struct display_timing *timing, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv) { struct edid_detailed_timing *t = buf; bool found = false; @@ -192,6 +384,73 @@ static bool edid_find_valid_timing(void *buf, int count, return found; } +static bool edid_get_standard_timing(struct edid1_info *edid, int i, unsigned int *x, + unsigned int *y, unsigned int *freq) +{ + unsigned int aspect = 10000; + unsigned char xres, vfreq; + + xres = EDID1_INFO_STANDARD_TIMING_XRESOLUTION(*edid, i); + vfreq = EDID1_INFO_STANDARD_TIMING_VFREQ(*edid, i); + if (xres != vfreq || (xres != 0 && xres != 1) || + (vfreq != 0 && vfreq != 1)) { + switch (EDID1_INFO_STANDARD_TIMING_ASPECT(*edid, i)) { + case ASPECT_625: // 16:10 + aspect = 6250; + break; + case ASPECT_75: // 4:3 + aspect = 7500; + break; + case ASPECT_8: // 5:4 + aspect = 8000; + break; + case ASPECT_5625: // 16:9 + aspect = 5625; + break; + } + + *x = (xres + 31) * 8; + *y = *x * aspect / 10000; + *freq = (vfreq & 0x3f) + 60; + + return true; + } + + return false; +} + +#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD) +static bool edid_find_valid_standard_timing(struct edid1_info *buf, + struct display_timing *timing, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv) +{ + unsigned int x, y, freq; + bool found = false; + int i, k; + + for (i = 0; i < ARRAY_SIZE(buf->standard_timings); i++) { + if (!edid_get_standard_timing(buf, i, &x, &y, &freq)) + continue; + + for (k = 0; k < ARRAY_SIZE(dmt_timings); k++) { + const struct display_timing *dt = &dmt_timings[k]; + + if (dt->hactive.typ == x && dt->vactive.typ == y) { + found = mode_valid(mode_valid_priv, dt); + if (found) { + memcpy(timing, dt, sizeof(*timing)); + return true; + } + } + } + } + + return found; +} +#endif + int edid_get_timing_validate(u8 *buf, int buf_size, struct display_timing *timing, int *panel_bits_per_colourp, @@ -218,8 +477,8 @@ int edid_get_timing_validate(u8 *buf, int buf_size, } /* Look for detailed timing in base EDID */ - found = edid_find_valid_timing(edid->monitor_details.descriptor, 4, - timing, mode_valid, mode_valid_priv); + found = edid_find_valid_detailed_timing(edid->monitor_details.descriptor, 4, + timing, mode_valid, mode_valid_priv); /* Look for detailed timing in CTA-861 Extension Block */ if (!found && edid->extension_flag && buf_size >= EDID_EXT_SIZE) { @@ -232,12 +491,19 @@ int edid_get_timing_validate(u8 *buf, int buf_size, int size = count * sizeof(struct edid_detailed_timing); if (offset >= 4 && offset + size < EDID_SIZE) - found = edid_find_valid_timing( + found = edid_find_valid_detailed_timing( (u8 *)info + offset, count, timing, mode_valid, mode_valid_priv); } } +#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD) + /* Look for timing in Standard Timings */ + if (!found) + found = edid_find_valid_standard_timing(edid, timing, mode_valid, + mode_valid_priv); +#endif + if (!found) return -EINVAL; @@ -269,7 +535,6 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, panel_bits_per_colourp, NULL, NULL); } - /** * Snip the tailing whitespace/return of a string. * @@ -463,34 +728,11 @@ void edid_print_info(struct edid1_info *edid_info) /* Standard timings. */ printf("Standard timings:\n"); for (i = 0; i < ARRAY_SIZE(edid_info->standard_timings); i++) { - unsigned int aspect = 10000; - unsigned int x, y; - unsigned char xres, vfreq; - - xres = EDID1_INFO_STANDARD_TIMING_XRESOLUTION(*edid_info, i); - vfreq = EDID1_INFO_STANDARD_TIMING_VFREQ(*edid_info, i); - if ((xres != vfreq) || - ((xres != 0) && (xres != 1)) || - ((vfreq != 0) && (vfreq != 1))) { - switch (EDID1_INFO_STANDARD_TIMING_ASPECT(*edid_info, - i)) { - case ASPECT_625: - aspect = 6250; - break; - case ASPECT_75: - aspect = 7500; - break; - case ASPECT_8: - aspect = 8000; - break; - case ASPECT_5625: - aspect = 5625; - break; - } - x = (xres + 31) * 8; - y = x * aspect / 10000; + unsigned int x, y, freq; + + if (edid_get_standard_timing(edid_info, i, &x, &y, &freq)) { printf("\t%dx%d%c\t%d Hz\n", x, y, - x > 1000 ? ' ' : '\t', (vfreq & 0x3f) + 60); + x > 1000 ? ' ' : '\t', freq); have_timing = 1; } } diff --git a/common/eeprom/eeprom_field.c b/common/eeprom/eeprom_field.c index f56eebe679f..64b9db18c25 100644 --- a/common/eeprom/eeprom_field.c +++ b/common/eeprom/eeprom_field.c @@ -6,7 +6,8 @@ * Igor Grinberg <grinberg@compulab.co.il> */ -#include <common.h> +#include <stdio.h> +#include <vsprintf.h> #include <linux/string.h> #include <eeprom_field.h> @@ -55,8 +56,8 @@ static int __eeprom_field_update_bin(struct eeprom_field *field, tmp[k] = value[reverse ? i - 1 + k : i + k]; } - byte = simple_strtoul(tmp, &endptr, 0); - if (*endptr != '\0' || byte < 0) + byte = simple_strtoul(tmp, &endptr, 16); + if (*endptr != '\0') return -1; field->buf[j] = byte; diff --git a/common/eeprom/eeprom_layout.c b/common/eeprom/eeprom_layout.c index 5a9be1da061..8c0b7e0b393 100644 --- a/common/eeprom/eeprom_layout.c +++ b/common/eeprom/eeprom_layout.c @@ -6,8 +6,8 @@ * Igor Grinberg <grinberg@compulab.co.il> */ -#include <common.h> #include <linux/kernel.h> +#include <linux/string.h> #include <eeprom_layout.h> #include <eeprom_field.h> @@ -57,6 +57,28 @@ static void eeprom_layout_print(const struct eeprom_layout *layout) } /* + * eeprom_layout_find_field() - finds a layout field by name + * @layout: A pointer to an existing struct layout. + * @field_name: The name of the field to update. + * @warn: Whether to print a warning if the field is not found. + * + * Returns: a pointer to the found field or NULL on failure. + */ +struct eeprom_field *eeprom_layout_find_field(struct eeprom_layout *layout, + char *field_name, bool warn) +{ + for (int i = 0; i < layout->num_of_fields; i++) + if (layout->fields[i].name != RESERVED_FIELDS && + !strcmp(layout->fields[i].name, field_name)) + return &layout->fields[i]; + + if (warn) + printf("No such field '%s'\n", field_name); + + return NULL; +} + +/* * eeprom_layout_update_field() - update a single field in the layout data. * @layout: A pointer to an existing struct layout. * @field_name: The name of the field to update. @@ -67,8 +89,8 @@ static void eeprom_layout_print(const struct eeprom_layout *layout) static int eeprom_layout_update_field(struct eeprom_layout *layout, char *field_name, char *new_data) { - int i, err; - struct eeprom_field *fields = layout->fields; + struct eeprom_field *field; + int err; if (new_data == NULL) return 0; @@ -76,21 +98,15 @@ static int eeprom_layout_update_field(struct eeprom_layout *layout, if (field_name == NULL) return -1; - for (i = 0; i < layout->num_of_fields; i++) { - if (fields[i].name == RESERVED_FIELDS || - strcmp(fields[i].name, field_name)) - continue; - - err = fields[i].update(&fields[i], new_data); - if (err) - printf("Invalid data for field %s\n", field_name); - - return err; - } + field = eeprom_layout_find_field(layout, field_name, true); + if (field == NULL) + return -1; - printf("No such field '%s'\n", field_name); + err = field->update(field, new_data); + if (err) + printf("Invalid data for field %s\n", field_name); - return -1; + return err; } /* @@ -111,14 +127,14 @@ void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf, else layout->layout_version = layout_version; + layout->data_size = buf_size; + layout->print = eeprom_layout_print; + layout->update = eeprom_layout_update_field; + eeprom_layout_assign(layout, layout_version); layout->data = buf; for (i = 0; i < layout->num_of_fields; i++) { layout->fields[i].buf = buf; buf += layout->fields[i].size; } - - layout->data_size = buf_size; - layout->print = eeprom_layout_print; - layout->update = eeprom_layout_update_field; } diff --git a/common/event.c b/common/event.c index 16c2ba6cc92..8d7513eb10b 100644 --- a/common/event.c +++ b/common/event.c @@ -9,13 +9,13 @@ #define LOG_CATEGORY LOGC_EVENT -#include <common.h> #include <event.h> #include <event_internal.h> #include <log.h> #include <linker_lists.h> #include <malloc.h> #include <asm/global_data.h> +#include <linux/errno.h> #include <linux/list.h> #include <relocate.h> @@ -48,6 +48,9 @@ const char *const type_name[] = { /* main loop events */ "main_loop", + + /* livetree has been built */ + "of_live_init", }; _Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size"); diff --git a/common/exports.c b/common/exports.c index 20d8b759bc2..48b084c3861 100644 --- a/common/exports.c +++ b/common/exports.c @@ -1,4 +1,3 @@ -#include <common.h> #include <command.h> #include <exports.h> #include <malloc.h> diff --git a/common/flash.c b/common/flash.c index 848f44e59df..fd1b4ddf660 100644 --- a/common/flash.c +++ b/common/flash.c @@ -6,10 +6,10 @@ /* #define DEBUG */ -#include <common.h> #include <flash.h> #include <log.h> -#include <uuid.h> +#include <u-boot/uuid.h> +#include <linux/string.h> #include <mtd/cfi_flash.h> @@ -110,13 +110,13 @@ addr2info(ulong addr) * Make sure all target addresses are within Flash bounds, * and no protected sectors are hit. * Returns: - * ERR_OK 0 - OK - * ERR_TIMEOUT 1 - write timeout - * ERR_NOT_ERASED 2 - Flash not erased - * ERR_PROTECTED 4 - target range includes protected sectors - * ERR_INVAL 8 - target address not in Flash memory - * ERR_ALIGN 16 - target address not aligned on boundary - * (only some targets require alignment) + * FL_ERR_OK 0 - OK + * FL_ERR_TIMEOUT 1 - write timeout + * FL_ERR_NOT_ERASED 2 - Flash not erased + * FL_ERR_PROTECTED 4 - target range includes protected sectors + * FL_ERR_INVAL 8 - target address not in Flash memory + * FL_ERR_ALIGN 16 - target address not aligned on boundary + * (only some targets require alignment) */ int flash_write(char *src, ulong addr, ulong cnt) @@ -131,11 +131,11 @@ flash_write(char *src, ulong addr, ulong cnt) __maybe_unused ulong cnt_orig = cnt; if (cnt == 0) { - return (ERR_OK); + return (FL_ERR_OK); } if (!info_first || !info_last) { - return (ERR_INVAL); + return (FL_ERR_INVAL); } for (info = info_first; info <= info_last; ++info) { @@ -146,7 +146,7 @@ flash_write(char *src, ulong addr, ulong cnt) if ((end >= info->start[i]) && (addr < e_addr) && (info->protect[i] != 0) ) { - return (ERR_PROTECTED); + return (FL_ERR_PROTECTED); } } } @@ -169,11 +169,11 @@ flash_write(char *src, ulong addr, ulong cnt) #if defined(CONFIG_FLASH_VERIFY) if (memcmp(src_orig, addr_orig, cnt_orig)) { printf("\nVerify failed!\n"); - return ERR_PROG_ERROR; + return FL_ERR_PROG_ERROR; } #endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */ - return (ERR_OK); + return (FL_ERR_OK); } /*----------------------------------------------------------------------- @@ -182,33 +182,33 @@ flash_write(char *src, ulong addr, ulong cnt) void flash_perror(int err) { switch (err) { - case ERR_OK: + case FL_ERR_OK: break; - case ERR_TIMEOUT: + case FL_ERR_TIMEOUT: puts ("Timeout writing to Flash\n"); break; - case ERR_NOT_ERASED: + case FL_ERR_NOT_ERASED: puts ("Flash not Erased\n"); break; - case ERR_PROTECTED: + case FL_ERR_PROTECTED: puts ("Can't write to protected Flash sectors\n"); break; - case ERR_INVAL: + case FL_ERR_INVAL: puts ("Outside available Flash\n"); break; - case ERR_ALIGN: + case FL_ERR_ALIGN: puts ("Start and/or end address not on sector boundary\n"); break; - case ERR_UNKNOWN_FLASH_VENDOR: + case FL_ERR_UNKNOWN_FLASH_VENDOR: puts ("Unknown Vendor of Flash\n"); break; - case ERR_UNKNOWN_FLASH_TYPE: + case FL_ERR_UNKNOWN_FLASH_TYPE: puts ("Unknown Type of Flash\n"); break; - case ERR_PROG_ERROR: + case FL_ERR_PROG_ERROR: puts ("General Flash Programming Error\n"); break; - case ERR_ABORTED: + case FL_ERR_ABORTED: puts("Flash Programming Aborted\n"); break; default: diff --git a/common/hash.c b/common/hash.c index 3d6b84de473..0c45992d5c7 100644 --- a/common/hash.c +++ b/common/hash.c @@ -10,7 +10,6 @@ */ #ifndef USE_HOSTCC -#include <common.h> #include <command.h> #include <env.h> #include <log.h> @@ -144,7 +143,8 @@ static int __maybe_unused hash_finish_sha512(struct hash_algo *algo, void *ctx, return 0; } -static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) +static int __maybe_unused hash_init_crc16_ccitt(struct hash_algo *algo, + void **ctxp) { uint16_t *ctx = malloc(sizeof(uint16_t)); *ctx = 0; @@ -152,16 +152,18 @@ static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) return 0; } -static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx, - const void *buf, unsigned int size, - int is_last) +static int __maybe_unused hash_update_crc16_ccitt(struct hash_algo *algo, + void *ctx, const void *buf, + unsigned int size, + int is_last) { *((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size); return 0; } -static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx, - void *dest_buf, int size) +static int __maybe_unused hash_finish_crc16_ccitt(struct hash_algo *algo, + void *ctx, void *dest_buf, + int size) { if (size < algo->digest_size) return -1; @@ -296,6 +298,7 @@ static struct hash_algo hash_algo[] = { #endif }, #endif +#if CONFIG_IS_ENABLED(CRC16) { .name = "crc16-ccitt", .digest_size = 2, @@ -305,6 +308,15 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc16_ccitt, .hash_finish = hash_finish_crc16_ccitt, }, +#endif +#if CONFIG_IS_ENABLED(CRC8) && IS_ENABLED(CONFIG_HASH_CRC8) + { + .name = "crc8", + .digest_size = 1, + .chunk_size = CHUNKSZ_CRC32, + .hash_func_ws = crc8_wd_buf, + }, +#endif #if CONFIG_IS_ENABLED(CRC32) { .name = "crc32", @@ -404,7 +416,7 @@ int hash_block(const char *algo_name, const void *data, unsigned int len, return 0; } -#if !defined(CONFIG_SPL_BUILD) && (defined(CONFIG_CMD_HASH) || \ +#if !defined(CONFIG_XPL_BUILD) && (defined(CONFIG_CMD_HASH) || \ defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32)) || \ defined(CONFIG_CMD_MD5SUM) /** diff --git a/common/hwconfig.c b/common/hwconfig.c index cac0b6348f4..25a8cd5bf5d 100644 --- a/common/hwconfig.c +++ b/common/hwconfig.c @@ -10,7 +10,6 @@ #ifndef HWCONFIG_TEST #include <config.h> -#include <common.h> #include <env.h> #include <exports.h> #include <hwconfig.h> @@ -78,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/Makefile b/common/init/Makefile index 853b56d1e57..224e092f88c 100644 --- a/common/init/Makefile +++ b/common/init/Makefile @@ -5,4 +5,4 @@ # obj-y += board_init.o -obj-$(CONFIG_$(SPL_TPL_)HANDOFF) += handoff.o +obj-$(CONFIG_$(PHASE_)HANDOFF) += handoff.o diff --git a/common/init/board_init.c b/common/init/board_init.c index ed2365daa35..a06ec1caa2c 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -6,7 +6,7 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> +#include <config.h> #include <bootstage.h> #include <init.h> #include <asm/global_data.h> diff --git a/common/init/handoff.c b/common/init/handoff.c index d0be1bb17a2..a7cd065fb38 100644 --- a/common/init/handoff.c +++ b/common/init/handoff.c @@ -5,7 +5,6 @@ * Copyright 2018 Google, Inc */ -#include <common.h> #include <handoff.h> #include <asm/global_data.h> diff --git a/common/iomux.c b/common/iomux.c index c428f7110a7..4844df51fbe 100644 --- a/common/iomux.c +++ b/common/iomux.c @@ -4,7 +4,6 @@ * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. */ -#include <common.h> #include <console.h> #include <serial.h> #include <malloc.h> @@ -132,7 +131,7 @@ int iomux_doenv(const int console, const char *arg) /* Stop dropped consoles */ for (i = 0; i < repeat; i++) { j = iomux_match_device(cons_set, cs_idx, old_set[i]); - if (j == cs_idx) + if (j == -ENOENT) console_stop(console, old_set[i]); } diff --git a/common/iotrace.c b/common/iotrace.c index 63d0cca3a00..a0a5613bd9b 100644 --- a/common/iotrace.c +++ b/common/iotrace.c @@ -5,7 +5,6 @@ #define IOTRACE_IMPL -#include <common.h> #include <mapmem.h> #include <time.h> #include <asm/global_data.h> diff --git a/common/kallsyms.c b/common/kallsyms.c index 13344e634b9..91594414099 100644 --- a/common/kallsyms.c +++ b/common/kallsyms.c @@ -5,8 +5,6 @@ * Licensed under the GPL-2 or later. */ -#include <common.h> - /* We need the weak marking as this symbol is provided specially */ extern const char system_map[] __attribute__((weak)); diff --git a/common/kgdb.c b/common/kgdb.c index 29b09fcfe56..ed2798bea24 100644 --- a/common/kgdb.c +++ b/common/kgdb.c @@ -87,7 +87,6 @@ * ****************************************************************************/ -#include <common.h> #include <asm/ptrace.h> #include <kgdb.h> @@ -447,7 +446,6 @@ handle_exception (struct pt_regs *regs) } break; - case 'k': /* kill the program, actually return to monitor */ kd.extype = KGDBEXIT_KILL; *regs = entry_regs; diff --git a/common/kgdb_stubs.c b/common/kgdb_stubs.c index 66aed7cea1c..256d88697d7 100644 --- a/common/kgdb_stubs.c +++ b/common/kgdb_stubs.c @@ -7,7 +7,6 @@ * Licensed under the GPL-2 or later. */ -#include <common.h> #include <cpu_func.h> #include <kgdb.h> #include <serial.h> diff --git a/common/log.c b/common/log.c index 42d35f04b68..b75e404420b 100644 --- a/common/log.c +++ b/common/log.c @@ -6,7 +6,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <display_options.h> #include <log.h> #include <malloc.h> @@ -32,6 +31,8 @@ static const char *const log_cat_name[] = { "event", "fs", "expo", + "console", + "test", }; _Static_assert(ARRAY_SIZE(log_cat_name) == LOGC_COUNT - LOGC_NONE, @@ -129,17 +130,25 @@ bool log_has_cat(enum log_category_t cat_list[], enum log_category_t cat) return false; } -bool log_has_file(const char *file_list, const char *file) +/** + * log_has_member() - check if a string is in a comma separated list + * + * @list: Comma separated list of strings + * @member: String to find + * + * Return: ``true`` if @member is in @list, else ``false`` + */ +static bool log_has_member(const char *list, const char *member) { - int file_len = strlen(file); + int member_len = strlen(member); const char *s, *p; int substr_len; - for (s = file_list; *s; s = p + (*p != '\0')) { + for (s = list; *s; s = p + (*p != '\0')) { p = strchrnul(s, ','); substr_len = p - s; - if (file_len >= substr_len && - !strncmp(file + file_len - substr_len, s, substr_len)) + if (member_len >= substr_len && + !strncmp(member + member_len - substr_len, s, substr_len)) return true; } @@ -180,7 +189,11 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec) continue; if (filt->file_list && - !log_has_file(filt->file_list, rec->file)) + !log_has_member(filt->file_list, rec->file)) + continue; + + if (filt->func_list && + !log_has_member(filt->func_list, rec->func)) continue; if (filt->flags & LOGFF_DENY) @@ -320,7 +333,7 @@ int _log_buffer(enum log_category_t cat, enum log_level_t level, int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[], enum log_level_t level, const char *file_list, - int flags) + const char *func_list, int flags) { struct log_filter *filt; struct log_device *ldev; @@ -355,6 +368,13 @@ int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[], goto err; } } + if (func_list) { + filt->func_list = strdup(func_list); + if (!filt->func_list) { + ret = -ENOMEM; + goto err; + } + } filt->filter_num = ldev->next_filter_num++; /* Add deny filters to the beginning of the list */ if (flags & LOGFF_DENY) diff --git a/common/log_console.c b/common/log_console.c index bb091ce21a4..9376baad664 100644 --- a/common/log_console.c +++ b/common/log_console.c @@ -6,7 +6,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <log.h> #include <asm/global_data.h> @@ -39,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 53c4def5d1c..0dcb5f7cdea 100644 --- a/common/log_syslog.c +++ b/common/log_syslog.c @@ -5,7 +5,6 @@ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> */ -#include <common.h> #include <log.h> #include <net.h> #include <asm/global_data.h> @@ -89,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/main.c b/common/main.c index 82d3aafa53c..b0b6e74f5d3 100644 --- a/common/main.c +++ b/common/main.c @@ -6,7 +6,6 @@ /* #define DEBUG */ -#include <common.h> #include <autoboot.h> #include <button.h> #include <bootstage.h> diff --git a/common/malloc_simple.c b/common/malloc_simple.c index 0a004d40e1e..f0f90a095bd 100644 --- a/common/malloc_simple.c +++ b/common/malloc_simple.c @@ -7,7 +7,6 @@ #define LOG_CATEGORY LOGC_ALLOC -#include <common.h> #include <log.h> #include <malloc.h> #include <mapmem.h> @@ -24,10 +23,11 @@ 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"); + log_err("alloc space exhausted ptr %lx limit %x\n", new_ptr, + gd->malloc_limit); return NULL; } @@ -88,6 +88,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/memsize.c b/common/memsize.c index d646df8b04c..86109579c95 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -4,7 +4,7 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include <common.h> +#include <config.h> #include <init.h> #include <asm/global_data.h> #include <cpu_func.h> diff --git a/common/memtop.c b/common/memtop.c new file mode 100644 index 00000000000..bff27d8211e --- /dev/null +++ b/common/memtop.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024, Linaro Limited + */ + +#include <fdt_support.h> +#include <fdtdec.h> +#include <memtop.h> + +#include <asm/types.h> + +#define MEM_RGN_COUNT 16 + +struct region { + phys_addr_t base; + phys_size_t size; +}; + +struct mem_region { + struct region rgn[MEM_RGN_COUNT]; + uint count; +}; + +static void add_mem_region(struct mem_region *mem_rgn, phys_addr_t base, + phys_size_t size) +{ + long i; + + for (i = mem_rgn->count; i >= 0; i--) { + if (i && base < mem_rgn->rgn[i - 1].base) { + mem_rgn->rgn[i] = mem_rgn->rgn[i - 1]; + } else { + mem_rgn->rgn[i].base = base; + mem_rgn->rgn[i].size = size; + break; + } + } + + mem_rgn->count++; +} + +static void mem_regions_init(struct mem_region *mem) +{ + uint i; + + mem->count = 0; + for (i = 0; i < MEM_RGN_COUNT; i++) { + mem->rgn[i].base = 0; + mem->rgn[i].size = 0; + } +} + +static int fdt_add_reserved_regions(struct mem_region *free_mem, + struct mem_region *reserved_mem, + void *fdt_blob) +{ + u64 addr, size; + int i, total, ret; + int nodeoffset, subnode; + struct fdt_resource res; + + if (fdt_check_header(fdt_blob) != 0) + return -1; + + /* process memreserve sections */ + total = fdt_num_mem_rsv(fdt_blob); + assert_noisy(total < MEM_RGN_COUNT); + for (i = 0; i < total; i++) { + if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) + continue; + add_mem_region(reserved_mem, addr, size); + } + + i = 0; + /* process reserved-memory */ + nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory"); + if (nodeoffset >= 0) { + subnode = fdt_first_subnode(fdt_blob, nodeoffset); + while (subnode >= 0) { + /* check if this subnode has a reg property */ + ret = fdt_get_resource(fdt_blob, subnode, "reg", 0, + &res); + if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) { + addr = res.start; + size = res.end - res.start + 1; + assert_noisy(i < MEM_RGN_COUNT); + add_mem_region(reserved_mem, addr, size); + } + + subnode = fdt_next_subnode(fdt_blob, subnode); + ++i; + } + } + + return 0; +} + +static long addrs_overlap(phys_addr_t base1, phys_size_t size1, + phys_addr_t base2, phys_size_t size2) +{ + const phys_addr_t base1_end = base1 + size1 - 1; + const phys_addr_t base2_end = base2 + size2 - 1; + + return ((base1 <= base2_end) && (base2 <= base1_end)); +} + +static long region_overlap_check(struct mem_region *mem_rgn, phys_addr_t base, + phys_size_t size) +{ + unsigned long i; + struct region *rgn = mem_rgn->rgn; + + for (i = 0; i < mem_rgn->count; i++) { + phys_addr_t rgnbase = rgn[i].base; + phys_size_t rgnsize = rgn[i].size; + + if (addrs_overlap(base, size, rgnbase, rgnsize)) + break; + } + + return (i < mem_rgn->count) ? i : -1; +} + +static phys_addr_t find_ram_top(struct mem_region *free_mem, + struct mem_region *reserved_mem, phys_size_t size) +{ + long i, rgn; + phys_addr_t base = 0; + phys_addr_t res_base; + + for (i = free_mem->count - 1; i >= 0; i--) { + phys_addr_t rgnbase = free_mem->rgn[i].base; + phys_size_t rgnsize = free_mem->rgn[i].size; + + if (rgnsize < size) + continue; + + base = rgnbase + rgnsize - size; + while (base && rgnbase <= base) { + rgn = region_overlap_check(reserved_mem, base, size); + if (rgn < 0) + return base; + + res_base = reserved_mem->rgn[rgn].base; + if (res_base < size) + break; + base = res_base - size; + } + } + + return 0; +} + +phys_addr_t get_mem_top(phys_addr_t ram_start, phys_size_t ram_size, + phys_size_t size, void *fdt) +{ + int i; + struct mem_region free_mem; + struct mem_region reserved_mem; + + mem_regions_init(&free_mem); + mem_regions_init(&reserved_mem); + + add_mem_region(&free_mem, ram_start, ram_size); + + i = fdt_add_reserved_regions(&free_mem, &reserved_mem, fdt); + if (i < 0) + return 0; + + return find_ram_top(&free_mem, &reserved_mem, size); +} diff --git a/common/menu.c b/common/menu.c index b55cf7b9996..5a2126aa01a 100644 --- a/common/menu.c +++ b/common/menu.c @@ -5,7 +5,6 @@ */ #include <ansi.h> -#include <common.h> #include <cli.h> #include <malloc.h> #include <errno.h> @@ -44,6 +43,7 @@ struct menu { void (*display_statusline)(struct menu *); void (*item_data_print)(void *); char *(*item_choice)(void *); + bool (*need_reprint)(void *); void *item_choice_data; struct list_head items; int item_cnt; @@ -118,6 +118,11 @@ static inline void *menu_item_destroy(struct menu *m, */ static inline void menu_display(struct menu *m) { + if (m->need_reprint) { + if (!m->need_reprint(m->item_choice_data)) + return; + } + if (m->title) { puts(m->title); putc('\n'); @@ -363,6 +368,9 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data) * item. Returns a key string corresponding to the chosen item or NULL if * no item has been selected. * + * need_reprint - If not NULL, will be called before printing the menu. + * Returning FALSE means the menu does not need reprint. + * * item_choice_data - Will be passed as the argument to the item_choice function * * Returns a pointer to the menu if successful, or NULL if there is @@ -372,6 +380,7 @@ struct menu *menu_create(char *title, int timeout, int prompt, void (*display_statusline)(struct menu *), void (*item_data_print)(void *), char *(*item_choice)(void *), + bool (*need_reprint)(void *), void *item_choice_data) { struct menu *m; @@ -387,6 +396,7 @@ struct menu *menu_create(char *title, int timeout, int prompt, m->display_statusline = display_statusline; m->item_data_print = item_data_print; m->item_choice = item_choice; + m->need_reprint = need_reprint; m->item_choice_data = item_choice_data; m->item_cnt = 0; @@ -399,7 +409,6 @@ struct menu *menu_create(char *title, int timeout, int prompt, } else m->title = NULL; - INIT_LIST_HEAD(&m->items); return m; @@ -527,14 +536,15 @@ enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, struct cli_ch_state *cch) { enum bootmenu_key key; - int c; + int c, errchar = 0; c = cli_ch_process(cch, 0); if (!c) { while (!c && !tstc()) { schedule(); mdelay(10); - c = cli_ch_process(cch, -ETIMEDOUT); + c = cli_ch_process(cch, errchar); + errchar = -ETIMEDOUT; } if (!c) { c = getchar(); diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 194c84e7e89..274e88a4921 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -9,7 +9,6 @@ * channel. */ -#include <common.h> #include <dm.h> #include <log.h> #include <miiphy.h> @@ -31,7 +30,7 @@ #define debug(fmt, args...) #endif /* MII_DEBUG */ -static struct list_head mii_devs; +static LIST_HEAD(mii_devs); static struct mii_dev *current_mii; /* @@ -56,16 +55,6 @@ struct mii_dev *miiphy_get_dev_by_name(const char *devname) return NULL; } -/***************************************************************************** - * - * Initialize global data. Need to be called before any other miiphy routine. - */ -void miiphy_init(void) -{ - INIT_LIST_HEAD(&mii_devs); - current_mii = NULL; -} - struct mii_dev *mdio_alloc(void) { struct mii_dev *bus; @@ -76,7 +65,7 @@ struct mii_dev *mdio_alloc(void) memset(bus, 0, sizeof(*bus)); - /* initalize mii_dev struct fields */ + /* initialize mii_dev struct fields */ INIT_LIST_HEAD(&bus->link); return bus; diff --git a/common/s_record.c b/common/s_record.c index 2b7651fcffc..486dd93abd4 100644 --- a/common/s_record.c +++ b/common/s_record.c @@ -4,7 +4,6 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include <common.h> #include <s_record.h> static int hex1_bin (char c); diff --git a/common/scp03.c b/common/scp03.c index 09ef7b5ba3d..54b1bd54b60 100644 --- a/common/scp03.c +++ b/common/scp03.c @@ -4,10 +4,11 @@ * */ -#include <common.h> #include <scp03.h> #include <tee.h> #include <tee/optee_ta_scp03.h> +#include <linux/errno.h> +#include <linux/string.h> static int scp03_enable(bool provision) { diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 6405374bcc1..a84a0f83924 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -78,14 +78,16 @@ 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 default 0xbfa0 if MACH_SUN50I_H616 default 0x7000 if RCAR_GEN3 default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0 + default 0x7fa0 if ARCH_SUNXI default 0x10000 if ASPEED_AST2600 default 0x27000 if IMX8MM && SPL_TEXT_BASE = 0x7E1000 + default 0x30000 if ARCH_SC5XX && (SC59X_64 || SC59X) + default 0x20000 if ARCH_SC5XX && (SC58X || SC57X) default 0x0 help Maximum size of the SPL image (text, data, rodata, and linker lists @@ -94,6 +96,7 @@ config SPL_MAX_SIZE config SPL_PAD_TO hex "Offset to which the SPL should be padded before appending the SPL payload" + default 0x7f8000 if ARCH_ROCKCHIP default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB default 0x11000 if ARCH_MX7 || (ARCH_MX6 && !MX6_OCRAM_256KB) default 0x10000 if ARCH_KEYSTONE @@ -110,7 +113,7 @@ config SPL_PAD_TO config SPL_HAS_BSS_LINKER_SECTION depends on SPL_FRAMEWORK bool "Use a specific address for the BSS via the linker script" - default y if ARCH_SUNXI || ARCH_MX6 || ARCH_OMAP2PLUS || MIPS || RISCV || ARCH_ZYNQMP + default y if ARCH_SUNXI || ARCH_MX6 || ARCH_OMAP2PLUS || MIPS || RISCV || ARCH_ZYNQMP || ARCH_SC5XX config SPL_BSS_START_ADDR hex "Link address for the BSS within the SPL binary" @@ -122,6 +125,9 @@ config SPL_BSS_START_ADDR default 0x4ff80000 if ARCH_SUNXI && !(MACH_SUN9I || MACH_SUNIV) default 0x2ff80000 if ARCH_SUNXI && MACH_SUN9I default 0x1000 if ARCH_ZYNQMP + default 0x200B0000 if ARCH_SC5XX && (SC59X_64 || SC59X) + default 0x20080000 if ARCH_SC5XX && SC58X + default 0x200A0000 if ARCH_SC5XX && SC57X choice prompt "Enforce SPL BSS limit" @@ -150,6 +156,7 @@ config SPL_BSS_MAX_SIZE depends on SPL_BSS_LIMIT default 0x100000 if ARCH_MX6 || RISCV default 0x80000 if ARCH_OMAP2PLUS || ARCH_SUNXI + default 0x10000 if ARCH_SC5XX help When non-zero, the linker checks that the actual memory used by SPL from __bss_start to __bss_end does not exceed it. @@ -206,7 +213,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,17 +268,30 @@ config SPL_LDSCRIPT config SPL_TEXT_BASE hex "SPL Text Base" + default 0x40200000 if OMAP34XX default 0x402F4000 if AM43XX default 0x402F0400 if AM33XX + default 0x80080000 if ARCH_K3 && ARM64 + default 0x43c00000 if ARCH_K3 && !ARM64 + default 0x00908000 if ARCH_MX6 + default 0x00912000 if ARCH_MX7 default 0x40301350 if OMAP54XX default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2 default 0x00060 if ARCH_SUNXI default 0xfffc0000 if ARCH_ZYNQMP + default 0x20080000 if ARCH_SC5XX default 0x0 help The address in memory that SPL will be running from. +config SPL_SOC_INIT + bool "Call SoC-specific initialization in SPL" + help + If this option is enabled, U-Boot will call the function + spl_soc_init() from board_init_r(). This function should be + provided by the SoC vendor. + config SPL_BOARD_INIT bool "Call board-specific initialization in SPL" help @@ -344,6 +364,12 @@ config SPL_LOAD_IMX_CONTAINER Support booting U-Boot from an i.MX8 container image. If you are not using i.MX8, say 'n'. +config SPL_IMX_CONTAINER_USE_TRAMPOLINE + bool + depends on SPL + help + Enable SPL load reader to load data to a trampoline buffer. + config IMX_CONTAINER_CFG string "i.MX8 Container config file" depends on SPL && SPL_LOAD_IMX_CONTAINER @@ -362,18 +388,36 @@ config SPL_SYS_MALLOC_SIMPLE config SPL_SHARES_INIT_SP_ADDR bool "SPL and U-Boot use the same initial stack pointer location" depends on (ARM || ARCH_JZ47XX || MICROBLAZE || RISCV) && SPL_FRAMEWORK - default n if ARCH_SUNXI || ARCH_MX6 || ARCH_MX7 + default n if ARCH_SUNXI || ARCH_MX6 || ARCH_MX7 || ARCH_SC5XX default y help In many cases, we can use the same initial stack pointer address for both SPL and U-Boot itself. If you need to specify a different address however, say N here and then set a different value in CONFIG_SPL_STACK. -config SPL_STACK - hex "Initial stack pointer location" +config SPL_HAVE_INIT_STACK + bool "SPL requires a initial, fixed, stack-pointer location" depends on (ARM || ARCH_JZ47XX || MICROBLAZE || RISCV) && \ SPL_FRAMEWORK || ROCKCHIP_RK3036 depends on !SPL_SHARES_INIT_SP_ADDR + default y if ARCH_MX7 + default y if ARCH_MX6 && MX6_OCRAM_256KB + default y if ARCH_MX6 && !MX6_OCRAM_256KB + default y if MACH_SUN50I_H6 || MACH_SUN50I_H616 || MACH_SUN8I_R528 + default y if MACH_SUN50I || MACH_SUN50I_H5 + default y if MACH_SUN9I + default y if ARCH_SUNXI + default y if ARCH_SC5XX && (SC59X_64 || SC59X) + default y if ARCH_SC5XX && SC58X + default y if ARCH_SC5XX && SC57X + help + Enable if the SPL phase should not use inherit its initial + stack-pointer from the settings for U-Boot proper, but should set + its own value. + +config SPL_STACK + hex "Address of the initial stack-pointer for the SPL phase" + depends on SPL_HAVE_INIT_STACK default 0x946bb8 if ARCH_MX7 default 0x93ffb8 if ARCH_MX6 && MX6_OCRAM_256KB default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB @@ -383,6 +427,9 @@ config SPL_STACK default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5 default 0x18000 if MACH_SUN9I default 0x8000 if ARCH_SUNXI + default 0x200e4000 if ARCH_SC5XX && (SC59X_64 || SC59X) + default 0x200b0000 if ARCH_SC5XX && SC58X + default 0x200d0000 if ARCH_SC5XX && SC57X help Address of the start of the stack SPL will use before SDRAM is initialized. @@ -409,6 +456,7 @@ config SPL_STACK_R_MALLOC_SIMPLE_LEN depends on SPL_STACK_R && SPL_SYS_MALLOC_SIMPLE hex "Size of malloc_simple heap after switching to DRAM SPL stack" default 0x400000 if ARCH_K3 && ARM64 + default 0x200000 if ARCH_K3 && CPU_V7R default 0x100000 help Specify the amount of the stack to use as memory pool for @@ -440,6 +488,7 @@ config SPL_CUSTOM_SYS_MALLOC_ADDR config SPL_SYS_MALLOC_SIZE hex "Size of the SPL malloc pool" depends on SPL_SYS_MALLOC + default 0x180000 if BIOSEMU && RISCV default 0x100000 config SPL_READ_ONLY @@ -482,24 +531,46 @@ 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 || \ - OMAP44XX || OMAP54XX || AM33XX || AM43XX || \ + 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)" + default SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR if MVEBU_SPL_BOOT_DEVICE_MMC + +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 @@ -509,7 +580,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR default 0x100 if ARCH_UNIPHIER default 0x0 if ARCH_MVEBU default 0x200 if ARCH_SOCFPGA || ARCH_AT91 - default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \ + default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ OMAP54XX || AM33XX || AM43XX || ARCH_K3 default 0x4000 if ARCH_ROCKCHIP default 0x822 if TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED @@ -530,13 +601,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 @@ -545,14 +609,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 @@ -560,6 +616,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 @@ -720,6 +778,7 @@ config SPL_FS_LOAD_PAYLOAD_NAME depends on SPL_FS_EXT4 || SPL_FS_FAT || SPL_FS_SQUASHFS || SPL_SEMIHOSTING default "tispl.bin" if SYS_K3_SPL_ATF default "u-boot.itb" if SPL_LOAD_FIT + default "linux.itb" if SPL_LOAD_FIT_OPENSBI_OS_BOOT default "u-boot.img" help Filename to read to load U-Boot when reading from filesystem. @@ -951,6 +1010,14 @@ config SPL_NAND_IDENT help SPL uses the chip ID list to identify the NAND flash. +config SPL_RELOC_LOADER + bool "Allow relocating the next phase" + help + In some cases multiple U-Boot phases need to run in SRAM, typically + at the same address. Enable this to support loading the next phase + to temporary memory, then copying it into place afterwards, then + jumping to it. + config SPL_UBI bool "Support UBI" help @@ -1055,6 +1122,8 @@ config SPL_DM_SPI_FLASH config SPL_NET bool "Support networking" + depends on !NET_LWIP + select SPL_USE_TINY_PRINTF_POINTER_SUPPORT if SPL_USE_TINY_PRINTF help Enable support for network devices (such as Ethernet) in SPL. This permits SPL to load U-Boot over a network link rather than @@ -1116,6 +1185,9 @@ config SPL_PAYLOAD_ARGS_ADDR hex "Address in memory to load 'args' file for Falcon Mode to" depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT default 0x88000000 if ARCH_OMAP2PLUS + default 0x99000000 if ARCH_SC5XX && SC59X_64 + default 0xA0000000 if ARCH_SC5XX && TARGET_SC594_SOM_EZKIT + default 0x80000000 if ARCH_SC5XX && TARGET_SC594_SOM_EZLITE help Address in memory where the 'args' file, typically a device tree will be loaded in to memory. @@ -1230,15 +1302,11 @@ config SPL_POWER_DOMAIN the drivers in drivers/power/domain as part of a SPL build. config SPL_RAM_SUPPORT - bool "Support booting from RAM" - default y if MICROBLAZE || ARCH_SOCFPGA || ARCH_TEGRA || ARCH_ZYNQ - help - Enable booting of an image in RAM. The image can be preloaded or - it can be loaded by SPL directly into RAM (e.g. using USB). + bool config SPL_RAM_DEVICE bool "Support booting from preloaded image in RAM" - depends on SPL_RAM_SUPPORT + select SPL_RAM_SUPPORT default y if MICROBLAZE || ARCH_SOCFPGA || ARCH_TEGRA || ARCH_ZYNQ help Enable booting of an image already loaded in RAM. The image has to @@ -1247,6 +1315,7 @@ config SPL_RAM_DEVICE config SPL_REMOTEPROC bool "Support REMOTEPROCS" + default y if (CPU_V7R && ARCH_K3) help Enable support for REMOTEPROCs in SPL. This permits to load a remote processor firmware in SPL. @@ -1293,7 +1362,7 @@ config SPL_SATA_RAW_U_BOOT_SECTOR config SPL_NVME bool "NVM Express device support" - depends on BLK + depends on SPL_BLK select FS_LOADER select SPL_BLK_FS help @@ -1391,6 +1460,24 @@ config SYS_SPI_U_BOOT_OFFS Address within SPI-Flash from where the u-boot payload is fetched from. +config SYS_SPI_KERNEL_OFFS + hex "Falcon mode: address of kernel payload in SPI flash" + depends on SPL_SPI_FLASH_SUPPORT && SPL_OS_BOOT + help + Address within SPI-Flash from where the kernel payload is fetched + in falcon boot. + +config SYS_SPI_ARGS_OFFS + hex "Falcon mode: address of args payload in SPI flash" + depends on SPL_SPI_FLASH_SUPPORT && SPL_OS_BOOT + help + Address within SPI-Flash from where the args payload (usually the + dtb) is fetched in falcon boot. + +config SYS_SPI_ARGS_SIZE + hex "Falcon mode: size of args payload in SPI flash" + depends on SPL_SPI_FLASH_SUPPORT && SPL_OS_BOOT + config SPL_THERMAL bool "Driver support for thermal devices" help @@ -1424,7 +1511,7 @@ config SPL_ATF help ATF(ARM Trusted Firmware) is a component for ARM AArch64 which is loaded by SPL (which is considered as BL2 in ATF terminology). - More detail at: https://github.com/ARM-software/arm-trusted-firmware + More detail at: https://github.com/TrustedFirmware-A/trusted-firmware-a config SPL_ATF_LOAD_IMAGE_V2 bool "Use the new LOAD_IMAGE_V2 parameter passing" diff --git a/common/spl/Kconfig.tpl b/common/spl/Kconfig.tpl index 4ee3b9b826d..a535b61ecd3 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, @@ -106,12 +106,6 @@ config TPL_LDSCRIPT May be left empty to trigger the Makefile infrastructure to fall back to the linker-script used for the SPL stage. -config TPL_NEEDS_SEPARATE_STACK - bool "TPL needs a separate initial stack-pointer" - help - Enable, if the TPL stage should not inherit its initial - stack-pointer from the settings for the SPL stage. - config TPL_POWER bool "Support power drivers" help @@ -140,11 +134,18 @@ config TPL_MAX_SIZE help The maximum size (in bytes) of the TPL stage. +config TPL_HAVE_INIT_STACK + bool "TPL requires a initial, fixed, stack-pointer location" + help + Enable if the TPL phase should not inherit its initial + stack-pointer from the settings for U-Boot proper, but should set its + own value. + config TPL_STACK - hex "Address of the initial stack-pointer for the TPL stage" - depends on TPL_NEEDS_SEPARATE_STACK + hex "Address of the initial stack-pointer for the TPL phase" + depends on TPL_HAVE_INIT_STACK help - The address of the initial stack-pointer for the TPL stage. + The address of the initial stack-pointer for the TPL phase Usually this will be the (aligned) top-of-stack. config TPL_READ_ONLY @@ -268,6 +269,14 @@ config TPL_RAM_DEVICE be already in memory when TPL takes over, e.g. loaded by the boot ROM. +config TPL_RELOC_LOADER + bool "Allow relocating the next phase" + help + In some cases multiple U-Boot phases need to run in SRAM, typically + at the same address. Enable this to support loading the next phase + to temporary memory, then copying it into place afterwards, then + jumping to it. + config TPL_RTC bool "Support RTC drivers" help diff --git a/common/spl/Kconfig.vpl b/common/spl/Kconfig.vpl index f1993026bba..434562443ac 100644 --- a/common/spl/Kconfig.vpl +++ b/common/spl/Kconfig.vpl @@ -9,6 +9,19 @@ config VPL_BANNER_PRINT info. Disabling this option could be useful to reduce VPL boot time (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud). +config VPL_LDSCRIPT + string "Linker script for the VPL stage" + default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARM64 + default "arch/\$(ARCH)/cpu/u-boot-spl.lds" + help + The TPL stage will usually require a different linker-script + (as it runs from a different memory region) than the regular + U-Boot stage. Set this to the path of the linker-script to + be used for TPL. + + May be left empty to trigger the Makefile infrastructure to + fall back to the linker-script used for the SPL stage. + config VPL_BOARD_INIT bool "Call board-specific initialization in VPL" help @@ -181,6 +194,14 @@ config VPL_PCI necessary driver support. This enables the drivers in drivers/pci as part of a VPL build. +config VPL_RELOC_LOADER + bool "Allow relocating the next phase" + help + In some cases multiple U-Boot phases need to run in SRAM, typically + at the same address. Enable this to support loading the next phase + to temporary memory, then copying it into place afterwards, then + jumping to it. + config VPL_RTC bool "Support RTC drivers" help @@ -222,12 +243,43 @@ config VPL_SPI_FLASH_SUPPORT lines). This enables the drivers in drivers/mtd/spi as part of a VPL build. This normally requires VPL_SPI_SUPPORT. +config VPL_SYS_MALLOC_SIMPLE + bool "Only use malloc_simple functions in the VPL" + default y + help + Say Y here to only use the *_simple malloc functions from + malloc_simple.c, rather then using the versions from dlmalloc.c; + this will make the VPL binary smaller at the cost of more heap + usage as the *_simple malloc functions do not re-use free-ed mem. + config VPL_TEXT_BASE hex "VPL Text Base" default 0x0 help The address in memory that VPL will be running from. +config VPL_MAX_SIZE + hex "Maximum size (in bytes) for the VPL stage" + default 0x2e000 if ROCKCHIP_RK3399 + default 0x0 + help + The maximum size (in bytes) of the TPL stage. This size is determined + by the amount of internal SRAM memory. + +config VPL_HAVE_INIT_STACK + bool "VPL requires a initial, fixed, stack-pointer location" + help + Enable if the VPL phase should not use inherit its initial + stack-pointer from the settings for U-Boot proper, but should set + its own value. + +config VPL_STACK + hex "Address of the initial stack-pointer for the VPL phase" + depends on VPL_HAVE_INIT_STACK + help + The address of the initial stack-pointer for the VPL phase + Usually this will be the (aligned) top-of-stack. + config VPL_BINMAN_SYMBOLS bool "Declare binman symbols in VPL" depends on VPL_FRAMEWORK && BINMAN @@ -243,7 +295,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..4c9482bd309 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -6,34 +6,37 @@ # Based on common/Makefile. # -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o -obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o -obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o -obj-$(CONFIG_$(SPL_TPL_)BLK_FS) += spl_blk_fs.o -obj-$(CONFIG_$(SPL_TPL_)LEGACY_IMAGE_FORMAT) += spl_legacy.o -obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o -obj-$(CONFIG_$(SPL_TPL_)XIP_SUPPORT) += spl_xip.o -obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += spl_ymodem.o +ifdef CONFIG_XPL_BUILD +obj-$(CONFIG_$(PHASE_)FRAMEWORK) += spl.o +obj-$(CONFIG_$(PHASE_)BOOTROM_SUPPORT) += spl_bootrom.o +obj-$(CONFIG_$(PHASE_)LOAD_FIT) += spl_fit.o +obj-$(CONFIG_$(PHASE_)BLK_FS) += spl_blk_fs.o +obj-$(CONFIG_$(PHASE_)LEGACY_IMAGE_FORMAT) += spl_legacy.o +obj-$(CONFIG_$(PHASE_)RELOC_LOADER) += spl_reloc.o +obj-$(CONFIG_$(PHASE_)NOR_SUPPORT) += spl_nor.o +obj-$(CONFIG_$(PHASE_)XIP_SUPPORT) += spl_xip.o +obj-$(CONFIG_$(PHASE_)YMODEM_SUPPORT) += spl_ymodem.o ifndef CONFIG_SPL_UBI -obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += spl_nand.o -obj-$(CONFIG_$(SPL_TPL_)ONENAND_SUPPORT) += spl_onenand.o +obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += spl_nand.o +obj-$(CONFIG_$(PHASE_)ONENAND_SUPPORT) += spl_onenand.o endif -obj-$(CONFIG_$(SPL_TPL_)UBI) += spl_ubi.o -obj-$(CONFIG_$(SPL_TPL_)NET) += spl_net.o -obj-$(CONFIG_$(SPL_TPL_)MMC) += spl_mmc.o -obj-$(CONFIG_$(SPL_TPL_)ATF) += spl_atf.o -obj-$(CONFIG_$(SPL_TPL_)OPTEE_IMAGE) += spl_optee.o -obj-$(CONFIG_$(SPL_TPL_)OPENSBI) += spl_opensbi.o -obj-$(CONFIG_$(SPL_TPL_)USB_STORAGE) += spl_usb.o -obj-$(CONFIG_$(SPL_TPL_)FS_FAT) += spl_fat.o -obj-$(CONFIG_$(SPL_TPL_)FS_EXT4) += spl_ext.o -obj-$(CONFIG_$(SPL_TPL_)LOAD_IMX_CONTAINER) += spl_imx_container.o -obj-$(CONFIG_$(SPL_TPL_)SATA) += spl_sata.o -obj-$(CONFIG_$(SPL_TPL_)NVME) += spl_nvme.o -obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += spl_semihosting.o -obj-$(CONFIG_$(SPL_TPL_)DFU) += spl_dfu.o -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 +obj-$(CONFIG_$(PHASE_)UBI) += spl_ubi.o +obj-$(CONFIG_$(PHASE_)NET) += spl_net.o +obj-$(CONFIG_$(PHASE_)MMC) += spl_mmc.o +obj-$(CONFIG_$(PHASE_)ATF) += spl_atf.o +obj-$(CONFIG_$(PHASE_)OPTEE_IMAGE) += spl_optee.o +obj-$(CONFIG_$(PHASE_)OPENSBI) += spl_opensbi.o +obj-$(CONFIG_$(PHASE_)USB_STORAGE) += spl_usb.o +obj-$(CONFIG_$(PHASE_)FS_FAT) += spl_fat.o +obj-$(CONFIG_$(PHASE_)FS_EXT4) += spl_ext.o +obj-$(CONFIG_$(PHASE_)LOAD_IMX_CONTAINER) += spl_imx_container.o +obj-$(CONFIG_$(PHASE_)SATA) += spl_sata.o +obj-$(CONFIG_$(PHASE_)NVME) += spl_nvme.o +obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += spl_semihosting.o +obj-$(CONFIG_$(PHASE_)DFU) += spl_dfu.o +obj-$(CONFIG_$(PHASE_)SPI_LOAD) += spl_spi.o +obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o +obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o endif + +obj-$(CONFIG_$(PHASE_)UPL) += spl_upl.o diff --git a/common/spl/spl.c b/common/spl/spl.c index e06bc75d36b..76fd56dfe4b 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -6,7 +6,7 @@ * Aneesh V <aneesh@ti.com> */ -#include <common.h> +#include <config.h> #include <bloblist.h> #include <binman_sym.h> #include <bootstage.h> @@ -23,7 +23,6 @@ #include <system-constants.h> #include <asm/global_data.h> #include <asm-generic/gpio.h> -#include <asm/u-boot.h> #include <nand.h> #include <fat.h> #include <u-boot/crc.h> @@ -51,8 +50,10 @@ u32 *boot_params_ptr = NULL; #if CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS) /* See spl.h for information about this */ +#if defined(CONFIG_SPL_BUILD) binman_sym_declare(ulong, u_boot_any, image_pos); binman_sym_declare(ulong, u_boot_any, size); +#endif #ifdef CONFIG_TPL binman_sym_declare(ulong, u_boot_spl_any, image_pos); @@ -98,9 +99,9 @@ __weak int dram_init_banksize(void) #if CONFIG_IS_ENABLED(OS_BOOT) __weak int spl_start_uboot(void) { - puts(SPL_TPL_PROMPT + puts(PHASE_PROMPT "Please implement spl_start_uboot() for your board\n"); - puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n"); + puts(PHASE_PROMPT "Direct Linux boot not active!\n"); return 1; } @@ -141,13 +142,13 @@ void spl_fixup_fdt(void *fdt_blob) /* fixup the memory dt node */ err = fdt_shrink_to_minimum(fdt_blob, 0); if (err == 0) { - printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err); + printf(PHASE_PROMPT "fdt_shrink_to_minimum err - %d\n", err); return; } err = arch_fixup_fdt(fdt_blob); if (err) { - printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err); + printf(PHASE_PROMPT "arch_fixup_fdt err - %d\n", err); return; } #endif @@ -177,12 +178,18 @@ ulong spl_get_image_pos(void) return BINMAN_SYM_MISSING; #ifdef CONFIG_VPL - if (spl_next_phase() == PHASE_VPL) + if (xpl_next_phase() == PHASE_VPL) return binman_sym(ulong, u_boot_vpl_any, image_pos); #endif - return spl_next_phase() == PHASE_SPL ? - binman_sym(ulong, u_boot_spl_any, image_pos) : - binman_sym(ulong, u_boot_any, image_pos); +#if defined(CONFIG_TPL) && !defined(CONFIG_VPL) + if (xpl_next_phase() == PHASE_SPL) + return binman_sym(ulong, u_boot_spl_any, image_pos); +#endif +#if defined(CONFIG_SPL_BUILD) + return binman_sym(ulong, u_boot_any, image_pos); +#endif + + return BINMAN_SYM_MISSING; } ulong spl_get_image_size(void) @@ -191,10 +198,10 @@ ulong spl_get_image_size(void) return BINMAN_SYM_MISSING; #ifdef CONFIG_VPL - if (spl_next_phase() == PHASE_VPL) + if (xpl_next_phase() == PHASE_VPL) return binman_sym(ulong, u_boot_vpl_any, size); #endif - return spl_next_phase() == PHASE_SPL ? + return xpl_next_phase() == PHASE_SPL ? binman_sym(ulong, u_boot_spl_any, size) : binman_sym(ulong, u_boot_any, size); } @@ -202,10 +209,10 @@ ulong spl_get_image_size(void) ulong spl_get_image_text_base(void) { #ifdef CONFIG_VPL - if (spl_next_phase() == PHASE_VPL) + if (xpl_next_phase() == PHASE_VPL) return CONFIG_VPL_TEXT_BASE; #endif - return spl_next_phase() == PHASE_SPL ? CONFIG_SPL_TEXT_BASE : + return xpl_next_phase() == PHASE_SPL ? CONFIG_SPL_TEXT_BASE : CONFIG_TEXT_BASE; } @@ -246,7 +253,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(); @@ -265,16 +271,21 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) */ if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) { /* Binman does not support separated entry addresses */ - spl_image->entry_point = u_boot_pos; - spl_image->load_addr = u_boot_pos; + spl_image->entry_point = spl_get_image_text_base(); + spl_image->load_addr = spl_get_image_text_base(); + spl_image->size = spl_get_image_size(); + log_debug("Next load addr %lx\n", spl_image->load_addr); } else { spl_image->entry_point = CONFIG_SYS_UBOOT_START; spl_image->load_addr = CONFIG_TEXT_BASE; + log_debug("Default load addr %x (u_boot_pos=%lx)\n", + CONFIG_TEXT_BASE, u_boot_pos); } spl_image->os = IH_OS_U_BOOT; - spl_image->name = "U-Boot"; + spl_image->name = xpl_name(xpl_next_phase()); + log_debug("Next phase: %s at %lx size %lx\n", spl_image->name, + spl_image->load_addr, (ulong)spl_image->size); } -#endif __weak int spl_parse_board_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, @@ -309,8 +320,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 @@ -320,10 +333,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)) { @@ -332,12 +344,12 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->load_addr = start; spl_image->entry_point = start; spl_image->size = size; - debug(SPL_TPL_PROMPT + debug(PHASE_PROMPT "payload Image, load addr: 0x%lx size: %d\n", 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)) { @@ -346,27 +358,26 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; spl_image->size = end - start; - debug(SPL_TPL_PROMPT + debug(PHASE_PROMPT "payload zImage, load addr: 0x%lx size: %d\n", 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; @@ -426,7 +437,7 @@ static int write_spl_handoff(void) ret = handoff_arch_save(ho); if (ret) return ret; - debug(SPL_TPL_PROMPT "Wrote SPL handoff\n"); + debug(PHASE_PROMPT "Wrote SPL handoff\n"); return 0; } @@ -444,7 +455,7 @@ static inline int write_spl_handoff(void) { return 0; } */ static enum bootstage_id get_bootstage_id(bool start) { - enum u_boot_phase phase = spl_phase(); + enum xpl_phase_t phase = xpl_phase(); if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL) return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL; @@ -467,19 +478,18 @@ static int spl_common_init(bool setup_malloc) gd->malloc_ptr = 0; } #endif - ret = bootstage_init(u_boot_first_phase()); + ret = bootstage_init(xpl_is_first_phase()); if (ret) { debug("%s: Failed to set up bootstage: ret=%d\n", __func__, ret); return ret; } - if (!u_boot_first_phase()) { + if (!xpl_is_first_phase()) { ret = bootstage_unstash_default(); if (ret) log_debug("Failed to unstash bootstage: ret=%d\n", ret); } - bootstage_mark_name(get_bootstage_id(true), - spl_phase_name(spl_phase())); + bootstage_mark_name(get_bootstage_id(true), xpl_name(xpl_phase())); #if CONFIG_IS_ENABLED(LOG) ret = log_init(); if (ret) { @@ -496,7 +506,7 @@ static int spl_common_init(bool setup_malloc) } if (CONFIG_IS_ENABLED(DM)) { bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL, - spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl"); + xpl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL); @@ -504,6 +514,10 @@ static int spl_common_init(bool setup_malloc) debug("dm_init_and_scan() returned error %d\n", ret); return ret; } + + ret = dm_autoprobe(); + if (ret) + return ret; } return 0; @@ -627,18 +641,21 @@ static int boot_from_devices(struct spl_image_info *spl_image, printf("Trying to boot from %s\n", spl_loader_name(loader)); else if (CONFIG_IS_ENABLED(SHOW_ERRORS)) { - printf(SPL_TPL_PROMPT + printf(PHASE_PROMPT "Unsupported Boot Device %d\n", bootdev); } else { - puts(SPL_TPL_PROMPT + puts(PHASE_PROMPT "Unsupported Boot Device!\n"); } } - if (loader && - !spl_load_image(spl_image, loader)) { - spl_image->boot_device = bootdev; - return 0; + if (loader) { + ret = spl_load_image(spl_image, loader); + if (!ret) { + spl_image->boot_device = bootdev; + return 0; + } + printf("Error: %d\n", ret); } } } @@ -672,19 +689,16 @@ void board_init_r(gd_t *dummy1, ulong dummy2) BOOT_DEVICE_NONE, BOOT_DEVICE_NONE, }; - typedef void __noreturn (*jump_to_image_t)(struct spl_image_info *); - jump_to_image_t jump_to_image = &jump_to_image_no_args; + spl_jump_to_image_t jump_to_image = &jump_to_image_no_args; struct spl_image_info spl_image; int ret, os; - debug(">>" SPL_TPL_PROMPT "board_init_r()\n"); + debug(">>" PHASE_PROMPT "board_init_r()\n"); spl_set_bd(); if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) { - mem_malloc_init((ulong)map_sysmem(SPL_SYS_MALLOC_START, - SPL_SYS_MALLOC_SIZE), - SPL_SYS_MALLOC_SIZE); + mem_malloc_init(SPL_SYS_MALLOC_START, SPL_SYS_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; } if (!(gd->flags & GD_FLG_SPL_INIT)) { @@ -697,7 +711,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) if (ret) { debug("%s: Failed to set up bloblist: ret=%d\n", __func__, ret); - puts(SPL_TPL_PROMPT "Cannot set up bloblist\n"); + puts(PHASE_PROMPT "Cannot set up bloblist\n"); hang(); } } @@ -706,28 +720,34 @@ void board_init_r(gd_t *dummy1, ulong dummy2) ret = setup_spl_handoff(); if (ret) { - puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n"); + puts(PHASE_PROMPT "Cannot set up SPL handoff\n"); hang(); } } - if (CONFIG_IS_ENABLED(BOARD_INIT)) - spl_board_init(); + if (CONFIG_IS_ENABLED(SOC_INIT)) + spl_soc_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) - puts(SPL_TPL_PROMPT "Cannot initialize PCI\n"); + puts(PHASE_PROMPT "Cannot initialize PCI\n"); /* 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 */ @@ -748,10 +768,10 @@ void board_init_r(gd_t *dummy1, ulong dummy2) ARRAY_SIZE(spl_boot_list)); if (ret) { if (CONFIG_IS_ENABLED(SHOW_ERRORS)) - printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n", + printf(PHASE_PROMPT "failed to boot from all boot devices (err=%d)\n", ret); else - puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n"); + puts(PHASE_PROMPT "failed to boot from all boot devices\n"); hang(); } @@ -759,7 +779,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) os = spl_image.os; if (os == IH_OS_U_BOOT) { - debug("Jumping to %s...\n", spl_phase_name(spl_next_phase())); + debug("Jumping to %s...\n", xpl_name(xpl_next_phase())); } else if (CONFIG_IS_ENABLED(ATF) && os == IH_OS_ARM_TRUSTED_FIRMWARE) { debug("Jumping to U-Boot via ARM Trusted Firmware\n"); spl_fixup_fdt(spl_image_fdt_addr(&spl_image)); @@ -782,7 +802,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"); @@ -805,9 +825,17 @@ void board_init_r(gd_t *dummy1, ulong dummy2) if (CONFIG_IS_ENABLED(HANDOFF)) { ret = write_spl_handoff(); if (ret) - printf(SPL_TPL_PROMPT + printf(PHASE_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(PHASE_PROMPT + "UPL hand-off write failed (err=%d)\n", ret); + hang(); + } + } if (CONFIG_IS_ENABLED(BLOBLIST)) { ret = bloblist_finish(); if (ret) @@ -816,6 +844,18 @@ void board_init_r(gd_t *dummy1, ulong dummy2) } spl_board_prepare_for_boot(); + + if (CONFIG_IS_ENABLED(RELOC_LOADER)) { + int ret; + + ret = spl_reloc_jump(&spl_image, jump_to_image); + if (ret) { + if (xpl_phase() == PHASE_VPL) + printf("jump failed %d\n", ret); + hang(); + } + } + jump_to_image(&spl_image); } @@ -825,15 +865,15 @@ void board_init_r(gd_t *dummy1, ulong dummy2) */ void preloader_console_init(void) { -#ifdef CONFIG_SPL_SERIAL +#if CONFIG_IS_ENABLED(SERIAL) gd->baudrate = CONFIG_BAUDRATE; 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 " - " + puts("\nU-Boot " PHASE_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME " " U_BOOT_TZ ")\n"); #endif #ifdef CONFIG_SPL_DISPLAY_PRINT @@ -884,7 +924,7 @@ __weak void spl_relocate_stack_check(void) */ ulong spl_relocate_stack_gd(void) { -#ifdef CONFIG_SPL_STACK_R +#if CONFIG_IS_ENABLED(STACK_R) gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; @@ -893,7 +933,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_atf.c b/common/spl/spl_atf.c index 3bdd013a35f..8bc5db77395 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -9,7 +9,6 @@ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH */ -#include <common.h> #include <atf_common.h> #include <cpu_func.h> #include <errno.h> @@ -42,9 +41,9 @@ struct bl2_to_bl31_params_mem_v2 { struct entry_point_info bl31_ep_info; }; -struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry, - uintptr_t bl33_entry, - uintptr_t fdt_addr) +struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry, + ulong bl33_entry, + ulong fdt_addr) { static struct bl2_to_bl31_params_mem bl31_params_mem; struct bl31_params *bl2_to_bl31_params; @@ -101,17 +100,17 @@ struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry, return bl2_to_bl31_params; } -__weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, - uintptr_t bl33_entry, - uintptr_t fdt_addr) +__weak struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry, + ulong bl33_entry, + ulong fdt_addr) { return bl2_plat_get_bl31_params_default(bl32_entry, bl33_entry, fdt_addr); } -struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry, - uintptr_t bl33_entry, - uintptr_t fdt_addr) +struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry, + ulong bl33_entry, + ulong fdt_addr) { static struct bl2_to_bl31_params_mem_v2 bl31_params_mem; struct bl_params *bl_params; @@ -174,9 +173,9 @@ struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry, return bl_params; } -__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry, - uintptr_t bl33_entry, - uintptr_t fdt_addr) +__weak struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry, + ulong bl33_entry, + ulong fdt_addr) { return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry, fdt_addr); @@ -189,8 +188,8 @@ static inline void raw_write_daif(unsigned int daif) typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, void *plat_params); -static void __noreturn bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry, - uintptr_t bl33_entry, uintptr_t fdt_addr) +static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry, + ulong bl33_entry, ulong fdt_addr) { atf_entry_t atf_entry = (atf_entry_t)bl31_entry; void *bl31_params; @@ -204,7 +203,8 @@ static void __noreturn bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry, fdt_addr); raw_write_daif(SPSR_EXCEPTION_MASK); - dcache_disable(); + if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) + dcache_disable(); atf_entry(bl31_params, (void *)fdt_addr); } @@ -238,7 +238,7 @@ static int spl_fit_images_find(void *blob, int os) return -FDT_ERR_NOTFOUND; } -uintptr_t spl_fit_images_get_entry(void *blob, int node) +ulong spl_fit_images_get_entry(void *blob, int node) { ulong val; int ret; @@ -253,10 +253,10 @@ uintptr_t spl_fit_images_get_entry(void *blob, int node) void __noreturn spl_invoke_atf(struct spl_image_info *spl_image) { - uintptr_t bl32_entry = 0; - uintptr_t bl33_entry = CONFIG_TEXT_BASE; + ulong bl32_entry = 0; + ulong bl33_entry = CONFIG_TEXT_BASE; void *blob = spl_image->fdt_addr; - uintptr_t platform_param = (uintptr_t)blob; + ulong platform_param = (ulong)blob; int node; /* diff --git a/common/spl/spl_blk_fs.c b/common/spl/spl_blk_fs.c index 04eac6f306b..bbf90a9741e 100644 --- a/common/spl/spl_blk_fs.c +++ b/common/spl/spl_blk_fs.c @@ -5,7 +5,6 @@ * */ -#include <common.h> #include <spl.h> #include <spl_load.h> #include <image.h> @@ -81,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_bootrom.c b/common/spl/spl_bootrom.c index 0eefd39a519..e172a2d7b83 100644 --- a/common/spl/spl_bootrom.c +++ b/common/spl/spl_bootrom.c @@ -3,7 +3,6 @@ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmH */ -#include <common.h> #include <spl.h> __weak int board_return_to_bootrom(struct spl_image_info *spl_image, diff --git a/common/spl/spl_dfu.c b/common/spl/spl_dfu.c index 8a779da8fa1..e9f381c392c 100644 --- a/common/spl/spl_dfu.c +++ b/common/spl/spl_dfu.c @@ -5,7 +5,6 @@ * * Ravi B <ravibabu@ti.com> */ -#include <common.h> #include <env.h> #include <spl.h> #include <linux/compiler.h> diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index 2be6f04b02c..7e0274a3058 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -1,11 +1,9 @@ // SPDX-License-Identifier: GPL-2.0+ -#include <common.h> #include <env.h> #include <part.h> #include <spl.h> #include <spl_load.h> -#include <asm/u-boot.h> #include <ext4fs.h> #include <errno.h> #include <image.h> @@ -13,12 +11,20 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, ulong size, void *buf) { + struct legacy_img_hdr *header; int ret; loff_t actlen; ret = ext4fs_read(buf, file_offset, size, &actlen); if (ret) return ret; + + if (CONFIG_IS_ENABLED(OS_BOOT)) { + header = (struct legacy_img_hdr *)buf; + if (image_get_magic(header) != FDT_MAGIC) + return size; + } + return actlen; } @@ -53,8 +59,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 a52f9e178e6..f426a068ff9 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -8,12 +8,10 @@ * FAT Image Functions copied from spl_mmc.c */ -#include <common.h> #include <env.h> #include <log.h> #include <spl.h> #include <spl_load.h> -#include <asm/u-boot.h> #include <fat.h> #include <errno.h> #include <image.h> @@ -49,6 +47,7 @@ static int spl_register_fat_device(struct blk_desc *block_dev, int partition) static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, ulong size, void *buf) { + struct legacy_img_hdr *header; loff_t actread; int ret; char *filename = load->priv; @@ -57,6 +56,12 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, if (ret) return ret; + if (CONFIG_IS_ENABLED(OS_BOOT)) { + header = (struct legacy_img_hdr *)buf; + if (image_get_magic(header) != FDT_MAGIC) + return size; + } + return actread; } @@ -85,12 +90,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 e5195d460c4..86506d6905c 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -4,7 +4,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <errno.h> #include <fpga.h> #include <gzip.h> @@ -13,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> @@ -190,7 +190,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, /** * load_simple_fit(): load the image described in a certain FIT node * @info: points to information about the device to load data from - * @sector: the start sector of the FIT image on the device + * @fit_offset: the offset of the FIT image on the device * @ctx: points to the FIT context structure * @node: offset of the DT node describing the image to load (relative * to @fit) @@ -199,7 +199,9 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, * the image gets loaded to the address pointed to by the * load_addr member in this struct, if load_addr is not 0 * - * Return: 0 on success or a negative error number. + * Return: 0 on success, -EPERM if this image is not the correct phase + * (for CONFIG_BOOTMETH_VBE_SIMPLE_FW), or another negative error number on + * other error. */ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, const struct spl_fit_info *ctx, int node, @@ -218,6 +220,25 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, const void *fit = ctx->fit; bool external_data = false; + log_debug("starting\n"); + if (CONFIG_IS_ENABLED(BOOTMETH_VBE) && + xpl_get_phase(info) != IH_PHASE_NONE) { + enum image_phase_t phase; + int ret; + + ret = fit_image_get_phase(fit, node, &phase); + /* if the image is for any phase, let's use it */ + if (ret == -ENOENT || phase == xpl_get_phase(info)) { + log_debug("found\n"); + } else if (ret < 0) { + log_debug("err=%d\n", ret); + return ret; + } else { + log_debug("- phase mismatch, skipping this image\n"); + return -EPERM; + } + } + if (IS_ENABLED(CONFIG_SPL_FPGA) || (IS_ENABLED(CONFIG_SPL_OS_BOOT) && spl_decompression_enabled())) { if (fit_image_get_type(fit, node, &type)) @@ -243,11 +264,14 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, if (!fit_image_get_data_position(fit, node, &offset)) { external_data = true; } else if (!fit_image_get_data_offset(fit, node, &offset)) { + log_debug("read offset %x = offset from fit %lx\n", + offset, (ulong)offset + ctx->ext_data_offset); offset += ctx->ext_data_offset; external_data = true; } if (external_data) { + ulong read_offset; void *src_ptr; /* External data */ @@ -270,11 +294,12 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, overhead = get_aligned_image_overhead(info, offset); size = get_aligned_image_size(info, length, offset); + read_offset = fit_offset + get_aligned_image_offset(info, + offset); + log_debug("reading from offset %x / %lx size %lx to %p: ", + offset, read_offset, size, src_ptr); - if (info->read(info, - fit_offset + - get_aligned_image_offset(info, offset), size, - src_ptr) < length) + if (info->read(info, read_offset, size, src_ptr) < length) return -EIO; debug("External data: dst=%p, offset=%x, size=%lx\n", @@ -282,7 +307,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, src = src_ptr + overhead; } else { /* Embedded data */ - if (fit_image_get_data(fit, node, &data, &length)) { + if (fit_image_get_emb_data(fit, node, &data, &length)) { puts("Cannot get image data/size\n"); return -ENOENT; } @@ -336,6 +361,9 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, else image_info->entry_point = FDT_ERROR; } + log_debug("- done loading\n"); + + upl_add_image(fit, node, load_addr, length); return 0; } @@ -369,7 +397,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, * Use the address following the image as target address for the * device tree. */ - image_info.load_addr = spl_image->load_addr + spl_image->size; + image_info.load_addr = ALIGN(spl_image->load_addr + spl_image->size, 8); /* Figure out which device tree the board wants to use */ node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index++); @@ -446,7 +474,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, image_info.load_addr = (ulong)tmpbuffer; ret = load_simple_fit(info, offset, ctx, node, &image_info); - if (ret < 0) + if (ret == -EPERM) + continue; + else if (ret < 0) break; /* Make room in FDT for changes from the overlay */ @@ -485,9 +515,6 @@ static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index, const char *name; int node; - if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY)) - return 0; - ret = spl_fit_get_image_name(ctx, "loadables", index, &name); if (ret < 0) return ret; @@ -588,7 +615,7 @@ __weak void *spl_load_simple_fit_fix_load(const void *fit) static void warn_deprecated(const char *msg) { printf("DEPRECATED: %s\n", msg); - printf("\tSee doc/uImage.FIT/source_file_format.txt\n"); + printf("\tSee https://fitspec.osfw.foundation/\n"); } static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, @@ -807,7 +834,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, image_info.load_addr = 0; ret = load_simple_fit(info, offset, &ctx, node, &image_info); - if (ret < 0) { + if (ret < 0 && ret != -EPERM) { printf("%s: can't load image loadables index %d (ret = %d)\n", __func__, index, ret); return ret; @@ -833,7 +860,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, spl_image->entry_point = image_info.entry_point; /* Record our loadables into the FDT */ - if (spl_image->fdt_addr) + if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) && + xpl_get_fdt_update(info) && spl_image->fdt_addr) spl_fit_record_loadable(&ctx, index, spl_image->fdt_addr, &image_info); @@ -848,6 +876,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; } @@ -858,7 +888,7 @@ int spl_load_fit_image(struct spl_image_info *spl_image, { struct bootm_headers images; const char *fit_uname_config = NULL; - uintptr_t fdt_hack; + ulong fdt_hack; const char *uname; ulong fw_data = 0, dt_data = 0, img_data = 0; ulong fw_len = 0, dt_len = 0, img_len = 0; @@ -900,7 +930,7 @@ int spl_load_fit_image(struct spl_image_info *spl_image, spl_image->os = IH_OS_INVALID; spl_image->name = genimg_get_os_name(spl_image->os); - debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", + debug(PHASE_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); #ifdef CONFIG_SPL_FIT_SIGNATURE @@ -942,6 +972,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_imx_container.c b/common/spl/spl_imx_container.c index b4ea9241d68..b3565efb225 100644 --- a/common/spl/spl_imx_container.c +++ b/common/spl/spl_imx_container.c @@ -4,7 +4,6 @@ */ #define LOG_CATEGORY LOGC_ARCH -#include <common.h> #include <stdlib.h> #include <errno.h> #include <imx_container.h> @@ -15,6 +14,16 @@ #include <asm/mach-imx/ahab.h> #endif +__weak bool arch_check_dst_in_secure(void *start, ulong size) +{ + return false; +} + +__weak void *arch_get_container_trampoline(void) +{ + return NULL; +} + static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, struct spl_load_info *info, struct container_hdr *container, @@ -23,6 +32,7 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, { struct boot_img_t *images; ulong offset, overhead, size; + void *buf, *trampoline; if (image_index > container->num_images) { debug("Invalid image number\n"); @@ -43,12 +53,27 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, debug("%s: container: %p offset: %lu size: %lu\n", __func__, container, offset, size); - if (info->read(info, offset, size, - map_sysmem(images[image_index].dst - overhead, - images[image_index].size)) < - images[image_index].size) { - printf("%s wrong\n", __func__); - return NULL; + + buf = map_sysmem(images[image_index].dst - overhead, images[image_index].size); + if (IS_ENABLED(CONFIG_SPL_IMX_CONTAINER_USE_TRAMPOLINE) && + arch_check_dst_in_secure(buf, size)) { + trampoline = arch_get_container_trampoline(); + if (!trampoline) { + printf("%s: trampoline size is zero\n", __func__); + return NULL; + } + + if (info->read(info, offset, size, trampoline) < images[image_index].size) { + printf("%s: failed to load image to a trampoline buffer\n", __func__); + return NULL; + } + + memcpy(buf, trampoline, images[image_index].size); + } else { + if (info->read(info, offset, size, buf) < images[image_index].size) { + printf("%s: failed to load image to a non-secure region\n", __func__); + return NULL; + } } #ifdef CONFIG_AHAB_BOOT diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index 08687ca8f6c..b3efb3e630e 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -3,7 +3,6 @@ * Copyright (C) 2020 Stefan Roese <sr@denx.de> */ -#include <common.h> #include <image.h> #include <log.h> #include <malloc.h> @@ -17,11 +16,11 @@ #define LZMA_LEN (1 << 20) -static void spl_parse_legacy_validate(uintptr_t start, uintptr_t size) +static void spl_parse_legacy_validate(ulong start, ulong size) { - uintptr_t spl_start = (uintptr_t)_start; - uintptr_t spl_end = (uintptr_t)&_image_binary_end; - uintptr_t end = start + size; + ulong spl_start = (ulong)_start; + ulong spl_end = (ulong)&_image_binary_end; + ulong end = start + size; if ((start >= spl_start && start < spl_end) || (end > spl_start && end <= spl_end) || @@ -72,7 +71,7 @@ int spl_parse_legacy_header(struct spl_image_info *spl_image, spl_image->os = image_get_os(header); spl_image->name = image_get_name(header); - debug(SPL_TPL_PROMPT + debug(PHASE_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 3d032bb27ce..d06f9f0dee6 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -5,7 +5,6 @@ * * Aneesh V <aneesh@ti.com> */ -#include <common.h> #include <dm.h> #include <log.h> #include <part.h> @@ -13,7 +12,6 @@ #include <spl_load.h> #include <linux/compiler.h> #include <errno.h> -#include <asm/u-boot.h> #include <errno.h> #include <mmc.h> #include <image.h> @@ -48,21 +46,18 @@ 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; + log_debug("(error=%d)\n", ret); + 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: @@ -72,41 +67,42 @@ 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); + struct udevice *dev; + struct uclass *uc; + + log_debug("Selecting MMC dev %d; seqs:\n", mmc_dev); + if (_LOG_DEBUG) { + uclass_id_foreach_dev(UCLASS_MMC, dev, uc) + log_debug("%d: %s\n", dev_seq(dev), dev->name); + } + 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; } +#if CONFIG_IS_ENABLED(DM_MMC) + log_debug("mmc %d: %s\n", mmc_dev, (*mmcp)->dev->name); +#endif return 0; } @@ -118,14 +114,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) { @@ -135,12 +131,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 @@ -166,10 +160,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 */ @@ -207,7 +199,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; @@ -216,8 +208,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) { @@ -235,40 +227,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 @@ -320,8 +312,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; } @@ -356,87 +348,85 @@ 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); + log_debug("boot_device=%d, mmc_dev=%d\n", bootdev->boot_device, + mmc_dev); 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. */ + fallthrough; #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 3b0a1524238..22883f4e8b9 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -3,7 +3,6 @@ * Copyright (C) 2011 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> */ -#include <common.h> #include <config.h> #include <fdt_support.h> #include <image.h> @@ -72,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 898f9df705a..2be7b73ed35 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -6,7 +6,6 @@ * (C) Copyright 2012 * Ilya Yanok <ilya.yanok@gmail.com> */ -#include <common.h> #include <env.h> #include <errno.h> #include <image.h> @@ -48,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 70745114efe..1021d933999 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Stefan Roese <sr@denx.de> */ -#include <common.h> +#include <config.h> #include <image.h> #include <imx_container.h> #include <log.h> @@ -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_nvme.c b/common/spl/spl_nvme.c index c8774d67ecf..0e15a3c7545 100644 --- a/common/spl/spl_nvme.c +++ b/common/spl/spl_nvme.c @@ -5,7 +5,6 @@ * */ -#include <common.h> #include <spl.h> #include <nvme.h> diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c index 53a8c6de89e..f6f65286c21 100644 --- a/common/spl/spl_onenand.c +++ b/common/spl/spl_onenand.c @@ -7,7 +7,6 @@ * Copyright (C) 2011 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> */ -#include <common.h> #include <config.h> #include <image.h> #include <log.h> diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c index ec62aab929b..0ed6afeacc6 100644 --- a/common/spl/spl_opensbi.c +++ b/common/spl/spl_opensbi.c @@ -5,7 +5,6 @@ * * Based on common/spl/spl_atf.c */ -#include <common.h> #include <cpu_func.h> #include <errno.h> #include <hang.h> @@ -58,6 +57,11 @@ void __noreturn spl_invoke_opensbi(struct spl_image_info *spl_image) hang(); } + if (!IS_ALIGNED((uintptr_t)spl_image->fdt_addr, 8)) { + pr_err("SPL image loaded an improperly-aligned device tree\n"); + hang(); + } + /* * Originally, u-boot-spl will place DTB directly after the kernel, * but the size of the kernel did not include the BSS section, which diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index 8aeda237be1..71b7a8374bb 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -9,7 +9,6 @@ * Michal Simek <michal.simek@amd.com> * Stefan Agner <stefan.agner@toradex.com> */ -#include <common.h> #include <binman_sym.h> #include <image.h> #include <log.h> @@ -70,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_reloc.c b/common/spl/spl_reloc.c new file mode 100644 index 00000000000..324b98eaf98 --- /dev/null +++ b/common/spl/spl_reloc.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <gzip.h> +#include <image.h> +#include <log.h> +#include <mapmem.h> +#include <spl.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/sections.h> +#include <asm/unaligned.h> +#include <linux/types.h> +#include <lzma/LzmaTypes.h> +#include <lzma/LzmaDec.h> +#include <lzma/LzmaTools.h> +#include <u-boot/crc.h> +#include <u-boot/lz4.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* provide a way to jump straight into the relocation code, for debugging */ +#define DEBUG_JUMP 0 + +enum { + /* margin to allow for stack growth */ + RELOC_STACK_MARGIN = 0x800, + + /* align base address for DMA controllers which require it */ + BASE_ALIGN = 0x200, + + STACK_PROT_VALUE = 0x51ce4697, +}; + +typedef int (*rcode_func)(struct spl_image_info *image); + +static int setup_layout(struct spl_image_info *image, ulong *addrp) +{ + ulong base, fdt_size; + ulong limit, rcode_base; + uint rcode_size; + int buf_size, margin; + char *rcode_buf; + + limit = ALIGN(map_to_sysmem(&limit) - RELOC_STACK_MARGIN, 8); + image->stack_prot = map_sysmem(limit, sizeof(uint)); + *image->stack_prot = STACK_PROT_VALUE; + + fdt_size = fdt_totalsize(gd->fdt_blob); + base = ALIGN(map_to_sysmem(gd->fdt_blob) + fdt_size + BASE_ALIGN - 1, + BASE_ALIGN); + + rcode_size = _rcode_end - _rcode_start; + rcode_base = limit - rcode_size; + buf_size = rcode_base - base; + uint need_size = image->size + image->fdt_size; + margin = buf_size - need_size; + log_debug("spl_reloc %s->%s: margin%s%lx limit %lx fdt_size %lx base %lx avail %x image %x fdt %lx need %x\n", + spl_phase_name(spl_phase()), spl_phase_name(spl_phase() + 1), + margin >= 0 ? " " : " -", abs(margin), limit, fdt_size, base, + buf_size, image->size, image->fdt_size, need_size); + if (margin < 0) { + log_err("Image size %x but buffer is only %x\n", need_size, + buf_size); + return -ENOSPC; + } + + rcode_buf = map_sysmem(rcode_base, rcode_size); + log_debug("_rcode_start %p: %x -- func %p %x\n", _rcode_start, + *(uint *)_rcode_start, setup_layout, *(uint *)setup_layout); + + image->reloc_offset = rcode_buf - _rcode_start; + log_debug("_rcode start %lx base %lx size %x offset %lx\n", + (ulong)map_to_sysmem(_rcode_start), rcode_base, rcode_size, + image->reloc_offset); + + memcpy(rcode_buf, _rcode_start, rcode_size); + + image->buf = map_sysmem(base, need_size); + image->fdt_buf = image->buf + image->size; + image->rcode_buf = rcode_buf; + *addrp = base; + + return 0; +} + +int spl_reloc_prepare(struct spl_image_info *image, ulong *addrp) +{ + int ret; + + ret = setup_layout(image, addrp); + if (ret) + return ret; + + return 0; +} + +typedef void __noreturn (*image_entry_noargs_t)(uint crc, uint unc_len); + +/* this is the relocation + jump code that is copied to the top of memory */ +__rcode int rcode_reloc_and_jump(struct spl_image_info *image) +{ + image_entry_noargs_t entry = (image_entry_noargs_t)image->entry_point; + u32 *dst; + ulong image_len; + size_t unc_len; + int ret, crc; + uint magic; + + dst = map_sysmem(image->load_addr, image->size); + unc_len = (void *)image->rcode_buf - (void *)dst; + image_len = image->size; + if (*image->stack_prot != STACK_PROT_VALUE) + return -EFAULT; + magic = get_unaligned_le32(image->buf); + if (CONFIG_IS_ENABLED(LZMA)) { + SizeT lzma_len = unc_len; + + ret = lzmaBuffToBuffDecompress((u8 *)dst, &lzma_len, + image->buf, image_len); + unc_len = lzma_len; + } else if (CONFIG_IS_ENABLED(GZIP)) { + ret = gunzip(dst, unc_len, image->buf, &image_len); + } else if (CONFIG_IS_ENABLED(LZ4) && magic == LZ4F_MAGIC) { + ret = ulz4fn(image->buf, image_len, dst, &unc_len); + if (ret) + return ret; + } else { + u32 *src, *end, *ptr; + + unc_len = image->size; + for (src = image->buf, end = (void *)src + image->size, + ptr = dst; src < end;) + *ptr++ = *src++; + } + if (*image->stack_prot != STACK_PROT_VALUE) + return -EFAULT; + + /* copy in the FDT if needed */ + if (image->fdt_size) + memcpy(image->fdt_start, image->fdt_buf, image->fdt_size); + + crc = crc8(0, (u8 *)dst, unc_len); + + /* jump to the entry point */ + entry(crc, unc_len); +} + +int spl_reloc_jump(struct spl_image_info *image, spl_jump_to_image_t jump) +{ + rcode_func loader; + int ret; + + log_debug("malloc usage %x bytes (%d KB of %d KB)\n", gd->malloc_ptr, + gd->malloc_ptr / 1024, CONFIG_VAL(SYS_MALLOC_F_LEN) / 1024); + + if (*image->stack_prot != STACK_PROT_VALUE) { + log_err("stack busted, cannot continue\n"); + return -EFAULT; + } + loader = (rcode_func)(void *)rcode_reloc_and_jump + image->reloc_offset; + log_debug("Jumping via %p to %lx - image %p size %x load %lx\n", loader, + image->entry_point, image, image->size, image->load_addr); + + log_debug("unc_len %lx\n", + image->rcode_buf - map_sysmem(image->load_addr, image->size)); + if (DEBUG_JUMP) { + rcode_reloc_and_jump(image); + } else { + /* + * Must disable LOG_DEBUG since the decompressor cannot call + * log functions, printf(), etc. + */ + _Static_assert(DEBUG_JUMP || !_DEBUG, + "Cannot have debug output from decompressor"); + ret = loader(image); + } + + return -EFAULT; +} diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 32746ce9f3c..67fc620d9be 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -8,9 +8,7 @@ * Derived work from spl_usb.c */ -#include <common.h> #include <spl.h> -#include <asm/u-boot.h> #include <sata.h> #include <scsi.h> #include <errno.h> diff --git a/common/spl/spl_sdp.c b/common/spl/spl_sdp.c index 9143c27bbf1..9ca80bd534f 100644 --- a/common/spl/spl_sdp.c +++ b/common/spl/spl_sdp.c @@ -4,7 +4,6 @@ * Author: Stefan Agner <stefan.agner@toradex.com> */ -#include <common.h> #include <log.h> #include <spl.h> #include <usb.h> diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index 941fa911040..f36863fe48d 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -3,7 +3,6 @@ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> */ -#include <common.h> #include <image.h> #include <log.h> #include <semihosting.h> @@ -44,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 89de73c726c..00dbd3011f0 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -8,7 +8,7 @@ * Heiko Schocher, DENX Software Engineering, hs@denx.de. */ -#include <common.h> +#include <config.h> #include <image.h> #include <imx_container.h> #include <log.h> @@ -77,20 +77,19 @@ 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()) { int err = spl_load(spl_image, bootdev, &load, 0, - CFG_SYS_SPI_KERNEL_OFFS); + CONFIG_SYS_SPI_KERNEL_OFFS); if (!err) /* Read device tree. */ - return spi_flash_read(flash, CFG_SYS_SPI_ARGS_OFFS, - CFG_SYS_SPI_ARGS_SIZE, - (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR); + return spi_flash_read( + flash, CONFIG_SYS_SPI_ARGS_OFFS, + CONFIG_SYS_SPI_ARGS_SIZE, + (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR); } #endif diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c index d7ab9efd110..a8d3f43b452 100644 --- a/common/spl/spl_ubi.c +++ b/common/spl/spl_ubi.c @@ -4,7 +4,6 @@ * Ladislav Michl <ladis@linux-mips.org> */ -#include <common.h> #include <config.h> #include <image.h> #include <nand.h> 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_usb.c b/common/spl/spl_usb.c index 479e2dc1826..932da56ab6d 100644 --- a/common/spl/spl_usb.c +++ b/common/spl/spl_usb.c @@ -8,10 +8,8 @@ * Derived work from spl_mmc.c */ -#include <common.h> #include <log.h> #include <spl.h> -#include <asm/u-boot.h> #include <errno.h> #include <usb.h> #include <fat.h> diff --git a/common/spl/spl_xip.c b/common/spl/spl_xip.c index 959915ffa61..1465c3e46b9 100644 --- a/common/spl/spl_xip.c +++ b/common/spl/spl_xip.c @@ -4,7 +4,7 @@ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. */ -#include <common.h> +#include <config.h> #include <image.h> #include <log.h> #include <spl.h> diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index 1faaa2c938d..2be957134c1 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -8,13 +8,11 @@ * * Matt Porter <mporter@ti.com> */ -#include <common.h> #include <gzip.h> #include <image.h> #include <log.h> #include <spl.h> #include <xyzModem.h> -#include <asm/u-boot.h> #include <linux/libfdt.h> #define BUF_SIZE 1024 @@ -134,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; diff --git a/common/splash.c b/common/splash.c index 6820db683bd..c5591293634 100644 --- a/common/splash.c +++ b/common/splash.c @@ -20,11 +20,12 @@ * */ -#include <common.h> #include <display_options.h> #include <env.h> #include <splash.h> #include <video.h> +#include <vsprintf.h> +#include <linux/kernel.h> static struct splash_location default_splash_locations[] = { { diff --git a/common/splash_source.c b/common/splash_source.c index 2ce0768833d..2df78a4f2d7 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -5,7 +5,6 @@ * Authors: Igor Grinberg <grinberg@compulab.co.il> */ -#include <common.h> #include <bmp_layout.h> #include <command.h> #include <env.h> @@ -216,7 +215,7 @@ static int splash_init_virtio(void) } } -#if defined(CONFIG_CMD_UBIFS) && !defined(CONFIG_SPL_BUILD) +#if defined(CONFIG_CMD_UBIFS) && !defined(CONFIG_XPL_BUILD) static int splash_mount_ubifs(struct splash_location *location) { int res; @@ -396,19 +395,10 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) } /* Extract the splash data from FIT */ - /* 1. Test if splash is in FIT internal data. */ - if (!fit_image_get_data(fit_header, node_offset, &internal_splash_data, &internal_splash_size)) - memmove((void *)(uintptr_t)bmp_load_addr, internal_splash_data, internal_splash_size); - /* 2. Test if splash is in FIT external data with fixed position. */ - else if (!fit_image_get_data_position(fit_header, node_offset, &external_splash_addr)) - is_splash_external = true; - /* 3. Test if splash is in FIT external data with offset. */ - else if (!fit_image_get_data_offset(fit_header, node_offset, &external_splash_addr)) { - /* Align data offset to 4-byte boundary */ - fit_size = ALIGN(fdt_totalsize(fit_header), 4); - /* External splash offset means the offset by end of FIT header */ - external_splash_addr += location->offset + fit_size; - is_splash_external = true; + if (!fit_image_get_data(fit_header, node_offset, &internal_splash_data, + &internal_splash_size)) { + memmove((void *)(uintptr_t)bmp_load_addr, internal_splash_data, + internal_splash_size); } else { printf("Failed to get splash image from FIT\n"); return -ENODATA; diff --git a/common/stackprot.c b/common/stackprot.c index 6495951a773..4e3297b7d00 100644 --- a/common/stackprot.c +++ b/common/stackprot.c @@ -3,7 +3,6 @@ * Copyright 2021 Broadcom */ -#include <common.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/stdio.c b/common/stdio.c index e3354f092dc..3eeb289dd8b 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -9,7 +9,6 @@ */ #include <config.h> -#include <common.h> #include <dm.h> #include <errno.h> #include <log.h> @@ -358,9 +357,6 @@ int stdio_add_devices(void) drv_system_init(); serial_stdio_init(); -#ifdef CONFIG_USB_TTY - drv_usbtty_init(); -#endif #ifdef CONFIG_USB_FUNCTION_ACM drv_usbacm_init (); #endif diff --git a/common/update.c b/common/update.c index ec302ca68fb..6801b49479d 100644 --- a/common/update.c +++ b/common/update.c @@ -6,7 +6,6 @@ * Bartlomiej Sieka <tur@semihalf.com> */ -#include <common.h> #include <cpu_func.h> #include <image.h> #include <linux/printk.h> @@ -255,7 +254,6 @@ int update_tftp(ulong addr, char *interface, char *devstring) else addr = CONFIG_UPDATE_LOAD_ADDR; - if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX, CONFIG_UPDATE_TFTP_CNT_MAX, addr)) { printf("Can't load update file, aborting auto-update\n"); diff --git a/common/usb.c b/common/usb.c index 99e6b857c74..7a8435296c6 100644 --- a/common/usb.c +++ b/common/usb.c @@ -25,7 +25,6 @@ * * For each transfer (except "Interrupt") we wait for completion. */ -#include <common.h> #include <command.h> #include <dm.h> #include <dm/device_compat.h> @@ -191,7 +190,6 @@ int usb_disable_asynch(int disable) } #endif /* !CONFIG_IS_ENABLED(DM_USB) */ - /*------------------------------------------------------------------- * Message wrappers. * @@ -215,8 +213,9 @@ int usb_int_msg(struct usb_device *dev, unsigned long pipe, * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). - * returns the transferred length if OK or -1 if error. The transferred length - * and the current status are stored in the dev->act_len and dev->status. + * returns the transferred length if OK, otherwise a negative error code. The + * transferred length and the current status are stored in the dev->act_len and + * dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, @@ -258,11 +257,14 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, break; mdelay(1); } + + if (timeout == 0) + return -ETIMEDOUT; + if (dev->status) return -1; return dev->act_len; - } /*------------------------------------------------------------------- @@ -290,7 +292,6 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, return -EIO; } - /*------------------------------------------------------------------- * Max Packet stuff */ @@ -556,17 +557,35 @@ int usb_clear_halt(struct usb_device *dev, int pipe) return 0; } - /********************************************************************** * get_descriptor type */ static int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, - USB_CNTL_TIMEOUT); + int i; + int result; + + if (size <= 0) /* No point in asking for no data */ + return -EINVAL; + + memset(buf, 0, size); /* Make sure we parse really received data */ + + for (i = 0; i < 3; ++i) { + /* retry on length 0 or error; some devices are flakey */ + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (type << 8) + index, 0, buf, size, + USB_CNTL_TIMEOUT); + if (result <= 0 && result != -ETIMEDOUT) + continue; + if (result > 1 && ((u8 *)buf)[1] != type) { + result = -ENODATA; + continue; + } + break; + } + return result; } /********************************************************************** @@ -746,7 +765,6 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid, return result; } - static void usb_try_string_workarounds(unsigned char *buf, int *length) { int newlength, oldlength = *length; @@ -761,7 +779,6 @@ static void usb_try_string_workarounds(unsigned char *buf, int *length) } } - static int usb_string_sub(struct usb_device *dev, unsigned int langid, unsigned int index, unsigned char *buf) { @@ -796,7 +813,6 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, return rc; } - /******************************************************************** * usb_string: * Get string index and translate it to ascii. @@ -852,7 +868,6 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) return err; } - /******************************************************************** * USB device handling: * the USB device are static allocated [USB_MAX_DEVICE]. @@ -1366,5 +1381,4 @@ void usb_find_usb2_hub_address_port(struct usb_device *udev, } #endif - /* EOF */ diff --git a/common/usb_hub.c b/common/usb_hub.c index 2e054eb9353..6a4bcec00bc 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -21,7 +21,6 @@ * Probes device for being a hub and configurate it */ -#include <common.h> #include <command.h> #include <dm.h> #include <env.h> @@ -29,6 +28,7 @@ #include <log.h> #include <malloc.h> #include <memalign.h> +#include <time.h> #include <asm/processor.h> #include <asm/unaligned.h> #include <linux/ctype.h> @@ -162,7 +162,6 @@ int usb_get_port_status(struct usb_device *dev, int port, void *data) return ret; } - static void usb_hub_power_on(struct usb_hub_device *hub) { int i; diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 820f591fc5b..36107a3b278 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -6,7 +6,6 @@ * Part of this source has been derived from the Linux USB * project. */ -#include <common.h> #include <console.h> #include <dm.h> #include <env.h> @@ -15,6 +14,7 @@ #include <malloc.h> #include <memalign.h> #include <stdio_dev.h> +#include <time.h> #include <watchdog.h> #include <asm/byteorder.h> #ifdef CONFIG_SANDBOX @@ -137,6 +137,11 @@ extern int __maybe_unused net_busy_flag; /* The period of time between two calls of usb_kbd_testc(). */ static unsigned long kbd_testc_tms; +int usb_kbd_remove_for_test(void) +{ + return console_remove_by_name(DEVNAME); +} + /* Puts character in the queue and sets up the in and out pointer. */ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c) { @@ -418,7 +423,7 @@ static int usb_kbd_testc(struct stdio_dev *sdev) */ unsigned long poll_delay = CONFIG_SYS_HZ / 50; -#ifdef CONFIG_CMD_NET +#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_LWIP) /* * If net_busy_flag is 1, NET transfer is running, * then we check key-pressed every second (first check may be @@ -612,7 +617,7 @@ static int probe_usb_keyboard(struct usb_device *dev) debug("USB KBD: register.\n"); memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev)); strcpy(usb_kbd_dev.name, DEVNAME); - usb_kbd_dev.flags = DEV_FLAGS_INPUT; + usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_DM; usb_kbd_dev.getc = usb_kbd_getc; usb_kbd_dev.tstc = usb_kbd_testc; usb_kbd_dev.priv = (void *)dev; @@ -643,71 +648,6 @@ static int probe_usb_keyboard(struct usb_device *dev) return 0; } -#if !CONFIG_IS_ENABLED(DM_USB) -/* Search for keyboard and register it if found. */ -int drv_usb_kbd_init(void) -{ - int error, i; - - debug("%s: Probing for keyboard\n", __func__); - /* Scan all USB Devices */ - for (i = 0; i < USB_MAX_DEVICE; i++) { - struct usb_device *dev; - - /* Get USB device. */ - dev = usb_get_dev_index(i); - if (!dev) - break; - - if (dev->devnum == -1) - continue; - - error = probe_usb_keyboard(dev); - if (!error) - return 1; - if (error && error != -ENOENT) - return error; - } - - /* No USB Keyboard found */ - return -1; -} - -/* Deregister the keyboard. */ -int usb_kbd_deregister(int force) -{ -#if CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER) - struct stdio_dev *dev; - struct usb_device *usb_kbd_dev; - struct usb_kbd_pdata *data; - - dev = stdio_get_by_name(DEVNAME); - if (dev) { - usb_kbd_dev = (struct usb_device *)dev->priv; - data = usb_kbd_dev->privptr; -#if CONFIG_IS_ENABLED(CONSOLE_MUX) - if (iomux_replace_device(stdin, DEVNAME, force ? "nulldev" : "")) - return 1; -#endif - if (stdio_deregister_dev(dev, force) != 0) - return 1; -#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE - destroy_int_queue(usb_kbd_dev, data->intq); -#endif - free(data->new); - free(data); - } - - return 0; -#else - return 1; -#endif -} - -#endif - -#if CONFIG_IS_ENABLED(DM_USB) - static int usb_kbd_probe(struct udevice *dev) { struct usb_device *udev = dev_get_parent_priv(dev); @@ -788,5 +728,3 @@ static const struct usb_device_id kbd_id_table[] = { }; U_BOOT_USB_DEVICE(usb_kbd, kbd_id_table); - -#endif diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c index 89e18a2ddad..7fe62b043e6 100644 --- a/common/usb_onboard_hub.c +++ b/common/usb_onboard_hub.c @@ -7,38 +7,208 @@ * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver */ -#include <common.h> +#include <asm/gpio.h> #include <dm.h> #include <dm/device_compat.h> +#include <i2c.h> +#include <linux/delay.h> #include <power/regulator.h> +#define USB5744_COMMAND_ATTACH 0x0056 +#define USB5744_COMMAND_ATTACH_LSB 0xAA +#define USB5744_CONFIG_REG_ACCESS 0x0037 +#define USB5744_CONFIG_REG_ACCESS_LSB 0x99 + struct onboard_hub { struct udevice *vdd; + struct gpio_desc *reset_gpio; +}; + +struct onboard_hub_data { + unsigned long reset_us; + unsigned long power_on_delay_us; + int (*init)(struct udevice *dev); }; +static int usb5744_i2c_init(struct udevice *dev) +{ + /* + * Prevent the MCU from the putting the HUB in suspend mode through register write. + * The BYPASS_UDC_SUSPEND bit (Bit 3) of the RuntimeFlags2 register at address + * 0x411D controls this aspect of the hub. + * Format to write to hub registers via SMBus- 2D 00 00 05 00 01 41 1D 08 + * Byte 0: Address of slave 2D + * Byte 1: Memory address 00 + * Byte 2: Memory address 00 + * Byte 3: Number of bytes to write to memory + * Byte 4: Write configuration register (00) + * Byte 5: Write the number of data bytes (01- 1 data byte) + * Byte 6: LSB of register address 0x41 + * Byte 7: MSB of register address 0x1D + * Byte 8: value to be written to the register + */ + u8 data_buf[8] = {0x0, 0x5, 0x0, 0x1, 0x41, 0x1D, 0x08}; + u8 config_reg_access_buf = USB5744_CONFIG_REG_ACCESS; + struct udevice *i2c_bus = NULL, *i2c_dev; + struct ofnode_phandle_args phandle; + u8 buf = USB5744_COMMAND_ATTACH; + struct dm_i2c_chip *i2c_chip; + int ret, slave_addr; + + ret = dev_read_phandle_with_args(dev, "i2c-bus", NULL, 0, 0, &phandle); + if (ret) { + dev_err(dev, "i2c-bus not specified\n"); + return ret; + } + + ret = device_get_global_by_ofnode(ofnode_get_parent(phandle.node), &i2c_bus); + if (ret) { + dev_err(dev, "Failed to get i2c node, err: %d\n", ret); + return ret; + } + + ret = ofnode_read_u32(phandle.node, "reg", &slave_addr); + if (ret) + return ret; + + ret = i2c_get_chip(i2c_bus, slave_addr, 1, &i2c_dev); + if (ret) { + dev_err(dev, "%s: can't find i2c chip device for addr 0x%x\n", __func__, + slave_addr); + return ret; + } + + i2c_chip = dev_get_parent_plat(i2c_dev); + if (!i2c_chip) { + dev_err(dev, "parent platform data not found\n"); + return -EINVAL; + } + + i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS; + /* SMBus write command */ + ret = dm_i2c_write(i2c_dev, 0, (uint8_t *)&data_buf, 8); + if (ret) { + dev_err(dev, "data_buf i2c_write failed, err:%d\n", ret); + return ret; + } + + /* Configuration register access command */ + ret = dm_i2c_write(i2c_dev, USB5744_CONFIG_REG_ACCESS_LSB, + &config_reg_access_buf, 2); + if (ret) { + dev_err(dev, "config_reg_access i2c_write failed, err: %d\n", ret); + return ret; + } + + /* USB Attach with SMBus */ + ret = dm_i2c_write(i2c_dev, USB5744_COMMAND_ATTACH_LSB, &buf, 2); + if (ret) { + dev_err(dev, "usb_attach i2c_write failed, err: %d\n", ret); + return ret; + } + + return 0; +} + +int usb_onboard_hub_reset(struct udevice *dev) +{ + struct onboard_hub_data *data = + (struct onboard_hub_data *)dev_get_driver_data(dev); + struct onboard_hub *hub = dev_get_priv(dev); + int ret; + + hub->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_IS_OUT); + + /* property is optional, don't return error! */ + if (!hub->reset_gpio) + return 0; + + ret = dm_gpio_set_value(hub->reset_gpio, 1); + if (ret) + return ret; + + udelay(data->reset_us); + + ret = dm_gpio_set_value(hub->reset_gpio, 0); + if (ret) + return ret; + + udelay(data->power_on_delay_us); + + return 0; +} + static int usb_onboard_hub_probe(struct udevice *dev) { + struct onboard_hub_data *data = + (struct onboard_hub_data *)dev_get_driver_data(dev); struct onboard_hub *hub = dev_get_priv(dev); int ret; ret = device_get_supply_regulator(dev, "vdd-supply", &hub->vdd); - if (ret) { + if (ret && ret != -ENOENT) { dev_err(dev, "can't get vdd-supply: %d\n", ret); return ret; } - ret = regulator_set_enable_if_allowed(hub->vdd, true); + if (hub->vdd) { + ret = regulator_set_enable_if_allowed(hub->vdd, true); + if (ret && ret != -ENOSYS) { + dev_err(dev, "can't enable vdd-supply: %d\n", ret); + return ret; + } + } + + ret = usb_onboard_hub_reset(dev); if (ret) - dev_err(dev, "can't enable vdd-supply: %d\n", ret); + return ret; + if (data->init) { + ret = data->init(dev); + if (ret) { + dev_err(dev, "onboard i2c init failed: %d\n", ret); + goto err; + } + } + return 0; +err: + dm_gpio_set_value(hub->reset_gpio, 0); return ret; } +static int usb_onboard_hub_bind(struct udevice *dev) +{ + struct ofnode_phandle_args phandle; + const void *fdt = gd->fdt_blob; + int ret, off; + + ret = dev_read_phandle_with_args(dev, "peer-hub", NULL, 0, 0, &phandle); + if (ret == -ENOENT) { + dev_dbg(dev, "peer-hub property not present\n"); + return 0; + } + + if (ret) { + dev_err(dev, "peer-hub not specified\n"); + return ret; + } + + off = ofnode_to_offset(phandle.node); + ret = fdt_node_check_compatible(fdt, off, "usb424,5744"); + if (!ret) + return 0; + + return -ENODEV; +} + static int usb_onboard_hub_remove(struct udevice *dev) { struct onboard_hub *hub = dev_get_priv(dev); int ret; + if (hub->reset_gpio) + dm_gpio_free(hub->reset_gpio->dev, hub->reset_gpio); + ret = regulator_set_enable_if_allowed(hub->vdd, false); if (ret) dev_err(dev, "can't disable vdd-supply: %d\n", ret); @@ -46,15 +216,34 @@ static int usb_onboard_hub_remove(struct udevice *dev) return ret; } +static const struct onboard_hub_data usb2514_data = { + .power_on_delay_us = 500, + .reset_us = 1, +}; + +static const struct onboard_hub_data usb5744_data = { + .init = usb5744_i2c_init, + .power_on_delay_us = 1000, + .reset_us = 5, +}; + static const struct udevice_id usb_onboard_hub_ids[] = { /* Use generic usbVID,PID dt-bindings (usb-device.yaml) */ - { .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */ - { } + { .compatible = "usb424,2514", /* USB2514B USB 2.0 */ + .data = (ulong)&usb2514_data, + }, { + .compatible = "usb424,2744", /* USB2744 USB 2.0 */ + .data = (ulong)&usb5744_data, + }, { + .compatible = "usb424,5744", /* USB5744 USB 3.0 */ + .data = (ulong)&usb5744_data, + } }; U_BOOT_DRIVER(usb_onboard_hub) = { .name = "usb_onboard_hub", .id = UCLASS_USB_HUB, + .bind = usb_onboard_hub_bind, .probe = usb_onboard_hub_probe, .remove = usb_onboard_hub_remove, .of_match = usb_onboard_hub_ids, diff --git a/common/usb_storage.c b/common/usb_storage.c index 774d5bdf54b..ac331f1c1b0 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -31,8 +31,6 @@ * only been tested with USB memory sticks. */ - -#include <common.h> #include <blk.h> #include <bootdev.h> #include <command.h> @@ -353,7 +351,6 @@ static int usb_stor_irq(struct usb_device *dev) return 0; } - #ifdef DEBUG static void usb_show_srb(struct scsi_cmd *pccb) @@ -665,7 +662,6 @@ static int usb_stor_CB_comdat(struct scsi_cmd *srb, struct us_data *us) return result; } - static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us) { int timeout; @@ -1117,7 +1113,6 @@ static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss, return ss->transport(srb, ss); } - #ifdef CONFIG_USB_BIN_FIXUP /* * Some USB storage devices queried for SCSI identification data respond with diff --git a/common/xyzModem.c b/common/xyzModem.c index fb319f71190..698a538a148 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -21,12 +21,13 @@ * *========================================================================== */ -#include <common.h> #include <xyzModem.h> #include <stdarg.h> +#include <time.h> #include <u-boot/crc.h> #include <watchdog.h> #include <env.h> +#include <vsprintf.h> /* Assumption - run xyzModem protocol over the console port */ @@ -61,7 +62,6 @@ static struct #define xyzModem_MAX_RETRIES_WITH_CRC 10 #define xyzModem_CAN_COUNT 3 /* Wait for 3 CAN before quitting */ - typedef int cyg_int32; static int CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) @@ -176,7 +176,6 @@ parse_num (char *s, unsigned long *val, char **es, char *delim) return true; } - #if defined(DEBUG) && !CONFIG_IS_ENABLED(USE_TINY_PRINTF) /* * Note: this debug setup works by storing the strings in a fixed buffer @@ -281,6 +280,7 @@ xyzModem_get_hdr (void) { case SOH: xyz.total_SOH++; + fallthrough; case STX: if (c == STX) xyz.total_STX++; |