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] - Rev 606

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

/*
 *    CF_Startup.c - Default init/startup/termination routines for
 *                     Embedded Metrowerks C++
 *
 *    Copyright © 1993-1998 Metrowerks, Inc. All Rights Reserved.
 *    Copyright © 2005 Freescale semiConductor Inc. All Rights Reserved.
 *
 *
 *    THEORY OF OPERATION
 *
 *    This version of thestartup code is intended for linker relocated
 *    executables.  The startup code will assign the stack pointer to
 *    __SP_INIT, assign the address of the data relative base address
 *    to a5, initialize the .bss/.sbss sections to zero, call any
 *    static C++ initializers and then call main.  Upon returning from
 *    main it will call C++ destructors and call exit to terminate.
 */
 
#ifdef __cplusplus
#pragma cplusplus off
#endif
#pragma PID off
#pragma PIC off
 
#include "startcf.h"
#include "RuntimeConfig.h"
 
	/* imported data */
 
extern unsigned long far _SP_INIT, _SDA_BASE;
extern unsigned long far _START_BSS, _END_BSS;
extern unsigned long far _START_SBSS, _END_SBSS;
extern unsigned long far __DATA_RAM, __DATA_ROM, __DATA_END;
 
	/* imported routines */
 
extern void __call_static_initializers(void);
extern int main(int, char **);
extern void exit(int);
 
	/* exported routines */
 
extern void _ExitProcess(void);
extern asm void _startup(void);
extern void __initialize_hardware(void);
extern void __initialize_system(void);
 
 
/*
 *    Dummy routine for initializing hardware.  For user's custom systems, you
 *    can create your own routine of the same name that will perform HW
 *    initialization.  The linker will do the right thing to ignore this
 *    definition and use the version in your file.
 */
#pragma overload void __initialize_hardware(void);
void __initialize_hardware(void)
{
}
 
/*
 *    Dummy routine for initializing systems.  For user's custom systems,
 *    you can create your own routine of the same name that will perform
 *    initialization.  The linker will do the right thing to ignore this
 *    definition and use the version in your file.
 */
#pragma overload void __initialize_system(void);
void __initialize_system(void)
{
}
 
/*
 *    Dummy routine for initializing C++.  This routine will get overloaded by the C++ runtime.
 */
#pragma overload void __call_static_initializers(void);
void __call_static_initializers(void)
{
}
 
/*
 *	Routine to copy a single section from ROM to RAM ...
 */
static __declspec(register_abi) void __copy_rom_section(char* dst, const char* src, unsigned long size)
{
	if (dst != src)
		 while (size--)
		    *dst++ = *src++;
}
 
/*
 *	Routine that copies all sections the user marked as ROM into
 *	their target RAM addresses ...
 *
 *	__S_romp is automatically generated by the linker if it
 *	is referenced by the program.  It is a table of RomInfo
 *	structures.  The final entry in the table has all-zero
 *	fields.
 */
static void __copy_rom_sections_to_ram(void)
{
	RomInfo		*info;
 
	/*
	 *	Go through the entire table, copying sections from ROM to RAM.
	 */
	for (info = _S_romp; info->Source != 0L || info->Target != 0L || info->Size != 0; ++info)
    __copy_rom_section( (char *)info->Target,(char *)info->Source, info->Size);
 
}
 
/*
 *    Exit handler called from the exit routine, if your OS needs
 *    to do something special for exit handling just replace this
 *    routines with what the OS needs to do ...
 */
asm void _ExitProcess(void)
{
	illegal
	rts
}
 
/*
 *    Routine to clear out blocks of memory should give good
 *    performance regardless of 68k or ColdFire part.
 */
static __declspec(register_abi) void clear_mem(char *dst, unsigned long n)
{
	unsigned long i;
	long *lptr;
 
	if (n >= 32)
	{
		/* align start address to a 4 byte boundary */
		i = (- (unsigned long) dst) & 3;
 
		if (i)
		{
			n -= i;
			do
				*dst++ = 0;
			while (--i);
		}
 
		/* use an unrolled loop to zero out 32byte blocks */
		i = n >> 5;
		if (i)
		{
			lptr = (long *)dst;
			dst += i * 32;
			do
			{
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
				*lptr++ = 0;
			}
			while (--i);
		}
		i = (n & 31) >> 2;
 
		/* handle any 4 byte blocks left */
		if (i)
		{
			lptr = (long *)dst;
			dst += i * 4;
			do
				*lptr++ = 0;
			while (--i);
		}
		n &= 3;
	}
 
	/* handle any byte blocks left */
	if (n)
		do
			*dst++ = 0;
		while (--n);
}
 
/*
 *    Startup routine for embedded application ...
 */
 
asm void _startup(void)
{
	/* disable interrupts */
    move.w        #0x2700,sr
 
	/* Pre-init SP, in case memory for stack is not valid it should be setup using 
	   MEMORY_INIT before __initialize_hardware is called 
	*/
	lea __SP_AFTER_RESET,a7; 
 
    /* initialize memory */
    MEMORY_INIT
 
	/* initialize any hardware specific issues */
    jsr           __initialize_hardware   
 
	/* setup the stack pointer */
    lea           _SP_INIT,a7
 
	/* setup A6 dummy stackframe */
    movea.l       #0,a6
    link          a6,#0
 
	/* setup A5 */
    lea           _SDA_BASE,a5
 
 
	/* zero initialize the .bss section */
 
    lea           _END_BSS, a0
    lea           _START_BSS, a1
    suba.l        a1, a0
    move.l        a0, d0
 
    beq           __skip_bss__
 
    lea           _START_BSS, a0
 
    /* call clear_mem with base pointer in a0 and size in d0 */
    jsr           clear_mem
 
__skip_bss__:
 
	/* zero initialize the .sbss section */
 
    lea           _END_SBSS, a0
    lea           _START_SBSS, a1
    suba.l        a1, a0
    move.l        a0, d0
 
    beq           __skip_sbss__
 
    lea           _START_SBSS, a0
 
    /* call clear_mem with base pointer in a0 and size in d0 */
    jsr           clear_mem
 
__skip_sbss__:
 
	/* copy all ROM sections to their RAM locations ... */
#if SUPPORT_ROM_TO_RAM
 
	/*
	 * _S_romp is a null terminated array of
	 * typedef struct RomInfo {
     *      unsigned long	Source;
     *      unsigned long	Target;
     *      unsigned long 	Size;
     *  } RomInfo;
     *
     * Watch out if you're rebasing using _PICPID_DELTA
     */
 
    lea           _S_romp, a0
    move.l        a0, d0
    beq           __skip_rom_copy__            
    jsr           __copy_rom_sections_to_ram
 
#else
 
	/*
   * There's a single block to copy from ROM to RAM, perform
   * the copy directly without using the __S_romp structure
   */
 
    lea           __DATA_RAM, a0
    lea           __DATA_ROM, a1
 
    cmpa          a0,a1
    beq           __skip_rom_copy__
 
    move.l        #__DATA_END, d0
    sub.l         a0, d0
 
    jsr           __copy_rom_section
 
#endif
__skip_rom_copy__:
 
	/* call C++ static initializers (__sinit__(void)) */
	jsr			  __call_static_initializers
 
	jsr		  	  __initialize_system
 
	/* call main(int, char **) */
	pea			  __argv
	clr.l		  -(sp)				/* clearing a long is ok since it's caller cleanup */
	jsr			  main
	addq.l		#8, sp
 
	unlk		  a6
 
	/* now call exit(0) to terminate the application */
	clr.l		  -(sp)
	jsr			  exit
	addq.l		#4, sp
 
	/* should never reach here but just in case */
	illegal
	rts
 
	/* exit will never return */
__argv:
    dc.l          0
}
 
 

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

powered by: WebSVN 2.1.0

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