Annotation of researchv9/sys/sundev/mb.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)mb.c 1.1 86/02/03 Copyr 1983 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * Mainbus support routines.
        !            11:  */
        !            12: 
        !            13: #include "../h/param.h"
        !            14: #include "../h/systm.h"
        !            15: #include "../h/vmmac.h"
        !            16: #include "../h/vmmeter.h"
        !            17: #include "../h/vmparam.h"
        !            18: #include "../h/map.h"
        !            19: #include "../h/buf.h"
        !            20: #include "../h/dir.h"
        !            21: #include "../h/user.h"
        !            22: #include "../h/proc.h"
        !            23: #include "../h/conf.h"
        !            24: /*#include "../h/kernel.h"*/
        !            25: 
        !            26: #include "../machine/mmu.h"
        !            27: #include "../machine/cpu.h"
        !            28: #include "../machine/psl.h"
        !            29: #include "../machine/pte.h"
        !            30: #include "../machine/reg.h"
        !            31: 
        !            32: #include "../sundev/mbvar.h"
        !            33: 
        !            34: /*
        !            35:  * Do transfer on controller argument.
        !            36:  * We queue for resource wait in the Mainbus code if necessary.
        !            37:  * We return 1 if the transfer was started, 0 if it was not.
        !            38:  * If you call this routine with the head of the queue for a
        !            39:  * Mainbus, it will automatically remove the controller from the Mainbus
        !            40:  * queue before it returns.  If some other controller is given
        !            41:  * as argument, it will be added to the request queue if the
        !            42:  * request cannot be started immediately.  This means that
        !            43:  * passing a controller which is on the queue but not at the head
        !            44:  * of the request queue is likely to be a disaster.
        !            45:  */
        !            46: mbgo(mc)
        !            47:        register struct mb_ctlr *mc;
        !            48: {
        !            49:        register struct mb_hd *mh = mc->mc_mh;
        !            50:        register struct buf *bp = mc->mc_tab.b_actf->b_actf;
        !            51:        register int s;
        !            52: 
        !            53:        s = splx(pritospl(SPLMB));
        !            54:        if ((mc->mc_driver->mdr_flags & MDR_XCLU) &&
        !            55:            mh->mh_users > 0 || mh->mh_xclu)
        !            56:                goto rwait;
        !            57:        mc->mc_mbinfo = mbsetup(mh, bp, MB_CANTWAIT);
        !            58:        if (mc->mc_mbinfo == 0)
        !            59:                goto rwait;
        !            60:        mh->mh_users++;
        !            61:        if (mc->mc_driver->mdr_flags & MDR_XCLU)
        !            62:                mh->mh_xclu = 1;
        !            63:        (void) splx(s);
        !            64:        if (mh->mh_actf == mc)
        !            65:                mh->mh_actf = mc->mc_forw;
        !            66:        if ((mc->mc_driver->mdr_flags & MDR_SWAB) && (bp->b_flags&B_READ)==0)
        !            67:                swab(bp->b_un.b_addr, bp->b_un.b_addr, (int)bp->b_bcount);
        !            68:        (*mc->mc_driver->mdr_go)(mc);
        !            69:        return (1);
        !            70: rwait:
        !            71:        if (mh->mh_actf != mc) {
        !            72:                mc->mc_forw = NULL;
        !            73:                if (mh->mh_actf == NULL)
        !            74:                        mh->mh_actf = mc;
        !            75:                else
        !            76:                        mh->mh_actl->mc_forw = mc;
        !            77:                mh->mh_actl = mc;
        !            78:        }
        !            79:        (void) splx(s);
        !            80:        return (0);
        !            81: }
        !            82: 
        !            83: mbdone(mc)
        !            84:        register struct mb_ctlr *mc;
        !            85: {
        !            86:        register struct mb_hd *mh = mc->mc_mh;
        !            87:        register struct buf *bp = mc->mc_tab.b_actf->b_actf;
        !            88: 
        !            89:        if (mc->mc_driver->mdr_flags & MDR_XCLU)
        !            90:                mh->mh_xclu = 0;
        !            91:        mh->mh_users--;
        !            92:        mbrelse(mh, &mc->mc_mbinfo);
        !            93:        if (mc->mc_driver->mdr_flags & MDR_SWAB)
        !            94:                swab(bp->b_un.b_addr, bp->b_un.b_addr, (int)bp->b_bcount);
        !            95:        (*mc->mc_driver->mdr_done)(mc);
        !            96: }
        !            97: 
        !            98: /*
        !            99:  * Allocate and setup Mainbus map registers.
        !           100:  * Flags says whether the caller can't
        !           101:  * wait (e.g. if the caller is at interrupt level).
        !           102:  *
        !           103:  * We also allow DMA to memory already mapped at the Mainbus
        !           104:  * (e.g., for Sun Ethernet board memory) and denote this with
        !           105:  * a zero in the MBI_NMR field.
        !           106:  */
        !           107: mbsetup(mh, bp, flags)
        !           108:        register struct mb_hd *mh;
        !           109:        struct buf *bp;
        !           110:        int flags;
        !           111: {
        !           112:        int npf, reg;
        !           113:        register struct pte *pte;
        !           114:        register char *addr;
        !           115:        int s, o;
        !           116:        struct mbcookie mbcookie;
        !           117: #ifdef sun2
        !           118:        int uc;
        !           119: #endif
        !           120: 
        !           121:        o = (int)bp->b_un.b_addr & PGOFSET;
        !           122:        if ((bp->b_flags & B_PHYS) == 0)
        !           123:                pte = &Sysmap[btop((int)bp->b_un.b_addr - KERNELBASE)];
        !           124:        else {
        !           125:                if (bp->b_kmx == 0)
        !           126:                        panic("mbsetup: zero kmx");
        !           127:                pte = &Usrptmap[bp->b_kmx];
        !           128:        }
        !           129: 
        !           130:        npf = btoc(bp->b_bcount + o);
        !           131:        if (buscheck(pte, npf)) {
        !           132:                mbcookie.mbi_mapreg = pte->pg_pfnum;
        !           133:                mbcookie.mbi_offset = o;
        !           134:                return (*(int *)&mbcookie);
        !           135:        }
        !           136: 
        !           137:        /* Defensively invalidate the page following the allocation */
        !           138:        npf++;
        !           139:        s = splx(pritospl(SPLMB));
        !           140:        while ((reg = (int)rmalloc(mh->mh_map, (long)npf)) == 0) {
        !           141:                if (flags & MB_CANTWAIT) {
        !           142:                        (void) splx(s);
        !           143:                        return (0);
        !           144:                }
        !           145:                mh->mh_mrwant++;
        !           146:                sleep((caddr_t)&mh->mh_mrwant, PSWP);
        !           147:        }
        !           148:        (void) splx(s);
        !           149:        mbcookie.mbi_mapreg = reg;
        !           150:        mbcookie.mbi_offset = o;
        !           151:        addr = &DVMA[ctob(reg)];
        !           152: #ifdef sun2
        !           153:        uc = getusercontext();
        !           154:        setusercontext(KCONTEXT);
        !           155: #endif
        !           156:        while (--npf > 0) {
        !           157:                register int pfnum;
        !           158: 
        !           159:                switch (*(int *)pte & PGT_MASK) {
        !           160:                default:
        !           161:                        /* may not go from dvma back out to the bus */
        !           162:                        panic("mbsetup: bad PGT");
        !           163:                case PGT_OBMEM:
        !           164:                case PGT_OBIO:
        !           165:                        if ((pfnum = pte->pg_pfnum) == 0)
        !           166:                                panic("mbsetup: zero pfnum");
        !           167:                        setpgmap(addr, (long)(PG_V | PG_KW | pfnum));
        !           168:                        addr += NBPG;
        !           169:                        pte++;
        !           170:                }
        !           171:        }
        !           172:        setpgmap(addr, (long)0);
        !           173: #ifdef sun2
        !           174:        setusercontext(uc);
        !           175: #endif
        !           176:        return (*(int *)&mbcookie);
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Non buffer setup interface... set up a buffer and call mbsetup.
        !           181:  */
        !           182: mballoc(mh, addr, bcnt, flags)
        !           183:        struct mb_hd *mh;
        !           184:        caddr_t addr;
        !           185:        int bcnt, flags;
        !           186: {
        !           187:        struct buf mbbuf;
        !           188: 
        !           189:        mbbuf.b_un.b_addr = addr;
        !           190:        mbbuf.b_flags = B_BUSY;
        !           191:        mbbuf.b_bcount = bcnt;
        !           192:        /* that's all the fields mbsetup() needs */
        !           193:        return (mbsetup(mh, &mbbuf, flags));
        !           194: }
        !           195: 
        !           196: /*
        !           197:  * Release resources on Mainbus, and then unblock resource waiters.
        !           198:  * The map register parameter is by value since we need to block
        !           199:  * against Mainbus resets.
        !           200:  */
        !           201: mbrelse(mh, amr)
        !           202:        register struct mb_hd *mh;
        !           203:        int *amr;
        !           204: {
        !           205:        register int reg, s;
        !           206:        register char *addr;
        !           207:        int mr;
        !           208: #ifdef sun2
        !           209:        int uc;
        !           210: #endif
        !           211:  
        !           212:        /*
        !           213:         * Carefully see if we should release the space, since
        !           214:         * it may be released asynchronously at Mainbus reset time.
        !           215:         */
        !           216:        s = splx(pritospl(SPLMB));
        !           217:        mr = *amr;
        !           218:        if (mr == 0) {
        !           219:                printf("mbrelse: MR == 0!!!\n");
        !           220:                (void) splx(s);
        !           221:                return;
        !           222:        }
        !           223:        *amr = 0;
        !           224:        (void) splx(s);         /* let interrupts in, we're safe for a while */
        !           225: 
        !           226:        if ((reg = MBI_MR(mr)) < dvmasize) {    /* DVMA memory */
        !           227:                long getpgmap();
        !           228:                register int npf = 1;           /* plus one for last entry */
        !           229: 
        !           230: #ifdef sun2
        !           231:                uc = getusercontext();
        !           232:                setusercontext(KCONTEXT);
        !           233: #endif
        !           234:                for (addr = &DVMA[ctob(reg)]; getpgmap(addr) != (long)0;
        !           235:                    addr += NBPG, npf++)
        !           236:                        setpgmap(addr, (long)0);
        !           237: #ifdef sun2
        !           238:                setusercontext(uc);
        !           239: #endif
        !           240:                /*
        !           241:                 * Put back the registers in the resource map.
        !           242:                 * The map code must not be reentered, so we do this
        !           243:                 * at high spl.
        !           244:                 */
        !           245:                s = splx(pritospl(SPLMB));
        !           246:                rmfree(mh->mh_map, (long)npf, (long)reg);
        !           247:                (void) splx(s);
        !           248: 
        !           249:                /*
        !           250:                 * Wakeup sleepers for map registers,
        !           251:                 * and also, if there are processes blocked in mbgo(),
        !           252:                 * give them a chance at the Mainbus.
        !           253:                 */
        !           254:                if (mh->mh_mrwant) {
        !           255:                        mh->mh_mrwant = 0;
        !           256:                        wakeup((caddr_t)&mh->mh_mrwant);
        !           257:                }
        !           258:        }
        !           259:        while (mh->mh_actf && mbgo(mh->mh_actf))
        !           260:                ;
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * Swap bytes in 16-bit [half-]words
        !           265:  * for going between the 11 and the interdata
        !           266:  */
        !           267: swab(pf, pt, n)
        !           268:        register caddr_t pf, pt;
        !           269:        register int n;
        !           270: {
        !           271:        register char temp;
        !           272: 
        !           273:        n = (n+1)>>1;
        !           274: 
        !           275:        while (--n >= 0) {
        !           276:                temp = *pf++;
        !           277:                *pt++ = *pf++;
        !           278:                *pt++ = temp;
        !           279:        }
        !           280: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.