1*284Sbill /* uba.c 3.3 06/22/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" 12*284Sbill #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) { 4240Sbill umrwant++; 4340Sbill sleep((caddr_t)ubamap, PSWP); 4440Sbill } 4540Sbill reg--; 4640Sbill bdp = 0; 4740Sbill if (bdpflg) 4840Sbill while ((bdp = malloc(bdpmap, 1)) == 0) { 4940Sbill bdpwant++; 5040Sbill sleep((caddr_t)bdpmap, PSWP); 5140Sbill } 5240Sbill splx(a); 5340Sbill ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o; 5440Sbill io = &(((struct uba_regs *)UBA0)->uba_map[reg]); 5540Sbill temp = (bdp << 21) | MRV; 5640Sbill rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; 5740Sbill if (bdp && (o & 01)) 5840Sbill temp |= BO; 5940Sbill if (bp->b_flags & B_UAREA) { 6040Sbill for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) { 6140Sbill if (rp->p_addr[i].pg_pfnum == 0) 6240Sbill panic("uba: zero upage"); 6340Sbill *(int *)io++ = rp->p_addr[i].pg_pfnum | temp; 6440Sbill } 6540Sbill } else if ((bp->b_flags & B_PHYS) == 0) { 6640Sbill v &= 0x1fffff; /* drop to physical addr */ 6740Sbill while (--npf != 0) 6840Sbill *(int *)io++ = v++ | temp; 6940Sbill } else { 7040Sbill if (bp->b_flags & B_PAGET) 7140Sbill pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 7240Sbill else 7340Sbill pte = vtopte(rp, v); 7440Sbill while (--npf != 0) { 7540Sbill if (pte->pg_pfnum == 0) 7640Sbill panic("uba zero uentry"); 7740Sbill *(int *)io++ = pte++->pg_pfnum | temp; 7840Sbill } 7940Sbill } 8040Sbill *(int *)io++ = 0; 8140Sbill return (ubinfo); 8240Sbill } 8340Sbill 8440Sbill struct buf ubabuf; 8540Sbill /* 8640Sbill * Non buffer unibus interface... set up a buffer and call ubasetup. 8740Sbill */ 8840Sbill uballoc(addr, bcnt, bdpflg) 8940Sbill caddr_t addr; 9040Sbill unsigned short bcnt; 9140Sbill { 9240Sbill register int a, ubinfo; 9340Sbill 9440Sbill a = spl6(); 9540Sbill while (ubabuf.b_flags & B_BUSY) { 9640Sbill ubabuf.b_flags |= B_WANTED; 9740Sbill sleep((caddr_t)&ubabuf, PRIUBA); 9840Sbill } 9940Sbill ubabuf.b_un.b_addr = addr; 10040Sbill ubabuf.b_flags = B_BUSY; 10140Sbill ubabuf.b_bcount = bcnt; 10240Sbill splx(a); 10340Sbill ubinfo = ubasetup(&ubabuf, bdpflg); 10440Sbill ubabuf.b_flags &= ~B_BUSY; 10540Sbill if (ubabuf.b_flags & B_WANTED) 10640Sbill wakeup((caddr_t)&ubabuf); 10740Sbill return (ubinfo); 10840Sbill } 10940Sbill 11040Sbill ubafree(mr) 11140Sbill int mr; 11240Sbill { 11340Sbill register int bdp, reg, npf, a; 11440Sbill 11540Sbill a = spl6(); 11640Sbill bdp = (mr >> 28) & 0x0f; 11740Sbill if (bdp) { 11840Sbill ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ 11940Sbill mfree(bdpmap, 1, bdp); 12040Sbill if (bdpwant) { 12140Sbill bdpwant = 0; 12240Sbill wakeup((caddr_t)bdpmap); 12340Sbill } 12440Sbill } 12540Sbill npf = (mr >> 18) & 0x3ff; 12640Sbill reg = ((mr >> 9) & 0x1ff) + 1; 12740Sbill mfree(ubamap, npf, reg); 12840Sbill if (umrwant) { 12940Sbill umrwant = 0; 13040Sbill wakeup((caddr_t)ubamap); 13140Sbill } 13240Sbill splx(a); 13340Sbill } 13440Sbill 13540Sbill ubainit() 13640Sbill { 13740Sbill 13840Sbill mfree(ubamap, 496, 1); 13940Sbill mfree(bdpmap, 15, 1); 14040Sbill } 141*284Sbill 142*284Sbill #define DELAY(N) { register int d; d = N; while (--d > 0); } 143*284Sbill 144*284Sbill ubareset() 145*284Sbill { 146*284Sbill struct uba_regs *up = (struct uba_regs *)UBA0; 147*284Sbill register struct cdevsw *cdp; 148*284Sbill int i; 149*284Sbill 150*284Sbill (void) spl6(); 151*284Sbill printf("UBA RESET:"); 152*284Sbill up->uba_cr = ADINIT; 153*284Sbill up->uba_cr = IFS|BRIE|USEFIE|SUEFIE; 154*284Sbill while ((up->uba_cnfgr & UBIC) == 0) 155*284Sbill ; 156*284Sbill for (cdp = cdevsw; cdp->d_open; cdp++) 157*284Sbill (*cdp->d_reset)(); 158*284Sbill printf("\n"); 159*284Sbill (void) spl0(); 160*284Sbill } 161