Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/evbarm Add support for reserved memory and MEMORY_D...



details:   https://anonhg.NetBSD.org/src/rev/3f54fcef913e
branches:  trunk
changeset: 354933:3f54fcef913e
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Jul 05 01:08:44 2017 +0000

description:
Add support for reserved memory and MEMORY_DISK_DYNAMIC for FDT-based
kernels.

diffstat:

 sys/arch/evbarm/conf/files.evbarm    |    7 +-
 sys/arch/evbarm/conf/std.exynos      |    3 +-
 sys/arch/evbarm/conf/std.sunxi       |    8 +-
 sys/arch/evbarm/conf/std.tegra       |    3 +-
 sys/arch/evbarm/conf/std.vexpress    |    3 +-
 sys/arch/evbarm/fdt/fdt_machdep.c    |  176 +++++++++++++++++++++++++++++++++-
 sys/arch/evbarm/include/bootconfig.h |    4 +-
 7 files changed, 191 insertions(+), 13 deletions(-)

diffs (truncated from 353 to 300 lines):

diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/conf/files.evbarm
--- a/sys/arch/evbarm/conf/files.evbarm Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/conf/files.evbarm Wed Jul 05 01:08:44 2017 +0000
@@ -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 @@
 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"
diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/conf/std.exynos
--- a/sys/arch/evbarm/conf/std.exynos   Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/conf/std.exynos   Wed Jul 05 01:08:44 2017 +0000
@@ -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                __NO_FIQ
 
 options        FDT                             # Flattened Device Tree support
+options        DRAM_BLOCKS=256
 options        MODULAR
 options        MODULAR_DEFAULT_AUTOLOAD
 options        __HAVE_CPU_COUNTER
diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/conf/std.sunxi
--- a/sys/arch/evbarm/conf/std.sunxi    Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/conf/std.sunxi    Wed Jul 05 01:08:44 2017 +0000
@@ -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/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 @@
 
 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
diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/conf/std.tegra
--- a/sys/arch/evbarm/conf/std.tegra    Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/conf/std.tegra    Wed Jul 05 01:08:44 2017 +0000
@@ -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/files.tegra"
 
 options        FDT                             # Flattened Device Tree support
+options        DRAM_BLOCKS=256
 options        MODULAR
 options        MODULAR_DEFAULT_AUTOLOAD
 options        __HAVE_CPU_COUNTER
diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/conf/std.vexpress
--- a/sys/arch/evbarm/conf/std.vexpress Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/conf/std.vexpress Wed Jul 05 01:08:44 2017 +0000
@@ -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/files.vexpress"
 
 options        FDT                             # Flattened Device Tree support
+options        DRAM_BLOCKS=256
 options        MODULAR
 options        MODULAR_DEFAULT_AUTOLOAD
 options        ARM_HAS_VBAR
diff -r 845a1f421295 -r 3f54fcef913e sys/arch/evbarm/fdt/fdt_machdep.c
--- a/sys/arch/evbarm/fdt/fdt_machdep.c Tue Jul 04 21:19:33 2017 +0000
+++ b/sys/arch/evbarm/fdt/fdt_machdep.c Wed Jul 05 01:08:44 2017 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 #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 @@
 
 #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 *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 @@
        }
 }
 
+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)



Home | Main Index | Thread Index | Old Index