diff options
| author | Tom Rini <trini@konsulko.com> | 2023-08-31 15:10:42 -0400 |
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2023-08-31 15:10:42 -0400 |
| commit | b8b512a45358d50bce2e17b5941c5e39b52a0594 (patch) | |
| tree | f70b4d2452f8ca45025916cd85f0d1af684902bb /include | |
| parent | b81a024e4a37097d3dcffccb225850f8f6dc8277 (diff) | |
| parent | 91caa3bb89b112a1421ee2ee3661baf67c64bab9 (diff) | |
Merge branch '2023-08-31-replace-more-init-hooks-with-events' into next
To quote the author:
This series replaces some more of the init hooks in board_f.c and
board_r.c with events. Notably it converts last_state_init() over.
It also provides a 'simple' event spy, which takes no arguments. It
turns out that this is quite a common case, so it is worth optimising
for this, to reduce code size, before events become too commonly used.
Finally, it introduces a way of emitting an event in an initcall,
instead of calling a function. This is likely to be used at least as
often as the functions, as we convert more of these initcalls.
As part of this, the initcall code is brought back into a C file. Somehow
the compiler has changed or something else, so that this does not confer
any benefits now.
For boards with EVENT enabled, this unfortunately results in small
growth, e.g. for firefly:
aarch64: (for 1/1 boards) all +114.0 data +16.0 rodata +22.0 text +76.0
arm: (for 1/1 boards) all +82.0 rodata +18.0 text +64.0
For boards without EVENT enabled the growth is smaller, e.g. nokia_rx51:
arm: (for 1/1 boards) all +32.0 data +8.0 rodata -8.0 text +32.0
I cannot find a good way to avoid the latter, other than macro magic
with an embedded comma (to completely remove an event entry), which
seems nasty.
Diffstat (limited to 'include')
| -rw-r--r-- | include/event.h | 72 | ||||
| -rw-r--r-- | include/init.h | 15 | ||||
| -rw-r--r-- | include/initcall.h | 72 |
3 files changed, 99 insertions, 60 deletions
diff --git a/include/event.h b/include/event.h index daf44bf8a83..747a9f6c654 100644 --- a/include/event.h +++ b/include/event.h @@ -32,6 +32,27 @@ enum event_t { /* Init hooks */ EVT_MISC_INIT_F, + /* + * Emitted before relocation to set up Firmware Support Package + * + * Where U-Boot relies on binary blobs to handle part of the system + * init, this event can be used to set up the blobs. This is used on + * some Intel platforms + */ + EVT_FSP_INIT_F, + + /* + * Emitted just before jumping to the main loop + * + * Some boards need to perform initialisation immediately before control + * is passed to the command-line interpreter (e.g. for init that depend + * on later phases in the init sequence). + * + * Some parts can be only initialized if all others (like Interrupts) + * are up and running (e.g. the PC-style ISA keyboard). + */ + EVT_LAST_STAGE_INIT, + /* Fpga load hook */ EVT_FPGA_LOAD, @@ -99,19 +120,48 @@ struct event { union event_data data; }; +/* Flags for event spy */ +enum evspy_flags { + EVSPYF_SIMPLE = 1 << 0, +}; + /** Function type for event handlers */ typedef int (*event_handler_t)(void *ctx, struct event *event); +/** Function type for simple event handlers */ +typedef int (*event_handler_simple_t)(void); + /** * struct evspy_info - information about an event spy * * @func: Function to call when the event is activated (must be first) * @type: Event type + * @flag: Flags for this spy * @id: Event id string */ struct evspy_info { event_handler_t func; - enum event_t type; + u8 type; + u8 flags; +#if CONFIG_IS_ENABLED(EVENT_DEBUG) + const char *id; +#endif +}; + +/** + * struct evspy_info_simple - information about an event spy + * + * THis is the 'simple' record, the only difference being the handler function + * + * @func: Function to call when the event is activated (must be first) + * @type: Event type + * @flag: Flags for this spy + * @id: Event id string + */ +struct evspy_info_simple { + event_handler_simple_t func; + u8 type; + u8 flags; #if CONFIG_IS_ENABLED(EVENT_DEBUG) const char *id; #endif @@ -119,9 +169,11 @@ struct evspy_info { /* Declare a new event spy */ #if CONFIG_IS_ENABLED(EVENT_DEBUG) -#define _ESPY_REC(_type, _func) { _func, _type, #_func, } +#define _ESPY_REC(_type, _func) { _func, _type, 0, #_func, } +#define _ESPY_REC_SIMPLE(_type, _func) { _func, _type, EVSPYF_SIMPLE, #_func, } #else #define _ESPY_REC(_type, _func) { _func, _type, } +#define _ESPY_REC_SIMPLE(_type, _func) { _func, _type, EVSPYF_SIMPLE } #endif static inline const char *event_spy_id(struct evspy_info *spy) @@ -164,10 +216,16 @@ static inline const char *event_spy_id(struct evspy_info *spy) * away the linker-list entry sometimes, e.g. with the EVT_FT_FIXUP entry in * vbe_simple.c - so for now, make it global. */ -#define EVENT_SPY(_type, _func) \ +#define EVENT_SPY_FULL(_type, _func) \ __used ll_entry_declare(struct evspy_info, _type ## _3_ ## _func, \ evspy_info) = _ESPY_REC(_type, _func) +/* Simple spy with no function arguemnts */ +#define EVENT_SPY_SIMPLE(_type, _func) \ + __used ll_entry_declare(struct evspy_info_simple, \ + _type ## _3_ ## _func, \ + evspy_info) = _ESPY_REC_SIMPLE(_type, _func) + /** * event_register - register a new spy * @@ -194,6 +252,14 @@ void event_show_spy_list(void); int event_manual_reloc(void); /** + * event_type_name() - Get the name of an event type + * + * @type: Type to check + * Return: Name of event, or "(unknown)" if not known + */ +const char *event_type_name(enum event_t type); + +/** * event_notify() - notify spies about an event * * It is possible to pass in union event_data here but that may not be diff --git a/include/init.h b/include/init.h index 3bf30476a2e..4e7fe26c200 100644 --- a/include/init.h +++ b/include/init.h @@ -58,17 +58,6 @@ int arch_cpu_init(void); int mach_cpu_init(void); /** - * arch_fsp_init() - perform firmware support package init - * - * Where U-Boot relies on binary blobs to handle part of the system init, this - * function can be used to set up the blobs. This is used on some Intel - * platforms. - * - * Return: 0 - */ -int arch_fsp_init(void); - -/** * arch_fsp_init() - perform post-relocation firmware support package init * * Where U-Boot relies on binary blobs to handle part of the system init, this @@ -281,15 +270,11 @@ void board_init_r(struct global_data *id, ulong dest_addr) __attribute__ ((noreturn)); int cpu_init_r(void); -int last_stage_init(void); int mac_read_from_eeprom(void); int set_cpu_clk_info(void); int update_flash_size(int flash_size); int arch_early_init_r(void); int misc_init_r(void); -#if defined(CONFIG_VID) -int init_func_vid(void); -#endif /* common/board_info.c */ int checkboard(void); diff --git a/include/initcall.h b/include/initcall.h index 69ce2680705..208effd8d13 100644 --- a/include/initcall.h +++ b/include/initcall.h @@ -6,52 +6,40 @@ #ifndef __INITCALL_H #define __INITCALL_H +#include <asm/types.h> +#include <event.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); -#include <log.h> -#ifdef CONFIG_EFI_APP -#include <efi.h> -#endif -#include <asm/global_data.h> +/* 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) -/* - * To enable debugging. add #define DEBUG at the top of the including file. +#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. * - * To find a symbol, use grep on u-boot.map + * @init_sequence: NULL-terminated init sequence to run + * Return: 0 if OK, or -ve error code from the first failure */ -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; - - /* - * Sandbox is relocated by the OS, so symbols always appear at - * the relocated address. - */ - if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC)) - reloc_ofs = gd->reloc_off; -#ifdef CONFIG_EFI_APP - reloc_ofs = (unsigned long)image_base; -#endif - if (reloc_ofs) - debug("initcall: %p (relocated to %p)\n", - (char *)*init_fnc_ptr - reloc_ofs, - (char *)*init_fnc_ptr); - else - debug("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs); - - 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; -} +int initcall_run_list(const init_fnc_t init_sequence[]); + +/** + * initcall_manual_reloc() - Do manual relocation on an initcall sequence + * + * @init_sequence: NULL-terminated init sequence to relocate + */ +void initcall_manual_reloc(init_fnc_t init_sequence[]); #endif |
