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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [common/] [crt0.S] - Diff between revs 47 and 52

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 47 Rev 52
/* ################################################################################################# */
/* ################################################################################################# */
/* # << NEORV32 - crt0.S - Start-Up Code >>                                                        # */
/* # << NEORV32 - crt0.S - Start-Up Code >>                                                        # */
/* # ********************************************************************************************* # */
/* # ********************************************************************************************* # */
/* # BSD 3-Clause License                                                                          # */
/* # BSD 3-Clause License                                                                          # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     # */
/* # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # Redistribution and use in source and binary forms, with or without modification, are          # */
/* # Redistribution and use in source and binary forms, with or without modification, are          # */
/* # permitted provided that the following conditions are met:                                     # */
/* # permitted provided that the following conditions are met:                                     # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # 1. Redistributions of source code must retain the above copyright notice, this list of        # */
/* # 1. Redistributions of source code must retain the above copyright notice, this list of        # */
/* #    conditions and the following disclaimer.                                                   # */
/* #    conditions and the following disclaimer.                                                   # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     # */
/* # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     # */
/* #    conditions and the following disclaimer in the documentation and/or other materials        # */
/* #    conditions and the following disclaimer in the documentation and/or other materials        # */
/* #    provided with the distribution.                                                            # */
/* #    provided with the distribution.                                                            # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  # */
/* # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  # */
/* #    endorse or promote products derived from this software without specific prior written      # */
/* #    endorse or promote products derived from this software without specific prior written      # */
/* #    permission.                                                                                # */
/* #    permission.                                                                                # */
/* #                                                                                               # */
/* #                                                                                               # */
/* # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   # */
/* # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   # */
/* # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               # */
/* # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               # */
/* # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    # */
/* # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    # */
/* # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     # */
/* # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     # */
/* # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # */
/* # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # */
/* # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    # */
/* # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    # */
/* # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     # */
/* # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     # */
/* # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  # */
/* # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  # */
/* # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            # */
/* # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            # */
/* # ********************************************************************************************* # */
/* # ********************************************************************************************* # */
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting # */
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting # */
/* ################################################################################################# */
/* ################################################################################################# */
.file   "crt0.S"
.file   "crt0.S"
.section .text.boot
.section .text.boot
.balign 4
.balign 4
.global _start
.global _start
// IO region
// IO region
.equ IO_BEGIN, 0xFFFFFF00 // start of processor-internal IO region
.equ IO_BEGIN, 0xFFFFFF00 // start of processor-internal IO region
_start:
_start:
.cfi_startproc
.cfi_startproc
.cfi_undefined ra
.cfi_undefined ra
// *********************************************************
// *********************************************************
// Clear register file (lower half, assume E extension)
// Clear integer register file (lower half, assume E extension)
// *********************************************************
// *********************************************************
__crt0_reg_file_clear:
__crt0_reg_file_clear:
//addi  x0, x0, 0 // hardwired to zero
//addi  x0, x0, 0 // hardwired to zero
  addi  x1, x0, 0
  addi  x1, x0, 0
  addi  x2, x0, 0
  addi  x2, x0, 0
  addi  x3, x0, 0
  addi  x3, x0, 0
  addi  x4, x0, 0
  addi  x4, x0, 0
  addi  x5, x0, 0
  addi  x5, x0, 0
  addi  x6, x0, 0
  addi  x6, x0, 0
  addi  x7, x0, 0
  addi  x7, x0, 0
  addi  x8, x0, 0
  addi  x8, x0, 0
  addi  x9, x0, 0
  addi  x9, x0, 0
//addi x10, x0, 0
//addi x10, x0, 0
//addi x11, x0, 0
//addi x11, x0, 0
//addi x12, x0, 0
//addi x12, x0, 0
//addi x13, x0, 0
//addi x13, x0, 0
  addi x14, x0, 0
  addi x14, x0, 0
  addi x15, x0, 0
  addi x15, x0, 0
// *********************************************************
// *********************************************************
// Clear register file (upper half, if no E extension)
// Initialize dummy trap handler base address
 
// *********************************************************
 
__crt0_neorv32_trap_init:
 
  la    x11, __crt0_dummy_trap_handler
 
  csrw  mtvec, x11 // set address of first-level exception handler
 
 
 
 
 
// *********************************************************
 
// Clear integer register file (upper half, if no E extension)
// *********************************************************
// *********************************************************
#ifndef __riscv_32e
#ifndef __riscv_32e
// save some program space if compiling bootloader
// 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
  addi x20, x0, 0
  addi x20, x0, 0
  addi x21, x0, 0
  addi x21, x0, 0
  addi x22, x0, 0
  addi x22, x0, 0
  addi x23, x0, 0
  addi x23, x0, 0
  addi x24, x0, 0
  addi x24, x0, 0
  addi x25, x0, 0
  addi x25, x0, 0
  addi x26, x0, 0
  addi x26, x0, 0
  addi x27, x0, 0
  addi x27, x0, 0
  addi x28, x0, 0
  addi x28, x0, 0
  addi x29, x0, 0
  addi x29, x0, 0
  addi x30, x0, 0
  addi x30, x0, 0
  addi x31, x0, 0
  addi x31, x0, 0
#endif
#endif
#endif
#endif
// *********************************************************
// *********************************************************
 
// Clear floating-point register file (if F extension enabled)
 
// *********************************************************
 
#ifdef __riscv_flen
 
// DO NOT DO THIS if compiling bootloader (to save some program space)
 
#ifndef make_bootloader
 
  fmv.s.x f0,  x0
 
  fmv.s.x f1,  x0
 
  fmv.s.x f2,  x0
 
  fmv.s.x f3,  x0
 
  fmv.s.x f4,  x0
 
  fmv.s.x f5,  x0
 
  fmv.s.x f6,  x0
 
  fmv.s.x f7,  x0
 
  fmv.s.x f8,  x0
 
  fmv.s.x f9,  x0
 
  fmv.s.x f10, x0
 
  fmv.s.x f11, x0
 
  fmv.s.x f12, x0
 
  fmv.s.x f13, x0
 
  fmv.s.x f14, x0
 
  fmv.s.x f15, x0
 
  fmv.s.x f16, x0
 
  fmv.s.x f17, x0
 
  fmv.s.x f18, x0
 
  fmv.s.x f19, x0
 
  fmv.s.x f20, x0
 
  fmv.s.x f21, x0
 
  fmv.s.x f22, x0
 
  fmv.s.x f23, x0
 
  fmv.s.x f24, x0
 
  fmv.s.x f25, x0
 
  fmv.s.x f26, x0
 
  fmv.s.x f27, x0
 
  fmv.s.x f28, x0
 
  fmv.s.x f29, x0
 
  fmv.s.x f30, x0
 
  fmv.s.x f31, x0
 
#endif
 
#endif
 
 
 
 
 
// *********************************************************
// No interrupts, thanks
// No interrupts, thanks
// *********************************************************
// *********************************************************
__crt0_status_init:
__crt0_status_init:
  li x10, 0x00001800    // clear mstatus and set mpp(1:0)
  li x10, 0x00001800    // clear mstatus and set mpp(1:0)
  csrrw zero, mstatus, x10
  csrrw zero, mstatus, x10
  csrrw zero, mie, zero // clear mie
  csrrw zero, mie, zero // clear mie
// *********************************************************
// *********************************************************
// 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
  la    sp, __crt0_stack_begin
  andi  sp, sp, 0xfffffffc // make sure this is aligned
  andi  sp, sp, 0xfffffffc // make sure this is aligned
  addi  fp, sp, 0          // frame pointer = 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
 
 
 
 
// *********************************************************
 
// Initialize dummy trap handler base address
 
// *********************************************************
 
__crt0_neorv32_trap_init:
 
  la    x11, __crt0_dummy_trap_handler
 
  csrw  mtvec, x11 // set address of first-level exception handler
 
 
 
 
 
// *********************************************************
// *********************************************************
// 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 access fault
// which is captured but actually ignored due to the dummy handler.
// which is captured but actually ignored due to the dummy handler.
// *********************************************************
// *********************************************************
__crt0_reset_io:
__crt0_reset_io:
  li x11, IO_BEGIN // start of processor-internal IO region
  li x11, IO_BEGIN // start of processor-internal IO region
__crt0_reset_io_loop:
__crt0_reset_io_loop:
  sw   zero, 0(x11)
  sw   zero, 0(x11)
  addi x11, x11, 4
  addi x11, x11, 4
  bne  zero, x11, __crt0_reset_io_loop
  bne  zero, x11, __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:
  bge  x11, x12, __crt0_clear_bss_loop_end
  bge  x11, x12, __crt0_clear_bss_loop_end
  sb   zero, 0(x11)
  sb   zero, 0(x11)
  addi x11, x11, 1
  addi x11, x11, 1
  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
__crt0_copy_data_loop:
__crt0_copy_data_loop:
  bge  x12, x13,  __crt0_copy_data_loop_end
  bge  x12, x13,  __crt0_copy_data_loop_end
  lb   x14, 0(x11)
  lb   x14, 0(x11)
  sb   x14, 0(x12)
  sb   x14, 0(x12)
  addi x11, x11, 1
  addi x11, x11, 1
  addi x12, x12, 1
  addi x12, x12, 1
  j    __crt0_copy_data_loop
  j    __crt0_copy_data_loop
__crt0_copy_data_loop_end:
__crt0_copy_data_loop_end:
// *********************************************************
// *********************************************************
// Call main function
// Call main function
// *********************************************************
// *********************************************************
__crt0_main_entry:
__crt0_main_entry:
  // setup arguments for calling main
  // setup arguments for calling main
  addi x10, zero, 0 // argc = 0
  addi x10, zero, 0 // argc = 0
  addi x11, zero, 0 // argv = 0
  addi x11, zero, 0 // argv = 0
  // clear cycle and instruction counters
  // clear cycle and instruction counters
  csrw mcycle,    zero
  csrw mcycle,    zero
  csrw mcycleh,   zero
  csrw mcycleh,   zero
  csrw minstret,  zero
  csrw minstret,  zero
  csrw minstreth, zero
  csrw minstreth, zero
  // enable read-access from user-mode for cycle[h], time[h] and instret[h]
  // enable read-access from user-mode for cycle[h], time[h] and instret[h]
  csrwi 0x306, 7 // mcounteren
  csrwi 0x306, 7 // mcounteren
  // enable auto-increment of all counters
  // enable auto-increment of all counters
  csrw 0x320, x0 // mcountinhibit
  csrw 0x320, x0 // mcountinhibit
  // restore mcause reset value (so that 'main' knows we are coming from reset)
  // restore mcause reset value (so that 'main' knows we are coming from reset)
  li x12, 0x80000000
  li x12, 0x80000000
  csrw mcause, x12
  csrw mcause, x12
  // call actual app's main function
  // call actual app's main function
  jal ra, main
  jal ra, main
// *********************************************************
// *********************************************************
// Go to endless sleep mode if main returns
// Go to endless sleep mode if main returns
// *********************************************************
// *********************************************************
__crt0_this_is_the_end:
__crt0_this_is_the_end:
  csrrci zero, mstatus, 8 // mstatus: disable global IRQs (MIE)
  csrrci zero, mstatus, 8 // mstatus: disable global IRQs (MIE)
  nop
  nop
  wfi
  wfi
__crt0_this_is_the_end_my_friend:
__crt0_this_is_the_end_my_friend:
  j __crt0_this_is_the_end_my_friend // in case WFI is not available
  j __crt0_this_is_the_end_my_friend // in case WFI is not available
// *********************************************************
// *********************************************************
// dummy trap handler (for exceptions & IRQs)
// dummy trap handler (for exceptions & IRQs)
// tries to move on to next instruction
// tries to move on to next instruction
// *********************************************************
// *********************************************************
.global __crt0_dummy_trap_handler
.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)
  sw      x9, 4(sp)
  sw      x9, 4(sp)
  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?
// is compressed instruction?
__crt0_dummy_trap_handler_exc_c_check:
__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
// is uncompressed instruction
__crt0_dummy_trap_handler_exc_uncrompressed:
__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    x9, 0(sp)
  lw    x9, 0(sp)
  lw    x8, 4(sp)
  lw    x8, 4(sp)
  addi  sp, sp, +8
  addi  sp, sp, +8
  mret
  mret
.cfi_endproc
.cfi_endproc
.end
.end
 
 

powered by: WebSVN 2.1.0

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