1*40Sbill /* uba.c 3.1 10/14/12 */ 2*40Sbill 3*40Sbill #include "../h/param.h" 4*40Sbill #include "../h/map.h" 5*40Sbill #include "../h/pte.h" 6*40Sbill #include "../h/uba.h" 7*40Sbill #include "../h/buf.h" 8*40Sbill #include "../h/dir.h" 9*40Sbill #include "../h/user.h" 10*40Sbill #include "../h/proc.h" 11*40Sbill #include "../h/vm.h" 12*40Sbill 13*40Sbill /* 14*40Sbill * Allocate as many contiguous UBA mapping registers 15*40Sbill * as are necessary to do transfer of bcnt bytes 16*40Sbill * to/from location baddr. Wait for enough map registers. 17*40Sbill * 18*40Sbill * Bdpflg is non-zero if a "buffered data path" (BDP) is 19*40Sbill * to be used, else 0 -> use direct data path (DDP). Return 20*40Sbill * 21*40Sbill * Bits 0-8 Byte offset 22*40Sbill * Bits 9-17 Start map reg. no. 23*40Sbill * Bits 18-27 No. mapping reg's 24*40Sbill * Bits 28-31 BDP no. 25*40Sbill */ 26*40Sbill ubasetup(bp, bdpflg) 27*40Sbill struct buf *bp; 28*40Sbill { 29*40Sbill register int temp, i; 30*40Sbill int npf, reg, bdp; 31*40Sbill unsigned v; 32*40Sbill register struct pte *pte, *io; 33*40Sbill struct proc *rp; 34*40Sbill int a, o, ubinfo; 35*40Sbill 36*40Sbill v = btop(bp->b_un.b_addr); 37*40Sbill o = (int)bp->b_un.b_addr & PGOFSET; 38*40Sbill npf = btoc(bp->b_bcount + o) + 1; 39*40Sbill a = spl6(); 40*40Sbill while ((reg = malloc(ubamap, npf)) == 0) { 41*40Sbill umrwant++; 42*40Sbill sleep((caddr_t)ubamap, PSWP); 43*40Sbill } 44*40Sbill reg--; 45*40Sbill bdp = 0; 46*40Sbill if (bdpflg) 47*40Sbill while ((bdp = malloc(bdpmap, 1)) == 0) { 48*40Sbill bdpwant++; 49*40Sbill sleep((caddr_t)bdpmap, PSWP); 50*40Sbill } 51*40Sbill splx(a); 52*40Sbill ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o; 53*40Sbill io = &(((struct uba_regs *)UBA0)->uba_map[reg]); 54*40Sbill temp = (bdp << 21) | MRV; 55*40Sbill rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; 56*40Sbill if (bdp && (o & 01)) 57*40Sbill temp |= BO; 58*40Sbill if (bp->b_flags & B_UAREA) { 59*40Sbill for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) { 60*40Sbill if (rp->p_addr[i].pg_pfnum == 0) 61*40Sbill panic("uba: zero upage"); 62*40Sbill *(int *)io++ = rp->p_addr[i].pg_pfnum | temp; 63*40Sbill } 64*40Sbill } else if ((bp->b_flags & B_PHYS) == 0) { 65*40Sbill v &= 0x1fffff; /* drop to physical addr */ 66*40Sbill while (--npf != 0) 67*40Sbill *(int *)io++ = v++ | temp; 68*40Sbill } else { 69*40Sbill if (bp->b_flags & B_PAGET) 70*40Sbill pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 71*40Sbill else 72*40Sbill pte = vtopte(rp, v); 73*40Sbill while (--npf != 0) { 74*40Sbill if (pte->pg_pfnum == 0) 75*40Sbill panic("uba zero uentry"); 76*40Sbill *(int *)io++ = pte++->pg_pfnum | temp; 77*40Sbill } 78*40Sbill } 79*40Sbill *(int *)io++ = 0; 80*40Sbill return (ubinfo); 81*40Sbill } 82*40Sbill 83*40Sbill struct buf ubabuf; 84*40Sbill /* 85*40Sbill * Non buffer unibus interface... set up a buffer and call ubasetup. 86*40Sbill */ 87*40Sbill uballoc(addr, bcnt, bdpflg) 88*40Sbill caddr_t addr; 89*40Sbill unsigned short bcnt; 90*40Sbill { 91*40Sbill register int a, ubinfo; 92*40Sbill 93*40Sbill a = spl6(); 94*40Sbill while (ubabuf.b_flags & B_BUSY) { 95*40Sbill ubabuf.b_flags |= B_WANTED; 96*40Sbill sleep((caddr_t)&ubabuf, PRIUBA); 97*40Sbill } 98*40Sbill ubabuf.b_un.b_addr = addr; 99*40Sbill ubabuf.b_flags = B_BUSY; 100*40Sbill ubabuf.b_bcount = bcnt; 101*40Sbill splx(a); 102*40Sbill ubinfo = ubasetup(&ubabuf, bdpflg); 103*40Sbill ubabuf.b_flags &= ~B_BUSY; 104*40Sbill if (ubabuf.b_flags & B_WANTED) 105*40Sbill wakeup((caddr_t)&ubabuf); 106*40Sbill return (ubinfo); 107*40Sbill } 108*40Sbill 109*40Sbill ubafree(mr) 110*40Sbill int mr; 111*40Sbill { 112*40Sbill register int bdp, reg, npf, a; 113*40Sbill 114*40Sbill a = spl6(); 115*40Sbill bdp = (mr >> 28) & 0x0f; 116*40Sbill if (bdp) { 117*40Sbill ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */ 118*40Sbill mfree(bdpmap, 1, bdp); 119*40Sbill if (bdpwant) { 120*40Sbill bdpwant = 0; 121*40Sbill wakeup((caddr_t)bdpmap); 122*40Sbill } 123*40Sbill } 124*40Sbill npf = (mr >> 18) & 0x3ff; 125*40Sbill reg = ((mr >> 9) & 0x1ff) + 1; 126*40Sbill mfree(ubamap, npf, reg); 127*40Sbill if (umrwant) { 128*40Sbill umrwant = 0; 129*40Sbill wakeup((caddr_t)ubamap); 130*40Sbill } 131*40Sbill splx(a); 132*40Sbill } 133*40Sbill 134*40Sbill ubainit() 135*40Sbill { 136*40Sbill 137*40Sbill mfree(ubamap, 496, 1); 138*40Sbill mfree(bdpmap, 15, 1); 139*40Sbill } 140