11 #include <generated/csr.h>
12 #include <generated/mem.h>
13 #include <net/microudp.h>
18 /* General address space functions */
20 #define NUMBER_OF_BYTES_ON_A_LINE 16
21 static void dump_bytes(unsigned int *ptr
, int count
, unsigned addr
)
23 char *data
= (char *)ptr
;
24 int line_bytes
= 0, i
= 0;
26 putsnonl("Memory dump:");
29 (count
> NUMBER_OF_BYTES_ON_A_LINE
)?
30 NUMBER_OF_BYTES_ON_A_LINE
: count
;
32 printf("\n0x%08x ", addr
);
33 for(i
=0;i
<line_bytes
;i
++)
34 printf("%02x ", *(unsigned char *)(data
+i
));
36 for(;i
<NUMBER_OF_BYTES_ON_A_LINE
;i
++)
41 for(i
=0;i
<line_bytes
;i
++) {
42 if((*(data
+i
) < 0x20) || (*(data
+i
) > 0x7e))
45 printf("%c", *(data
+i
));
48 for(;i
<NUMBER_OF_BYTES_ON_A_LINE
;i
++)
51 data
+= (char)line_bytes
;
58 static void mr(char *startaddr
, char *len
)
65 printf("mr <address> [length]\n");
68 addr
= (unsigned *)strtoul(startaddr
, &c
, 0);
70 printf("incorrect address\n");
76 length
= strtoul(len
, &c
, 0);
78 printf("incorrect length\n");
83 dump_bytes(addr
, length
, (unsigned)addr
);
86 static void mw(char *addr
, char *value
, char *count
)
94 if((*addr
== 0) || (*value
== 0)) {
95 printf("mw <address> <value> [count]\n");
98 addr2
= (unsigned int *)strtoul(addr
, &c
, 0);
100 printf("incorrect address\n");
103 value2
= strtoul(value
, &c
, 0);
105 printf("incorrect value\n");
111 count2
= strtoul(count
, &c
, 0);
113 printf("incorrect count\n");
117 for (i
=0;i
<count2
;i
++) *addr2
++ = value2
;
120 static void mc(char *dstaddr
, char *srcaddr
, char *count
)
123 unsigned int *dstaddr2
;
124 unsigned int *srcaddr2
;
128 if((*dstaddr
== 0) || (*srcaddr
== 0)) {
129 printf("mc <dst> <src> [count]\n");
132 dstaddr2
= (unsigned int *)strtoul(dstaddr
, &c
, 0);
134 printf("incorrect destination address\n");
137 srcaddr2
= (unsigned int *)strtoul(srcaddr
, &c
, 0);
139 printf("incorrect source address\n");
145 count2
= strtoul(count
, &c
, 0);
147 printf("incorrect count\n");
151 for (i
=0;i
<count2
;i
++) *dstaddr2
++ = *srcaddr2
++;
154 static void crc(char *startaddr
, char *len
)
160 if((*startaddr
== 0)||(*len
== 0)) {
161 printf("crc <address> <length>\n");
164 addr
= (char *)strtoul(startaddr
, &c
, 0);
166 printf("incorrect address\n");
169 length
= strtoul(len
, &c
, 0);
171 printf("incorrect length\n");
175 printf("CRC32: %08x\n", crc32((unsigned char *)addr
, length
));
178 static void ident(void)
180 char buffer
[IDENT_SIZE
];
183 printf("Ident: %s\n", buffer
);
188 CSR_IE
= 1, CSR_IM
, CSR_IP
, CSR_ICC
, CSR_DCC
, CSR_CC
, CSR_CFG
, CSR_EBA
,
189 CSR_DC
, CSR_DEBA
, CSR_JTX
, CSR_JRX
, CSR_BP0
, CSR_BP1
, CSR_BP2
, CSR_BP3
,
190 CSR_WP0
, CSR_WP1
, CSR_WP2
, CSR_WP3
,
193 /* processor registers */
194 static int parse_csr(const char *csr
)
196 if(!strcmp(csr
, "ie")) return CSR_IE
;
197 if(!strcmp(csr
, "im")) return CSR_IM
;
198 if(!strcmp(csr
, "ip")) return CSR_IP
;
199 if(!strcmp(csr
, "icc")) return CSR_ICC
;
200 if(!strcmp(csr
, "dcc")) return CSR_DCC
;
201 if(!strcmp(csr
, "cc")) return CSR_CC
;
202 if(!strcmp(csr
, "cfg")) return CSR_CFG
;
203 if(!strcmp(csr
, "eba")) return CSR_EBA
;
204 if(!strcmp(csr
, "dc")) return CSR_DC
;
205 if(!strcmp(csr
, "deba")) return CSR_DEBA
;
206 if(!strcmp(csr
, "jtx")) return CSR_JTX
;
207 if(!strcmp(csr
, "jrx")) return CSR_JRX
;
208 if(!strcmp(csr
, "bp0")) return CSR_BP0
;
209 if(!strcmp(csr
, "bp1")) return CSR_BP1
;
210 if(!strcmp(csr
, "bp2")) return CSR_BP2
;
211 if(!strcmp(csr
, "bp3")) return CSR_BP3
;
212 if(!strcmp(csr
, "wp0")) return CSR_WP0
;
213 if(!strcmp(csr
, "wp1")) return CSR_WP1
;
214 if(!strcmp(csr
, "wp2")) return CSR_WP2
;
215 if(!strcmp(csr
, "wp3")) return CSR_WP3
;
220 static void rcsr(char *csr
)
223 register unsigned int value
;
226 printf("rcsr <csr>\n");
230 csr2
= parse_csr(csr
);
232 printf("incorrect csr\n");
237 case CSR_IE
: asm volatile ("rcsr %0,ie":"=r"(value
)); break;
238 case CSR_IM
: asm volatile ("rcsr %0,im":"=r"(value
)); break;
239 case CSR_IP
: asm volatile ("rcsr %0,ip":"=r"(value
)); break;
240 case CSR_CC
: asm volatile ("rcsr %0,cc":"=r"(value
)); break;
241 case CSR_CFG
: asm volatile ("rcsr %0,cfg":"=r"(value
)); break;
242 case CSR_EBA
: asm volatile ("rcsr %0,eba":"=r"(value
)); break;
243 case CSR_DEBA
: asm volatile ("rcsr %0,deba":"=r"(value
)); break;
244 case CSR_JTX
: asm volatile ("rcsr %0,jtx":"=r"(value
)); break;
245 case CSR_JRX
: asm volatile ("rcsr %0,jrx":"=r"(value
)); break;
246 default: printf("csr write only\n"); return;
249 printf("%08x\n", value
);
252 static void wcsr(char *csr
, char *value
)
256 register unsigned int value2
;
258 if((*csr
== 0) || (*value
== 0)) {
259 printf("wcsr <csr> <address>\n");
263 csr2
= parse_csr(csr
);
265 printf("incorrect csr\n");
268 value2
= strtoul(value
, &c
, 0);
270 printf("incorrect value\n");
275 case CSR_IE
: asm volatile ("wcsr ie,%0"::"r"(value2
)); break;
276 case CSR_IM
: asm volatile ("wcsr im,%0"::"r"(value2
)); break;
277 case CSR_ICC
: asm volatile ("wcsr icc,%0"::"r"(value2
)); break;
278 case CSR_DCC
: asm volatile ("wcsr dcc,%0"::"r"(value2
)); break;
279 case CSR_EBA
: asm volatile ("wcsr eba,%0"::"r"(value2
)); break;
280 case CSR_DC
: asm volatile ("wcsr dcc,%0"::"r"(value2
)); break;
281 case CSR_DEBA
: asm volatile ("wcsr deba,%0"::"r"(value2
)); break;
282 case CSR_JTX
: asm volatile ("wcsr jtx,%0"::"r"(value2
)); break;
283 case CSR_JRX
: asm volatile ("wcsr jrx,%0"::"r"(value2
)); break;
284 case CSR_BP0
: asm volatile ("wcsr bp0,%0"::"r"(value2
)); break;
285 case CSR_BP1
: asm volatile ("wcsr bp1,%0"::"r"(value2
)); break;
286 case CSR_BP2
: asm volatile ("wcsr bp2,%0"::"r"(value2
)); break;
287 case CSR_BP3
: asm volatile ("wcsr bp3,%0"::"r"(value2
)); break;
288 case CSR_WP0
: asm volatile ("wcsr wp0,%0"::"r"(value2
)); break;
289 case CSR_WP1
: asm volatile ("wcsr wp1,%0"::"r"(value2
)); break;
290 case CSR_WP2
: asm volatile ("wcsr wp2,%0"::"r"(value2
)); break;
291 case CSR_WP3
: asm volatile ("wcsr wp3,%0"::"r"(value2
)); break;
292 default: printf("csr read only\n"); return;
296 #endif /* __lm32__ */
298 /* Init + command line */
300 static void help(void)
302 puts("LiteX SoC BIOS");
303 puts("Available commands:");
304 puts("mr - read address space");
305 puts("mw - write address space");
306 puts("mc - copy address space");
307 puts("crc - compute CRC32 of a part of the address space");
308 puts("ident - display identifier");
310 puts("rcsr - read processor CSR");
311 puts("wcsr - write processor CSR");
313 #ifdef CSR_ETHMAC_BASE
314 puts("netboot - boot via TFTP");
316 puts("serialboot - boot via SFL");
317 #ifdef FLASH_BOOT_ADDRESS
318 puts("flashboot - boot from flash");
320 #ifdef ROM_BOOT_ADDRESS
321 puts("romboot - boot from embedded rom");
323 #ifdef CSR_SDRAM_BASE
324 puts("memtest - run a memory test");
328 static char *get_token(char **str
)
332 c
= (char *)strchr(*str
, ' ');
335 *str
= *str
+strlen(*str
);
344 static void do_command(char *c
)
348 token
= get_token(&c
);
350 if(strcmp(token
, "mr") == 0) mr(get_token(&c
), get_token(&c
));
351 else if(strcmp(token
, "mw") == 0) mw(get_token(&c
), get_token(&c
), get_token(&c
));
352 else if(strcmp(token
, "mc") == 0) mc(get_token(&c
), get_token(&c
), get_token(&c
));
353 else if(strcmp(token
, "crc") == 0) crc(get_token(&c
), get_token(&c
));
354 else if(strcmp(token
, "ident") == 0) ident();
357 else if(strcmp(token
, "flushl2") == 0) flush_l2_cache();
360 #ifdef FLASH_BOOT_ADDRESS
361 else if(strcmp(token
, "flashboot") == 0) flashboot();
363 #ifdef ROM_BOOT_ADDRESS
364 else if(strcmp(token
, "romboot") == 0) romboot();
366 else if(strcmp(token
, "serialboot") == 0) serialboot();
367 #ifdef CSR_ETHMAC_BASE
368 else if(strcmp(token
, "netboot") == 0) netboot();
371 else if(strcmp(token
, "help") == 0) help();
374 else if(strcmp(token
, "rcsr") == 0) rcsr(get_token(&c
));
375 else if(strcmp(token
, "wcsr") == 0) wcsr(get_token(&c
), get_token(&c
));
378 #ifdef CSR_SDRAM_BASE
379 else if(strcmp(token
, "sdrrow") == 0) sdrrow(get_token(&c
));
380 else if(strcmp(token
, "sdrsw") == 0) sdrsw();
381 else if(strcmp(token
, "sdrhw") == 0) sdrhw();
382 else if(strcmp(token
, "sdrrdbuf") == 0) sdrrdbuf(-1);
383 else if(strcmp(token
, "sdrrd") == 0) sdrrd(get_token(&c
), get_token(&c
));
384 else if(strcmp(token
, "sdrrderr") == 0) sdrrderr(get_token(&c
));
385 else if(strcmp(token
, "sdrwr") == 0) sdrwr(get_token(&c
));
386 #ifdef CSR_DDRPHY_BASE
387 #ifndef A7DDRPHY_BITSLIP
388 else if(strcmp(token
, "sdrwlon") == 0) sdrwlon();
389 else if(strcmp(token
, "sdrwloff") == 0) sdrwloff();
391 else if(strcmp(token
, "sdrlevel") == 0) sdrlevel();
393 else if(strcmp(token
, "memtest") == 0) memtest();
394 else if(strcmp(token
, "sdrinit") == 0) sdrinit();
397 else if(strcmp(token
, "") != 0)
398 printf("Command not found\n");
401 extern unsigned int _ftext
, _erodata
;
403 static void crcbios(void)
405 unsigned int offset_bios
;
407 unsigned int expected_crc
;
408 unsigned int actual_crc
;
411 * _erodata is located right after the end of the flat
412 * binary image. The CRC tool writes the 32-bit CRC here.
413 * We also use the address of _erodata to know the length
416 offset_bios
= (unsigned int)&_ftext
;
417 expected_crc
= _erodata
;
418 length
= (unsigned int)&_erodata
- offset_bios
;
419 actual_crc
= crc32((unsigned char *)offset_bios
, length
);
420 if(expected_crc
== actual_crc
)
421 printf("BIOS CRC passed (%08x)\n", actual_crc
);
423 printf("BIOS CRC failed (expected %08x, got %08x)\n", expected_crc
, actual_crc
);
424 printf("The system will continue, but expect problems.\n");
428 static void readstr(char *s
, int size
)
442 putsnonl("\x08 \x08");
461 static int test_user_abort(void)
465 printf("Automatic boot in 2 seconds...\n");
466 printf("Q/ESC: abort boot\n");
467 #ifdef FLASH_BOOT_ADDRESS
468 printf("F: boot from flash\n");
470 printf("S: boot from serial\n");
471 #ifdef CSR_ETHMAC_BASE
472 printf("N: boot from network\n");
474 #ifdef ROM_BOOT_ADDRESS
475 printf("R: boot from embedded ROM\n");
478 timer0_reload_write(0);
479 #ifndef TEST_USER_ABORT_DELAY
480 timer0_load_write(SYSTEM_CLOCK_FREQUENCY
*2);
482 timer0_load_write(TEST_USER_ABORT_DELAY
);
485 timer0_update_value_write(1);
486 while(timer0_value_read()) {
487 if(readchar_nonblock()) {
489 if((c
== 'Q')||(c
== 'q')||(c
== '\e')) {
493 #ifdef FLASH_BOOT_ADDRESS
494 if((c
== 'F')||(c
== 'f')) {
499 if((c
== 'S')||(c
== 's')) {
503 #ifdef CSR_ETHMAC_BASE
504 if((c
== 'N')||(c
== 'n')) {
509 #ifdef ROM_BOOT_ADDRESS
510 if((c
== 'R')||(c
== 'r')) {
516 timer0_update_value_write(1);
521 static void boot_sequence(void)
523 if(test_user_abort()) {
524 #ifdef FLASH_BOOT_ADDRESS
527 #ifdef ROM_BOOT_ADDRESS
531 #ifdef CSR_ETHMAC_BASE
532 #ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
537 printf("No boot medium found\n");
541 int main(int i
, char **c
)
549 printf("\nLiteX SoC BIOS ");
557 printf("(unknown)\n");
560 "(c) Copyright 2012-2016 Enjoy-Digital\n"
561 "(c) Copyright 2007-2016 M-Labs Limited\n"
562 "Built "__DATE__
" "__TIME__
"\n");
565 #ifdef CSR_ETHMAC_BASE
568 #ifdef CSR_SDRAM_BASE
576 printf("Memory initialization failed\n");
579 putsnonl("\e[1mBIOS>\e[0m ");