blob: 75f75b5cf8130b961b048d912cbf8d7f07188bd9 [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>
Aaron Durbin17200ad2015-05-01 16:48:54 -050021#include <string.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020022#include <security/vboot/misc.h>
23#include <security/vboot/symbols.h>
24#include <security/vboot/vboot_common.h>
Aaron Durbin17200ad2015-05-01 16:48:54 -050025
Julius Werner73d042b2017-03-17 16:54:48 -070026/* Ensure vboot configuration is valid: */
27_Static_assert(IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) +
28 IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) == 1,
29 "vboot must either start in bootblock or romstage (not both!)");
Julius Werner58c39382017-02-13 17:53:29 -080030_Static_assert(!IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE) ||
Julius Werner73d042b2017-03-17 16:54:48 -070031 IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),
32 "stand-alone verstage must start in (i.e. after) bootblock");
Julius Werner58c39382017-02-13 17:53:29 -080033_Static_assert(!IS_ENABLED(CONFIG_VBOOT_RETURN_FROM_VERSTAGE) ||
34 IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE),
Julius Werner73d042b2017-03-17 16:54:48 -070035 "return from verstage only makes sense for separate verstages");
36
Aaron Durbin17200ad2015-05-01 16:48:54 -050037/* The stage loading code is compiled and entered from multiple stages. The
38 * helper functions below attempt to provide more clarity on when certain
39 * code should be called. */
40
41static int verification_should_run(void)
42{
Julius Werner58c39382017-02-13 17:53:29 -080043 if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE))
Julius Werner73d042b2017-03-17 16:54:48 -070044 return ENV_VERSTAGE;
45 else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
46 return ENV_ROMSTAGE;
47 else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
48 return ENV_BOOTBLOCK;
49 else
50 die("impossible!");
Aaron Durbin17200ad2015-05-01 16:48:54 -050051}
52
53static int verstage_should_load(void)
54{
Julius Werner58c39382017-02-13 17:53:29 -080055 if (IS_ENABLED(CONFIG_VBOOT_SEPARATE_VERSTAGE))
Julius Werner73d042b2017-03-17 16:54:48 -070056 return ENV_BOOTBLOCK;
57 else
Aaron Durbin17200ad2015-05-01 16:48:54 -050058 return 0;
Aaron Durbin17200ad2015-05-01 16:48:54 -050059}
60
Aaron Durbin6d720f32015-12-08 17:00:23 -060061static int vboot_executed CAR_GLOBAL;
62
Furquan Shaikha6c5ddd2016-07-22 06:59:40 -070063int vb2_logic_executed(void)
Aaron Durbin6d720f32015-12-08 17:00:23 -060064{
Julius Werner73d042b2017-03-17 16:54:48 -070065 /* If we are in a stage that would load the verstage or execute the
66 vboot logic directly, we store the answer in a global. */
67 if (verstage_should_load() || verification_should_run())
68 return car_get_var(vboot_executed);
69
70 if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) {
71 /* All other stages are "after the bootblock" */
72 return !ENV_BOOTBLOCK;
73 } else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
74 /* Post-RAM stages are "after the romstage" */
75#ifdef __PRE_RAM__
76 return 0;
77#else
Aaron Durbin6d720f32015-12-08 17:00:23 -060078 return 1;
Julius Werner73d042b2017-03-17 16:54:48 -070079#endif
80 } else {
81 die("impossible!");
Aaron Durbin6d720f32015-12-08 17:00:23 -060082 }
Aaron Durbin6d720f32015-12-08 17:00:23 -060083}
84
85static void vboot_prepare(void)
Aaron Durbin17200ad2015-05-01 16:48:54 -050086{
Paul Kocialkowski18117682016-05-14 15:30:52 +020087 if (verification_should_run()) {
Julius Werner58c39382017-02-13 17:53:29 -080088 /* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
Aaron Durbin17200ad2015-05-01 16:48:54 -050089 verstage_main();
Aaron Durbin6d720f32015-12-08 17:00:23 -060090 car_set_var(vboot_executed, 1);
Furquan Shaikh85aa1352016-07-22 08:56:43 -070091 vb2_save_recovery_reason_vbnv();
Aaron Durbin17200ad2015-05-01 16:48:54 -050092 } else if (verstage_should_load()) {
Aaron Durbin37a5d152015-09-17 16:09:30 -050093 struct cbfsf file;
Aaron Durbinac12c66c2015-05-20 12:08:55 -050094 struct prog verstage =
Aaron Durbin7e7a4df2015-12-08 14:34:35 -060095 PROG_INIT(PROG_VERSTAGE,
Aaron Durbinac12c66c2015-05-20 12:08:55 -050096 CONFIG_CBFS_PREFIX "/verstage");
Aaron Durbin17200ad2015-05-01 16:48:54 -050097
Aaron Durbince2c50d2015-05-13 13:33:27 -050098 printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
99
Aaron Durbin17200ad2015-05-01 16:48:54 -0500100 /* load verstage from RO */
Aaron Durbin37a5d152015-09-17 16:09:30 -0500101 if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
102 die("failed to load verstage");
103
104 cbfs_file_data(prog_rdev(&verstage), &file);
105
106 if (cbfs_prog_stage_load(&verstage))
Aaron Durbin17200ad2015-05-01 16:48:54 -0500107 die("failed to load verstage");
108
109 /* verify and select a slot */
110 prog_run(&verstage);
111
112 /* This is not actually possible to hit this condition at
113 * runtime, but this provides a hint to the compiler for dead
114 * code elimination below. */
Julius Werner58c39382017-02-13 17:53:29 -0800115 if (!IS_ENABLED(CONFIG_VBOOT_RETURN_FROM_VERSTAGE))
Aaron Durbin6d720f32015-12-08 17:00:23 -0600116 return;
117
118 car_set_var(vboot_executed, 1);
Aaron Durbin17200ad2015-05-01 16:48:54 -0500119 }
120
Aaron Durbinb5933662015-10-07 16:03:41 -0500121 /*
122 * Fill in vboot cbmem objects before moving to ramstage so all
123 * downstream users have access to vboot results. This path only
Julius Wernerfa8fa7d2017-03-16 19:32:48 -0700124 * applies to platforms employing VBOOT_STARTS_IN_ROMSTAGE because
Aaron Durbinb5933662015-10-07 16:03:41 -0500125 * cbmem comes online prior to vboot verification taking place. For
126 * other platforms the vboot cbmem objects are initialized when
127 * cbmem comes online.
128 */
Julius Wernerfa8fa7d2017-03-16 19:32:48 -0700129 if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
Aaron Durbinb5933662015-10-07 16:03:41 -0500130 vb2_store_selected_region();
Aaron Durbin17200ad2015-05-01 16:48:54 -0500131 vboot_fill_handoff();
Aaron Durbinb5933662015-10-07 16:03:41 -0500132 }
Aaron Durbin17200ad2015-05-01 16:48:54 -0500133}
134
Aaron Durbin6d720f32015-12-08 17:00:23 -0600135static int vboot_locate(struct cbfs_props *props)
Aaron Durbin17200ad2015-05-01 16:48:54 -0500136{
Aaron Durbin6d720f32015-12-08 17:00:23 -0600137 struct region selected_region;
Aaron Durbin899d13d2015-05-15 23:39:23 -0500138
Aaron Durbin6d720f32015-12-08 17:00:23 -0600139 /* Don't honor vboot results until the vboot logic has run. */
Furquan Shaikha6c5ddd2016-07-22 06:59:40 -0700140 if (!vb2_logic_executed())
Aaron Durbinb6981c02015-05-15 15:57:51 -0500141 return -1;
Aaron Durbin17200ad2015-05-01 16:48:54 -0500142
Aaron Durbin6d720f32015-12-08 17:00:23 -0600143 if (vb2_get_selected_region(&selected_region))
Aaron Durbin4e50cdd2015-05-15 23:25:46 -0500144 return -1;
Aaron Durbinb6981c02015-05-15 15:57:51 -0500145
Aaron Durbin6d720f32015-12-08 17:00:23 -0600146 props->offset = region_offset(&selected_region);
147 props->size = region_sz(&selected_region);
Aaron Durbin17200ad2015-05-01 16:48:54 -0500148
Aaron Durbinb6981c02015-05-15 15:57:51 -0500149 return 0;
Aaron Durbin17200ad2015-05-01 16:48:54 -0500150}
151
Aaron Durbin6d720f32015-12-08 17:00:23 -0600152const struct cbfs_locator vboot_locator = {
Aaron Durbin17200ad2015-05-01 16:48:54 -0500153 .name = "VBOOT",
Aaron Durbin6d720f32015-12-08 17:00:23 -0600154 .prepare = vboot_prepare,
Aaron Durbin899d13d2015-05-15 23:39:23 -0500155 .locate = vboot_locate,
Aaron Durbin17200ad2015-05-01 16:48:54 -0500156};