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()
#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)
{
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;
}
@ -461,11 +471,13 @@ static inline unsigned int get_cr(void)
unsigned int val;
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");
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");
return val;
@ -474,11 +486,11 @@ static inline unsigned int get_cr(void)
static inline void set_cr(unsigned int val)
{
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)
: "cc");
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)
: "cc");
isb();

View file

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

View file

@ -85,8 +85,9 @@ struct mbus_win {
static inline unsigned int readfr_extra_feature_reg(void)
{
unsigned int val;
asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
(val)::"cc");
asm_arm_or_thumb2("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r"
(val)::"cc");
return val;
}
@ -96,8 +97,8 @@ static inline unsigned int readfr_extra_feature_reg(void)
*/
static inline void writefr_extra_feature_reg(unsigned int val)
{
asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
(val):"cc");
asm_arm_or_thumb2("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r"
(val):"cc");
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 (*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,
(void *)(new_gd->relocaddr - new_gd->reloc_off),
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));
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 <status_led.h>
#include <sysreset.h>
#include <time.h>
#include <timer.h>
#include <trace.h>
#include <upl.h>
@ -753,7 +754,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);
@ -881,81 +882,86 @@ static int initf_upl(void)
return 0;
}
static const init_fnc_t init_sequence_f[] = {
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
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,
initf_upl,
log_init,
initf_bootstage, /* uses its own timer, so does not need DM */
event_init,
bloblist_maybe_init,
setup_spl_handoff,
#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
console_record_init,
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.
@ -968,48 +974,51 @@ static const init_fnc_t init_sequence_f[] = {
* - monitor code
* - board info struct
*/
setup_dest_addr,
#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_OF_INITIAL_DTB_READONLY)
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,
#if defined(CONFIG_OF_BOARD_FIXUP) && defined(CONFIG_OF_INITIAL_DTB_READONLY)
reloc_fdt,
fix_fdt,
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
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
#if !defined(CONFIG_OF_BOARD_FIXUP) || !defined(CONFIG_OF_INITIAL_DTB_READONLY)
reloc_fdt,
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
reloc_bootstage,
reloc_bloblist,
setup_reloc,
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
copy_uboot_to_ram,
do_elf_reloc_fixups,
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
clear_bss,
INITCALL(clear_bss);
/*
* Deregister all cyclic functions before relocation, so that
* 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
* 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)
{
@ -1034,8 +1042,7 @@ void board_init_f(ulong boot_flags)
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) && \
@ -1049,8 +1056,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
@ -1063,18 +1070,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

View file

@ -603,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
@ -625,29 +628,30 @@ 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_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(ARM) || CONFIG_IS_ENABLED(RISCV) || \
CONFIG_IS_ENABLED(SANDBOX)
INITCALL(board_init); /* Setup chipselects */
#endif
/*
* 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
* implement this.
*/
#ifdef CONFIG_CLOCKS
set_cpu_clk_info, /* Setup clock information */
#if CONFIG_IS_ENABLED(CLOCKS)
INITCALL(set_cpu_clk_info);
#endif
initr_lmb,
#ifdef CONFIG_EFI_LOADER
efi_memory_init,
INITCALL(initr_lmb);
#if CONFIG_IS_ENABLED(EFI_LOADER)
INITCALL(efi_memory_init);
#endif
#ifdef CONFIG_BINMAN_FDT
initr_binman,
#if CONFIG_IS_ENABLED(BINMAN_FDT)
INITCALL(initr_binman);
#endif
#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 */
INITCALL(timer_init); /* initialize timer */
#endif
initr_status_led,
initr_boot_led_blink,
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_PCI_ENDPOINT
pci_ep_init,
#if CONFIG_IS_ENABLED(PCI_ENDPOINT)
INITCALL(pci_ep_init);
#endif
#if defined(CONFIG_CMD_NET)
INIT_FUNC_WATCHDOG_RESET
initr_net,
#if CONFIG_IS_ENABLED(CMD_NET)
WATCHDOG_RESET();
INITCALL(initr_net);
#endif
#ifdef CONFIG_POST
initr_post,
#if CONFIG_IS_ENABLED(POST)
INITCALL(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
initr_boot_led_on,
run_main_loop,
};
INITCALL(initr_boot_led_on);
INITCALL(run_main_loop);
}
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
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();

View file

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

View file

@ -43,7 +43,6 @@ endif
obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o
obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
obj-y += initcall.o
obj-y += ldiv.o
obj-$(CONFIG_XXHASH) += xxhash.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:
# u-boot-1 0..... 282.101375: funcgraph_exit: 0.006 us | }
# 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
found_start = False
@ -224,8 +224,8 @@ def check_funcgraph(ubman, fname, proftool, map_fname, trace_dat):
found_end = True
# The next function after initf_bootstage() exits should be
# initcall_is_event()
assert upto == 'calc_reloc_ofs()'
# event_init()
assert upto == 'event_init()'
# Now look for initf_dm() and dm_timer_init() so we can check the bootstage
# 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
# once after
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
with open(trace_fg, 'r') as fd:
for line in fd: