diff options
Diffstat (limited to 'src/ssx/ssx/ssx_init.c')
-rwxr-xr-x | src/ssx/ssx/ssx_init.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/ssx/ssx/ssx_init.c b/src/ssx/ssx/ssx_init.c new file mode 100755 index 0000000..fc12a9b --- /dev/null +++ b/src/ssx/ssx/ssx_init.c @@ -0,0 +1,159 @@ +// $Id: ssx_init.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_init.c,v $ +//----------------------------------------------------------------------------- +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//----------------------------------------------------------------------------- + +/// \file ssx_init.c +/// \brief SSX initialization +/// +/// The entry points in this file are initialization routines - they are never +/// needed after SSX initialization and their code space could be reclaimed by +/// the application after initialization if required. + +#include "ssx.h" + +uint32_t __ssx_timebase_frequency_hz; +uint32_t __ssx_timebase_frequency_khz; +uint32_t __ssx_timebase_frequency_mhz; + + +/// Initialize SSX. +/// +/// \param noncritical_stack A stack area for noncritical interrupt handlers. +/// +/// \param noncritical_stack_size The size (in bytes) of the stack area for +/// noncritical interrupt handlers. +/// +/// \param critical_stack A stack area for critical interrupt handlers. +/// +/// \param critical_stack_size The size (in bytes) of the stack area for +/// critical interrupt handlers. +/// +/// \param initial_timebase The initial value of the SSX timebase. If this +/// argument is given as the special value \c SSX_TIMEBASE_CONTINUE, then the +/// timebase is not reset. +/// +/// \param timebase_frequency_hz The frequency of the SSX timebase in Hz. +/// +/// This routine \e must be called before any other SSX / routines, and \e +/// should be called before any interrupts are enabled. +/// +/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors +/// +/// \retval 0 Successful completion +/// +/// \retval -SSX_INVALID_ARGUMENT_INIT A stack pointer is 0 or is given +/// a 0 size. +/// +/// \retval -SSX_STACK_OVERFLOW One or both stacks are not large enough to +/// support a minimum context save in the event of an interrupt. + +// Note that SSX does not rely on any static initialization of dynamic +// variables. In debugging sessions using RAM-resident SSX images it is +// assumed that the processor may be reset at any time, so we always need to +// reset everything at initialization. + +int +ssx_initialize(SsxAddress noncritical_stack, + size_t noncritical_stack_size, + SsxAddress critical_stack, + size_t critical_stack_size, + SsxTimebase initial_timebase, + uint32_t timebase_frequency_hz) +{ + int rc; + + if (SSX_ERROR_CHECK_API) { + SSX_ERROR_IF((noncritical_stack == 0) || + (noncritical_stack_size == 0) || + (critical_stack == 0) || + (critical_stack_size == 0), + SSX_INVALID_ARGUMENT_INIT); + } + + if (initial_timebase != SSX_TIMEBASE_CONTINUES) { + __ssx_timebase_set(initial_timebase); + } + + __ssx_timebase_frequency_hz = timebase_frequency_hz; + __ssx_timebase_frequency_khz = timebase_frequency_hz / 1000; + __ssx_timebase_frequency_mhz = timebase_frequency_hz / 1000000; + + __ssx_thread_machine_context_default = SSX_THREAD_MACHINE_CONTEXT_DEFAULT; + + rc = __ssx_stack_init(&noncritical_stack, &noncritical_stack_size); + if (rc) { + return rc; + } + + __ssx_noncritical_stack = noncritical_stack; + __ssx_noncritical_stack_size = noncritical_stack_size; + + rc = __ssx_stack_init(&critical_stack, &critical_stack_size); + if (rc) { + return rc; + } + + __ssx_critical_stack = critical_stack; + __ssx_critical_stack_size = critical_stack_size; + +#if SSX_TIMER_SUPPORT + + // Initialize the time queue sentinel as a circular queue, set the next + // timeout and clear the cursor. + + ssx_deque_sentinel_create((SsxDeque*)&__ssx_time_queue); + __ssx_time_queue.cursor = 0; + __ssx_time_queue.next_timeout = SSX_TIMEBASE_MAX; + +#endif /* SSX_TIMER_SUPPORT */ + +#if SSX_THREAD_SUPPORT + + // Clear the priority map. The final entry [SSX_THREADS] is for the idle + // thread. + + int i; + for (i = 0; i <= SSX_THREADS; i++) { + __ssx_priority_map[i] = 0; + } + + // Initialize the thread scheduler + + __ssx_thread_queue_clear(&__ssx_run_queue); + __ssx_current_thread = 0; + __ssx_next_thread = 0; + __ssx_delayed_switch = 0; + +#endif /* SSX_THREAD_SUPPORT */ + + return SSX_OK; +} + + +/// Call the application main() +/// +/// __ssx_main() is called from the bootloader. It's only purpose is to +/// provide a place for the SSX_MAIN_HOOK to be called before main() is +/// called. + +void +__ssx_main(int argc, char **argv) +{ + SSX_MAIN_HOOK; + + int main(int argc, char **argv); + main(argc, argv); +} + + + + + + + + + |