xref: /aosp_15_r20/external/coreboot/src/security/vboot/bootmode.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <bootmode.h>
5 #include <bootstate.h>
6 #include <vb2_api.h>
7 #include <security/vboot/misc.h>
8 #include <security/vboot/vbnv.h>
9 #include <security/vboot/vboot_common.h>
10 
11 /*
12  * Functions which check vboot information should only be called after verstage
13  * has run.  Otherwise, they will hit the assertion in vboot_get_context().
14  */
15 
vboot_check_recovery_request(void)16 int vboot_check_recovery_request(void)
17 {
18 	return vb2api_get_recovery_reason(vboot_get_context());
19 }
20 
vboot_recovery_mode_enabled(void)21 int vboot_recovery_mode_enabled(void)
22 {
23 	return vboot_get_context()->flags & VB2_CONTEXT_RECOVERY_MODE;
24 }
25 
vboot_developer_mode_enabled(void)26 int vboot_developer_mode_enabled(void)
27 {
28 	return vboot_get_context()->flags & VB2_CONTEXT_DEVELOPER_MODE;
29 }
30 
clear_recovery_mode_switch(void)31 int __weak clear_recovery_mode_switch(void)
32 {
33 	return 0;
34 }
35 
do_clear_recovery_mode_switch(void * unused)36 static void do_clear_recovery_mode_switch(void *unused)
37 {
38 	if (vboot_get_context()->flags & VB2_CONTEXT_FORCE_RECOVERY_MODE)
39 		clear_recovery_mode_switch();
40 }
41 /*
42  * The recovery mode switch (typically backed by EC) is not cleared until
43  * BS_WRITE_TABLES for two reasons:
44  *
45  * (1) On some platforms, FSP initialization may cause a reboot.  Push clearing
46  * the recovery mode switch until after FSP code runs, so that a manual recovery
47  * request (three-finger salute) will function correctly under this condition.
48  *
49  * (2) To give the implementation of clear_recovery_mode_switch a chance to
50  * add an event to elog.  See the function in chromeec/switches.c.
51  */
52 BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
53 		      do_clear_recovery_mode_switch, NULL);
54 
55 #if CONFIG(VBOOT_CLEAR_RECOVERY_IN_RAMSTAGE)
vboot_clear_recovery_request(void * unused)56 static void vboot_clear_recovery_request(void *unused)
57 {
58 	struct vb2_context *ctx;
59 
60 	ctx = vboot_get_context();
61 	vb2api_clear_recovery(ctx);
62 	save_vbnv(ctx->nvdata);
63 }
64 
65 /* This has to be called before back_up_vbnv_cmos, so BS_ON_ENTRY is used here. */
66 BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY,
67 		      vboot_clear_recovery_request, NULL);
68 #endif
69 
get_recovery_mode_retrain_switch(void)70 int __weak get_recovery_mode_retrain_switch(void)
71 {
72 	return 0;
73 }
74 
get_ec_is_trusted(void)75 int __weak get_ec_is_trusted(void)
76 {
77 	/*
78 	 * If board doesn't override this, by default we always assume EC is in
79 	 * RW and untrusted. However, newer platforms with Google TPM are supposed
80 	 * to use GSC BOOT_MODE to report this and won't need to override this
81 	 * anymore.
82 	 */
83 	return 0;
84 }
85 
86 #if CONFIG(VBOOT_NO_BOARD_SUPPORT)
87 /**
88  * TODO: Create flash protection interface which implements get_write_protect_state.
89  * get_recovery_mode_switch should be implemented as default function.
90  */
get_write_protect_state(void)91 int __weak get_write_protect_state(void)
92 {
93 	return 0;
94 }
95 
get_recovery_mode_switch(void)96 int __weak get_recovery_mode_switch(void)
97 {
98 	return 0;
99 }
100 
fill_lb_gpios(struct lb_gpios * gpios)101 void __weak fill_lb_gpios(struct lb_gpios *gpios)
102 {
103 }
104 
105 #endif
106