blob: b45c9505f8ae537ba8f5cd7327209680837262ff [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
24 c = cbmem_add(CBMEM_ID_STAGEx_CACHE + stage_id, prog_size(stage));
Marshall Dawson0876caa2018-01-30 15:54:52 -070025 if (c == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080026 printk(BIOS_ERR, "Can't add stage_cache %x to cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070027 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060028 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070029 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060030
31 memcpy(c, prog_start(stage), prog_size(stage));
32}
33
Marshall Dawson8d6e0e02018-01-30 15:33:23 -070034void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
35{
36 void *c;
37
38 c = cbmem_add(CBMEM_ID_STAGEx_RAW + stage_id, size);
39 if (c == NULL) {
40 printk(BIOS_DEBUG, "Error: Can't add %x raw data to cbmem\n",
41 CBMEM_ID_STAGEx_RAW + stage_id);
42 return;
43 }
44
45 memcpy(c, base, size);
46}
47
48void stage_cache_get_raw(int stage_id, void **base, size_t *size)
49{
50 const struct cbmem_entry *e;
51
52 e = cbmem_entry_find(CBMEM_ID_STAGEx_RAW + stage_id);
53 if (e == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080054 printk(BIOS_ERR, "Can't find raw %x data in cbmem\n",
Marshall Dawson8d6e0e02018-01-30 15:33:23 -070055 CBMEM_ID_STAGEx_RAW + stage_id);
56 return;
57 }
58
59 *base = cbmem_entry_start(e);
60 *size = cbmem_entry_size(e);
61}
62
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060063void stage_cache_load_stage(int stage_id, struct prog *stage)
64{
65 struct stage_cache *meta;
66 const struct cbmem_entry *e;
67 void *c;
68 size_t size;
69 void *load_addr;
70
71 prog_set_entry(stage, NULL, NULL);
72
73 meta = cbmem_find(CBMEM_ID_STAGEx_META + stage_id);
Marshall Dawson0876caa2018-01-30 15:54:52 -070074 if (meta == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080075 printk(BIOS_ERR, "Can't find %x metadata in cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070076 CBMEM_ID_STAGEx_META + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060077 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070078 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060079
80 e = cbmem_entry_find(CBMEM_ID_STAGEx_CACHE + stage_id);
81
Marshall Dawson0876caa2018-01-30 15:54:52 -070082 if (e == NULL) {
Julius Wernere9665952022-01-21 17:06:20 -080083 printk(BIOS_ERR, "Can't find stage_cache %x in cbmem\n",
Marshall Dawson0876caa2018-01-30 15:54:52 -070084 CBMEM_ID_STAGEx_CACHE + stage_id);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060085 return;
Marshall Dawson0876caa2018-01-30 15:54:52 -070086 }
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060087
88 c = cbmem_entry_start(e);
89 size = cbmem_entry_size(e);
90 load_addr = (void *)(uintptr_t)meta->load_addr;
91
92 memcpy(load_addr, c, size);
93
94 prog_set_area(stage, load_addr, size);
Kyösti Mälkkid87e4b32017-09-05 22:43:05 +030095 prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr,
96 (void *)(uintptr_t)meta->arg);
Aaron Durbinbd74a4b2015-03-06 23:17:33 -060097}