Line 33... |
Line 33... |
// #################################################################################################
|
// #################################################################################################
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* @file neorv32_rte.c
|
* @file neorv32_rte.c
|
* @author Stephan Nolting
|
|
* @brief NEORV32 Runtime Environment.
|
* @brief NEORV32 Runtime Environment.
|
**************************************************************************/
|
**************************************************************************/
|
|
|
#include "neorv32.h"
|
#include "neorv32.h"
|
#include "neorv32_rte.h"
|
#include "neorv32_rte.h"
|
Line 65... |
Line 64... |
void neorv32_rte_setup(void) {
|
void neorv32_rte_setup(void) {
|
|
|
// configure trap handler base address
|
// configure trap handler base address
|
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&__neorv32_rte_core));
|
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&__neorv32_rte_core));
|
|
|
|
// disable all IRQ channels
|
|
neorv32_cpu_csr_write(CSR_MIE, 0);
|
|
|
|
// clear all pending IRQs
|
|
neorv32_cpu_csr_write(CSR_MIP, 0);
|
|
|
|
// clear BUSKEEPER error flags
|
|
NEORV32_BUSKEEPER.CTRL = 0;
|
|
|
// install debug handler for all sources
|
// install debug handler for all sources
|
uint8_t id;
|
uint8_t id;
|
for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
|
for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
|
neorv32_rte_exception_uninstall(id); // this will configure the debug handler
|
neorv32_rte_exception_uninstall(id); // this will configure the debug handler
|
}
|
}
|
|
|
// clear BUSKEEPER error flags
|
|
NEORV32_BUSKEEPER.CTRL = 0;
|
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* Install exception handler function to NEORV32 runtime environment.
|
* Install exception handler function to NEORV32 runtime environment.
|
Line 129... |
Line 134... |
* @warning When using the the RTE, this function is the ONLY function that can use the 'interrupt' attribute!
|
* @warning When using the the RTE, this function is the ONLY function that can use the 'interrupt' attribute!
|
**************************************************************************/
|
**************************************************************************/
|
static void __attribute__((__interrupt__)) __attribute__((aligned(4))) __neorv32_rte_core(void) {
|
static void __attribute__((__interrupt__)) __attribute__((aligned(4))) __neorv32_rte_core(void) {
|
|
|
register uint32_t rte_mepc = neorv32_cpu_csr_read(CSR_MEPC);
|
register uint32_t rte_mepc = neorv32_cpu_csr_read(CSR_MEPC);
|
neorv32_cpu_csr_write(CSR_MSCRATCH, rte_mepc); // store for later
|
neorv32_cpu_csr_write(CSR_MSCRATCH, rte_mepc); // backup for later
|
register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
|
|
|
// compute return address
|
// compute return address
|
if (((int32_t)rte_mcause) >= 0) { // modify pc only if not interrupt (MSB cleared)
|
if (((int32_t)rte_mcause) >= 0) { // modify pc only if not interrupt (MSB cleared)
|
|
|
// get low half word of faulting instruction
|
// get low half word of faulting instruction
|
register uint32_t rte_trap_inst = neorv32_cpu_load_unsigned_half(rte_mepc);
|
register uint32_t rte_trap_inst = neorv32_cpu_load_unsigned_half(rte_mepc);
|
|
|
if ((rte_trap_inst & 3) == 3) { // faulting instruction is uncompressed instruction
|
rte_mepc += 4; // default: faulting instruction is uncompressed
|
rte_mepc += 4;
|
if (neorv32_cpu_csr_read(CSR_MISA) & (1 << CSR_MISA_C)) { // C extension implemented?
|
|
if ((rte_trap_inst & 3) != 3) { // faulting instruction is compressed instruction
|
|
rte_mepc -= 2;
|
}
|
}
|
else { // faulting instruction is compressed instruction
|
|
rte_mepc += 2;
|
|
}
|
}
|
|
|
// store new return address
|
// store new return address
|
neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
|
neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
|
}
|
}
|
Line 744... |
Line 749... |
uint32_t misa_hw = neorv32_cpu_csr_read(CSR_MISA);
|
uint32_t misa_hw = neorv32_cpu_csr_read(CSR_MISA);
|
|
|
// mask hardware features that are not used by software
|
// mask hardware features that are not used by software
|
uint32_t check = misa_hw & misa_sw;
|
uint32_t check = misa_hw & misa_sw;
|
|
|
//
|
|
if (check == misa_sw) {
|
if (check == misa_sw) {
|
return 0;
|
return 0;
|
}
|
}
|
else {
|
else {
|
if ((silent == 0) && (neorv32_uart0_available() != 0)) {
|
if ((silent == 0) && (neorv32_uart0_available() != 0)) {
|