xref: /original-bsd/sys/vax/uba/uba.c (revision d25e1985)
1 /*	uba.c	3.6	09/16/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 		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  */
89 uballoc(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 
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 }
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;
140 	int i, 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 }
153