Annotation of coherent/b/kernel/i386/fakedma.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * these routines are written in C until the 386 compiler/assembler
        !             3:  * are available
        !             4:  *
        !             5:  * Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991
        !             6:  */
        !             7: 
        !             8: #include <sys/coherent.h>
        !             9: #include <sys/reg.h>
        !            10: #include <sys/clist.h>
        !            11: #include <errno.h>
        !            12: #include <sys/inode.h>
        !            13: #include <sys/proc.h>
        !            14: #include <sys/seg.h>
        !            15: #include <signal.h>
        !            16: #include <sys/uproc.h>
        !            17: #include <sys/buf.h>
        !            18: 
        !            19: #define        min(a, b)       ((a) < (b) ? (a) : (b))
        !            20: 
        !            21: /*
        !            22:  * dmacopy()
        !            23:  *
        !            24:  * Copy "npage" 4 kbyte pages from phys addr "from" to phys addr "to".
        !            25:  */
        !            26: dmacopy(npage, from, to) 
        !            27: long   npage;
        !            28: cseg_t *from, *to;
        !            29: {
        !            30:        int save = setspace(SEG_386_KD);
        !            31: 
        !            32:        while (npage--) {
        !            33:                int work = workAlloc(); /* Get a virtual click pair. */
        !            34:                ptable1_v[work] = *from++ | SEG_SRW;
        !            35:                ptable1_v[work + 1] = *to++ | SEG_SRW;
        !            36:                mmuupd();
        !            37:                copyseg_d(NBPC, ctob(work), ctob(work + 1));
        !            38:                workFree(work);
        !            39:        }
        !            40:        setspace(save);
        !            41: }
        !            42: 
        !            43: /*
        !            44:  * dmaclear()
        !            45:  *
        !            46:  * Given a byte count, a system global address, and a fill value,
        !            47:  * write the fill value through the given range of memory.
        !            48:  */
        !            49: dmaclear(nbytes, to, fill)
        !            50: long   nbytes, fill;
        !            51: paddr_t        to;
        !            52: {
        !            53:        unsigned off;
        !            54:        int     n;
        !            55:        cseg_t *base;
        !            56:        int save = setspace(SEG_386_KD);
        !            57:        int work = workAlloc(); /* Get a virtual click pair. */
        !            58: 
        !            59:        off = to & (NBPC-1);
        !            60:        base = &sysmem.u.pbase[btocrd(to)];
        !            61:        n = min(nbytes, NBPC-off);
        !            62:        ptable1_v[work] = *base++ | SEG_SRW;
        !            63:        mmuupd();
        !            64:        
        !            65:        clearseg_d(n, ctob(work)+off, fill);
        !            66:        nbytes -= n;
        !            67: 
        !            68:        while (nbytes >= NBPC) {
        !            69:                ptable1_v[work] = *base++ | SEG_SRW;
        !            70:                mmuupd();
        !            71:                clearseg_d(NBPC, ctob(work), fill);
        !            72:                nbytes -= NBPC;
        !            73:        }
        !            74: 
        !            75:        if (nbytes) {
        !            76:                ptable1_v[work] = *base++ | SEG_SRW;
        !            77:                mmuupd();
        !            78:                clearseg_d(nbytes, ctob(work), fill);
        !            79:        }
        !            80:        setspace(save);
        !            81:        workFree(work);
        !            82: }
        !            83: 
        !            84: /*
        !            85:  * dmain()
        !            86:  * 
        !            87:  * Copy in "nbytes" from system global address "to" to kernel address
        !            88:  * "vaddr".
        !            89:  */
        !            90: dmain(nbytes, to, vaddr)
        !            91: long   nbytes;
        !            92: paddr_t        to;
        !            93: caddr_t        vaddr;
        !            94: {
        !            95:        unsigned off;
        !            96:        unsigned        n, n1;
        !            97:        cseg_t* base;
        !            98:        int work = workAlloc(); /* Get a virtual click pair. */
        !            99:        int save = setspace(SEG_386_KD);
        !           100: 
        !           101:        off = to & (NBPC-1);
        !           102:        base = &sysmem.u.pbase[btocrd(to)];
        !           103: 
        !           104:        n = min(nbytes, NBPC-off);
        !           105:        ptable1_v[work] = *base++ | SEG_SRW;
        !           106:        mmuupd();
        !           107: 
        !           108:        if (nbytes==n) {
        !           109:                /*
        !           110:                 * only one page
        !           111:                 * n = min(n & (sizeof(long)-1), n)
        !           112:                 * copy n bytes; nbytes -= n;
        !           113:                 * copy (nbytes >> 2) long words; nbytes &= sizeof(long)-1
        !           114:                 * copy nbytes bytes
        !           115:                 */
        !           116:                if (n >= sizeof(long))
        !           117:                        n &= sizeof(long)-1;
        !           118:                if (n)
        !           119:                        copyseg_b(n, ctob(work)+off, vaddr);
        !           120:                off += n;
        !           121:                vaddr += n;
        !           122:                nbytes -= n;
        !           123:                if (n = nbytes & ~(sizeof(long)-1)) {
        !           124:                        copyseg_d(n, ctob(work)+off, vaddr);
        !           125:                        off += n;
        !           126:                        vaddr += n;
        !           127:                        nbytes -= n;
        !           128:                }
        !           129:        } else {
        !           130:                /*
        !           131:                 * more than one page
        !           132:                 * copy n&3 bytes
        !           133:                 * copy n >> 2 long words
        !           134:                 * in the first page
        !           135:                 */                     
        !           136:                if (n1 = n & 3)
        !           137:                        copyseg_b(n1, ctob(work)+off, vaddr);
        !           138:                off += n1;
        !           139:                vaddr += n1;
        !           140:                nbytes -= n1;
        !           141:                if (n = n & ~(sizeof(long)-1)) {
        !           142:                        copyseg_d(n, ctob(work)+off, vaddr);
        !           143:                        off += n;
        !           144:                        vaddr += n;
        !           145:                        nbytes -= n;
        !           146:                }
        !           147: 
        !           148:                /*
        !           149:                 * copy nbytes>>BPCSHIFT full pages
        !           150:                 */
        !           151:                while (nbytes >= NBPC) {
        !           152:                        ptable1_v[work] = *base++ | SEG_SRW;
        !           153:                        mmuupd();
        !           154:        
        !           155:                        copyseg_d(NBPC, ctob(work), vaddr);
        !           156:                        vaddr += NBPC;
        !           157:                        nbytes -= NBPC;
        !           158:                }
        !           159:                /*
        !           160:                 * page n-1 (last one)
        !           161:                 *
        !           162:                 * copy nbytes>>2 long words
        !           163:                 * copy nbytes & 3 bytes
        !           164:                 */
        !           165:                ptable1_v[work] = *base++ | SEG_SRW;
        !           166:                mmuupd();
        !           167:        
        !           168:                if (n = nbytes & ~(sizeof(long)-1)) {
        !           169:                        copyseg_d(n, ctob(work), vaddr);
        !           170:                        vaddr += n;
        !           171:                        nbytes -= n;
        !           172:                }
        !           173:                if (nbytes)
        !           174:                        copyseg_b(nbytes, ctob(work)+n, vaddr);
        !           175:        }
        !           176: 
        !           177:        setspace(save);
        !           178:        workFree(work);
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * dmaout()
        !           183:  * 
        !           184:  * Copy out "nbytes" from kernel address "vaddr" to system global address
        !           185:  * "to".
        !           186:  */
        !           187: dmaout(nbytes, to, vaddr)
        !           188: long   nbytes;
        !           189: paddr_t        to;
        !           190: caddr_t        vaddr;
        !           191: {
        !           192:        unsigned off;
        !           193:        unsigned        n, n1;
        !           194:        cseg_t *base;
        !           195:        int work = workAlloc(); /* Get a virtual click pair. */
        !           196:        int save = setspace(SEG_386_KD);
        !           197: 
        !           198:        off = to & (NBPC-1);
        !           199:        base = &sysmem.u.pbase[btocrd(to)];
        !           200: 
        !           201:        n = min(nbytes, NBPC-off);
        !           202:        ptable1_v[work] = *base++ | SEG_SRW;
        !           203:        mmuupd();
        !           204: 
        !           205:        if (nbytes==n) {
        !           206:                /*
        !           207:                 * only one page
        !           208:                 * n = min(n & (sizeof(long)-1), n)
        !           209:                 * copy n bytes; nbytes -= n;
        !           210:                 * copy (nbytes >> 2) long words; nbytes &= sizeof(long)-1
        !           211:                 * copy nbytes bytes
        !           212:                 */
        !           213:                if (n1 = n & (sizeof(long)-1))
        !           214:                        copyseg_b(n1, vaddr, ctob(work)+off);
        !           215:                off += n1;
        !           216:                vaddr += n1;
        !           217:                nbytes -= n1;
        !           218:                if (n = nbytes & ~(sizeof(long)-1)) {
        !           219:                        copyseg_d(n, vaddr, ctob(work)+off);
        !           220:                        off += n;
        !           221:                        vaddr += n;
        !           222:                        nbytes -= n;
        !           223:                }
        !           224:        } else {
        !           225:                /*
        !           226:                 * more than one page
        !           227:                 * copy n&3 bytes
        !           228:                 * copy n >> 2 long words
        !           229:                 * in the first page
        !           230:                 */                     
        !           231:                if (n1 = n & (sizeof(long)-1))
        !           232:                        copyseg_b(n1, vaddr, ctob(work)+off);
        !           233:                off += n1;
        !           234:                vaddr += n1;
        !           235:                nbytes -= n1;
        !           236:                if (n = n & ~(sizeof(long)-1)) {
        !           237:                        copyseg_d(n, vaddr, ctob(work)+off);
        !           238:                        off += n;
        !           239:                        vaddr += n;
        !           240:                        nbytes -= n;
        !           241:                }
        !           242: 
        !           243:                /*
        !           244:                 * copy nbytes>>BPCSHIFT full pages
        !           245:                 */
        !           246:                while (nbytes >= NBPC) {
        !           247:                        ptable1_v[work] = *base++ | SEG_SRW;
        !           248:                        mmuupd();
        !           249:                        copyseg_d(NBPC, vaddr, ctob(work));
        !           250:                        vaddr += NBPC;
        !           251:                        nbytes -= NBPC;
        !           252:                }
        !           253: 
        !           254:                /* now the transfer to memory is click-aligned */
        !           255:                off = 0;
        !           256: 
        !           257:                /*
        !           258:                 * page n-1 (last one)
        !           259:                 *
        !           260:                 * copy nbytes>>2 long words
        !           261:                 * copy nbytes & 3 bytes
        !           262:                 */
        !           263:                ptable1_v[work] = *base++ | SEG_SRW;
        !           264:                mmuupd();
        !           265:        
        !           266:                if (n = nbytes & ~(sizeof(long)-1)) {
        !           267:                        copyseg_d(n, vaddr, ctob(work));
        !           268:                        vaddr += n;
        !           269:                        off += n;
        !           270:                        nbytes -= n;
        !           271:                }
        !           272:                if (nbytes)
        !           273:                        copyseg_b(nbytes, vaddr, ctob(work)+off);
        !           274:        }
        !           275: 
        !           276:        setspace(save);
        !           277:        workFree(work);
        !           278: }
        !           279: 
        !           280: /*
        !           281:  * dmaio2()
        !           282:  * 
        !           283:  * Copy in "nbytes" from an I/O port "port" to the system global address
        !           284:  * "to".
        !           285:  */
        !           286: dmaio2(nbytes, to, port)
        !           287: long   nbytes, port;
        !           288: paddr_t        to;
        !           289: {
        !           290:        unsigned off;
        !           291:        int     n;
        !           292:        cseg_t *base;
        !           293:        int save = setspace(SEG_386_KD);
        !           294:        int work = workAlloc(); /* Get a virtual click pair. */
        !           295: 
        !           296:        off = to & (NBPC-1);
        !           297:        base = &sysmem.u.pbase[btocrd(to)];
        !           298: 
        !           299:        n = min(nbytes, NBPC-off);
        !           300:        ptable1_v[work] = *base++ | SEG_SRW;
        !           301:        mmuupd();
        !           302:        
        !           303:        io2seg(n, ctob(work)+off, port);
        !           304:        nbytes -= n;
        !           305: 
        !           306:        while (nbytes >= NBPC) {
        !           307:                ptable1_v[work] = *base++ | SEG_SRW;
        !           308:                mmuupd();
        !           309:                io2seg(NBPC, ctob(work), port);
        !           310:                nbytes -= NBPC;
        !           311:        }
        !           312: 
        !           313:        if (nbytes) {
        !           314:                ptable1_v[work] = *base++ | SEG_SRW;
        !           315:                mmuupd();
        !           316:                io2seg(nbytes, ctob(work), port);
        !           317:        }
        !           318:        setspace(save);
        !           319:        workFree(work);
        !           320: }
        !           321: 
        !           322: /*
        !           323:  * dma2io()
        !           324:  * 
        !           325:  * Copy out "nbytes" from the system global address "from" to an I/O port
        !           326:  * "port".
        !           327:  */
        !           328: dma2io(nbytes, to, port)
        !           329: long   nbytes, port;
        !           330: paddr_t        to;
        !           331: {
        !           332:        unsigned off;
        !           333:        int     n;
        !           334:        cseg_t *base;
        !           335:        int save = setspace(SEG_386_KD);
        !           336:        int work = workAlloc(); /* Get a virtual click pair. */
        !           337: 
        !           338:        off = to & (NBPC-1);
        !           339:        base = &sysmem.u.pbase[btocrd(to)];
        !           340: 
        !           341:        n = min(nbytes, NBPC-off);
        !           342:        ptable1_v[work] = *base++ | SEG_SRW;
        !           343:        mmuupd();
        !           344:        
        !           345:        seg2io(n, ctob(work)+off, port);
        !           346:        nbytes -= n;
        !           347: 
        !           348:        while (nbytes >= NBPC) {
        !           349:                ptable1_v[work] = *base++ | SEG_SRW;
        !           350:                mmuupd();
        !           351:                seg2io(NBPC, ctob(work), port);
        !           352:                nbytes -= NBPC;
        !           353:        }
        !           354: 
        !           355:        if (nbytes) {
        !           356:                ptable1_v[work] = *base++ | SEG_SRW;
        !           357:                mmuupd();
        !           358:                seg2io(nbytes, ctob(work), port);
        !           359:        }
        !           360:        setspace(save);
        !           361:        workFree(work);
        !           362: }
        !           363: 
        !           364: /*
        !           365:  * pxcopy()
        !           366:  *
        !           367:  * copy "n" bytes of data at kernel address "v" from address "uo" in:
        !           368:  *     system global address space             (space&SEG_VIRT)
        !           369:  *     physical memory                         !(space&SEG_VIRT)
        !           370:  * Rights are determined by (space&~SEG_VIRT):
        !           371:  *     "v" can be anywhere in kernel address space     SEG_386_KD
        !           372:  *     "v" must be an address accessible to the user   SEG_386_UD
        !           373:  * Up to one click of data can be copied. No alignment restrictions
        !           374:  * on "uo" apply.
        !           375:  */
        !           376: pxcopy(uo, v, n, space)
        !           377: unsigned       uo;
        !           378: char   *v;
        !           379: register int n;
        !           380: {
        !           381:        cseg_t *base;
        !           382:        register        int save, err;
        !           383:        int work;
        !           384: 
        !           385:        if (n > NBPC)
        !           386:                return 0;
        !           387: 
        !           388:        work = workAlloc();
        !           389:        if (space & SEG_VIRT) {
        !           390:                space &= ~SEG_VIRT;
        !           391:                base = &sysmem.u.pbase[btocrd(uo)];
        !           392:                ptable1_v[work] = *base++ | SEG_SRW;
        !           393:                ptable1_v[work + 1] = *base++ | SEG_SRW;
        !           394:        } else {
        !           395:                ptable1_v[work] = (uo&~(NBPC-1)) + SEG_SRW;
        !           396:                ptable1_v[work + 1] = (uo&~(NBPC-1)) + NBPC + SEG_SRW;
        !           397:        }
        !           398:        mmuupd();
        !           399:        save = setspace(space);
        !           400: 
        !           401:        err = ukcopy(ctob(work) + (uo&(NBPC-1)), v, n);
        !           402:        setspace(save);
        !           403:        workFree(work);
        !           404:        return err;
        !           405: }
        !           406: 
        !           407: /*
        !           408:  * xpcopy()
        !           409:  * 
        !           410:  * copy "n" bytes of data from kernel address "v" to address "uo" in:
        !           411:  *      system global address space                      (space&SEG_VIRT)
        !           412:  *      physical memory                                 !(space&SEG_VIRT)
        !           413:  * Rights are determined by (space&~SEG_VIRT):
        !           414:  *      "v" can be anywhere in kernel address space      SEG_386_KD
        !           415:  *      "v" must be an address accessible to the user    SEG_386_UD
        !           416:  * Up to one click of data can be copied. No alignment restrictions on "uo"
        !           417:  * apply.
        !           418:  */
        !           419: xpcopy(v, uo, n, space)
        !           420: char   *v;
        !           421: unsigned uo;
        !           422: register int n;
        !           423: {
        !           424:        register cseg_t *base;
        !           425:        register        int save, err;
        !           426:        int work;
        !           427: 
        !           428:        if (n > NBPC)
        !           429:                return 0;
        !           430: 
        !           431:        work = workAlloc();
        !           432:        if (space & SEG_VIRT) {
        !           433:                space &= ~SEG_VIRT;
        !           434:                base = &sysmem.u.pbase[btocrd(uo)];
        !           435:                ptable1_v[work] = *base++ | SEG_SRW;
        !           436:                ptable1_v[work + 1] = *base++ | SEG_SRW;
        !           437:        } else {
        !           438:                ptable1_v[work] = (uo&~(NBPC-1)) + SEG_SRW;
        !           439:                ptable1_v[work + 1] = (uo&~(NBPC-1)) + NBPC + SEG_SRW;
        !           440:        }
        !           441:        mmuupd();
        !           442:        save = setspace(space);
        !           443: 
        !           444:        err = kucopy(v, ctob(work) + (uo&(NBPC-1)), n);
        !           445:        setspace(save);
        !           446:        workFree(work);
        !           447:        return err;
        !           448: }

unix.superglobalmegacorp.com

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