OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ColdFire_MCF52221_CodeWarrior/] [sources/] [startcf.c] - Blame information for rev 620

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 jeremybenn
/*
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.