Merge patch series "Static initcalls"

Jerome Forissier <jerome.forissier@linaro.org> says:

This series replaces the dynamic initcalls (with function pointers) with
static calls, and gets rid of initcall_run_list(), init_sequence_f,
init_sequence_f_r and init_sequence_r. This makes the code simpler and the
binary slighlty smaller: -2281 bytes/-0.21 % with LTO enabled and -510
bytes/-0.05 % with LTO disabled (xilinx_zynqmp_kria_defconfig).

Execution time doesn't seem to change noticeably. There is no impact on
the SPL.

The inline assembly fixes, although they look unrelated, are triggered
on some platforms with LTO enabled. For example: kirkwood_defconfig.

CI: https://source.denx.de/u-boot/custodians/u-boot-net/-/pipelines/25514

Link: https://lore.kernel.org/r/20250404135038.2134570-1-jerome.forissier@linaro.org
This commit is contained in:
Tom Rini 2025-04-14 08:59:45 -06:00
commit 8c98b57d72
10 changed files with 295 additions and 376 deletions

View file

@ -428,11 +428,21 @@ void switch_to_hypervisor_ret(void);
#define wfi() #define wfi()
#endif #endif
#if !defined(__thumb2__)
/*
* We will need to switch to ARM mode (.arm) for some instructions such as
* mrc p15 etc.
*/
#define asm_arm_or_thumb2(insn) asm volatile(".arm\n\t" insn)
#else
#define asm_arm_or_thumb2(insn) asm volatile(insn)
#endif
static inline unsigned long read_mpidr(void) static inline unsigned long read_mpidr(void)
{ {
unsigned long val; unsigned long val;
asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (val)); asm_arm_or_thumb2("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
return val; return val;
} }
@ -461,11 +471,13 @@ static inline unsigned int get_cr(void)
unsigned int val; unsigned int val;
if (is_hyp()) if (is_hyp())
asm volatile("mrc p15, 4, %0, c1, c0, 0 @ get CR" : "=r" (val) asm_arm_or_thumb2("mrc p15, 4, %0, c1, c0, 0 @ get CR"
: "=r" (val)
: :
: "cc"); : "cc");
else else
asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) asm_arm_or_thumb2("mrc p15, 0, %0, c1, c0, 0 @ get CR"
: "=r" (val)
: :
: "cc"); : "cc");
return val; return val;
@ -474,11 +486,11 @@ static inline unsigned int get_cr(void)
static inline void set_cr(unsigned int val) static inline void set_cr(unsigned int val)
{ {
if (is_hyp()) if (is_hyp())
asm volatile("mcr p15, 4, %0, c1, c0, 0 @ set CR" : asm_arm_or_thumb2("mcr p15, 4, %0, c1, c0, 0 @ set CR" :
: "r" (val) : "r" (val)
: "cc"); : "cc");
else else
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : asm_arm_or_thumb2("mcr p15, 0, %0, c1, c0, 0 @ set CR" :
: "r" (val) : "r" (val)
: "cc"); : "cc");
isb(); isb();

View file

@ -10,6 +10,7 @@
#include <malloc.h> #include <malloc.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/global_data.h> #include <asm/global_data.h>
#include <asm/system.h>
#include <linux/errno.h> #include <linux/errno.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -126,7 +127,7 @@ void invalidate_l2_cache(void)
{ {
unsigned int val = 0; unsigned int val = 0;
asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" asm_arm_or_thumb2("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
: : "r" (val) : "cc"); : : "r" (val) : "cc");
isb(); isb();
} }

View file

@ -85,7 +85,8 @@ struct mbus_win {
static inline unsigned int readfr_extra_feature_reg(void) static inline unsigned int readfr_extra_feature_reg(void)
{ {
unsigned int val; unsigned int val;
asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
asm_arm_or_thumb2("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
(val)::"cc"); (val)::"cc");
return val; return val;
} }
@ -96,7 +97,7 @@ static inline unsigned int readfr_extra_feature_reg(void)
*/ */
static inline void writefr_extra_feature_reg(unsigned int val) static inline void writefr_extra_feature_reg(unsigned int val)
{ {
asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" asm_arm_or_thumb2("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
(val):"cc"); (val):"cc");
isb(); isb();
} }

View file

@ -19,18 +19,13 @@ int dram_init(void)
void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr) void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr)
{ {
void (*reloc_board_init_r)(gd_t *gd, ulong dest) = board_init_r; if (new_gd->reloc_off)
if (new_gd->reloc_off) {
memcpy((void *)new_gd->relocaddr, memcpy((void *)new_gd->relocaddr,
(void *)(new_gd->relocaddr - new_gd->reloc_off), (void *)(new_gd->relocaddr - new_gd->reloc_off),
new_gd->mon_len); new_gd->mon_len);
reloc_board_init_r += new_gd->reloc_off;
}
__asm__ __volatile__("mov.l %0, r15\n" : : "m" (new_gd->start_addr_sp)); __asm__ __volatile__("mov.l %0, r15\n" : : "m" (new_gd->start_addr_sp));
while (1) while (1)
reloc_board_init_r(new_gd, 0x0); board_init_r(new_gd, 0x0);
} }

View file

@ -38,6 +38,7 @@
#include <spl.h> #include <spl.h>
#include <status_led.h> #include <status_led.h>
#include <sysreset.h> #include <sysreset.h>
#include <time.h>
#include <timer.h> #include <timer.h>
#include <trace.h> #include <trace.h>
#include <upl.h> #include <upl.h>
@ -753,7 +754,7 @@ static int setup_reloc(void)
return 0; return 0;
} }
#ifdef CONFIG_OF_BOARD_FIXUP #if CONFIG_IS_ENABLED(OF_BOARD_FIXUP)
static int fix_fdt(void) static int fix_fdt(void)
{ {
return board_fix_fdt((void *)gd->fdt_blob); return board_fix_fdt((void *)gd->fdt_blob);
@ -881,81 +882,86 @@ static int initf_upl(void)
return 0; return 0;
} }
static const init_fnc_t init_sequence_f[] = { static void initcall_run_f(void)
setup_mon_len, {
#ifdef CONFIG_OF_CONTROL /*
fdtdec_setup, * 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 #endif
#ifdef CONFIG_TRACE_EARLY #if CONFIG_IS_ENABLED(TRACE_EARLY)
trace_early_init, INITCALL(trace_early_init);
#endif #endif
initf_malloc, INITCALL(initf_malloc);
initf_upl, INITCALL(initf_upl);
log_init, INITCALL(log_init);
initf_bootstage, /* uses its own timer, so does not need DM */ INITCALL(initf_bootstage); /* uses its own timer, so does not need DM */
event_init, INITCALL(event_init);
bloblist_maybe_init, INITCALL(bloblist_maybe_init);
setup_spl_handoff, INITCALL(setup_spl_handoff);
#if defined(CONFIG_CONSOLE_RECORD_INIT_F) #if CONFIG_IS_ENABLED(CONSOLE_RECORD_INIT_F)
console_record_init, INITCALL(console_record_init);
#endif #endif
INITCALL_EVENT(EVT_FSP_INIT_F), INITCALL_EVT(EVT_FSP_INIT_F);
arch_cpu_init, /* basic arch cpu dependent setup */ INITCALL(arch_cpu_init); /* basic arch cpu dependent setup */
mach_cpu_init, /* SoC/machine dependent CPU setup */ INITCALL(mach_cpu_init); /* SoC/machine dependent CPU setup */
initf_dm, INITCALL(initf_dm);
#if defined(CONFIG_BOARD_EARLY_INIT_F) #if CONFIG_IS_ENABLED(BOARD_EARLY_INIT_F)
board_early_init_f, INITCALL(board_early_init_f);
#endif #endif
#if defined(CONFIG_PPC) || defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K) #if defined(CONFIG_PPC) || defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
/* get CPU and bus clocks according to the environment variable */ /* 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 #endif
#if !defined(CONFIG_M68K) || (defined(CONFIG_M68K) && !defined(CONFIG_MCFTMR)) #if !defined(CONFIG_M68K) || (defined(CONFIG_M68K) && !defined(CONFIG_MCFTMR))
timer_init, /* initialize timer */ INITCALL(timer_init); /* initialize timer */
#endif #endif
#if defined(CONFIG_BOARD_POSTCLK_INIT) #if CONFIG_IS_ENABLED(BOARD_POSTCLK_INIT)
board_postclk_init, INITCALL(board_postclk_init);
#endif #endif
env_init, /* initialize environment */ INITCALL(env_init); /* initialize environment */
init_baud_rate, /* initialze baudrate settings */ INITCALL(init_baud_rate); /* initialze baudrate settings */
serial_init, /* serial communications setup */ INITCALL(serial_init); /* serial communications setup */
console_init_f, /* stage 1 init of console */ INITCALL(console_init_f); /* stage 1 init of console */
display_options, /* say that we are here */ INITCALL(display_options); /* say that we are here */
display_text_info, /* show debugging info if required */ INITCALL(display_text_info); /* show debugging info if required */
checkcpu, INITCALL(checkcpu);
#if defined(CONFIG_SYSRESET) #if CONFIG_IS_ENABLED(SYSRESET)
print_resetinfo, INITCALL(print_resetinfo);
#endif #endif
#if defined(CONFIG_DISPLAY_CPUINFO) /* display cpu info (and speed) */
print_cpuinfo, /* display cpu info (and speed) */ #if CONFIG_IS_ENABLED(DISPLAY_CPUINFO)
INITCALL(print_cpuinfo);
#endif #endif
#if defined(CONFIG_DTB_RESELECT) #if CONFIG_IS_ENABLED(DTB_RESELECT)
embedded_dtb_select, INITCALL(embedded_dtb_select);
#endif #endif
#if defined(CONFIG_DISPLAY_BOARDINFO) #if CONFIG_IS_ENABLED(DISPLAY_BOARDINFO)
show_board_info, INITCALL(show_board_info);
#endif #endif
INIT_FUNC_WATCHDOG_INIT WATCHDOG_INIT();
INITCALL_EVENT(EVT_MISC_INIT_F), INITCALL_EVT(EVT_MISC_INIT_F);
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if CONFIG_IS_ENABLED(SYS_I2C_LEGACY) #if CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
init_func_i2c, INITCALL(init_func_i2c);
#endif #endif
announce_dram_init, INITCALL(announce_dram_init);
dram_init, /* configure available RAM banks */ INITCALL(dram_init); /* configure available RAM banks */
#ifdef CONFIG_POST #if CONFIG_IS_ENABLED(POST)
post_init_f, INITCALL(post_init_f);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if defined(CFG_SYS_DRAM_TEST) #if defined(CFG_SYS_DRAM_TEST)
testdram, INITCALL(testdram);
#endif /* CFG_SYS_DRAM_TEST */ #endif /* CFG_SYS_DRAM_TEST */
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if CONFIG_IS_ENABLED(POST)
#ifdef CONFIG_POST INITCALL(init_post);
init_post,
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
/* /*
* Now that we have DRAM mapped and working, we can * Now that we have DRAM mapped and working, we can
* relocate the code and continue running from DRAM. * relocate the code and continue running from DRAM.
@ -968,48 +974,51 @@ static const init_fnc_t init_sequence_f[] = {
* - monitor code * - monitor code
* - board info struct * - board info struct
*/ */
setup_dest_addr, INITCALL(setup_dest_addr);
#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_OF_INITIAL_DTB_READONLY) #if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \
fix_fdt, !CONFIG_IS_ENABLED(OF_INITIAL_DTB_READONLY)
INITCALL(fix_fdt);
#endif #endif
#ifdef CFG_PRAM #ifdef CFG_PRAM
reserve_pram, INITCALL(reserve_pram);
#endif #endif
reserve_round_4k, INITCALL(reserve_round_4k);
setup_relocaddr_from_bloblist, INITCALL(setup_relocaddr_from_bloblist);
arch_reserve_mmu, INITCALL(arch_reserve_mmu);
reserve_video, INITCALL(reserve_video);
reserve_trace, INITCALL(reserve_trace);
reserve_uboot, INITCALL(reserve_uboot);
reserve_malloc, INITCALL(reserve_malloc);
reserve_board, INITCALL(reserve_board);
reserve_global_data, INITCALL(reserve_global_data);
reserve_fdt, INITCALL(reserve_fdt);
#if defined(CONFIG_OF_BOARD_FIXUP) && defined(CONFIG_OF_INITIAL_DTB_READONLY) #if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \
reloc_fdt, CONFIG_IS_ENABLED(OF_INITIAL_DTB_READONLY)
fix_fdt, INITCALL(reloc_fdt);
INITCALL(fix_fdt);
#endif #endif
reserve_bootstage, INITCALL(reserve_bootstage);
reserve_bloblist, INITCALL(reserve_bloblist);
reserve_arch, INITCALL(reserve_arch);
reserve_stacks, INITCALL(reserve_stacks);
dram_init_banksize, INITCALL(dram_init_banksize);
show_dram_config, INITCALL(show_dram_config);
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
setup_bdinfo, INITCALL(setup_bdinfo);
display_new_sp, INITCALL(display_new_sp);
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if !defined(CONFIG_OF_BOARD_FIXUP) || !defined(CONFIG_OF_INITIAL_DTB_READONLY) #if !CONFIG_IS_ENABLED(OF_BOARD_FIXUP) || \
reloc_fdt, !CONFIG_IS_ENABLED(INITIAL_DTB_READONLY)
INITCALL(reloc_fdt);
#endif #endif
reloc_bootstage, INITCALL(reloc_bootstage);
reloc_bloblist, INITCALL(reloc_bloblist);
setup_reloc, INITCALL(setup_reloc);
#if defined(CONFIG_X86) || defined(CONFIG_ARC) #if CONFIG_IS_ENABLED(X86) || CONFIG_IS_ENABLED(ARC)
copy_uboot_to_ram, INITCALL(copy_uboot_to_ram);
do_elf_reloc_fixups, INITCALL(do_elf_reloc_fixups);
#endif #endif
clear_bss, INITCALL(clear_bss);
/* /*
* Deregister all cyclic functions before relocation, so that * Deregister all cyclic functions before relocation, so that
* gd->cyclic_list does not contain any references to pre-relocation * gd->cyclic_list does not contain any references to pre-relocation
@ -1019,12 +1028,11 @@ static const init_fnc_t init_sequence_f[] = {
* This should happen as late as possible so that the window where a * This should happen as late as possible so that the window where a
* watchdog device is not serviced is as small as possible. * watchdog device is not serviced is as small as possible.
*/ */
cyclic_unregister_all, INITCALL(cyclic_unregister_all);
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) #if !CONFIG_IS_ENABLED(ARM) && !CONFIG_IS_ENABLED(SANDBOX)
jump_to_copy, INITCALL(jump_to_copy);
#endif #endif
NULL, }
};
void board_init_f(ulong boot_flags) void board_init_f(ulong boot_flags)
{ {
@ -1034,8 +1042,7 @@ void board_init_f(ulong boot_flags)
gd->flags &= ~GD_FLG_HAVE_CONSOLE; gd->flags &= ~GD_FLG_HAVE_CONSOLE;
gd->boardf = &boardf; gd->boardf = &boardf;
if (initcall_run_list(init_sequence_f)) initcall_run_f();
hang();
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
!defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \ !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \
@ -1049,8 +1056,8 @@ void board_init_f(ulong boot_flags)
/* /*
* For now this code is only used on x86. * For now this code is only used on x86.
* *
* init_sequence_f_r is the list of init functions which are run when * Run init functions which are run when U-Boot is executing from Flash with a
* U-Boot is executing from Flash with a semi-limited 'C' environment. * semi-limited 'C' environment.
* The following limitations must be considered when implementing an * The following limitations must be considered when implementing an
* '_f_r' function: * '_f_r' function:
* - 'static' variables are read-only * - 'static' variables are read-only
@ -1063,18 +1070,16 @@ void board_init_f(ulong boot_flags)
* NOTE: At present only x86 uses this route, but it is intended that * NOTE: At present only x86 uses this route, but it is intended that
* all archs will move to this when generic relocation is implemented. * all archs will move to this when generic relocation is implemented.
*/ */
static const init_fnc_t init_sequence_f_r[] = { static void initcall_run_f_r(void)
#if !CONFIG_IS_ENABLED(X86_64) {
init_cache_f_r, #if CONFIG_IS_ENABLED(X86_64)
INITCALL(init_cache_f_r);
#endif #endif
}
NULL,
};
void board_init_f_r(void) void board_init_f_r(void)
{ {
if (initcall_run_list(init_sequence_f_r)) initcall_run_f_r();
hang();
/* /*
* The pre-relocation drivers may be using memory that has now gone * The pre-relocation drivers may be using memory that has now gone

View file

@ -603,21 +603,24 @@ static int run_main_loop(void)
} }
/* /*
* Over time we hope to remove these functions with code fragments and * Over time we hope to remove most of the driver-related init and do it
* stub functions, and instead call the relevant function directly. * if/when the driver is later used.
*
* We also 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? * TODO: perhaps reset the watchdog in the initcall function after each call?
*/ */
static init_fnc_t init_sequence_r[] = {
initr_trace, static void initcall_run_r(void)
initr_reloc, {
event_init, /*
* 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? */ /* TODO: could x86/PPC have this also perhaps? */
#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) #if CONFIG_IS_ENABLED(ARM) || CONFIG_IS_ENABLED(RISCV)
initr_caches, INITCALL(initr_caches);
/* Note: For Freescale LS2 SoCs, new MMU table is created in DDR. /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
* A temporary mapping of IFC high region is since removed, * A temporary mapping of IFC high region is since removed,
* so environmental variables in NOR flash is not available * so environmental variables in NOR flash is not available
@ -625,29 +628,30 @@ static init_fnc_t init_sequence_r[] = {
* region. * region.
*/ */
#endif #endif
initr_reloc_global_data, INITCALL(initr_reloc_global_data);
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) #if CONFIG_IS_ENABLED(SYS_INIT_RAM_LOCK) && CONFIG_IS_ENABLED(E500)
initr_unlock_ram_in_cache, INITCALL(initr_unlock_ram_in_cache);
#endif #endif
initr_barrier, INITCALL(initr_barrier);
initr_malloc, INITCALL(initr_malloc);
log_init, INITCALL(log_init);
initr_bootstage, /* Needs malloc() but has its own timer */ INITCALL(initr_bootstage); /* Needs malloc() but has its own timer */
#if defined(CONFIG_CONSOLE_RECORD) #if CONFIG_IS_ENABLED(CONSOLE_RECORD)
console_record_init, INITCALL(console_record_init);
#endif #endif
#ifdef CONFIG_SYS_NONCACHED_MEMORY #if CONFIG_IS_ENABLED(SYS_NONCACHED_MEMORY)
noncached_init, INITCALL(noncached_init);
#endif #endif
initr_of_live, INITCALL(initr_of_live);
#ifdef CONFIG_DM #if CONFIG_IS_ENABLED(DM)
initr_dm, INITCALL(initr_dm);
#endif #endif
#ifdef CONFIG_ADDR_MAP #if CONFIG_IS_ENABLED(ADDR_MAP)
init_addr_map, INITCALL(init_addr_map);
#endif #endif
#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) || defined(CONFIG_SANDBOX) #if CONFIG_IS_ENABLED(ARM) || CONFIG_IS_ENABLED(RISCV) || \
board_init, /* Setup chipselects */ CONFIG_IS_ENABLED(SANDBOX)
INITCALL(board_init); /* Setup chipselects */
#endif #endif
/* /*
* TODO: printing of the clock inforamtion of the board is now * TODO: printing of the clock inforamtion of the board is now
@ -655,139 +659,141 @@ static init_fnc_t init_sequence_r[] = {
* davinci SOC's is added. Remove this check once all the board * davinci SOC's is added. Remove this check once all the board
* implement this. * implement this.
*/ */
#ifdef CONFIG_CLOCKS #if CONFIG_IS_ENABLED(CLOCKS)
set_cpu_clk_info, /* Setup clock information */ INITCALL(set_cpu_clk_info);
#endif #endif
initr_lmb, INITCALL(initr_lmb);
#ifdef CONFIG_EFI_LOADER #if CONFIG_IS_ENABLED(EFI_LOADER)
efi_memory_init, INITCALL(efi_memory_init);
#endif #endif
#ifdef CONFIG_BINMAN_FDT #if CONFIG_IS_ENABLED(BINMAN_FDT)
initr_binman, INITCALL(initr_binman);
#endif #endif
#ifdef CONFIG_FSP_VERSION2 #if CONFIG_IS_ENABLED(FSP_VERSION2)
arch_fsp_init_r, INITCALL(arch_fsp_init_r);
#endif #endif
initr_dm_devices, INITCALL(initr_dm_devices);
stdio_init_tables, INITCALL(stdio_init_tables);
serial_initialize, INITCALL(serial_initialize);
initr_announce, INITCALL(initr_announce);
dm_announce, INITCALL(dm_announce);
#if CONFIG_IS_ENABLED(WDT) #if CONFIG_IS_ENABLED(WDT)
initr_watchdog, INITCALL(initr_watchdog);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
arch_initr_trap, INITCALL(arch_initr_trap);
#if defined(CONFIG_BOARD_EARLY_INIT_R) #if CONFIG_IS_ENABLED(BOARD_EARLY_INIT_R)
board_early_init_r, INITCALL(board_early_init_r);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#ifdef CONFIG_POST #if CONFIG_IS_ENABLED(POST)
post_output_backlog, INITCALL(post_output_backlog);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT) #if CONFIG_IS_ENABLED(PCI_INIT_R) && CONFIG_IS_ENABLED(SYS_EARLY_PCI_INIT)
/* /*
* Do early PCI configuration _before_ the flash gets initialised, * Do early PCI configuration _before_ the flash gets initialised,
* because PCU resources are crucial for flash access on some boards. * because PCU resources are crucial for flash access on some boards.
*/ */
pci_init, INITCALL(pci_init);
#endif #endif
#ifdef CONFIG_ARCH_EARLY_INIT_R #if CONFIG_IS_ENABLED(ARCH_EARLY_INIT_R)
arch_early_init_r, INITCALL(arch_early_init_r);
#endif #endif
power_init_board, INITCALL(power_init_board);
#ifdef CONFIG_MTD_NOR_FLASH #if CONFIG_IS_ENABLED(MTD_NOR_FLASH)
initr_flash, INITCALL(initr_flash);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) #if CONFIG_IS_ENABLED(PPC) || CONFIG_IS_ENABLED(M68K) || CONFIG_IS_ENABLED(X86)
/* initialize higher level parts of CPU like time base and timers */ /* initialize higher level parts of CPU like time base and timers */
cpu_init_r, INITCALL(cpu_init_r);
#endif #endif
#ifdef CONFIG_EFI_LOADER #if CONFIG_IS_ENABLED(EFI_LOADER)
efi_init_early, INITCALL(efi_init_early);
#endif #endif
#ifdef CONFIG_CMD_NAND #if CONFIG_IS_ENABLED(CMD_NAND)
initr_nand, INITCALL(initr_nand);
#endif #endif
#ifdef CONFIG_CMD_ONENAND #if CONFIG_IS_ENABLED(CMD_ONENAND)
initr_onenand, INITCALL(initr_onenand);
#endif #endif
#ifdef CONFIG_MMC #if CONFIG_IS_ENABLED(MMC)
initr_mmc, INITCALL(initr_mmc);
#endif #endif
#ifdef CONFIG_XEN #if CONFIG_IS_ENABLED(XEN)
xen_init, INITCALL(xen_init);
#endif #endif
#ifdef CONFIG_PVBLOCK #if CONFIG_IS_ENABLED(PVBLOCK)
initr_pvblock, INITCALL(initr_pvblock);
#endif #endif
initr_env, INITCALL(initr_env);
#ifdef CONFIG_SYS_MALLOC_BOOTPARAMS #if CONFIG_IS_ENABLED(SYS_MALLOC_BOOTPARAMS)
initr_malloc_bootparams, INITCALL(initr_malloc_bootparams);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
cpu_secondary_init_r, INITCALL(cpu_secondary_init_r);
#if defined(CONFIG_ID_EEPROM) #if CONFIG_IS_ENABLED(ID_EEPROM)
mac_read_from_eeprom, INITCALL(mac_read_from_eeprom);
#endif #endif
INITCALL_EVENT(EVT_SETTINGS_R), INITCALL_EVT(EVT_SETTINGS_R);
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#if defined(CONFIG_PCI_INIT_R) && !defined(CONFIG_SYS_EARLY_PCI_INIT) #if CONFIG_IS_ENABLED(PCI_INIT_R) && !CONFIG_IS_ENABLED(SYS_EARLY_PCI_INIT)
/* /*
* Do pci configuration * Do pci configuration
*/ */
pci_init, INITCALL(pci_init);
#endif #endif
stdio_add_devices, INITCALL(stdio_add_devices);
jumptable_init, INITCALL(jumptable_init);
#ifdef CONFIG_API #if CONFIG_IS_ENABLED(API)
api_init, INITCALL(api_init);
#endif #endif
console_init_r, /* fully init console as a device */ INITCALL(console_init_r); /* fully init console as a device */
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE #if CONFIG_IS_ENABLED(DISPLAY_BOARDINFO_LATE)
console_announce_r, INITCALL(console_announce_r);
show_board_info, INITCALL(show_board_info);
#endif #endif
#ifdef CONFIG_ARCH_MISC_INIT /* miscellaneous arch-dependent init */
arch_misc_init, /* miscellaneous arch-dependent init */ #if CONFIG_IS_ENABLED(ARCH_MISC_INIT)
INITCALL(arch_misc_init);
#endif #endif
#ifdef CONFIG_MISC_INIT_R /* miscellaneous platform-dependent init */
misc_init_r, /* miscellaneous platform-dependent init */ #if CONFIG_IS_ENABLED(MISC_INIT_R)
INITCALL(misc_init_r);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
#ifdef CONFIG_CMD_KGDB #if CONFIG_IS_ENABLED(CMD_KGDB)
kgdb_init, INITCALL(kgdb_init);
#endif #endif
interrupt_init, INITCALL(interrupt_init);
#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K) #if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K)
timer_init, /* initialize timer */ INITCALL(timer_init); /* initialize timer */
#endif #endif
initr_status_led, INITCALL(initr_status_led);
initr_boot_led_blink, INITCALL(initr_boot_led_blink);
/* PPC has a udelay(20) here dating from 2002. Why? */ /* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_BOARD_LATE_INIT #if CONFIG_IS_ENABLED(BOARD_LATE_INIT)
board_late_init, INITCALL(board_late_init);
#endif #endif
#ifdef CONFIG_PCI_ENDPOINT #if CONFIG_IS_ENABLED(PCI_ENDPOINT)
pci_ep_init, INITCALL(pci_ep_init);
#endif #endif
#if defined(CONFIG_CMD_NET) #if CONFIG_IS_ENABLED(CMD_NET)
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
initr_net, INITCALL(initr_net);
#endif #endif
#ifdef CONFIG_POST #if CONFIG_IS_ENABLED(POST)
initr_post, INITCALL(initr_post);
#endif #endif
INIT_FUNC_WATCHDOG_RESET WATCHDOG_RESET();
INITCALL_EVENT(EVT_LAST_STAGE_INIT), INITCALL_EVT(EVT_LAST_STAGE_INIT);
#if defined(CFG_PRAM) #if defined(CFG_PRAM)
initr_mem, INITCALL(initr_mem);
#endif #endif
initr_boot_led_on, INITCALL(initr_boot_led_on);
run_main_loop, INITCALL(run_main_loop);
}; }
void board_init_r(gd_t *new_gd, ulong dest_addr) void board_init_r(gd_t *new_gd, ulong dest_addr)
{ {
@ -814,8 +820,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
#endif #endif
gd->flags &= ~GD_FLG_LOG_READY; gd->flags &= ~GD_FLG_LOG_READY;
if (initcall_run_list(init_sequence_r)) initcall_run_r();
hang();
/* NOTREACHED - run_main_loop() does not return */ /* NOTREACHED - run_main_loop() does not return */
hang(); hang();

View file

@ -8,31 +8,34 @@
#include <asm/types.h> #include <asm/types.h>
#include <event.h> #include <event.h>
#include <hang.h>
_Static_assert(EVT_COUNT < 256, "Can only support 256 event types with 8 bits"); _Static_assert(EVT_COUNT < 256, "Can only support 256 event types with 8 bits");
/** #define INITCALL(_call) \
* init_fnc_t - Init function do { \
* if (_call()) { \
* Return: 0 if OK -ve on error printf("%s(): initcall %s() failed\n", __func__, \
*/ #_call); \
typedef int (*init_fnc_t)(void); hang(); \
} \
} while (0)
/* Top bit indicates that the initcall is an event */ #define INITCALL_EVT(_evt) \
#define INITCALL_IS_EVENT GENMASK(BITS_PER_LONG - 1, 8) do { \
#define INITCALL_EVENT_TYPE GENMASK(7, 0) if (event_notify_null(_evt)) { \
printf("%s(): event %d/%s failed\n", __func__, _evt, \
event_type_name(_evt)) ; \
hang(); \
} \
} while (0)
#define INITCALL_EVENT(_type) (void *)((_type) | INITCALL_IS_EVENT) #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
#define WATCHDOG_INIT() INITCALL(init_func_watchdog_init)
/** #define WATCHDOG_RESET() INITCALL(init_func_watchdog_reset)
* initcall_run_list() - Run through a list of function calls #else
* #define WATCHDOG_INIT()
* This calls functions one after the other, stopping at the first error, or #define WATCHDOG_RESET()
* when NULL is obtained. #endif
*
* @init_sequence: NULL-terminated init sequence to run
* Return: 0 if OK, or -ve error code from the first failure
*/
int initcall_run_list(const init_fnc_t init_sequence[]);
#endif #endif

View file

@ -43,7 +43,6 @@ endif
obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o
obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
obj-y += initcall.o
obj-y += ldiv.o obj-y += ldiv.o
obj-$(CONFIG_XXHASH) += xxhash.o obj-$(CONFIG_XXHASH) += xxhash.o
obj-y += net_utils.o obj-y += net_utils.o

View file

@ -1,102 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013 The Chromium OS Authors.
*/
#include <efi.h>
#include <initcall.h>
#include <log.h>
#include <relocate.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
static ulong calc_reloc_ofs(void)
{
#ifdef CONFIG_EFI_APP
return (ulong)image_base;
#endif
/*
* Sandbox is relocated by the OS, so symbols always appear at
* the relocated address.
*/
if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC))
return gd->reloc_off;
return 0;
}
/**
* initcall_is_event() - Get the event number for an initcall
*
* func: Function pointer to check
* Return: Event number, if this is an event, else 0
*/
static int initcall_is_event(init_fnc_t func)
{
ulong val = (ulong)func;
if ((val & INITCALL_IS_EVENT) == INITCALL_IS_EVENT)
return val & INITCALL_EVENT_TYPE;
return 0;
}
/*
* To enable debugging. add #define DEBUG at the top of the including file.
*
* To find a symbol, use grep on u-boot.map
*/
int initcall_run_list(const init_fnc_t init_sequence[])
{
ulong reloc_ofs;
const init_fnc_t *ptr;
enum event_t type;
init_fnc_t func;
int ret = 0;
for (ptr = init_sequence; func = *ptr, func; ptr++) {
reloc_ofs = calc_reloc_ofs();
type = initcall_is_event(func);
if (type) {
if (!CONFIG_IS_ENABLED(EVENT))
continue;
debug("initcall: event %d/%s\n", type,
event_type_name(type));
} else if (reloc_ofs) {
debug("initcall: %p (relocated to %p)\n",
(char *)func - reloc_ofs, (char *)func);
} else {
debug("initcall: %p\n", (char *)func - reloc_ofs);
}
ret = type ? event_notify_null(type) : func();
if (ret)
break;
}
if (ret) {
if (CONFIG_IS_ENABLED(EVENT)) {
char buf[60];
/* don't worry about buf size as we are dying here */
if (type) {
sprintf(buf, "event %d/%s", type,
event_type_name(type));
} else {
sprintf(buf, "call %p",
(char *)func - reloc_ofs);
}
printf("initcall failed at %s (err=%dE)\n", buf, ret);
} else {
printf("initcall failed at call %p (err=%d)\n",
(char *)func - reloc_ofs, ret);
}
return ret;
}
return 0;
}

View file

@ -201,7 +201,7 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
# Then look for this: # Then look for this:
# u-boot-1 0..... 282.101375: funcgraph_exit: 0.006 us | } # u-boot-1 0..... 282.101375: funcgraph_exit: 0.006 us | }
# Then check for this: # Then check for this:
# u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | calc_reloc_ofs(); # u-boot-1 0..... 282.101375: funcgraph_entry: 0.000 us | event_init();
expected_indent = None expected_indent = None
found_start = False found_start = False
@ -224,8 +224,8 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
found_end = True found_end = True
# The next function after initf_bootstage() exits should be # The next function after initf_bootstage() exits should be
# initcall_is_event() # event_init()
assert upto == 'calc_reloc_ofs()' assert upto == 'event_init()'
# Now look for initf_dm() and dm_timer_init() so we can check the bootstage # Now look for initf_dm() and dm_timer_init() so we can check the bootstage
# time # time
@ -274,7 +274,7 @@ def check_flamegraph(ubman, fname, proftool, map_fname, trace_fg):
# We expect dm_timer_init() to be called twice: once before relocation and # We expect dm_timer_init() to be called twice: once before relocation and
# once after # once after
look1 = 'initf_dm;dm_timer_init 1' look1 = 'initf_dm;dm_timer_init 1'
look2 = 'board_init_r;initcall_run_list;initr_dm_devices;dm_timer_init 1' look2 = 'board_init_r;initcall_run_r;initr_dm_devices;dm_timer_init 1'
found = 0 found = 0
with open(trace_fg, 'r') as fd: with open(trace_fg, 'r') as fd:
for line in fd: for line in fd: