| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | #include "common.h"#include "io.h"#include "sdcard.h"#include "abcio.h"#include "sys.h"#include "console.h"#include "esp.h"#include "config.h"#define DEBUG     0#define MINITESTS 1#define DELAY     0void __hot con_print_hex(unsigned int n){    for (int i = 0; i < 8; i++) {	unsigned int c = n >> 28;	n <<= 4;	con_putc(c + ((c >= 10) ? 'a'-10 : '0'));    }}volatile __sbss uint32_t timer_irq_count;IRQHANDLER(sysclock,0){    uint32_t count = timer_irq_count;    count++;    timer_irq_count = count;    if ( MINITESTS ) {	static const char spinner[4] = "/-\\|";	if (!(count & (TIMER_HZ-1))) {	    uint32_t seconds = count >> TIMER_SHIFT;	    CON_DATA = spinner[seconds & 3];	    CON_DATA = '\b';	}    }}static void late_init(void);static void hello_sdram(void);#define TEST_DATA_0 0x01234567#define TEST_DATA_1 0x98badcfestatic const volatile __dram_datauint32_t test_data[2] = { TEST_DATA_0, TEST_DATA_1 };uint32_t __sbss timer_irq_start;void __hot init(void){    static __string_hot const char hello[] =	"\n\n*** Hello, World! ***\n"	"MAX80 "#ifdef TEST	"testing"#endif	"firmware compiled on: ";    timer_irq_start = rdtime();    /* Start ROM copy engine, unmask timer and fatal exceptions */    unmask_irqs((1U << ROMCOPY_IRQ)|(1U << EBREAK_IRQ)|		(1U << BUSERR_IRQ)|(1U << SYSCLOCK_IRQ));    con_puts(hello);    con_puts(__datestamp);    con_putc('\n');    set_leds(7);    wait_romcopy_done();    if ( test_data[0] == TEST_DATA_0 && test_data[1] == TEST_DATA_1 ) {	con_puts(hotstr("SDRAM seems ok - skipping test\n"));    } else {	volatile uint32_t *dp;	uint32_t v;	uint32_t wrerr;	uint32_t not_zero, all_ones;	uint32_t rx = 0x193ac604;	v = wrerr = 0;	all_ones  = -1;	not_zero  = 0;	for (dp = (volatile uint32_t *)__dram_init_start;	     dp < (volatile uint32_t *)__dram_init_end; dp++) {	    uint32_t v1, v2;	    v1 = *dp;	    v += v1;	    v2 = v1 ^ rx;	    *dp = v2;	    wrerr |= *dp ^ v2;	    *dp = v1;	    not_zero |= v1;	    all_ones &= v1;	    rx *= 0xf4d5725f;	}	con_puts(hotstr("SDRAM data checksum: "));	con_print_hex(v);	con_puts(hotstr(" expected "));	con_print_hex(__dram_checksum);	con_putc('\n');	con_puts(hotstr("Bits always set, clear: "));	con_print_hex(all_ones);	con_putc(' ');	con_print_hex(~not_zero);	con_putc('\n');	con_puts(hotstr("Test data: "));	con_print_hex(test_data[0]);	con_putc(' ');	con_print_hex(test_data[1]);	con_putc('\n');	if (wrerr)	    con_puts(hotstr("SDRAM read/write error\n"));	v = 0;	for (dp = (volatile uint32_t *)__dram_bss_start;	     dp < (volatile uint32_t *)__dram_bss_end; dp++) {	    uint32_t x = *dp;	    v |= x;	}	if (v)	    con_puts(hotstr("SDRAM .bss is not zero!\n"));    }    if ( MINITESTS ) {	uint32_t hello_dump[4];	con_puts(hotstr("SDRAM jump test:"));	memcpy(hello_dump, (void *)hello_sdram, sizeof hello_dump);	for (int i = 0; i < 4; i++) {	    con_putc(' ');	    con_print_hex(hello_dump[i]);	}	con_puts(hotstr("\nJumping to SDRAM... "));	hello_sdram();	con_puts(hotstr("back in SRAM.\n"));    }    set_leds(6);    con_flush();    heap_init();    set_leds(5);#if DELAY    con_puts(hotstr("Waiting 5 s for testing..."));    udelay(5000000);    con_putc('\n');    con_flush();#endif    late_init();}static void __noinline hello_sdram(void){    con_puts("in SDRAM... ");}volatile uint32_t __dram_bss test_dram[8];static void __noinline late_init(void){    if (SYS_MAGIC != SYS_MAGIC_MAX80) {	con_puts("Not a MAX80 board?!?!\n\n");	_die();    } else {	con_printf("MAX80 ver %u.%u rework flags %02x fpga %u\n",		   SYS_BOARDMAJOR, SYS_BOARDMINOR,		   SYS_BOARDFIX, SYS_BOARDFPGA);	if (SYS_BOARDMAJOR != SYS_BOARDFPGA) {	    con_puts("Invalid FPGA firmware for this board revision\n");	    _die();	}    }    con_putc('\n');    if ( MINITESTS ) {	con_puts("Quick DRAM test:\n");	for (int i = 0; i < 8; i++) {	    uint32_t v = (i*0x11111111) + 0x44332211;	    test_dram[i] = v;	    (void)test_dram[i];	/* Force immediate readback */	    con_printf("%08x ", v);	}	con_putc('\n');	for (int i = 0; i < 8; i++) {	    con_printf("%08x ", test_dram[i]);	}	con_puts("\n\nRandom number generator test:\n");	for (int i = 0; i < 8; i++)	    con_printf("%08x ", rdrand());	con_puts("\n\n");    }    set_leds(4);    esp_init();    /* Ready for communications */    /* Let ESP know we are ready... */    ESP_SPI_IRQ_SET = (1 << EL_DIRQ_HELLO);    /* Wait for ESP to send us a configuration */    while (!do_update_config) {	mask_irq(ESP_IRQ);	if (!do_update_config)	    waitfor(ESP_IRQ);	unmask_irq(ESP_IRQ);    }    update_config();    set_leds(3);    abc_init_memmap();    set_leds(2);    read_rtc();    rtc_abc_init();    sdcard_reset();    abcdisk_init();    pun80_init();    set_leds(1);    abc_init();    /* Release WAIT# if asserted */    ABC_BUSCTL = 0;    set_leds(0);}
 |