boot state: schedule static callbacks

Many of the boot state callbacks can be scheduled at compile time.
Therefore, provide a way for a compilation unit to inform the
boot state machine when its callbacks should be called. Each C
module can export the callbacks and their scheduling requirements
without changing the shared boot flow code.

Change-Id: Ibc4cea4bd5ad45b2149c2d4aa91cbea652ed93ed
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/3133
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Aaron Durbin 2013-04-24 16:12:52 -05:00 committed by Ronald G. Minnich
parent 7e35efa83c
commit a4feddf897
5 changed files with 51 additions and 0 deletions

View File

@ -61,6 +61,9 @@ SECTIONS
cpu_drivers = . ;
*(.rodata.cpu_driver)
ecpu_drivers = . ;
_bs_init_begin = .;
*(.bs_init)
_bs_init_end = .;
*(.rodata)
*(.rodata.*)
/* kevinh/Ispiri - Added an align, because the objcopy tool

View File

@ -64,6 +64,9 @@ SECTIONS
cpu_drivers = . ;
*(.rodata.cpu_driver)
ecpu_drivers = . ;
_bs_init_begin = .;
*(.bs_init)
_bs_init_end = .;
*(.rodata)
*(.rodata.*)

View File

@ -158,4 +158,25 @@ int boot_state_sched_on_exit(struct boot_state_callback *bscb,
/* Entry into the boot state machine. */
void hardwaremain(int boot_complete);
/* In order to schedule boot state callbacks at compile-time specify the
* entries in an array using the BOOT_STATE_INIT_ENTRIES and
* BOOT_STATE_INIT_ENTRY macros below. */
struct boot_state_init_entry {
boot_state_t state;
boot_state_sequence_t when;
struct boot_state_callback bscb;
};
#define BOOT_STATE_INIT_ATTR __attribute__ ((used,section (".bs_init")))
#define BOOT_STATE_INIT_ENTRIES(name_) \
static struct boot_state_init_entry name_[] BOOT_STATE_INIT_ATTR
#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \
{ \
.state = state_, \
.when = when_, \
.bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \
}
#endif /* BOOTSTATE_H */

View File

@ -293,6 +293,23 @@ int boot_state_sched_on_exit(struct boot_state_callback *bscb,
return boot_state_sched_callback(state, bscb, BS_ON_EXIT);
}
static void boot_state_schedule_static_entries(void)
{
extern struct boot_state_init_entry _bs_init_begin;
extern struct boot_state_init_entry _bs_init_end;
struct boot_state_init_entry *cur;
cur = &_bs_init_begin;
while (cur != &_bs_init_end) {
if (cur->when == BS_ON_ENTRY)
boot_state_sched_on_entry(&cur->bscb, cur->state);
else
boot_state_sched_on_exit(&cur->bscb, cur->state);
cur++;
}
}
void hardwaremain(int boot_complete)
{
timestamp_stash(TS_START_RAMSTAGE);
@ -318,6 +335,9 @@ void hardwaremain(int boot_complete)
hard_reset();
}
/* Schedule the static boot state entries. */
boot_state_schedule_static_entries();
/* FIXME: Is there a better way to handle this? */
init_timer();

View File

@ -61,6 +61,10 @@ SECTIONS
cpu_drivers = . ;
*(.rodata.cpu_driver)
ecpu_drivers = . ;
_bs_init_begin = .;
*(.bs_init)
_bs_init_end = .;
. = ALIGN(4);
*(.rodata);