Annotation of sys/arch/hppa/dev/mem.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mem.c,v 1.28 2006/05/29 08:09:16 mickey Exp $ */
2:
3: /*
4: * Copyright (c) 1998-2004 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26: * THE POSSIBILITY OF SUCH DAMAGE.
27: */
28: /*
29: * Copyright (c) 1991,1992,1994, The University of Utah and
30: * the Computer Systems Laboratory (CSL). All rights reserved.
31: *
32: * Subject to your agreements with CMU,
33: * permission to use, copy, modify and distribute this software and its
34: * documentation is hereby granted, provided that both the copyright
35: * notice and this permission notice appear in all copies of the
36: * software, derivative works or modified versions, and any portions
37: * thereof, and that both notices appear in supporting documentation.
38: *
39: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
40: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
41: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42: *
43: * CSL requests users of this software to return to csl-dist@cs.utah.edu any
44: * improvements that they make and grant CSL redistribution rights.
45: *
46: * Utah $Hdr: mem.c 1.9 94/12/16$
47: */
48: /*
49: * Mach Operating System
50: * Copyright (c) 1992 Carnegie Mellon University
51: * All Rights Reserved.
52: *
53: * Permission to use, copy, modify and distribute this software and its
54: * documentation is hereby granted, provided that both the copyright
55: * notice and this permission notice appear in all copies of the
56: * software, derivative works or modified versions, and any portions
57: * thereof, and that both notices appear in supporting documentation.
58: *
59: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
60: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
61: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
62: *
63: * Carnegie Mellon requests users of this software to return to
64: *
65: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
66: * School of Computer Science
67: * Carnegie Mellon University
68: * Pittsburgh PA 15213-3890
69: *
70: * any improvements or extensions that they make and grant Carnegie Mellon
71: * the rights to redistribute these changes.
72: */
73:
74: #include <sys/param.h>
75: #include <sys/systm.h>
76: #include <sys/buf.h>
77: #include <sys/malloc.h>
78: #include <sys/proc.h>
79: #include <sys/uio.h>
80: #include <sys/types.h>
81: #include <sys/device.h>
82: #include <sys/errno.h>
83: #include <sys/ioctl.h>
84: #include <sys/file.h>
85:
86: #include <uvm/uvm.h>
87:
88: #include <machine/conf.h>
89: #include <machine/bus.h>
90: #include <machine/iomod.h>
91: #include <machine/autoconf.h>
92: #include <machine/pmap.h>
93:
94: #include <hppa/dev/cpudevs.h>
95: #include <hppa/dev/viper.h>
96:
97: #define VIPER_HPA 0xfffbf000
98:
99: /* registers on the PCXL2 MIOC */
100: struct l2_mioc {
101: u_int32_t pad[0x20]; /* 0x000 */
102: u_int32_t mioc_control; /* 0x080 MIOC control bits */
103: u_int32_t mioc_status; /* 0x084 MIOC status bits */
104: u_int32_t pad1[6]; /* 0x088 */
105: u_int32_t sltcv; /* 0x0a0 L2 cache control */
106: #define SLTCV_AVWL 0x00002000 /* extra cycle for addr valid write low */
107: #define SLTCV_UP4COUT 0x00001000 /* update cache on CPU castouts */
108: #define SLTCV_EDCEN 0x08000000 /* enable error correction */
109: #define SLTCV_EDTAG 0x10000000 /* enable diagtag */
110: #define SLTCV_CHKTP 0x20000000 /* enable parity checking */
111: #define SLTCV_LOWPWR 0x40000000 /* low power mode */
112: #define SLTCV_ENABLE 0x80000000 /* enable L2 cache */
113: #define SLTCV_BITS "\020\15avwl\16up4cout\24edcen\25edtag\26chktp\27lowpwr\30l2ena"
114: u_int32_t tagmask; /* 0x0a4 L2 cache tag mask */
115: u_int32_t diagtag; /* 0x0a8 L2 invalidates tag */
116: u_int32_t sltestat; /* 0x0ac L2 last logged tag read */
117: u_int32_t slteadd; /* 0x0b0 L2 pa of -- " -- */
118: u_int32_t pad2[3]; /* 0x0b4 */
119: u_int32_t mtcv; /* 0x0c0 MIOC timings */
120: u_int32_t ref; /* 0x0cc MIOC refresh timings */
121: u_int32_t pad3[4]; /* 0x0d0 */
122: u_int32_t mderradd; /* 0x0e0 addr of most evil mem error */
123: u_int32_t pad4; /* 0x0e4 */
124: u_int32_t dmaerr; /* 0x0e8 addr of most evil dma error */
125: u_int32_t dioerr; /* 0x0ec addr of most evil dio error */
126: u_int32_t gsc_timeout; /* 0x0f0 1-compl of GSC timeout delay */
127: u_int32_t hidmamem; /* 0x0f4 amount of phys mem installed */
128: u_int32_t pad5[2]; /* 0x0f8 */
129: u_int32_t memcomp[16]; /* 0x100 memory address comparators */
130: u_int32_t memmask[16]; /* 0x140 masks for -- " -- */
131: u_int32_t memtest; /* 0x180 test address decoding */
132: u_int32_t pad6[0xf]; /* 0x184 */
133: u_int32_t outchk; /* 0x1c0 address decoding output */
134: u_int32_t pad7[0x168]; /* 0x200 */
135: u_int32_t gsc15x_config; /* 0x7a0 writev enable */
136: };
137:
138: struct mem_softc {
139: struct device sc_dev;
140:
141: volatile struct vi_trs *sc_vp;
142: volatile struct l2_mioc *sc_l2;
143: };
144:
145: int memmatch(struct device *, void *, void *);
146: void memattach(struct device *, struct device *, void *);
147:
148: struct cfattach mem_ca = {
149: sizeof(struct mem_softc), memmatch, memattach
150: };
151:
152: struct cfdriver mem_cd = {
153: NULL, "mem", DV_DULL
154: };
155:
156: caddr_t zeropage;
157:
158: int
159: memmatch(parent, cfdata, aux)
160: struct device *parent;
161: void *cfdata;
162: void *aux;
163: {
164: register struct confargs *ca = aux;
165:
166: if (ca->ca_type.iodc_type != HPPA_TYPE_MEMORY ||
167: ca->ca_type.iodc_sv_model != HPPA_MEMORY_PDEP)
168: return 0;
169:
170: return 1;
171: }
172:
173: void
174: memattach(parent, self, aux)
175: struct device *parent;
176: struct device *self;
177: void *aux;
178: {
179: struct pdc_iodc_minit pdc_minit PDC_ALIGNMENT;
180: struct mem_softc *sc = (struct mem_softc *)self;
181: struct confargs *ca = aux;
182: int err;
183:
184: printf (":");
185:
186: /* XXX check if we are dealing w/ Viper */
187: if (ca->ca_hpa == (hppa_hpa_t)VIPER_HPA) {
188:
189: sc->sc_vp = (struct vi_trs *)
190: &((struct iomod *)ca->ca_hpa)->priv_trs;
191:
192: /* XXX other values seem to blow it up */
193: if (sc->sc_vp->vi_status.hw_rev == 0) {
194: u_int32_t vic;
195: int s, settimeout;
196:
197: switch (cpu_hvers) {
198: case HPPA_BOARD_HP715_33:
199: case HPPA_BOARD_HP715S_33:
200: case HPPA_BOARD_HP715T_33:
201: case HPPA_BOARD_HP715_50:
202: case HPPA_BOARD_HP715S_50:
203: case HPPA_BOARD_HP715T_50:
204: case HPPA_BOARD_HP715_75:
205: case HPPA_BOARD_HP725_50:
206: case HPPA_BOARD_HP725_75:
207: settimeout = 1;
208: break;
209: default:
210: settimeout = 0;
211: break;
212: }
213: if (sc->sc_dev.dv_cfdata->cf_flags & 1)
214: settimeout = !settimeout;
215:
216: printf(" viper rev %x,", sc->sc_vp->vi_status.hw_rev);
217: #ifdef DEBUG
218: printf(" ctrl %b", VI_CTRL, VI_CTRL_BITS);
219: #endif
220: s = splhigh();
221: vic = VI_CTRL;
222: vic &= ~VI_CTRL_CORE_DEN;
223: vic &= ~VI_CTRL_SGC0_DEN;
224: vic &= ~VI_CTRL_SGC1_DEN;
225: vic |= VI_CTRL_EISA_DEN;
226: vic |= VI_CTRL_CORE_PRF;
227:
228: if (settimeout && (vic & VI_CTRL_VSC_TOUT) == 0)
229: vic |= (850 << 19); /* clks */
230:
231: sc->sc_vp->vi_control = vic;
232:
233: __asm __volatile("stwas %1, 0(%0)"
234: :: "r" (&VI_CTRL), "r" (vic) : "memory");
235: splx(s);
236: #ifdef DEBUG
237: printf (" >> %b,", vic, VI_CTRL_BITS);
238: #endif
239: } else
240: sc->sc_vp = NULL;
241: } else
242: sc->sc_vp = NULL;
243:
244: if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_NINIT,
245: &pdc_minit, ca->ca_hpa, PAGE0->imm_spa_size)) < 0)
246: pdc_minit.max_spa = PAGE0->imm_max_mem;
247:
248: printf(" size %d", pdc_minit.max_spa / (1024*1024));
249: if (pdc_minit.max_spa % (1024*1024))
250: printf(".%d", pdc_minit.max_spa % (1024*1024));
251: printf("MB");
252:
253: /* L2 cache controller is a part of the memory controller on PCXL2 */
254: if (cpu_type == hpcxl2) {
255: sc->sc_l2 = (struct l2_mioc *)ca->ca_hpa;
256: #ifdef DEBUG
257: printf(", sltcv %b", sc->sc_l2->sltcv, SLTCV_BITS);
258: #endif
259: /* sc->sc_l2->sltcv |= SLTCV_UP4COUT; */
260: if (sc->sc_l2->sltcv & SLTCV_ENABLE) {
261: u_int32_t tagmask = sc->sc_l2->tagmask >> 20;
262:
263: printf(", %dMB L2 cache", tagmask + 1);
264: }
265: }
266:
267: printf("\n");
268: }
269:
270: void
271: viper_setintrwnd(mask)
272: u_int32_t mask;
273: {
274: register struct mem_softc *sc;
275:
276: sc = mem_cd.cd_devs[0];
277:
278: if (sc->sc_vp)
279: sc->sc_vp->vi_intrwd = mask;
280: }
281:
282: void
283: viper_eisa_en()
284: {
285: struct mem_softc *sc;
286:
287: sc = mem_cd.cd_devs[0];
288: if (sc->sc_vp) {
289: u_int32_t vic;
290: int s;
291:
292: s = splhigh();
293: vic = VI_CTRL;
294: vic &= ~VI_CTRL_EISA_DEN;
295: sc->sc_vp->vi_control = vic;
296: __asm __volatile("stwas %1, 0(%0)"
297: :: "r" (&VI_CTRL), "r" (vic) : "memory");
298: splx(s);
299: }
300: }
301:
302: int
303: mmopen(dev, flag, ioflag, p)
304: dev_t dev;
305: int flag;
306: int ioflag;
307: struct proc *p;
308: {
309: return (0);
310: }
311:
312: /*ARGSUSED*/
313: int
314: mmclose(dev, flag, mode, p)
315: dev_t dev;
316: int flag, mode;
317: struct proc *p;
318: {
319: return (0);
320: }
321:
322: int
323: mmrw(dev, uio, flags)
324: dev_t dev;
325: struct uio *uio;
326: int flags;
327: {
328: struct iovec *iov;
329: vaddr_t v, o;
330: int error = 0;
331: u_int c;
332:
333: while (uio->uio_resid > 0 && error == 0) {
334: iov = uio->uio_iov;
335: if (iov->iov_len == 0) {
336: uio->uio_iov++;
337: uio->uio_iovcnt--;
338: if (uio->uio_iovcnt < 0)
339: panic("mmrw");
340: continue;
341: }
342: switch (minor(dev)) {
343:
344: case 0: /* /dev/mem */
345:
346: /* If the address isn't in RAM, bail. */
347: v = uio->uio_offset;
348: if (btoc(v) > physmem) {
349: error = EFAULT;
350: /* this will break us out of the loop */
351: continue;
352: }
353: c = ctob(physmem) - v;
354: c = min(c, uio->uio_resid);
355: error = uiomove((caddr_t)v, c, uio);
356: break;
357:
358: case 1: /* /dev/kmem */
359: v = uio->uio_offset;
360: o = v & PGOFSET;
361: c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
362: if (btoc(v) > physmem && !uvm_kernacc((caddr_t)v,
363: c, (uio->uio_rw == UIO_READ) ? B_READ : B_WRITE)) {
364: error = EFAULT;
365: /* this will break us out of the loop */
366: continue;
367: }
368: error = uiomove((caddr_t)v, c, uio);
369: break;
370:
371: case 2: /* /dev/null */
372: if (uio->uio_rw == UIO_WRITE)
373: uio->uio_resid = 0;
374: return (0);
375:
376: case 12: /* /dev/zero */
377: /* Write to /dev/zero is ignored. */
378: if (uio->uio_rw == UIO_WRITE) {
379: uio->uio_resid = 0;
380: return (0);
381: }
382: /*
383: * On the first call, allocate and zero a page
384: * of memory for use with /dev/zero.
385: */
386: if (zeropage == NULL) {
387: zeropage = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
388: bzero(zeropage, PAGE_SIZE);
389: }
390: c = min(iov->iov_len, PAGE_SIZE);
391: error = uiomove(zeropage, c, uio);
392: break;
393:
394: default:
395: return (ENXIO);
396: }
397: }
398:
399: return (error);
400: }
401:
402: paddr_t
403: mmmmap(dev, off, prot)
404: dev_t dev;
405: off_t off;
406: int prot;
407: {
408: if (minor(dev) != 0)
409: return (-1);
410:
411: /*
412: * Allow access only in RAM.
413: */
414: #if 0
415: if (off < ctob(firstusablepage) ||
416: off >= ctob(lastusablepage + 1))
417: return (-1);
418: #endif
419: return (atop(off));
420: }
421:
422: int
423: mmioctl(dev, cmd, data, flags, p)
424: dev_t dev;
425: u_long cmd;
426: caddr_t data;
427: int flags;
428: struct proc *p;
429: {
430: return (EOPNOTSUPP);
431: }
CVSweb