Module Name:    src
Committed By:   reinoud
Date:           Tue Dec 27 14:55:31 UTC 2011

Modified Files:
        src/sys/arch/usermode/dev: cpu.c
        src/sys/arch/usermode/usermode: machdep.c pmap.c vm_machdep.c

Log Message:
Implement physio() for NetBSD/usermode the right way!


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/usermode/dev/cpu.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/usermode/usermode/machdep.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/usermode/usermode/pmap.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/usermode/usermode/vm_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/usermode/dev/cpu.c
diff -u src/sys/arch/usermode/dev/cpu.c:1.56 src/sys/arch/usermode/dev/cpu.c:1.57
--- src/sys/arch/usermode/dev/cpu.c:1.56	Sat Dec 24 12:23:24 2011
+++ src/sys/arch/usermode/dev/cpu.c	Tue Dec 27 14:55:31 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.56 2011/12/24 12:23:24 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.57 2011/12/27 14:55:31 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_hz.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.56 2011/12/24 12:23:24 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.57 2011/12/27 14:55:31 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -379,16 +379,25 @@ cpu_initclocks(void)
 void
 cpu_startup(void)
 {
+	vaddr_t minaddr, maxaddr;
 	size_t stacksize, msgbufsize = 32 * 1024;
 	void *stack_pagefault_ucp;
 
+	/* get ourself a message buffer */
 	um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP);
 	if (um_msgbuf == NULL)
 		panic("couldn't allocate msgbuf");
 	initmsgbuf(um_msgbuf, msgbufsize);
 
+	/* allocate a submap for physio, 1Mb enough? */
+	minaddr = 0;
+	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+				   1024 * 1024, 0, false, NULL);
+
+	/* say hi! */
 	banner();
 
+	/* init lwp0 */
 	memset(&lwp0pcb, 0, sizeof(lwp0pcb));
 	if (thunk_getcontext(&lwp0pcb.pcb_ucp))
 		panic("getcontext failed");

Index: src/sys/arch/usermode/usermode/machdep.c
diff -u src/sys/arch/usermode/usermode/machdep.c:1.45 src/sys/arch/usermode/usermode/machdep.c:1.46
--- src/sys/arch/usermode/usermode/machdep.c:1.45	Mon Dec 26 21:22:23 2011
+++ src/sys/arch/usermode/usermode/machdep.c	Tue Dec 27 14:55:31 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.45 2011/12/26 21:22:23 jmcneill Exp $ */
+/* $NetBSD: machdep.c,v 1.46 2011/12/27 14:55:31 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org>
@@ -38,7 +38,7 @@
 #include "opt_sdl.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.45 2011/12/26 21:22:23 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.46 2011/12/27 14:55:31 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -62,6 +62,8 @@ char machine[_SYS_NMLN] = "";
 char machine_arch[_SYS_NMLN] = "";
 char module_machine_usermode[_SYS_NMLN] = "";
 
+struct vm_map *phys_map = NULL;
+
 static char **saved_argv;
 char *usermode_root_image_path = NULL;
 static char usermode_tap_devicebuf[PATH_MAX] = "";

Index: src/sys/arch/usermode/usermode/pmap.c
diff -u src/sys/arch/usermode/usermode/pmap.c:1.82 src/sys/arch/usermode/usermode/pmap.c:1.83
--- src/sys/arch/usermode/usermode/pmap.c:1.82	Sun Dec 25 21:10:00 2011
+++ src/sys/arch/usermode/usermode/pmap.c	Tue Dec 27 14:55:31 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.82 2011/12/25 21:10:00 reinoud Exp $ */
+/* $NetBSD: pmap.c,v 1.83 2011/12/27 14:55:31 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.82 2011/12/25 21:10:00 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.83 2011/12/27 14:55:31 reinoud Exp $");
 
 #include "opt_memsize.h"
 #include "opt_kmempages.h"
@@ -648,9 +648,6 @@ pmap_page_deactivate(struct pv_entry *pv
 	uint32_t map_flags;
 	void *addr;
 
-	if (pv->pv_vflags & PV_WIRED)
-		return;
-
 	map_flags = THUNK_MAP_FILE | THUNK_MAP_FIXED | THUNK_MAP_SHARED;
 	addr = thunk_mmap((void *) va, PAGE_SIZE, THUNK_PROT_NONE,
 		map_flags, mem_fh, pa);

Index: src/sys/arch/usermode/usermode/vm_machdep.c
diff -u src/sys/arch/usermode/usermode/vm_machdep.c:1.3 src/sys/arch/usermode/usermode/vm_machdep.c:1.4
--- src/sys/arch/usermode/usermode/vm_machdep.c:1.3	Wed Aug 10 01:32:44 2011
+++ src/sys/arch/usermode/usermode/vm_machdep.c	Tue Dec 27 14:55:31 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.3 2011/08/10 01:32:44 jmcneill Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.4 2011/12/27 14:55:31 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,21 +27,73 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.3 2011/08/10 01:32:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.4 2011/12/27 14:55:31 reinoud Exp $");
 
-#include <sys/types.h>
 #include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
 
 #include <uvm/uvm_extern.h>
 
+
+/*
+ * Map a user I/O request into kernel virtual address space.
+ * Note: the pages are already locked by uvm_vslock(), so we
+ * do not need to pass an access_type to pmap_enter().
+ */
+/* This code was originally stolen from the alpha/acorn26 port. */
+
 int
 vmapbuf(struct buf *bp, vsize_t len)
 {
+	vaddr_t faddr, taddr, off;
+	paddr_t pa;
+	struct proc *p;
+	vm_prot_t prot;
+
+	if ((bp->b_flags & B_PHYS) == 0)
+		panic("vmapbuf");
+	p = bp->b_proc;
+	bp->b_saveaddr = bp->b_data;
+	faddr = trunc_page((vaddr_t)bp->b_data);
+	off = (vaddr_t)bp->b_data - faddr;
+	len = round_page(off + len);
+	taddr = uvm_km_alloc(phys_map, len, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+	bp->b_data = (void *)(taddr + off);
+	len = atop(len);
+	prot = bp->b_flags & B_READ ? VM_PROT_READ | VM_PROT_WRITE :
+				      VM_PROT_READ;
+	while (len--) {
+		if (pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map), faddr,
+		    &pa) == false)
+			panic("vmapbuf: null page frame");
+		pmap_enter(vm_map_pmap(phys_map), taddr, trunc_page(pa),
+		    prot, prot | PMAP_WIRED);
+		faddr += PAGE_SIZE;
+		taddr += PAGE_SIZE;
+	}
+	pmap_update(vm_map_pmap(phys_map));
+
 	return 0;
 }
 
+/*
+ * Unmap a previously-mapped user I/O request.
+ */
 void
 vunmapbuf(struct buf *bp, vsize_t len)
 {
+	vaddr_t addr, off;
+
+	if ((bp->b_flags & B_PHYS) == 0)
+		panic("vunmapbuf");
+	addr = trunc_page((vaddr_t)bp->b_data);
+	off = (vaddr_t)bp->b_data - addr;
+	len = round_page(off + len);
+	pmap_remove(vm_map_pmap(phys_map), addr, addr + len);
+	pmap_update(vm_map_pmap(phys_map));
+	uvm_km_free(phys_map, addr, len, UVM_KMF_VAONLY);
+	bp->b_data = bp->b_saveaddr;
+	bp->b_saveaddr = NULL;
 }
+

Reply via email to