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