1 #include "boot.h" 2 3 /* 4 * this doesn't yet use the crc 5 */ 6 7 typedef struct Uboot Uboot; 8 struct Uboot { 9 Queue* iq; 10 Block* partial; 11 ulong csum; 12 long bno; 13 uchar buf[64]; 14 int nleft; 15 int ntimeout; 16 }; 17 18 static Uboot uboot; 19 ulong crc32(void *buf, int n, ulong crc); 20 21 static void 22 uartbrecv(uchar *p, int n) 23 { 24 Uboot *ub; 25 Block *b; 26 27 ub = &uboot; 28 if(n > 0 && ub->iq != nil){ 29 b = iallocb(n); 30 memmove(b->wp, p, n); 31 b->wp += n; 32 qbwrite(ub->iq, b); 33 } 34 } 35 36 int 37 uartinit(void) 38 { 39 return 1<<0; 40 } 41 42 Partition* 43 setuartpart(int, char *s) 44 { 45 static Partition pp[1]; 46 47 if(strcmp(s, "boot") != 0 && strcmp(s, "disk") != 0) 48 return 0; 49 pp[0].start = 0; 50 pp[0].end = 2*1024*1024; 51 strcpy(pp[0].name, "boot"); 52 return pp; 53 } 54 55 long 56 uartseek(int, long) 57 { 58 /* start the boot */ 59 if(uboot.iq == nil) 60 uboot.iq = qopen(64*1024, 0, 0, 0); 61 if(uboot.partial){ 62 freeb(uboot.partial); 63 uboot.partial = 0; 64 } 65 print("uart: start transmission\n"); 66 uartsetboot(uartbrecv); 67 uboot.csum = ~0; 68 uboot.bno = 0; 69 uboot.nleft = 0; 70 uboot.ntimeout = 0; 71 return 0; 72 } 73 74 static long 75 uartreadn(void *buf, int nb) 76 { 77 ulong start; 78 Uboot *ub; 79 int l; 80 Block *b; 81 uchar *p; 82 83 p = buf; 84 ub = &uboot; 85 start = m->ticks; 86 while(nb > 0){ 87 b = ub->partial; 88 ub->partial = nil; 89 if(b == nil){ 90 ub->ntimeout = 0; 91 while((b = qget(ub->iq)) == 0){ 92 if(TK2MS(m->ticks - start) >= 15*1000){ 93 if(++ub->ntimeout >= 3){ 94 print("uart: timeout\n"); 95 return 0; 96 } 97 uartputs("n", 1); 98 } 99 } 100 } 101 l = BLEN(b); 102 if(l > nb) 103 l = nb; 104 memmove(p, b->rp, l); 105 b->rp += l; 106 if(b->rp >= b->wp) 107 freeb(b); 108 else 109 ub->partial = b; 110 nb -= l; 111 p += l; 112 } 113 return p-(uchar*)buf; 114 } 115 116 long 117 uartread(int, void *buf, long n) 118 { 119 uchar *p; 120 int l; 121 static uchar lbuf[64]; 122 123 p = buf; 124 if((l = uboot.nleft) > 0){ 125 if(l > n) 126 l = n; 127 uboot.nleft -= l; 128 memmove(p, uboot.buf, l); 129 p += l; 130 n -= l; 131 } 132 while(n > 0){ 133 l = uartreadn(lbuf, sizeof(lbuf)); 134 if(l < sizeof(lbuf)) 135 return 0; 136 if(l > n){ 137 uboot.nleft = l-n; 138 memmove(uboot.buf, lbuf+n, uboot.nleft); 139 l = n; 140 } 141 memmove(p, lbuf, l); 142 n -= l; 143 p += l; 144 uboot.bno++; 145 uartputs("y", 1); 146 } 147 return p-(uchar*)buf; 148 } 149 150 /* 151 * from Rob Warnock 152 */ 153 static ulong crc32tab[256]; /* initialised on first call to crc32 */ 154 155 enum { 156 CRC32POLY = 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */ 157 }; 158 159 /* 160 * Build auxiliary table for parallel byte-at-a-time CRC-32. 161 */ 162 static void 163 initcrc32(void) 164 { 165 int i, j; 166 ulong c; 167 168 for(i = 0; i < 256; i++) { 169 for(c = i << 24, j = 8; j > 0; j--) 170 if(c & (1<<31)) 171 c = (c<<1) ^ CRC32POLY; 172 else 173 c <<= 1; 174 crc32tab[i] = c; 175 } 176 } 177 178 ulong 179 crc32(void *buf, int n, ulong crc) 180 { 181 uchar *p; 182 183 if(crc32tab[1] == 0) 184 initcrc32(); 185 crc = ~crc; 186 for(p = buf; --n >= 0;) 187 crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++]; 188 return ~crc; 189 } 190