1*2055Swnj /* uba.c 4.5 12/30/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" 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 */ 106*2055Swnj 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 } 11840Sbill bdp = (mr >> 28) & 0x0f; 11940Sbill if (bdp) { 12040Sbill ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ 12140Sbill mfree(bdpmap, 1, bdp); 12240Sbill if (bdpwant) { 12340Sbill bdpwant = 0; 12440Sbill wakeup((caddr_t)bdpmap); 12540Sbill } 12640Sbill } 12740Sbill npf = (mr >> 18) & 0x3ff; 12840Sbill reg = ((mr >> 9) & 0x1ff) + 1; 12940Sbill mfree(ubamap, npf, reg); 13040Sbill if (umrwant) { 13140Sbill umrwant = 0; 13240Sbill wakeup((caddr_t)ubamap); 13340Sbill } 13440Sbill splx(a); 13540Sbill } 13640Sbill 13740Sbill ubainit() 13840Sbill { 13940Sbill 14040Sbill mfree(ubamap, 496, 1); 1411901Swnj mfree(bdpmap, NUBABDP, 1); 14240Sbill } 143284Sbill 144284Sbill #define DELAY(N) { register int d; d = N; while (--d > 0); } 145284Sbill 146284Sbill ubareset() 147284Sbill { 148284Sbill struct uba_regs *up = (struct uba_regs *)UBA0; 149284Sbill register struct cdevsw *cdp; 1501781Sbill int s; 151284Sbill 152302Sbill s = spl6(); 1531901Swnj #if VAX==780 154284Sbill printf("UBA RESET:"); 155284Sbill up->uba_cr = ADINIT; 156284Sbill up->uba_cr = IFS|BRIE|USEFIE|SUEFIE; 157284Sbill while ((up->uba_cnfgr & UBIC) == 0) 158284Sbill ; 1591901Swnj #endif 1601901Swnj #if VAX==750 1611901Swnj printf("UNIBUS INIT:"); 1621901Swnj mtpr(IUR, 1); 1631901Swnj DELAY(100000); 1641901Swnj #endif 165284Sbill for (cdp = cdevsw; cdp->d_open; cdp++) 166284Sbill (*cdp->d_reset)(); 167284Sbill printf("\n"); 168302Sbill splx(s); 169284Sbill } 170