Line 209... |
Line 209... |
* NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
|
* NEORV32 runtime environment: Debug exception handler, printing various exception/interrupt information via UART.
|
* @note This function is used by neorv32_rte_exception_uninstall(void) only.
|
* @note This function is used by neorv32_rte_exception_uninstall(void) only.
|
**************************************************************************/
|
**************************************************************************/
|
static void __neorv32_rte_debug_exc_handler(void) {
|
static void __neorv32_rte_debug_exc_handler(void) {
|
|
|
neorv32_uart_printf("\n\n<< NEORV32 Runtime Environment >>\n");
|
// intro
|
|
neorv32_uart_printf("<RTE> ");
|
neorv32_uart_printf("System time: 0x%x_%x\n", neorv32_cpu_csr_read(CSR_TIMEH), neorv32_cpu_csr_read(CSR_TIME));
|
|
|
|
|
// cause
|
register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
|
|
register uint32_t trap_inst;
|
|
|
|
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
|
|
|
|
|
|
if (trap_cause & 0x80000000) {
|
|
neorv32_uart_printf("INTERRUPT");
|
|
}
|
|
else {
|
|
neorv32_uart_printf("EXCEPTION");
|
|
if ((trap_inst & 3) == 3) {
|
|
trap_addr -= 4;
|
|
}
|
|
else {
|
|
trap_addr -= 2;
|
|
}
|
|
}
|
|
neorv32_uart_printf(" at instruction address: 0x%x\n", trap_addr);
|
|
|
|
neorv32_uart_printf("Cause: ");
|
|
switch (trap_cause) {
|
switch (trap_cause) {
|
case TRAP_CODE_I_MISALIGNED: neorv32_uart_printf("Instruction address misaligned"); break;
|
case TRAP_CODE_I_MISALIGNED: neorv32_uart_printf("Instruction address misaligned"); break;
|
case TRAP_CODE_I_ACCESS: neorv32_uart_printf("Instruction access fault"); break;
|
case TRAP_CODE_I_ACCESS: neorv32_uart_printf("Instruction access fault"); break;
|
case TRAP_CODE_I_ILLEGAL: neorv32_uart_printf("Illegal instruction"); break;
|
case TRAP_CODE_I_ILLEGAL: neorv32_uart_printf("Illegal instruction"); break;
|
case TRAP_CODE_BREAKPOINT: neorv32_uart_printf("Breakpoint (EBREAK)"); break;
|
case TRAP_CODE_BREAKPOINT: neorv32_uart_printf("Breakpoint (EBREAK)"); break;
|
Line 255... |
Line 234... |
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt channel 2"); break;
|
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt channel 2"); break;
|
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt channel 3"); break;
|
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt channel 3"); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
}
|
}
|
|
|
// fault address
|
// address
|
neorv32_uart_printf("\nFaulting instruction (low half word): 0x%x", trap_inst);
|
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
|
|
register uint32_t trap_inst;
|
if ((trap_inst & 3) != 3) {
|
|
neorv32_uart_printf(" (decompressed)\n");
|
|
}
|
|
|
|
neorv32_uart_printf("\nMTVAL: 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL));
|
|
|
|
neorv32_uart_printf("Trying to resume application @ 0x%x...", neorv32_cpu_csr_read(CSR_MEPC));
|
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
|
|
|
neorv32_uart_printf("\n<</NEORV32 Runtime Environment >>\n\n");
|
if ((trap_cause & 0x80000000) == 0) {
|
|
if ((trap_inst & 3) == 3) {
|
|
trap_addr -= 4;
|
|
}
|
|
else {
|
|
trap_addr -= 2;
|
|
}
|
|
}
|
|
neorv32_uart_printf(" @0x%x, MTVAL=0x%x </RTE>", trap_addr, neorv32_cpu_csr_read(CSR_MTVAL));
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* NEORV32 runtime environment: Print hardware configuration information via UART
|
* NEORV32 runtime environment: Print hardware configuration information via UART
|
Line 324... |
Line 306... |
neorv32_uart_putc(' ');
|
neorv32_uart_putc(' ');
|
}
|
}
|
}
|
}
|
neorv32_uart_printf("(0x%x)\n", tmp);
|
neorv32_uart_printf("(0x%x)\n", tmp);
|
|
|
// Clock speed
|
|
neorv32_uart_printf("Clock speed: %u Hz\n", SYSINFO_CLK);
|
// Misc
|
|
neorv32_uart_printf("\n-- System --\n");
|
|
neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
|
|
|
|
|
// Memory configuration
|
// Memory configuration
|
neorv32_uart_printf("\n-- Memory Configuration --\n");
|
neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
|
|
|
uint32_t size = SYSINFO_ISPACE_SIZE;
|
uint32_t size = SYSINFO_ISPACE_SIZE;
|
uint32_t base = SYSINFO_ISPACE_BASE;
|
uint32_t base = SYSINFO_ISPACE_BASE;
|
neorv32_uart_printf("Instruction memory: %u bytes @ 0x%x\n", size, base);
|
neorv32_uart_printf("Instruction memory: %u bytes @ 0x%x\n", size, base);
|
neorv32_uart_printf("Internal IMEM: ");
|
neorv32_uart_printf("Internal IMEM: ");
|
Line 351... |
Line 336... |
|
|
neorv32_uart_printf("External interface: ");
|
neorv32_uart_printf("External interface: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
|
|
|
// peripherals
|
// peripherals
|
neorv32_uart_printf("\n-- Peripherals --\n");
|
neorv32_uart_printf("\n-- Processor Peripherals --\n");
|
|
|
tmp = SYSINFO_FEATURES;
|
tmp = SYSINFO_FEATURES;
|
|
|
neorv32_uart_printf("GPIO: ");
|
neorv32_uart_printf("GPIO: ");
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
|
|
|