⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 __ppc_eabi_init.c

📁 mpc55**系列芯片的例程 包括SCI,SPI,TIMER,FIT,EDMA等几乎所有功能的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************/
/*

FILE
	__ppc_eabi_init.c
	$Date: 2007/04/16 18:22:39 $
	$Revision: 1.11 $
	
DESCRIPTION

	Use this file for C or C++.  Contains calls to initialize memory pools
	for use with malloc/free, exceptions and static initializers.  If your
	project does not use exceptions, then the initialization code for them 
	is stripped out.  If they are used, the linker will add them 
	automatically.  A C-only program will be a little smaller (160 bytes) 
	with __ppc_eabi_init.c.

	Interface for board-level initialization and user-level initialization.
	
	If hardware initialization and pre-main user initialization are required,
	copy this file to your project directory and customize it (instead of
	customizing __start.c).
	
	Note that __init_hardware should not write on the stack until the
	memory controller is properly configured.

	
	void __init_hardware(void)
	
		Initialize the hardware, including the memory controller.
	
	void __init_user(void)
	
		Allow the user to perform initialization before calling main().
	
	void __init_cpp(void)
	
		CodeWarrior C++ initialization before calling main().  Calls
		constructors of which the cpp exception handling initialization
		is the first constructor, if exceptions are used.
	
	void __fini_cpp(void)
	
		Calls destructors.
	
	void _ExitProcess(void)
 		
 		This function simply stalls the debugger.  You may want to rewrite this
 		function if you are using an OS.
	
 	abort and exit
 
 	In order to correctly implement the required startup/termination sequence for
 	C and C++ programs, we need to have an exit() routine that can be called by
 	the program startup code. The exit() routine is supposed to
 
 		(1)	call any functions registered via atexit()
 		(2) call destructors for any global objects
 		(3)	flush any unwritten buffers, close any open files, etc.
 		(4) terminates the program
 
 	We don't, however, want to require the ANSI C library for every CodeWarrior
 	program, since it drags in lots of code that may not be needed.
 
 	Instead we provide a dummy exit() function which simply calls the destructors
 	and terminates the program. We assume that any program which uses atexit()
 	or <stdio.h> and which requires those cleanup behaviors will have linked with
 	the ANSI C library, whose definition of exit() will override the one here.
 
 	We similarly define a dummy abort() function (which is called by the default
 	terminate() handler).
 
 	Programs which rely on the proper ANSI C/C++ behavior must use the ANSI C
 	library, and order it in the CodeWarrior project or command-line so that
 	its definitions supersede these definitions in the runtime support library.

COPYRIGHT	
	(c) 2002-2006 Freescale Semiconductor, Inc.
	All rights reserved.

HISTORY
	97 APR 17 LLY	Created.
	97 JUN 24 MEA	Added support for C++ and malloc memory heaps.
	97 JUN 26 MEA	Made C and C++ versions of this file.  Added abort and exit.
	97 JUL 17 SCM	Customized for MPC821 ADS board.
	97 JUL 20 MEA	Changed __exit to _ExitProcess so as not to conflict with MSL.
					_ExitProcess added to this file; removed form __start.c.
	99 JAN 22 MEA	Removed exception handing to __init_cpp_exceptions.c for use
					with 2.2.2 compiler (post Release 4).  Put prototypes for
					exit and abort within extern "C" to avoid name-mangling.

*/
/***************************************************************************/

#pragma exceptions off
#pragma ANSI_strict off
#pragma only_std_keywords off

#define ALLOC_ADDITIONAL_HEAPS 0

#include <__ppc_eabi_init.h>
#include <__ppc_eabi_linker.h>		/* linker-generated symbol declarations */
#if ALLOC_ADDITIONAL_HEAPS
#include <pool_alloc.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

static void __init_cpp(void);
static void __fini_cpp(void);
typedef void (*voidfunctionptr) (void);	/* ptr to function returning void */
__declspec(section ".init") extern voidfunctionptr _ctors[];
__declspec(section ".init") extern voidfunctionptr _dtors[];
__declspec(weak) extern void abort(void);
__declspec(weak) extern void exit(int status);
extern void usr_init();
__declspec(section ".init") static int __get_runtime_linktime_delta(void);
__declspec(section ".init") static int __get_linktime_address(void);
__declspec(section ".init") static void __mwerks_fixup_relocations(void);

#ifdef __cplusplus
}
#endif

/***************************************************************************/
/*
 *	__init_hardware
 *
 *	Initialize the processor and board.
 *
 *	Note: this function must not access memory until the memory controller
 *	is initialized.  Using "fralloc" (frame allocate) or writing this
 *	function in C will cause this routine to break because writing into
 *	stack memory is not valid until after usr_init returns.
 */
/***************************************************************************/

asm void __init_hardware(void)
{
	/*
	 *	Initialize board unless running with MWDebug.
	 *	Uncomment the initialization below if running standalone. 
	 *	You may need to perform other initializations.
	 */
	nofralloc

   /*
	* If we are using Hardware  floating point we need to make sure
 	* to enable the FP bit in the  MSR
 	*/	

#if __option(floatingpoint)==1 &&  __option(sfp_emulation)==0
 	mfmsr r3
 	ori  r3,r3,0x00002000
 	mtmsr r3
#endif

   /*
	* If we have selected Altivec Programming Model we need to make sure
 	* to enable the Altivec bit in the  MSR
 	*/	

#if __VEC__
 	mfmsr r3
	oris r3,r3,0x0200
 	mtmsr r3
#endif	

   /*
	* Enable the MSR[SPE] bit for e500/Zen
 	*/	

#if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__)
	mfmsr r3
	oris   r3,r3,0x0200
	mtmsr r3
#endif

	/*
	 *	When customizing, be aware that the memory controller may not be
	 *	configured.
	 */

#if defined(ROM_VERSION) || defined(CACHE_VERSION)
	mflr	r31						/* save off return address in NV reg */
	bl		usr_init				/* init board hardware */
	mtlr	r31						/* get saved return address */
#endif

	blr
}

#if ALLOC_ADDITIONAL_HEAPS
static void AllocMoreHeaps(void)
{
	/*
	 *	By default, we MSL's allocation (malloc/free) even with C++.
	 *	If you have declared a heap size in the Project Pref panel,
	 *	a defaull heap will be created the first time you call
	 *	malloc.  You can add more calls to init_alloc to create additional
	 *	heaps.
	 */
	init_alloc(some_address1, some_size1);
	init_alloc(some_address2, some_size2);
}
#endif

asm void __init_user(void)
{
	fralloc
	/*
	 *	Allocate additional heaps.
	 */
#if ALLOC_ADDITIONAL_HEAPS
	bl		AllocMoreHeaps
#endif

	/*
	 *	initialization of static initializers
	 */	
#if (defined(__cplusplus) || defined(__VEC__)) && !defined(DO_NOT_LOAD_CTORS_DTORS)
	bl		__init_cpp
#endif

	/*
	 *	Add your initializations here.
	 */
	frfree
	blr
}

#if defined(__cplusplus) || defined(__VEC__)
static void __init_cpp(void)
{
	voidfunctionptr *constructor;

	/*
	 *	call static initializers
	 */
	for (constructor = _ctors; *constructor; constructor++) {
		(*constructor)();
	}
}

static void __fini_cpp(void)
{
	voidfunctionptr *destructor;

	/*
	 *	call destructors
	 */
	for (destructor = _dtors; *destructor; destructor++) {
		(*destructor)();
	}
}
#endif

extern void abort(void)
{
	_ExitProcess();
}

extern void exit(int status)
{
	#pragma unused(status)

#if (defined(__cplusplus) || defined(__VEC__)) && !defined(DO_NOT_LOAD_CTORS_DTORS)
	__fini_cpp();
#endif
	_ExitProcess();
}


/*
 *	_ExitProcess
 *
 *	PowerPC EABI Runtime termination
 */
asm void _ExitProcess(void)
{
	nofralloc
	
#if VLE_ON
	/* the inline assembler can not translate this instruction */
	se_illegal							/* arbitrary break trap for halt */
#else
	opword 0x00454E44					/* arbitrary break trap for halt */
#endif
}

/****************************************************************************/
/*
 *	__flush_cache
 *
 *	For the given memory range, forces all modified data cache contents to be 
 *	written to memory and invalidates the associated instruction cache
 *	entries.
 *	
 */
/****************************************************************************/
asm void __flush_cache(register void *address, register unsigned int size)
{
#pragma unused (address, size)
	/* r3 is address, r4 is size */
	nofralloc

#if !defined( __PPC555__ ) && !defined( __PPC56X__ )
#if VLE_ON
	/* the inline assembler can not translate 2 instructions into 1 */
	e_li    r5,0xFFFFFFF1
#else
	lis		r5, 0xffff
	ori		r5, r5, 0xfff1
#endif
	and		r5, r5, r3				/* make address 8-byte aligned		*/
	subf	r3, r5, r3				/* get unaligned-aligned difference	*/
	add		r4, r4, r3				/* increase size accordingly		*/

rept:
/*
** Note: If no data cache, then just invalidate the instruction
** cache entry.
**
** The MPC 5xx processors do not have data cache.
*/
#if !defined( __PPC505__ ) && !defined( __PPC509__ )

#if !defined(__PPCGENERIC__)
	dcbst	0,r5
#endif

#endif

#if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__)
#if VLE_ON
	se_isync
#else
	msync
#endif
#else
	sync
#endif

	
#if !defined(__PPCGENERIC__)
	icbi	0,r5
#endif

	addic	r5,r5,0x8
	subic.	r4,r4,0x8
	bge		rept
	isync
#endif
	blr
}

#if __option(sda_pic_pid)
/* The following functions are used with SDA PIC/PID support.  						*/
/* __init_registers and __init_data will overload weak versions found in __start.c	*/

/***************************************************************************
*** Requirements for SDA PIC/PID ***

The basic requirement for SDA PIC/PID is that the startup code (.init) and
the segments .sdata and .sdata2 all maintain their link time address 
relationship at runtime.  In other words if the link time addresses are:
.init = 0x00002000
.sdata2 = 0x00003000
.sdata = 0x00004000
but that .init somehow is executed at 0x00002500, then those link time 
addresses must all increment by 0x00000500 for their runtime addresses.  
Any segment that does not maintain the address relationship at runtime is 
considered external and must be addressed with absolute addresses.  
Segments that do maintain their link time address relationship at runtime 
are considered internal and must be addressed with pc and sda relative 
addressing.  More on external and internal segments, below.

Having .init, .sdata2 and .sdata, as well as other internal segments, end
up at runtime without the link time relationship is not detected in this
runtime but it is at least technically possible for someone to modify the
runtime to support this, at least for a specific application.

*** Internal and External segments and references ***

At link time, the linker determines whether code and data segments are 
external or internal.  Internal segments reference their data as far or 
near offsets of the small data registers r2 and r13.  Their code 
references are normally pc relative, but if far code references are 
required, they also use offsets of the small data registers.  Internal
segments can also reference code and data in other internal segments
with the same addressing that they would use for their own code ad data.
By default, all segments in your application are considered internal with 
one exception listed below.

External segments are segments that are at absolute addresses.  
Segments with a name like .abs.xxxxxxxx, where xxxxxxxx is a hex address
are considered external.  External segments reference their data with 
absolute addressing and code references within the segment can be pc 
relative or absolute.  Any other segment must use absolute references 
to reference code or data in external segments.  External segments must 
reference an internal segment with small data registers for code and data.

Akin to external segments are external symbol references.  These are 
symbols, usually linker generated symbols, that are determined to be not 
within any segment in your application.  They will be referenced with
absolute addressing.  All symbols in an external segment are considered
to be external symbol references.

The ldf has 2 mechanisms for you to override the linker's defaults:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -