blob: 5e76fb0801f28a66c99b9e4a474f12df0e0d5fd6 [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06002
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06003#include <cbmem.h>
4#include <stage_cache.h>
5#include <string.h>
Marshall Dawson0876caa2018-01-30 15:54:52 -07006#include <console/console.h>
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06007
Aaron Durbinbd74a4b2015-03-06 23:17:33 -06008/* Stage cache uses cbmem. */
Aaron Durbin54546c92015-08-05 00:52:13 -05009void stage_cache_add(int stage_id, const struct prog *stage)
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060010{
11 struct stage_cache *meta;
12 void *c;
13
14 meta = cbmem_add(CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta));
Marshall Dawson0876caa2018-01-30 15:54:52 -070015 if (meta == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080016 printk(BIOS_ERR, "Can't add %x metadata to cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070017 CBMEM_ID_STAGEx_META + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060018 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070019 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060020 meta->load_addr = (uintptr_t)prog_start(stage);
21 meta->entry_addr = (uintptr_t)prog_entry(stage);
Kyösti Mälkkid87e4b32017-09-05 22:43:05 +030022 meta->arg = (uintptr_t)prog_entry_arg(stage);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060023
Patrick Georgied0647a2023-12-13 17:57:34 +010024 unsigned int p_size = prog_size(stage);
25 if (stage_id == STAGE_RAMSTAGE) {
26 /* heap resides at the end of the image and will be
27 reinitialized, so it doesn't make sense to copy it around. */
28 p_size -= CONFIG_HEAP_SIZE;
29 }
30
31 c = cbmem_add(CBMEM_ID_STAGEx_CACHE + stage_id, p_size);
Marshall Dawson0876caa2018-01-30 15:54:52 -070032 if (c == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080033 printk(BIOS_ERR, "Can't add stage_cache %x to cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070034 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060035 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070036 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060037
Patrick Georgied0647a2023-12-13 17:57:34 +010038 memcpy(c, prog_start(stage), p_size);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060039}
40
Marshall Dawson8d6e0e02018-01-30 15:33:23 -070041void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
42{
43 void *c;
44
45 c = cbmem_add(CBMEM_ID_STAGEx_RAW + stage_id, size);
46 if (c == NULL) {
47 printk(BIOS_DEBUG, "Error: Can't add %x raw data to cbmem\n",
48 CBMEM_ID_STAGEx_RAW + stage_id);
49 return;
50 }
51
52 memcpy(c, base, size);
53}
54
55void stage_cache_get_raw(int stage_id, void **base, size_t *size)
56{
57 const struct cbmem_entry *e;
58
59 e = cbmem_entry_find(CBMEM_ID_STAGEx_RAW + stage_id);
60 if (e == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080061 printk(BIOS_ERR, "Can't find raw %x data in cbmem\n",
Marshall Dawson8d6e0e02018-01-30 15:33:23 -070062 CBMEM_ID_STAGEx_RAW + stage_id);
63 return;
64 }
65
66 *base = cbmem_entry_start(e);
67 *size = cbmem_entry_size(e);
68}
69
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060070void stage_cache_load_stage(int stage_id, struct prog *stage)
71{
72 struct stage_cache *meta;
73 const struct cbmem_entry *e;
74 void *c;
75 size_t size;
76 void *load_addr;
77
78 prog_set_entry(stage, NULL, NULL);
79
80 meta = cbmem_find(CBMEM_ID_STAGEx_META + stage_id);
Marshall Dawson0876caa2018-01-30 15:54:52 -070081 if (meta == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080082 printk(BIOS_ERR, "Can't find %x metadata in cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070083 CBMEM_ID_STAGEx_META + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060084 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070085 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060086
87 e = cbmem_entry_find(CBMEM_ID_STAGEx_CACHE + stage_id);
88
Marshall Dawson0876caa2018-01-30 15:54:52 -070089 if (e == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080090 printk(BIOS_ERR, "Can't find stage_cache %x in cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070091 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060092 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070093 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060094
95 c = cbmem_entry_start(e);
96 size = cbmem_entry_size(e);
97 load_addr = (void *)(uintptr_t)meta->load_addr;
98
99 memcpy(load_addr, c, size);
100
101 prog_set_area(stage, load_addr, size);
Kyösti Mälkkid87e4b32017-09-05 22:43:05 +0300102 prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr,
103 (void *)(uintptr_t)meta->arg);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -0600104}