system.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "fw.h"
  2. #include "io.h"
  3. #include "sdcard.h"
  4. #include "abcio.h"
  5. #include "sys.h"
  6. #include "console.h"
  7. #define DEBUG 0
  8. #define MINITESTS 1
  9. #define DELAY 1
  10. static void __hot con_print_hex(unsigned int n)
  11. {
  12. for (int i = 0; i < 8; i++) {
  13. unsigned int c = n >> 28;
  14. n <<= 4;
  15. con_putc(c + ((c >= 10) ? 'a'-10 : '0'));
  16. }
  17. }
  18. /* Don't mark no_return or gcc moves it to SDRAM */
  19. static void __hot __text_hot killed(const char *how, size_t pc)
  20. {
  21. /* Cannot use con_printf() here */
  22. const uint16_t *pcp;
  23. size_t mtval;
  24. asm volatile("csrr %0,mtval" : "=r" (mtval));
  25. /* Try to move back to the previous instruction (if not a jump...) */
  26. pc += -4 + (pc & 1);
  27. pcp = (const uint16_t *)pc;
  28. con_puts(hotstr("ERROR: "));
  29. con_puts(how);
  30. con_puts(hotstr(" at 0x"));
  31. con_print_hex(pc);
  32. con_puts(hotstr(" (0x"));
  33. con_print_hex((pcp[1] << 16) + pcp[0]);
  34. con_puts(hotstr(")\nBad address: 0x"));
  35. con_print_hex(mtval);
  36. con_putc('\n');
  37. for (int i = 0; i < 32; i += 8) {
  38. for (int j = 0; j < 8; j++) {
  39. uint32_t v = rdxreg(i+j);
  40. con_print_hex(v);
  41. con_putc((j == 7) ? '\n' : ' ');
  42. }
  43. }
  44. con_flush();
  45. udelay(5000000);
  46. reset(SYS_RESET_SOFT);
  47. }
  48. IRQHANDLER(buserr,0)
  49. {
  50. killed(hotstr("misaligned"), pc);
  51. }
  52. IRQHANDLER(ebreak,0)
  53. {
  54. killed(hotstr("invalid instruction"), pc);
  55. }
  56. volatile __sbss uint32_t timer_irq_count;
  57. IRQHANDLER(sysclock,0)
  58. {
  59. uint32_t count = timer_irq_count;
  60. count++;
  61. timer_irq_count = count;
  62. if ( MINITESTS ) {
  63. static const char spinner[4] = "/-\\|";
  64. if (!(count & (TIMER_HZ-1))) {
  65. uint32_t seconds = count >> TIMER_SHIFT;
  66. CON_DATA = spinner[seconds & 3];
  67. CON_DATA = '\b';
  68. }
  69. }
  70. }
  71. static void late_init(void);
  72. uint32_t __sbss timer_irq_start;
  73. void __hot init(void)
  74. {
  75. static __string_hot const char hello[] =
  76. "\n\n*** Hello, World! ***\n"
  77. "MAX80 "
  78. #ifdef TEST
  79. "testing"
  80. #endif
  81. "firmware compiled on: ";
  82. timer_irq_start = rdtime();
  83. /* Start ROM copy engine, unmask timer and fatal exceptions */
  84. unmask_irqs((1U << ROMCOPY_IRQ)|(1U << EBREAK_IRQ)|
  85. (1U << BUSERR_IRQ)|(1U << SYSCLOCK_IRQ));
  86. con_puts(hello);
  87. con_puts(__datestamp);
  88. con_putc('\n');
  89. set_leds(7);
  90. wait_romcopy_done();
  91. if ( MINITESTS ) {
  92. extern uint32_t __dram_init_start[], __dram_init_end[];
  93. extern uint32_t __dram_bss_start[], __dram_bss_end[];
  94. volatile uint32_t *dp;
  95. uint32_t v;
  96. uint32_t wrerr;
  97. uint32_t not_zero, all_ones;
  98. uint32_t rx = 0x193ac604;
  99. v = wrerr = 0;
  100. all_ones = -1;
  101. not_zero = 0;
  102. for (dp = __dram_init_start; dp < __dram_init_end; dp++) {
  103. uint32_t v1, v2;
  104. v1 = *dp;
  105. v += v1;
  106. v2 = v1 ^ rx;
  107. *dp = v2;
  108. wrerr |= *dp ^ v2;
  109. *dp = v1;
  110. not_zero |= v1;
  111. all_ones &= v1;
  112. rx *= 0xf4d5725f;
  113. }
  114. con_puts(hotstr("SDRAM data checksum: "));
  115. con_print_hex(v);
  116. con_puts(hotstr(" expected "));
  117. con_print_hex(__dram_checksum);
  118. con_putc('\n');
  119. con_puts(hotstr("Bits always set, clear: "));
  120. con_print_hex(all_ones);
  121. con_putc(' ');
  122. con_print_hex(~not_zero);
  123. con_putc('\n');
  124. if (wrerr)
  125. con_puts(hotstr("SDRAM read/write error\n"));
  126. v = 0;
  127. for (dp = __dram_bss_start; dp < __dram_bss_end; dp++) {
  128. uint32_t x = *dp;
  129. v |= x;
  130. }
  131. if (v)
  132. con_puts(hotstr("SDRAM .bss is not zero!\n"));
  133. }
  134. set_leds(6);
  135. con_flush();
  136. set_leds(5);
  137. #if DELAY
  138. con_puts(hotstr("Waiting 5 s for testing..."));
  139. udelay(5000000);
  140. con_putc('\n');
  141. con_flush();
  142. #endif
  143. late_init();
  144. }
  145. volatile uint32_t __dram_bss test_dram[8];
  146. static void __hot late_init(void)
  147. {
  148. /* This needs to be done as early as possible!!! */
  149. con_puts("Running abc_init_memmap: ");
  150. con_flush();
  151. abc_init_memmap();
  152. con_puts("ok\n");
  153. if (SYS_MAGIC != SYS_MAGIC_MAX80) {
  154. con_puts("Not a MAX80 board?!?!\n\n");
  155. _die();
  156. } else {
  157. con_printf("MAX80 ver %u.%u rework flags %02x fpga %u\n",
  158. SYS_BOARDMAJOR, SYS_BOARDMINOR,
  159. SYS_BOARDFIX, SYS_BOARDFPGA);
  160. if (SYS_BOARDMAJOR != SYS_BOARDFPGA) {
  161. con_puts("Invalid FPGA firmware for this board revision\n");
  162. _die();
  163. }
  164. }
  165. con_putc('\n');
  166. if ( MINITESTS ) {
  167. con_puts("Quick DRAM test:\n");
  168. for (int i = 0; i < 8; i++) {
  169. uint32_t v = (i*0x11111111) + 0x44332211;
  170. test_dram[i] = v;
  171. (void)test_dram[i]; /* Force immediate readback */
  172. con_printf("%08x ", v);
  173. }
  174. con_putc('\n');
  175. for (int i = 0; i < 8; i++) {
  176. con_printf("%08x ", test_dram[i]);
  177. }
  178. con_puts("\n\nRandom number generator test:\n");
  179. for (int i = 0; i < 8; i++)
  180. con_printf("%08x ", rdrand());
  181. con_puts("\n\n");
  182. }
  183. rom_get_serial();
  184. set_leds(4);
  185. read_rtc();
  186. rtc_abc_init();
  187. set_leds(3);
  188. sdcard_reset();
  189. disk_cache_init();
  190. abcdisk_init();
  191. set_leds(2);
  192. pun80_init();
  193. set_leds(1);
  194. abc_init();
  195. /* Release WAIT# if asserted */
  196. ABC_BUSCTL = 0;
  197. set_leds(0);
  198. }