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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [bootloader/] [bootloader.c] - Diff between revs 42 and 47

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

Rev 42 Rev 47
Line 151... Line 151...
 
 
/**********************************************************************//**
/**********************************************************************//**
 * This global variable keeps the size of the available executable in bytes.
 * This global variable keeps the size of the available executable in bytes.
 * If =0 no executable is available (yet).
 * If =0 no executable is available (yet).
 **************************************************************************/
 **************************************************************************/
uint32_t exe_available = 0;
volatile uint32_t exe_available = 0;
 
 
 
 
 
/**********************************************************************//**
 
 * Only set during executable fetch (required for cpaturing STORE-BUS-TIMOUT exception).
 
 **************************************************************************/
 
volatile uint32_t getting_exe = 0;
 
 
 
 
// Function prototypes
// Function prototypes
void __attribute__((__interrupt__)) bootloader_trap_handler(void);
void __attribute__((__interrupt__)) bootloader_trap_handler(void);
void fast_upload(int src);
void fast_upload(int src);
Line 185... Line 191...
 
 
#ifdef __riscv_compressed
#ifdef __riscv_compressed
  #warning In order to allow the bootloader to run on any CPU configuration it should be compiled using the base ISA (rv32i/e) only.
  #warning In order to allow the bootloader to run on any CPU configuration it should be compiled using the base ISA (rv32i/e) only.
#endif
#endif
 
 
  // global variable for executable size; 0 means there is no exe available
  exe_available = 0; // global variable for executable size; 0 means there is no exe available
  exe_available = 0;
  getting_exe   = 0; // we are not trying to get an executable yet
 
 
  // ------------------------------------------------
 
  // Minimal CPU hardware initialization
 
  // - all IO devices are reset and disabled by the crt0 code
 
  // ------------------------------------------------
 
 
 
  // confiure trap handler (bare-metal, no neorv32 rte available)
 
  neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
 
 
 
 
 
  // ------------------------------------------------
  // ------------------------------------------------
  // Minimal processor hardware initialization
  // Minimal processor hardware initialization
  // - all IO devices are reset and disabled by the crt0 code
  // - all IO devices are reset and disabled by the crt0 code
  // ------------------------------------------------
  // ------------------------------------------------
Line 224... Line 221...
  neorv32_uart_setup(BAUD_RATE, 0, 0, 0);
  neorv32_uart_setup(BAUD_RATE, 0, 0, 0);
 
 
  // Configure machine system timer interrupt for ~2Hz
  // Configure machine system timer interrupt for ~2Hz
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (clock_speed/4));
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (clock_speed/4));
 
 
 
  // confiure trap handler (bare-metal, no neorv32 rte available)
 
  neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&bootloader_trap_handler));
 
 
 
  // active timer IRQ
  neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source
  neorv32_cpu_csr_write(CSR_MIE, 1 << CSR_MIE_MTIE); // activate MTIME IRQ source
  neorv32_cpu_eint(); // enable global interrupts
  neorv32_cpu_eint(); // enable global interrupts
 
 
 
 
  // ------------------------------------------------
  // ------------------------------------------------
Line 403... Line 404...
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Bootloader trap handler. Used for the MTIME tick and to capture any other traps.
 * Bootloader trap handler. Used for the MTIME tick and to capture any other traps.
 * @warning Since we have no runtime environment, we have to use the interrupt attribute here. Here, and only here!
 * @warning Since we have no runtime environment, we have to use the interrupt attribute here. Here and only here!
 **************************************************************************/
 **************************************************************************/
void __attribute__((__interrupt__)) bootloader_trap_handler(void) {
void __attribute__((__interrupt__)) bootloader_trap_handler(void) {
 
 
  // make sure this was caused by MTIME IRQ
 
  uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
  uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
 
 
 
  // make sure this was caused by MTIME IRQ
  if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
  if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
    if (STATUS_LED_EN == 1) {
    if (STATUS_LED_EN == 1) {
      // toggle status LED
      // toggle status LED
      neorv32_gpio_pin_toggle(STATUS_LED);
      neorv32_gpio_pin_toggle(STATUS_LED);
    }
    }
    // set time for next IRQ
    // set time for next IRQ
    neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
    neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
  }
  }
 
  else {
  else if (cause == TRAP_CODE_S_ACCESS) { // seems like executable is too large
    // store bus access error during get_exe
 
    // -> seems like executable is too large
 
    if ((cause == TRAP_CODE_S_ACCESS) && (getting_exe)) {
    system_error(ERROR_SIZE);
    system_error(ERROR_SIZE);
  }
  }
 
    // unknown error
  else {
  else {
    neorv32_uart_print("\n\nEXC (");
    neorv32_uart_print("\n\nEXC (");
    print_hex_word(cause);
    print_hex_word(cause);
    neorv32_uart_print(") @ 0x");
    neorv32_uart_print(") @ 0x");
    print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
    print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
    system_error(ERROR_SYSTEM);
    system_error(ERROR_SYSTEM);
  }
  }
}
}
 
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Get executable stream.
 * Get executable stream.
 *
 *
 * @param src Source of executable stream data. See #EXE_STREAM_SOURCE.
 * @param src Source of executable stream data. See #EXE_STREAM_SOURCE.
 **************************************************************************/
 **************************************************************************/
void get_exe(int src) {
void get_exe(int src) {
 
 
 
  getting_exe = 1; // to inform trap handler we were trying to get an executable
 
 
  // is MEM implemented and read-only?
  // is MEM implemented and read-only?
  if ((SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) &&
  if ((SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) &&
      (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)))  {
      (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)))  {
    system_error(ERROR_ROM);
    system_error(ERROR_ROM);
  }
  }
Line 491... Line 498...
  }
  }
  else {
  else {
    neorv32_uart_print("OK");
    neorv32_uart_print("OK");
    exe_available = size; // store exe size
    exe_available = size; // store exe size
  }
  }
 
 
 
  getting_exe = 0; // to inform trap handler we are done getting an executable
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Store content of instruction memory to SPI flash.
 * Store content of instruction memory to SPI flash.

powered by: WebSVN 2.1.0

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