blob: 234ae8f4ade7c39b2eb75cd8ce93e8340ed01319 [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 <commonlib/bsd/cbfs_private.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -05006#include <console/console.h>
Aaron Durbinf7ce40b2016-08-24 14:58:12 -05007#include <ec/google/chromeec/ec.h>
Aaron Durbin09560fa2015-05-12 16:43:10 -05008#include <rmodule.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +02009#include <security/vboot/misc.h>
10#include <security/vboot/symbols.h>
11#include <security/vboot/vboot_common.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050012
Julius Werner73d042b2017-03-17 16:54:48 -070013/* Ensure vboot configuration is valid: */
Julius Wernercd49cce2019-03-05 16:53:33 -080014_Static_assert(CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) +
Martin Roth8a3a3c82020-05-04 10:13:45 -060015 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) +
Julius Wernercd49cce2019-03-05 16:53:33 -080016 CONFIG(VBOOT_STARTS_IN_ROMSTAGE) == 1,
Martin Roth8a3a3c82020-05-04 10:13:45 -060017 "vboot must start in bootblock, PSP or romstage (but only one!)");
18_Static_assert(!CONFIG(VBOOT_SEPARATE_VERSTAGE) || CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) ||
19 CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK),
20 "stand-alone verstage must start in or before bootblock ");
Julius Wernercd49cce2019-03-05 16:53:33 -080021_Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) ||
22 CONFIG(VBOOT_SEPARATE_VERSTAGE),
Julius Werner73d042b2017-03-17 16:54:48 -070023 "return from verstage only makes sense for separate verstages");
24
Arthur Heymans344e86b2019-11-20 19:47:10 +010025int vboot_executed;
Aaron Durbin6d720f32015-12-08 17:00:23 -060026
Julius Wernerfdabf3f2020-05-06 17:06:35 -070027static void after_verstage(void)
Julius Werner1e37c9c2019-12-11 17:09:39 -080028{
Julius Wernerfdabf3f2020-05-06 17:06:35 -070029 vboot_executed = 1; /* Mark verstage execution complete. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080030
31 const struct cbfs_boot_device *cbd = vboot_get_cbfs_boot_device();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070032 if (!cbd) /* Can't initialize RW CBFS in recovery mode. */
Julius Werner1e37c9c2019-12-11 17:09:39 -080033 return;
Julius Wernerfdabf3f2020-05-06 17:06:35 -070034
35 cb_err_t err = cbfs_init_boot_device(cbd, NULL); /* TODO: RW hash */
36 if (err && err != CB_CBFS_CACHE_FULL) /* TODO: -> recovery? */
37 die("RW CBFS initialization failure: %d", err);
Julius Werner1e37c9c2019-12-11 17:09:39 -080038}
39
Wim Vervoorn1058dd82019-11-01 10:22:22 +010040void vboot_run_logic(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050041{
Paul Kocialkowski18117682016-05-14 15:30:52 +020042 if (verification_should_run()) {
Julius Werner58c39382017-02-13 17:53:29 -080043 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
Aaron Durbin17200ad2015-05-01 16:48:54 -050044 verstage_main();
Julius Wernerfdabf3f2020-05-06 17:06:35 -070045 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050046 } else if (verstage_should_load()) {
Aaron Durbin37a5d152015-09-17 16:09:30 -050047 struct cbfsf file;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050048 struct prog verstage =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060049 PROG_INIT(PROG_VERSTAGE,
Aaron Durbinac12c66c2015-05-20 12:08:55 -050050 CONFIG_CBFS_PREFIX "/verstage");
Aaron Durbin17200ad2015-05-01 16:48:54 -050051
Aaron Durbince2c50d2015-05-13 13:33:27 -050052 printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
53
Aaron Durbin17200ad2015-05-01 16:48:54 -050054 /* load verstage from RO */
Aaron Durbin37a5d152015-09-17 16:09:30 -050055 if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
56 die("failed to load verstage");
57
58 cbfs_file_data(prog_rdev(&verstage), &file);
59
60 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -050061 die("failed to load verstage");
62
63 /* verify and select a slot */
64 prog_run(&verstage);
65
66 /* This is not actually possible to hit this condition at
67 * runtime, but this provides a hint to the compiler for dead
68 * code elimination below. */
Julius Wernercd49cce2019-03-05 16:53:33 -080069 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -060070 return;
71
Julius Wernerfdabf3f2020-05-06 17:06:35 -070072 after_verstage();
Aaron Durbin17200ad2015-05-01 16:48:54 -050073 }
Aaron Durbin17200ad2015-05-01 16:48:54 -050074}
75
Julius Werner1e37c9c2019-12-11 17:09:39 -080076const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050077{
Aaron Durbin6d720f32015-12-08 17:00:23 -060078 /* Don't honor vboot results until the vboot logic has run. */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080079 if (!vboot_logic_executed())
Julius Werner1e37c9c2019-12-11 17:09:39 -080080 return NULL;
Aaron Durbin17200ad2015-05-01 16:48:54 -050081
Julius Werner1e37c9c2019-12-11 17:09:39 -080082 static struct cbfs_boot_device cbd;
83 if (region_device_sz(&cbd.rdev))
84 return &cbd;
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080085
Julius Werner1e37c9c2019-12-11 17:09:39 -080086 struct vb2_context *ctx = vboot_get_context();
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080087 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
Julius Werner1e37c9c2019-12-11 17:09:39 -080088 return NULL;
Aaron Durbinb6981c02015-05-15 15:57:51 -050089
Julius Werner1e37c9c2019-12-11 17:09:39 -080090 boot_device_init();
91 if (vboot_locate_firmware(ctx, &cbd.rdev))
92 return NULL;
93
94 cbfs_boot_device_find_mcache(&cbd, CBMEM_ID_CBFS_RW_MCACHE);
95
96 return &cbd;
Aaron Durbin17200ad2015-05-01 16:48:54 -050097}