Annotation of cci/sys/tahoe/_iosubr.c, revision 1.1

1.1     ! root        1: #include "../h/param.h"
        !             2: #include "../h/buf.h"
        !             3: #include "../h/cmap.h"
        !             4: #include "../h/conf.h"
        !             5: #include "../h/dir.h"
        !             6: #include "../h/dk.h"
        !             7: #include "../h/map.h"
        !             8: #include "../machine/mtpr.h"
        !             9: #include "../machine/pte.h"
        !            10: #include "../h/systm.h"
        !            11: #include "../vba/vbavar.h"
        !            12: #include "../h/user.h"
        !            13: #include "../h/vmmac.h"
        !            14: #include "../h/proc.h"
        !            15: 
        !            16: 
        !            17: /*
        !            18:  * Next piece of logic takes care of unusual cases when less (or more) than
        !            19:  * a full block (or sector) are required. This is done by the swaping
        !            20:  * logic, when it brings page table pages from the swap device.
        !            21:  * Since some controllers can't read less than a sector, the
        !            22:  * only alternative is to read the disk to a temporary buffer and
        !            23:  * then to move the amount needed back to the process (usually proc[0]
        !            24:  * or proc[2]).
        !            25:  * On Tahoe, the virtual addresses versus physical I/O problem creates
        !            26:  * the need to move I/O data through an intermediate buffer whenever one
        !            27:  * of the following is true:
        !            28:  *     1) The data length is not a multiple of sector size
        !            29:  *     2) The base address + length cross a physical page boundary
        !            30:  *     3) The virtual address for I/O is not in the system space.
        !            31:  */
        !            32: 
        !            33: buf_setup(bp, sectsize)
        !            34: register struct        buf *bp;
        !            35: long   sectsize;       /* This disk's physical sector size */
        !            36: {
        !            37: /*
        !            38:  * IO buffer preparation for possible buffered transfer.
        !            39:  * The relevant page table entries are kept in the 'buf' structure,
        !            40:  * for later use by the driver's 'start' routine or 'interrupt'
        !            41:  * routine, when user's data has to be moved to the intermediate
        !            42:  * buffer.
        !            43:  */
        !            44:        register struct pte *source_pte_adr;
        !            45:        register struct proc *rp;
        !            46:        register v;
        !            47: 
        !            48:        if ((((int)bp->b_un.b_addr & PGOFSET) + bp->b_bcount) > NBPG ||
        !            49:                        (bp->b_bcount % sectsize) != 0 ||
        !            50:                        ((int)bp->b_un.b_addr & 0xc0000000) != 0xc0000000) {
        !            51:                bp->b_flags |= B_NOT1K;
        !            52:                v = btop(bp->b_un.b_addr);
        !            53:                if (bp->b_flags & B_DIRTY)
        !            54:                        rp = &proc[2];
        !            55:                if (bp->b_flags & B_UAREA)
        !            56:                        source_pte_adr = &rp->p_addr[v];
        !            57:                else
        !            58:                        source_pte_adr = vtopte(rp, v);
        !            59:                bp->b_ptecnt = (bp->b_bcount + NBPG -1 +
        !            60:                        ((int)bp->b_un.b_addr & PGOFSET)) / NBPG;
        !            61:                bcopy (source_pte_adr, bp->b_upte, bp->b_ptecnt*4);
        !            62:        }
        !            63: }
        !            64: 
        !            65: int mapbusy;           /* semaphore on the system IOmap buffer */
        !            66: 
        !            67: get_ioadr(bp, buffer, map, utl)
        !            68: struct buf *bp;
        !            69: char   *buffer;        /* Driver's own intermediate buffer. */
        !            70: long   *map;           /* A bunch of system pte's */
        !            71: struct user *utl;      /* The system address mapped through 'map' */
        !            72: /*
        !            73:  * This routine is usually called by the 'start' routine. It
        !            74:  * returns the physical address of the first byte for IO, to
        !            75:  * be presented to the controller. If intermediate buffering is
        !            76:  * needed and a write out is done, now is the time to get the
        !            77:  * original user's data in the buffer.
        !            78:  */
        !            79: {
        !            80:        register phadr, i;
        !            81: 
        !            82:        if (bp->b_flags & B_NOT1K) {
        !            83:                phadr = vtoph (bp->b_proc, buffer);
        !            84:                if ( (bp->b_flags & B_READ) == 0) {
        !            85:                        for (i=0; i<bp->b_ptecnt; i++) {
        !            86:                                map[i] = bp->b_upte[i] 
        !            87:                                        & ~PG_PROT | PG_V | PG_KR;
        !            88:                                mtpr ((caddr_t)utl + i*NBPG, TBIS);
        !            89:                                mtpr ((caddr_t)utl + i*NBPG, P1DC);
        !            90:                        }
        !            91:                        bcopy (((int)bp->b_un.b_addr & PGOFSET) + 
        !            92:                                        (caddr_t)utl, buffer,bp->b_bcount);
        !            93:                }
        !            94:        } 
        !            95:        else
        !            96:                phadr = vtoph (bp->b_proc, bp->b_un.b_addr);
        !            97:        return (phadr);
        !            98: }
        !            99: 
        !           100: end_transfer(bp, buffer, map, utl)
        !           101: register struct buf *bp;
        !           102: char   *buffer;        /* Driver's own intermediate buffer. */
        !           103: long   *map;   /* A bunch of system pte's */
        !           104: struct user *utl;      /* The system address mapped through 'map' */
        !           105: {
        !           106: /*
        !           107:  * Called by the driver's interrupt routine, after the data is
        !           108:  * realy in or out. If that was a read, and the NOT1K flag was on,
        !           109:  * now is the time to move the data back into user's space. 
        !           110:  * Mostly analogous to the get_ioadr routine, but in the reverse direction.
        !           111:  */
        !           112:        register i, cnt;
        !           113: 
        !           114:        if (bp->b_flags & B_READ)
        !           115:                if (bp->b_flags & B_NOT1K) {
        !           116:                        for (cnt = bp->b_bcount ; cnt >= 0; cnt -= NBPG) {
        !           117:                                mtpr ((int)buffer + cnt-1, P1DC);
        !           118:                                mtpr ((caddr_t)bp->b_un.b_addr + cnt-1, P1DC);
        !           119:                        }
        !           120:                        if ( ((int)buffer & PGOFSET) != 0)
        !           121:                                mtpr (buffer, P1DC);
        !           122:                        if ( ((int)bp->b_un.b_addr & PGOFSET) != 0)
        !           123:                                mtpr ((caddr_t)bp->b_un.b_addr, P1DC);
        !           124:                        for (i=0; i<bp->b_ptecnt; i++) {
        !           125:                                map[i] = bp->b_upte[i] 
        !           126:                                        & ~PG_PROT | PG_V | PG_KW;
        !           127:                                mtpr ((caddr_t)utl + i*NBPG, TBIS);
        !           128:                        }
        !           129:                        bcopy (buffer, 
        !           130:                                ((int)bp->b_un.b_addr & PGOFSET) + 
        !           131:                                        (caddr_t)utl, bp->b_bcount);
        !           132:                }
        !           133:                else
        !           134:                        mtpr (bp->b_un.b_addr, P1DC);
        !           135:        bp->b_flags &= ~B_NOT1K;
        !           136: }
        !           137: 
        !           138: movob (byte, address)
        !           139: {
        !           140:        asm(" movob 7(fp),*8(fp);");
        !           141: }
        !           142: 
        !           143: movow (word, address)
        !           144: {
        !           145:        asm(" movow 6(fp),*8(fp);");
        !           146: }
        !           147: 

unix.superglobalmegacorp.com

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