Module Name: src
Committed By: thorpej
Date: Sat Jan 6 17:32:41 UTC 2024
Modified Files:
src/sys/arch/virt68k/include: bootinfo.h vmparam.h
src/sys/arch/virt68k/virt68k: bootinfo.c machdep.c
Log Message:
The RAM disk specified by bootinfo is not necessarily loaded along with
the static kernel image. Map is separately and account for it in the
available memory segments.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/virt68k/include/bootinfo.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/virt68k/include/vmparam.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/virt68k/virt68k/bootinfo.c \
src/sys/arch/virt68k/virt68k/machdep.c
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/virt68k/include/bootinfo.h
diff -u src/sys/arch/virt68k/include/bootinfo.h:1.3 src/sys/arch/virt68k/include/bootinfo.h:1.4
--- src/sys/arch/virt68k/include/bootinfo.h:1.3 Tue Jan 2 17:13:03 2024
+++ src/sys/arch/virt68k/include/bootinfo.h Sat Jan 6 17:32:40 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: bootinfo.h,v 1.3 2024/01/02 17:13:03 thorpej Exp $ */
+/* $NetBSD: bootinfo.h,v 1.4 2024/01/06 17:32:40 thorpej Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -142,6 +142,7 @@ extern size_t bootinfo_mem_segments_igno
extern struct bi_mem_info bootinfo_mem_segments[];
extern struct bi_mem_info bootinfo_mem_segments_avail[];
extern int bootinfo_mem_nsegments;
+extern int bootinfo_mem_nsegments_avail;
extern vaddr_t bootinfo_end;
#define bootinfo_dataptr(bi) ((void *)&(bi)->bi_data[0])
Index: src/sys/arch/virt68k/include/vmparam.h
diff -u src/sys/arch/virt68k/include/vmparam.h:1.1 src/sys/arch/virt68k/include/vmparam.h:1.2
--- src/sys/arch/virt68k/include/vmparam.h:1.1 Tue Jan 2 07:41:01 2024
+++ src/sys/arch/virt68k/include/vmparam.h Sat Jan 6 17:32:40 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.1 2024/01/02 07:41:01 thorpej Exp $ */
+/* $NetBSD: vmparam.h,v 1.2 2024/01/06 17:32:40 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -115,10 +115,15 @@
/*
* Constants which control the way the VM system deals with memory segments.
- * The Qemu virt68k platform only has a single memory segment.
+ *
+ * We generally assume there's just a single real memory segment on this
+ * platform, but we need to be able to deal with a "hole" left by a RAM
+ * disk if the loader provided one. We optimize for the loader either
+ * plopping the RAM disk immediately after the kernel image or at the end
+ * of RAM, which would still leave us with a single large segment.
*/
-#define VM_PHYSSEG_MAX 1
-#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
+#define VM_PHYSSEG_MAX 4
+#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
#define VM_NFREELIST 1
#define VM_FREELIST_DEFAULT 0
Index: src/sys/arch/virt68k/virt68k/bootinfo.c
diff -u src/sys/arch/virt68k/virt68k/bootinfo.c:1.3 src/sys/arch/virt68k/virt68k/bootinfo.c:1.4
--- src/sys/arch/virt68k/virt68k/bootinfo.c:1.3 Tue Jan 2 17:13:03 2024
+++ src/sys/arch/virt68k/virt68k/bootinfo.c Sat Jan 6 17:32:41 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: bootinfo.c,v 1.3 2024/01/02 17:13:03 thorpej Exp $ */
+/* $NetBSD: bootinfo.c,v 1.4 2024/01/06 17:32:41 thorpej Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bootinfo.c,v 1.3 2024/01/02 17:13:03 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bootinfo.c,v 1.4 2024/01/06 17:32:41 thorpej Exp $");
#include "opt_md.h"
@@ -38,6 +38,8 @@ __KERNEL_RCSID(0, "$NetBSD: bootinfo.c,v
#include <sys/cpu.h>
#include <sys/rnd.h>
+#include <uvm/uvm_extern.h>
+
#ifdef MEMORY_DISK_DYNAMIC
#include <dev/md.h>
#endif
@@ -58,10 +60,14 @@ size_t bootinfo_mem_segments_ignored_b
struct bi_mem_info bootinfo_mem_segments[VM_PHYSSEG_MAX];
struct bi_mem_info bootinfo_mem_segments_avail[VM_PHYSSEG_MAX];
int bootinfo_mem_nsegments;
+int bootinfo_mem_nsegments_avail;
static paddr_t bootinfo_console_addr;
static bool bootinfo_console_addr_valid;
+static uint32_t bootinfo_initrd_start;
+static uint32_t bootinfo_initrd_size;
+
static bool
bootinfo_set_console(paddr_t pa)
{
@@ -141,9 +147,79 @@ bootinfo_add_mem(struct bi_record *bi)
m->mem_size = m68k_trunc_page(m->mem_size);
physmem += m->mem_size >> PGSHIFT;
- bootinfo_mem_segments[bootinfo_mem_nsegments] = *m;
- bootinfo_mem_segments_avail[bootinfo_mem_nsegments] = *m;
- bootinfo_mem_nsegments++;
+ bootinfo_mem_segments[bootinfo_mem_nsegments++] = *m;
+ bootinfo_mem_segments_avail[bootinfo_mem_nsegments_avail++] = *m;
+}
+
+static inline void
+bootinfo_add_initrd(struct bi_record *bi)
+{
+ struct bi_mem_info *rd = bootinfo_dataptr(bi);
+
+ if (bootinfo_initrd_size == 0) {
+ bootinfo_initrd_start = rd->mem_addr;
+ bootinfo_initrd_size = rd->mem_size;
+ }
+}
+
+static inline void
+bootinfo_reserve_initrd(void)
+{
+ if (bootinfo_initrd_size == 0) {
+ return;
+ }
+
+ paddr_t initrd_start = bootinfo_initrd_start;
+ paddr_t initrd_end = bootinfo_initrd_start + bootinfo_initrd_size;
+ int i;
+
+ /* Page-align the RAM disk start/end. */
+ initrd_end = m68k_round_page(initrd_end);
+ initrd_start = m68k_trunc_page(initrd_start);
+
+ /*
+ * XXX All if this code assumes that the RAM disk fits within
+ * XXX a single memory segment.
+ */
+
+ for (i = 0; i < bootinfo_mem_nsegments_avail; i++) {
+ /* Memory segment start/end already page-aligned. */
+ paddr_t seg_start = bootinfo_mem_segments_avail[i].mem_addr;
+ paddr_t seg_end = seg_start +
+ bootinfo_mem_segments_avail[i].mem_size;
+
+ if (initrd_start >= seg_end ||
+ initrd_end <= seg_start) {
+ /* Does not fall within this segment. */
+ continue;
+ }
+
+ if (initrd_start > seg_start && initrd_end < seg_end) {
+ /* We need to split this segment. */
+ /* XXX */
+ printf("WARNING: ignoring RAM disk that splits "
+ "memory segment.\n");
+ bootinfo_initrd_size = 0;
+ return;
+ }
+
+ printf("Reserving RAM disk pages %p - %p from memory "
+ "segment %d.\n", (void *)initrd_start,
+ (void *)(initrd_end - 1), i);
+
+ if (initrd_start == seg_start) {
+ seg_start = initrd_end;
+ }
+
+ if (initrd_end == seg_end) {
+ seg_end = initrd_start;
+ }
+
+ /* Now adjust the segment. */
+ bootinfo_mem_segments_avail[i].mem_addr = seg_start;
+ bootinfo_mem_segments_avail[i].mem_size = seg_end - seg_start;
+ return;
+ }
}
static inline void
@@ -198,6 +274,10 @@ bootinfo_start(struct bi_record *first)
bootinfo_add_mem(bi);
break;
+ case BI_RAMDISK:
+ bootinfo_add_initrd(bi);
+ break;
+
case BI_VIRT_GF_TTY_BASE:
bootinfo_gf_tty_consinit(bi);
break;
@@ -209,6 +289,12 @@ bootinfo_start(struct bi_record *first)
/* Set bootinfo_end to be just past the BI_LAST record. */
bootinfo_end = (vaddr_t)bootinfo_next(bi);
+
+ /*
+ * If we have a RAM disk, we need to take it out of the
+ * available memory segments.
+ */
+ bootinfo_reserve_initrd();
}
/*
@@ -287,10 +373,34 @@ void
bootinfo_setup_initrd(void)
{
#ifdef MEMORY_DISK_DYNAMIC
- struct bi_record *bi = bootinfo_find(BI_RAMDISK);
- if (bi != NULL) {
- struct bi_mem_info *rd = bootinfo_dataptr(bi);
- md_root_setconf((void *)rd->mem_addr, rd->mem_size);
+ if (bootinfo_initrd_size != 0) {
+ paddr_t rdstart, rdend, rdpgoff;
+ vaddr_t rdva, rdoff;
+ vsize_t rdvsize;
+
+ printf("Initializing root RAM disk @ %p - %p\n",
+ (void *)bootinfo_initrd_start,
+ (void *)(bootinfo_initrd_start + bootinfo_initrd_size - 1));
+
+ rdend = m68k_round_page(bootinfo_initrd_start +
+ bootinfo_initrd_size);
+ rdstart = m68k_trunc_page(bootinfo_initrd_start);
+ rdvsize = rdend - rdstart;
+ rdpgoff = bootinfo_initrd_start & PAGE_MASK;
+
+ rdva = uvm_km_alloc(kernel_map, rdvsize, PAGE_SIZE,
+ UVM_KMF_VAONLY);
+ if (rdva == 0) {
+ printf("WARNING: Unable to allocate KVA for "
+ "RAM disk.\n");
+ return;
+ }
+ for (rdoff = 0; rdoff < rdvsize; rdoff += PAGE_SIZE) {
+ pmap_kenter_pa(rdva + rdoff, rdstart + rdoff,
+ VM_PROT_READ | VM_PROT_WRITE, 0);
+ }
+ md_root_setconf((void *)(rdva + rdpgoff),
+ bootinfo_initrd_size);
}
#endif /* MEMORY_DISK_DYNAMIC */
}
Index: src/sys/arch/virt68k/virt68k/machdep.c
diff -u src/sys/arch/virt68k/virt68k/machdep.c:1.3 src/sys/arch/virt68k/virt68k/machdep.c:1.4
--- src/sys/arch/virt68k/virt68k/machdep.c:1.3 Tue Jan 2 18:10:36 2024
+++ src/sys/arch/virt68k/virt68k/machdep.c Sat Jan 6 17:32:41 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.3 2024/01/02 18:10:36 thorpej Exp $ */
+/* $NetBSD: machdep.c,v 1.4 2024/01/06 17:32:41 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.3 2024/01/02 18:10:36 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4 2024/01/06 17:32:41 thorpej Exp $");
#include "opt_ddb.h"
#include "opt_m060sp.h"
@@ -171,7 +171,7 @@ virt68k_init(void)
/*
* Tell the VM system about available physical memory.
*/
- for (i = 0; i < bootinfo_mem_nsegments; i++) {
+ for (i = 0; i < bootinfo_mem_nsegments_avail; i++) {
if (bootinfo_mem_segments_avail[i].mem_size < PAGE_SIZE) {
/*
* Segment has been completely gobbled up.