[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     ! 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