Line 60... |
Line 60... |
* gives detailed information about the exception/interrupt. Actual handler can be installed afterwards
|
* gives detailed information about the exception/interrupt. Actual handler can be installed afterwards
|
* via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
|
* via neorv32_rte_exception_install(uint8_t id, void (*handler)(void)).
|
**************************************************************************/
|
**************************************************************************/
|
void neorv32_rte_setup(void) {
|
void neorv32_rte_setup(void) {
|
|
|
|
// check if CSR system is available at all
|
|
if (neorv32_cpu_csr_read(CSR_MISA) == 0) {
|
|
neorv32_uart_printf("<RTE> WARNING! CPU CSR system not available! </RTE>");
|
|
}
|
|
|
// configure trap handler base address
|
// configure trap handler base address
|
uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
|
uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
|
neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
|
neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
|
|
|
// install debug handler for all sources
|
// install debug handler for all sources
|
Line 208... |
Line 213... |
case TRAP_CODE_S_ACCESS: neorv32_uart_printf("Store access fault"); break;
|
case TRAP_CODE_S_ACCESS: neorv32_uart_printf("Store access fault"); break;
|
case TRAP_CODE_MENV_CALL: neorv32_uart_printf("Environment call"); break;
|
case TRAP_CODE_MENV_CALL: neorv32_uart_printf("Environment call"); break;
|
case TRAP_CODE_MSI: neorv32_uart_printf("Machine software interrupt"); break;
|
case TRAP_CODE_MSI: neorv32_uart_printf("Machine software interrupt"); break;
|
case TRAP_CODE_MTI: neorv32_uart_printf("Machine timer interrupt"); break;
|
case TRAP_CODE_MTI: neorv32_uart_printf("Machine timer interrupt"); break;
|
case TRAP_CODE_MEI: neorv32_uart_printf("Machine external interrupt"); break;
|
case TRAP_CODE_MEI: neorv32_uart_printf("Machine external interrupt"); break;
|
case TRAP_CODE_FIRQ_0: neorv32_uart_printf("Fast interrupt 0 (WDT)"); break;
|
case TRAP_CODE_FIRQ_0: neorv32_uart_printf("Fast interrupt 0"); break;
|
case TRAP_CODE_FIRQ_1: neorv32_uart_printf("Fast interrupt 1 (GPIO)"); break;
|
case TRAP_CODE_FIRQ_1: neorv32_uart_printf("Fast interrupt 1"); break;
|
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt 2 (UART)"); break;
|
case TRAP_CODE_FIRQ_2: neorv32_uart_printf("Fast interrupt 2"); break;
|
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt 3 (SPI/TWI)"); break;
|
case TRAP_CODE_FIRQ_3: neorv32_uart_printf("Fast interrupt 3"); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
}
|
}
|
|
|
// address
|
// address
|
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
|
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
|
register uint32_t trap_inst;
|
register uint32_t trap_inst;
|
|
|
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
|
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
|
|
|
if ((trap_cause & 0x80000000) == 0) {
|
if ((trap_cause & 0x80000000) == 0) { // is exception?
|
if ((trap_inst & 3) == 3) {
|
if ((trap_inst & 3) == 3) { // is uncompressed instruction?
|
trap_addr -= 4;
|
trap_addr -= 4;
|
}
|
}
|
else {
|
else {
|
trap_addr -= 2;
|
trap_addr -= 2;
|
}
|
}
|