1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <program_loading.h>
9 * Place the region in free memory range.
11 static bool fit_place_mem(const struct range_entry
*r
, void *arg
)
13 struct region
*region
= arg
;
16 if (range_entry_tag(r
) != BM_MEM_RAM
)
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
);
22 if (start
+ region
->size
< range_entry_end(r
)) {
23 region
->offset
= (size_t)start
;
30 bool fit_payload_arch(struct prog
*payload
, struct fit_config_node
*config
,
31 struct region
*kernel
,
33 struct region
*initrd
)
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.
41 kernel
->offset
= (uintptr_t)_dram
+ 32 * MiB
;
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.
50 if (!bootmem_walk(fit_place_mem
, kernel
))
53 /* Mark as reserved for future allocations. */
54 bootmem_add_range(kernel
->offset
, kernel
->size
, BM_MEM_PAYLOAD
);
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.
61 fdt
->offset
= (uintptr_t)_dram
+ 128 * MiB
;
63 if (!bootmem_walk(fit_place_mem
, fdt
))
66 /* Mark as reserved for future allocations. */
67 bootmem_add_range(fdt
->offset
, fdt
->size
, BM_MEM_PAYLOAD
);
70 if (config
->ramdisk
) {
71 initrd
->offset
= fdt
->offset
+ fdt
->size
;
73 if (!bootmem_walk(fit_place_mem
, initrd
))
76 /* Mark as reserved for future allocations. */
77 bootmem_add_range(initrd
->offset
, initrd
->size
, BM_MEM_PAYLOAD
);
80 /* Kernel expects FDT as argument */
81 arg
= (void *)fdt
->offset
;
83 prog_set_entry(payload
, (void *)kernel
->offset
, arg
);
85 bootmem_dump_ranges();