Annotation of sys/arch/hp300/hp300/mem.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mem.c,v 1.23 2005/10/28 09:07:48 martin Exp $ */
2: /* $NetBSD: mem.c,v 1.25 1999/03/27 00:30:06 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.
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/systm.h>
46: #include <sys/buf.h>
47: #include <sys/conf.h>
48: #include <sys/malloc.h>
49: #include <sys/proc.h>
50: #include <sys/uio.h>
51:
52: #include <machine/cpu.h>
53:
54: #include <uvm/uvm_extern.h>
55:
56: extern u_int lowram;
57: extern char *extiobase;
58: extern int eiomapsize;
59: static caddr_t devzeropage;
60:
61: #define mmread mmrw
62: #define mmwrite mmrw
63: cdev_decl(mm);
64:
65: /*ARGSUSED*/
66: int
67: mmopen(dev, flag, mode, p)
68: dev_t dev;
69: int flag, mode;
70: struct proc *p;
71: {
72:
73: switch (minor(dev)) {
74: case 0:
75: case 1:
76: case 2:
77: case 12:
78: return (0);
79: default:
80: return (ENXIO);
81: }
82: }
83:
84: /*ARGSUSED*/
85: int
86: mmclose(dev, flag, mode, p)
87: dev_t dev;
88: int flag, mode;
89: struct proc *p;
90: {
91:
92: return (0);
93: }
94:
95: /*ARGSUSED*/
96: int
97: mmrw(dev, uio, flags)
98: dev_t dev;
99: struct uio *uio;
100: int flags;
101: {
102: vaddr_t o, v;
103: int c;
104: struct iovec *iov;
105: int error = 0;
106: static int physlock;
107: vm_prot_t prot;
108:
109: if (minor(dev) == 0) {
110: /* lock against other uses of shared vmmap */
111: while (physlock > 0) {
112: physlock++;
113: error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
114: "mmrw", 0);
115: if (error)
116: return (error);
117: }
118: physlock = 1;
119: }
120: while (uio->uio_resid > 0 && error == 0) {
121: iov = uio->uio_iov;
122: if (iov->iov_len == 0) {
123: uio->uio_iov++;
124: uio->uio_iovcnt--;
125: if (uio->uio_iovcnt < 0)
126: panic("mmrw");
127: continue;
128: }
129: switch (minor(dev)) {
130:
131: /* minor device 0 is physical memory */
132: case 0:
133: v = uio->uio_offset;
134:
135: /*
136: * Only allow reads in physical RAM.
137: */
138: if (v >= 0xFFFFFFFC || v < lowram) {
139: error = EFAULT;
140: goto unlock;
141: }
142:
143: prot = uio->uio_rw == UIO_READ ? VM_PROT_READ :
144: VM_PROT_WRITE;
145: pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
146: trunc_page(v), prot, prot|PMAP_WIRED);
147: pmap_update(pmap_kernel());
148: o = uio->uio_offset & PGOFSET;
149: c = min(uio->uio_resid, (int)(NBPG - o));
150: error = uiomove((caddr_t)vmmap + o, c, uio);
151: pmap_remove(pmap_kernel(), (vaddr_t)vmmap,
152: (vaddr_t)vmmap + NBPG);
153: pmap_update(pmap_kernel());
154: continue;
155:
156: /* minor device 1 is kernel memory */
157: case 1:
158: v = uio->uio_offset;
159: c = min(iov->iov_len, MAXPHYS);
160: if (!uvm_kernacc((caddr_t)v, c,
161: uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
162: return (EFAULT);
163:
164: /*
165: * Don't allow reading intio or dio
166: * device space. This could lead to
167: * corruption of device registers.
168: */
169: if (ISIIOVA(v) ||
170: ((caddr_t)v >= extiobase &&
171: (caddr_t)v < (extiobase + (eiomapsize * NBPG))))
172: return (EFAULT);
173:
174: error = uiomove((caddr_t)v, c, uio);
175: continue;
176:
177: /* minor device 2 is EOF/RATHOLE */
178: case 2:
179: if (uio->uio_rw == UIO_WRITE)
180: uio->uio_resid = 0;
181: return (0);
182:
183: /* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
184: case 12:
185: if (uio->uio_rw == UIO_WRITE) {
186: c = iov->iov_len;
187: break;
188: }
189: /*
190: * On the first call, allocate and zero a page
191: * of memory for use with /dev/zero.
192: */
193: if (devzeropage == NULL) {
194: devzeropage = (caddr_t)
195: malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
196: bzero(devzeropage, PAGE_SIZE);
197: }
198: c = min(iov->iov_len, PAGE_SIZE);
199: error = uiomove(devzeropage, c, uio);
200: continue;
201:
202: default:
203: return (ENXIO);
204: }
205: if (error)
206: break;
207: iov->iov_base = (caddr_t)iov->iov_base + c;
208: iov->iov_len -= c;
209: uio->uio_offset += c;
210: uio->uio_resid -= c;
211: }
212: if (minor(dev) == 0) {
213: unlock:
214: if (physlock > 1)
215: wakeup((caddr_t)&physlock);
216: physlock = 0;
217: }
218: return (error);
219: }
220:
221: paddr_t
222: mmmmap(dev, off, prot)
223: dev_t dev;
224: off_t off;
225: int prot;
226: {
227: /*
228: * /dev/mem is the only one that makes sense through this
229: * interface. For /dev/kmem any physaddr we return here
230: * could be transient and hence incorrect or invalid at
231: * a later time. /dev/null just doesn't make any sense
232: * and /dev/zero is a hack that is handled via the default
233: * pager in mmap().
234: */
235: if (minor(dev) != 0)
236: return (-1);
237:
238: /*
239: * Allow access only in RAM.
240: */
241: if ((u_int)off < lowram || (u_int)off >= 0xFFFFFFFC)
242: return (-1);
243: return (atop(off));
244: }
245:
246: int
247: mmioctl(dev, cmd, data, flags, p)
248: dev_t dev;
249: u_long cmd;
250: caddr_t data;
251: int flags;
252: struct proc *p;
253: {
254: return (EOPNOTSUPP);
255: }
CVSweb