#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 0 void __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 0x98badcfe static const volatile __dram_data uint32_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); }