coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
cbfs.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _CBFS_H_
4 #define _CBFS_H_
5 
6 #include <cbmem.h>
8 #include <commonlib/mem_pool.h>
9 #include <commonlib/region.h>
10 #include <endian.h>
11 #include <program_loading.h>
12 #include <types.h>
13 #include <vb2_sha.h>
14 
15 
16 /**********************************************************************************************
17  * CBFS FILE ACCESS APIs *
18  **********************************************************************************************/
19 
20 /*
21  * These are the APIs used to access files in CBFS. In order to keep the calls simple and free
22  * of clutter in the common cases, but still offer all advanced functionality when needed, there
23  * are many different variations that are implemented by wrapping the same underlying API with
24  * static inlines. All accessors have in common that they look up files by name, and will
25  * transparently decompress files that are compressed.
26  *
27  * There are three main flavors of CBFS accessors:
28  *
29  * size_t cbfs_load(char *name, void *buf, size_t size): Loads the contents of a CBFS file into
30  * a buffer provided by the caller (by providing pointer and size to it). Will return the
31  * amount of bytes loaded on success, or 0 on error.
32  *
33  * void *cbfs_map(char *name, size_t *size_out): Maps a file into the address space. If the file
34  * is not compressed and the platform supports direct memory-mapping for the boot medium,
35  * a pointer to the platform mapping is returned directly. In all other cases, memory will
36  * be allocated from the cbfs_cache and file data will be loaded into there. Returns a
37  * pointer to the mapping on success, or NULL on error. If an optional size_out parameter
38  * is passed in, it will be filled out with the size of the mapped data. Caller should call
39  * cbfs_unmap() after it is done using the mapping to free up the cbfs_cache if possible.
40  *
41  * void *cbfs_alloc(char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out): Loads
42  * file data into memory provided by a custom allocator function that the caller passes in.
43  * The caller may pass an argument that is passed through verbatim to the allocator.
44  * Returns the pointer returned by the allocator (where the file data was loaded to) on
45  * success, or NULL on error. If an optional size_out parameter is passed in, it will be
46  * filled out with the size of the loaded data.
47  *
48  * void *cbfs_cbmem_alloc(char *name, uint32_t cbmem_id, size_t *size_out): Wrapper around
49  * cbfs_alloc() that will provide an allocator function for allocating space for the file
50  * data in CBMEM, with the provided CBMEM ID.
51  *
52  * All of these flavors have variations with any of the following optional parameters added:
53  *
54  * ..._ro_...: Will force looking up the CBFS file in the read-only CBFS (the "COREBOOT" FMAP
55  * section), even when running in an RW stage from one of the RW CBFSs. Only relevant if
56  * CONFIG(VBOOT) is set.
57  *
58  * ..._unverified_area_...: Will look for the CBFS file in the named FMAP area, rather than
59  * any of the default (RO or RW) CBFSs. Files accessed this way are *not* verified in any
60  * way (even if CONFIG(CBFS_VERIFICATION) is enabled) and should always be treated as
61  * untrusted (potentially malicious) data. Mutually exclusive with the ..._ro_... variant.
62  *
63  * ..._type_...: May pass in an extra enum cbfs_type *type parameter. If the value it points to
64  * is CBFS_TYPE_QUERY, it will be replaced with the actual CBFS type of the found file. If
65  * it is anything else, the type will be compared with the actually found type, and the
66  * operation will fail if they don't match.
67  */
68 
69 /*
70  * An allocator function for passing to cbfs_alloc(). Takes the argument that was originally
71  * passed to cbfs_alloc(), the size of the file to be loaded, and a pointer to the already
72  * loaded and verified file metadata (for rare cases where the allocator needs to check custom
73  * attributes). Must return a pointer to space of the requested size where the file data should
74  * be loaded, or NULL to make the operation fail.
75  */
76 typedef void *(*cbfs_allocator_t)(void *arg, size_t size, const union cbfs_mdata *mdata);
77 
78 static inline size_t cbfs_load(const char *name, void *buf, size_t size);
79 static inline size_t cbfs_ro_load(const char *name, void *buf, size_t size);
80 static inline size_t cbfs_type_load(const char *name, void *buf, size_t size,
81  enum cbfs_type *type);
82 static inline size_t cbfs_ro_type_load(const char *name, void *buf, size_t size,
83  enum cbfs_type *type);
84 static inline size_t cbfs_unverified_area_load(const char *area, const char *name,
85  void *buf, size_t size);
86 
87 static inline void *cbfs_map(const char *name, size_t *size_out);
88 static inline void *cbfs_ro_map(const char *name, size_t *size_out);
89 static inline void *cbfs_type_map(const char *name, size_t *size_out, enum cbfs_type *type);
90 static inline void *cbfs_ro_type_map(const char *name, size_t *size_out, enum cbfs_type *type);
91 static inline void *cbfs_unverified_area_map(const char *area, const char *name,
92  size_t *size_out);
93 
94 static inline void *cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
95  size_t *size_out);
96 static inline void *cbfs_ro_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
97  size_t *size_out);
98 static inline void *cbfs_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
99  size_t *size_out, enum cbfs_type *type);
100 static inline void *cbfs_ro_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
101  size_t *size_out, enum cbfs_type *type);
102 static inline void *cbfs_unverified_area_alloc(const char *area, const char *name,
103  cbfs_allocator_t allocator, void *arg,
104  size_t *size_out);
105 
106 static inline void *cbfs_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out);
107 static inline void *cbfs_ro_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out);
108 static inline void *cbfs_type_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out,
109  enum cbfs_type *type);
110 static inline void *cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id,
111  size_t *size_out, enum cbfs_type *type);
112 static inline void *cbfs_unverified_area_cbmem_alloc(const char *area, const char *name,
113  uint32_t cbmem_id, size_t *size_out);
114 
115 /*
116  * Starts the processes of preloading a file into RAM.
117  *
118  * This method depends on COOP_MULTITASKING to parallelize the loading. This method is only
119  * effective when the underlying rdev supports DMA operations.
120  *
121  * When `cbfs_load`, `cbfs_alloc`, or `cbfs_map` are called after a preload has been started,
122  * they will wait for the preload to complete (if it hasn't already) and then perform
123  * verification and/or decompression.
124  *
125  * This method does not have a return value because the system should boot regardless if this
126  * method succeeds or fails.
127  */
128 void cbfs_preload(const char *name);
129 
130 /* Removes a previously allocated CBFS mapping. Should try to unmap mappings in strict LIFO
131  order where possible, since mapping backends often don't support more complicated cases. */
132 void cbfs_unmap(void *mapping);
133 
134 /* Load stage into memory filling in prog. Return 0 on success. < 0 on error. */
135 enum cb_err cbfs_prog_stage_load(struct prog *prog);
136 
137 /* Returns the size of a CBFS file, or 0 on error. Avoid using this function to allocate space,
138  and instead use cbfs_alloc() so the file only needs to be looked up once. */
139 static inline size_t cbfs_get_size(const char *name);
140 static inline size_t cbfs_ro_get_size(const char *name);
141 
142 /* Returns the type of a CBFS file, or CBFS_TYPE_NULL on error. Use cbfs_type_load() instead of
143  this where possible to avoid looking up the file more than once. */
144 static inline enum cbfs_type cbfs_get_type(const char *name);
145 static inline enum cbfs_type cbfs_ro_get_type(const char *name);
146 
147 /* Check whether a CBFS file exists. */
148 static inline bool cbfs_file_exists(const char *name);
149 static inline bool cbfs_ro_file_exists(const char *name);
150 
151 
152 /**********************************************************************************************
153  * BOOT DEVICE HELPER APIs *
154  **********************************************************************************************/
155 
156 /*
157  * The shared memory pool for backing mapped CBFS files, and other CBFS allocation needs.
158  */
159 extern struct mem_pool cbfs_cache;
160 
161 /*
162  * Data structure that represents "a" CBFS boot device, with optional metadata cache. Generally
163  * we only have one of these, or two (RO and RW) when CONFIG(VBOOT) is set. The region device
164  * stored here must always be a subregion of boot_device_ro().
165  */
167  struct region_device rdev;
168  void *mcache;
169  size_t mcache_size;
170 };
171 
172 /* Helper to fill out |mcache| and |mcache_size| in a cbfs_boot_device. */
174 
175 /*
176  * Retrieves the currently active CBFS boot device. If |force_ro| is set, will always return the
177  * read-only CBFS instead (this only makes a difference when CONFIG(VBOOT) is enabled). May
178  * perform certain CBFS initialization tasks. Returns NULL on error (e.g. boot device IO error).
179  */
180 const struct cbfs_boot_device *cbfs_get_boot_device(bool force_ro);
181 
182 /*
183  * Builds the mcache (if |cbd->mcache| is set) and verifies |metadata_hash| (if it is not NULL).
184  * If CB_CBFS_CACHE_FULL is returned, the mcache is incomplete but still valid and the metadata
185  * hash was still verified. Should be called once per *boot* (not once per stage) before the
186  * first CBFS access.
187  */
188 enum cb_err cbfs_init_boot_device(const struct cbfs_boot_device *cbd,
189  struct vb2_hash *metadata_hash);
190 
191 
192 /**********************************************************************************************
193  * INTERNAL HELPERS FOR INLINES, DO NOT USE. *
194  **********************************************************************************************/
195 enum cb_err _cbfs_boot_lookup(const char *name, bool force_ro,
196  union cbfs_mdata *mdata, struct region_device *rdev);
197 
198 void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
199  size_t *size_out, bool force_ro, enum cbfs_type *type);
200 
201 void *_cbfs_unverified_area_alloc(const char *area, const char *name,
202  cbfs_allocator_t allocator, void *arg, size_t *size_out);
203 
205  void *buf;
206  size_t buf_size;
207 };
208 void *_cbfs_default_allocator(void *arg, size_t size, const union cbfs_mdata *unused);
209 
210 void *_cbfs_cbmem_allocator(void *arg, size_t size, const union cbfs_mdata *unused);
211 
212 /**********************************************************************************************
213  * INLINE IMPLEMENTATIONS *
214  **********************************************************************************************/
215 static inline void *cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
216  size_t *size_out)
217 {
218  return cbfs_type_alloc(name, allocator, arg, size_out, NULL);
219 }
220 
221 static inline void *cbfs_ro_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
222  size_t *size_out)
223 {
224  return cbfs_ro_type_alloc(name, allocator, arg, size_out, NULL);
225 }
226 
227 static inline void *cbfs_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
228  size_t *size_out, enum cbfs_type *type)
229 {
230  return _cbfs_alloc(name, allocator, arg, size_out, false, type);
231 }
232 
233 static inline void *cbfs_ro_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
234  size_t *size_out, enum cbfs_type *type)
235 {
236  return _cbfs_alloc(name, allocator, arg, size_out, true, type);
237 }
238 
239 static inline void *cbfs_unverified_area_alloc(const char *area, const char *name,
240  cbfs_allocator_t allocator, void *arg,
241  size_t *size_out)
242 {
243  return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out);
244 }
245 
246 static inline void *cbfs_map(const char *name, size_t *size_out)
247 {
248  return cbfs_type_map(name, size_out, NULL);
249 }
250 
251 static inline void *cbfs_ro_map(const char *name, size_t *size_out)
252 {
253  return cbfs_ro_type_map(name, size_out, NULL);
254 }
255 
256 static inline void *cbfs_type_map(const char *name, size_t *size_out, enum cbfs_type *type)
257 {
258  return cbfs_type_alloc(name, NULL, NULL, size_out, type);
259 }
260 
261 static inline void *cbfs_ro_type_map(const char *name, size_t *size_out, enum cbfs_type *type)
262 {
263  return cbfs_ro_type_alloc(name, NULL, NULL, size_out, type);
264 }
265 
266 static inline void *cbfs_unverified_area_map(const char *area, const char *name,
267  size_t *size_out)
268 {
269  return _cbfs_unverified_area_alloc(area, name, NULL, NULL, size_out);
270 }
271 
272 static inline size_t _cbfs_load(const char *name, void *buf, size_t size, bool force_ro,
273  enum cbfs_type *type)
274 {
275  struct _cbfs_default_allocator_arg arg = { .buf = buf, .buf_size = size };
276  if (_cbfs_alloc(name, _cbfs_default_allocator, &arg, &size, force_ro, type))
277  return size;
278  else
279  return 0;
280 }
281 
282 static inline size_t cbfs_load(const char *name, void *buf, size_t size)
283 {
284  return cbfs_type_load(name, buf, size, NULL);
285 }
286 
287 static inline size_t cbfs_type_load(const char *name, void *buf, size_t size,
288  enum cbfs_type *type)
289 {
290  return _cbfs_load(name, buf, size, false, type);
291 }
292 
293 static inline size_t cbfs_ro_load(const char *name, void *buf, size_t size)
294 {
295  return cbfs_ro_type_load(name, buf, size, NULL);
296 }
297 
298 static inline size_t cbfs_ro_type_load(const char *name, void *buf, size_t size,
299  enum cbfs_type *type)
300 {
301  return _cbfs_load(name, buf, size, true, type);
302 }
303 
304 static inline size_t cbfs_unverified_area_load(const char *area, const char *name,
305  void *buf, size_t size)
306 {
307  struct _cbfs_default_allocator_arg arg = { .buf = buf, .buf_size = size };
309  return size;
310  else
311  return 0;
312 }
313 
314 static inline void *cbfs_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out)
315 {
316  return cbfs_type_cbmem_alloc(name, cbmem_id, size_out, NULL);
317 }
318 
319 static inline void *cbfs_ro_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out)
320 {
321  return cbfs_ro_type_cbmem_alloc(name, cbmem_id, size_out, NULL);
322 }
323 
324 static inline void *cbfs_type_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out,
325  enum cbfs_type *type)
326 {
327  return cbfs_type_alloc(name, _cbfs_cbmem_allocator, (void *)(uintptr_t)cbmem_id,
328  size_out, type);
329 }
330 
331 static inline void *cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id,
332  size_t *size_out, enum cbfs_type *type)
333 {
334  return cbfs_ro_type_alloc(name, _cbfs_cbmem_allocator, (void *)(uintptr_t)cbmem_id,
335  size_out, type);
336 }
337 
338 static inline void *cbfs_unverified_area_cbmem_alloc(const char *area, const char *name,
339  uint32_t cbmem_id, size_t *size_out)
340 {
342  (void *)(uintptr_t)cbmem_id, size_out);
343 }
344 
345 static inline size_t cbfs_get_size(const char *name)
346 {
347  union cbfs_mdata mdata;
348  struct region_device rdev;
349  if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
350  return 0;
351  return be32toh(mdata.h.len);
352 }
353 
354 static inline size_t cbfs_ro_get_size(const char *name)
355 {
356  union cbfs_mdata mdata;
357  struct region_device rdev;
358  if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
359  return 0;
360  return be32toh(mdata.h.len);
361 }
362 
363 static inline enum cbfs_type cbfs_get_type(const char *name)
364 {
365  union cbfs_mdata mdata;
366  struct region_device rdev;
367  if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
368  return CBFS_TYPE_NULL;
369  return be32toh(mdata.h.type);
370 }
371 
372 static inline enum cbfs_type cbfs_ro_get_type(const char *name)
373 {
374  union cbfs_mdata mdata;
375  struct region_device rdev;
376  if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
377  return CBFS_TYPE_NULL;
378  return be32toh(mdata.h.type);
379 }
380 
381 static inline bool cbfs_file_exists(const char *name)
382 {
383  union cbfs_mdata mdata;
384  struct region_device rdev;
385  if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
386  return false;
387  return true;
388 }
389 
390 static inline bool cbfs_ro_file_exists(const char *name)
391 {
392  union cbfs_mdata mdata;
393  struct region_device rdev;
394  if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
395  return false;
396  return true;
397 }
398 
399 #endif
const char * name
Definition: mmu.c:92
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
void cbfs_unmap(void *mapping)
Definition: cbfs.c:86
struct mem_pool cbfs_cache
Definition: cbfs.c:26
static size_t _cbfs_load(const char *name, void *buf, size_t size, bool force_ro, enum cbfs_type *type)
Definition: cbfs.h:272
static void * cbfs_unverified_area_alloc(const char *area, const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out)
Definition: cbfs.h:239
static void * cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:331
static bool cbfs_file_exists(const char *name)
Definition: cbfs.h:381
static void * cbfs_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:227
static void * cbfs_ro_type_map(const char *name, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:261
void cbfs_boot_device_find_mcache(struct cbfs_boot_device *cbd, uint32_t id)
Definition: cbfs.c:588
static void * cbfs_unverified_area_cbmem_alloc(const char *area, const char *name, uint32_t cbmem_id, size_t *size_out)
Definition: cbfs.h:338
static void * cbfs_ro_map(const char *name, size_t *size_out)
Definition: cbfs.h:251
static size_t cbfs_get_size(const char *name)
Definition: cbfs.h:345
void * _cbfs_default_allocator(void *arg, size_t size, const union cbfs_mdata *unused)
Definition: cbfs.c:510
static void * cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out)
Definition: cbfs.h:215
static size_t cbfs_unverified_area_load(const char *area, const char *name, void *buf, size_t size)
Definition: cbfs.h:304
static size_t cbfs_ro_get_size(const char *name)
Definition: cbfs.h:354
enum cb_err cbfs_prog_stage_load(struct prog *prog)
Definition: cbfs.c:523
enum cb_err cbfs_init_boot_device(const struct cbfs_boot_device *cbd, struct vb2_hash *metadata_hash)
Definition: cbfs.c:615
static void * cbfs_type_map(const char *name, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:256
void * _cbfs_cbmem_allocator(void *arg, size_t size, const union cbfs_mdata *unused)
Definition: cbfs.c:518
void * _cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool force_ro, enum cbfs_type *type)
Definition: cbfs.c:449
static void * cbfs_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out)
Definition: cbfs.h:314
static void * cbfs_ro_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out)
Definition: cbfs.h:221
static bool cbfs_ro_file_exists(const char *name)
Definition: cbfs.h:390
static void * cbfs_map(const char *name, size_t *size_out)
Definition: cbfs.h:246
static void * cbfs_type_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:324
static size_t cbfs_type_load(const char *name, void *buf, size_t size, enum cbfs_type *type)
Definition: cbfs.h:287
static size_t cbfs_load(const char *name, void *buf, size_t size)
Definition: cbfs.h:282
static void * cbfs_ro_type_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, enum cbfs_type *type)
Definition: cbfs.h:233
static enum cbfs_type cbfs_ro_get_type(const char *name)
Definition: cbfs.h:372
const struct cbfs_boot_device * cbfs_get_boot_device(bool force_ro)
Definition: cbfs.c:634
static size_t cbfs_ro_type_load(const char *name, void *buf, size_t size, enum cbfs_type *type)
Definition: cbfs.h:298
void *(* cbfs_allocator_t)(void *arg, size_t size, const union cbfs_mdata *mdata)
Definition: cbfs.h:76
static size_t cbfs_ro_load(const char *name, void *buf, size_t size)
Definition: cbfs.h:293
static enum cbfs_type cbfs_get_type(const char *name)
Definition: cbfs.h:363
void cbfs_preload(const char *name)
Definition: cbfs.c:299
void * _cbfs_unverified_area_alloc(const char *area, const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out)
Definition: cbfs.c:487
enum cb_err _cbfs_boot_lookup(const char *name, bool force_ro, union cbfs_mdata *mdata, struct region_device *rdev)
Definition: cbfs.c:37
static void * cbfs_unverified_area_map(const char *area, const char *name, size_t *size_out)
Definition: cbfs.h:266
static void * cbfs_ro_cbmem_alloc(const char *name, uint32_t cbmem_id, size_t *size_out)
Definition: cbfs.h:319
cbfs_type
@ CBFS_TYPE_NULL
static struct region_device rdev
Definition: flashconsole.c:14
static uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:130
struct bootblock_arg arg
Definition: decompressor.c:22
unsigned int type
Definition: edid.c:57
static uint8_t * buf
Definition: uart.c:7
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
void * mcache
Definition: cbfs.h:168
size_t mcache_size
Definition: cbfs.h:169
struct region_device rdev
Definition: cbfs.h:167
uint32_t len
struct cbfs_file h
Definition: cbfs_mdata.h:21