]> begriffs open source - cmsis-freertos/blob - Demo/ColdFire_MCF52221_CodeWarrior/sources/startcf.c
Update cmsis_os2.c
[cmsis-freertos] / Demo / ColdFire_MCF52221_CodeWarrior / sources / startcf.c
1 /*
2  *    CF_Startup.c - Default init/startup/termination routines for
3  *                     Embedded Metrowerks C++
4  *
5  *    Copyright © 1993-1998 Metrowerks, Inc. All Rights Reserved.
6  *    Copyright © 2005 Freescale semiConductor Inc. All Rights Reserved.
7  *
8  *
9  *    THEORY OF OPERATION
10  *
11  *    This version of thestartup code is intended for linker relocated
12  *    executables.  The startup code will assign the stack pointer to
13  *    __SP_INIT, assign the address of the data relative base address
14  *    to a5, initialize the .bss/.sbss sections to zero, call any
15  *    static C++ initializers and then call main.  Upon returning from
16  *    main it will call C++ destructors and call exit to terminate.
17  */
18
19 #ifdef __cplusplus
20 #pragma cplusplus off
21 #endif
22 #pragma PID off
23 #pragma PIC off
24
25 #include "startcf.h"
26 #include "RuntimeConfig.h"
27
28         /* imported data */
29
30 extern unsigned long far _SP_INIT, _SDA_BASE;
31 extern unsigned long far _START_BSS, _END_BSS;
32 extern unsigned long far _START_SBSS, _END_SBSS;
33 extern unsigned long far __DATA_RAM, __DATA_ROM, __DATA_END;
34
35         /* imported routines */
36
37 extern void __call_static_initializers(void);
38 extern int main(int, char **);
39 extern void exit(int);
40
41         /* exported routines */
42
43 extern void _ExitProcess(void);
44 extern asm void _startup(void);
45 extern void __initialize_hardware(void);
46 extern void __initialize_system(void);
47
48
49 /*
50  *    Dummy routine for initializing hardware.  For user's custom systems, you
51  *    can create your own routine of the same name that will perform HW
52  *    initialization.  The linker will do the right thing to ignore this
53  *    definition and use the version in your file.
54  */
55 #pragma overload void __initialize_hardware(void);
56 void __initialize_hardware(void)
57 {
58 }
59
60 /*
61  *    Dummy routine for initializing systems.  For user's custom systems,
62  *    you can create your own routine of the same name that will perform
63  *    initialization.  The linker will do the right thing to ignore this
64  *    definition and use the version in your file.
65  */
66 #pragma overload void __initialize_system(void);
67 void __initialize_system(void)
68 {
69 }
70
71 /*
72  *    Dummy routine for initializing C++.  This routine will get overloaded by the C++ runtime.
73  */
74 #pragma overload void __call_static_initializers(void);
75 void __call_static_initializers(void)
76 {
77 }
78
79 /*
80  *      Routine to copy a single section from ROM to RAM ...
81  */
82 static __declspec(register_abi) void __copy_rom_section(char* dst, const char* src, unsigned long size)
83 {
84         if (dst != src)
85                  while (size--)
86                     *dst++ = *src++;
87 }
88
89 /*
90  *      Routine that copies all sections the user marked as ROM into
91  *      their target RAM addresses ...
92  *
93  *      __S_romp is automatically generated by the linker if it
94  *      is referenced by the program.  It is a table of RomInfo
95  *      structures.  The final entry in the table has all-zero
96  *      fields.
97  */
98 static void __copy_rom_sections_to_ram(void)
99 {
100         RomInfo         *info;
101
102         /*
103          *      Go through the entire table, copying sections from ROM to RAM.
104          */
105         for (info = _S_romp; info->Source != 0L || info->Target != 0L || info->Size != 0; ++info)
106     __copy_rom_section( (char *)info->Target,(char *)info->Source, info->Size);
107                                                         
108 }
109
110 /*
111  *    Exit handler called from the exit routine, if your OS needs
112  *    to do something special for exit handling just replace this
113  *    routines with what the OS needs to do ...
114  */
115 asm void _ExitProcess(void)
116 {
117         illegal
118         rts
119 }
120
121 /*
122  *    Routine to clear out blocks of memory should give good
123  *    performance regardless of 68k or ColdFire part.
124  */
125 static __declspec(register_abi) void clear_mem(char *dst, unsigned long n)
126 {
127         unsigned long i;
128         long *lptr;
129
130         if (n >= 32)
131         {
132                 /* align start address to a 4 byte boundary */
133                 i = (- (unsigned long) dst) & 3;
134
135                 if (i)
136                 {
137                         n -= i;
138                         do
139                                 *dst++ = 0;
140                         while (--i);
141                 }
142
143                 /* use an unrolled loop to zero out 32byte blocks */
144                 i = n >> 5;
145                 if (i)
146                 {
147                         lptr = (long *)dst;
148                         dst += i * 32;
149                         do
150                         {
151                                 *lptr++ = 0;
152                                 *lptr++ = 0;
153                                 *lptr++ = 0;
154                                 *lptr++ = 0;
155                                 *lptr++ = 0;
156                                 *lptr++ = 0;
157                                 *lptr++ = 0;
158                                 *lptr++ = 0;
159                         }
160                         while (--i);
161                 }
162                 i = (n & 31) >> 2;
163
164                 /* handle any 4 byte blocks left */
165                 if (i)
166                 {
167                         lptr = (long *)dst;
168                         dst += i * 4;
169                         do
170                                 *lptr++ = 0;
171                         while (--i);
172                 }
173                 n &= 3;
174         }
175
176         /* handle any byte blocks left */
177         if (n)
178                 do
179                         *dst++ = 0;
180                 while (--n);
181 }
182
183 /*
184  *    Startup routine for embedded application ...
185  */
186
187 asm void _startup(void)
188 {
189         /* disable interrupts */
190     move.w        #0x2700,sr
191     
192         /* Pre-init SP, in case memory for stack is not valid it should be setup using 
193            MEMORY_INIT before __initialize_hardware is called 
194         */
195         lea __SP_AFTER_RESET,a7; 
196
197     /* initialize memory */
198     MEMORY_INIT
199
200         /* initialize any hardware specific issues */
201     jsr           __initialize_hardware   
202   
203         /* setup the stack pointer */
204     lea           _SP_INIT,a7
205
206         /* setup A6 dummy stackframe */
207     movea.l       #0,a6
208     link          a6,#0
209
210         /* setup A5 */
211     lea           _SDA_BASE,a5
212
213
214         /* zero initialize the .bss section */
215
216     lea           _END_BSS, a0
217     lea           _START_BSS, a1
218     suba.l        a1, a0
219     move.l        a0, d0
220
221     beq           __skip_bss__
222
223     lea           _START_BSS, a0
224
225     /* call clear_mem with base pointer in a0 and size in d0 */
226     jsr           clear_mem
227
228 __skip_bss__:
229
230         /* zero initialize the .sbss section */
231
232     lea           _END_SBSS, a0
233     lea           _START_SBSS, a1
234     suba.l        a1, a0
235     move.l        a0, d0
236
237     beq           __skip_sbss__
238
239     lea           _START_SBSS, a0
240
241     /* call clear_mem with base pointer in a0 and size in d0 */
242     jsr           clear_mem
243
244 __skip_sbss__:
245
246         /* copy all ROM sections to their RAM locations ... */
247 #if SUPPORT_ROM_TO_RAM
248
249         /*
250          * _S_romp is a null terminated array of
251          * typedef struct RomInfo {
252      *      unsigned long       Source;
253      *      unsigned long       Target;
254      *      unsigned long       Size;
255      *  } RomInfo;
256      *
257      * Watch out if you're rebasing using _PICPID_DELTA
258      */
259
260     lea           _S_romp, a0
261     move.l        a0, d0
262     beq           __skip_rom_copy__            
263     jsr           __copy_rom_sections_to_ram
264
265 #else
266
267         /*
268    * There's a single block to copy from ROM to RAM, perform
269    * the copy directly without using the __S_romp structure
270    */
271
272     lea           __DATA_RAM, a0
273     lea           __DATA_ROM, a1
274     
275     cmpa          a0,a1
276     beq           __skip_rom_copy__
277               
278     move.l        #__DATA_END, d0
279     sub.l         a0, d0
280                   
281     jsr           __copy_rom_section
282
283 #endif
284 __skip_rom_copy__:
285         
286         /* call C++ static initializers (__sinit__(void)) */
287         jsr                       __call_static_initializers
288
289         jsr                       __initialize_system
290
291         /* call main(int, char **) */
292         pea                       __argv
293         clr.l             -(sp)                         /* clearing a long is ok since it's caller cleanup */
294         jsr                       main
295         addq.l          #8, sp
296         
297         unlk              a6
298         
299         /* now call exit(0) to terminate the application */
300         clr.l             -(sp)
301         jsr                       exit
302         addq.l          #4, sp
303
304         /* should never reach here but just in case */
305         illegal
306         rts
307
308         /* exit will never return */
309 __argv:
310     dc.l          0
311 }
312