summaryrefslogtreecommitdiff
path: root/startup.S
blob: 010b99a2d28fb1a831d28e17f83c94c685d6adda (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/******************************************************************************
* author: Freddie Chopin, http://www.freddiechopin.info/
* file: startup.S
* last change: 2012-01-08
*
* chip: ARMv6-M (Cortex-M0)
* compiler: arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
*
* description:
* ARMv6-M (Cortex-M0) assembly startup code
******************************************************************************/

/*
+=============================================================================+
| includes
+=============================================================================+
*/

#include "hdr/hdr_special_registers.h"

/*
+=============================================================================+
| ARMv6-M (Cortex-M0) startup code
+=============================================================================+
*/

.text
.balign 2
.syntax unified
.thumb
.thumb_func
.global Reset_Handler

Reset_Handler:

/*
+-----------------------------------------------------------------------------+
| Initialize the process stack pointer
+-----------------------------------------------------------------------------+
*/

	ldr		r0, =__process_stack_end
	msr		PSP, r0

/*
+-----------------------------------------------------------------------------+
| Thread mode uses process stack (PSP). Thread mode on ARMv6-M is privileged.
+-----------------------------------------------------------------------------+
*/

	movs	r0, #CONTROL_ALTERNATE_STACK
	msr		CONTROL, r0
	isb

/*
+-----------------------------------------------------------------------------+
| Branch to low_level_init_0() function (.data and .bss are not initialized!)
+-----------------------------------------------------------------------------+
*/

	ldr		r0, =low_level_init_0
	blx		r0

/*
+-----------------------------------------------------------------------------+
| Initialize .data section
+-----------------------------------------------------------------------------+
*/

	ldr		r1, =__data_init_start
    ldr		r2, =__data_start
    ldr		r3, =__data_end

	b		2f
1:	ldmia	r1!, {r0}
	stmia	r2!, {r0}
2:	cmp		r2, r3
	bne		1b

/*
+-----------------------------------------------------------------------------+
| Zero-init .bss section
+-----------------------------------------------------------------------------+
*/

	movs	r0, #0
	ldr		r1, =__bss_start
	ldr		r2, =__bss_end

	b		2f
1:	stmia	r1!, {r0}
2:	cmp		r1, r2
	bne		1b


/*
+-----------------------------------------------------------------------------+
| Call C++ constructors for global and static objects
+-----------------------------------------------------------------------------+
*/
#ifdef __USES_CXX
	ldr		r0, =__libc_init_array
	blx		r0
#endif

/*
+-----------------------------------------------------------------------------+
| Branch to low_level_init_1() function
+-----------------------------------------------------------------------------+
*/

	ldr		r0, =low_level_init_1
	blx		r0

/*
+-----------------------------------------------------------------------------+
| Branch to main() with link
+-----------------------------------------------------------------------------+
*/

	ldr		r0, =main
	blx		r0

/*
+-----------------------------------------------------------------------------+
| Call C++ destructors for global and static objects
+-----------------------------------------------------------------------------+
*/
#ifdef __USES_CXX
	ldr		r0, =__libc_fini_array
	blx		r0
#endif

/*
+-----------------------------------------------------------------------------+
| On return - loop till the end of the world
+-----------------------------------------------------------------------------+
*/

	b		.

/*
+=============================================================================+
| __default_low_level_init() - replacement for undefined low_level_init_0()
| and/or low_level_init_1(). This function just returns.
+=============================================================================+
*/

.text
.balign 2
.syntax unified
.thumb
.thumb_func
.global __default_low_level_init

__default_low_level_init:
	bx		lr

/*
+=============================================================================+
| assign undefined low_level_init_0() and/or low_level_init_1() to
| __default_low_level_init()
+=============================================================================+
*/

.weak	low_level_init_0
.global	low_level_init_0
.set	low_level_init_0, __default_low_level_init

.weak	low_level_init_1
.global	low_level_init_1
.set	low_level_init_1, __default_low_level_init

/******************************************************************************
* END OF FILE
******************************************************************************/