blob: 2533a1d4157f4e7af4ac22ec8565a5e4e46f434d [file] [log] [blame]
Daisuke Nojiri79cac092014-06-30 08:51:39 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 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.
Daisuke Nojiri79cac092014-06-30 08:51:39 -070014 */
15
Aaron Durbin1f0ce3a2016-11-18 09:05:18 -060016/* This needs to be pulled in first so that the handoff code below and
17 * peek into the vb2 data structures. Additionally, vboot doesn't currently
18 * include what it uses in its own headers. Provide the types it's after.
19 * TODO: fix this necessity. */
20#define NEED_VB20_INTERNALS
21#include <stddef.h>
22#include <stdint.h>
23#include <vb2_api.h>
24
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070025#include <arch/stages.h>
26#include <assert.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070027#include <bootmode.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070028#include <string.h>
29#include <cbfs.h>
30#include <cbmem.h>
31#include <console/console.h>
32#include <console/vtxprintf.h>
Aaron Durbin0424c952015-03-28 23:56:22 -050033#include <fmap.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070034#include <stdlib.h>
35#include <timestamp.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070036#include <vboot_struct.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070037#include <vboot/vbnv.h>
38#include <vboot/misc.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070039
40/**
41 * Sets vboot_handoff based on the information in vb2_shared_data
Daisuke Nojiri79cac092014-06-30 08:51:39 -070042 */
43static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070044 struct vb2_shared_data *vb2_sd)
Daisuke Nojiri79cac092014-06-30 08:51:39 -070045{
46 VbSharedDataHeader *vb_sd =
47 (VbSharedDataHeader *)vboot_handoff->shared_data;
48 uint32_t *oflags = &vboot_handoff->init_params.out_flags;
49
50 vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
51
52 vboot_handoff->selected_firmware = vb2_sd->fw_slot;
53
Daisuke Nojiri79cac092014-06-30 08:51:39 -070054 vb_sd->firmware_index = vb2_sd->fw_slot;
55
56 vb_sd->magic = VB_SHARED_DATA_MAGIC;
57 vb_sd->struct_version = VB_SHARED_DATA_VERSION;
58 vb_sd->struct_size = sizeof(VbSharedDataHeader);
59 vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
60 vb_sd->data_used = sizeof(VbSharedDataHeader);
Julius Wernere319e482015-01-29 17:50:58 -080061 vb_sd->fw_version_tpm = vb2_sd->fw_version_secdata;
Daisuke Nojiri79cac092014-06-30 08:51:39 -070062
Gediminas Ramanauskasceaabc92014-11-04 20:07:09 -080063 if (get_write_protect_state())
64 vb_sd->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED;
Paul Kocialkowskia4003272015-09-03 11:27:27 +020065 if (get_sw_write_protect_state())
Daisuke Nojiri5d8ef4c2015-07-22 11:49:17 -070066 vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED;
Gediminas Ramanauskasceaabc92014-11-04 20:07:09 -080067
Daisuke Nojiri79cac092014-06-30 08:51:39 -070068 if (vb2_sd->recovery_reason) {
69 vb_sd->firmware_index = 0xFF;
Daisuke Nojiri6ce74592015-10-21 13:31:44 -070070 if (vb2_sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY)
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070071 vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
Daisuke Nojiri79cac092014-06-30 08:51:39 -070072 *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
73 *oflags |= VB_INIT_OUT_CLEAR_RAM;
74 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
75 *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
76 }
77 if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
78 *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
79 *oflags |= VB_INIT_OUT_CLEAR_RAM;
80 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
81 *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
82 vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
83 vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
84 }
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070085 /* TODO: Set these in depthcharge */
Duncan Laurie6324de12016-01-20 13:15:12 -080086 if (IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070087 vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
Duncan Laurie6324de12016-01-20 13:15:12 -080088 if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070089 vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
Duncan Laurie6324de12016-01-20 13:15:12 -080090 if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070091 vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
Duncan Laurie6324de12016-01-20 13:15:12 -080092 if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE))
93 vb_sd->flags |= VBSD_EC_SLOW_UPDATE;
94 if (IS_ENABLED(CONFIG_VBOOT_OPROM_MATTERS)) {
95 vb_sd->flags |= VBSD_OPROM_MATTERS;
96 /*
97 * Inform vboot if the display was enabled by dev/rec
98 * mode or was requested by vboot kernel phase.
99 */
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -0700100 if ((*oflags & VB_INIT_OUT_ENABLE_DISPLAY) ||
Duncan Laurie6324de12016-01-20 13:15:12 -0800101 vboot_wants_oprom()) {
102 vb_sd->flags |= VBSD_OPROM_LOADED;
103 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
104 }
105 }
Daisuke Nojiri2624c8d2014-11-13 11:35:52 -0800106
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700107 /* In vboot1, VBSD_FWB_TRIED is
108 * set only if B is booted as explicitly requested. Therefore, if B is
109 * booted because A was found bad, the flag should not be set. It's
110 * better not to touch it if we can only ambiguously control it. */
111 /* if (vb2_sd->fw_slot)
112 vb_sd->flags |= VBSD_FWB_TRIED; */
113
114 /* copy kernel subkey if it's found */
115 if (vb2_sd->workbuf_preamble_size) {
116 struct vb2_fw_preamble *fp;
117 uintptr_t dst, src;
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700118 printk(BIOS_INFO, "Copying FW preamble\n");
Daisuke Nojiri742fc8d2014-10-10 10:51:06 -0700119 fp = (struct vb2_fw_preamble *)((uintptr_t)vb2_sd +
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700120 vb2_sd->workbuf_preamble_offset);
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700121 src = (uintptr_t)&fp->kernel_subkey +
122 fp->kernel_subkey.key_offset;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700123 dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700124 assert(dst + fp->kernel_subkey.key_size <=
125 (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
126 memcpy((void *)dst, (void *)src,
127 fp->kernel_subkey.key_size);
128 vb_sd->data_used += fp->kernel_subkey.key_size;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700129 vb_sd->kernel_subkey.key_offset =
130 dst - (uintptr_t)&vb_sd->kernel_subkey;
131 vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
132 vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700133 vb_sd->kernel_subkey.key_version =
134 fp->kernel_subkey.key_version;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700135 }
136
137 vb_sd->recovery_reason = vb2_sd->recovery_reason;
138}
139
Aaron Durbin17200ad2015-05-01 16:48:54 -0500140void vboot_fill_handoff(void)
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700141{
142 struct vboot_handoff *vh;
143 struct vb2_shared_data *sd;
144
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500145 sd = vb2_get_shared_data();
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700146 sd->workbuf_hash_offset = 0;
147 sd->workbuf_hash_size = 0;
148
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700149 printk(BIOS_INFO, "creating vboot_handoff structure\n");
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700150 vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700151 if (vh == NULL)
152 /* we don't need to failover gracefully here because this
153 * shouldn't happen with the image that has passed QA. */
154 die("failed to allocate vboot_handoff structure\n");
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700155
156 memset(vh, 0, sizeof(*vh));
157
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700158 /* needed until we finish transtion to vboot2 for kernel verification */
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700159 fill_vboot_handoff(vh, sd);
Aaron Durbind87cc3f2016-02-01 17:37:16 -0600160
Furquan Shaikh626eea22016-11-12 11:09:28 -0800161
162 /* Log the recovery mode switches if required, before clearing them. */
163 log_recovery_mode_switch();
164
Aaron Durbind87cc3f2016-02-01 17:37:16 -0600165 /*
166 * The recovery mode switch is cleared (typically backed by EC) here
167 * to allow multiple queries to get_recovery_mode_switch() and have
168 * them return consistent results during the verified boot path as well
169 * as dram initialization. x86 systems ignore the saved dram settings
170 * in the recovery path in order to start from a clean slate. Therefore
171 * clear the state here since this function is called when memory
172 * is known to be up.
173 */
174 clear_recovery_mode_switch();
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700175}
Aaron Durbinb5933662015-10-07 16:03:41 -0500176
177/*
178 * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
179 * verification doesn't happen until after cbmem is brought online.
180 * Therefore, the vboot results would not be initialized so don't
181 * automatically add results when cbmem comes online.
182 */
183#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
184static void vb2_fill_handoff_cbmem(int unused)
185{
186 vboot_fill_handoff();
187}
188ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem)
189#endif