Module Name: src Committed By: jmcneill Date: Tue Oct 30 21:32:35 UTC 2018
Modified Files: src/sys/arch/evbarm/fdt: fdt_machdep.c Added Files: src/sys/arch/evbarm/fdt: fdt_memory.c fdt_memory.h Log Message: Replace extent(9) with our own code to deal with adding and reserving memory ranges. To generate a diff of this commit: cvs rdiff -u -r1.48 -r1.49 src/sys/arch/evbarm/fdt/fdt_machdep.c cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/fdt/fdt_memory.c \ src/sys/arch/evbarm/fdt/fdt_memory.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/fdt/fdt_machdep.c diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.48 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.49 --- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.48 Tue Oct 30 16:41:53 2018 +++ src/sys/arch/evbarm/fdt/fdt_machdep.c Tue Oct 30 21:32:35 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: fdt_machdep.c,v 1.48 2018/10/30 16:41:53 skrll Exp $ */ +/* $NetBSD: fdt_machdep.c,v 1.49 2018/10/30 21:32:35 jmcneill Exp $ */ /*- * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.48 2018/10/30 16:41:53 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.49 2018/10/30 21:32:35 jmcneill Exp $"); #include "opt_machdep.h" #include "opt_bootconfig.h" @@ -55,7 +55,6 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep. #include <sys/proc.h> #include <sys/reboot.h> #include <sys/termios.h> -#include <sys/extent.h> #include <sys/bootblock.h> #include <sys/disklabel.h> #include <sys/vnode.h> @@ -80,6 +79,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep. #include <evbarm/include/autoconf.h> #include <evbarm/fdt/machdep.h> #include <evbarm/fdt/platform.h> +#include <evbarm/fdt/fdt_memory.h> #include <arm/fdt/arm_fdtvar.h> @@ -110,9 +110,6 @@ char *boot_args = NULL; u_long uboot_args[4] __attribute__((__section__(".data"))); const uint8_t *fdt_addr_r __attribute__((__section__(".data"))); -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> @@ -198,16 +195,7 @@ fdt_get_memory(uint64_t *pstart, uint64_ void fdt_add_reserved_memory_range(uint64_t addr, uint64_t size) { - uint64_t start = addr; - uint64_t end = addr + size; - - int error = extent_free(fdt_memory_ext, start, - end - start, EX_NOWAIT); - if (error != 0) - printf("MEM ERROR: res %" PRIx64 "-%" PRIx64 " failed: %d\n", - start, end, error); - else - VPRINTF("MEM: res %" PRIx64 "-%" PRIx64 "\n", start, end); + fdt_memory_remove_range(addr, size); } /* @@ -248,6 +236,49 @@ fdt_add_reserved_memory(uint64_t min_add } } +static void +fdt_add_dram_blocks(const struct fdt_memory *m, void *arg) +{ + BootConfig *bc = arg; + + VPRINTF(" %lx - %lx\n", m->start, m->end - 1); + bc->dram[bc->dramblocks].address = m->start; + bc->dram[bc->dramblocks].pages = + (m->end - m->start) / PAGE_SIZE; + bc->dramblocks++; +} + +#define MAX_PHYSMEM 64 +static int nfdt_physmem = 0; +static struct boot_physmem fdt_physmem[MAX_PHYSMEM]; + +static void +fdt_add_boot_physmem(const struct fdt_memory *m, void *arg) +{ + struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++]; + + VPRINTF(" %lx - %lx\n", m->start, m->end - 1); + + KASSERT(nfdt_physmem <= MAX_PHYSMEM); + + bp->bp_start = atop(round_page(m->start)); + bp->bp_pages = atop(trunc_page(m->end)) - bp->bp_start; + bp->bp_freelist = VM_FREELIST_DEFAULT; + +#ifdef _LP64 + if (m->end > 0x100000000) + bp->bp_freelist = VM_FREELIST_HIGHMEM; +#endif + +#ifdef PMAP_NEED_ALLOC_POOLPAGE + const uint64_t memory_size = *(uint64_t *)arg; + if (atop(memory_size) > bp->bp_pages) { + arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP; + bp->bp_freelist = VM_FREELIST_DIRECTMAP; + } +#endif +} + /* * Define usable memory regions. */ @@ -256,12 +287,8 @@ fdt_build_bootconfig(uint64_t mem_start, { const int memory = OF_finddevice("/memory"); BootConfig *bc = &bootconfig; - struct extent_region *er; uint64_t addr, size; - int index, error; - - fdt_memory_ext = extent_create("FDT Memory", mem_start, mem_end, - fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), EX_EARLY); + int index; for (index = 0; fdtbus_get_reg64(memory, index, &addr, &size) == 0; @@ -271,19 +298,14 @@ fdt_build_bootconfig(uint64_t mem_start, if (addr + size > mem_end) size = mem_end - addr; - error = extent_alloc_region(fdt_memory_ext, addr, size, - EX_NOWAIT); - if (error != 0) - printf("MEM ERROR: add %" PRIx64 "-%" PRIx64 " failed: %d\n", - addr, addr + size, error); - VPRINTF("MEM: add %" PRIx64 "-%" PRIx64 "\n", addr, addr + size); + fdt_memory_add_range(addr, size); } fdt_add_reserved_memory(mem_start, mem_end); const uint64_t initrd_size = initrd_end - initrd_start; if (initrd_size > 0) - fdt_add_reserved_memory_range(initrd_start, initrd_size); + fdt_memory_remove_range(initrd_start, initrd_size); const int framebuffer = OF_finddevice("/chosen/framebuffer"); if (framebuffer >= 0) { @@ -296,13 +318,7 @@ fdt_build_bootconfig(uint64_t mem_start, VPRINTF("Usable memory:\n"); bc->dramblocks = 0; - LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) { - VPRINTF(" %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++; - } + fdt_memory_foreach(fdt_add_dram_blocks, bc); } static void @@ -518,34 +534,8 @@ initarm(void *arg) parse_mi_bootargs(boot_args); - #define MAX_PHYSMEM 64 - static struct boot_physmem fdt_physmem[MAX_PHYSMEM]; - int nfdt_physmem = 0; - struct extent_region *er; - - VPRINTF("Memory regions :\n"); - LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) { - VPRINTF(" %lx - %lx\n", er->er_start, er->er_end); - struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++]; - - KASSERT(nfdt_physmem <= MAX_PHYSMEM); - - bp->bp_start = atop(round_page(er->er_start)); - bp->bp_pages = atop(trunc_page(er->er_end + 1)) - bp->bp_start; - bp->bp_freelist = VM_FREELIST_DEFAULT; - -#ifdef _LP64 - if (er->er_end > 0x100000000) - bp->bp_freelist = VM_FREELIST_HIGHMEM; -#endif - -#ifdef PMAP_NEED_ALLOC_POOLPAGE - if (atop(memory_size) > bp->bp_pages) { - arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP; - bp->bp_freelist = VM_FREELIST_DIRECTMAP; - } -#endif - } + VPRINTF("Memory regions:\n"); + fdt_memory_foreach(fdt_add_boot_physmem, &memory_size); u_int sp = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem, nfdt_physmem); Added files: Index: src/sys/arch/evbarm/fdt/fdt_memory.c diff -u /dev/null src/sys/arch/evbarm/fdt/fdt_memory.c:1.1 --- /dev/null Tue Oct 30 21:32:35 2018 +++ src/sys/arch/evbarm/fdt/fdt_memory.c Tue Oct 30 21:32:35 2018 @@ -0,0 +1,169 @@ +/* $NetBSD: fdt_memory.c,v 1.1 2018/10/30 21:32:35 jmcneill Exp $ */ + +/*- + * Copyright (c) 2018 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill <jmcne...@invisible.ca>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_bootconfig.h" + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: fdt_memory.c,v 1.1 2018/10/30 21:32:35 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/queue.h> + +#include <evbarm/fdt/fdt_memory.h> + +struct fdt_memory_range { + struct fdt_memory mr_mem; + bool mr_used; + TAILQ_ENTRY(fdt_memory_range) mr_list; +}; + +static TAILQ_HEAD(fdt_memory_rangehead, fdt_memory_range) fdt_memory_ranges = + TAILQ_HEAD_INITIALIZER(fdt_memory_ranges); + +static struct fdt_memory_range fdt_memory_range_pool[sizeof(struct fdt_memory_range) * DRAM_BLOCKS]; + +static struct fdt_memory_range * +fdt_memory_range_alloc(void) +{ + for (size_t n = 0; n < DRAM_BLOCKS; n++) + if (!fdt_memory_range_pool[n].mr_used) { + fdt_memory_range_pool[n].mr_used = true; + return &fdt_memory_range_pool[n]; + } + + printf("%s: no free memory ranges, increase DRAM_BLOCKS!\n", __func__); + return NULL; +} + +static void +fdt_memory_range_free(struct fdt_memory_range *mr) +{ + mr->mr_used = false; +} + +void +fdt_memory_add_range(uint64_t start, uint64_t size) +{ + struct fdt_memory_range *mr, *prev, *cur, *tmp; + bool inserted = false; + + mr = fdt_memory_range_alloc(); + if (mr == NULL) + return; + + mr->mr_mem.start = start; + mr->mr_mem.end = start + size; + + /* + * Add the new range to the list of sorted ranges. + */ + TAILQ_FOREACH(cur, &fdt_memory_ranges, mr_list) + if (mr->mr_mem.start <= cur->mr_mem.start) { + TAILQ_INSERT_BEFORE(cur, mr, mr_list); + inserted = true; + break; + } + if (!inserted) + TAILQ_INSERT_TAIL(&fdt_memory_ranges, mr, mr_list); + + /* + * Remove overlaps. + */ + TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) { + prev = TAILQ_PREV(mr, fdt_memory_rangehead, mr_list); + if (prev && prev->mr_mem.end > mr->mr_mem.start) { + mr->mr_mem.start = prev->mr_mem.end; + if (mr->mr_mem.start >= mr->mr_mem.end) { + TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list); + fdt_memory_range_free(mr); + } + } + } + + /* + * Combine adjacent ranges. + */ + TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) { + prev = TAILQ_PREV(mr, fdt_memory_rangehead, mr_list); + if (prev && prev->mr_mem.end == mr->mr_mem.start) { + prev->mr_mem.end = mr->mr_mem.end; + TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list); + fdt_memory_range_free(mr); + } + } +} + +void +fdt_memory_remove_range(uint64_t start, uint64_t size) +{ + struct fdt_memory_range *mr, *next, *tmp; + const uint64_t end = start + size; + + TAILQ_FOREACH_SAFE(mr, &fdt_memory_ranges, mr_list, tmp) { + if (start <= mr->mr_mem.start && end >= mr->mr_mem.end) { + /* + * Removed range completely covers this range, + * just remove it. + */ + TAILQ_REMOVE(&fdt_memory_ranges, mr, mr_list); + fdt_memory_range_free(mr); + } else if (start > mr->mr_mem.start && end < mr->mr_mem.end) { + /* + * Removed range is completely contained by this range, + * split it. + */ + next = fdt_memory_range_alloc(); + if (next == NULL) + panic("fdt_memory_remove_range"); + next->mr_mem.start = end; + next->mr_mem.end = mr->mr_mem.end; + mr->mr_mem.end = start; + TAILQ_INSERT_AFTER(&fdt_memory_ranges, mr, next, mr_list); + } else { + /* + * Partial overlap. + */ + if (start >= mr->mr_mem.start && start < mr->mr_mem.end) + mr->mr_mem.end = start; + if (end < mr->mr_mem.end && end > mr->mr_mem.start) + mr->mr_mem.start = end; + } + } +} + +void +fdt_memory_foreach(void (*fn)(const struct fdt_memory *, void *), void *arg) +{ + struct fdt_memory_range *mr; + + TAILQ_FOREACH(mr, &fdt_memory_ranges, mr_list) + fn(&mr->mr_mem, arg); +} Index: src/sys/arch/evbarm/fdt/fdt_memory.h diff -u /dev/null src/sys/arch/evbarm/fdt/fdt_memory.h:1.1 --- /dev/null Tue Oct 30 21:32:35 2018 +++ src/sys/arch/evbarm/fdt/fdt_memory.h Tue Oct 30 21:32:35 2018 @@ -0,0 +1,44 @@ +/* $NetBSD: fdt_memory.h,v 1.1 2018/10/30 21:32:35 jmcneill Exp $ */ + +/*- + * Copyright (c) 2018 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill <jmcne...@invisible.ca>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _EVBARM_FDT_FDT_MEMORY_H +#define _EVBARM_FDT_FDT_MEMORY_H + +struct fdt_memory { + uint64_t start; + uint64_t end; +}; + +void fdt_memory_add_range(uint64_t, uint64_t); +void fdt_memory_remove_range(uint64_t, uint64_t); +void fdt_memory_foreach(void (*)(const struct fdt_memory *, void *), void *); + +#endif /* !_EVBARM_FDT_FDT_MEMORY_H */