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