|
|
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.