-
Notifications
You must be signed in to change notification settings - Fork 0
/
startup.cpp
126 lines (101 loc) · 3.5 KB
/
startup.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**************************************************************************************
* INCLUDE
**************************************************************************************/
#include <stdint.h>
#include <algorithm>
/**************************************************************************************
* TYPEDEFS
**************************************************************************************/
typedef void(*FuncType)(void);
/**************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************/
/* These external variables are defined by the linker script and define various
* sections which need to be preset with a certain value or (bss sections needs
* to be zeroed, data section needs to be initialized with data stored in flash,
* ctors of static global objects need to be called, ...)
*/
extern uintptr_t __bss_start;
extern uintptr_t __bss_end;
extern uintptr_t __data_src_start;
extern uintptr_t __data_dst_start;
extern uintptr_t __data_dst_end;
extern FuncType __preinit_array_start[];
extern FuncType __preinit_array_end [];
extern FuncType __init_array_start [];
extern FuncType __init_array_end [];
extern FuncType __fini_array_start [];
extern FuncType __fini_array_end [];
/**************************************************************************************
* FUNCTION PROTOTYPES
**************************************************************************************/
extern "C" void __start(void) __attribute__ ((noreturn)) __attribute__ ((section (".text.startup")));
void init_bss ();
void init_data ();
void preinit_array();
void init_array ();
void fini_array ();
/**************************************************************************************
* FUNCTION IMPLEMENTATION
**************************************************************************************/
extern "C" void __start(void)
{
/* Load global pointer */
asm volatile("la gp, __global_pointer$");
/* Initialize stack pointer */
asm volatile("la sp, __stack_end");
asm volatile("andi sp, sp, -16");
/* Clear the BSS segment */
init_bss();
/* Perform the ROM-to-RAM initialisation */
init_data();
/* Perform preinit/init steps - call static ctors */
preinit_array();
init_array();
/* Jump to main */
asm volatile("call main");
/* In case we should return from main perform deinitialisation - calling static dtors */
fini_array();
/* Loop forever and don't return */
for(;;) { }
}
void init_bss()
{
std::fill(&__bss_start, &__bss_end, 0U);
}
void init_data()
{
/* Calculate the size of the data section */
std::size_t const cnt = (&__data_dst_end - &__data_dst_start);
/* Copy the data initialisation code from flash to RAM */
std::copy(&__data_src_start,
&__data_src_start + cnt,
&__data_dst_start);
}
void preinit_array()
{
std::for_each(__preinit_array_start,
__preinit_array_end,
[](FuncType const func)
{
func();
});
}
void init_array()
{
std::for_each(__init_array_start,
__init_array_end,
[](FuncType const func)
{
func();
});
}
void fini_array()
{
std::for_each(__fini_array_start,
__fini_array_end,
[](FuncType const func)
{
func();
});
}