123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- /*********************************************************************
- * SEGGER Microcontroller GmbH *
- * The Embedded Experts *
- **********************************************************************
- * *
- * (c) 2014 - 2021 SEGGER Microcontroller GmbH *
- * *
- * www.segger.com Support: support@segger.com *
- * *
- **********************************************************************
- * *
- * All rights reserved. *
- * *
- * Redistribution and use in source and binary forms, with or *
- * without modification, are permitted provided that the following *
- * condition is met: *
- * *
- * - Redistributions of source code must retain the above copyright *
- * notice, this condition and the following disclaimer. *
- * *
- * 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 *
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
- * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 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 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 OF THE POSSIBILITY OF SUCH *
- * DAMAGE. *
- * *
- **********************************************************************
- -------------------------- END-OF-HEADER -----------------------------
- File : SEGGER_RISCV_crt0.s
- Purpose : Generic runtime init startup code for RISC-V CPUs.
- Designed to work with the SEGGER linker to produce
- smallest possible executables.
- This file does not normally require any customization.
- Additional information:
- Preprocessor Definitions
- FULL_LIBRARY
- If defined then
- - argc, argv are set up by calling SEGGER_SEMIHOST_GetArgs().
- - the exit symbol is defined and executes on return from main.
- - the exit symbol calls destructors, atexit functions and then
- calls SEGGER_SEMIHOST_Exit().
- If not defined then
- - argc and argv are not valid (main is assumed to not take parameters)
- - the exit symbol is defined, executes on return from main and
- halts in a loop.
- */
- #include "hpm_csr_regs.h"
- /*********************************************************************
- *
- * Defines, configurable
- *
- **********************************************************************
- */
- #ifndef APP_ENTRY_POINT
- #define APP_ENTRY_POINT reset_handler
- #endif
- #ifndef ARGSSPACE
- #define ARGSSPACE 128
- #endif
- /*********************************************************************
- *
- * Macros
- *
- **********************************************************************
- */
- //
- // Declare a label as function symbol (without switching sections)
- //
- .macro MARK_FUNC Name
- .global \Name
- .type \Name, function
- \Name:
- .endm
- //
- // Declare a regular function.
- // Functions from the startup are placed in the init section.
- //
- .macro START_FUNC Name
- .section .init.\Name, "ax"
- .global \Name
- #if __riscv_compressed
- .balign 2
- #else
- .balign 4
- #endif
- .type \Name, function
- \Name:
- .endm
- //
- // Declare a weak function
- //
- .macro WEAK_FUNC Name
- .section .init.\Name, "ax", %progbits
- .global \Name
- .weak \Name
- #if __riscv_compressed
- .balign 2
- #else
- .balign 4
- #endif
- .type \Name, function
- \Name:
- .endm
- //
- // Mark the end of a function and calculate its size
- //
- .macro END_FUNC name
- .size \name,.-\name
- .endm
- /*********************************************************************
- *
- * Externals
- *
- **********************************************************************
- */
- .extern APP_ENTRY_POINT // typically main
- /*********************************************************************
- *
- * Global functions
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * _start
- *
- * Function description
- * Entry point for the startup code.
- * Usually called by the reset handler.
- * Performs all initialisation, based on the entries in the
- * linker-generated init table, then calls main().
- * It is device independent, so there should not be any need for an
- * end-user to modify it.
- *
- * Additional information
- * At this point, the stack pointer should already have been
- * initialized
- * - by hardware (such as on Cortex-M),
- * - by the device-specific reset handler,
- * - or by the debugger (such as for RAM Code).
- */
- #undef L
- #define L(label) .L_start_##label
- START_FUNC _start
- .option push
- .option norelax
- lui gp, %hi(__global_pointer$)
- addi gp, gp, %lo(__global_pointer$)
- lui tp, %hi(__thread_pointer$)
- addi tp, tp, %lo(__thread_pointer$)
- .option pop
- csrw mstatus, zero
- csrw mcause, zero
- #ifdef __riscv_flen
- /* Enable FPU */
- li t0, CSR_MSTATUS_FS_MASK
- csrrs t0, mstatus, t0
- /* Initialize FCSR */
- fscsr zero
- #endif
- #ifdef INIT_EXT_RAM_FOR_DATA
- la t0, _stack_safe
- mv sp, t0
- call _init_ext_ram
- #endif
- lui t0, %hi(__stack_end__)
- addi sp, t0, %lo(__stack_end__)
- #ifndef __NO_SYSTEM_INIT
- //
- // Call _init
- //
- call _init
- #endif
- //
- // Call linker init functions which in turn performs the following:
- // * Perform segment init
- // * Perform heap init (if used)
- // * Call constructors of global Objects (if any exist)
- //
- la s0, __SEGGER_init_table__ // Set table pointer to start of initialization table
- L(RunInit):
- lw a0, (s0) // Get next initialization function from table
- add s0, s0, 4 // Increment table pointer to point to function arguments
- jalr a0 // Call initialization function
- j L(RunInit)
- //
- MARK_FUNC __SEGGER_init_done
- //
- // Time to call main(), the application entry point.
- //
- #ifndef NO_CLEANUP_AT_START
- /* clean up */
- call _clean_up
- #endif
- #if defined(CONFIG_FREERTOS) && CONFIG_FREERTOS
- #define HANDLER_TRAP freertos_risc_v_trap_handler
- #define HANDLER_S_TRAP freertos_risc_v_trap_handler
- /* Use mscratch to store isr level */
- csrw mscratch, 0
- #elif defined(CONFIG_UCOS_III) && CONFIG_UCOS_III
- #define HANDLER_TRAP ucos_risc_v_trap_handler
- #define HANDLER_S_TRAP ucos_risc_v_trap_handler
- /* Use mscratch to store isr level */
- csrw mscratch, 0
- #elif defined(CONFIG_THREADX) && CONFIG_THREADX
- #define HANDLER_TRAP tx_risc_v_trap_handler
- #define HANDLER_S_TRAP tx_risc_v_trap_handler
- /* Use mscratch to store isr level */
- csrw mscratch, 0
- #else
- #define HANDLER_TRAP irq_handler_trap
- #define HANDLER_S_TRAP irq_handler_s_trap
- #endif
- #ifndef USE_NONVECTOR_MODE
- /* Initial machine trap-vector Base */
- la t0, __vector_table
- csrw mtvec, t0
- /* Enable vectored external PLIC interrupt */
- csrsi CSR_MMISC_CTL, 2
- #else
- /* Initial machine trap-vector Base */
- la t0, HANDLER_TRAP
- csrw mtvec, t0
- /* Disable vectored external PLIC interrupt */
- csrci CSR_MMISC_CTL, 2
- #endif
- MARK_FUNC start
- #ifndef FULL_LIBRARY
- //
- // In a real embedded application ("Free-standing environment"),
- // main() does not get any arguments,
- // which means it is not necessary to init a0 and a1.
- //
- call APP_ENTRY_POINT
- tail exit
- END_FUNC _start
- //
- // end of _start
- // Fall-through to exit if main ever returns.
- //
- MARK_FUNC exit
- //
- // In a free-standing environment, if returned from application:
- // Loop forever.
- //
- j .
- .size exit,.-exit
- #else
- //
- // In a hosted environment,
- // we need to load a0 and a1 with argc and argv, in order to handle
- // the command line arguments.
- // This is required for some programs running under control of a
- // debugger, such as automated tests.
- //
- li a0, ARGSSPACE
- la a1, args
- call debug_getargs
- li a0, ARGSSPACE
- la a1, args
- call APP_ENTRY_POINT // Call to application entry point (usually main())
- call exit // Call exit function
- j . // If we unexpectedly return from exit, hang.
- END_FUNC _start
- #endif
- #ifdef FULL_LIBRARY
- li a0, ARGSSPACE
- la a1, args
- call debug_getargs
- li a0, ARGSSPACE
- la a1, args
- #else
- li a0, 0
- li a1, 0
- #endif
- call APP_ENTRY_POINT
- tail exit
- END_FUNC _start
- //
- #ifdef FULL_LIBRARY
- /*********************************************************************
- *
- * exit
- *
- * Function description
- * Exit of the system.
- * Called on return from application entry point or explicit call
- * to exit.
- *
- * Additional information
- * In a hosted environment exit gracefully, by
- * saving the return value,
- * calling destructurs of global objects,
- * calling registered atexit functions,
- * and notifying the host/debugger.
- */
- #undef L
- #define L(label) .L_exit_##label
- WEAK_FUNC exit
- mv s1, a0 // Save the exit parameter/return result
- //
- // Call destructors
- //
- la s0, __dtors_start__
- L(Loop):
- la t0, __dtors_end__
- beq s0, t0, L(End)
- lw t1, 0(s0)
- addi s0, s0, 4
- jalr t1
- j L(Loop)
- L(End):
- //
- // Call atexit functions
- //
- call _execute_at_exit_fns
- //
- // Call debug_exit with return result/exit parameter
- //
- mv a0, s1
- call debug_exit
- //
- // If execution is not terminated, loop forever
- //
- L(ExitLoop):
- j L(ExitLoop) // Loop forever.
- END_FUNC exit
- #endif
- #ifdef FULL_LIBRARY
- .bss
- args:
- .space ARGSSPACE
- .size args, .-args
- .type args, %object
- #endif
- .section .isr_vector, "ax"
- .weak nmi_handler
- nmi_handler:
- 1: j 1b
- #include "../vectors.h"
- /*************************** End of file ****************************/
|