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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [bootloader/] [bootloader.c] - Diff between revs 22 and 23

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

Rev 22 Rev 23
Line 225... Line 225...
  neorv32_uart_print("\nMISA: ");
  neorv32_uart_print("\nMISA: ");
  print_hex_word(neorv32_cpu_csr_read(CSR_MISA));
  print_hex_word(neorv32_cpu_csr_read(CSR_MISA));
  neorv32_uart_print("\nCONF: ");
  neorv32_uart_print("\nCONF: ");
  print_hex_word(SYSINFO_FEATURES);
  print_hex_word(SYSINFO_FEATURES);
  neorv32_uart_print("\nIMEM: ");
  neorv32_uart_print("\nIMEM: ");
  print_hex_word(SYSINFO_ISPACE_SIZE);
  print_hex_word(SYSINFO_IMEM_SIZE);
  neorv32_uart_print(" bytes @ ");
  neorv32_uart_print(" bytes @ ");
  print_hex_word(SYSINFO_ISPACE_BASE);
  print_hex_word(SYSINFO_ISPACE_BASE);
  neorv32_uart_print("\nDMEM: ");
  neorv32_uart_print("\nDMEM: ");
  print_hex_word(SYSINFO_DSPACE_SIZE);
  print_hex_word(SYSINFO_DMEM_SIZE);
  neorv32_uart_print(" bytes @ ");
  neorv32_uart_print(" bytes @ ");
  print_hex_word(SYSINFO_DSPACE_BASE);
  print_hex_word(SYSINFO_DSPACE_BASE);
 
 
 
 
  // ------------------------------------------------
  // ------------------------------------------------
Line 322... Line 322...
    neorv32_uart_print("No executable available.");
    neorv32_uart_print("No executable available.");
    return;
    return;
  }
  }
 
 
  // no need to shutdown or reset the used peripherals
  // no need to shutdown or reset the used peripherals
 
  // no need to disable interrupt sources
  // -> this will be done by application's crt0
  // -> this will be done by application's crt0
 
 
  // deactivate IRQs and IRQ sources
  // deactivate global IRQs
  neorv32_cpu_dint();
  neorv32_cpu_dint();
  neorv32_cpu_csr_write(CSR_MIE, 0);
 
 
 
  neorv32_uart_print("Booting...\n\n");
  neorv32_uart_print("Booting...\n\n");
 
 
  // wait for UART to finish transmitting
  // wait for UART to finish transmitting
  while ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0);
  while ((UART_CT & (1<<UART_CT_TX_BUSY)) != 0);
 
 
  // reset performance counters (to benchmark actual application)
  // reset performance counters (to benchmark actual application)
  asm volatile ("csrw mcycle,    zero"); // will also clear 'cycle'
  asm volatile ("csrw mcycle,    zero"); // also clears 'cycle'
  asm volatile ("csrw mcycleh,   zero"); // will also clear 'cycleh'
  asm volatile ("csrw mcycleh,   zero"); // also clears 'cycleh'
  asm volatile ("csrw minstret,  zero"); // will also clear 'instret'
  asm volatile ("csrw minstret,  zero"); // also clears 'instret'
  asm volatile ("csrw minstreth, zero"); // will also clear 'instreth'
  asm volatile ("csrw minstreth, zero"); // also clears 'instreth'
 
 
  // start app at instruction space base address
  // start app at instruction space base address
  register uint32_t app_base = SYSINFO_ISPACE_BASE;
  register uint32_t app_base = SYSINFO_ISPACE_BASE;
  asm volatile ("jalr zero, %0" : : "r" (app_base));
  asm volatile ("jalr zero, %0" : : "r" (app_base));
  while (1);
  while (1);
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Bootloader trap handler.
 * Bootloader trap handler. Used for the MTIME tick and to capture any other traps.
 * Primarily used for the MTIME tick.
 
 * @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
  // 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);
  if (cause != TRAP_CODE_MTI) { // raw exception code for MTI
  if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
    neorv32_uart_print("\n\nEXCEPTION (");
 
    print_hex_word(cause);
 
    neorv32_uart_print(") @ 0x");
 
    print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
 
    system_error(ERROR_SYSTEM);
 
    while(1); // freeze
 
  }
 
  else {
 
    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 if (cause == TRAP_CODE_S_ACCESS) { // seems like executable is too large
 
    system_error(ERROR_SIZE);
 
  }
 
 
 
  else {
 
    neorv32_uart_print("\n\nEXCEPTION (");
 
    print_hex_word(cause);
 
    neorv32_uart_print(") @ 0x");
 
    print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
 
    system_error(ERROR_SYSTEM);
 
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Get executable stream.
 * Get executable stream.
Line 412... Line 415...
 
 
  // image size and checksum
  // image size and checksum
  uint32_t size  = get_exe_word(src, addr + EXE_OFFSET_SIZE); // size in bytes
  uint32_t size  = get_exe_word(src, addr + EXE_OFFSET_SIZE); // size in bytes
  uint32_t check = get_exe_word(src, addr + EXE_OFFSET_CHECKSUM); // complement sum checksum
  uint32_t check = get_exe_word(src, addr + EXE_OFFSET_CHECKSUM); // complement sum checksum
 
 
  // executable too large?
 
  uint32_t imem_size = SYSINFO_ISPACE_SIZE;
 
  if (size > imem_size) {
 
    system_error(ERROR_SIZE);
 
  }
 
 
 
  // transfer program data
  // transfer program data
  uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE;
  uint32_t *pnt = (uint32_t*)SYSINFO_ISPACE_BASE;
  uint32_t checksum = 0;
  uint32_t checksum = 0;
  uint32_t d = 0, i = 0;
  uint32_t d = 0, i = 0;
  addr = addr + EXE_OFFSET_DATA;
  addr = addr + EXE_OFFSET_DATA;
Line 546... Line 543...
 *
 *
 * @param[in] err_code Error code. See #ERROR_CODES.
 * @param[in] err_code Error code. See #ERROR_CODES.
 **************************************************************************/
 **************************************************************************/
void system_error(uint8_t err_code) {
void system_error(uint8_t err_code) {
 
 
  neorv32_uart_print("\a\nBootloader ERR_"); // output error code with annoying bell sound
  neorv32_uart_print("\a\nERROR_"); // output error code with annoying bell sound
  neorv32_uart_putc('0' + ((char)err_code)); // FIXME err_code should/must be below 10
  neorv32_uart_putc('0' + ((char)err_code)); // FIXME err_code should/must be below 10
 
 
  neorv32_cpu_dint(); // deactivate IRQs
  neorv32_cpu_dint(); // deactivate IRQs
  if (STATUS_LED_EN == 1) {
  if (STATUS_LED_EN == 1) {
    neorv32_gpio_port_set(1 << STATUS_LED); // permanently light up status LED
    neorv32_gpio_port_set(1 << STATUS_LED); // permanently light up status LED

powered by: WebSVN 2.1.0

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