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