1    /* --COPYRIGHT--,ESD
     2     *  Copyright (c) 2008 Texas Instruments. All rights reserved. 
     3     *  This program and the accompanying materials are made available under the 
     4     *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
     5     *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
     6     *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
     7     *  Distribution License is available at 
     8     *  http://www.eclipse.org/org/documents/edl-v10.php.
     9     *
    10     *  Contributors:
    11     *      Texas Instruments - initial implementation
    12     * --/COPYRIGHT--*/
    13    /*
    14     *  ======== Startup.xdc ========
    15     *
    16     *! Revision History
    17     *! ================
    18     *! 14-Dec-2007 sasha   moved comments from the internal section to
    19     *                      implemenation
    20     */
    21    
    22    package xdc.runtime;
    23    
    24    /*!
    25     *  ======== Startup ========
    26     *  The `xdc.runtime` startup bootstrap
    27     *
    28     *  Every module can optionally define a startup function which is called
    29     *  before `main()`.  Modules declare that they want to participate in this
    30     *  startup sequence via the `@ModuleStartup` attribute in the module's spec
    31     *  file.  Modules that use this attribute must also implement the following
    32     *  startup function:
    33     *  @p(code)
    34     *      Int Mod_Module_startup(Int state);
    35     *  @p
    36     *  where "Mod" is the name of the module requesting startup support.
    37     *
    38     *  The parameter to the startup function serves as "state variable" whose
    39     *  initial value will be `Startup_NOTDONE`. If `startup()` returns a value
    40     *  other than `Startup_DONE`, it will be called in a subsequent pass with this
    41     *  return value passed in as `state`.  To ensure this process terminates,
    42     *  no startup function is ever called more than `{@link #maxPasses}`
    43     *  times.
    44     *
    45     *  For situations in which the startup of one module depends upon another
    46     *  having completed its startup processing, the following function is
    47     *  automatically defined for all modules and proxies:
    48     *  @p(code)
    49     *      Bool Mod_Module_startupDone();
    50     *  @p
    51     *  where "Mod" is the name of some module or proxy.  These predicates can
    52     *  be used as guards inside of a startup function to probe whether a
    53     *  particular module has completed its own startup processing.  As a
    54     *  convenience, the function `Startup_rtsDone()` probes the necessary set of
    55     *  `xdc.runtime` modules required to support instance `create()` functions, and
    56     *  should be called before any startup-time instance creation and/or
    57     *  memory allocation is performed.
    58     *  @p(code)
    59     *      Int Mod_Module_startup(Int state)
    60     *      {
    61     *          if (!Startup_rtsDone()) {
    62     *              return (Startup_NOTDONE);
    63     *          }
    64     *              .
    65     *              .
    66     *              .
    67     *          return (Startup_DONE);
    68     *      }
    69     *  @p
    70     *
    71     *  @a(Startup Sequence)
    72     *  The following list defines when in the startup sequence the user provided
    73     *  startup functions are being invoked:
    74     *  @p(nlist)
    75     *   - CPU is initialized and C stack setup is performed.
    76     *   - Function specified by `Startup.resetFxn` is called.
    77     *     `Startup.resetFxn` is called only on platforms where reset is performed
    78     *     before running a program. For example, boot code for all TI targets
    79     *     invokes `Startup.resetFxn`, while that function is not invoked on
    80     *     Microsoft targets.
    81     *   - C runtime initialization is performed.
    82     *   - Functions from the array `Startup.firstFxns` are called.
    83     *   - All `Mod_Module_startup` functions are called in a loop until all such
    84     *     functions return `Startup_DONE` or `maxPasses` threshold is reached.
    85     *   - Functions from the array `Startup.lastFxns` are called.
    86     *   - The function `main` is called.
    87     *  @p
    88     *     The steps 4 - 6 occur during C++ static object initialization. Since
    89     *     the ANSI C++ Language Standard does not provide a means to control
    90     *     the order of C++ constructors, if a C++ constructor uses an XDC module,
    91     *     there is no guarantee that the module's startup function already ran.
    92     *     Therefore, any C++ constructor that needs XDC modules' services should
    93     *     call `Startup_exec` first to force all startup related functions from
    94     *     steps 4 - 6 to run, before the constructor uses any XDC module.
    95     *  @p
    96     *     Also, if a target does not support C++, the steps 4 - 6 will not run
    97     *     automatically. It is then up to a user's code to invoke `Startup_exec`,
    98     *     possibly as the first step in `main`.
    99     *  @p
   100     */
   101    @Template("./Startup.xdt")
   102    
   103    module Startup {
   104    
   105        /*!
   106         *  ======== DONE ========
   107         *  Returned from module startup functions no further calls are required
   108         */
   109        const Int DONE = -1;
   110    
   111        /*!
   112         *  ======== NOTDONE ========
   113         *  Initial value of state argument passed to module startup functions
   114         */
   115        const Int NOTDONE = 0;
   116    
   117        /*!
   118         *  ======== maxPasses ========
   119         *  Max number of iterations over the set of startup functions
   120         */
   121        config Int maxPasses = 32;
   122        
   123        /*!
   124         *  ======== InitFxn ========
   125         *  Type of function assignable to `firstFxns`, `lastFxns`, or `resetFxn`
   126         */
   127        typedef Void (*InitFxn)();
   128        
   129        /*!
   130         *  ======== firstFxns ========
   131         *  List of functions called before module startup
   132         *
   133         */
   134        config InitFxn firstFxns[length] = [];
   135    
   136        /*!
   137         *  ======== lastFxns ========
   138         *  List of functions called after module startup
   139         *
   140         */
   141        config InitFxn lastFxns[length] = [];
   142    
   143        /*!
   144         *  ======== resetFxn ========
   145         *  Function to be called by during initialization
   146         *
   147         *  This function is called only on platforms where reset is performed
   148         *  before running the program. The purpose of this function is to set up
   149         *  the hardware registers (cache, external memory interface, etc.) before
   150         *  any other code executes.
   151         *  
   152         */
   153        metaonly config InitFxn resetFxn = null;
   154    
   155        /*!
   156         *  ======== exec ========
   157         *  Execute the startup functions of all resident modules
   158         *
   159         *  Note that this function is idempotent, and can be called at any point
   160         *  in the platform/target startup sequence in which "ordinary" C functions
   161         *  can execute.  By default, this function is called as part of the
   162         *  standard C++ static initialization sequence.
   163         *
   164         *  If your target compiler does not support C++, this function must be
   165         *  called at least once prior to using any `xdc.runtime` modules.
   166         *  Simply call this function at the very beginning of `main()`.
   167         */
   168        Void exec();
   169    
   170        /*!
   171         *  ======== rtsDone ========
   172         *  Query the state of the `xdc.runtime` package
   173         *
   174         *  This function is used by module startup functions to determine
   175         *  when it is possible to use the `xdc.runtime` modules; e.g. to
   176         *  allocate memory, create instances managed by some module (even
   177         *  those outside the `xdc.runtime` package), call a `Log` function,
   178         *  etc.
   179         *
   180         *  @a(returns)     
   181         *  Returns `TRUE` when all `xdc.runtime` modules have completed
   182         *  initialization.
   183         */
   184        Bool rtsDone();
   185    
   186    internal:
   187    
   188        /*!
   189         *  ======== reset ========
   190         *  Application-specific reset function
   191         *
   192         *  This function is defined in `Startup.xdt`
   193         *  (`xdc_runtime_Startup_reset__I`) and is called as early as
   194         *  possible in the program initialization process; for many platforms,
   195         *  it is called prior the the initialization of the C runtime
   196         *  environment.
   197         */
   198        Void reset();
   199    
   200        Void startMods(Int state[], Int len);
   201        readonly config Void (*startModsFxn)(Int[], Int) = startMods;
   202    
   203        extern Void execImplFxn() = xdc_runtime_Startup_exec__I;
   204    
   205        readonly config Void (*execImpl)() = execImplFxn;
   206    
   207        typedef Int (*SFxn)(Int);
   208        config SFxn sfxnTab[];
   209        
   210        /*!
   211         *  ======== sfxnRts ========
   212         *  Array of runtime modules' startup functions 
   213         *
   214         *  This array also contains startup functions of the modules that inherit
   215         *  from interfaces in `xdc.runtime`. Functions added to this array are
   216         *  called only once before the startup procedure for all modules begins.
   217         */
   218        config Bool sfxnRts[];
   219    
   220        struct Module_State {
   221            Int *stateTab;      /* initially null */
   222            Bool execFlag;      /* if true, startup code processing started */
   223            Bool rtsDoneFlag;
   224        };
   225    
   226    }
   227    /*
   228     *  @(#) xdc.runtime; 2, 0, 0, 0,214; 7-29-2009 14:53:44; /db/ztree/library/trees/xdc-t56x/src/packages/
   229     */
   230