diff options
| author | Tom Rini <[email protected]> | 2026-03-18 18:36:50 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-03-18 18:36:50 -0600 |
| commit | eb00c710508d09b2a3b9aca75dd18280f1304703 (patch) | |
| tree | f91864725bde06d16a7243e0a539b28b03c0f125 /arch | |
| parent | 28608c808774a39ec47d31353b141db547136e58 (diff) | |
| parent | dc88ac7681084b2aff8c3c4e1bb3e861451489a3 (diff) | |
Merge patch series "bootm: Clean up arch-specific, pre-OS clean-up"
Simon Glass <[email protected]> says:
Each arch does something slightly different before booting the OS. Some
archs even do different things depending on the CPU type.
It is quite hard to know what actually happens in the final milliseconds
before the OS boot.
This series attempts to start cleaning up U-Boot in this area.
The basic intent is to create a new bootm_final() function which can be
called by all archs. It provides some flags for a couple of necessary
variations but otherwise it is generic.
All architectures are converted over to use this new function.
board_quiesce_devices() is moved into bootm_final() so that all archs
benefit from it.
This series fixes a bug in device_remove() is fixed where removing a
parent with specialised flags (e.g. DM_REMOVE_ACTIVE_ALL) could leave
children activated, since they do not match the flags. This fixes is
needed to avoid bootm_final() causing test failures on sandbox.
Future work could take this a little further:
- Convert EFI loader to use the same function
- Improve comments for cleanup_before_linux() across architectures
- Support fake-run tracing on all archs
Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arc/lib/bootm.c | 8 | ||||
| -rw-r--r-- | arch/arm/lib/bootm.c | 50 | ||||
| -rw-r--r-- | arch/m68k/lib/bootm.c | 2 | ||||
| -rw-r--r-- | arch/microblaze/lib/bootm.c | 8 | ||||
| -rw-r--r-- | arch/mips/lib/bootm.c | 7 | ||||
| -rw-r--r-- | arch/nios2/lib/bootm.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/lib/bootm.c | 7 | ||||
| -rw-r--r-- | arch/riscv/include/asm/u-boot-riscv.h | 1 | ||||
| -rw-r--r-- | arch/riscv/lib/bootm.c | 39 | ||||
| -rw-r--r-- | arch/sandbox/lib/bootm.c | 1 | ||||
| -rw-r--r-- | arch/sh/lib/bootm.c | 2 | ||||
| -rw-r--r-- | arch/x86/lib/bootm.c | 14 | ||||
| -rw-r--r-- | arch/xtensa/lib/bootm.c | 2 |
13 files changed, 25 insertions, 118 deletions
diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index 91bce5235a5..91165a06a46 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -50,17 +50,13 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) { ulong kernel_entry; unsigned int r0, r2; - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); - kernel_entry = images->ep; debug("## Transferring control to Linux (at address %08lx)...\n", kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - printf("\nStarting kernel ...%s\n\n", fake ? - "(fake run for tracing)" : ""); - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); + bootm_final(flag); if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { r0 = 2; @@ -72,7 +68,7 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) cleanup_before_linux(); - if (!fake) + if (!(flag & BOOTM_STATE_OS_FAKE_GO)) board_jump_and_run(kernel_entry, r0, 0, r2); } diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 019eca95780..727b9c5ca5b 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -42,42 +42,6 @@ DECLARE_GLOBAL_DATA_PTR; static struct tag *params; -__weak void board_quiesce_devices(void) -{ -} - -/** - * announce_and_cleanup() - Print message and prepare for kernel boot - * - * @fake: non-zero to do everything except actually boot - */ -static void announce_and_cleanup(int fake) -{ - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); -#ifdef CONFIG_BOOTSTAGE_FDT - bootstage_fdt_add_report(); -#endif - bootstage_stash_default(); -#ifdef CONFIG_BOOTSTAGE_REPORT - bootstage_report(); -#endif - - board_quiesce_devices(); - - printf("\nStarting kernel ...%s\n\n", fake ? - "(fake run for tracing)" : ""); - /* - * Call remove function of all devices with a removal flag set. - * This may be useful for last-stage operations, like cancelling - * of DMA operation or releasing device internal buffers. - * dm_remove_devices_active() ensures that vital devices are removed in - * a second round. - */ - dm_remove_devices_active(); - - cleanup_before_linux(); -} - static void setup_start_tag (struct bd_info *bd) { params = (struct tag *)bd->bi_boot_params; @@ -294,8 +258,6 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*kernel_entry)(void *fdt_addr, void *res0, void *res1, void *res2); - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); - kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1, void *res2))images->ep; @@ -303,9 +265,10 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) (ulong) kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - announce_and_cleanup(fake); + bootm_final(flag); + cleanup_before_linux(); - if (!fake) { + if (!(flag & BOOTM_STATE_OS_FAKE_GO)) { #ifdef CONFIG_ARMV8_PSCI armv8_setup_psci(); #endif @@ -340,8 +303,6 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) char *s; void (*kernel_entry)(int zero, int arch, uint params); unsigned long r2; - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); - kernel_entry = (void (*)(int, int, uint))images->ep; #ifdef CONFIG_CPU_V7M ulong addr = (ulong)kernel_entry | 1; @@ -366,14 +327,15 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) debug("## Transferring control to Linux (at address %08lx)" \ "...\n", (ulong) kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - announce_and_cleanup(fake); + bootm_final(flag); + cleanup_before_linux(); if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) r2 = (unsigned long)images->ft_addr; else r2 = gd->bd->bi_boot_params; - if (fake) + if (flag & BOOTM_STATE_OS_FAKE_GO) return; #ifdef CONFIG_ARMV7_NONSEC diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 1fa112f8dbf..7d65f3ea1a8 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -62,6 +62,8 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) bootstage_mark(BOOTSTAGE_ID_RUN_OS); + bootm_final(0); + /* * Linux Kernel Parameters (passing board info data): * sp+00: Ignore, side effect of using jsr to jump to kernel diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 2410515f4ac..b54c902602f 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -26,8 +26,6 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) ulong dt = (ulong)images->ft_addr; ulong rd_start = images->initrd_start; ulong cmdline = images->cmdline_start; - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); - thekernel = (void (*)(char *, ulong, ulong))images->ep; debug("## Transferring control to Linux (at address 0x%08lx) ", @@ -36,13 +34,11 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) cmdline, rd_start, dt); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - printf("\nStarting kernel ...%s\n\n", fake ? - "(fake run for tracing)" : ""); - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); + bootm_final(flag); flush_cache_all(); - if (!fake) { + if (!(flag & BOOTM_STATE_OS_FAKE_GO)) { /* * Linux Kernel Parameters (passing device tree): * r5: pointer to command line diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 87195100023..066c830f3fa 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -268,12 +268,7 @@ static void boot_jump_linux(struct bootm_headers *images) if (CONFIG_IS_ENABLED(MALTA)) linux_extra = gd->ram_size; -#if IS_ENABLED(CONFIG_BOOTSTAGE_FDT) - bootstage_fdt_add_report(); -#endif -#if IS_ENABLED(CONFIG_BOOTSTAGE_REPORT) - bootstage_report(); -#endif + bootm_final(0); if (CONFIG_IS_ENABLED(RESTORE_EXCEPTION_VECTOR_BASE)) trap_restore(); diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 294ebfb508b..6004e83bf0c 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -41,6 +41,8 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; + bootm_final(0); + /* flushes data and instruction caches before calling the kernel */ disable_interrupts(); flush_dcache_all(); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index dc44bf3ab3a..f9351a17a48 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -54,12 +54,7 @@ static void boot_jump_linux(struct bootm_headers *images) bootstage_mark(BOOTSTAGE_ID_RUN_OS); -#ifdef CONFIG_BOOTSTAGE_FDT - bootstage_fdt_add_report(); -#endif -#ifdef CONFIG_BOOTSTAGE_REPORT - bootstage_report(); -#endif + bootm_final(0); #if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h index 543a1688db8..3a8fdb57136 100644 --- a/arch/riscv/include/asm/u-boot-riscv.h +++ b/arch/riscv/include/asm/u-boot-riscv.h @@ -16,7 +16,6 @@ int cleanup_before_linux(void); /* board/.../... */ int board_init(void); -void board_quiesce_devices(void); int riscv_board_reserved_mem_fixup(void *fdt); int riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt); diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 9544907ab1e..69c9ca5c487 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -25,39 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -__weak void board_quiesce_devices(void) -{ -} - -/** - * announce_and_cleanup() - Print message and prepare for kernel boot - * - * @fake: non-zero to do everything except actually boot - */ -static void announce_and_cleanup(int fake) -{ - printf("\nStarting kernel ...%s\n\n", fake ? - "(fake run for tracing)" : ""); - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); -#ifdef CONFIG_BOOTSTAGE_FDT - bootstage_fdt_add_report(); -#endif -#if CONFIG_IS_ENABLED(BOOTSTAGE_REPORT) - bootstage_report(); -#endif - - board_quiesce_devices(); - - /* - * Call remove function of all devices with a removal flag set. - * This may be useful for last-stage operations, like cancelling - * of DMA operation or releasing device internal buffers. - */ - dm_remove_devices_active(); - - cleanup_before_linux(); -} - static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && IS_ENABLED(CONFIG_LMB) && images->ft_len) { @@ -75,7 +42,6 @@ static void boot_prep_linux(struct bootm_headers *images) static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*kernel)(ulong hart, void *dtb); - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); #ifdef CONFIG_SMP int ret; #endif @@ -87,9 +53,10 @@ static void boot_jump_linux(struct bootm_headers *images, int flag) debug("## Transferring control to kernel (at address %08lx) ...\n", (ulong)kernel); - announce_and_cleanup(fake); + bootm_final(flag); + cleanup_before_linux(); - if (!fake) { + if (!(flag & BOOTM_STATE_OS_FAKE_GO)) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { #ifdef CONFIG_SMP ret = smp_call_function(images->ep, diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c index 44ba8b52e13..7a5f6f7d36e 100644 --- a/arch/sandbox/lib/bootm.c +++ b/arch/sandbox/lib/bootm.c @@ -73,6 +73,7 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { bootstage_mark(BOOTSTAGE_ID_RUN_OS); + bootm_final(flag); printf("## Transferring control to Linux (at address %08lx)...\n", images->ep); printf("sandbox: continuing, as we cannot run Linux\n"); diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 1c118870dad..81d5957edaa 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -92,6 +92,8 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) images->rd_end - images->rd_start); } + bootm_final(0); + /* Boot kernel */ kernel(); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 7a94dc877e3..cde4fbf3557 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -34,22 +34,10 @@ DECLARE_GLOBAL_DATA_PTR; void bootm_announce_and_cleanup(void) { - printf("\nStarting kernel ...\n\n"); - #ifdef CONFIG_SYS_COREBOOT timestamp_add_now(TS_START_KERNEL); #endif - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); -#if IS_ENABLED(CONFIG_BOOTSTAGE_REPORT) - bootstage_report(); -#endif - - /* - * Call remove function of all devices with a removal flag set. - * This may be useful for last-stage operations, like cancelling - * of DMA operation or releasing device internal buffers. - */ - dm_remove_devices_active(); + bootm_final(0); } #if defined(CONFIG_OF_LIBFDT) && !defined(CONFIG_OF_NO_KERNEL) diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c index 2958f207397..c19ac9d1f9a 100644 --- a/arch/xtensa/lib/bootm.c +++ b/arch/xtensa/lib/bootm.c @@ -178,6 +178,8 @@ int do_bootm_linux(int flag, struct bootm_info *bmi) printf("Transferring Control to Linux @0x%08lx ...\n\n", (ulong)images->ep); + bootm_final(flag); + flush_dcache_range((unsigned long)params_start, (unsigned long)params); if (flag & BOOTM_STATE_OS_FAKE_GO) |
