Commit | Line | Data |
---|---|---|
f86df66c | 1 | /* uba.c 3.2 %G% */ |
c14fd247 BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/map.h" | |
5 | #include "../h/pte.h" | |
6 | #include "../h/uba.h" | |
7 | #include "../h/buf.h" | |
8 | #include "../h/dir.h" | |
9 | #include "../h/user.h" | |
10 | #include "../h/proc.h" | |
11 | #include "../h/vm.h" | |
12 | ||
13 | /* | |
14 | * Allocate as many contiguous UBA mapping registers | |
15 | * as are necessary to do transfer of bcnt bytes | |
16 | * to/from location baddr. Wait for enough map registers. | |
17 | * | |
18 | * Bdpflg is non-zero if a "buffered data path" (BDP) is | |
19 | * to be used, else 0 -> use direct data path (DDP). Return | |
20 | * | |
21 | * Bits 0-8 Byte offset | |
22 | * Bits 9-17 Start map reg. no. | |
23 | * Bits 18-27 No. mapping reg's | |
24 | * Bits 28-31 BDP no. | |
25 | */ | |
26 | ubasetup(bp, bdpflg) | |
27 | struct buf *bp; | |
28 | { | |
29 | register int temp, i; | |
30 | int npf, reg, bdp; | |
31 | unsigned v; | |
32 | register struct pte *pte, *io; | |
33 | struct proc *rp; | |
34 | int a, o, ubinfo; | |
35 | ||
36 | v = btop(bp->b_un.b_addr); | |
37 | o = (int)bp->b_un.b_addr & PGOFSET; | |
38 | npf = btoc(bp->b_bcount + o) + 1; | |
39 | a = spl6(); | |
40 | while ((reg = malloc(ubamap, npf)) == 0) { | |
41 | umrwant++; | |
42 | sleep((caddr_t)ubamap, PSWP); | |
43 | } | |
44 | reg--; | |
45 | bdp = 0; | |
46 | if (bdpflg) | |
47 | while ((bdp = malloc(bdpmap, 1)) == 0) { | |
48 | bdpwant++; | |
49 | sleep((caddr_t)bdpmap, PSWP); | |
50 | } | |
51 | splx(a); | |
52 | ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o; | |
53 | io = &(((struct uba_regs *)UBA0)->uba_map[reg]); | |
54 | temp = (bdp << 21) | MRV; | |
55 | rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; | |
56 | if (bdp && (o & 01)) | |
57 | temp |= BO; | |
58 | if (bp->b_flags & B_UAREA) { | |
59 | for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) { | |
60 | if (rp->p_addr[i].pg_pfnum == 0) | |
61 | panic("uba: zero upage"); | |
62 | *(int *)io++ = rp->p_addr[i].pg_pfnum | temp; | |
63 | } | |
64 | } else if ((bp->b_flags & B_PHYS) == 0) { | |
65 | v &= 0x1fffff; /* drop to physical addr */ | |
66 | while (--npf != 0) | |
67 | *(int *)io++ = v++ | temp; | |
68 | } else { | |
69 | if (bp->b_flags & B_PAGET) | |
70 | pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; | |
71 | else | |
72 | pte = vtopte(rp, v); | |
73 | while (--npf != 0) { | |
74 | if (pte->pg_pfnum == 0) | |
75 | panic("uba zero uentry"); | |
76 | *(int *)io++ = pte++->pg_pfnum | temp; | |
77 | } | |
78 | } | |
79 | *(int *)io++ = 0; | |
80 | return (ubinfo); | |
81 | } | |
82 | ||
83 | struct buf ubabuf; | |
84 | /* | |
85 | * Non buffer unibus interface... set up a buffer and call ubasetup. | |
86 | */ | |
87 | uballoc(addr, bcnt, bdpflg) | |
88 | caddr_t addr; | |
89 | unsigned short bcnt; | |
90 | { | |
91 | register int a, ubinfo; | |
92 | ||
93 | a = spl6(); | |
94 | while (ubabuf.b_flags & B_BUSY) { | |
95 | ubabuf.b_flags |= B_WANTED; | |
96 | sleep((caddr_t)&ubabuf, PRIUBA); | |
97 | } | |
98 | ubabuf.b_un.b_addr = addr; | |
99 | ubabuf.b_flags = B_BUSY; | |
100 | ubabuf.b_bcount = bcnt; | |
101 | splx(a); | |
102 | ubinfo = ubasetup(&ubabuf, bdpflg); | |
103 | ubabuf.b_flags &= ~B_BUSY; | |
104 | if (ubabuf.b_flags & B_WANTED) | |
105 | wakeup((caddr_t)&ubabuf); | |
106 | return (ubinfo); | |
107 | } | |
108 | ||
109 | ubafree(mr) | |
110 | int mr; | |
111 | { | |
112 | register int bdp, reg, npf, a; | |
113 | ||
114 | a = spl6(); | |
115 | bdp = (mr >> 28) & 0x0f; | |
116 | if (bdp) { | |
117 | ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ | |
118 | mfree(bdpmap, 1, bdp); | |
119 | if (bdpwant) { | |
120 | bdpwant = 0; | |
121 | wakeup((caddr_t)bdpmap); | |
122 | } | |
123 | } | |
124 | npf = (mr >> 18) & 0x3ff; | |
125 | reg = ((mr >> 9) & 0x1ff) + 1; | |
126 | mfree(ubamap, npf, reg); | |
127 | if (umrwant) { | |
128 | umrwant = 0; | |
129 | wakeup((caddr_t)ubamap); | |
130 | } | |
131 | splx(a); | |
132 | } | |
133 | ||
134 | ubainit() | |
135 | { | |
136 | ||
137 | mfree(ubamap, 496, 1); | |
138 | mfree(bdpmap, 15, 1); | |
139 | } |