2 * CF_Startup.c - Default init/startup/termination routines for
3 * Embedded Metrowerks C++
5 * Copyright © 1993-1998 Metrowerks, Inc. All Rights Reserved.
6 * Copyright © 2005 Freescale semiConductor Inc. All Rights Reserved.
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.
26 #include "RuntimeConfig.h"
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;
35 /* imported routines */
37 extern void __call_static_initializers(void);
38 extern int main(int, char **);
39 extern void exit(int);
41 /* exported routines */
43 extern void _ExitProcess(void);
44 extern asm void _startup(void);
45 extern void __initialize_hardware(void);
46 extern void __initialize_system(void);
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.
55 #pragma overload void __initialize_hardware(void);
56 void __initialize_hardware(void)
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.
66 #pragma overload void __initialize_system(void);
67 void __initialize_system(void)
72 * Dummy routine for initializing C++. This routine will get overloaded by the C++ runtime.
74 #pragma overload void __call_static_initializers(void);
75 void __call_static_initializers(void)
80 * Routine to copy a single section from ROM to RAM ...
82 static __declspec(register_abi) void __copy_rom_section(char* dst, const char* src, unsigned long size)
90 * Routine that copies all sections the user marked as ROM into
91 * their target RAM addresses ...
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
98 static void __copy_rom_sections_to_ram(void)
103 * Go through the entire table, copying sections from ROM to RAM.
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);
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 ...
115 asm void _ExitProcess(void)
122 * Routine to clear out blocks of memory should give good
123 * performance regardless of 68k or ColdFire part.
125 static __declspec(register_abi) void clear_mem(char *dst, unsigned long n)
132 /* align start address to a 4 byte boundary */
133 i = (- (unsigned long) dst) & 3;
143 /* use an unrolled loop to zero out 32byte blocks */
164 /* handle any 4 byte blocks left */
176 /* handle any byte blocks left */
184 * Startup routine for embedded application ...
187 asm void _startup(void)
189 /* disable interrupts */
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
195 lea __SP_AFTER_RESET,a7;
197 /* initialize memory */
200 /* initialize any hardware specific issues */
201 jsr __initialize_hardware
203 /* setup the stack pointer */
206 /* setup A6 dummy stackframe */
214 /* zero initialize the .bss section */
225 /* call clear_mem with base pointer in a0 and size in d0 */
230 /* zero initialize the .sbss section */
241 /* call clear_mem with base pointer in a0 and size in d0 */
246 /* copy all ROM sections to their RAM locations ... */
247 #if SUPPORT_ROM_TO_RAM
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;
257 * Watch out if you're rebasing using _PICPID_DELTA
262 beq __skip_rom_copy__
263 jsr __copy_rom_sections_to_ram
268 * There's a single block to copy from ROM to RAM, perform
269 * the copy directly without using the __S_romp structure
276 beq __skip_rom_copy__
278 move.l #__DATA_END, d0
281 jsr __copy_rom_section
286 /* call C++ static initializers (__sinit__(void)) */
287 jsr __call_static_initializers
289 jsr __initialize_system
291 /* call main(int, char **) */
293 clr.l -(sp) /* clearing a long is ok since it's caller cleanup */
299 /* now call exit(0) to terminate the application */
304 /* should never reach here but just in case */
308 /* exit will never return */