From 31680ad106c4ba0c13a18d2e76b0265cb22e4686 Mon Sep 17 00:00:00 2001 From: mhorne Date: Thu, 19 Mar 2020 17:21:09 -0400 Subject: [PATCH] RISC-V: exclude reserved memory regions Currently, there is no mechanism through which the SBI firmware can communicate the details of its reserved memory region(s) to a supervisor payload. There has been some discussion recently on how this can be achieved [1], and it seems that it will happen via the device-tree, a new set of SBI calls, or some combination of both. This hasn't caused any issues for us yet, since we exclude all physical memory below the kernel's load address from being allocated, and on all currently supported platforms this covers the SBI firmware region. OpenSBI has begun specifying its section of memory under the "reserved-memory" device-tree property [2], which we can parse easily. If this property is present, we know exactly which region of physical memory the kernel should ignore. In the case that no "reserved-memory" property is found, exclude the lowest 2MB of memory from allocation. This isn't a perfect solution, but it is consistent with how the currently supported platforms are set up, allowing us to handle this case with BBL or the current release of OpenSBI. [1] https://github.com/riscv/riscv-sbi-doc/pull/37 [2] https://lists.infradead.org/pipermail/opensbi/2020-March/001544.html --- sys/riscv/riscv/machdep.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c index 32867ea7c2a72d..897008bdb85183 100644 --- a/sys/riscv/riscv/machdep.c +++ b/sys/riscv/riscv/machdep.c @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -827,6 +828,15 @@ initriscv(struct riscv_bootparams *rvbp) #ifdef FDT try_load_dtb(kmdp); + /* + * Exclude reserved memory specified by the device tree. Typically, + * this contains an entry for memory used by the runtime SBI firmware. + */ + if (fdt_get_reserved_mem(mem_regions, &mem_regions_sz) == 0) { + physmem_exclude_regions(mem_regions, mem_regions_sz, + EXFLAG_NODUMP | EXFLAG_NOALLOC); + } + /* Grab physical memory regions information from device tree. */ if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0) { panic("Cannot get physical memory regions"); @@ -843,6 +853,21 @@ initriscv(struct riscv_bootparams *rvbp) kernlen = (lastaddr - KERNBASE); pmap_bootstrap(rvbp->kern_l1pt, mem_regions[0].mr_start, kernlen); +#ifdef FDT + /* + * XXX: Exclude the lowest 2MB of physical memory, if it hasn't been + * already, as this area is assumed to contain the SBI firmware. This + * is a little fragile, but it is consistent with the platforms we + * support so far. + * + * TODO: remove this when the all regular booting methods properly + * report their reserved memory in the device tree. + */ + if (mem_regions[0].mr_start == physmap[0]) { + physmem_exclude_region(mem_regions[0].mr_start, L2_SIZE, + EXFLAG_NODUMP | EXFLAG_NOALLOC); + } +#endif physmem_init_kernel_globals(); /* Establish static device mappings */