xref: /csrg-svn/sys/vax/uba/uba.c (revision 2067)
1*2067Swnj /*	uba.c	4.6	01/06/81	*/
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"
131901Swnj #include "../h/mtpr.h"
1440Sbill 
1540Sbill /*
1640Sbill  * Allocate as many contiguous UBA mapping registers
1740Sbill  * as are necessary to do transfer of bcnt bytes
1840Sbill  * to/from location baddr.  Wait for enough map registers.
1940Sbill  *
2040Sbill  * Bdpflg is non-zero if a "buffered data path" (BDP) is
2140Sbill  * to be used, else 0 -> use direct data path (DDP).  Return
2240Sbill  *
2340Sbill  *	Bits 0-8	Byte offset
2440Sbill  *	Bits 9-17	Start map reg. no.
2540Sbill  *	Bits 18-27	No. mapping reg's
2640Sbill  *	Bits 28-31	BDP no.
2740Sbill  */
2840Sbill ubasetup(bp, bdpflg)
2940Sbill struct buf *bp;
3040Sbill {
3140Sbill 	register int temp, i;
3240Sbill 	int npf, reg, bdp;
3340Sbill 	unsigned v;
3440Sbill 	register struct pte *pte, *io;
3540Sbill 	struct proc *rp;
3640Sbill 	int a, o, ubinfo;
3740Sbill 
3840Sbill 	v = btop(bp->b_un.b_addr);
3940Sbill 	o = (int)bp->b_un.b_addr & PGOFSET;
4040Sbill 	npf = btoc(bp->b_bcount + o) + 1;
4140Sbill 	a = spl6();
4240Sbill 	while ((reg = malloc(ubamap, npf)) == 0) {
43883Sbill 		panic("ran out of uba map");
4440Sbill 		umrwant++;
4540Sbill 		sleep((caddr_t)ubamap, PSWP);
4640Sbill 	}
4740Sbill 	reg--;
4840Sbill 	bdp = 0;
4940Sbill 	if (bdpflg)
5040Sbill 		while ((bdp = malloc(bdpmap, 1)) == 0) {
51883Sbill 			panic("ran out of bdp's");
5240Sbill 			bdpwant++;
5340Sbill 			sleep((caddr_t)bdpmap, PSWP);
5440Sbill 		}
5540Sbill 	splx(a);
5640Sbill 	ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
5740Sbill 	io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
5840Sbill 	temp = (bdp << 21) | MRV;
5940Sbill 	rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
6040Sbill 	if (bdp && (o & 01))
6140Sbill 		temp |= BO;
6240Sbill 	if (bp->b_flags & B_UAREA) {
6340Sbill 		for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
6440Sbill 			if (rp->p_addr[i].pg_pfnum == 0)
6540Sbill 				panic("uba: zero upage");
6640Sbill 			*(int *)io++ = rp->p_addr[i].pg_pfnum | temp;
6740Sbill 		}
6840Sbill 	} else if ((bp->b_flags & B_PHYS) == 0) {
69728Sbill 		pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
7040Sbill 		while (--npf != 0)
71728Sbill 			*(int *)io++ = pte++->pg_pfnum | temp;
7240Sbill 	} else {
7340Sbill 		if (bp->b_flags & B_PAGET)
7440Sbill 			pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
7540Sbill 		else
7640Sbill 			pte = vtopte(rp, v);
7740Sbill 		while (--npf != 0) {
7840Sbill 			if (pte->pg_pfnum == 0)
7940Sbill 				panic("uba zero uentry");
8040Sbill 			*(int *)io++ = pte++->pg_pfnum | temp;
8140Sbill 		}
8240Sbill 	}
8340Sbill 	*(int *)io++ = 0;
8440Sbill 	return (ubinfo);
8540Sbill }
8640Sbill 
8740Sbill /*
8840Sbill  * Non buffer unibus interface... set up a buffer and call ubasetup.
8940Sbill  */
9040Sbill uballoc(addr, bcnt, bdpflg)
9140Sbill 	caddr_t addr;
9240Sbill 	unsigned short bcnt;
9340Sbill {
94883Sbill 	struct buf ubabuf;
9540Sbill 
9640Sbill 	ubabuf.b_un.b_addr = addr;
9740Sbill 	ubabuf.b_flags = B_BUSY;
9840Sbill 	ubabuf.b_bcount = bcnt;
99883Sbill 	/* that's all the fields ubasetup() needs */
100883Sbill 	return (ubasetup(&ubabuf, bdpflg));
10140Sbill }
10240Sbill 
1032053Swnj /*
1042053Swnj  * Old ubafree(info) is now ubarelse(&info) to avoid races.
1052053Swnj  */
1062055Swnj ubarelse(amr)
1072053Swnj 	int *amr;
10840Sbill {
10940Sbill 	register int bdp, reg, npf, a;
1102053Swnj 	int mr;
11140Sbill 
11240Sbill 	a = spl6();
1132053Swnj 	mr = *amr;
1142053Swnj 	if (mr == 0) {
1152053Swnj 		splx(a);
1162053Swnj 		return;
1172053Swnj 	}
118*2067Swnj 	*amr = 0;
11940Sbill 	bdp = (mr >> 28) & 0x0f;
12040Sbill 	if (bdp) {
12140Sbill 		((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE;	/* purge */
12240Sbill 		mfree(bdpmap, 1, bdp);
12340Sbill 		if (bdpwant) {
12440Sbill 			bdpwant = 0;
12540Sbill 			wakeup((caddr_t)bdpmap);
12640Sbill 		}
12740Sbill 	}
12840Sbill 	npf = (mr >> 18) & 0x3ff;
12940Sbill 	reg = ((mr >> 9) & 0x1ff) + 1;
13040Sbill 	mfree(ubamap, npf, reg);
13140Sbill 	if (umrwant) {
13240Sbill 		umrwant = 0;
13340Sbill 		wakeup((caddr_t)ubamap);
13440Sbill 	}
13540Sbill 	splx(a);
13640Sbill }
13740Sbill 
13840Sbill ubainit()
13940Sbill {
14040Sbill 
14140Sbill 	mfree(ubamap, 496, 1);
1421901Swnj 	mfree(bdpmap, NUBABDP, 1);
14340Sbill }
144284Sbill 
145284Sbill #define	DELAY(N)	{ register int d; d = N; while (--d > 0); }
146284Sbill 
147284Sbill ubareset()
148284Sbill {
149284Sbill 	struct uba_regs *up = (struct uba_regs *)UBA0;
150284Sbill 	register struct cdevsw *cdp;
1511781Sbill 	int s;
152284Sbill 
153302Sbill 	s = spl6();
1541901Swnj #if VAX==780
155284Sbill 	printf("UBA RESET:");
156284Sbill 	up->uba_cr = ADINIT;
157284Sbill 	up->uba_cr = IFS|BRIE|USEFIE|SUEFIE;
158284Sbill 	while ((up->uba_cnfgr & UBIC) == 0)
159284Sbill 		;
1601901Swnj #endif
1611901Swnj #if VAX==750
1621901Swnj 	printf("UNIBUS INIT:");
1631901Swnj 	mtpr(IUR, 1);
1641901Swnj 	DELAY(100000);
1651901Swnj #endif
166284Sbill 	for (cdp = cdevsw; cdp->d_open; cdp++)
167284Sbill 		(*cdp->d_reset)();
168284Sbill 	printf("\n");
169302Sbill 	splx(s);
170284Sbill }
171