blob: aeb44988397f302754bb799b6d7980a9b8ce1b6a [file] [log] [blame]
Daisuke Nojiri742fc8d2014-10-10 10:51:06 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
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 Nojiri742fc8d2014-10-10 10:51:06 -070014 */
15
Furquan Shaikha6c5ddd2016-07-22 06:59:40 -070016#include <assert.h>
Aaron Durbin0e571fd2015-05-08 17:14:15 -050017#include <cbmem.h>
Joel Kitching0bcee882019-02-11 15:37:49 +080018#include <console/console.h>
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080019#include <fmap.h>
Joel Kitching0bcee882019-02-11 15:37:49 +080020#include <stdint.h>
Joel Kitching0bcee882019-02-11 15:37:49 +080021#include <symbols.h>
Aaron Durbinb5a20b22015-10-06 17:29:03 -050022#include <vb2_api.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020023#include <security/vboot/misc.h>
24#include <security/vboot/symbols.h>
25#include <security/vboot/vboot_common.h>
Daisuke Nojiri742fc8d2014-10-10 10:51:06 -070026
Arthur Heymans344e86b2019-11-20 19:47:10 +010027static struct vb2_context *vboot_ctx;
Joel Kitching2332c742019-10-23 15:01:37 +080028
Yu-Ping Wu63b97002019-11-26 13:31:32 +080029static void *vboot_get_workbuf(void)
Aaron Durbinb5933662015-10-07 16:03:41 -050030{
Yu-Ping Wua2962da2019-11-26 10:47:35 +080031 void *wb = NULL;
Aaron Durbinb5933662015-10-07 16:03:41 -050032
Joel Kitching0bcee882019-02-11 15:37:49 +080033 if (cbmem_possibly_online())
Yu-Ping Wua2962da2019-11-26 10:47:35 +080034 wb = cbmem_find(CBMEM_ID_VBOOT_WORKBUF);
Aaron Durbinb5933662015-10-07 16:03:41 -050035
Yu-Ping Wua2962da2019-11-26 10:47:35 +080036 if (wb == NULL && CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) &&
Joel Kitching0bcee882019-02-11 15:37:49 +080037 preram_symbols_available())
Yu-Ping Wua2962da2019-11-26 10:47:35 +080038 wb = _vboot2_work;
Aaron Durbinb5933662015-10-07 16:03:41 -050039
Yu-Ping Wua2962da2019-11-26 10:47:35 +080040 assert(wb != NULL);
Joel Kitching0bcee882019-02-11 15:37:49 +080041
Yu-Ping Wua2962da2019-11-26 10:47:35 +080042 return wb;
Joel Kitching2332c742019-10-23 15:01:37 +080043}
44
45struct vb2_context *vboot_get_context(void)
46{
Yu-Ping Wua2962da2019-11-26 10:47:35 +080047 void *wb;
Aaron Durbinb5a20b22015-10-06 17:29:03 -050048
Joel Kitching2332c742019-10-23 15:01:37 +080049 /* Return if context has already been initialized/restored. */
Arthur Heymans344e86b2019-11-20 19:47:10 +010050 if (vboot_ctx)
51 return vboot_ctx;
Joel Kitching2332c742019-10-23 15:01:37 +080052
Yu-Ping Wua2962da2019-11-26 10:47:35 +080053 wb = vboot_get_workbuf();
Joel Kitching2332c742019-10-23 15:01:37 +080054
55 /* Restore context from a previous stage. */
56 if (vboot_logic_executed()) {
Yu-Ping Wua2962da2019-11-26 10:47:35 +080057 assert(vb2api_reinit(wb, &vboot_ctx) == VB2_SUCCESS);
Arthur Heymans344e86b2019-11-20 19:47:10 +010058 return vboot_ctx;
Joel Kitching2332c742019-10-23 15:01:37 +080059 }
60
61 assert(verification_should_run());
Aaron Durbinb5a20b22015-10-06 17:29:03 -050062
Joel Kitching2332c742019-10-23 15:01:37 +080063 /* Initialize vb2_shared_data and friends. */
Yu-Ping Wua2962da2019-11-26 10:47:35 +080064 assert(vb2api_init(wb, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE,
Arthur Heymans344e86b2019-11-20 19:47:10 +010065 &vboot_ctx) == VB2_SUCCESS);
Aaron Durbinb5a20b22015-10-06 17:29:03 -050066
Arthur Heymans344e86b2019-11-20 19:47:10 +010067 return vboot_ctx;
Daisuke Nojirie5d13782014-12-18 11:59:06 -080068}
Aaron Durbinb5a20b22015-10-06 17:29:03 -050069
Julius Wernerf8e17642019-12-12 13:23:06 -080070int vboot_locate_firmware(struct vb2_context *ctx, struct region_device *fw)
Aaron Durbinb5a20b22015-10-06 17:29:03 -050071{
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080072 const char *name;
Aaron Durbin6d720f32015-12-08 17:00:23 -060073
Yu-Ping Wuaeb652a2019-11-14 15:42:25 +080074 if (vboot_is_firmware_slot_a(ctx))
75 name = "FW_MAIN_A";
76 else
77 name = "FW_MAIN_B";
Aaron Durbin6d720f32015-12-08 17:00:23 -060078
Julius Wernerf8e17642019-12-12 13:23:06 -080079 int ret = fmap_locate_area_as_rdev(name, fw);
80 if (ret)
81 return ret;
82
83 /* Truncate area to the size that was actually signed by vboot. */
84 return rdev_chain(fw, fw, 0, vb2api_get_firmware_size(ctx));
Aaron Durbinb5a20b22015-10-06 17:29:03 -050085}
Aaron Durbinb5933662015-10-07 16:03:41 -050086
Joel Kitchingaf8471c2019-03-13 22:38:07 +080087static void vboot_setup_cbmem(int unused)
Joel Kitching0bcee882019-02-11 15:37:49 +080088{
Yu-Ping Wua2962da2019-11-26 10:47:35 +080089 const size_t cbmem_size = VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE;
90 void *wb_cbmem = cbmem_add(CBMEM_ID_VBOOT_WORKBUF, cbmem_size);
91 assert(wb_cbmem != NULL);
92 /*
93 * For platforms where VBOOT_STARTS_IN_BOOTBLOCK, vboot verification
94 * occurs before CBMEM is brought online, using pre-RAM. In order to
95 * make vboot data structures available downstream, copy vboot workbuf
96 * from SRAM/CAR into CBMEM.
97 */
98 if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK))
99 assert(vb2api_relocate(wb_cbmem, _vboot2_work, cbmem_size,
100 &vboot_ctx) == VB2_SUCCESS);
Joel Kitching0bcee882019-02-11 15:37:49 +0800101}
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800102ROMSTAGE_CBMEM_INIT_HOOK(vboot_setup_cbmem)