xref: /csrg-svn/sys/vax/uba/uba.c (revision 883)
1*883Sbill /*	uba.c	3.6	09/16/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"
12284Sbill #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) {
42*883Sbill 		panic("ran out of uba map");
4340Sbill 		umrwant++;
4440Sbill 		sleep((caddr_t)ubamap, PSWP);
4540Sbill 	}
4640Sbill 	reg--;
4740Sbill 	bdp = 0;
4840Sbill 	if (bdpflg)
4940Sbill 		while ((bdp = malloc(bdpmap, 1)) == 0) {
50*883Sbill 			panic("ran out of bdp's");
5140Sbill 			bdpwant++;
5240Sbill 			sleep((caddr_t)bdpmap, PSWP);
5340Sbill 		}
5440Sbill 	splx(a);
5540Sbill 	ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
5640Sbill 	io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
5740Sbill 	temp = (bdp << 21) | MRV;
5840Sbill 	rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
5940Sbill 	if (bdp && (o & 01))
6040Sbill 		temp |= BO;
6140Sbill 	if (bp->b_flags & B_UAREA) {
6240Sbill 		for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
6340Sbill 			if (rp->p_addr[i].pg_pfnum == 0)
6440Sbill 				panic("uba: zero upage");
6540Sbill 			*(int *)io++ = rp->p_addr[i].pg_pfnum | temp;
6640Sbill 		}
6740Sbill 	} else if ((bp->b_flags & B_PHYS) == 0) {
68728Sbill 		pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
6940Sbill 		while (--npf != 0)
70728Sbill 			*(int *)io++ = pte++->pg_pfnum | temp;
7140Sbill 	} else {
7240Sbill 		if (bp->b_flags & B_PAGET)
7340Sbill 			pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
7440Sbill 		else
7540Sbill 			pte = vtopte(rp, v);
7640Sbill 		while (--npf != 0) {
7740Sbill 			if (pte->pg_pfnum == 0)
7840Sbill 				panic("uba zero uentry");
7940Sbill 			*(int *)io++ = pte++->pg_pfnum | temp;
8040Sbill 		}
8140Sbill 	}
8240Sbill 	*(int *)io++ = 0;
8340Sbill 	return (ubinfo);
8440Sbill }
8540Sbill 
8640Sbill /*
8740Sbill  * Non buffer unibus interface... set up a buffer and call ubasetup.
8840Sbill  */
8940Sbill uballoc(addr, bcnt, bdpflg)
9040Sbill 	caddr_t addr;
9140Sbill 	unsigned short bcnt;
9240Sbill {
93*883Sbill 	struct buf ubabuf;
9440Sbill 
9540Sbill 	ubabuf.b_un.b_addr = addr;
9640Sbill 	ubabuf.b_flags = B_BUSY;
9740Sbill 	ubabuf.b_bcount = bcnt;
98*883Sbill 	/* that's all the fields ubasetup() needs */
99*883Sbill 	return (ubasetup(&ubabuf, bdpflg));
10040Sbill }
10140Sbill 
10240Sbill ubafree(mr)
10340Sbill 	int mr;
10440Sbill {
10540Sbill 	register int bdp, reg, npf, a;
10640Sbill 
10740Sbill 	a = spl6();
10840Sbill 	bdp = (mr >> 28) & 0x0f;
10940Sbill 	if (bdp) {
11040Sbill 		((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE;	/* purge */
11140Sbill 		mfree(bdpmap, 1, bdp);
11240Sbill 		if (bdpwant) {
11340Sbill 			bdpwant = 0;
11440Sbill 			wakeup((caddr_t)bdpmap);
11540Sbill 		}
11640Sbill 	}
11740Sbill 	npf = (mr >> 18) & 0x3ff;
11840Sbill 	reg = ((mr >> 9) & 0x1ff) + 1;
11940Sbill 	mfree(ubamap, npf, reg);
12040Sbill 	if (umrwant) {
12140Sbill 		umrwant = 0;
12240Sbill 		wakeup((caddr_t)ubamap);
12340Sbill 	}
12440Sbill 	splx(a);
12540Sbill }
12640Sbill 
12740Sbill ubainit()
12840Sbill {
12940Sbill 
13040Sbill 	mfree(ubamap, 496, 1);
13140Sbill 	mfree(bdpmap, 15, 1);
13240Sbill }
133284Sbill 
134284Sbill #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
135284Sbill 
136284Sbill ubareset()
137284Sbill {
138284Sbill 	struct uba_regs *up = (struct uba_regs *)UBA0;
139284Sbill 	register struct cdevsw *cdp;
140302Sbill 	int i, s;
141284Sbill 
142302Sbill 	s = spl6();
143284Sbill 	printf("UBA RESET:");
144284Sbill 	up->uba_cr = ADINIT;
145284Sbill 	up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
146284Sbill 	while ((up->uba_cnfgr & UBIC) == 0)
147284Sbill 		;
148284Sbill 	for (cdp = cdevsw; cdp->d_open; cdp++)
149284Sbill 		(*cdp->d_reset)();
150284Sbill 	printf("\n");
151302Sbill 	splx(s);
152284Sbill }
153