[BACK]Return to mem.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa / dev

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