Annotation of researchv9/sys/sundev/mb.c, revision 1.1.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.