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 {

Reply via email to