|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.