blob: e7ed26faaeafa4031f704d60e539b5534515c364 [file] [log] [blame]
#include <linux/bug.h>
#include <linux/kernel.h>
#include <asm/x86_init_fn.h>
#include <asm/bootparam.h>
#include <asm/boot.h>
#include <asm/setup.h>
DEFINE_LINKTABLE_INIT_DATA(struct x86_init_fn, x86_init_fns);
static bool x86_init_fn_supports_subarch(struct x86_init_fn *fn)
{
if (!fn->supp_hardware_subarch) {
pr_info("Init sequence fails to declares supported subarchs: %s\n", fn->name);
WARN_ON(1);
}
if (BIT(boot_params.hdr.hardware_subarch) & fn->supp_hardware_subarch)
return true;
return false;
}
void x86_init_fn_early_init(void)
{
int ret;
struct x86_init_fn *init_fn;
unsigned int num_inits = LINUX_SECTION_SIZE(x86_init_fns);
pr_info("Number of init entries: %d\n", num_inits);
LINKTABLE_FOR_EACH(init_fn, x86_init_fns) {
if (!x86_init_fn_supports_subarch(init_fn))
continue;
if (!init_fn->detect)
init_fn->flags |= INIT_DETECTED;
else {
ret = init_fn->detect();
if (ret > 0)
init_fn->flags |= INIT_DETECTED;
}
if (init_fn->flags & INIT_DETECTED) {
init_fn->flags |= INIT_DETECTED;
pr_info("Initializing %s ...\n", init_fn->name);
init_fn->early_init();
pr_info("Completed initializing %s !\n", init_fn->name);
if (init_fn->flags & INIT_FINISH_IF_DETECTED)
break;
}
}
}
void x86_init_fn_late_init(void)
{
struct x86_init_fn *init_fn;
LINKTABLE_FOR_EACH(init_fn, x86_init_fns) {
if ((init_fn->flags & INIT_DETECTED) && init_fn->late_init) {
pr_info("Running late init for %s ...\n", init_fn->name);
init_fn->late_init();
pr_info("Completed late initializing of %s !\n", init_fn->name);
}
}
}
void x86_init_fn_setup_arch(void)
{
struct x86_init_fn *init_fn;
LINKTABLE_FOR_EACH(init_fn, x86_init_fns) {
if ((init_fn->flags & INIT_DETECTED) && init_fn->setup_arch) {
pr_info("Running setup_arch for %s ...\n", init_fn->name);
init_fn->setup_arch();
}
}
}