1*1901Swnj /* uba.c 4.3 12/17/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" 13*1901Swnj #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 10340Sbill ubafree(mr) 10440Sbill int mr; 10540Sbill { 10640Sbill register int bdp, reg, npf, a; 10740Sbill 10840Sbill a = spl6(); 10940Sbill bdp = (mr >> 28) & 0x0f; 11040Sbill if (bdp) { 11140Sbill ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ 11240Sbill mfree(bdpmap, 1, bdp); 11340Sbill if (bdpwant) { 11440Sbill bdpwant = 0; 11540Sbill wakeup((caddr_t)bdpmap); 11640Sbill } 11740Sbill } 11840Sbill npf = (mr >> 18) & 0x3ff; 11940Sbill reg = ((mr >> 9) & 0x1ff) + 1; 12040Sbill mfree(ubamap, npf, reg); 12140Sbill if (umrwant) { 12240Sbill umrwant = 0; 12340Sbill wakeup((caddr_t)ubamap); 12440Sbill } 12540Sbill splx(a); 12640Sbill } 12740Sbill 12840Sbill ubainit() 12940Sbill { 13040Sbill 13140Sbill mfree(ubamap, 496, 1); 132*1901Swnj mfree(bdpmap, NUBABDP, 1); 13340Sbill } 134284Sbill 135284Sbill #define DELAY(N) { register int d; d = N; while (--d > 0); } 136284Sbill 137284Sbill ubareset() 138284Sbill { 139284Sbill struct uba_regs *up = (struct uba_regs *)UBA0; 140284Sbill register struct cdevsw *cdp; 1411781Sbill int s; 142284Sbill 143302Sbill s = spl6(); 144*1901Swnj #if VAX==780 145284Sbill printf("UBA RESET:"); 146284Sbill up->uba_cr = ADINIT; 147284Sbill up->uba_cr = IFS|BRIE|USEFIE|SUEFIE; 148284Sbill while ((up->uba_cnfgr & UBIC) == 0) 149284Sbill ; 150*1901Swnj #endif 151*1901Swnj #if VAX==750 152*1901Swnj printf("UNIBUS INIT:"); 153*1901Swnj mtpr(IUR, 1); 154*1901Swnj DELAY(100000); 155*1901Swnj #endif 156284Sbill for (cdp = cdevsw; cdp->d_open; cdp++) 157284Sbill (*cdp->d_reset)(); 158284Sbill printf("\n"); 159302Sbill splx(s); 160284Sbill } 161