/**************************************************************************
** *
** FILE : cstart.c *
** *
** DESCRIPTION : *
** The system startup code initializes the processor's registers *
** and the application C variables. *
** *
** Copyright 1996-2014 Altium BV *
** *
**************************************************************************/
#include "cstart.h" /* include configuration */
#include <stdlib.h>
#include <stdbool.h>
#ifdef __CPU__
#include __SFRFILE__(__CPU__)
#endif
#pragma weak exit
#pragma extern _Exit
#pragma profiling off /* prevent profiling information on cstart */
#pragma tradeoff 4 /* preset tradeoff level (for size) */
#pragma runtime BCM /* disable runtime error checking for cstart */
#pragma nomisrac /* disable MISRA-C checking */
#pragma noclear /* bss clearing not before cinit */
#pragma immediate_in_code /* no external ROM access before bus configuration */
#if __USE_ARGC_ARGV
static char argcv[__ARGCV_BUFSIZE];
extern int _argcv( const char *, size_t );
#endif
/* linker definitions */
extern __far void _lc_ue_ustack[]; /* user stack end */
extern __far void _lc_ue_istack[]; /* interrupt stack end */
extern __far void _lc_u_int_tab[]; /* interrupt table */
extern __far void _lc_u_trap_tab[]; /* trap table */
extern __far void _SMALL_DATA_[]; /* centre of A0 addressable area */
extern __far void _LITERAL_DATA_[]; /* centre of A1 addressable area */
extern __far void _A8_DATA_[]; /* centre of A8 addressable area */
extern __far void _A9_DATA_[]; /* centre of A9 addressable area */
/* external functions */
#if __C_INIT
extern void _c_init(void); /* C initialization function */
#endif
#ifdef __CALL_INIT
extern void _call_init(void); /* call a user function before main() */
#endif
#ifdef _CALL_ENDINIT
extern void _endinit(void); /* call a user function with protection switched off */
#endif
/* local functions */
static void __noinline__ __noreturn__ __jump__ __init_sp( void );
static void __noinline__ __noreturn__ __jump__ _start( void );
/* library references */
#pragma extern main
extern int main( int argc, char *argv[] );
/* endinit types */
typedef enum
{
_ENDINIT_DISABLE,
_ENDINIT_ENABLE
} _endinit_t;
static void inline endinit_set(_endinit_t endinit_value);
/* external interface to endinit_set */
extern void _endinit_clear(void) { endinit_set(_ENDINIT_DISABLE); }
extern void _endinit_set (void) { endinit_set(_ENDINIT_ENABLE); }
#if __PROF_ENABLE__
extern void __prof_init( void );
#endif
#if __CLOCKS_PER_SEC_INIT
static void setclockpersec( void );
extern unsigned long long setfoschz( unsigned long long );
#endif
#if ( defined _REGUSERDEF16X_H || defined _REGTC23X_ADAS_H || defined _REGTC23X_H || defined _REGTC2D5T_H || defined _REGTC27X_H || defined _REGTC27XB_H || defined _REGTC27XC_H || defined _REGTC26X_H || defined _REGTC29X_H)
#define WDT_CON0 SCU_WDTCPU0CON0
#define WDT_CON1 SCU_WDTCPU0CON1
static void inline safety_endinit_set(_endinit_t endinit_value);
/* external interface to endinit_set */
extern void _safety_endinit_clear(void) { safety_endinit_set(_ENDINIT_DISABLE); }
extern void _safety_endinit_set (void) { safety_endinit_set(_ENDINIT_ENABLE); }
#endif
#if ( defined _REGUSERDEF16X_H || defined _REGTC2D5T_H || defined _REGTC27X_H || defined _REGTC27XB_H || defined _REGTC27XC_H || defined _REGTC26X_H || defined _REGTC29X_H)
#if (__HALT_INIT_TC1 && (__HALT_VALUE_TC1 & 0x2)) || (__HALT_INIT_TC2 && (__HALT_VALUE_TC2 & 0x2))
#if __C_INIT || __CLOCKS_PER_SEC_INIT || __PROF_ENABLE__ || _CALL_ENDINIT || (defined __CALL_INIT)
/* c init semaphores */
#if (defined _REGTC27X_H || defined _REGTC27XB_H || defined _REGTC27XC_H || defined _REGTC29X_H)
#define __AT_NOT_CACHED_MEMORY__ __at(0x70000000)
#else
#define __AT_NOT_CACHED_MEMORY__
#endif
unsigned int volatile __far __align(4) _tcx_end_c_init __AT_NOT_CACHED_MEMORY__; /* _tcx_end_c_init := 1 << core_id */
#endif
#endif
#endif
/*********************************************************************************
* reset vector
*********************************************************************************/
#pragma section code libc.reset
#pragma optimize g
void _START( void )
{
__init_sp();
}
#pragma optimize restore
#pragma section code restore
/*********************************************************************************
* EBU boot configuration
*********************************************************************************/
#if defined EBU_BOOTCFG && defined __EBU_BOOTCFG_VALUE
#if __EBU_BOOTCFG_INIT
#pragma section farrom libc.ebu_bootcfg
const int __far _EBU_BOOTCFG __protect__ = __EBU_BOOTCFG_VALUE; /* locate at RESET + EBU_ALIGN */
#pragma section farrom restore
#endif
#endif
/*********************************************************************************
* initialize stackpointer
*********************************************************************************/
static void __noinline__ __noreturn__ __jump__ __init_sp( void )
{
/* The initialization of the stackpointer is done in a seperate function,
because it must be executed in a function which has no stack use.
When a function uses a stack it will be updated at the start of the
function. In this function, however, the stackpointer has an irrelevant
value at the start of the function. A starting value for the stackpointer
is determined and written in this function. The update to the
stackpointer at the start of the function would therefore be undone.
*/
/*
* CPU_TC.033 workaround:
* The stack pointers are aligned to quad-word boundary to workaround these
* functional problems CPU_TC.033.
* Also the C compiler workaround for the appropriate CPU function problem
* need to be enabled with --silicon-bug=cpu-tc033, to align circular
* buffers on a quad-word boundary and to size all stack frames to an integral
* number of quad-words.
*/
#if __CPU_TC033_INITIAL__
# define STACK_ALIGN 0xfffffff0
#else
# define STACK_ALIGN 0xfffffff8
#endif
/*
* Load user stack pointer.
* Disable this if not started from RESET vector. (E.g.
* ROM monitors require to keep in control of vectors)
*/
#if __USP_INIT
unsigned int sp = (unsigned int)(_lc_ue_ustack) & STACK_ALIGN;
__asm("mov.a\tsp,%0"::"d"(sp));
#endif
_start();
}
/*********************************************************************************
* startup code
*********************************************************************************/
static void __noinline__ __noreturn__ __jump__ _start( void )
{
#if ( defined _REGUSERDEF16X_H || defined _REGTC2D5T_H || defined _REGTC27X_H || defined _REGTC27XB_H || defined _REGTC27XC_H || defined _REGTC26X_H || defined _REGTC29X_H)
#if __STADD_INIT_TC1
/*
* Set start address of TC1
* Reset value is 0