Commit | Line | Data |
---|---|---|
b28deaf8 | 1 | /* uba.c 4.4 %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" | |
2e74ef16 | 12 | #include "../h/conf.h" |
868a6a95 | 13 | #include "../h/mtpr.h" |
c14fd247 BJ |
14 | |
15 | /* | |
16 | * Allocate as many contiguous UBA mapping registers | |
17 | * as are necessary to do transfer of bcnt bytes | |
18 | * to/from location baddr. Wait for enough map registers. | |
19 | * | |
20 | * Bdpflg is non-zero if a "buffered data path" (BDP) is | |
21 | * to be used, else 0 -> use direct data path (DDP). Return | |
22 | * | |
23 | * Bits 0-8 Byte offset | |
24 | * Bits 9-17 Start map reg. no. | |
25 | * Bits 18-27 No. mapping reg's | |
26 | * Bits 28-31 BDP no. | |
27 | */ | |
28 | ubasetup(bp, bdpflg) | |
29 | struct buf *bp; | |
30 | { | |
31 | register int temp, i; | |
32 | int npf, reg, bdp; | |
33 | unsigned v; | |
34 | register struct pte *pte, *io; | |
35 | struct proc *rp; | |
36 | int a, o, ubinfo; | |
37 | ||
38 | v = btop(bp->b_un.b_addr); | |
39 | o = (int)bp->b_un.b_addr & PGOFSET; | |
40 | npf = btoc(bp->b_bcount + o) + 1; | |
41 | a = spl6(); | |
42 | while ((reg = malloc(ubamap, npf)) == 0) { | |
89e0f717 | 43 | panic("ran out of uba map"); |
c14fd247 BJ |
44 | umrwant++; |
45 | sleep((caddr_t)ubamap, PSWP); | |
46 | } | |
47 | reg--; | |
48 | bdp = 0; | |
49 | if (bdpflg) | |
50 | while ((bdp = malloc(bdpmap, 1)) == 0) { | |
89e0f717 | 51 | panic("ran out of bdp's"); |
c14fd247 BJ |
52 | bdpwant++; |
53 | sleep((caddr_t)bdpmap, PSWP); | |
54 | } | |
55 | splx(a); | |
56 | ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o; | |
57 | io = &(((struct uba_regs *)UBA0)->uba_map[reg]); | |
58 | temp = (bdp << 21) | MRV; | |
59 | rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; | |
60 | if (bdp && (o & 01)) | |
61 | temp |= BO; | |
62 | if (bp->b_flags & B_UAREA) { | |
63 | for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) { | |
64 | if (rp->p_addr[i].pg_pfnum == 0) | |
65 | panic("uba: zero upage"); | |
66 | *(int *)io++ = rp->p_addr[i].pg_pfnum | temp; | |
67 | } | |
68 | } else if ((bp->b_flags & B_PHYS) == 0) { | |
da1392b6 | 69 | pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)]; |
c14fd247 | 70 | while (--npf != 0) |
da1392b6 | 71 | *(int *)io++ = pte++->pg_pfnum | temp; |
c14fd247 BJ |
72 | } else { |
73 | if (bp->b_flags & B_PAGET) | |
74 | pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; | |
75 | else | |
76 | pte = vtopte(rp, v); | |
77 | while (--npf != 0) { | |
78 | if (pte->pg_pfnum == 0) | |
79 | panic("uba zero uentry"); | |
80 | *(int *)io++ = pte++->pg_pfnum | temp; | |
81 | } | |
82 | } | |
83 | *(int *)io++ = 0; | |
84 | return (ubinfo); | |
85 | } | |
86 | ||
c14fd247 BJ |
87 | /* |
88 | * Non buffer unibus interface... set up a buffer and call ubasetup. | |
89 | */ | |
90 | uballoc(addr, bcnt, bdpflg) | |
91 | caddr_t addr; | |
92 | unsigned short bcnt; | |
93 | { | |
89e0f717 | 94 | struct buf ubabuf; |
c14fd247 | 95 | |
c14fd247 BJ |
96 | ubabuf.b_un.b_addr = addr; |
97 | ubabuf.b_flags = B_BUSY; | |
98 | ubabuf.b_bcount = bcnt; | |
89e0f717 BJ |
99 | /* that's all the fields ubasetup() needs */ |
100 | return (ubasetup(&ubabuf, bdpflg)); | |
c14fd247 BJ |
101 | } |
102 | ||
b28deaf8 BJ |
103 | /* |
104 | * Old ubafree(info) is now ubarelse(&info) to avoid races. | |
105 | */ | |
106 | ubafree(amr) | |
107 | int *amr; | |
c14fd247 BJ |
108 | { |
109 | register int bdp, reg, npf, a; | |
b28deaf8 | 110 | int mr; |
c14fd247 BJ |
111 | |
112 | a = spl6(); | |
b28deaf8 BJ |
113 | mr = *amr; |
114 | if (mr == 0) { | |
115 | splx(a); | |
116 | return; | |
117 | } | |
c14fd247 BJ |
118 | bdp = (mr >> 28) & 0x0f; |
119 | if (bdp) { | |
120 | ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ | |
121 | mfree(bdpmap, 1, bdp); | |
122 | if (bdpwant) { | |
123 | bdpwant = 0; | |
124 | wakeup((caddr_t)bdpmap); | |
125 | } | |
126 | } | |
127 | npf = (mr >> 18) & 0x3ff; | |
128 | reg = ((mr >> 9) & 0x1ff) + 1; | |
129 | mfree(ubamap, npf, reg); | |
130 | if (umrwant) { | |
131 | umrwant = 0; | |
132 | wakeup((caddr_t)ubamap); | |
133 | } | |
134 | splx(a); | |
135 | } | |
136 | ||
137 | ubainit() | |
138 | { | |
139 | ||
140 | mfree(ubamap, 496, 1); | |
868a6a95 | 141 | mfree(bdpmap, NUBABDP, 1); |
c14fd247 | 142 | } |
2e74ef16 BJ |
143 | |
144 | #define DELAY(N) { register int d; d = N; while (--d > 0); } | |
145 | ||
146 | ubareset() | |
147 | { | |
148 | struct uba_regs *up = (struct uba_regs *)UBA0; | |
149 | register struct cdevsw *cdp; | |
49c84d3f | 150 | int s; |
2e74ef16 | 151 | |
4ea0bfc4 | 152 | s = spl6(); |
868a6a95 | 153 | #if VAX==780 |
2e74ef16 BJ |
154 | printf("UBA RESET:"); |
155 | up->uba_cr = ADINIT; | |
156 | up->uba_cr = IFS|BRIE|USEFIE|SUEFIE; | |
157 | while ((up->uba_cnfgr & UBIC) == 0) | |
158 | ; | |
868a6a95 BJ |
159 | #endif |
160 | #if VAX==750 | |
161 | printf("UNIBUS INIT:"); | |
162 | mtpr(IUR, 1); | |
163 | DELAY(100000); | |
164 | #endif | |
2e74ef16 BJ |
165 | for (cdp = cdevsw; cdp->d_open; cdp++) |
166 | (*cdp->d_reset)(); | |
167 | printf("\n"); | |
4ea0bfc4 | 168 | splx(s); |
2e74ef16 | 169 | } |