blob: 626fbc52a4521149d6ee45e6ffd267a58b194540 [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>
Joel Kitching0bcee882019-02-11 15:37:49 +080019#include <stdint.h>
Aaron Durbinb5a20b22015-10-06 17:29:03 -050020#include <string.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
Elyes HAOUASeb1dea8f2019-06-16 15:45:36 +020027struct vboot_working_data *vboot_get_working_data(void)
Aaron Durbinb5933662015-10-07 16:03:41 -050028{
Joel Kitchingaf8471c2019-03-13 22:38:07 +080029 struct vboot_working_data *wd = NULL;
Aaron Durbinb5933662015-10-07 16:03:41 -050030
Joel Kitching0bcee882019-02-11 15:37:49 +080031 if (cbmem_possibly_online())
32 wd = cbmem_find(CBMEM_ID_VBOOT_WORKBUF);
Aaron Durbinb5933662015-10-07 16:03:41 -050033
Joel Kitching0bcee882019-02-11 15:37:49 +080034 if (wd == NULL && CONFIG(VBOOT_STARTS_IN_BOOTBLOCK) &&
35 preram_symbols_available())
Joel Kitchingaf8471c2019-03-13 22:38:07 +080036 wd = (struct vboot_working_data *)_vboot2_work;
Aaron Durbinb5933662015-10-07 16:03:41 -050037
Joel Kitching0bcee882019-02-11 15:37:49 +080038 assert(wd != NULL);
39
40 return wd;
Aaron Durbinb5933662015-10-07 16:03:41 -050041}
42
Joel Kitchingaf8471c2019-03-13 22:38:07 +080043void vboot_init_work_context(struct vb2_context *ctx)
Daisuke Nojirie5d13782014-12-18 11:59:06 -080044{
Joel Kitchingaf8471c2019-03-13 22:38:07 +080045 struct vboot_working_data *wd;
Aaron Durbinb5a20b22015-10-06 17:29:03 -050046
Joel Kitching0097f552019-02-21 12:36:55 +080047 /* First initialize the working data region. */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080048 wd = vboot_get_working_data();
Joel Kitching0097f552019-02-21 12:36:55 +080049 memset(wd, 0, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE);
Aaron Durbinb5a20b22015-10-06 17:29:03 -050050
51 /*
52 * vboot prefers 16-byte alignment. This takes away 16 bytes
53 * from the VBOOT2_WORK region, but the vboot devs said that's okay.
54 */
55 wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
Joel Kitching0097f552019-02-21 12:36:55 +080056 wd->buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE
57 - wd->buffer_offset;
Aaron Durbinb5a20b22015-10-06 17:29:03 -050058
59 /* Initialize the vb2_context. */
60 memset(ctx, 0, sizeof(*ctx));
Joel Kitchingaf8471c2019-03-13 22:38:07 +080061 ctx->workbuf = (void *)vboot_get_shared_data();
Aaron Durbinb5a20b22015-10-06 17:29:03 -050062 ctx->workbuf_size = wd->buffer_size;
Joel Kitching0bcee882019-02-11 15:37:49 +080063}
Aaron Durbinb5a20b22015-10-06 17:29:03 -050064
Joel Kitchingaf8471c2019-03-13 22:38:07 +080065void vboot_finalize_work_context(struct vb2_context *ctx)
Joel Kitching0bcee882019-02-11 15:37:49 +080066{
67 /*
Joel Kitchingaf8471c2019-03-13 22:38:07 +080068 * Shrink buffer_size so that vboot_migrate_cbmem knows how
69 * much of vboot_working_data needs to be copied into CBMEM
70 * (if applicable), and so that downstream users know how much
71 * of the workbuf is currently used.
Joel Kitching0bcee882019-02-11 15:37:49 +080072 */
Joel Kitchingaf8471c2019-03-13 22:38:07 +080073 vboot_get_working_data()->buffer_size = ctx->workbuf_used;
Aaron Durbinb5a20b22015-10-06 17:29:03 -050074}
75
Joel Kitchingaf8471c2019-03-13 22:38:07 +080076struct vb2_shared_data *vboot_get_shared_data(void)
Aaron Durbinb5a20b22015-10-06 17:29:03 -050077{
Joel Kitchingaf8471c2019-03-13 22:38:07 +080078 struct vboot_working_data *wd = vboot_get_working_data();
Daisuke Nojirie5d13782014-12-18 11:59:06 -080079 return (void *)((uintptr_t)wd + wd->buffer_offset);
80}
Aaron Durbinb5a20b22015-10-06 17:29:03 -050081
Joel Kitchingaf8471c2019-03-13 22:38:07 +080082int vboot_get_selected_region(struct region *region)
Aaron Durbinb5a20b22015-10-06 17:29:03 -050083{
Joel Kitching0bcee882019-02-11 15:37:49 +080084 const struct selected_region *reg =
Joel Kitchingaf8471c2019-03-13 22:38:07 +080085 &vboot_get_working_data()->selected_region;
Aaron Durbin6d720f32015-12-08 17:00:23 -060086
87 if (reg == NULL)
88 return -1;
89
90 if (reg->offset == 0 && reg->size == 0)
91 return -1;
92
93 region->offset = reg->offset;
94 region->size = reg->size;
95
96 return 0;
Aaron Durbinb5a20b22015-10-06 17:29:03 -050097}
98
Joel Kitchingaf8471c2019-03-13 22:38:07 +080099void vboot_set_selected_region(const struct region *region)
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500100{
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800101 struct selected_region *reg =
102 &vboot_get_working_data()->selected_region;
Furquan Shaikha6c5ddd2016-07-22 06:59:40 -0700103
104 assert(reg != NULL);
105
Aaron Durbin6d720f32015-12-08 17:00:23 -0600106 reg->offset = region_offset(region);
107 reg->size = region_sz(region);
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500108}
109
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800110int vboot_is_slot_selected(void)
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500111{
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800112 struct selected_region *reg =
113 &vboot_get_working_data()->selected_region;
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500114
Furquan Shaikha6c5ddd2016-07-22 06:59:40 -0700115 assert(reg != NULL);
116
117 return reg->size > 0;
Aaron Durbinb5a20b22015-10-06 17:29:03 -0500118}
Aaron Durbinb5933662015-10-07 16:03:41 -0500119
Julius Wernereda20b62019-07-01 16:44:01 -0700120#if CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)
Aaron Durbinb5933662015-10-07 16:03:41 -0500121/*
Joel Kitching0bcee882019-02-11 15:37:49 +0800122 * For platforms that do not employ VBOOT_STARTS_IN_ROMSTAGE, vboot
123 * verification occurs before CBMEM is brought online, using pre-RAM.
124 * In order to make vboot data structures available downstream, copy
Julius Wernereda20b62019-07-01 16:44:01 -0700125 * vboot_working_data from SRAM/CAR into CBMEM.
Aaron Durbinb5933662015-10-07 16:03:41 -0500126 */
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800127static void vboot_migrate_cbmem(int unused)
Aaron Durbinb5933662015-10-07 16:03:41 -0500128{
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800129 const struct vboot_working_data *wd_preram =
130 (struct vboot_working_data *)_vboot2_work;
Joel Kitching0bcee882019-02-11 15:37:49 +0800131 size_t cbmem_size = wd_preram->buffer_offset + wd_preram->buffer_size;
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800132 struct vboot_working_data *wd_cbmem =
Joel Kitching0bcee882019-02-11 15:37:49 +0800133 cbmem_add(CBMEM_ID_VBOOT_WORKBUF, cbmem_size);
Joel Kitching51ffa7e2019-03-16 16:58:27 +0800134 assert(wd_cbmem != NULL);
135
Joel Kitching0bcee882019-02-11 15:37:49 +0800136 printk(BIOS_DEBUG,
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800137 "VBOOT: copying vboot_working_data (%zu bytes) to CBMEM...\n",
Joel Kitching0bcee882019-02-11 15:37:49 +0800138 cbmem_size);
139 memcpy(wd_cbmem, wd_preram, cbmem_size);
Aaron Durbinb5933662015-10-07 16:03:41 -0500140}
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800141ROMSTAGE_CBMEM_INIT_HOOK(vboot_migrate_cbmem)
Julius Wernereda20b62019-07-01 16:44:01 -0700142#else
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800143static void vboot_setup_cbmem(int unused)
Joel Kitching0bcee882019-02-11 15:37:49 +0800144{
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800145 struct vboot_working_data *wd_cbmem =
Joel Kitching0097f552019-02-21 12:36:55 +0800146 cbmem_add(CBMEM_ID_VBOOT_WORKBUF,
147 VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE);
Joel Kitching0bcee882019-02-11 15:37:49 +0800148 assert(wd_cbmem != NULL);
149}
Joel Kitchingaf8471c2019-03-13 22:38:07 +0800150ROMSTAGE_CBMEM_INIT_HOOK(vboot_setup_cbmem)
Aaron Durbinb5933662015-10-07 16:03:41 -0500151#endif