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