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