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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [common/] [crt0.S] - Diff between revs 59 and 61

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

Rev 59 Rev 61
Line 42... Line 42...
.cfi_startproc
.cfi_startproc
.cfi_undefined ra
.cfi_undefined ra
 
 
  nop
  nop
 
 
// *********************************************************
// ************************************************************************************************
// Clear integer register file (lower half, assume E extension)
 
// *********************************************************
 
__crt0_reg_file_clear:
 
//addi  x0, x0, 0 // hardwired to zero
 
  addi  x1, x0, 0
 
  addi  x2, x0, 0
 
  addi  x3, x0, 0
 
  addi  x4, x0, 0
 
  addi  x5, x0, 0
 
  addi  x6, x0, 0
 
  addi  x7, x0, 0
 
//addi  x8, x0, 0
 
//addi  x9, x0, 0
 
//addi x10, x0, 0
 
//addi x11, x0, 0
 
//addi x12, x0, 0
 
//addi x13, x0, 0
 
  addi x14, x0, 0
 
  addi x15, x0, 0
 
 
 
 
 
// *********************************************************
 
// Setup pointers using linker script symbols
// Setup pointers using linker script symbols
// *********************************************************
// ************************************************************************************************
__crt0_pointer_init:
__crt0_pointer_init:
.option push
.option push
.option norelax
.option norelax
  la    sp, __crt0_stack_begin
 
  andi  sp, sp, 0xfffffffc // make sure this is aligned
  la sp, __crt0_stack_begin  // stack pointer
  addi  fp, sp, 0          // frame pointer = stack pointer
 
  la gp, __global_pointer$ // global pointer
  la gp, __global_pointer$ // global pointer
 
 
.option pop
.option pop
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Setup CPU core CSRs (some of them DO NOT have a dedicated reset and need to be explicitly initialized)
// Setup CPU core CSRs (some of them DO NOT have a dedicated
// *********************************************************
// reset and need to be explicitly initialized)
 
// ************************************************************************************************
__crt0_cpu_csr_init:
__crt0_cpu_csr_init:
 
 
  // set address of first-level exception handler
  la   x10,   __crt0_dummy_trap_handler // configure early trap handler
  la   x10, __crt0_dummy_trap_handler
 
  csrw mtvec,  x10
  csrw mtvec,  x10
  csrw mepc,   x10
  csrw mepc,  x10                       // just to init mepc
  csrw mtval,  zero
 
  csrw mcause, zero
 
 
 
  // no global IRQ enable (is also done by hardware)
  csrw mstatus, zero                    // disable global IRQ
  csrw mstatus, zero
 
 
 
  // absolutely no interrupts, thanks
  csrw mie, zero                        // absolutely no interrupts sources, thanks
  csrw mie, zero
 
 
 
  // no access from less-privileged modes to counter CSRs
  csrw mcounteren, zero                 // no access from less-privileged modes to counter CSRs
  csrw mcounteren, zero
 
 
 
  // stop all counters except for [m]cycle[h] and [m]instret[h]
  li   x11,   ~5                        // stop all counters except for [m]cycle[h] and [m]instret[h]
  li   x11, ~5
  csrw 0x320, x11                       // = mcountinhibit (literal address for lagacy toolchain compatibility)
  csrw 0x320, x11 // mcountinhibit (literal address for lagacy toolchain compatibility)
 
 
 
  // clear cycle counters
  csrw mcycle,    zero                  // reset cycle counters
  csrw mcycle,  zero
 
  csrw mcycleh, zero
  csrw mcycleh, zero
 
  csrw minstret,  zero                  // reset instruction counters
  // clear instruction counters
 
  csrw minstret,  zero
 
  csrw minstreth, zero
  csrw minstreth, zero
 
 
#if defined(__riscv_flen) && (__riscv_flen != 0)
#if defined(__riscv_flen)
  // clear floating-point CSR (rounding mode & exception flags)
  csrw fcsr, zero                       // reset floating-point CSR
  csrw fcsr, zero
 
#endif
#endif
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Clear integer register file (upper half, if no E extension)
// Initialize integer register file (lower half)
// *********************************************************
// ************************************************************************************************
 
__crt0_reg_file_clear:
 
//addi  x0, x0, 0 // hardwired to zero
 
  addi  x1, x0, 0
 
//addi  x2, x0, 0 // stack pointer sp
 
//addi  x3, x0, 0 // gloabl pointer gp
 
  addi  x4, x0, 0
 
  addi  x5, x0, 0
 
  addi  x6, x0, 0
 
  addi  x7, x0, 0
 
//addi  x8, x0, 0 // initialized within crt0
 
//addi  x9, x0, 0 // initialized within crt0
 
//addi x10, x0, 0 // initialized within crt0
 
//addi x11, x0, 0 // initialized within crt0
 
//addi x12, x0, 0 // initialized within crt0
 
//addi x13, x0, 0 // initialized within crt0
 
  addi x14, x0, 0
 
  addi x15, x0, 0
 
 
 
 
 
// ************************************************************************************************
 
// Initialize integer register file (upper half, if no E extension)
 
// ************************************************************************************************
#ifndef __riscv_32e
#ifndef __riscv_32e
// DO NOT DO THIS if compiling bootloader (to save some program space)
// do not do this if compiling bootloader (to save some program space)
#ifndef make_bootloader
#ifndef make_bootloader
  addi x16, x0, 0
  addi x16, x0, 0
  addi x17, x0, 0
  addi x17, x0, 0
  addi x18, x0, 0
  addi x18, x0, 0
  addi x19, x0, 0
  addi x19, x0, 0
Line 142... Line 132...
  addi x31, x0, 0
  addi x31, x0, 0
#endif
#endif
#endif
#endif
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Reset/deactivate IO/peripheral devices
// Reset/deactivate IO/peripheral devices
// Devices, that are not implemented, will cause a store access fault
// Devices, that are not implemented, will cause a store bus access fault
// which is captured but actually ignored due to the dummy handler.
// which is captured (but actually ignored) by the dummy trap handler.
// *********************************************************
// ************************************************************************************************
__crt0_reset_io:
__crt0_reset_io:
  la x8, __ctr0_io_space_begin // start of processor-internal IO region
  la x8, __ctr0_io_space_begin // start of processor-internal IO region
  la x9, __ctr0_io_space_end   // end of processor-internal IO region
  la x9, __ctr0_io_space_end   // end of processor-internal IO region
 
 
__crt0_reset_io_loop:
__crt0_reset_io_loop:
  sw   zero, 0(x8)
  sw   zero, 0(x8)
  addi x8,   x8, 4
  addi x8,   x8, 4
  bne  x8,   x9, __crt0_reset_io_loop
  bne  x8,   x9, __crt0_reset_io_loop
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Clear .bss section (byte-wise) using linker script symbols
// Clear .bss section (byte-wise) using linker script symbols
// *********************************************************
// ************************************************************************************************
__crt0_clear_bss:
__crt0_clear_bss:
  la x11, __crt0_bss_start
  la x11, __crt0_bss_start
  la x12, __crt0_bss_end
  la x12, __crt0_bss_end
 
 
__crt0_clear_bss_loop:
__crt0_clear_bss_loop:
Line 173... Line 163...
  j    __crt0_clear_bss_loop
  j    __crt0_clear_bss_loop
 
 
__crt0_clear_bss_loop_end:
__crt0_clear_bss_loop_end:
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Copy initialized .data section from ROM to RAM (byte-wise) using linker script symbols
// Copy initialized .data section from ROM to RAM (byte-wise) using linker script symbols
// *********************************************************
// ************************************************************************************************
__crt0_copy_data:
__crt0_copy_data:
  la x11, __crt0_copy_data_src_begin  // start of data area (copy source)
  la x11, __crt0_copy_data_src_begin  // start of data area (copy source)
  la x12, __crt0_copy_data_dst_begin  // start of data area (copy destination)
  la x12, __crt0_copy_data_dst_begin  // start of data area (copy destination)
  la x13, __crt0_copy_data_dst_end    // last address of destination data area
  la x13, __crt0_copy_data_dst_end    // last address of destination data area
 
 
Line 192... Line 182...
  j    __crt0_copy_data_loop
  j    __crt0_copy_data_loop
 
 
__crt0_copy_data_loop_end:
__crt0_copy_data_loop_end:
 
 
 
 
// *********************************************************
// ************************************************************************************************
// Call main function
// Setup arguments and call main function
// *********************************************************
// ************************************************************************************************
__crt0_main_entry:
__crt0_main_entry:
 
  addi x10, zero, 0 // a0 = argc = 0
 
  addi x11, zero, 0 // a1 = argv = 0
 
  jal  ra,  main    // call actual app's main function, this "should" not return
 
 
 
 
 
// ************************************************************************************************
 
// call "after main" handler (if there is any) if main really returns
 
// ************************************************************************************************
 
__crt0_main_aftermath:
 
  csrw  mscratch, a0                 // copy main's return code in mscratch for debugger
 
 
 
#ifndef make_bootloader              // after_main handler not supported for bootloader
 
  .weak __neorv32_crt0_after_main
 
  la   ra, __neorv32_crt0_after_main
 
  beqz ra, __crt0_main_aftermath_end // check if an aftermath handler has been specified
 
  jalr ra                            // execute handler, main's return code in a0
 
#endif
 
 
 
 
  // setup arguments for calling main
// ************************************************************************************************
  addi x10, zero, 0 // argc = 0
// go to endless sleep mode
  addi x11, zero, 0 // argv = 0
// ************************************************************************************************
 
__crt0_main_aftermath_end:
  // call actual app's main function
  csrci mstatus,  8                  // mstatus: disable global IRQs (mstatus.mie)
  jal ra, main
__crt0_main_aftermath_end_loop:
 
  wfi                                // try to go to sleep mode
 
  j __crt0_main_aftermath_end_loop   // endless loop
// *********************************************************
 
// Go to endless sleep mode if main returns
 
// *********************************************************
// ************************************************************************************************
__crt0_this_is_the_end:
// dummy trap handler (for exceptions & IRQs during very early boot stage)
  csrrci zero, mstatus, 8 // mstatus: disable global IRQs (MIE)
// does nothing but tries to move on to next instruction
__crt0_this_is_the_end_my_friend:
// ************************************************************************************************
  wfi
 
  j __crt0_this_is_the_end_my_friend
 
 
 
 
 
// *********************************************************
 
// dummy trap handler (for exceptions & IRQs)
 
// tries to move on to next instruction
 
// *********************************************************
 
.global __crt0_dummy_trap_handler
 
.balign 4
.balign 4
__crt0_dummy_trap_handler:
__crt0_dummy_trap_handler:
 
 
  addi  sp, sp, -8
  addi  sp, sp, -8
  sw      x8, 0(sp)
  sw      x8, 0(sp)
Line 232... Line 231...
  csrr  x8, mcause
  csrr  x8, mcause
  blt   x8, zero, __crt0_dummy_trap_handler_irq  // skip mepc modification if interrupt
  blt   x8, zero, __crt0_dummy_trap_handler_irq  // skip mepc modification if interrupt
 
 
  csrr  x8, mepc
  csrr  x8, mepc
 
 
// is compressed instruction?
__crt0_dummy_trap_handler_exc_c_check:             // is compressed instruction?
__crt0_dummy_trap_handler_exc_c_check:
 
  lh    x9, 0(x8)   // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
  lh    x9, 0(x8)   // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
  andi  x9, x9, 3   // mask: isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
  andi  x9, x9, 3   // mask: isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
 
 
  addi  x8, x8, +2  // only this for compressed instructions
  addi  x8, x8, +2  // only this for compressed instructions
  csrw  mepc, x8    // set return address when compressed instruction
  csrw  mepc, x8    // set return address when compressed instruction
 
 
  addi  x8, zero, 3
  addi  x8, zero, 3
  bne   x8, x9, __crt0_dummy_trap_handler_irq // jump if compressed instruction
  bne   x8, x9, __crt0_dummy_trap_handler_irq // jump if compressed instruction
 
 
// is uncompressed instruction
__crt0_dummy_trap_handler_exc_uncrompressed:       // is uncompressed instruction!
__crt0_dummy_trap_handler_exc_uncrompressed:
 
  csrr  x8, mepc
  csrr  x8, mepc
  addi  x8, x8, +2  // add another 2 (making +4) for uncompressed instructions
  addi  x8, x8, +2  // add another 2 (making +4) for uncompressed instructions
  csrw  mepc, x8
  csrw  mepc, x8
 
 
__crt0_dummy_trap_handler_irq:
__crt0_dummy_trap_handler_irq:
 
 
  lw    x8, 0(sp)
  lw    x8, 0(sp)
  lw    x9, 4(sp)
  lw    x9, 4(sp)
  addi  sp, sp, +8
  addi  sp, sp, +8
 
 
  mret
  mret

powered by: WebSVN 2.1.0

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