]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/freedom-metal/src/entry.S
Base project to replace existing Freedom Studio project using latest Freedom Studio...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_GCC / freedom-metal / src / entry.S
1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
3
4 /* This code executes before _start, which is contained inside the C library.
5  * In embedded systems we want to ensure that _enter, which contains the first
6  * code to be executed, can be loaded at a specific address.  To enable this
7  * feature we provide the '.text.metal.init.enter' section, which is
8  * defined to have the first address being where execution should start. */
9 .section .text.metal.init.enter
10 .global _enter
11
12 _enter:
13     .cfi_startproc
14
15     /* Inform the debugger that there is nowhere to backtrace past _enter. */
16     .cfi_undefined ra
17
18     /* The absolute first thing that must happen is configuring the global
19      * pointer register, which must be done with relaxation disabled because
20      * it's not valid to obtain the address of any symbol without GP
21      * configured.  The C environment might go ahead and do this again, but
22      * that's safe as it's a fixed register. */
23 .option push
24 .option norelax
25     la gp, __global_pointer$
26 .option pop
27
28     /* Set up a simple trap vector to catch anything that goes wrong early in
29      * the boot process. */
30     la t0, early_trap_vector
31     csrw mtvec, t0
32     /* enable chicken bit if core is bullet series*/
33     la t0, __metal_chicken_bit
34     beqz t0, 1f
35     csrwi 0x7C1, 0
36 1:
37
38     /* There may be pre-initialization routines inside the MBI code that run in
39      * C, so here we set up a C environment.  First we set up a stack pointer,
40      * which is left as a weak reference in order to allow initialization
41      * routines that do not need a stack to be set up to transparently be
42      * called. */
43     .weak __metal_stack_pointer
44     la sp, __metal_stack_pointer
45
46     /* Check for an initialization routine and call it if one exists, otherwise
47      * just skip over the call entirely.   Note that __metal_initialize isn't
48      * actually a full C function, as it doesn't end up with the .bss or .data
49      * segments having been initialized.  This is done to avoid putting a
50      * burden on systems that can be initialized without having a C environment
51      * set up. */
52     .weak __metal_before_start
53     la ra, __metal_before_start
54     beqz ra, 1f
55     jalr ra
56 1:
57
58     /* At this point we can enter the C runtime's startup file.  The arguments
59      * to this function are designed to match those provided to the SEE, just
60      * so we don't have to write another ABI. */
61     csrr a0, mhartid
62     li a1, 0
63     li a2, 0
64     call _start
65
66     /* If we've made it back here then there's probably something wrong.  We
67      * allow the METAL to register a handler here. */
68     .weak __metal_after_main
69     la ra, __metal_after_main
70     beqz ra, 1f
71     jalr ra
72 1:
73
74     /* If that handler returns then there's not a whole lot we can do.  Just
75      * try to make some noise. */
76      la t0, 1f
77      csrw mtvec, t0
78 1:
79      lw t1, 0(x0)
80      j 1b
81
82     .cfi_endproc
83
84 /* For sanity's sake we set up an early trap vector that just does nothing.  If
85  * you end up here then there's a bug in the early boot code somewhere. */
86 .section .text.metal.init.trapvec
87 .align 2
88 early_trap_vector:
89     .cfi_startproc
90     csrr t0, mcause
91     csrr t1, mepc
92     csrr t2, mtval
93     j early_trap_vector
94     .cfi_endproc
95
96 /* The GCC port might not emit a __register_frame_info symbol, which eventually
97  * results in a weak undefined reference that eventually causes crash when it
98  * is dereference early in boot.  We really shouldn't need to put this here,
99  * but to deal with what I think is probably a bug in the linker script I'm
100  * going to leave this in for now.  At least it's fairly cheap :) */
101 .weak __register_frame_info
102 .global __register_frame_info
103 .section .text.metal.init.__register_frame_info
104 __register_frame_info:
105     .cfi_startproc
106     ret
107     .cfi_endproc