blob: 9c6e56e9af6af682ed4cb734e146c414d558de3c [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>
Julius Werner1e37c9c2019-12-11 17:09:39 -08005#include <cbmem.h>
6#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 Werner1e37c9c2019-12-11 17:09:39 -080028static void build_rw_mcache(void)
29{
30 if (CONFIG(NO_CBFS_MCACHE))
31 return;
32
33 const struct cbfs_boot_device *cbd = vboot_get_cbfs_boot_device();
34 if (!cbd) /* Don't build RW mcache in recovery mode. */
35 return;
36 cb_err_t err = cbfs_mcache_build(&cbd->rdev, cbd->mcache,
37 cbd->mcache_size, NULL);
38 if (err && err != CB_CBFS_CACHE_FULL)
39 die("Failed to build RW mcache."); /* TODO: -> recovery? */
40}
41
Wim Vervoorn1058dd82019-11-01 10:22:22 +010042void vboot_run_logic(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050043{
Paul Kocialkowski18117682016-05-14 15:30:52 +020044 if (verification_should_run()) {
Julius Werner58c39382017-02-13 17:53:29 -080045 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
Aaron Durbin17200ad2015-05-01 16:48:54 -050046 verstage_main();
Arthur Heymans344e86b2019-11-20 19:47:10 +010047 vboot_executed = 1;
Julius Werner1e37c9c2019-12-11 17:09:39 -080048 build_rw_mcache();
Aaron Durbin17200ad2015-05-01 16:48:54 -050049 } else if (verstage_should_load()) {
Aaron Durbin37a5d152015-09-17 16:09:30 -050050 struct cbfsf file;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050051 struct prog verstage =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060052 PROG_INIT(PROG_VERSTAGE,
Aaron Durbinac12c66c2015-05-20 12:08:55 -050053 CONFIG_CBFS_PREFIX "/verstage");
Aaron Durbin17200ad2015-05-01 16:48:54 -050054
Aaron Durbince2c50d2015-05-13 13:33:27 -050055 printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
56
Aaron Durbin17200ad2015-05-01 16:48:54 -050057 /* load verstage from RO */
Aaron Durbin37a5d152015-09-17 16:09:30 -050058 if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
59 die("failed to load verstage");
60
61 cbfs_file_data(prog_rdev(&verstage), &file);
62
63 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -050064 die("failed to load verstage");
65
66 /* verify and select a slot */
67 prog_run(&verstage);
68
69 /* This is not actually possible to hit this condition at
70 * runtime, but this provides a hint to the compiler for dead
71 * code elimination below. */
Julius Wernercd49cce2019-03-05 16:53:33 -080072 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -060073 return;
74
Arthur Heymans344e86b2019-11-20 19:47:10 +010075 vboot_executed = 1;
Julius Werner1e37c9c2019-12-11 17:09:39 -080076 build_rw_mcache();
Aaron Durbin17200ad2015-05-01 16:48:54 -050077 }
Aaron Durbin17200ad2015-05-01 16:48:54 -050078}
79
Julius Werner1e37c9c2019-12-11 17:09:39 -080080const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050081{
Aaron Durbin6d720f32015-12-08 17:00:23 -060082 /* Don't honor vboot results until the vboot logic has run. */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080083 if (!vboot_logic_executed())
Julius Werner1e37c9c2019-12-11 17:09:39 -080084 return NULL;
Aaron Durbin17200ad2015-05-01 16:48:54 -050085
Julius Werner1e37c9c2019-12-11 17:09:39 -080086 static struct cbfs_boot_device cbd;
87 if (region_device_sz(&cbd.rdev))
88 return &cbd;
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080089
Julius Werner1e37c9c2019-12-11 17:09:39 -080090 struct vb2_context *ctx = vboot_get_context();
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080091 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
Julius Werner1e37c9c2019-12-11 17:09:39 -080092 return NULL;
Aaron Durbinb6981c02015-05-15 15:57:51 -050093
Julius Werner1e37c9c2019-12-11 17:09:39 -080094 boot_device_init();
95 if (vboot_locate_firmware(ctx, &cbd.rdev))
96 return NULL;
97
98 cbfs_boot_device_find_mcache(&cbd, CBMEM_ID_CBFS_RW_MCACHE);
99
100 return &cbd;
Aaron Durbin17200ad2015-05-01 16:48:54 -0500101}