blob: 3aac48d1743ea8615398f7fdada462ba11c2744c [file] [log] [blame]
Aaron Durbin17200ad2015-05-01 16:48:54 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 Google, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Aaron Durbin17200ad2015-05-01 16:48:54 -050014 */
15
Aaron Durbin6d720f32015-12-08 17:00:23 -060016#include <arch/early_variables.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050017#include <cbfs.h>
18#include <console/console.h>
Aaron Durbinf7ce40b2016-08-24 14:58:12 -050019#include <ec/google/chromeec/ec.h>
Aaron Durbin09560fa2015-05-12 16:43:10 -050020#include <rmodule.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020021#include <security/vboot/misc.h>
22#include <security/vboot/symbols.h>
23#include <security/vboot/vboot_common.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050024
Julius Werner73d042b2017-03-17 16:54:48 -070025/* Ensure vboot configuration is valid: */
Julius Wernercd49cce2019-03-05 16:53:33 -080026_Static_assert(CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) +
27 CONFIG(VBOOT_STARTS_IN_ROMSTAGE) == 1,
Julius Werner73d042b2017-03-17 16:54:48 -070028 "vboot must either start in bootblock or romstage (not both!)");
Julius Wernercd49cce2019-03-05 16:53:33 -080029_Static_assert(!CONFIG(VBOOT_SEPARATE_VERSTAGE) ||
30 CONFIG(VBOOT_STARTS_IN_BOOTBLOCK),
Julius Werner73d042b2017-03-17 16:54:48 -070031 "stand-alone verstage must start in (i.e. after) bootblock");
Julius Wernercd49cce2019-03-05 16:53:33 -080032_Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) ||
33 CONFIG(VBOOT_SEPARATE_VERSTAGE),
Julius Werner73d042b2017-03-17 16:54:48 -070034 "return from verstage only makes sense for separate verstages");
35
Julius Werner998dc172019-05-09 14:16:13 -070036int vboot_executed CAR_GLOBAL;
Aaron Durbin6d720f32015-12-08 17:00:23 -060037
38static void vboot_prepare(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050039{
Paul Kocialkowski18117682016-05-14 15:30:52 +020040 if (verification_should_run()) {
Julius Werner58c39382017-02-13 17:53:29 -080041 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
Aaron Durbin17200ad2015-05-01 16:48:54 -050042 verstage_main();
Aaron Durbin6d720f32015-12-08 17:00:23 -060043 car_set_var(vboot_executed, 1);
Aaron Durbin17200ad2015-05-01 16:48:54 -050044 } else if (verstage_should_load()) {
Aaron Durbin37a5d152015-09-17 16:09:30 -050045 struct cbfsf file;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050046 struct prog verstage =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060047 PROG_INIT(PROG_VERSTAGE,
Aaron Durbinac12c66c2015-05-20 12:08:55 -050048 CONFIG_CBFS_PREFIX "/verstage");
Aaron Durbin17200ad2015-05-01 16:48:54 -050049
Aaron Durbince2c50d2015-05-13 13:33:27 -050050 printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
51
Aaron Durbin17200ad2015-05-01 16:48:54 -050052 /* load verstage from RO */
Aaron Durbin37a5d152015-09-17 16:09:30 -050053 if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
54 die("failed to load verstage");
55
56 cbfs_file_data(prog_rdev(&verstage), &file);
57
58 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -050059 die("failed to load verstage");
60
61 /* verify and select a slot */
62 prog_run(&verstage);
63
64 /* This is not actually possible to hit this condition at
65 * runtime, but this provides a hint to the compiler for dead
66 * code elimination below. */
Julius Wernercd49cce2019-03-05 16:53:33 -080067 if (!CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -060068 return;
69
70 car_set_var(vboot_executed, 1);
Aaron Durbin17200ad2015-05-01 16:48:54 -050071 }
Aaron Durbin17200ad2015-05-01 16:48:54 -050072}
73
Aaron Durbin6d720f32015-12-08 17:00:23 -060074static int vboot_locate(struct cbfs_props *props)
Aaron Durbin17200ad2015-05-01 16:48:54 -050075{
Aaron Durbin6d720f32015-12-08 17:00:23 -060076 struct region selected_region;
Aaron Durbin899d13d2015-05-15 23:39:23 -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())
Aaron Durbinb6981c02015-05-15 15:57:51 -050080 return -1;
Aaron Durbin17200ad2015-05-01 16:48:54 -050081
Joel Kitchingaf8471c2019-03-13 22:38:07 +080082 if (vboot_get_selected_region(&selected_region))
Aaron Durbin4e50cdd2015-05-15 23:25:46 -050083 return -1;
Aaron Durbinb6981c02015-05-15 15:57:51 -050084
Aaron Durbin6d720f32015-12-08 17:00:23 -060085 props->offset = region_offset(&selected_region);
86 props->size = region_sz(&selected_region);
Aaron Durbin17200ad2015-05-01 16:48:54 -050087
Aaron Durbinb6981c02015-05-15 15:57:51 -050088 return 0;
Aaron Durbin17200ad2015-05-01 16:48:54 -050089}
90
Aaron Durbin6d720f32015-12-08 17:00:23 -060091const struct cbfs_locator vboot_locator = {
Aaron Durbin17200ad2015-05-01 16:48:54 -050092 .name = "VBOOT",
Aaron Durbin6d720f32015-12-08 17:00:23 -060093 .prepare = vboot_prepare,
Aaron Durbin899d13d2015-05-15 23:39:23 -050094 .locate = vboot_locate,
Aaron Durbin17200ad2015-05-01 16:48:54 -050095};