1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <boot_device.h>
6 #include <commonlib/bsd/cbfs_private.h>
7 #include <console/console.h>
8 #include <ec/google/chromeec/ec.h>
10 #include <security/vboot/misc.h>
11 #include <security/vboot/symbols.h>
12 #include <security/vboot/vboot_common.h>
13 #include <timestamp.h>
15 /* Ensure vboot configuration is valid: */
16 _Static_assert(CONFIG(VBOOT_STARTS_IN_BOOTBLOCK
) +
17 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK
) +
18 CONFIG(VBOOT_STARTS_IN_ROMSTAGE
) == 1,
19 "vboot must start in bootblock, PSP or romstage (but only one!)");
20 _Static_assert(!CONFIG(VBOOT_SEPARATE_VERSTAGE
) || CONFIG(VBOOT_STARTS_IN_BOOTBLOCK
) ||
21 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK
),
22 "stand-alone verstage must start in or before bootblock ");
23 _Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE
) ||
24 CONFIG(VBOOT_SEPARATE_VERSTAGE
),
25 "return from verstage only makes sense for separate verstages");
29 static void after_verstage(void)
31 struct vb2_hash
*metadata_hash
= NULL
;
32 struct vb2_context
*ctx
= NULL
;
34 vboot_executed
= 1; /* Mark verstage execution complete. */
36 const struct cbfs_boot_device
*cbd
= vboot_get_cbfs_boot_device();
37 if (!cbd
) /* Can't initialize RW CBFS in recovery mode. */
40 if (CONFIG(VBOOT_CBFS_INTEGRATION
)) {
41 ctx
= vboot_get_context();
42 vb2_error_t rv
= vb2api_get_metadata_hash(ctx
, &metadata_hash
);
44 vboot_fail_and_reboot(ctx
, VB2_RECOVERY_FW_PREAMBLE
, rv
);
47 enum cb_err err
= cbfs_init_boot_device(cbd
, metadata_hash
);
48 if (err
&& err
!= CB_CBFS_CACHE_FULL
) {
49 if (CONFIG(VBOOT_CBFS_INTEGRATION
)) {
50 printk(BIOS_ERR
, "RW CBFS initialization failed: %d\n", err
);
51 /* CBFS error code does not fit in subcode. Use only lowest byte. */
52 vboot_fail_and_reboot(ctx
, VB2_RECOVERY_FW_BODY
, err
& 0xFF);
54 die("RW CBFS initialization failure: %d", err
);
59 void vboot_run_logic(void)
61 if (verification_should_run()) {
62 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
65 } else if (verstage_should_load()) {
66 struct prog verstage
=
67 PROG_INIT(PROG_VERSTAGE
,
68 CONFIG_CBFS_PREFIX
"/verstage");
70 printk(BIOS_DEBUG
, "VBOOT: Loading verstage.\n");
72 timestamp_add_now(TS_COPYVER_START
);
73 if (cbfs_prog_stage_load(&verstage
))
74 die("failed to load verstage");
75 timestamp_add_now(TS_COPYVER_END
);
77 /* verify and select a slot */
80 /* This is not actually possible to hit this condition at
81 * runtime, but this provides a hint to the compiler for dead
82 * code elimination below. */
83 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE
))
90 const struct cbfs_boot_device
*vboot_get_cbfs_boot_device(void)
92 /* Don't honor vboot results until the vboot logic has run. */
93 if (!vboot_logic_executed())
96 static struct cbfs_boot_device cbd
;
97 if (region_device_sz(&cbd
.rdev
))
100 struct vb2_context
*ctx
= vboot_get_context();
101 if (ctx
->flags
& VB2_CONTEXT_RECOVERY_MODE
)
105 if (vboot_locate_firmware(ctx
, &cbd
.rdev
))
108 cbfs_boot_device_find_mcache(&cbd
, CBMEM_ID_CBFS_RW_MCACHE
);