14 #include <net/microudp.h>
21 CSR_IE
= 1, CSR_IM
, CSR_IP
, CSR_ICC
, CSR_DCC
, CSR_CC
, CSR_CFG
, CSR_EBA
,
22 CSR_DC
, CSR_DEBA
, CSR_JTX
, CSR_JRX
, CSR_BP0
, CSR_BP1
, CSR_BP2
, CSR_BP3
,
23 CSR_WP0
, CSR_WP1
, CSR_WP2
, CSR_WP3
,
26 /* General address space functions */
28 #define NUMBER_OF_BYTES_ON_A_LINE 16
29 static void dump_bytes(unsigned int *ptr
, int count
, unsigned addr
)
31 char *data
= (char *)ptr
;
32 int line_bytes
= 0, i
= 0;
34 putsnonl("Memory dump:");
37 (count
> NUMBER_OF_BYTES_ON_A_LINE
)?
38 NUMBER_OF_BYTES_ON_A_LINE
: count
;
40 printf("\n0x%08x ", addr
);
41 for(i
=0;i
<line_bytes
;i
++)
42 printf("%02x ", *(unsigned char *)(data
+i
));
44 for(;i
<NUMBER_OF_BYTES_ON_A_LINE
;i
++)
49 for(i
=0;i
<line_bytes
;i
++) {
50 if((*(data
+i
) < 0x20) || (*(data
+i
) > 0x7e))
53 printf("%c", *(data
+i
));
56 for(;i
<NUMBER_OF_BYTES_ON_A_LINE
;i
++)
59 data
+= (char)line_bytes
;
66 static void mr(char *startaddr
, char *len
)
73 printf("mr <address> [length]\n");
76 addr
= (unsigned *)strtoul(startaddr
, &c
, 0);
78 printf("incorrect address\n");
84 length
= strtoul(len
, &c
, 0);
86 printf("incorrect length\n");
91 dump_bytes(addr
, length
, (unsigned)addr
);
94 static void mw(char *addr
, char *value
, char *count
)
102 if((*addr
== 0) || (*value
== 0)) {
103 printf("mw <address> <value> [count]\n");
106 addr2
= (unsigned int *)strtoul(addr
, &c
, 0);
108 printf("incorrect address\n");
111 value2
= strtoul(value
, &c
, 0);
113 printf("incorrect value\n");
119 count2
= strtoul(count
, &c
, 0);
121 printf("incorrect count\n");
125 for (i
=0;i
<count2
;i
++) *addr2
++ = value2
;
128 static void mc(char *dstaddr
, char *srcaddr
, char *count
)
131 unsigned int *dstaddr2
;
132 unsigned int *srcaddr2
;
136 if((*dstaddr
== 0) || (*srcaddr
== 0)) {
137 printf("mc <dst> <src> [count]\n");
140 dstaddr2
= (unsigned int *)strtoul(dstaddr
, &c
, 0);
142 printf("incorrect destination address\n");
145 srcaddr2
= (unsigned int *)strtoul(srcaddr
, &c
, 0);
147 printf("incorrect source address\n");
153 count2
= strtoul(count
, &c
, 0);
155 printf("incorrect count\n");
159 for (i
=0;i
<count2
;i
++) *dstaddr2
++ = *srcaddr2
++;
162 static void crc(char *startaddr
, char *len
)
168 if((*startaddr
== 0)||(*len
== 0)) {
169 printf("crc <address> <length>\n");
172 addr
= (char *)strtoul(startaddr
, &c
, 0);
174 printf("incorrect address\n");
177 length
= strtoul(len
, &c
, 0);
179 printf("incorrect length\n");
183 printf("CRC32: %08x\n", crc32((unsigned char *)addr
, length
));
186 /* processor registers */
187 static int parse_csr(const char *csr
)
189 if(!strcmp(csr
, "ie")) return CSR_IE
;
190 if(!strcmp(csr
, "im")) return CSR_IM
;
191 if(!strcmp(csr
, "ip")) return CSR_IP
;
192 if(!strcmp(csr
, "icc")) return CSR_ICC
;
193 if(!strcmp(csr
, "dcc")) return CSR_DCC
;
194 if(!strcmp(csr
, "cc")) return CSR_CC
;
195 if(!strcmp(csr
, "cfg")) return CSR_CFG
;
196 if(!strcmp(csr
, "eba")) return CSR_EBA
;
197 if(!strcmp(csr
, "dc")) return CSR_DC
;
198 if(!strcmp(csr
, "deba")) return CSR_DEBA
;
199 if(!strcmp(csr
, "jtx")) return CSR_JTX
;
200 if(!strcmp(csr
, "jrx")) return CSR_JRX
;
201 if(!strcmp(csr
, "bp0")) return CSR_BP0
;
202 if(!strcmp(csr
, "bp1")) return CSR_BP1
;
203 if(!strcmp(csr
, "bp2")) return CSR_BP2
;
204 if(!strcmp(csr
, "bp3")) return CSR_BP3
;
205 if(!strcmp(csr
, "wp0")) return CSR_WP0
;
206 if(!strcmp(csr
, "wp1")) return CSR_WP1
;
207 if(!strcmp(csr
, "wp2")) return CSR_WP2
;
208 if(!strcmp(csr
, "wp3")) return CSR_WP3
;
213 static void rcsr(char *csr
)
216 register unsigned int value
;
219 printf("rcsr <csr>\n");
223 csr2
= parse_csr(csr
);
225 printf("incorrect csr\n");
230 case CSR_IE
: asm volatile ("rcsr %0,ie":"=r"(value
)); break;
231 case CSR_IM
: asm volatile ("rcsr %0,im":"=r"(value
)); break;
232 case CSR_IP
: asm volatile ("rcsr %0,ip":"=r"(value
)); break;
233 case CSR_CC
: asm volatile ("rcsr %0,cc":"=r"(value
)); break;
234 case CSR_CFG
: asm volatile ("rcsr %0,cfg":"=r"(value
)); break;
235 case CSR_EBA
: asm volatile ("rcsr %0,eba":"=r"(value
)); break;
236 case CSR_DEBA
: asm volatile ("rcsr %0,deba":"=r"(value
)); break;
237 case CSR_JTX
: asm volatile ("rcsr %0,jtx":"=r"(value
)); break;
238 case CSR_JRX
: asm volatile ("rcsr %0,jrx":"=r"(value
)); break;
239 default: printf("csr write only\n"); return;
242 printf("%08x\n", value
);
245 static void wcsr(char *csr
, char *value
)
249 register unsigned int value2
;
251 if((*csr
== 0) || (*value
== 0)) {
252 printf("wcsr <csr> <address>\n");
256 csr2
= parse_csr(csr
);
258 printf("incorrect csr\n");
261 value2
= strtoul(value
, &c
, 0);
263 printf("incorrect value\n");
268 case CSR_IE
: asm volatile ("wcsr ie,%0"::"r"(value2
)); break;
269 case CSR_IM
: asm volatile ("wcsr im,%0"::"r"(value2
)); break;
270 case CSR_ICC
: asm volatile ("wcsr icc,%0"::"r"(value2
)); break;
271 case CSR_DCC
: asm volatile ("wcsr dcc,%0"::"r"(value2
)); break;
272 case CSR_EBA
: asm volatile ("wcsr eba,%0"::"r"(value2
)); break;
273 case CSR_DC
: asm volatile ("wcsr dcc,%0"::"r"(value2
)); break;
274 case CSR_DEBA
: asm volatile ("wcsr deba,%0"::"r"(value2
)); break;
275 case CSR_JTX
: asm volatile ("wcsr jtx,%0"::"r"(value2
)); break;
276 case CSR_JRX
: asm volatile ("wcsr jrx,%0"::"r"(value2
)); break;
277 case CSR_BP0
: asm volatile ("wcsr bp0,%0"::"r"(value2
)); break;
278 case CSR_BP1
: asm volatile ("wcsr bp1,%0"::"r"(value2
)); break;
279 case CSR_BP2
: asm volatile ("wcsr bp2,%0"::"r"(value2
)); break;
280 case CSR_BP3
: asm volatile ("wcsr bp3,%0"::"r"(value2
)); break;
281 case CSR_WP0
: asm volatile ("wcsr wp0,%0"::"r"(value2
)); break;
282 case CSR_WP1
: asm volatile ("wcsr wp1,%0"::"r"(value2
)); break;
283 case CSR_WP2
: asm volatile ("wcsr wp2,%0"::"r"(value2
)); break;
284 case CSR_WP3
: asm volatile ("wcsr wp3,%0"::"r"(value2
)); break;
285 default: printf("csr read only\n"); return;
289 static void dfs(char *baseaddr
)
295 printf("dfs <address>\n");
298 addr
= strtoul(baseaddr
, &c
, 0);
300 printf("incorrect address\n");
303 print_isd_info(addr
);
306 /* Init + command line */
308 static void help(void)
310 puts("Milkymist(tm) BIOS");
311 puts("Don't know what to do? Try 'flashboot'.\n");
312 puts("Available commands:");
313 puts("mr - read address space");
314 puts("mw - write address space");
315 puts("mc - copy address space");
316 puts("crc - compute CRC32 of a part of the address space");
317 puts("rcsr - read processor CSR");
318 puts("wcsr - write processor CSR");
319 puts("netboot - boot via TFTP");
320 puts("serialboot - boot via SFL");
321 puts("flashboot - boot from flash");
322 puts("version - display version");
325 static char *get_token(char **str
)
329 c
= (char *)strchr(*str
, ' ');
332 *str
= *str
+strlen(*str
);
341 static void do_command(char *c
)
345 token
= get_token(&c
);
347 if(strcmp(token
, "mr") == 0) mr(get_token(&c
), get_token(&c
));
348 else if(strcmp(token
, "mw") == 0) mw(get_token(&c
), get_token(&c
), get_token(&c
));
349 else if(strcmp(token
, "mc") == 0) mc(get_token(&c
), get_token(&c
), get_token(&c
));
350 else if(strcmp(token
, "crc") == 0) crc(get_token(&c
), get_token(&c
));
352 else if(strcmp(token
, "flashboot") == 0) flashboot();
353 else if(strcmp(token
, "serialboot") == 0) serialboot();
354 else if(strcmp(token
, "netboot") == 0) netboot();
356 else if(strcmp(token
, "version") == 0) puts(VERSION
);
358 else if(strcmp(token
, "help") == 0) help();
360 else if(strcmp(token
, "rcsr") == 0) rcsr(get_token(&c
));
361 else if(strcmp(token
, "wcsr") == 0) wcsr(get_token(&c
), get_token(&c
));
363 else if(strcmp(token
, "ddrrow") == 0) ddrrow(get_token(&c
));
364 else if(strcmp(token
, "ddrsw") == 0) ddrsw();
365 else if(strcmp(token
, "ddrhw") == 0) ddrhw();
366 else if(strcmp(token
, "ddrrd") == 0) ddrrd(get_token(&c
));
367 else if(strcmp(token
, "ddrwr") == 0) ddrwr(get_token(&c
));
368 else if(strcmp(token
, "memtest") == 0) memtest();
369 else if(strcmp(token
, "ddrinit") == 0) ddrinit();
370 else if(strcmp(token
, "asmiprobe") == 0) asmiprobe();
372 else if(strcmp(token
, "dfs") == 0) dfs(get_token(&c
));
374 else if(strcmp(token
, "") != 0)
375 printf("Command not found\n");
379 extern unsigned int _edata
;
381 static void crcbios(void)
383 unsigned int offset_bios
;
385 unsigned int expected_crc
;
386 unsigned int actual_crc
;
389 * _edata is located right after the end of the flat
390 * binary image. The CRC tool writes the 32-bit CRC here.
391 * We also use the address of _edata to know the length
394 offset_bios
= rescue
? FLASH_OFFSET_RESCUE_BIOS
: FLASH_OFFSET_REGULAR_BIOS
;
395 expected_crc
= _edata
;
396 length
= (unsigned int)&_edata
- offset_bios
;
397 actual_crc
= crc32((unsigned char *)offset_bios
, length
);
398 if(expected_crc
== actual_crc
)
399 printf("BIOS CRC passed (%08x)\n", actual_crc
);
401 printf("BIOS CRC failed (expected %08x, got %08x)\n", expected_crc
, actual_crc
);
402 printf("The system will continue, but expect problems.\n");
406 static void print_mac(void)
408 unsigned char *macadr
= (unsigned char *)FLASH_OFFSET_MAC_ADDRESS
;
410 printf("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", macadr
[0], macadr
[1], macadr
[2], macadr
[3], macadr
[4], macadr
[5]);
413 static const char banner
[] =
414 "\nMILKYMIST(tm) v"VERSION
" BIOS http://www.milkymist.org\n"
415 "(c) Copyright 2007-2013 Sebastien Bourdeauducq\n"
416 "Built "__DATE__
" "__TIME__
"\n\n"
417 "This program is free software: you can redistribute it and/or modify\n"
418 "it under the terms of the GNU General Public License as published by\n"
419 "the Free Software Foundation, version 3 of the License.";
421 static void readstr(char *s
, int size
)
435 putsnonl("\x08 \x08");
454 static int test_user_abort(void)
458 printf("Automatic boot in 2 seconds...\n");
459 printf("Q/ESC: abort boot\n");
460 printf("F7: boot from serial\n");
461 printf("F8: boot from network\n");
464 timer_set_counter(get_system_frequency()*2);
467 if(readchar_nonblock()) {
469 if((c
== 'Q')||(c
== '\e')) {
486 static void boot_sequence(void)
488 if(test_user_abort()) {
498 printf("No boot medium found\n");
502 int main(int i
, char **c
)
507 rescue
= !((unsigned int)main
> FLASH_OFFSET_REGULAR_BIOS
);
515 printf("Rescue mode\n");
523 printf("Memory initialization failed\n");
526 putsnonl("\e[1mBIOS>\e[0m ");