xref: /csrg-svn/sys/vax/uba/uba.c (revision 284)
1*284Sbill /*	uba.c	3.3	06/22/80	*/
240Sbill 
340Sbill #include "../h/param.h"
440Sbill #include "../h/map.h"
540Sbill #include "../h/pte.h"
640Sbill #include "../h/uba.h"
740Sbill #include "../h/buf.h"
840Sbill #include "../h/dir.h"
940Sbill #include "../h/user.h"
1040Sbill #include "../h/proc.h"
1140Sbill #include "../h/vm.h"
12*284Sbill #include "../h/conf.h"
1340Sbill 
1440Sbill /*
1540Sbill  * Allocate as many contiguous UBA mapping registers
1640Sbill  * as are necessary to do transfer of bcnt bytes
1740Sbill  * to/from location baddr.  Wait for enough map registers.
1840Sbill  *
1940Sbill  * Bdpflg is non-zero if a "buffered data path" (BDP) is
2040Sbill  * to be used, else 0 -> use direct data path (DDP).  Return
2140Sbill  *
2240Sbill  *	Bits 0-8	Byte offset
2340Sbill  *	Bits 9-17	Start map reg. no.
2440Sbill  *	Bits 18-27	No. mapping reg's
2540Sbill  *	Bits 28-31	BDP no.
2640Sbill  */
2740Sbill ubasetup(bp, bdpflg)
2840Sbill struct buf *bp;
2940Sbill {
3040Sbill 	register int temp, i;
3140Sbill 	int npf, reg, bdp;
3240Sbill 	unsigned v;
3340Sbill 	register struct pte *pte, *io;
3440Sbill 	struct proc *rp;
3540Sbill 	int a, o, ubinfo;
3640Sbill 
3740Sbill 	v = btop(bp->b_un.b_addr);
3840Sbill 	o = (int)bp->b_un.b_addr & PGOFSET;
3940Sbill 	npf = btoc(bp->b_bcount + o) + 1;
4040Sbill 	a = spl6();
4140Sbill 	while ((reg = malloc(ubamap, npf)) == 0) {
4240Sbill 		umrwant++;
4340Sbill 		sleep((caddr_t)ubamap, PSWP);
4440Sbill 	}
4540Sbill 	reg--;
4640Sbill 	bdp = 0;
4740Sbill 	if (bdpflg)
4840Sbill 		while ((bdp = malloc(bdpmap, 1)) == 0) {
4940Sbill 			bdpwant++;
5040Sbill 			sleep((caddr_t)bdpmap, PSWP);
5140Sbill 		}
5240Sbill 	splx(a);
5340Sbill 	ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
5440Sbill 	io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
5540Sbill 	temp = (bdp << 21) | MRV;
5640Sbill 	rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
5740Sbill 	if (bdp && (o & 01))
5840Sbill 		temp |= BO;
5940Sbill 	if (bp->b_flags & B_UAREA) {
6040Sbill 		for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
6140Sbill 			if (rp->p_addr[i].pg_pfnum == 0)
6240Sbill 				panic("uba: zero upage");
6340Sbill 			*(int *)io++ = rp->p_addr[i].pg_pfnum | temp;
6440Sbill 		}
6540Sbill 	} else if ((bp->b_flags & B_PHYS) == 0) {
6640Sbill 		v &= 0x1fffff;			/* drop to physical addr */
6740Sbill 		while (--npf != 0)
6840Sbill 			*(int *)io++ = v++ | temp;
6940Sbill 	} else {
7040Sbill 		if (bp->b_flags & B_PAGET)
7140Sbill 			pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
7240Sbill 		else
7340Sbill 			pte = vtopte(rp, v);
7440Sbill 		while (--npf != 0) {
7540Sbill 			if (pte->pg_pfnum == 0)
7640Sbill 				panic("uba zero uentry");
7740Sbill 			*(int *)io++ = pte++->pg_pfnum | temp;
7840Sbill 		}
7940Sbill 	}
8040Sbill 	*(int *)io++ = 0;
8140Sbill 	return (ubinfo);
8240Sbill }
8340Sbill 
8440Sbill struct	buf ubabuf;
8540Sbill /*
8640Sbill  * Non buffer unibus interface... set up a buffer and call ubasetup.
8740Sbill  */
8840Sbill uballoc(addr, bcnt, bdpflg)
8940Sbill 	caddr_t addr;
9040Sbill 	unsigned short bcnt;
9140Sbill {
9240Sbill 	register int a, ubinfo;
9340Sbill 
9440Sbill 	a = spl6();
9540Sbill 	while (ubabuf.b_flags & B_BUSY) {
9640Sbill 		ubabuf.b_flags |= B_WANTED;
9740Sbill 		sleep((caddr_t)&ubabuf, PRIUBA);
9840Sbill 	}
9940Sbill 	ubabuf.b_un.b_addr = addr;
10040Sbill 	ubabuf.b_flags = B_BUSY;
10140Sbill 	ubabuf.b_bcount = bcnt;
10240Sbill 	splx(a);
10340Sbill 	ubinfo = ubasetup(&ubabuf, bdpflg);
10440Sbill 	ubabuf.b_flags &= ~B_BUSY;
10540Sbill 	if (ubabuf.b_flags & B_WANTED)
10640Sbill 		wakeup((caddr_t)&ubabuf);
10740Sbill 	return (ubinfo);
10840Sbill }
10940Sbill 
11040Sbill ubafree(mr)
11140Sbill 	int mr;
11240Sbill {
11340Sbill 	register int bdp, reg, npf, a;
11440Sbill 
11540Sbill 	a = spl6();
11640Sbill 	bdp = (mr >> 28) & 0x0f;
11740Sbill 	if (bdp) {
11840Sbill 		((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE;	/* purge */
11940Sbill 		mfree(bdpmap, 1, bdp);
12040Sbill 		if (bdpwant) {
12140Sbill 			bdpwant = 0;
12240Sbill 			wakeup((caddr_t)bdpmap);
12340Sbill 		}
12440Sbill 	}
12540Sbill 	npf = (mr >> 18) & 0x3ff;
12640Sbill 	reg = ((mr >> 9) & 0x1ff) + 1;
12740Sbill 	mfree(ubamap, npf, reg);
12840Sbill 	if (umrwant) {
12940Sbill 		umrwant = 0;
13040Sbill 		wakeup((caddr_t)ubamap);
13140Sbill 	}
13240Sbill 	splx(a);
13340Sbill }
13440Sbill 
13540Sbill ubainit()
13640Sbill {
13740Sbill 
13840Sbill 	mfree(ubamap, 496, 1);
13940Sbill 	mfree(bdpmap, 15, 1);
14040Sbill }
141*284Sbill 
142*284Sbill #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
143*284Sbill 
144*284Sbill ubareset()
145*284Sbill {
146*284Sbill 	struct uba_regs *up = (struct uba_regs *)UBA0;
147*284Sbill 	register struct cdevsw *cdp;
148*284Sbill 	int i;
149*284Sbill 
150*284Sbill 	(void) spl6();
151*284Sbill 	printf("UBA RESET:");
152*284Sbill 	up->uba_cr = ADINIT;
153*284Sbill 	up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
154*284Sbill 	while ((up->uba_cnfgr & UBIC) == 0)
155*284Sbill 		;
156*284Sbill 	for (cdp = cdevsw; cdp->d_open; cdp++)
157*284Sbill 		(*cdp->d_reset)();
158*284Sbill 	printf("\n");
159*284Sbill 	(void) spl0();
160*284Sbill }
161