Skip to content

Commit 3fbaf47

Browse files
committed
kboot: Add mapped reserved-memory ranges to memory map
This is the same thing U-Boot does for the EFI mem map, and means these ranges get a `struct page` in the kernel. Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 3122708 commit 3fbaf47

File tree

1 file changed

+64
-3
lines changed

1 file changed

+64
-3
lines changed

src/kboot.c

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
#define MAX_DISP_MAPPINGS 8
3939

40+
#define MAX_MEM_REGIONS 32
41+
4042
static void *dt = NULL;
4143
static int dt_bufsize = 0;
4244
static void *initrd_start = NULL;
@@ -330,13 +332,72 @@ static int dt_set_memory(void)
330332
printf("FDT: DRAM at 0x%lx size 0x%lx\n", dram_base, dram_size);
331333
printf("FDT: Usable memory is 0x%lx..0x%lx (0x%lx)\n", dram_min, dram_max, dram_max - dram_min);
332334

333-
u64 memreg[2] = {cpu_to_fdt64(dram_min), cpu_to_fdt64(dram_max - dram_min)};
335+
struct {
336+
fdt64_t start;
337+
fdt64_t size;
338+
} memreg[MAX_MEM_REGIONS] = {{cpu_to_fdt64(dram_min), cpu_to_fdt64(dram_max - dram_min)}};
339+
int num_regions = 1;
340+
341+
int resv_node = fdt_path_offset(dt, "/reserved-memory");
342+
if (resv_node < 0)
343+
bail("FDT: '/reserved-memory' not found\n");
344+
345+
int node;
346+
/* Find all reserved memory nodes */
347+
fdt_for_each_subnode(node, dt, resv_node)
348+
{
349+
const char *name = fdt_get_name(dt, node, NULL);
350+
const char *status = fdt_getprop(dt, node, "status", NULL);
351+
if (status && !strcmp(status, "disabled"))
352+
continue;
353+
354+
if (fdt_getprop(dt, node, "no-map", NULL))
355+
continue;
356+
357+
const fdt64_t *reg = fdt_getprop(dt, node, "reg", NULL);
358+
if (!reg)
359+
continue;
360+
361+
u64 resv_start = fdt64_to_cpu(reg[0]);
362+
u64 resv_len = fdt64_to_cpu(reg[1]);
363+
u64 resv_end = resv_start + resv_len;
364+
365+
if (resv_start < dram_min) {
366+
if (resv_end > dram_min) {
367+
bail("FDT: reserved-memory node %s intersects start of RAM (%lx..%lx %lx..%lx)\n",
368+
name, resv_start, resv_end, dram_min, dram_max);
369+
}
370+
} else if (resv_end > dram_max) {
371+
if (resv_start < dram_max) {
372+
bail("FDT: reserved-memory node %s intersects end of RAM (%lx..%lx %lx..%lx)\n",
373+
name, resv_start, resv_end, dram_min, dram_max);
374+
}
375+
} else {
376+
continue;
377+
}
378+
379+
if ((resv_start | resv_len) & (SZ_16K - 1)) {
380+
bail("FDT: reserved-memory node %s not page-aligned, ignoring (%lx..%lx)\n", name,
381+
resv_start, resv_end);
382+
continue;
383+
}
384+
385+
printf("FDT: Adding reserved-memory node %s (%lx..%lx) to RAM map\n", name, resv_start,
386+
resv_end);
387+
388+
if (num_regions >= MAX_MEM_REGIONS) {
389+
bail("FDT: Out of memory regions for reserved-memory\n");
390+
}
391+
392+
memreg[num_regions].start = cpu_to_fdt64(resv_start);
393+
memreg[num_regions++].size = cpu_to_fdt64(resv_len);
394+
}
334395

335-
int node = fdt_path_offset(dt, "/memory");
396+
node = fdt_path_offset(dt, "/memory");
336397
if (node < 0)
337398
bail("FDT: /memory node not found in devtree\n");
338399

339-
if (fdt_setprop(dt, node, "reg", memreg, sizeof(memreg)))
400+
if (fdt_setprop(dt, node, "reg", memreg, sizeof(memreg[0]) * num_regions))
340401
bail("FDT: couldn't set memory.reg property\n");
341402

342403
return 0;

0 commit comments

Comments
 (0)