diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-26 22:46:49 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-03-26 22:46:49 +0000 |
commit | 41b2e57afa7e227691bf8ce524f36cb8c31e66ce (patch) | |
tree | c40240b3e7ccd46e52e7f240a5b3ab8493fb7dcf /sys | |
parent | 9b8419b9f02d0a7ac0124c6e12fd7d93e2b4870d (diff) |
The devicetree standard allows for multiple /memory nodes, each with
multiple memory ranges. We support the latter, but not the former.
Fix this, such that we detect all the memory on the Milk-V Pioneer
board.
ok miod@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/riscv64/riscv64/machdep.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/sys/arch/riscv64/riscv64/machdep.c b/sys/arch/riscv64/riscv64/machdep.c index 35b54050e64..f2ff2a9b0f1 100644 --- a/sys/arch/riscv64/riscv64/machdep.c +++ b/sys/arch/riscv64/riscv64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.36 2024/02/21 04:26:45 dlg Exp $ */ +/* $OpenBSD: machdep.c,v 1.37 2024/03/26 22:46:48 kettenis Exp $ */ /* * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se> @@ -551,6 +551,7 @@ initriscv(struct riscv_bootparams *rbp) paddr_t fdt_start = (paddr_t)rbp->dtbp_phys; size_t fdt_size; struct fdt_reg reg; + const char *s; void *node; EFI_PHYSICAL_ADDRESS system_table = 0; int (*map_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int, @@ -647,27 +648,37 @@ initriscv(struct riscv_bootparams *rbp) process_kernel_args(); /* - * Determine physical RAM address range from FDT. + * Determine physical RAM address range from the /memory nodes + * in the FDT. There can be multiple nodes and each node can + * contain multiple ranges. */ node = fdt_find_node("/memory"); if (node == NULL) panic("%s: no memory specified", __func__); ramstart = (paddr_t)-1, ramend = 0; - for (i = 0; i < VM_PHYSSEG_MAX; i++) { - if (fdt_get_reg(node, i, ®)) - break; - if (reg.size == 0) - continue; - - start = reg.addr; - end = reg.addr + reg.size; - - if (start < ramstart) - ramstart = start; - if (end > ramend) - ramend = end; + while (node) { + s = fdt_node_name(node); + if (strncmp(s, "memory", 6) == 0 && + (s[6] == '\0' || s[6] == '@')) { + for (i = 0; i < VM_PHYSSEG_MAX; i++) { + if (fdt_get_reg(node, i, ®)) + break; + if (reg.size == 0) + continue; + + start = reg.addr; + end = reg.addr + reg.size; + + if (start < ramstart) + ramstart = start; + if (end > ramend) + ramend = end; + + physmem += atop(reg.size); + } + } - physmem += atop(ramend - ramstart); + node = fdt_next_node(node); } /* The bootloader has loaded us into a 64MB block. */ |