OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_rte.c] - Diff between revs 67 and 68

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 67 Rev 68
Line 46... Line 46...
 * The >private< trap vector look-up table of the NEORV32 RTE.
 * The >private< trap vector look-up table of the NEORV32 RTE.
 **************************************************************************/
 **************************************************************************/
static uint32_t __neorv32_rte_vector_lut[NEORV32_RTE_NUM_TRAPS] __attribute__((unused)); // trap handler vector table
static uint32_t __neorv32_rte_vector_lut[NEORV32_RTE_NUM_TRAPS] __attribute__((unused)); // trap handler vector table
 
 
// private functions
// private functions
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16)));
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(4)));
static void __neorv32_rte_debug_exc_handler(void);
static void __neorv32_rte_debug_exc_handler(void);
static void __neorv32_rte_print_true_false(int state);
static void __neorv32_rte_print_true_false(int state);
static void __neorv32_rte_print_checkbox(int state);
static void __neorv32_rte_print_checkbox(int state);
static void __neorv32_rte_print_hex_word(uint32_t num);
static void __neorv32_rte_print_hex_word(uint32_t num);
 
 
Line 63... Line 63...
 * 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) {
 
 
  // configure trap handler base address
  // configure trap handler base address
  uint32_t mtvec_base = (uint32_t)(&__neorv32_rte_core);
  neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&__neorv32_rte_core));
  neorv32_cpu_csr_write(CSR_MTVEC, mtvec_base);
 
 
 
  // 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 109... Line 111...
 **************************************************************************/
 **************************************************************************/
int neorv32_rte_exception_uninstall(uint8_t id) {
int neorv32_rte_exception_uninstall(uint8_t id) {
 
 
  // id valid?
  // id valid?
  if ((id >= RTE_TRAP_I_MISALIGNED) && (id <= CSR_MIE_FIRQ15E)) {
  if ((id >= RTE_TRAP_I_MISALIGNED) && (id <= CSR_MIE_FIRQ15E)) {
    __neorv32_rte_vector_lut[id] = (uint32_t)(&__neorv32_rte_debug_exc_handler); // use dummy handler in case the exception is accidently triggered
    __neorv32_rte_vector_lut[id] = (uint32_t)(&__neorv32_rte_debug_exc_handler); // use dummy handler in case the exception is accidentally triggered
    return 0;
    return 0;
  }
  }
  return 1;
  return 1;
}
}
 
 
Line 124... Line 126...
 * @note This function must no be explicitly used by the user.
 * @note This function must no be explicitly used by the user.
 * @note The RTE core uses mscratch CSR to store the trap-causing mepc for further (user-defined) processing.
 * @note The RTE core uses mscratch CSR to store the trap-causing mepc for further (user-defined) processing.
 *
 *
 * @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(16)))  __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); // store 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 exception (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;
    register uint32_t rte_trap_inst;
    asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (rte_trap_inst) : [input_i] "r" (rte_mepc));
    asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (rte_trap_inst) : [input_i] "r" (rte_mepc));
 
 
Line 149... Line 151...
    // store new return address
    // store new return address
    neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
    neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
  }
  }
 
 
  // find according trap handler
  // find according trap handler
  register uint32_t rte_handler = (uint32_t)(&__neorv32_rte_debug_exc_handler);
  register uint32_t rte_handler;
  switch (rte_mcause) {
  switch (rte_mcause) {
    case TRAP_CODE_I_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_MISALIGNED]; break;
    case TRAP_CODE_I_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_MISALIGNED]; break;
    case TRAP_CODE_I_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ACCESS]; break;
    case TRAP_CODE_I_ACCESS:     rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ACCESS]; break;
    case TRAP_CODE_I_ILLEGAL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ILLEGAL]; break;
    case TRAP_CODE_I_ILLEGAL:    rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_I_ILLEGAL]; break;
    case TRAP_CODE_BREAKPOINT:   rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
    case TRAP_CODE_BREAKPOINT:   rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
Line 180... Line 182...
    case TRAP_CODE_FIRQ_11:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_11]; break;
    case TRAP_CODE_FIRQ_11:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_11]; break;
    case TRAP_CODE_FIRQ_12:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_12]; break;
    case TRAP_CODE_FIRQ_12:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_12]; break;
    case TRAP_CODE_FIRQ_13:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_13]; break;
    case TRAP_CODE_FIRQ_13:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_13]; break;
    case TRAP_CODE_FIRQ_14:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_14]; break;
    case TRAP_CODE_FIRQ_14:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_14]; break;
    case TRAP_CODE_FIRQ_15:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_15]; break;
    case TRAP_CODE_FIRQ_15:      rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_15]; break;
    default: break;
    default:                     rte_handler = (uint32_t)(&__neorv32_rte_debug_exc_handler); break;
  }
  }
 
 
  // execute handler
  // execute handler
  void (*handler_pnt)(void);
  void (*handler_pnt)(void);
  handler_pnt = (void*)rte_handler;
  handler_pnt = (void*)rte_handler;
Line 728... Line 730...
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * NEORV32 runtime environment: Check required ISA extensions (via compiler flags) against available ISA extensions (via MISA csr).
 * NEORV32 runtime environment: Check required ISA extensions (via compiler flags) against available ISA extensions (via MISA csr).
 *
 *
 * @param[in] silent Show error message (via neorv32.uart) if isa_sw > isa_hw when != 0.
 * @param[in] silent Show error message (via neorv32.uart) if isa_sw > isa_hw when = 0.
 * @return MISA content according to compiler configuration.
 * @return MISA content according to compiler configuration.
 **************************************************************************/
 **************************************************************************/
int neorv32_rte_check_isa(int silent) {
int neorv32_rte_check_isa(int silent) {
 
 
  uint32_t misa_sw = neorv32_rte_get_compiler_isa();
  uint32_t misa_sw = neorv32_rte_get_compiler_isa();
Line 744... Line 746...
  //
  //
  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)) {
      neorv32_uart0_printf("\nWARNING! SW_ISA (features required) vs HW_ISA (features available) mismatch!\n"
      neorv32_uart0_printf("\nWARNING! SW_ISA (features required) vs HW_ISA (features available) mismatch!\n"
                          "SW_ISA = 0x%x (compiler flags)\n"
                          "SW_ISA = 0x%x (compiler flags)\n"
                          "HW_ISA = 0x%x (misa csr)\n\n", misa_sw, misa_hw);
                          "HW_ISA = 0x%x (misa csr)\n\n", misa_sw, misa_hw);
    }
    }
    return 1;
    return 1;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.