blob: 1c4343bdc56a0d11627fe5395446b1b524e12add [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>
Raul E Rangel170ac852021-06-09 15:39:19 -060013#include <timestamp.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050014
Julius Werner73d042b2017-03-17 16:54:48 -070015/* Ensure vboot configuration is valid: */
Julius Wernercd49cce2019-03-05 16:53:33 -080016_Static_assert(CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) +
Martin Roth8a3a3c82020-05-04 10:13:45 -060017 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) +
Julius Wernercd49cce2019-03-05 16:53:33 -080018 CONFIG(VBOOT_STARTS_IN_ROMSTAGE) == 1,
Martin Roth8a3a3c82020-05-04 10:13:45 -060019 "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 ");
Julius Wernercd49cce2019-03-05 16:53:33 -080023_Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) ||
24 CONFIG(VBOOT_SEPARATE_VERSTAGE),
Julius Werner73d042b2017-03-17 16:54:48 -070025 "return from verstage only makes sense for separate verstages");
26
Arthur Heymans344e86b2019-11-20 19:47:10 +010027int vboot_executed;
Aaron Durbin6d720f32015-12-08 17:00:23 -060028
Julius Wernerfdabf3f2020-05-06 17:06:35 -070029static void after_verstage(void)
Julius Werner1e37c9c2019-12-11 17:09:39 -080030{
Julius Wernerfdabf3f2020-05-06 17:06:35 -070031 vboot_executed = 1; /* Mark verstage execution complete. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080032
33 const struct cbfs_boot_device *cbd = vboot_get_cbfs_boot_device();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070034 if (!cbd) /* Can't initialize RW CBFS in recovery mode. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080035 return;
Julius Wernerfdabf3f2020-05-06 17:06:35 -070036
37 cb_err_t err = cbfs_init_boot_device(cbd, NULL); /* TODO: RW hash */
38 if (err && err != CB_CBFS_CACHE_FULL) /* TODO: -> recovery? */
39 die("RW CBFS initialization failure: %d", err);
Julius Werner1e37c9c2019-12-11 17:09:39 -080040}
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();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070047 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050048 } else if (verstage_should_load()) {
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
Jakub Czapigaad6157e2022-02-15 11:50:31 +010055 timestamp_add_now(TS_COPYVER_START);
Aaron Durbin37a5d152015-09-17 16:09:30 -050056 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -050057 die("failed to load verstage");
Jakub Czapigaad6157e2022-02-15 11:50:31 +010058 timestamp_add_now(TS_COPYVER_END);
Aaron Durbin17200ad2015-05-01 16:48:54 -050059
60 /* verify and select a slot */
61 prog_run(&verstage);
62
63 /* This is not actually possible to hit this condition at
64 * runtime, but this provides a hint to the compiler for dead
65 * code elimination below. */
Julius Wernercd49cce2019-03-05 16:53:33 -080066 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -060067 return;
68
Julius Wernerfdabf3f2020-05-06 17:06:35 -070069 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050070 }
Aaron Durbin17200ad2015-05-01 16:48:54 -050071}
72
Julius Werner1e37c9c2019-12-11 17:09:39 -080073const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050074{
Aaron Durbin6d720f32015-12-08 17:00:23 -060075 /* Don't honor vboot results until the vboot logic has run. */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080076 if (!vboot_logic_executed())
Julius Werner1e37c9c2019-12-11 17:09:39 -080077 return NULL;
Aaron Durbin17200ad2015-05-01 16:48:54 -050078
Julius Werner1e37c9c2019-12-11 17:09:39 -080079 static struct cbfs_boot_device cbd;
80 if (region_device_sz(&cbd.rdev))
81 return &cbd;
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080082
Julius Werner1e37c9c2019-12-11 17:09:39 -080083 struct vb2_context *ctx = vboot_get_context();
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080084 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
Julius Werner1e37c9c2019-12-11 17:09:39 -080085 return NULL;
Aaron Durbinb6981c02015-05-15 15:57:51 -050086
Julius Werner1e37c9c2019-12-11 17:09:39 -080087 boot_device_init();
88 if (vboot_locate_firmware(ctx, &cbd.rdev))
89 return NULL;
90
91 cbfs_boot_device_find_mcache(&cbd, CBMEM_ID_CBFS_RW_MCACHE);
92
93 return &cbd;
Aaron Durbin17200ad2015-05-01 16:48:54 -050094}