1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <acpi/acpi.h>
4 #include <arch/exception.h>
5 #include <bootblock_common.h>
6 #include <console/console.h>
7 #include <delay.h>
8 #include <metadata_hash.h>
9 #include <option.h>
10 #include <post.h>
11 #include <program_loading.h>
12 #include <security/tpm/tspi.h>
13 #include <symbols.h>
14 #include <timestamp.h>
15
bootblock_mainboard_early_init(void)16 __weak void bootblock_mainboard_early_init(void) { /* no-op */ }
bootblock_soc_early_init(void)17 __weak void bootblock_soc_early_init(void) { /* do nothing */ }
bootblock_soc_init(void)18 __weak void bootblock_soc_init(void) { /* do nothing */ }
bootblock_mainboard_init(void)19 __weak void bootblock_mainboard_init(void) { /* do nothing */ }
20
21 /*
22 * This is a the same as the bootblock main(), with the difference that it does
23 * not collect a timestamp. Instead it accepts the initial timestamp and
24 * possibly additional timestamp entries as arguments. This can be used in cases
25 * where earlier stamps are available. Note that this function is designed to be
26 * entered from C code. This function assumes that the timer has already been
27 * initialized, so it does not call init_timer().
28 */
bootblock_main_with_timestamp(uint64_t base_timestamp,struct timestamp_entry * timestamps,size_t num_timestamps)29 void bootblock_main_with_timestamp(uint64_t base_timestamp,
30 struct timestamp_entry *timestamps, size_t num_timestamps)
31 {
32 /* Initialize timestamps if we have TIMESTAMP region in memlayout.ld. */
33 if (CONFIG(COLLECT_TIMESTAMPS) &&
34 REGION_SIZE(timestamp) > 0) {
35 int i;
36 timestamp_init(base_timestamp);
37 for (i = 0; i < num_timestamps; i++)
38 timestamp_add(timestamps[i].entry_id,
39 timestamps[i].entry_stamp);
40 }
41
42 timestamp_add_now(TS_BOOTBLOCK_START);
43
44 bootblock_soc_early_init();
45 bootblock_mainboard_early_init();
46
47 if (CONFIG(USE_OPTION_TABLE))
48 sanitize_cmos();
49
50 if (CONFIG(CMOS_POST))
51 cmos_post_init();
52
53 if (CONFIG(BOOTBLOCK_CONSOLE)) {
54 console_init();
55 exception_init();
56 }
57
58 bootblock_soc_init();
59 bootblock_mainboard_init();
60
61 if (CONFIG(TPM_MEASURED_BOOT_INIT_BOOTBLOCK)) {
62 int s3resume = acpi_is_wakeup_s3();
63 tpm_setup(s3resume);
64 }
65
66 timestamp_add_now(TS_BOOTBLOCK_END);
67
68 run_romstage();
69 }
70
bootblock_main_with_basetime(uint64_t base_timestamp)71 void bootblock_main_with_basetime(uint64_t base_timestamp)
72 {
73 bootblock_main_with_timestamp(base_timestamp, NULL, 0);
74 }
75
main(void)76 void main(void)
77 {
78 uint64_t base_timestamp = 0;
79
80 init_timer();
81
82 if (CONFIG(COLLECT_TIMESTAMPS))
83 base_timestamp = timestamp_get();
84
85 bootblock_main_with_timestamp(base_timestamp, NULL, 0);
86 }
87
88 #if CONFIG(COMPRESS_BOOTBLOCK)
89 /*
90 * This is the bootblock entry point when it is run after a decompressor stage.
91 * For non-decompressor builds, _start is generally defined in architecture-
92 * specific assembly code. In decompressor builds that architecture
93 * initialization code already ran in the decompressor, so the bootblock can
94 * start straight into common code with a C environment.
95 */
96 void _start(struct bootblock_arg *arg);
_start(struct bootblock_arg * arg)97 void _start(struct bootblock_arg *arg)
98 {
99 if (CONFIG(CBFS_VERIFICATION))
100 metadata_hash_import_anchor(arg->metadata_hash_anchor);
101 bootblock_main_with_timestamp(arg->base_timestamp, arg->timestamps,
102 arg->num_timestamps);
103 }
104
105 #endif
106