Module Name: src
Committed By: jmcneill
Date: Wed Jul 5 01:08:45 UTC 2017
Modified Files:
src/sys/arch/evbarm/conf: files.evbarm std.exynos std.sunxi std.tegra
std.vexpress
src/sys/arch/evbarm/fdt: fdt_machdep.c
src/sys/arch/evbarm/include: bootconfig.h
Log Message:
Add support for reserved memory and MEMORY_DISK_DYNAMIC for FDT-based
kernels.
To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/evbarm/conf/files.evbarm
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/conf/std.exynos
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/conf/std.sunxi
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/evbarm/conf/std.tegra
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/evbarm/conf/std.vexpress
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbarm/include/bootconfig.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/evbarm/conf/files.evbarm
diff -u src/sys/arch/evbarm/conf/files.evbarm:1.25 src/sys/arch/evbarm/conf/files.evbarm:1.26
--- src/sys/arch/evbarm/conf/files.evbarm:1.25 Thu Dec 4 21:15:48 2014
+++ src/sys/arch/evbarm/conf/files.evbarm Wed Jul 5 01:08:44 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files.evbarm,v 1.25 2014/12/04 21:15:48 joerg Exp $
+# $NetBSD: files.evbarm,v 1.26 2017/07/05 01:08:44 jmcneill Exp $
#
# First try for arm-specific configuration info
#
@@ -48,4 +48,9 @@ defflag opt_plcom.h PLCOM_DEBUG
device plcom { }: tty
file arch/evbarm/dev/plcom.c plcom needs-flag
+#
+# Maximum number of memory ranges
+#
+defparam opt_machdep.h DRAM_BLOCKS
+
include "arch/arm/conf/majors.arm32"
Index: src/sys/arch/evbarm/conf/std.exynos
diff -u src/sys/arch/evbarm/conf/std.exynos:1.4 src/sys/arch/evbarm/conf/std.exynos:1.5
--- src/sys/arch/evbarm/conf/std.exynos:1.4 Sun Jul 2 18:22:29 2017
+++ src/sys/arch/evbarm/conf/std.exynos Wed Jul 5 01:08:44 2017
@@ -1,4 +1,4 @@
-# $NetBSD: std.exynos,v 1.4 2017/07/02 18:22:29 skrll Exp $
+# $NetBSD: std.exynos,v 1.5 2017/07/05 01:08:44 jmcneill Exp $
#
machine evbarm arm
@@ -12,6 +12,7 @@ options ARM_TRUSTZONE_FIRMWARE
options __NO_FIQ
options FDT # Flattened Device Tree support
+options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER
Index: src/sys/arch/evbarm/conf/std.sunxi
diff -u src/sys/arch/evbarm/conf/std.sunxi:1.2 src/sys/arch/evbarm/conf/std.sunxi:1.3
--- src/sys/arch/evbarm/conf/std.sunxi:1.2 Mon Jul 3 00:51:44 2017
+++ src/sys/arch/evbarm/conf/std.sunxi Wed Jul 5 01:08:44 2017
@@ -1,4 +1,4 @@
-# $NetBSD: std.sunxi,v 1.2 2017/07/03 00:51:44 jmcneill Exp $
+# $NetBSD: std.sunxi,v 1.3 2017/07/05 01:08:44 jmcneill Exp $
#
machine evbarm arm
@@ -7,6 +7,7 @@ include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.sunxi"
options FDT # Flattened Device Tree support
+options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER
@@ -28,3 +29,8 @@ makeoptions CPUFLAGS="-march=armv7-a -mf
options ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>"
options ARM_GENERIC_TODR
+
+# initrd support
+options MEMORY_DISK_HOOKS
+options MEMORY_DISK_DYNAMIC
+pseudo-device md
Index: src/sys/arch/evbarm/conf/std.tegra
diff -u src/sys/arch/evbarm/conf/std.tegra:1.14 src/sys/arch/evbarm/conf/std.tegra:1.15
--- src/sys/arch/evbarm/conf/std.tegra:1.14 Sat Jul 1 09:17:44 2017
+++ src/sys/arch/evbarm/conf/std.tegra Wed Jul 5 01:08:44 2017
@@ -1,4 +1,4 @@
-# $NetBSD: std.tegra,v 1.14 2017/07/01 09:17:44 skrll Exp $
+# $NetBSD: std.tegra,v 1.15 2017/07/05 01:08:44 jmcneill Exp $
#
machine evbarm arm
@@ -7,6 +7,7 @@ include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.tegra"
options FDT # Flattened Device Tree support
+options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER
Index: src/sys/arch/evbarm/conf/std.vexpress
diff -u src/sys/arch/evbarm/conf/std.vexpress:1.5 src/sys/arch/evbarm/conf/std.vexpress:1.6
--- src/sys/arch/evbarm/conf/std.vexpress:1.5 Sun Jul 2 10:52:35 2017
+++ src/sys/arch/evbarm/conf/std.vexpress Wed Jul 5 01:08:44 2017
@@ -1,4 +1,4 @@
-# $NetBSD: std.vexpress,v 1.5 2017/07/02 10:52:35 skrll Exp $
+# $NetBSD: std.vexpress,v 1.6 2017/07/05 01:08:44 jmcneill Exp $
#
# standard NetBSD/evbarm for VEXPRESS options
@@ -9,6 +9,7 @@ include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.vexpress"
options FDT # Flattened Device Tree support
+options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options ARM_HAS_VBAR
Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.7 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.8
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.7 Sun Jun 11 20:25:07 2017
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c Wed Jul 5 01:08:45 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.7 2017/06/11 20:25:07 jmcneill Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.8 2017/07/05 01:08:45 jmcneill Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.7 2017/06/11 20:25:07 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.8 2017/07/05 01:08:45 jmcneill Exp $");
#include "opt_machdep.h"
#include "opt_ddb.h"
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/termios.h>
+#include <sys/extent.h>
#include <uvm/uvm_extern.h>
@@ -70,6 +71,10 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.
#include <arm/fdt/arm_fdtvar.h>
+#ifdef MEMORY_DISK_DYNAMIC
+#include <dev/md.h>
+#endif
+
#ifndef FDT_MAX_BOOT_STRING
#define FDT_MAX_BOOT_STRING 1024
#endif
@@ -79,6 +84,11 @@ char bootargs[FDT_MAX_BOOT_STRING] = "";
char *boot_args = NULL;
u_int uboot_args[4] = { 0 }; /* filled in by xxx_start.S (not in bss) */
+static char fdt_memory_ext_storage[EXTENT_FIXED_STORAGE_SIZE(DRAM_BLOCKS)];
+static struct extent *fdt_memory_ext;
+
+static uint64_t initrd_start, initrd_end;
+
#include <libfdt.h>
#include <dev/fdt/fdtvar.h>
#define FDT_BUF_SIZE (128*1024)
@@ -167,6 +177,155 @@ fdt_get_memory(uint64_t *paddr, uint64_t
}
}
+static void
+fdt_add_reserved_memory_range(uint64_t addr, uint64_t size)
+{
+ int error;
+
+ error = extent_free(fdt_memory_ext, addr, size, EX_NOWAIT);
+ if (error != 0)
+ printf("MEM ERROR: add %llx-%llx failed: %d\n",
+ addr, size, error);
+ DPRINTF("MEM: res %llx-%llx: %d\n", addr, size);
+}
+
+/*
+ * Exclude memory ranges from memory config from a /reserved-memory/ child
+ */
+static void
+fdt_add_reserved_memory(int phandle, uint64_t max_addr)
+{
+ uint64_t addr, size;
+ int index;
+
+ for (index = 0;
+ fdtbus_get_reg64(phandle, index, &addr, &size) == 0;
+ index++) {
+ if (addr >= max_addr)
+ continue;
+ if (addr + size > max_addr)
+ size = max_addr - addr;
+ fdt_add_reserved_memory_range(addr, size);
+ }
+}
+
+/*
+ * Define usable memory regions.
+ */
+static void
+fdt_build_bootconfig(uint64_t mem_addr, uint64_t mem_size)
+{
+ const int memory = OF_finddevice("/memory");
+ const uint64_t max_addr = mem_addr + mem_size;
+ BootConfig *bc = &bootconfig;
+ struct extent_region *er;
+ uint64_t addr, size;
+ int index, child, error;
+
+ fdt_memory_ext = extent_create("FDT Memory", mem_addr, max_addr,
+ fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), 0);
+
+ for (index = 0;
+ fdtbus_get_reg64(memory, index, &addr, &size) == 0;
+ index++) {
+ if (addr >= max_addr)
+ continue;
+ if (addr + size > max_addr)
+ size = max_addr - addr;
+
+ error = extent_alloc_region(fdt_memory_ext, addr, size,
+ EX_NOWAIT);
+ if (error != 0)
+ printf("MEM ERROR: add %llx-%llx failed: %d\n",
+ addr, size, error);
+ DPRINTF("MEM: add %llx-%llx\n", addr, size);
+ }
+
+ const int reserved = OF_finddevice("/reserved-memory");
+ if (reserved > 0)
+ for (child = OF_child(reserved); child; child = OF_peer(child))
+ fdt_add_reserved_memory(child, max_addr);
+
+ const uint64_t initrd_size = initrd_end - initrd_start;
+ if (initrd_size > 0)
+ fdt_add_reserved_memory_range(initrd_start, initrd_size);
+
+ DPRINTF("Usable memory:\n");
+ bc->dramblocks = 0;
+ LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
+ DPRINTF(" %lx - %lx\n", er->er_start, er->er_end);
+ bc->dram[bc->dramblocks].address = er->er_start;
+ bc->dram[bc->dramblocks].pages =
+ (er->er_end - er->er_start) / PAGE_SIZE;
+ bc->dramblocks++;
+ }
+}
+
+static void
+fdt_probe_initrd(uint64_t *pstart, uint64_t *pend)
+{
+ *pstart = *pend = 0;
+
+#ifdef MEMORY_DISK_DYNAMIC
+ const int chosen = OF_finddevice("/chosen");
+ if (chosen < 0)
+ return;
+
+ int len;
+ const void *start_data = fdtbus_get_prop(chosen,
+ "linux,initrd-start", &len);
+ const void *end_data = fdtbus_get_prop(chosen,
+ "linux,initrd-end", NULL);
+ if (start_data == NULL || end_data == NULL)
+ return;
+
+ switch (len) {
+ case 4:
+ *pstart = be32dec(start_data);
+ *pend = be32dec(end_data);
+ break;
+ case 8:
+ *pstart = be64dec(start_data);
+ *pend = be64dec(end_data);
+ break;
+ default:
+ printf("Unsupported len %d for /chosen/initrd-start\n", len);
+ return;
+ }
+#endif
+}
+
+static void
+fdt_setup_initrd(void)
+{
+#ifdef MEMORY_DISK_DYNAMIC
+ const uint64_t initrd_size = initrd_end - initrd_start;
+ paddr_t startpa = trunc_page(initrd_start);
+ paddr_t endpa = round_page(initrd_end);
+ paddr_t pa;
+ vaddr_t va;
+ void *md_start;
+
+ if (initrd_size == 0)
+ return;
+
+ va = uvm_km_alloc(kernel_map, initrd_size, 0,
+ UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
+ if (va == 0) {
+ printf("Failed to allocate VA for initrd\n");
+ return;
+ }
+
+ md_start = (void *)va;
+
+ for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
+ pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0);
+ pmap_update(pmap_kernel());
+
+ md_root_setconf(md_start, initrd_size);
+#endif
+}
+
u_int
initarm(void *arg)
{
@@ -271,10 +430,11 @@ initarm(void *arg)
const bool mapallmem_p = false;
#endif
- /* Fake bootconfig structure for the benefit of pmap.c. */
- bootconfig.dramblocks = 1;
- bootconfig.dram[0].address = (bus_addr_t)memory_addr;
- bootconfig.dram[0].pages = ram_size / PAGE_SIZE;
+ /* Parse ramdisk info */
+ fdt_probe_initrd(&initrd_start, &initrd_end);
+
+ /* Populate bootconfig structure for the benefit of pmap.c. */
+ fdt_build_bootconfig(memory_addr, memory_size);
arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
KERNEL_BASE_PHYS);
@@ -295,7 +455,6 @@ initarm(void *arg)
#endif
return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
-
}
static void
@@ -360,6 +519,9 @@ fdt_device_register(device_t self, void
{
const struct arm_platform *plat = arm_fdt_platform();
+ if (device_is_a(self, "armfdt"))
+ fdt_setup_initrd();
+
if (plat && plat->device_register)
plat->device_register(self, aux);
}
Index: src/sys/arch/evbarm/include/bootconfig.h
diff -u src/sys/arch/evbarm/include/bootconfig.h:1.6 src/sys/arch/evbarm/include/bootconfig.h:1.7
--- src/sys/arch/evbarm/include/bootconfig.h:1.6 Mon Feb 6 14:03:22 2006
+++ src/sys/arch/evbarm/include/bootconfig.h Wed Jul 5 01:08:45 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: bootconfig.h,v 1.6 2006/02/06 14:03:22 hamajima Exp $ */
+/* $NetBSD: bootconfig.h,v 1.7 2017/07/05 01:08:45 jmcneill Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
@@ -36,6 +36,8 @@
* SUCH DAMAGE.
*/
+#include "opt_machdep.h"
+
#include <arm/bootconfig.h>
typedef struct _PhysMem {