coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
fit_payload.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <bootmem.h>
4 #include <program_loading.h>
5 #include <fit.h>
6 #include <symbols.h>
7 
8 /**
9  * Place the region in free memory range.
10  */
11 static bool fit_place_mem(const struct range_entry *r, void *arg)
12 {
13  struct region *region = arg;
14  resource_t start;
15 
16  if (range_entry_tag(r) != BM_MEM_RAM)
17  return true;
18 
19  /* Linux 4.15 doesn't like 4KiB alignment. Align to 1 MiB for now. */
20  start = ALIGN_UP(MAX(region->offset, range_entry_base(r)), 1 * MiB);
21 
22  if (start + region->size < range_entry_end(r)) {
23  region->offset = (size_t)start;
24  return false;
25  }
26 
27  return true;
28 }
29 
30 bool fit_payload_arch(struct prog *payload, struct fit_config_node *config,
31  struct region *kernel,
32  struct region *fdt,
33  struct region *initrd)
34 {
35  void *arg = NULL;
36 
37  /**
38  * The kernel ARM documentation recommends loading the kernel above 32MiB
39  * in order to avoid the need to need to relocate prior to decompression.
40  */
41  kernel->offset = (uintptr_t)_dram + 32 * MiB;
42 
43  /**
44  * The code assumes that bootmem_walk provides a sorted list of memory
45  * regions, starting from the lowest address.
46  * The order of the calls here doesn't matter, as the placement is
47  * enforced in the called functions.
48  * For details check code on top.
49  */
50  if (!bootmem_walk(fit_place_mem, kernel))
51  return false;
52 
53  /* Mark as reserved for future allocations. */
54  bootmem_add_range(kernel->offset, kernel->size, BM_MEM_PAYLOAD);
55 
56  /**
57  * To ensure the fdt is not overwritten by the kernel decompressor, place
58  * the fdt above the 128 MB from the start of RAM, as recommended by the
59  * kernel documentation.
60  */
61  fdt->offset = (uintptr_t)_dram + 128 * MiB;
62 
63  if (!bootmem_walk(fit_place_mem, fdt))
64  return false;
65 
66  /* Mark as reserved for future allocations. */
68 
69  /* Place INITRD */
70  if (config->ramdisk) {
71  initrd->offset = fdt->offset + fdt->size;
72 
73  if (!bootmem_walk(fit_place_mem, initrd))
74  return false;
75 
76  /* Mark as reserved for future allocations. */
77  bootmem_add_range(initrd->offset, initrd->size, BM_MEM_PAYLOAD);
78  }
79 
80  /* Kernel expects FDT as argument */
81  arg = (void *)fdt->offset;
82 
83  prog_set_entry(payload, (void *)kernel->offset, arg);
84 
86 
87  return true;
88 }
bool fit_payload_arch(struct prog *payload, struct fit_config_node *config, struct region *kernel, struct region *fdt, struct region *initrd)
Definition: fit_payload.c:30
static bool fit_place_mem(const struct range_entry *r, void *arg)
Place the region in free memory range.
Definition: fit_payload.c:11
void bootmem_dump_ranges(void)
Definition: bootmem.c:155
@ BM_MEM_RAM
Definition: bootmem.h:23
@ BM_MEM_PAYLOAD
Definition: bootmem.h:35
void bootmem_add_range(uint64_t start, uint64_t size, const enum bootmem_type tag)
Definition: bootmem.c:88
bool bootmem_walk(range_action_t action, void *arg)
Walk memory tables and call the provided function, for every region.
Definition: bootmem.c:183
#define MiB
Definition: helpers.h:76
#define MAX(a, b)
Definition: helpers.h:40
#define ALIGN_UP(x, a)
Definition: helpers.h:17
u8 _dram[]
struct bootblock_arg arg
Definition: decompressor.c:22
enum board_config config
Definition: memory.c:448
static resource_t range_entry_base(const struct range_entry *r)
Definition: memrange.h:44
static resource_t range_entry_end(const struct range_entry *r)
Definition: memrange.h:50
static unsigned long range_entry_tag(const struct range_entry *r)
Definition: memrange.h:61
static void prog_set_entry(struct prog *prog, void *e, void *arg)
u64 resource_t
Definition: resource.h:43
#define NULL
Definition: stddef.h:19
__SIZE_TYPE__ size_t
Definition: stddef.h:7
unsigned long uintptr_t
Definition: stdint.h:21
Definition: memrange.h:24
Definition: region.h:76
size_t size
Definition: region.h:78
size_t offset
Definition: region.h:77