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