Line 44... |
Line 44... |
|
|
// Privates
|
// Privates
|
static void __neorv32_rte_dummy_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_dummy_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
|
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
|
static void __neorv32_rte_print_hw_version(void) __attribute__((unused));
|
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* Setup NEORV32 runtime environment in debug mode.
|
* Setup NEORV32 runtime environment in debug mode.
|
*
|
*
|
Line 92... |
Line 91... |
|
|
if (exc_id == EXCID_MSI) { neorv32_cpu_irq_enable(CPU_MIE_MSIE); } // activate software interrupt
|
if (exc_id == EXCID_MSI) { neorv32_cpu_irq_enable(CPU_MIE_MSIE); } // activate software interrupt
|
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_enable(CPU_MIE_MTIE); } // activate timer interrupt
|
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_enable(CPU_MIE_MTIE); } // activate timer interrupt
|
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_enable(CPU_MIE_MEIE); } // activate external interrupt
|
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_enable(CPU_MIE_MEIE); } // activate external interrupt
|
|
|
uint32_t vt_base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); // base address of vector table
|
uint32_t vt_base = SYSINFO_DSPACE_BASE; // base address of vector table
|
vt_base = vt_base + (((uint32_t)exc_id) << 2);
|
vt_base = vt_base + (((uint32_t)exc_id) << 2);
|
(*(IO_REG32 (vt_base))) = (uint32_t)handler;
|
(*(IO_REG32 (vt_base))) = (uint32_t)handler;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
Line 125... |
Line 124... |
|
|
if (exc_id == EXCID_MSI) { neorv32_cpu_irq_disable(CPU_MIE_MSIE); } // deactivate software interrupt
|
if (exc_id == EXCID_MSI) { neorv32_cpu_irq_disable(CPU_MIE_MSIE); } // deactivate software interrupt
|
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_disable(CPU_MIE_MTIE); } // deactivate timer interrupt
|
if (exc_id == EXCID_MTI) { neorv32_cpu_irq_disable(CPU_MIE_MTIE); } // deactivate timer interrupt
|
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_disable(CPU_MIE_MEIE); } // deactivate external interrupt
|
if (exc_id == EXCID_MEI) { neorv32_cpu_irq_disable(CPU_MIE_MEIE); } // deactivate external interrupt
|
|
|
uint32_t vt_base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); // base address of vector table
|
uint32_t vt_base = SYSINFO_DSPACE_BASE; // base address of vector table
|
vt_base = vt_base + (((uint32_t)exc_id) << 2);
|
vt_base = vt_base + (((uint32_t)exc_id) << 2);
|
(*(IO_REG32 (vt_base))) = (uint32_t)(&__neorv32_rte_dummy_exc_handler); // use dummy handler in case the exception is triggered
|
(*(IO_REG32 (vt_base))) = (uint32_t)(&__neorv32_rte_dummy_exc_handler); // use dummy handler in case the exception is triggered
|
|
|
return 0;
|
return 0;
|
}
|
}
|
Line 159... |
Line 158... |
|
|
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_addr = neorv32_cpu_csr_read(CSR_MEPC);
|
register uint32_t trap_inst;
|
register uint32_t trap_inst;
|
|
|
// get faulting instruction
|
|
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) {
|
if (trap_cause & 0x80000000) {
|
neorv32_uart_printf("INTERRUPT");
|
neorv32_uart_printf("INTERRUPT");
|
}
|
}
|
else {
|
else {
|
neorv32_uart_printf("EXCEPTION");
|
neorv32_uart_printf("EXCEPTION");
|
Line 194... |
Line 193... |
case 0x8000000B: neorv32_uart_printf("Machine external interrupt (via CLIC)"); break;
|
case 0x8000000B: neorv32_uart_printf("Machine external interrupt (via CLIC)"); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
|
}
|
}
|
|
|
// fault address
|
// fault address
|
neorv32_uart_printf("\nFaulting instruction: 0x%x\n", trap_inst);
|
neorv32_uart_printf("\nFaulting instruction (low): 0x%x\n", trap_inst);
|
neorv32_uart_printf("MTVAL: 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL));
|
neorv32_uart_printf("MTVAL: 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL));
|
|
|
if ((trap_inst & 3) != 3) {
|
if ((trap_inst & 3) != 3) {
|
neorv32_uart_printf("(decompressed)\n");
|
neorv32_uart_printf("(decompressed)\n");
|
}
|
}
|
Line 222... |
Line 221... |
|
|
// CPU configuration
|
// CPU configuration
|
neorv32_uart_printf("\n-- Central Processing Unit --\n");
|
neorv32_uart_printf("\n-- Central Processing Unit --\n");
|
|
|
// Hart ID
|
// Hart ID
|
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
|
neorv32_uart_printf("Hart ID: %u\n", neorv32_cpu_csr_read(CSR_MHARTID));
|
|
|
|
// Custom user code
|
|
neorv32_uart_printf("User code: 0x%x\n", SYSINFO_USER_CODE);
|
|
|
// HW version
|
// HW version
|
neorv32_uart_printf("Hardware version: ");
|
neorv32_uart_printf("Hardware version: ");
|
__neorv32_rte_print_hw_version();
|
neorv32_rte_print_hw_version();
|
neorv32_uart_printf(" (0x%x)\n", neorv32_cpu_csr_read(CSR_MIMPID));
|
neorv32_uart_printf(" (0x%x)\n", neorv32_cpu_csr_read(CSR_MIMPID));
|
|
|
// CPU architecture
|
// CPU architecture
|
neorv32_uart_printf("Architecture: ");
|
neorv32_uart_printf("Architecture: ");
|
tmp = neorv32_cpu_csr_read(CSR_MISA);
|
tmp = neorv32_cpu_csr_read(CSR_MISA);
|
Line 258... |
Line 260... |
neorv32_uart_putc(' ');
|
neorv32_uart_putc(' ');
|
}
|
}
|
}
|
}
|
neorv32_uart_printf("(0x%x)\n", tmp);
|
neorv32_uart_printf("(0x%x)\n", tmp);
|
|
|
// Performance counters
|
|
neorv32_uart_printf("CNT & time CSRs: ");
|
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_CSR_COUNTERS));
|
|
|
|
// Clock speed
|
// Clock speed
|
neorv32_uart_printf("Clock speed: %u Hz\n", neorv32_cpu_csr_read(CSR_MCLOCK));
|
neorv32_uart_printf("Clock speed: %u Hz\n", SYSINFO_CLK);
|
|
|
// Memory configuration
|
// Memory configuration
|
neorv32_uart_printf("\n-- Memory Configuration --\n");
|
neorv32_uart_printf("\n-- Memory Configuration --\n");
|
|
|
uint32_t size = neorv32_cpu_csr_read(CSR_MISPACESIZE);
|
uint32_t size = SYSINFO_ISPACE_SIZE;
|
uint32_t base = neorv32_cpu_csr_read(CSR_MISPACEBASE);
|
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: ");
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
|
neorv32_uart_printf("Internal IMEM as ROM: ");
|
neorv32_uart_printf("Internal IMEM as ROM: ");
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM_ROM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
|
|
|
size = neorv32_cpu_csr_read(CSR_MDSPACESIZE);
|
size = SYSINFO_DSPACE_SIZE;
|
base = neorv32_cpu_csr_read(CSR_MDSPACEBASE);
|
base = SYSINFO_DSPACE_BASE;
|
neorv32_uart_printf("Data memory: %u bytes @ 0x%x\n", size, base);
|
neorv32_uart_printf("Data memory: %u bytes @ 0x%x\n", size, base);
|
neorv32_uart_printf("Internal DMEM: ");
|
neorv32_uart_printf("Internal DMEM: ");
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_DMEM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
|
|
|
neorv32_uart_printf("Bootloader: ");
|
neorv32_uart_printf("Bootloader: ");
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_BOOTLOADER));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
|
|
|
neorv32_uart_printf("External interface: ");
|
neorv32_uart_printf("External interface: ");
|
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_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-- Peripherals --\n");
|
tmp = neorv32_cpu_csr_read(CSR_MFEATURES);
|
tmp = SYSINFO_FEATURES;
|
|
|
neorv32_uart_printf("GPIO: ");
|
neorv32_uart_printf("GPIO: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_GPIO));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
|
|
|
neorv32_uart_printf("MTIME: ");
|
neorv32_uart_printf("MTIME: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_MTIME));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
|
|
|
neorv32_uart_printf("UART: ");
|
neorv32_uart_printf("UART: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_UART));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART));
|
|
|
neorv32_uart_printf("SPI: ");
|
neorv32_uart_printf("SPI: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_SPI));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
|
|
|
neorv32_uart_printf("TWI: ");
|
neorv32_uart_printf("TWI: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TWI));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
|
|
|
neorv32_uart_printf("PWM: ");
|
neorv32_uart_printf("PWM: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_PWM));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
|
|
|
neorv32_uart_printf("WDT: ");
|
neorv32_uart_printf("WDT: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_WDT));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
|
|
|
neorv32_uart_printf("CLIC: ");
|
neorv32_uart_printf("CLIC: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_CLIC));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CLIC));
|
|
|
neorv32_uart_printf("TRNG: ");
|
neorv32_uart_printf("TRNG: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TRNG));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
|
|
|
neorv32_uart_printf("DEVNULL: ");
|
neorv32_uart_printf("DEVNULL: ");
|
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_DEVNULL));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_DEVNULL));
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* NEORV32 runtime environment: Private function to print true or false.
|
* NEORV32 runtime environment: Private function to print true or false.
|
Line 342... |
Line 340... |
}
|
}
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* NEORV32 runtime environment: Private function to show the processor version in human-readable format.
|
* NEORV32 runtime environment: Function to show the processor version in human-readable format.
|
* @note This function is used by neorv32_rte_print_hw_config(void) only.
|
|
**************************************************************************/
|
**************************************************************************/
|
static void __neorv32_rte_print_hw_version(void) {
|
void neorv32_rte_print_hw_version(void) {
|
|
|
uint32_t i;
|
uint32_t i;
|
char tmp, cnt;
|
char tmp, cnt;
|
uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID);
|
uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID);
|
|
|