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; } +