1 | /* Copyright (c) 2012-2015 Red Hat, Inc. All rights reserved. |
---|
2 | |
---|
3 | This copyrighted material is made available to anyone wishing to use, modify, |
---|
4 | copy, or redistribute it subject to the terms and conditions of the BSD |
---|
5 | License. This program is distributed in the hope that it will be useful, |
---|
6 | but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties |
---|
7 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license |
---|
8 | is available at http://www.opensource.org/licenses. Any Red Hat trademarks that |
---|
9 | are incorporated in the source code or documentation are not subject to the BSD |
---|
10 | License and may only be used or replicated with the express permission of |
---|
11 | Red Hat, Inc. |
---|
12 | */ |
---|
13 | |
---|
14 | #include "memmodel.h" |
---|
15 | |
---|
16 | ;; The linker links all .crt_* sections in asciibetical order at the |
---|
17 | ;; same place. So, the four digits in .crt_NNNN_xxx name created by |
---|
18 | ;; the START_CRT_FUNC macro determine the link order, so, keep them |
---|
19 | ;; in sequential order here. The first two digits are set here, the |
---|
20 | ;; second two allow users to insert code between code fragments here. |
---|
21 | |
---|
22 | #if L0 |
---|
23 | .section ".resetvec", "a" |
---|
24 | __msp430_resetvec_hook: |
---|
25 | .word __crt0_start |
---|
26 | |
---|
27 | ;; Here we provide weak definitions of the symbols used in the |
---|
28 | ;; init_highbss and move_highdata blocks, in case they are not |
---|
29 | ;; provided by the linker script. They are defined here because |
---|
30 | ;; this block is always included in every executable, and because |
---|
31 | ;; if there were defined in the blocks that need them their values |
---|
32 | ;; would be used without giving the linker script a chance to |
---|
33 | ;; override them. |
---|
34 | ;; |
---|
35 | ;; The weak definitions are needed if the user targets an MCU |
---|
36 | ;; without high memory - and hence uses a linker script without |
---|
37 | ;; a definition of the .upper.bss or .upper.data sections - and |
---|
38 | ;; they have compiled their code with the -mdata-region=either |
---|
39 | ;; command line option. That option causes the assembler to |
---|
40 | ;; define the __crt0_move_highdata and/or crt0_init_highbss |
---|
41 | ;; symbols, which in turn forces the inclusion of the |
---|
42 | ;; move_highdata and/or init_highbss blocks in the startup code, |
---|
43 | ;; regardless of the fact that the sections are not present in |
---|
44 | ;; the linker script. |
---|
45 | |
---|
46 | WEAK_DEF __upper_data_init |
---|
47 | WEAK_DEF __rom_highdatacopysize |
---|
48 | WEAK_DEF __high_datastart |
---|
49 | WEAK_DEF __rom_highdatastart |
---|
50 | WEAK_DEF __high_bssstart |
---|
51 | WEAK_DEF __high_bsssize |
---|
52 | |
---|
53 | START_CRT_FUNC 0000 start |
---|
54 | .refsym __msp430_resetvec_hook |
---|
55 | #ifdef MINRT |
---|
56 | .refsym __crt0_call_just_main |
---|
57 | #else |
---|
58 | .refsym __crt0_call_init_then_main |
---|
59 | #endif |
---|
60 | mov_ #__stack, R1 |
---|
61 | |
---|
62 | END_CRT_FUNC start |
---|
63 | #endif |
---|
64 | |
---|
65 | |
---|
66 | #if Lbss |
---|
67 | ;; Note - this section is only included in the startup code of the |
---|
68 | ;; application if it is needed. It is responsible for initializing |
---|
69 | ;; the contents of the .bss section. |
---|
70 | |
---|
71 | START_CRT_FUNC 0100 init_bss |
---|
72 | |
---|
73 | mov_ #__bssstart, R12 |
---|
74 | clr.w R13 |
---|
75 | mov_ #__bsssize, R14 |
---|
76 | #ifdef __MSP430X_LARGE__ |
---|
77 | clr.w R15 ; We assume that __bsssize is never > 64K |
---|
78 | #endif |
---|
79 | call_ #memset |
---|
80 | |
---|
81 | END_CRT_FUNC init_bss |
---|
82 | #endif /* Lbss */ |
---|
83 | |
---|
84 | |
---|
85 | #ifdef __MSP430X_LARGE__ |
---|
86 | #if Lhigh_bss |
---|
87 | ;; Note - this section is only included in the startup code of the |
---|
88 | ;; application if it is needed. It is responsible for initializing |
---|
89 | ;; the contents of the .upper.bss section. |
---|
90 | |
---|
91 | START_CRT_FUNC 0200 init_highbss |
---|
92 | |
---|
93 | mov_ #__high_bssstart, R12 |
---|
94 | mov.w #0, R13 |
---|
95 | mov_ #__high_bsssize, R14 |
---|
96 | ;; If __high_bsssize is zero then skip the call to memset. |
---|
97 | ;; This can happen if all of the bss data was placed into .either.bss. |
---|
98 | cmp.w #0, R14 |
---|
99 | jeq 1f |
---|
100 | call_ #memset |
---|
101 | 1: |
---|
102 | END_CRT_FUNC init_highbss |
---|
103 | #endif /* Lhigh_bss */ |
---|
104 | #endif /* __MSP430X_LARGE__ */ |
---|
105 | |
---|
106 | |
---|
107 | #if Lmovedata |
---|
108 | ;; Note - this section is only included in the startup code of the |
---|
109 | ;; application if it is needed. It is responsible for copying the |
---|
110 | ;; contents of the .data section from its load address (in ROM) to |
---|
111 | ;; its run-time address (in RAM). |
---|
112 | |
---|
113 | START_CRT_FUNC 0300 movedata |
---|
114 | |
---|
115 | mov_ #__datastart, R12 |
---|
116 | mov_ #__romdatastart, R13 |
---|
117 | |
---|
118 | ;; memmove and memcpy do not currently work when src == dst |
---|
119 | cmp_ R12, R13 |
---|
120 | jeq 1f |
---|
121 | |
---|
122 | mov_ #__romdatacopysize, R14 |
---|
123 | |
---|
124 | call_ #memmove |
---|
125 | 1: |
---|
126 | END_CRT_FUNC movedata |
---|
127 | #endif /* Lmovedata */ |
---|
128 | |
---|
129 | |
---|
130 | #ifdef __MSP430X_LARGE__ |
---|
131 | #if Lmove_highdata |
---|
132 | ;; Note - this section is only included in the startup code of the application |
---|
133 | ;; if it is needed. It is responsible either for making sure that the |
---|
134 | ;; contents of the .upper.data section have their correct startup values. |
---|
135 | ;; If a copy of the .upper.data section is stored in ROM then this means |
---|
136 | ;; copying the contents into HIFRAM. If a copy of .upper.data is stored in a |
---|
137 | ;; shadow section in HIFRAM then this means copying from the shadow section |
---|
138 | ;; into the real section. |
---|
139 | |
---|
140 | START_CRT_FUNC 0400 move_highdata |
---|
141 | ;; __rom_highdatacopysize may be zero. Test this first because |
---|
142 | ;; its value may come from the weak definitions above and we do |
---|
143 | ;; not want to access the memory at address 0 pointed to by the |
---|
144 | ;; weak definition of __upper_data_init. |
---|
145 | mov.w #__rom_highdatacopysize, R14 |
---|
146 | cmp.w #0, R14 |
---|
147 | jeq 3f |
---|
148 | |
---|
149 | /* Test our status word. */ |
---|
150 | cmpx.w #0, &__upper_data_init |
---|
151 | jeq 1f |
---|
152 | /* Status word is non-zero - copy from shadow into upper. */ |
---|
153 | mov_ #__high_datastart, R12 |
---|
154 | mov_ #__rom_highdatastart, R13 |
---|
155 | jmp 2f |
---|
156 | |
---|
157 | 1: /* Status word is zero. Copy from upper to shadow and change status word. */ |
---|
158 | movx.w #1, &__upper_data_init |
---|
159 | mov_ #__rom_highdatastart, R12 |
---|
160 | mov_ #__high_datastart, R13 |
---|
161 | |
---|
162 | 2: ;; __rom_highdatacopysize may be zero. memmove should cope. |
---|
163 | mov.w #__rom_highdatacopysize, R14 |
---|
164 | |
---|
165 | call_ #memmove |
---|
166 | 3: |
---|
167 | END_CRT_FUNC move_highdata |
---|
168 | #endif /* Lmove_highdata */ |
---|
169 | #endif /* __MSP430X_LARGE__ */ |
---|
170 | |
---|
171 | |
---|
172 | #if Lmain_minrt |
---|
173 | ;; Note - this section is only included in the startup code of the |
---|
174 | ;; application if it is needed. It is responsible for just calling |
---|
175 | ;; main. No initialization code is called first, and main is not |
---|
176 | ;; expected to return. |
---|
177 | |
---|
178 | START_CRT_FUNC 0600 call_just_main |
---|
179 | |
---|
180 | clr.w R12 ; Set argc == 0 |
---|
181 | call_ #main |
---|
182 | END_CRT_FUNC call_just_main |
---|
183 | #endif /* Lmain_minrt */ |
---|
184 | |
---|
185 | |
---|
186 | #if Lmain |
---|
187 | ;; Note - this section is only included in the startup code of the |
---|
188 | ;; application if it is needed. It is responsible for calling the |
---|
189 | ;; initialization code - constructors, etc - and then main. If main |
---|
190 | ;; returns then the following section should be present to catch it. |
---|
191 | |
---|
192 | START_CRT_FUNC 0700 call_init_then_main |
---|
193 | |
---|
194 | call_ #__msp430_init |
---|
195 | |
---|
196 | clr.w R12 ; Set argc == 0 |
---|
197 | call_ #main |
---|
198 | |
---|
199 | END_CRT_FUNC call_init_then_main |
---|
200 | #endif /* Lmain */ |
---|
201 | |
---|
202 | |
---|
203 | #if Lcallexit |
---|
204 | ;; Note - this section is only included in the startup code of the |
---|
205 | ;; application if it is needed. It is responsible for calling exit |
---|
206 | ;; once main has finished. |
---|
207 | |
---|
208 | START_CRT_FUNC 0800 call_exit |
---|
209 | |
---|
210 | call_ #_exit |
---|
211 | |
---|
212 | END_CRT_FUNC call_exit |
---|
213 | #endif /* Lcallexit */ |
---|
214 | |
---|
215 | ;---------------------------------------- |
---|
216 | |
---|
217 | #ifndef MINRT |
---|
218 | #if L0 |
---|
219 | .section ".crt_0900main_init", "ax", @progbits |
---|
220 | .global _msp430_run_init_array |
---|
221 | .type _msp430_run_init_array,@function |
---|
222 | _msp430_run_init_array: |
---|
223 | mov_ #__init_array_start, R4 |
---|
224 | mov_ #__init_array_end, R5 |
---|
225 | mov_ #PTRsz, R6 |
---|
226 | br_ #_msp430_run_array |
---|
227 | |
---|
228 | .global _msp430_run_preinit_array |
---|
229 | .type _msp430_run_preinit_array,@function |
---|
230 | _msp430_run_preinit_array: |
---|
231 | mov_ #__preinit_array_start, R4 |
---|
232 | mov_ #__preinit_array_end, R5 |
---|
233 | mov_ #PTRsz, R6 |
---|
234 | br_ #_msp430_run_array |
---|
235 | |
---|
236 | .global _msp430_run_fini_array |
---|
237 | .type _msp430_run_fini_array,@function |
---|
238 | _msp430_run_fini_array: |
---|
239 | mov_ #__fini_array_start, R4 |
---|
240 | mov_ #__fini_array_end, R5 |
---|
241 | mov_ #-PTRsz, R6 |
---|
242 | br_ #_msp430_run_array |
---|
243 | |
---|
244 | _msp430_run_array: |
---|
245 | cmp_ R4, R5 |
---|
246 | jeq _msp430_run_done |
---|
247 | mov_ @R4, R7 |
---|
248 | add_ R6, R4 |
---|
249 | call_ @R7 |
---|
250 | br_ _msp430_run_array |
---|
251 | |
---|
252 | _msp430_run_done: |
---|
253 | ret_ |
---|
254 | |
---|
255 | ;---------------------------------------- |
---|
256 | |
---|
257 | .section .init,"ax" |
---|
258 | |
---|
259 | .global __msp430_init |
---|
260 | __msp430_init: |
---|
261 | |
---|
262 | .section .fini,"ax" |
---|
263 | |
---|
264 | .global __msp430_fini |
---|
265 | __msp430_fini: |
---|
266 | call_ #_msp430_run_fini_array |
---|
267 | |
---|
268 | #endif |
---|
269 | #endif /* not MINRT */ |
---|