blob: 56a0664328737ea1cf1f5719e0bab71744d96a06 [file] [log] [blame]
Angel Pons986d50e2020-04-02 23:48:53 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin17200ad2015-05-01 16:48:54 -05002
Julius Werner1e37c9c2019-12-11 17:09:39 -08003#include <boot_device.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -05004#include <cbfs.h>
Elyes HAOUAS26a69212021-02-08 10:02:56 +01005#include <cbmem.h>
Julius Werner1e37c9c2019-12-11 17:09:39 -08006#include <commonlib/bsd/cbfs_private.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -05007#include <console/console.h>
Aaron Durbinf7ce40b2016-08-24 14:58:12 -05008#include <ec/google/chromeec/ec.h>
Aaron Durbin09560fa2015-05-12 16:43:10 -05009#include <rmodule.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020010#include <security/vboot/misc.h>
11#include <security/vboot/symbols.h>
12#include <security/vboot/vboot_common.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050013
Julius Werner73d042b2017-03-17 16:54:48 -070014/* Ensure vboot configuration is valid: */
Julius Wernercd49cce2019-03-05 16:53:33 -080015_Static_assert(CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) +
Martin Roth8a3a3c82020-05-04 10:13:45 -060016 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) +
Julius Wernercd49cce2019-03-05 16:53:33 -080017 CONFIG(VBOOT_STARTS_IN_ROMSTAGE) == 1,
Martin Roth8a3a3c82020-05-04 10:13:45 -060018 "vboot must start in bootblock, PSP or romstage (but only one!)");
19_Static_assert(!CONFIG(VBOOT_SEPARATE_VERSTAGE) || CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) ||
20 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK),
21 "stand-alone verstage must start in or before bootblock ");
Julius Wernercd49cce2019-03-05 16:53:33 -080022_Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) ||
23 CONFIG(VBOOT_SEPARATE_VERSTAGE),
Julius Werner73d042b2017-03-17 16:54:48 -070024 "return from verstage only makes sense for separate verstages");
25
Arthur Heymans344e86b2019-11-20 19:47:10 +010026int vboot_executed;
Aaron Durbin6d720f32015-12-08 17:00:23 -060027
Julius Wernerfdabf3f2020-05-06 17:06:35 -070028static void after_verstage(void)
Julius Werner1e37c9c2019-12-11 17:09:39 -080029{
Julius Wernerfdabf3f2020-05-06 17:06:35 -070030 vboot_executed = 1; /* Mark verstage execution complete. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080031
32 const struct cbfs_boot_device *cbd = vboot_get_cbfs_boot_device();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070033 if (!cbd) /* Can't initialize RW CBFS in recovery mode. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080034 return;
Julius Wernerfdabf3f2020-05-06 17:06:35 -070035
36 cb_err_t err = cbfs_init_boot_device(cbd, NULL); /* TODO: RW hash */
37 if (err && err != CB_CBFS_CACHE_FULL) /* TODO: -> recovery? */
38 die("RW CBFS initialization failure: %d", err);
Julius Werner1e37c9c2019-12-11 17:09:39 -080039}
40
Wim Vervoorn1058dd82019-11-01 10:22:22 +010041void vboot_run_logic(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050042{
Paul Kocialkowski18117682016-05-14 15:30:52 +020043 if (verification_should_run()) {
Julius Werner58c39382017-02-13 17:53:29 -080044 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
Aaron Durbin17200ad2015-05-01 16:48:54 -050045 verstage_main();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070046 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050047 } else if (verstage_should_load()) {
Aaron Durbin37a5d152015-09-17 16:09:30 -050048 struct cbfsf file;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050049 struct prog verstage =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060050 PROG_INIT(PROG_VERSTAGE,
Aaron Durbinac12c66c2015-05-20 12:08:55 -050051 CONFIG_CBFS_PREFIX "/verstage");
Aaron Durbin17200ad2015-05-01 16:48:54 -050052
Aaron Durbince2c50d2015-05-13 13:33:27 -050053 printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
54
Aaron Durbin17200ad2015-05-01 16:48:54 -050055 /* load verstage from RO */
Aaron Durbin37a5d152015-09-17 16:09:30 -050056 if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
57 die("failed to load verstage");
58
59 cbfs_file_data(prog_rdev(&verstage), &file);
60
61 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -050062 die("failed to load verstage");
63
64 /* verify and select a slot */
65 prog_run(&verstage);
66
67 /* This is not actually possible to hit this condition at
68 * runtime, but this provides a hint to the compiler for dead
69 * code elimination below. */
Julius Wernercd49cce2019-03-05 16:53:33 -080070 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -060071 return;
72
Julius Wernerfdabf3f2020-05-06 17:06:35 -070073 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050074 }
Aaron Durbin17200ad2015-05-01 16:48:54 -050075}
76
Julius Werner1e37c9c2019-12-11 17:09:39 -080077const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050078{
Aaron Durbin6d720f32015-12-08 17:00:23 -060079 /* Don't honor vboot results until the vboot logic has run. */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080080 if (!vboot_logic_executed())
Julius Werner1e37c9c2019-12-11 17:09:39 -080081 return NULL;
Aaron Durbin17200ad2015-05-01 16:48:54 -050082
Julius Werner1e37c9c2019-12-11 17:09:39 -080083 static struct cbfs_boot_device cbd;
84 if (region_device_sz(&cbd.rdev))
85 return &cbd;
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080086
Julius Werner1e37c9c2019-12-11 17:09:39 -080087 struct vb2_context *ctx = vboot_get_context();
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080088 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
Julius Werner1e37c9c2019-12-11 17:09:39 -080089 return NULL;
Aaron Durbinb6981c02015-05-15 15:57:51 -050090
Julius Werner1e37c9c2019-12-11 17:09:39 -080091 boot_device_init();
92 if (vboot_locate_firmware(ctx, &cbd.rdev))
93 return NULL;
94
95 cbfs_boot_device_find_mcache(&cbd, CBMEM_ID_CBFS_RW_MCACHE);
96
97 return &cbd;
Aaron Durbin17200ad2015-05-01 16:48:54 -050098}