blob: b0bd04ca1658244218511ee7f26b1320837c9765 [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
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070016#include <arch/stages.h>
17#include <assert.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070018#include <bootmode.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070019#include <stdint.h>
20#include <stddef.h>
21#include <string.h>
22#include <cbfs.h>
23#include <cbmem.h>
24#include <console/console.h>
25#include <console/vtxprintf.h>
Aaron Durbin0424c952015-03-28 23:56:22 -050026#include <fmap.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070027#include <stdlib.h>
28#include <timestamp.h>
Randall Spangler144c2282014-12-03 17:35:53 -080029#define NEED_VB20_INTERNALS /* TODO: remove me! */
30#include <vb2_api.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070031#include <vboot_struct.h>
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070032#include <vboot/vbnv.h>
33#include <vboot/misc.h>
Daisuke Nojiri79cac092014-06-30 08:51:39 -070034
35/**
36 * Sets vboot_handoff based on the information in vb2_shared_data
Daisuke Nojiri79cac092014-06-30 08:51:39 -070037 */
38static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070039 struct vb2_shared_data *vb2_sd)
Daisuke Nojiri79cac092014-06-30 08:51:39 -070040{
41 VbSharedDataHeader *vb_sd =
42 (VbSharedDataHeader *)vboot_handoff->shared_data;
43 uint32_t *oflags = &vboot_handoff->init_params.out_flags;
44
45 vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
46
47 vboot_handoff->selected_firmware = vb2_sd->fw_slot;
48
Daisuke Nojiri79cac092014-06-30 08:51:39 -070049 vb_sd->firmware_index = vb2_sd->fw_slot;
50
51 vb_sd->magic = VB_SHARED_DATA_MAGIC;
52 vb_sd->struct_version = VB_SHARED_DATA_VERSION;
53 vb_sd->struct_size = sizeof(VbSharedDataHeader);
54 vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
55 vb_sd->data_used = sizeof(VbSharedDataHeader);
Julius Wernere319e482015-01-29 17:50:58 -080056 vb_sd->fw_version_tpm = vb2_sd->fw_version_secdata;
Daisuke Nojiri79cac092014-06-30 08:51:39 -070057
Gediminas Ramanauskasceaabc92014-11-04 20:07:09 -080058 if (get_write_protect_state())
59 vb_sd->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED;
Paul Kocialkowskia4003272015-09-03 11:27:27 +020060 if (get_sw_write_protect_state())
Daisuke Nojiri5d8ef4c2015-07-22 11:49:17 -070061 vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED;
Gediminas Ramanauskasceaabc92014-11-04 20:07:09 -080062
Daisuke Nojiri79cac092014-06-30 08:51:39 -070063 if (vb2_sd->recovery_reason) {
64 vb_sd->firmware_index = 0xFF;
Daisuke Nojiri6ce74592015-10-21 13:31:44 -070065 if (vb2_sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY)
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070066 vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
Daisuke Nojiri79cac092014-06-30 08:51:39 -070067 *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
68 *oflags |= VB_INIT_OUT_CLEAR_RAM;
69 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
70 *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
71 }
72 if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
73 *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
74 *oflags |= VB_INIT_OUT_CLEAR_RAM;
75 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
76 *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
77 vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
78 vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
79 }
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -070080 /* TODO: Set these in depthcharge */
Duncan Laurie6324de12016-01-20 13:15:12 -080081 if (IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070082 vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
Duncan Laurie6324de12016-01-20 13:15:12 -080083 if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070084 vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
Duncan Laurie6324de12016-01-20 13:15:12 -080085 if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH))
Daisuke Nojiri79cac092014-06-30 08:51:39 -070086 vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
Duncan Laurie6324de12016-01-20 13:15:12 -080087 if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE))
88 vb_sd->flags |= VBSD_EC_SLOW_UPDATE;
89 if (IS_ENABLED(CONFIG_VBOOT_OPROM_MATTERS)) {
90 vb_sd->flags |= VBSD_OPROM_MATTERS;
91 /*
92 * Inform vboot if the display was enabled by dev/rec
93 * mode or was requested by vboot kernel phase.
94 */
Furquan Shaikh2a12e2e2016-07-25 11:48:03 -070095 if ((*oflags & VB_INIT_OUT_ENABLE_DISPLAY) ||
Duncan Laurie6324de12016-01-20 13:15:12 -080096 vboot_wants_oprom()) {
97 vb_sd->flags |= VBSD_OPROM_LOADED;
98 *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
99 }
100 }
Daisuke Nojiri2624c8d2014-11-13 11:35:52 -0800101
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700102 /* In vboot1, VBSD_FWB_TRIED is
103 * set only if B is booted as explicitly requested. Therefore, if B is
104 * booted because A was found bad, the flag should not be set. It's
105 * better not to touch it if we can only ambiguously control it. */
106 /* if (vb2_sd->fw_slot)
107 vb_sd->flags |= VBSD_FWB_TRIED; */
108
109 /* copy kernel subkey if it's found */
110 if (vb2_sd->workbuf_preamble_size) {
111 struct vb2_fw_preamble *fp;
112 uintptr_t dst, src;
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700113 printk(BIOS_INFO, "Copying FW preamble\n");
Daisuke Nojiri742fc8d2014-10-10 10:51:06 -0700114 fp = (struct vb2_fw_preamble *)((uintptr_t)vb2_sd +
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700115 vb2_sd->workbuf_preamble_offset);
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700116 src = (uintptr_t)&fp->kernel_subkey +
117 fp->kernel_subkey.key_offset;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700118 dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700119 assert(dst + fp->kernel_subkey.key_size <=
120 (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
121 memcpy((void *)dst, (void *)src,
122 fp->kernel_subkey.key_size);
123 vb_sd->data_used += fp->kernel_subkey.key_size;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700124 vb_sd->kernel_subkey.key_offset =
125 dst - (uintptr_t)&vb_sd->kernel_subkey;
126 vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
127 vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700128 vb_sd->kernel_subkey.key_version =
129 fp->kernel_subkey.key_version;
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700130 }
131
132 vb_sd->recovery_reason = vb2_sd->recovery_reason;
133}
134
Aaron Durbin17200ad2015-05-01 16:48:54 -0500135void vboot_fill_handoff(void)
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700136{
137 struct vboot_handoff *vh;
138 struct vb2_shared_data *sd;
139
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500140 sd = vb2_get_shared_data();
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700141 sd->workbuf_hash_offset = 0;
142 sd->workbuf_hash_size = 0;
143
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700144 printk(BIOS_INFO, "creating vboot_handoff structure\n");
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700145 vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700146 if (vh == NULL)
147 /* we don't need to failover gracefully here because this
148 * shouldn't happen with the image that has passed QA. */
149 die("failed to allocate vboot_handoff structure\n");
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700150
151 memset(vh, 0, sizeof(*vh));
152
Daisuke Nojiriefddcfb2014-09-04 09:55:34 -0700153 /* needed until we finish transtion to vboot2 for kernel verification */
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700154 fill_vboot_handoff(vh, sd);
Aaron Durbind87cc3f2016-02-01 17:37:16 -0600155
156 /*
157 * The recovery mode switch is cleared (typically backed by EC) here
158 * to allow multiple queries to get_recovery_mode_switch() and have
159 * them return consistent results during the verified boot path as well
160 * as dram initialization. x86 systems ignore the saved dram settings
161 * in the recovery path in order to start from a clean slate. Therefore
162 * clear the state here since this function is called when memory
163 * is known to be up.
164 */
165 clear_recovery_mode_switch();
Daisuke Nojiri79cac092014-06-30 08:51:39 -0700166}
Aaron Durbinb5933662015-10-07 16:03:41 -0500167
168/*
169 * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
170 * verification doesn't happen until after cbmem is brought online.
171 * Therefore, the vboot results would not be initialized so don't
172 * automatically add results when cbmem comes online.
173 */
174#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
175static void vb2_fill_handoff_cbmem(int unused)
176{
177 vboot_fill_handoff();
178}
179ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem)
180#endif