|
|
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: 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: caddr_t source_pte_adr; ! 45: ! 46: if ((((int)bp->b_un.b_addr & PGOFSET) + bp->b_bcount) > NBPG || ! 47: (bp->b_bcount % sectsize) != 0 || ! 48: ((int)bp->b_un.b_addr & 0xc0000000) != 0xc0000000) { ! 49: bp->b_flags |= B_NOT1K; ! 50: if (bp->b_flags & B_DIRTY) ! 51: source_pte_adr = (caddr_t)vtopte(&proc[2], ! 52: btop(bp->b_un.b_addr)); ! 53: else source_pte_adr = (caddr_t)vtopte(bp->b_proc, ! 54: btop(bp->b_un.b_addr)); ! 55: bp->b_ptecnt = (bp->b_bcount + NBPG -1 + ! 56: ((int)bp->b_un.b_addr & PGOFSET)) / NBPG; ! 57: bcopy (source_pte_adr, bp->b_upte, bp->b_ptecnt*4); ! 58: } ! 59: } ! 60: ! 61: int mapbusy; /* semaphore on the system IOmap buffer */ ! 62: ! 63: get_ioadr(bp, buffer, map, utl) ! 64: struct buf *bp; ! 65: char *buffer; /* Driver's own intermediate buffer. */ ! 66: long *map; /* A bunch of system pte's */ ! 67: struct user *utl; /* The system address mapped through 'map' */ ! 68: /* ! 69: * This routine is usually called by the 'start' routine. It ! 70: * returns the physical address of the first byte for IO, to ! 71: * be presented to the controller. If intermediate buffering is ! 72: * needed and a write out is done, now is the time to get the ! 73: * original user's data in the buffer. ! 74: */ ! 75: { ! 76: register phadr, i; ! 77: ! 78: if (bp->b_flags & B_NOT1K) { ! 79: phadr = vtoph (bp->b_proc, buffer); ! 80: if ( (bp->b_flags & B_READ) == 0) { ! 81: for (i=0; i<bp->b_ptecnt; i++) { ! 82: map[i] = bp->b_upte[i] ! 83: & ~PG_PROT | PG_V | PG_KR; ! 84: mtpr ((caddr_t)utl + i*NBPG, TBIS); ! 85: mtpr ((caddr_t)utl + i*NBPG, P1DC); ! 86: } ! 87: bcopy (((int)bp->b_un.b_addr & PGOFSET) + ! 88: (caddr_t)utl, buffer,bp->b_bcount); ! 89: } ! 90: } ! 91: else ! 92: phadr = vtoph (bp->b_proc, bp->b_un.b_addr); ! 93: return (phadr); ! 94: } ! 95: ! 96: end_transfer(bp, buffer, map, utl) ! 97: register struct buf *bp; ! 98: char *buffer; /* Driver's own intermediate buffer. */ ! 99: long *map; /* A bunch of system pte's */ ! 100: struct user *utl; /* The system address mapped through 'map' */ ! 101: { ! 102: /* ! 103: * Called by the driver's interrupt routine, after the data is ! 104: * realy in or out. If that was a read, and the NOT1K flag was on, ! 105: * now is the time to move the data back into user's space. ! 106: * Mostly analogous to the get_ioadr routine, but in the reverse direction. ! 107: */ ! 108: register i, cnt; ! 109: ! 110: if (bp->b_flags & B_READ) ! 111: if (bp->b_flags & B_NOT1K) { ! 112: for (cnt = bp->b_bcount ; cnt >= 0; cnt -= NBPG) { ! 113: mtpr ((int)buffer + cnt-1, P1DC); ! 114: mtpr ((caddr_t)bp->b_un.b_addr + cnt-1, P1DC); ! 115: } ! 116: if ( ((int)buffer & PGOFSET) != 0) ! 117: mtpr (buffer, P1DC); ! 118: if ( ((int)bp->b_un.b_addr & PGOFSET) != 0) ! 119: mtpr ((caddr_t)bp->b_un.b_addr, P1DC); ! 120: for (i=0; i<bp->b_ptecnt; i++) { ! 121: map[i] = bp->b_upte[i] ! 122: & ~PG_PROT | PG_V | PG_KW; ! 123: mtpr ((caddr_t)utl + i*NBPG, TBIS); ! 124: } ! 125: bcopy (buffer, ! 126: ((int)bp->b_un.b_addr & PGOFSET) + ! 127: (caddr_t)utl, bp->b_bcount); ! 128: } ! 129: else ! 130: mtpr (bp->b_un.b_addr, P1DC); ! 131: bp->b_flags &= ~B_NOT1K; ! 132: } ! 133: ! 134: movob (byte, address) ! 135: { ! 136: asm(" movob 7(fp),*8(fp);"); ! 137: } ! 138: ! 139: movow (word, address) ! 140: { ! 141: asm(" movow 6(fp),*8(fp);"); ! 142: } ! 143:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.