Module Name: src Committed By: uebayasi Date: Thu Aug 19 12:36:59 UTC 2010
Modified Files: src/share/man/man4 [uebayasi-xip]: md.4 src/sys/arch/evbppc/conf [uebayasi-xip]: OPENBLOCKS266 majors.evbppc src/sys/arch/powerpc/conf [uebayasi-xip]: files.powerpc src/sys/conf [uebayasi-xip]: files Added Files: src/share/man/man4 [uebayasi-xip]: xmd.4 src/sys/arch/powerpc/powerpc [uebayasi-xip]: xmd_machdep.c src/sys/dev [uebayasi-xip]: xmd.c xmdvar.h Log Message: Initial addition of xmd(4), XIP memory disk. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.5.26.1 src/share/man/man4/md.4 cvs rdiff -u -r0 -r1.1.2.1 src/share/man/man4/xmd.4 cvs rdiff -u -r1.46.2.2 -r1.46.2.3 src/sys/arch/evbppc/conf/OPENBLOCKS266 cvs rdiff -u -r1.28.6.1 -r1.28.6.2 src/sys/arch/evbppc/conf/majors.evbppc cvs rdiff -u -r1.71.4.2 -r1.71.4.3 src/sys/arch/powerpc/conf/files.powerpc cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/powerpc/powerpc/xmd_machdep.c cvs rdiff -u -r1.974.2.7 -r1.974.2.8 src/sys/conf/files cvs rdiff -u -r0 -r1.1.2.1 src/sys/dev/xmd.c src/sys/dev/xmdvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/md.4 diff -u src/share/man/man4/md.4:1.5 src/share/man/man4/md.4:1.5.26.1 --- src/share/man/man4/md.4:1.5 Sun Feb 25 04:22:01 2007 +++ src/share/man/man4/md.4 Thu Aug 19 12:36:59 2010 @@ -1,4 +1,4 @@ -.\" $NetBSD: md.4,v 1.5 2007/02/25 04:22:01 uwe Exp $ +.\" $NetBSD: md.4,v 1.5.26.1 2010/08/19 12:36:59 uebayasi Exp $ .\" .\" This file is in the public domain. .\" @@ -35,5 +35,6 @@ .El .Sh SEE ALSO .Xr options 4 , +.Xr xmd 4 , .Xr mdconfig 8 , .Xr mdsetimage 8 Index: src/sys/arch/evbppc/conf/OPENBLOCKS266 diff -u src/sys/arch/evbppc/conf/OPENBLOCKS266:1.46.2.2 src/sys/arch/evbppc/conf/OPENBLOCKS266:1.46.2.3 --- src/sys/arch/evbppc/conf/OPENBLOCKS266:1.46.2.2 Wed Aug 11 14:03:58 2010 +++ src/sys/arch/evbppc/conf/OPENBLOCKS266 Thu Aug 19 12:36:58 2010 @@ -1,4 +1,4 @@ -# $NetBSD: OPENBLOCKS266,v 1.46.2.2 2010/08/11 14:03:58 uebayasi Exp $ +# $NetBSD: OPENBLOCKS266,v 1.46.2.3 2010/08/19 12:36:58 uebayasi Exp $ # # GENERIC -- everything that's currently supported # @@ -7,7 +7,7 @@ #options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "OPENBLOCKS266-$Revision: 1.46.2.2 $" +#ident "OPENBLOCKS266-$Revision: 1.46.2.3 $" maxusers 32 @@ -197,6 +197,7 @@ #pseudo-device fss # file system snapshot device #pseudo-device md 1 # memory disk device #pseudo-device vnd # disk-like interface to files +#pseudo-device xmd 1 # XIP memory disk device # network pseudo-devices pseudo-device loop # network loopback Index: src/sys/arch/evbppc/conf/majors.evbppc diff -u src/sys/arch/evbppc/conf/majors.evbppc:1.28.6.1 src/sys/arch/evbppc/conf/majors.evbppc:1.28.6.2 --- src/sys/arch/evbppc/conf/majors.evbppc:1.28.6.1 Wed Aug 11 13:56:27 2010 +++ src/sys/arch/evbppc/conf/majors.evbppc Thu Aug 19 12:36:58 2010 @@ -1,4 +1,4 @@ -# $NetBSD: majors.evbppc,v 1.28.6.1 2010/08/11 13:56:27 uebayasi Exp $ +# $NetBSD: majors.evbppc,v 1.28.6.2 2010/08/19 12:36:58 uebayasi Exp $ # # Device majors for evbppc # (When possible, make entries the same as macppc) @@ -81,6 +81,7 @@ device-major nsmb char 98 nsmb device-major xlcom char 99 xlcom device-major flash char 100 block 15 flash +device-major xmd char 101 block 16 xmd # Majors up to 143 are reserved for machine-dependant drivers. # New machine-independent driver majors are assigned in Index: src/sys/arch/powerpc/conf/files.powerpc diff -u src/sys/arch/powerpc/conf/files.powerpc:1.71.4.2 src/sys/arch/powerpc/conf/files.powerpc:1.71.4.3 --- src/sys/arch/powerpc/conf/files.powerpc:1.71.4.2 Wed Aug 11 13:20:07 2010 +++ src/sys/arch/powerpc/conf/files.powerpc Thu Aug 19 12:36:58 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files.powerpc,v 1.71.4.2 2010/08/11 13:20:07 uebayasi Exp $ +# $NetBSD: files.powerpc,v 1.71.4.3 2010/08/19 12:36:58 uebayasi Exp $ defflag opt_altivec.h ALTIVEC K_ALTIVEC defflag opt_openpic.h OPENPIC OPENPIC_SERIAL_MODE @@ -94,3 +94,5 @@ file arch/powerpc/powerpc/linux_sigcode.S compat_linux file arch/powerpc/powerpc/linux_trap.c compat_linux file arch/powerpc/powerpc/linux_syscall.c compat_linux + +file arch/powerpc/powerpc/xmd_machdep.c xmd Index: src/sys/conf/files diff -u src/sys/conf/files:1.974.2.7 src/sys/conf/files:1.974.2.8 --- src/sys/conf/files:1.974.2.7 Tue Aug 17 06:45:56 2010 +++ src/sys/conf/files Thu Aug 19 12:36:58 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.974.2.7 2010/08/17 06:45:56 uebayasi Exp $ +# $NetBSD: files,v 1.974.2.8 2010/08/19 12:36:58 uebayasi Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20100430 @@ -271,6 +271,10 @@ defparam opt_md.h MEMORY_DISK_SERVER=1 MEMORY_DISK_ROOT_SIZE MEMORY_DISK_RBFLAGS +# XIP memory (ram) disk options +# +defflag opt_xmd.h XMD_ROOT_SIZE + defflag opt_tftproot.h TFTPROOT TFTPROOT_DEBUG # Support for hardware performance monitoring counters @@ -1256,6 +1260,7 @@ defpseudodev cgd: disk, des, blowfish, cast128, rijndael defpseudodev md: disk defpseudodev fss: disk +defpseudodev xmd: disk defpseudo pty: tty defpseudo rnd @@ -1415,6 +1420,7 @@ file dev/sequencer.c sequencer needs-flag file dev/video.c video needs-flag file dev/vnd.c vnd needs-flag +file dev/xmd.c xmd needs-count file kern/bufq_disksort.c bufq_disksort file kern/bufq_fcfs.c bufq_fcfs file kern/bufq_priocscan.c bufq_priocscan Added files: Index: src/share/man/man4/xmd.4 diff -u /dev/null src/share/man/man4/xmd.4:1.1.2.1 --- /dev/null Thu Aug 19 12:36:59 2010 +++ src/share/man/man4/xmd.4 Thu Aug 19 12:36:59 2010 @@ -0,0 +1,30 @@ +.\" $NetBSD: xmd.4,v 1.1.2.1 2010/08/19 12:36:59 uebayasi Exp $ +.\" +.\" This file is in the public domain. +.\" +.Dd August 19, 2010 +.Dt XMD 4 +.Os +.Sh NAME +.Nm xmd +.Nd XIP memory disk +.Sh SYNOPSIS +.Cd "pseudo-device xmd" Op Ar count +.Sh DESCRIPTION +The +.Nm +driver enables use of system or user memory as a disk, which can be +mounted as XIP (eXecute-In-Place), so that filesystem data are read +without consuming intermediate page cache buffers. +.Pp +Memory for the disk is allocated within the kernel and set with +.Xr mdsetimage 8 +before the +.Nm +device may be used as a disk. +.Nm +disks should be mounted as read-only to enable XIP. +.Sh SEE ALSO +.Xr md 4 , +.Xr options 4 , +.Xr mdsetimage 8 Index: src/sys/arch/powerpc/powerpc/xmd_machdep.c diff -u /dev/null src/sys/arch/powerpc/powerpc/xmd_machdep.c:1.1.2.1 --- /dev/null Thu Aug 19 12:36:59 2010 +++ src/sys/arch/powerpc/powerpc/xmd_machdep.c Thu Aug 19 12:36:58 2010 @@ -0,0 +1,69 @@ +/* $NetBSD: xmd_machdep.c,v 1.1.2.1 2010/08/19 12:36:58 uebayasi Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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_xip.h" + +#include <sys/param.h> +#include <sys/mman.h> + +#include <uvm/uvm_page.h> + +#include <dev/xmdvar.h> + +paddr_t +xmd_machdep_mmap(vaddr_t addr, off_t off, int prot) +{ + + /* addr is in PA == VA RAM area. */ + KASSERT(addr >= 0x00000000); + KASSERT(addr < 0x80000000); + + return addr; +} + +void * +xmd_machdep_physload(vaddr_t addr, size_t size) +{ + paddr_t s, e, as, ae; + + /* addr is in PA == VA RAM area. */ + KASSERT(addr >= 0x00000000); + KASSERT(addr < 0x80000000); + + s = as = (addr) >> PAGE_SHIFT; + e = ae = (addr + size) >> PAGE_SHIFT; + + return uvm_page_physload_device(s, e, as, ae, PROT_READ, 0); +} + +void +xmd_machdep_physunload(void *phys) +{ + + uvm_page_physunload_device(phys); +} Index: src/sys/dev/xmd.c diff -u /dev/null src/sys/dev/xmd.c:1.1.2.1 --- /dev/null Thu Aug 19 12:36:59 2010 +++ src/sys/dev/xmd.c Thu Aug 19 12:36:58 2010 @@ -0,0 +1,299 @@ +/* $NetBSD: xmd.c,v 1.1.2.1 2010/08/19 12:36:58 uebayasi Exp $ */ + +/*- + * Copyright (c) 2010 Tsubai Masanari. All rights reserved. + * Copyright (c) 2010 Masao Uebayashi. All rights reserved. + * + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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_xip.h" +#include "opt_xmd.h" + +#ifndef XIP +#error xmd(4) needs options XIP +#endif + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/ioctl.h> +#include <sys/kmem.h> +#include <sys/buf.h> +#include <sys/bufq.h> +#include <sys/device.h> +#include <sys/disk.h> +#include <sys/disklabel.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/kmem.h> + +#include <machine/vmparam.h> + +#include <dev/xmdvar.h> + +struct xmd_softc { + vaddr_t sc_addr; + size_t sc_size; + + void *sc_phys; + + struct disk sc_dkdev; + struct bufq_state *sc_buflist; +}; + +void xmdattach(int); +static void xmd_attach(device_t, device_t, void *); +static int xmd_detach(device_t, int); +static dev_type_open(xmd_open); +static dev_type_close(xmd_close); +static dev_type_ioctl(xmd_ioctl); +static dev_type_mmap(xmd_mmap); +static dev_type_strategy(xmd_strategy); +static dev_type_size(xmd_size); + +struct bdevsw xmd_bdevsw = { + xmd_open, xmd_close, xmd_strategy, xmd_ioctl, + nodump, xmd_size, D_DISK | D_MPSAFE +}; + +struct cdevsw xmd_cdevsw = { + nullopen, nullclose, nullread, nowrite, xmd_ioctl, + nostop, notty, nopoll, xmd_mmap, nokqfilter +}; + +extern struct cfdriver xmd_cd; +CFATTACH_DECL3_NEW(xmd, sizeof(struct xmd_softc), + NULL, xmd_attach, xmd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); + +static struct dkdriver xmddkdriver = { xmd_strategy, NULL }; + +const char md_root_image[XMD_ROOT_SIZE << DEV_BSHIFT] __aligned(PAGE_SIZE) = + "|This is the root ramdisk!\n"; +const size_t md_root_size = XMD_ROOT_SIZE << DEV_BSHIFT; + +void +xmdattach(int n) +{ + int i; + cfdata_t cf; + + if (config_cfattach_attach("xmd", &xmd_ca)) { + aprint_error("xmd: cfattach_attach failed\n"); + return; + } + + /* XXX Support single instance for now. */ + KASSERT(n == 1); + + for (i = 0; i < n; i++) { + cf = kmem_alloc(sizeof(*cf), KM_SLEEP); + KASSERT(cf != NULL); + cf->cf_name = "xmd"; + cf->cf_atname = "xmd"; + cf->cf_unit = i; + cf->cf_fstate = FSTATE_NOTFOUND; + (void)config_attach_pseudo(cf); + } +} + +static void +xmd_attach(device_t parent, device_t self, void *aux) +{ + struct xmd_softc *sc = device_private(self); + + sc->sc_addr = (vaddr_t)md_root_image; + sc->sc_size = (size_t)md_root_size; + +#ifdef XIP + sc->sc_phys = xmd_machdep_physload(sc->sc_addr, sc->sc_size); +#endif + + bufq_alloc(&sc->sc_buflist, "fcfs", 0); + + disk_init(&sc->sc_dkdev, device_xname(self), &xmddkdriver); + disk_attach(&sc->sc_dkdev); + + if (!pmf_device_register(self, NULL, NULL)) + aprint_error_dev(self, "couldn't establish power handler\n"); +} + +static int +xmd_detach(device_t self, int flags) +{ + struct xmd_softc *sc = device_private(self); + int rc; + + rc = 0; + mutex_enter(&sc->sc_dkdev.dk_openlock); + if (sc->sc_dkdev.dk_openmask == 0) + ; /* nothing to do */ + else if ((flags & DETACH_FORCE) == 0) + rc = EBUSY; + mutex_exit(&sc->sc_dkdev.dk_openlock); + + if (rc != 0) + return rc; + + pmf_device_deregister(self); + disk_detach(&sc->sc_dkdev); + disk_destroy(&sc->sc_dkdev); + bufq_free(sc->sc_buflist); + return 0; +} + +static int +xmd_open(dev_t dev, int flags, int fmt, struct lwp *l) +{ + struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); + struct disk *dk = &sc->sc_dkdev; + const int part = DISKUNIT(dev); + const int pmask = 1 << part; + + if (sc == NULL) + return ENXIO; + + mutex_enter(&dk->dk_openlock); + switch (fmt) { + case S_IFCHR: + dk->dk_copenmask |= pmask; + break; + case S_IFBLK: + dk->dk_bopenmask |= pmask; + break; + } + dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; + mutex_exit(&dk->dk_openlock); + + return 0; +} + +static int +xmd_close(dev_t dev, int flags, int fmt, struct lwp *l) +{ + + return 0; +} + +int +xmd_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) +{ + struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); + const int part = DISKUNIT(dev); + int error = 0; + + if (sc == NULL) + return -1; + + switch (cmd) { +#ifdef XIP + case DIOCGPHYSSEG: + if (sc->sc_phys == NULL) + error = EINVAL; + else + *(void **)data = sc->sc_phys; + break; +#endif + + case DIOCGDINFO: + *(struct disklabel *)data = *sc->sc_dkdev.dk_label; + break; + + case DIOCGPART: + ((struct partinfo *)data)->disklab = sc->sc_dkdev.dk_label; + ((struct partinfo *)data)->part = + &sc->sc_dkdev.dk_label->d_partitions[part]; + break; + + default: + error = EINVAL; + break; + } + + return error; +} + +paddr_t +xmd_mmap(dev_t dev, off_t off, int prot) +{ + struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); + + if (sc == NULL) + return -1; + + if ((u_int64_t)off >= sc->sc_size) + return -1; + + return xmd_machdep_mmap(sc->sc_addr, off, prot); +} + +static void +xmd_strategy(struct buf *bp) +{ + struct xmd_softc *sc; + void *addr; + size_t off, count; + + sc = device_lookup_private(&xmd_cd, DISKUNIT(bp->b_dev)); + + off = bp->b_blkno << DEV_BSHIFT; + + /* XXX is b_bcount==0 legal? */ + + if (off >= sc->sc_size) { + if (bp->b_flags & B_READ) + /* XXX why not error? */ + goto done; + bp->b_error = EIO; + goto done; + } + + if (bp->b_bcount <= (sc->sc_size - off)) + count = bp->b_bcount; + else + count = sc->sc_size - off; + + addr = (void *)(sc->sc_addr + off); + + if (bp->b_flags & B_READ) + memcpy(bp->b_data, addr, count); + else + panic("%s: block write is not supported", __func__); + + bp->b_resid = bp->b_bcount - count; + + done: + biodone(bp); +} + +static int +xmd_size(dev_t dev) +{ + struct xmd_softc *sc; + + sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); + if (sc == NULL) + return 0; + + return sc->sc_size >> DEV_BSHIFT; +} Index: src/sys/dev/xmdvar.h diff -u /dev/null src/sys/dev/xmdvar.h:1.1.2.1 --- /dev/null Thu Aug 19 12:36:59 2010 +++ src/sys/dev/xmdvar.h Thu Aug 19 12:36:58 2010 @@ -0,0 +1,36 @@ +/* $NetBSD: xmdvar.h,v 1.1.2.1 2010/08/19 12:36:58 uebayasi Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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 _DEV_XMDVAR_H_ +#define _DEV_XMDVAR_H_ + +paddr_t xmd_machdep_mmap(vaddr_t, off_t, int); +void *xmd_machdep_physload(vaddr_t, size_t); +void xmd_machdep_physunload(void *); + +#endif