1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 8 enum { 9 BDSIZE= 1024, /* TO DO: check this */ 10 }; 11 12 static Map bdmapv[BDSIZE/sizeof(BD)]; 13 static RMap bdmap = {"buffer descriptors"}; 14 15 void 16 cpminit(void) 17 { 18 IMM *io; 19 20 io = m->iomem; 21 io->sdcr = 1; 22 io->lccr &= ~1; /* disable LCD */ 23 io->pcint = 0; /* disable all port C interrupts */ 24 io->pcso = 0; 25 io->pcdir =0; 26 io->pcpar = 0; 27 io->pcdat = 0; 28 io->papar = 0; 29 io->padir = 0; 30 io->paodr = 0; 31 io->padat = 0; 32 io->pbpar = 0; 33 io->pbdir = 0; 34 io->pbodr = 0; 35 io->pbdat = 0; 36 eieio(); 37 38 for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */ 39 eieio(); 40 41 mapinit(&bdmap, bdmapv, sizeof(bdmapv)); 42 mapfree(&bdmap, DPBASE, BDSIZE); 43 } 44 45 void 46 cpmop(int op, int cno, int param) 47 { 48 IMM *io; 49 int s; 50 51 s = splhi(); 52 io = m->iomem; 53 eieio(); 54 while(io->cpcr & 1) 55 eieio(); 56 io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1; 57 eieio(); 58 while(io->cpcr & 1) 59 eieio(); 60 splx(s); 61 } 62 63 /* 64 * connect SCCx clocks in NSMI mode (x=1 for USB) 65 */ 66 void 67 sccnmsi(int x, int rcs, int tcs) 68 { 69 IMM *io; 70 ulong v; 71 int sh; 72 73 sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */ 74 v = (((rcs&7)<<3) | (tcs&7)) << sh; 75 io = ioplock(); 76 io->sicr = (io->sicr & ~(0xFF<<sh)) | v; 77 iopunlock(); 78 } 79 80 void 81 scc2stop(void) 82 { 83 SCC *scc; 84 85 scc = IOREGS(0xA20, SCC); 86 if(scc->gsmrl & (3<<4)){ 87 cpmop(GracefulStopTx, SCC2ID, 0); 88 cpmop(CloseRxBD, SCC2ID, 0); 89 delay(1); 90 scc->gsmrl &= ~(3<<4); /* disable current use */ 91 archetherdisable(SCC2ID); 92 } 93 } 94 95 BD * 96 bdalloc(int n) 97 { 98 ulong a; 99 100 a = mapalloc(&bdmap, 0, n*sizeof(BD), 0); 101 if(a == 0) 102 panic("bdalloc"); 103 return KADDR(a); 104 } 105 106 void 107 bdfree(BD *b, int n) 108 { 109 if(b){ 110 eieio(); 111 mapfree(&bdmap, PADDR(b), n*sizeof(BD)); 112 } 113 } 114 115 /* 116 * initialise receive and transmit buffer rings. 117 */ 118 int 119 ioringinit(Ring* r, int nrdre, int ntdre, int bufsize) 120 { 121 int i, x; 122 123 /* the ring entries must be aligned on sizeof(BD) boundaries */ 124 r->nrdre = nrdre; 125 if(r->rdr == nil) 126 r->rdr = bdalloc(nrdre); 127 /* the buffer size must align with cache lines since the cache doesn't snoop */ 128 bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1); 129 if(r->rrb == nil) 130 r->rrb = malloc(nrdre*bufsize); 131 if(r->rdr == nil || r->rrb == nil) 132 return -1; 133 dcflush(r->rrb, nrdre*bufsize); 134 x = PADDR(r->rrb); 135 for(i = 0; i < nrdre; i++){ 136 r->rdr[i].length = 0; 137 r->rdr[i].addr = x; 138 r->rdr[i].status = BDEmpty|BDInt; 139 x += bufsize; 140 } 141 r->rdr[i-1].status |= BDWrap; 142 r->rdrx = 0; 143 144 r->ntdre = ntdre; 145 if(r->tdr == nil) 146 r->tdr = bdalloc(ntdre); 147 if(r->txb == nil) 148 r->txb = malloc(ntdre*sizeof(Block*)); 149 if(r->tdr == nil || r->txb == nil) 150 return -1; 151 for(i = 0; i < ntdre; i++){ 152 r->txb[i] = nil; 153 r->tdr[i].addr = 0; 154 r->tdr[i].length = 0; 155 r->tdr[i].status = 0; 156 } 157 r->tdr[i-1].status |= BDWrap; 158 r->tdrh = 0; 159 r->tdri = 0; 160 r->ntq = 0; 161 return 0; 162 } 163