blob: 5c202baa4370681bda01483c37bd352b15fb5482 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h>
#include <arch/exception.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <delay.h>
#include <metadata_hash.h>
#include <option.h>
#include <post.h>
#include <program_loading.h>
#include <security/tpm/tspi.h>
#include <symbols.h>
#include <timestamp.h>
__weak void bootblock_mainboard_early_init(void) { /* no-op */ }
__weak void bootblock_soc_early_init(void) { /* do nothing */ }
__weak void bootblock_soc_init(void) { /* do nothing */ }
__weak void bootblock_mainboard_init(void) { /* do nothing */ }
/*
* This is a the same as the bootblock main(), with the difference that it does
* not collect a timestamp. Instead it accepts the initial timestamp and
* possibly additional timestamp entries as arguments. This can be used in cases
* where earlier stamps are available. Note that this function is designed to be
* entered from C code. This function assumes that the timer has already been
* initialized, so it does not call init_timer().
*/
void bootblock_main_with_timestamp(uint64_t base_timestamp,
struct timestamp_entry *timestamps, size_t num_timestamps)
{
/* Initialize timestamps if we have TIMESTAMP region in memlayout.ld. */
if (CONFIG(COLLECT_TIMESTAMPS) &&
REGION_SIZE(timestamp) > 0) {
int i;
timestamp_init(base_timestamp);
for (i = 0; i < num_timestamps; i++)
timestamp_add(timestamps[i].entry_id,
timestamps[i].entry_stamp);
}
timestamp_add_now(TS_BOOTBLOCK_START);
bootblock_soc_early_init();
bootblock_mainboard_early_init();
if (CONFIG(USE_OPTION_TABLE))
sanitize_cmos();
if (CONFIG(CMOS_POST))
cmos_post_init();
if (CONFIG(BOOTBLOCK_CONSOLE)) {
console_init();
exception_init();
}
bootblock_soc_init();
bootblock_mainboard_init();
if (CONFIG(TPM_MEASURED_BOOT_INIT_BOOTBLOCK)) {
int s3resume = acpi_is_wakeup_s3();
tpm_setup(s3resume);
}
timestamp_add_now(TS_BOOTBLOCK_END);
run_romstage();
}
void bootblock_main_with_basetime(uint64_t base_timestamp)
{
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
}
void main(void)
{
uint64_t base_timestamp = 0;
init_timer();
if (CONFIG(COLLECT_TIMESTAMPS))
base_timestamp = timestamp_get();
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
}
#if CONFIG(COMPRESS_BOOTBLOCK)
/*
* This is the bootblock entry point when it is run after a decompressor stage.
* For non-decompressor builds, _start is generally defined in architecture-
* specific assembly code. In decompressor builds that architecture
* initialization code already ran in the decompressor, so the bootblock can
* start straight into common code with a C environment.
*/
void _start(struct bootblock_arg *arg);
void _start(struct bootblock_arg *arg)
{
if (CONFIG(CBFS_VERIFICATION))
metadata_hash_import_anchor(arg->metadata_hash_anchor);
bootblock_main_with_timestamp(arg->base_timestamp, arg->timestamps,
arg->num_timestamps);
}
#endif