blob: d4dd82ffcce807f54650b2447754d6210f6f81db [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06003
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06004#include <cbmem.h>
5#include <stage_cache.h>
6#include <string.h>
Marshall Dawson0876caa2018-01-30 15:54:52 -07007#include <console/console.h>
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06008
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06009/* Stage cache uses cbmem. */
Aaron Durbin54546c92015-08-05 00:52:13 -050010void stage_cache_add(int stage_id, const struct prog *stage)
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060011{
12 struct stage_cache *meta;
13 void *c;
14
15 meta = cbmem_add(CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta));
Marshall Dawson0876caa2018-01-30 15:54:52 -070016 if (meta == NULL) {
17 printk(BIOS_ERR, "Error: Can't add %x metadata to cbmem\n",
18 CBMEM_ID_STAGEx_META + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060019 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070020 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060021 meta->load_addr = (uintptr_t)prog_start(stage);
22 meta->entry_addr = (uintptr_t)prog_entry(stage);
Kyösti Mälkkid87e4b32017-09-05 22:43:05 +030023 meta->arg = (uintptr_t)prog_entry_arg(stage);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060024
25 c = cbmem_add(CBMEM_ID_STAGEx_CACHE + stage_id, prog_size(stage));
Marshall Dawson0876caa2018-01-30 15:54:52 -070026 if (c == NULL) {
27 printk(BIOS_ERR, "Error: Can't add stage_cache %x to cbmem\n",
28 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060029 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070030 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060031
32 memcpy(c, prog_start(stage), prog_size(stage));
33}
34
Marshall Dawson8d6e0e02018-01-30 15:33:23 -070035void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
36{
37 void *c;
38
39 c = cbmem_add(CBMEM_ID_STAGEx_RAW + stage_id, size);
40 if (c == NULL) {
41 printk(BIOS_DEBUG, "Error: Can't add %x raw data to cbmem\n",
42 CBMEM_ID_STAGEx_RAW + stage_id);
43 return;
44 }
45
46 memcpy(c, base, size);
47}
48
49void stage_cache_get_raw(int stage_id, void **base, size_t *size)
50{
51 const struct cbmem_entry *e;
52
53 e = cbmem_entry_find(CBMEM_ID_STAGEx_RAW + stage_id);
54 if (e == NULL) {
55 printk(BIOS_ERR, "Error: Can't find raw %x data in cbmem\n",
56 CBMEM_ID_STAGEx_RAW + stage_id);
57 return;
58 }
59
60 *base = cbmem_entry_start(e);
61 *size = cbmem_entry_size(e);
62}
63
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060064void stage_cache_load_stage(int stage_id, struct prog *stage)
65{
66 struct stage_cache *meta;
67 const struct cbmem_entry *e;
68 void *c;
69 size_t size;
70 void *load_addr;
71
72 prog_set_entry(stage, NULL, NULL);
73
74 meta = cbmem_find(CBMEM_ID_STAGEx_META + stage_id);
Marshall Dawson0876caa2018-01-30 15:54:52 -070075 if (meta == NULL) {
76 printk(BIOS_ERR, "Error: Can't find %x metadata in cbmem\n",
77 CBMEM_ID_STAGEx_META + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060078 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070079 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060080
81 e = cbmem_entry_find(CBMEM_ID_STAGEx_CACHE + stage_id);
82
Marshall Dawson0876caa2018-01-30 15:54:52 -070083 if (e == NULL) {
84 printk(BIOS_ERR, "Error: Can't find stage_cache %x in cbmem\n",
85 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060086 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070087 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060088
89 c = cbmem_entry_start(e);
90 size = cbmem_entry_size(e);
91 load_addr = (void *)(uintptr_t)meta->load_addr;
92
93 memcpy(load_addr, c, size);
94
95 prog_set_area(stage, load_addr, size);
Kyösti Mälkkid87e4b32017-09-05 22:43:05 +030096 prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr,
97 (void *)(uintptr_t)meta->arg);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060098}