Annotation of coherent/b/kernel/i386/fakedma.c, revision 1.1.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.