coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ext_stage_cache.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cbmem.h>
4 #include <console/console.h>
5 #include <imd.h>
6 #include <stage_cache.h>
7 #include <string.h>
8 
9 static struct imd imd_stage_cache;
10 
11 static void stage_cache_create_empty(void)
12 {
13  struct imd *imd;
14  void *base;
15  size_t size;
16 
19  imd_handle_init(imd, (void *)(size + (uintptr_t)base));
20 
21  printk(BIOS_DEBUG, "External stage cache:\n");
22  imd_create_tiered_empty(imd, 4096, 4096, 1024, 32);
23  if (imd_limit_size(imd, size))
24  printk(BIOS_DEBUG, "Could not limit stage cache size.\n");
25 }
26 
27 static void stage_cache_recover(void)
28 {
29  struct imd *imd;
30  void *base;
31  size_t size;
32 
35  imd_handle_init(imd, (void *)(size + (uintptr_t)base));
36  if (imd_recover(imd))
37  printk(BIOS_DEBUG, "Unable to recover external stage cache.\n");
38 }
39 
40 void stage_cache_add(int stage_id, const struct prog *stage)
41 {
42  struct imd *imd;
43  const struct imd_entry *e;
44  struct stage_cache *meta;
45  void *c;
46 
48  e = imd_entry_add(imd, CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta));
49 
50  if (e == NULL) {
51  printk(BIOS_DEBUG, "Error: Can't add %x metadata to imd\n",
52  CBMEM_ID_STAGEx_META + stage_id);
53  return;
54  }
55 
56  meta = imd_entry_at(imd, e);
57 
58  meta->load_addr = (uintptr_t)prog_start(stage);
59  meta->entry_addr = (uintptr_t)prog_entry(stage);
60  meta->arg = (uintptr_t)prog_entry_arg(stage);
61 
62  e = imd_entry_add(imd, CBMEM_ID_STAGEx_CACHE + stage_id,
63  prog_size(stage));
64 
65  if (e == NULL) {
66  printk(BIOS_DEBUG, "Error: Can't add stage_cache %x to imd\n",
67  CBMEM_ID_STAGEx_CACHE + stage_id);
68  return;
69  }
70 
71  c = imd_entry_at(imd, e);
72 
73  memcpy(c, prog_start(stage), prog_size(stage));
74 }
75 
76 void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
77 {
78  struct imd *imd;
79  const struct imd_entry *e;
80  void *c;
81 
83  e = imd_entry_add(imd, CBMEM_ID_STAGEx_RAW + stage_id, size);
84  if (e == NULL) {
85  printk(BIOS_DEBUG, "Error: Can't add %x raw data to imd\n",
86  CBMEM_ID_STAGEx_RAW + stage_id);
87  return;
88  }
89 
90  c = imd_entry_at(imd, e);
91  if (c == NULL) {
92  printk(BIOS_DEBUG, "Error: Can't get %x raw entry in imd\n",
93  CBMEM_ID_STAGEx_RAW + stage_id);
94  return;
95  }
96 
97  memcpy(c, base, size);
98 }
99 
100 void stage_cache_get_raw(int stage_id, void **base, size_t *size)
101 {
102  struct imd *imd;
103  const struct imd_entry *e;
104 
105  imd = &imd_stage_cache;
106  e = imd_entry_find(imd, CBMEM_ID_STAGEx_RAW + stage_id);
107  if (e == NULL) {
108  printk(BIOS_DEBUG, "Error: Can't find %x raw data to imd\n",
109  CBMEM_ID_STAGEx_RAW + stage_id);
110  return;
111  }
112 
113  *base = imd_entry_at(imd, e);
114  *size = imd_entry_size(e);
115 }
116 
117 void stage_cache_load_stage(int stage_id, struct prog *stage)
118 {
119  struct imd *imd;
120  struct stage_cache *meta;
121  const struct imd_entry *e;
122  void *c;
123  size_t size;
124 
125  imd = &imd_stage_cache;
126  e = imd_entry_find(imd, CBMEM_ID_STAGEx_META + stage_id);
127  if (e == NULL) {
128  printk(BIOS_DEBUG, "Error: Can't find %x metadata in imd\n",
129  CBMEM_ID_STAGEx_META + stage_id);
130  return;
131  }
132 
133  meta = imd_entry_at(imd, e);
134 
135  e = imd_entry_find(imd, CBMEM_ID_STAGEx_CACHE + stage_id);
136 
137  if (e == NULL) {
138  printk(BIOS_DEBUG, "Error: Can't find stage_cache %x in imd\n",
139  CBMEM_ID_STAGEx_CACHE + stage_id);
140  return;
141  }
142 
143  c = imd_entry_at(imd, e);
144  size = imd_entry_size(e);
145 
146  memcpy((void *)(uintptr_t)meta->load_addr, c, size);
147 
148  prog_set_area(stage, (void *)(uintptr_t)meta->load_addr, size);
149  prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr,
150  (void *)(uintptr_t)meta->arg);
151 }
152 
153 static void stage_cache_setup(int is_recovery)
154 {
155  if (is_recovery)
157  else
159 }
160 
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_)
Definition: cbmem.h:134
#define CBMEM_ID_STAGEx_RAW
Definition: cbmem_id.h:58
#define CBMEM_ID_STAGEx_CACHE
Definition: cbmem_id.h:57
#define CBMEM_ID_STAGEx_META
Definition: cbmem_id.h:56
#define printk(level,...)
Definition: stdlib.h:16
POSTCAR_CBMEM_INIT_HOOK(migrate_ehci_debug)
RAMSTAGE_CBMEM_INIT_HOOK(migrate_ehci_debug)
void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
static void stage_cache_recover(void)
static struct imd imd_stage_cache
void stage_cache_get_raw(int stage_id, void **base, size_t *size)
void stage_cache_add(int stage_id, const struct prog *stage)
static void stage_cache_setup(int is_recovery)
static void stage_cache_create_empty(void)
void stage_cache_load_stage(int stage_id, struct prog *stage)
int imd_limit_size(struct imd *imd, size_t max_size)
Definition: imd.c:458
const struct imd_entry * imd_entry_find(const struct imd *imd, uint32_t id)
Definition: imd.c:536
void * imd_entry_at(const struct imd *imd, const struct imd_entry *entry)
Definition: imd.c:568
size_t imd_entry_size(const struct imd_entry *entry)
Definition: imd.c:563
int imd_recover(struct imd *imd)
Definition: imd.c:428
const struct imd_entry * imd_entry_add(const struct imd *imd, uint32_t id, size_t size)
Definition: imd.c:509
void imd_handle_init(struct imd *imd, void *upper_limit)
Definition: imd.c:352
int imd_create_tiered_empty(struct imd *imd, size_t lg_root_size, size_t lg_entry_align, size_t sm_root_size, size_t sm_entry_align)
Definition: imd.c:391
static struct imd imd
Definition: imd_cbmem.c:16
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static void * prog_entry(const struct prog *prog)
static void * prog_entry_arg(const struct prog *prog)
static void prog_set_entry(struct prog *prog, void *e, void *arg)
static void * prog_start(const struct prog *prog)
static size_t prog_size(const struct prog *prog)
static void prog_set_area(struct prog *prog, void *start, size_t size)
uintptr_t base
Definition: uart.c:17
#define NULL
Definition: stddef.h:19
unsigned long uintptr_t
Definition: stdint.h:21
Definition: imd_private.h:14
uint32_t size
Definition: imd_private.h:18
Definition: imd.h:147
uint64_t load_addr
Definition: stage_cache.h:56
uint64_t arg
Definition: stage_cache.h:58
uint64_t entry_addr
Definition: stage_cache.h:57
#define c(value, pmcreg, dst_bits)
void stage_cache_external_region(void **base, size_t *size)
Definition: tseg_region.c:61