Annotation of sys/arch/mips64/mips64/mem.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mem.c,v 1.7 2007/05/03 19:34:00 miod Exp $ */
2: /* $NetBSD: mem.c,v 1.6 1995/04/10 11:55:03 mycroft 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 and Ralph Campbell.
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. All advertising materials mentioning features or use of this software
22: * must display the following acknowledgement:
23: * This product includes software developed by the University of
24: * California, Berkeley and its contributors.
25: * 4. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: *
41: * @(#)mem.c 8.3 (Berkeley) 1/12/94
42: */
43:
44: /*
45: * Memory special file
46: */
47:
48: #include <sys/param.h>
49: #include <sys/conf.h>
50: #include <sys/buf.h>
51: #include <sys/proc.h>
52: #include <sys/user.h>
53: #include <sys/msgbuf.h>
54: #include <sys/systm.h>
55: #include <sys/uio.h>
56: #include <sys/malloc.h>
57:
58: #include <machine/autoconf.h>
59: #include <machine/pte.h>
60: #include <machine/cpu.h>
61:
62: #include <uvm/uvm_extern.h>
63:
64: #ifdef APERTURE
65: static int ap_open_count = 0;
66: extern int allowaperture;
67: #endif
68: caddr_t zeropage;
69:
70: #define mmread mmrw
71: #define mmwrite mmrw
72: cdev_decl(mm);
73:
74: /*ARGSUSED*/
75: int
76: mmopen(dev_t dev, int flag, int mode, struct proc *p)
77: {
78:
79: switch (minor(dev)) {
80: case 0:
81: case 1:
82: case 2:
83: case 12:
84: return (0);
85: #ifdef APERTURE
86: case 4:
87: if (suser(p->p_ucred, &p->p_acflag) != 0 || !allowaperture)
88: return (EPERM);
89:
90: /* authorize only one simultaneous open() */
91: if (ap_open_count > 0)
92: return(EPERM);
93: ap_open_count++;
94: return (0);
95: #endif
96: default:
97: return (ENXIO);
98: }
99: }
100:
101: /*ARGSUSED*/
102: int
103: mmclose(dev_t dev, int flag, int mode, struct proc *p)
104: {
105: #ifdef APERTURE
106: if (minor(dev) == 4)
107: ap_open_count--;
108: #endif
109: return (0);
110: }
111:
112: /*ARGSUSED*/
113: int
114: mmrw(dev_t dev, struct uio *uio, int flags)
115: {
116: struct iovec *iov;
117: boolean_t allowed;
118: int error = 0, c;
119: vaddr_t v;
120:
121: while (uio->uio_resid > 0 && error == 0) {
122: iov = uio->uio_iov;
123: if (iov->iov_len == 0) {
124: uio->uio_iov++;
125: uio->uio_iovcnt--;
126: if (uio->uio_iovcnt < 0)
127: panic("mmrw");
128: continue;
129: }
130: switch (minor(dev)) {
131:
132: /* minor device 0 is physical memory */
133: case 0:
134: v = uio->uio_offset;
135: c = iov->iov_len;
136: if (v + c > ctob(physmem))
137: return (EFAULT);
138: v = (vaddr_t)PHYS_TO_XKPHYS(v, CCA_NONCOHERENT);
139: error = uiomove((caddr_t)v, c, uio);
140: continue;
141:
142: /* minor device 1 is kernel memory */
143: case 1:
144: v = uio->uio_offset;
145: c = min(iov->iov_len, MAXPHYS);
146:
147: /* Allow access to RAM through XKPHYS... */
148: if (IS_XKPHYS(v) && IS_XKPHYS(v + (vsize_t)c) &&
149: XKPHYS_TO_PHYS(v + (vsize_t)c) <= ptoa(physmem))
150: allowed = TRUE;
151: /* ...or through KSEG0... */
152: else if (v >= KSEG0_BASE &&
153: v + (vsize_t)c < KSEG0_BASE + KSEG_SIZE &&
154: (physmem >= atop(KSEG_SIZE) ||
155: v + (vsize_t)c <= KSEG0_BASE + ptoa(physmem)))
156: allowed = TRUE;
157: /* ...or through KSEG1... */
158: else if (v >= KSEG1_BASE &&
159: v + (vsize_t)c < KSEG1_BASE + KSEG_SIZE &&
160: (physmem >= atop(KSEG_SIZE) ||
161: v + c <= KSEG1_BASE + ptoa(physmem)))
162: allowed = TRUE;
163: /* ...otherwise, check it's within kernel kvm limits. */
164: else
165: allowed = uvm_kernacc((caddr_t)v, c,
166: uio->uio_rw == UIO_READ ? B_READ : B_WRITE);
167:
168: if (allowed) {
169: error = uiomove((caddr_t)v, c, uio);
170: continue;
171: } else {
172: return (EFAULT);
173: }
174:
175: /* minor device 2 is EOF/RATHOLE */
176: case 2:
177: if (uio->uio_rw == UIO_WRITE)
178: uio->uio_resid = 0;
179: return (0);
180:
181: /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
182: case 12:
183: if (uio->uio_rw == UIO_WRITE) {
184: c = iov->iov_len;
185: break;
186: }
187: if (zeropage == NULL) {
188: zeropage = (caddr_t)
189: malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
190: bzero(zeropage, PAGE_SIZE);
191: }
192: c = min(iov->iov_len, PAGE_SIZE);
193: error = uiomove(zeropage, c, uio);
194: continue;
195:
196: default:
197: return (ENODEV);
198: }
199: if (error)
200: break;
201: iov->iov_base += c;
202: iov->iov_len -= c;
203: uio->uio_offset += c;
204: uio->uio_resid -= c;
205: }
206: return error;
207: }
208:
209: /*ARGSUSED*/
210: paddr_t
211: mmmmap(dev_t dev, off_t off, int prot)
212: {
213: #ifdef APERTURE
214: if (minor(dev) == 4) {
215: if (off >= 0x0000 && off < 0x10000) {
216: off += sys_config.pci_io[0].bus_base;
217: return atop(off);
218: } else if (off >= 0xa0000 && off < 0x10000000) {
219: off += sys_config.pci_mem[0].bus_base;
220: return atop(off);
221: } else {
222: return -1;
223: }
224: }
225: #endif
226: return -1;
227: }
228:
229: int
230: mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
231: {
232: return (EOPNOTSUPP);
233: }
CVSweb