xref: /csrg-svn/sys/vax/uba/uba.c (revision 728)
1 /*	uba.c	3.5	08/27/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  */
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) {
42 		umrwant++;
43 		sleep((caddr_t)ubamap, PSWP);
44 	}
45 	reg--;
46 	bdp = 0;
47 	if (bdpflg)
48 		while ((bdp = malloc(bdpmap, 1)) == 0) {
49 			bdpwant++;
50 			sleep((caddr_t)bdpmap, PSWP);
51 		}
52 	splx(a);
53 	ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
54 	io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
55 	temp = (bdp << 21) | MRV;
56 	rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
57 	if (bdp && (o & 01))
58 		temp |= BO;
59 	if (bp->b_flags & B_UAREA) {
60 		for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
61 			if (rp->p_addr[i].pg_pfnum == 0)
62 				panic("uba: zero upage");
63 			*(int *)io++ = rp->p_addr[i].pg_pfnum | temp;
64 		}
65 	} else if ((bp->b_flags & B_PHYS) == 0) {
66 		pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
67 		while (--npf != 0)
68 			*(int *)io++ = pte++->pg_pfnum | temp;
69 	} else {
70 		if (bp->b_flags & B_PAGET)
71 			pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
72 		else
73 			pte = vtopte(rp, v);
74 		while (--npf != 0) {
75 			if (pte->pg_pfnum == 0)
76 				panic("uba zero uentry");
77 			*(int *)io++ = pte++->pg_pfnum | temp;
78 		}
79 	}
80 	*(int *)io++ = 0;
81 	return (ubinfo);
82 }
83 
84 struct	buf ubabuf;
85 /*
86  * Non buffer unibus interface... set up a buffer and call ubasetup.
87  */
88 uballoc(addr, bcnt, bdpflg)
89 	caddr_t addr;
90 	unsigned short bcnt;
91 {
92 	register int a, ubinfo;
93 
94 	a = spl6();
95 	while (ubabuf.b_flags & B_BUSY) {
96 		ubabuf.b_flags |= B_WANTED;
97 		sleep((caddr_t)&ubabuf, PRIUBA);
98 	}
99 	ubabuf.b_un.b_addr = addr;
100 	ubabuf.b_flags = B_BUSY;
101 	ubabuf.b_bcount = bcnt;
102 	splx(a);
103 	ubinfo = ubasetup(&ubabuf, bdpflg);
104 	ubabuf.b_flags &= ~B_BUSY;
105 	if (ubabuf.b_flags & B_WANTED)
106 		wakeup((caddr_t)&ubabuf);
107 	return (ubinfo);
108 }
109 
110 ubafree(mr)
111 	int mr;
112 {
113 	register int bdp, reg, npf, a;
114 
115 	a = spl6();
116 	bdp = (mr >> 28) & 0x0f;
117 	if (bdp) {
118 		((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE;	/* purge */
119 		mfree(bdpmap, 1, bdp);
120 		if (bdpwant) {
121 			bdpwant = 0;
122 			wakeup((caddr_t)bdpmap);
123 		}
124 	}
125 	npf = (mr >> 18) & 0x3ff;
126 	reg = ((mr >> 9) & 0x1ff) + 1;
127 	mfree(ubamap, npf, reg);
128 	if (umrwant) {
129 		umrwant = 0;
130 		wakeup((caddr_t)ubamap);
131 	}
132 	splx(a);
133 }
134 
135 ubainit()
136 {
137 
138 	mfree(ubamap, 496, 1);
139 	mfree(bdpmap, 15, 1);
140 }
141 
142 #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
143 
144 ubareset()
145 {
146 	struct uba_regs *up = (struct uba_regs *)UBA0;
147 	register struct cdevsw *cdp;
148 	int i, s;
149 
150 	s = spl6();
151 	printf("UBA RESET:");
152 	up->uba_cr = ADINIT;
153 	up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
154 	while ((up->uba_cnfgr & UBIC) == 0)
155 		;
156 	for (cdp = cdevsw; cdp->d_open; cdp++)
157 		(*cdp->d_reset)();
158 	printf("\n");
159 	splx(s);
160 }
161