Annotation of sys/arch/alpha/alpha/mem.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: mem.c,v 1.21 2006/04/13 14:41:08 brad Exp $ */
! 2: /* $NetBSD: mem.c,v 1.26 2000/03/29 03:48:20 simonb Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1988 University of Utah.
! 6: * Copyright (c) 1982, 1986, 1990, 1993
! 7: * The Regents of the University of California. All rights reserved.
! 8: *
! 9: * This code is derived from software contributed to Berkeley by
! 10: * the Systems Programming Group of the University of Utah Computer
! 11: * Science Department.
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that the following conditions
! 15: * are met:
! 16: * 1. Redistributions of source code must retain the above copyright
! 17: * notice, this list of conditions and the following disclaimer.
! 18: * 2. Redistributions in binary form must reproduce the above copyright
! 19: * notice, this list of conditions and the following disclaimer in the
! 20: * documentation and/or other materials provided with the distribution.
! 21: * 3. Neither the name of the University nor the names of its contributors
! 22: * may be used to endorse or promote products derived from this software
! 23: * without specific prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: *
! 37: * @(#)mem.c 8.3 (Berkeley) 1/12/94
! 38: */
! 39:
! 40: /*
! 41: * Memory special file
! 42: */
! 43:
! 44: #include <sys/param.h>
! 45: #include <sys/buf.h>
! 46: #include <sys/systm.h>
! 47: #include <sys/uio.h>
! 48: #include <sys/malloc.h>
! 49: #include <sys/msgbuf.h>
! 50: #include <sys/mman.h>
! 51: #include <sys/conf.h>
! 52:
! 53: #include <machine/cpu.h>
! 54:
! 55: #include <uvm/uvm_extern.h>
! 56:
! 57: #define mmread mmrw
! 58: #define mmwrite mmrw
! 59: cdev_decl(mm);
! 60:
! 61: caddr_t zeropage;
! 62:
! 63: /* open counter for aperture */
! 64: #ifdef APERTURE
! 65: static int ap_open_count = 0;
! 66: static pid_t ap_open_pid = -1;
! 67: extern int allowaperture;
! 68: #endif
! 69:
! 70: /*ARGSUSED*/
! 71: int
! 72: mmopen(dev, flag, mode, p)
! 73: dev_t dev;
! 74: int flag, mode;
! 75: struct proc *p;
! 76: {
! 77:
! 78: switch (minor(dev)) {
! 79: case 0:
! 80: case 1:
! 81: case 2:
! 82: return (0);
! 83: #ifdef APERTURE
! 84: case 4:
! 85: if (suser(p, 0) != 0 || !allowaperture)
! 86: return (EPERM);
! 87:
! 88: /* authorize only one simultaneous open() from the same pid */
! 89: if (ap_open_count > 0 && p->p_pid != ap_open_pid)
! 90: return(EPERM);
! 91: ap_open_count++;
! 92: ap_open_pid = p->p_pid;
! 93: return (0);
! 94: #endif
! 95: case 12:
! 96: return (0);
! 97: default:
! 98: return (ENXIO);
! 99: }
! 100: }
! 101:
! 102: /*ARGSUSED*/
! 103: int
! 104: mmclose(dev, flag, mode, p)
! 105: dev_t dev;
! 106: int flag, mode;
! 107: struct proc *p;
! 108: {
! 109:
! 110: #ifdef APERTURE
! 111: if (minor(dev) == 4) {
! 112: ap_open_count--;
! 113: ap_open_pid = -1;
! 114: }
! 115: #endif
! 116: return (0);
! 117: }
! 118:
! 119: /*ARGSUSED*/
! 120: int
! 121: mmrw(dev, uio, flags)
! 122: dev_t dev;
! 123: struct uio *uio;
! 124: int flags;
! 125: {
! 126: register vaddr_t o, v;
! 127: register int c;
! 128: register struct iovec *iov;
! 129: int error = 0, rw;
! 130: extern int msgbufmapped;
! 131:
! 132: while (uio->uio_resid > 0 && !error) {
! 133: iov = uio->uio_iov;
! 134: if (iov->iov_len == 0) {
! 135: uio->uio_iov++;
! 136: uio->uio_iovcnt--;
! 137: if (uio->uio_iovcnt < 0)
! 138: panic("mmrw");
! 139: continue;
! 140: }
! 141: switch (minor(dev)) {
! 142:
! 143: /* minor device 0 is physical memory */
! 144: case 0:
! 145: v = uio->uio_offset;
! 146: kmemphys:
! 147: if (v >= ALPHA_K0SEG_TO_PHYS((vaddr_t)msgbufp)) {
! 148: if (msgbufmapped == 0) {
! 149: printf("Message Buf not Mapped\n");
! 150: error = EFAULT;
! 151: break;
! 152: }
! 153: }
! 154:
! 155: /* Allow reads only in RAM. */
! 156: rw = (uio->uio_rw == UIO_READ) ? PROT_READ : PROT_WRITE;
! 157: if ((alpha_pa_access(v) & rw) != rw) {
! 158: error = EFAULT;
! 159: break;
! 160: }
! 161:
! 162: o = uio->uio_offset & PGOFSET;
! 163: c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
! 164: error =
! 165: uiomove((caddr_t)ALPHA_PHYS_TO_K0SEG(v), c, uio);
! 166: break;
! 167:
! 168: /* minor device 1 is kernel memory */
! 169: case 1:
! 170: v = uio->uio_offset;
! 171:
! 172: if (v >= ALPHA_K0SEG_BASE && v <= ALPHA_K0SEG_END) {
! 173: v = ALPHA_K0SEG_TO_PHYS(v);
! 174: goto kmemphys;
! 175: }
! 176:
! 177: c = min(iov->iov_len, MAXPHYS);
! 178: if (!uvm_kernacc((caddr_t)v, c,
! 179: uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
! 180: return (EFAULT);
! 181: error = uiomove((caddr_t)v, c, uio);
! 182: break;
! 183:
! 184: /* minor device 2 is EOF/rathole */
! 185: case 2:
! 186: if (uio->uio_rw == UIO_WRITE)
! 187: uio->uio_resid = 0;
! 188: return (0);
! 189:
! 190: /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
! 191: case 12:
! 192: if (uio->uio_rw == UIO_WRITE) {
! 193: uio->uio_resid = 0;
! 194: return (0);
! 195: }
! 196: /*
! 197: * On the first call, allocate and zero a page
! 198: * of memory for use with /dev/zero.
! 199: */
! 200: if (zeropage == NULL) {
! 201: zeropage = (caddr_t)
! 202: malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
! 203: bzero(zeropage, PAGE_SIZE);
! 204: }
! 205: c = min(iov->iov_len, PAGE_SIZE);
! 206: error = uiomove(zeropage, c, uio);
! 207: break;
! 208:
! 209: default:
! 210: return (ENXIO);
! 211: }
! 212: }
! 213: return (error);
! 214: }
! 215:
! 216: paddr_t
! 217: mmmmap(dev, off, prot)
! 218: dev_t dev;
! 219: off_t off;
! 220: int prot;
! 221: {
! 222: switch (minor(dev)) {
! 223: case 0:
! 224: /*
! 225: * /dev/mem is the only one that makes sense through this
! 226: * interface. For /dev/kmem any physaddr we return here
! 227: * could be transient and hence incorrect or invalid at
! 228: * a later time. /dev/null just doesn't make any sense
! 229: * and /dev/zero is a hack that is handled via the default
! 230: * pager in mmap().
! 231: */
! 232:
! 233: /*
! 234: * Allow access only in RAM.
! 235: */
! 236: if ((prot & alpha_pa_access(atop(off))) != prot)
! 237: return (-1);
! 238: return (atop(off));
! 239:
! 240: #ifdef APERTURE
! 241: case 4:
! 242: /* minor device 4 is aperture driver */
! 243: switch (allowaperture) {
! 244: case 1:
! 245: if ((prot & alpha_pa_access(atop(off))) != prot)
! 246: return (-1);
! 247: return atop(off);
! 248: default:
! 249: return -1;
! 250: }
! 251: #endif
! 252: default:
! 253: return -1;
! 254: }
! 255: }
! 256:
! 257: int
! 258: mmioctl(dev, cmd, data, flags, p)
! 259: dev_t dev;
! 260: u_long cmd;
! 261: caddr_t data;
! 262: int flags;
! 263: struct proc *p;
! 264: {
! 265: return (EOPNOTSUPP);
! 266: }
CVSweb