mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
initcall: Move to inline function
The board_r init function was complaining that we are looping through an array, calling all our tiny init stubs sequentially via indirect function calls (which can't be speculated, so they are slow). The solution to that is pretty easy though. All we need to do is inline the function that loops through the functions and the compiler will automatically convert almost all indirect calls into direct inlined code. With this patch, the overall code size drops (by 40 bytes on riscv64) and boot time should become measurably faster for every target. Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
a9484aa769
commit
47870afab9
4 changed files with 35 additions and 45 deletions
|
@ -633,10 +633,7 @@ 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
|
||||
* 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?
|
||||
|
|
|
@ -8,6 +8,39 @@
|
|||
|
||||
typedef int (*init_fnc_t)(void);
|
||||
|
||||
int initcall_run_list(const init_fnc_t init_sequence[]);
|
||||
#include <common.h>
|
||||
#include <initcall.h>
|
||||
#include <efi.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static inline int initcall_run_list(const init_fnc_t init_sequence[])
|
||||
{
|
||||
const init_fnc_t *init_fnc_ptr;
|
||||
|
||||
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
|
||||
unsigned long reloc_ofs = 0;
|
||||
int ret;
|
||||
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
reloc_ofs = gd->reloc_off;
|
||||
#ifdef CONFIG_EFI_APP
|
||||
reloc_ofs = (unsigned long)image_base;
|
||||
#endif
|
||||
debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
|
||||
else
|
||||
debug("\n");
|
||||
ret = (*init_fnc_ptr)();
|
||||
if (ret) {
|
||||
printf("initcall sequence %p failed at call %p (err=%d)\n",
|
||||
init_sequence,
|
||||
(char *)*init_fnc_ptr - reloc_ofs, ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,6 @@ obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
|
|||
obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
|
||||
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
|
||||
obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
|
||||
obj-y += initcall.o
|
||||
obj-y += ldiv.o
|
||||
obj-$(CONFIG_MD5) += md5.o
|
||||
obj-y += net_utils.o
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2013 The Chromium OS Authors.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <initcall.h>
|
||||
#include <efi.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int initcall_run_list(const init_fnc_t init_sequence[])
|
||||
{
|
||||
const init_fnc_t *init_fnc_ptr;
|
||||
|
||||
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
|
||||
unsigned long reloc_ofs = 0;
|
||||
int ret;
|
||||
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
reloc_ofs = gd->reloc_off;
|
||||
#ifdef CONFIG_EFI_APP
|
||||
reloc_ofs = (unsigned long)image_base;
|
||||
#endif
|
||||
debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
|
||||
else
|
||||
debug("\n");
|
||||
ret = (*init_fnc_ptr)();
|
||||
if (ret) {
|
||||
printf("initcall sequence %p failed at call %p (err=%d)\n",
|
||||
init_sequence,
|
||||
(char *)*init_fnc_ptr - reloc_ofs, ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue