BSD 4 development
[unix-history] / usr / src / sys / dev / uba.c
CommitLineData
40b94a16
BJ
1/* uba.c 4.2 11/9/80 */
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#include "../h/conf.h"
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 */
27ubasetup(bp, bdpflg)
28struct 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) {
42 panic("ran out of uba map");
43 umrwant++;
44 sleep((caddr_t)ubamap, PSWP);
45 }
46 reg--;
47 bdp = 0;
48 if (bdpflg)
49 while ((bdp = malloc(bdpmap, 1)) == 0) {
50 panic("ran out of bdp's");
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) {
68 pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
69 while (--npf != 0)
70 *(int *)io++ = pte++->pg_pfnum | temp;
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
86/*
87 * Non buffer unibus interface... set up a buffer and call ubasetup.
88 */
89uballoc(addr, bcnt, bdpflg)
90 caddr_t addr;
91 unsigned short bcnt;
92{
93 struct buf ubabuf;
94
95 ubabuf.b_un.b_addr = addr;
96 ubabuf.b_flags = B_BUSY;
97 ubabuf.b_bcount = bcnt;
98 /* that's all the fields ubasetup() needs */
99 return (ubasetup(&ubabuf, bdpflg));
100}
101
102ubafree(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
127ubainit()
128{
129
130 mfree(ubamap, 496, 1);
131 mfree(bdpmap, 15, 1);
132}
133
134#define DELAY(N) { register int d; d = N; while (--d > 0); }
135
136ubareset()
137{
138 struct uba_regs *up = (struct uba_regs *)UBA0;
139 register struct cdevsw *cdp;
140 int s;
141
142 s = spl6();
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");
151 splx(s);
152}