Skip to content

Commit d2956e4

Browse files
hoshinolinamarcan
authored andcommitted
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 55efddd commit d2956e4

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/kboot.c

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

335399
int node = fdt_path_offset(dt, "/memory");
336400
if (node < 0)
337401
bail("FDT: /memory node not found in devtree\n");
338402

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

342406
return 0;

0 commit comments

Comments
 (0)