[444] | 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 */ |
---|