xref: /aosp_15_r20/external/coreboot/src/lib/bootblock.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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