1    /* 
     2     *  Copyright (c) 2008-2020 Texas Instruments Incorporated
     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     * */
    13    /*
    14     *  ======== Startup.xdc ========
    15     */
    16    
    17    package xdc.runtime;
    18    
    19    /*!
    20     *  ======== Startup ========
    21     *  The `xdc.runtime` startup bootstrap
    22     *
    23     *  This module manages the very early startup initialization that occurs
    24     *  before C's `main()` function is invoked.  This initialization typically
    25     *  consists of setting hardware specific registers that control watchdog
    26     *  timers, access to memory, cache settings, clock speeds, etc.
    27     *
    28     *  In addition to configuration parameters that allow the user to add custom
    29     *  startup functions, this module also provides services that allow modules
    30     *  to automatically add initialization functions to the startup sequence.
    31     *
    32     *  @a(Startup Sequence)
    33     *  The following list defines the startup sequence and, in particular, when
    34     *  user provided startup functions are invoked:
    35     *  @p(nlist)
    36     *   - CPU is initialized and initial C stack setup is performed.
    37     *   - The function specified by `Startup.resetFxn` is called.
    38     *     `Startup.resetFxn` is called only on platforms where reset is performed
    39     *     before running a program. For example, boot code for all TI targets
    40     *     invokes `Startup.resetFxn`, but this function is not invoked on
    41     *     Microsoft targets.
    42     *   - C runtime initialization is performed.
    43     *   - Functions from the array `Startup.firstFxns` are called.
    44     *   - All `Mod_Module_startup` functions (see Module Initialization below)
    45     *     are called in a loop until all such functions return
    46     *     `{@link #Startup_DONE}` or the `{@link #maxPasses}` threshold is
    47     *     reached.
    48     *   - Functions from the array `Startup.lastFxns` are called.
    49     *   - The function `main` is called.
    50     *  @p
    51     *     The steps 4 - 6 occur during C++ static object initialization. Since
    52     *     the ANSI C++ Language Standard does not provide a means to control
    53     *     the order of C++ constructors, if a C++ constructor uses an XDC module,
    54     *     there is no guarantee that the module's startup function already ran.
    55     *     Therefore, any C++ constructor that needs XDC modules' services should
    56     *     call `Startup_exec` first to force all startup related functions from
    57     *     steps 4 - 6 to run, before the constructor uses any XDC module.
    58     *  @p
    59     *     Also, if a target does not support C++, the steps 4 - 6 will not run
    60     *     automatically. It is then up to a user's code to invoke `Startup_exec`,
    61     *     possibly as the first step in `main`.
    62     *  @p
    63     *
    64     *  @a(Module Initialization)
    65     *  Every module can optionally define a startup function which is called
    66     *  before `main()`.  Modules declare that they want to participate in this
    67     *  startup sequence via the `@ModuleStartup` attribute in the module's spec
    68     *  file.  Modules that use this attribute must also implement the following
    69     *  startup function:
    70     *  @p(code)
    71     *      Int Mod_Module_startup(Int state);
    72     *  @p
    73     *  where "Mod" is the name of the module requesting startup support.
    74     *
    75     *  The parameter to the startup function serves as "state variable" whose
    76     *  initial value will be `Startup_NOTDONE`. If `startup()` returns a value
    77     *  other than `Startup_DONE`, it will be called in a subsequent pass with this
    78     *  return value passed in as `state`.  To ensure this process terminates,
    79     *  no startup function is ever called more than `{@link #maxPasses}`
    80     *  times.
    81     *
    82     *  For situations in which the startup of one module depends upon another
    83     *  having completed its startup processing, the following function is
    84     *  automatically defined for all modules and proxies:
    85     *  @p(code)
    86     *      Bool Mod_Module_startupDone();
    87     *  @p
    88     *  where "Mod" is the name of a module or a proxy. These predicates can be
    89     *  used as guards inside of a startup function to probe whether a particular
    90     *  module has completed its own startup processing. As a convenience, the
    91     *  function `Startup_rtsDone()` probes the necessary set of `xdc.runtime`
    92     *  modules required to support instance `create()` functions, and should be
    93     *  called before any startup-time instance creation and/or memory allocation
    94     *  is performed.
    95     *  @p(code)
    96     *      Int Mod_Module_startup(Int state)
    97     *      {
    98     *          if (!Startup_rtsDone()) {
    99     *              return (Startup_NOTDONE);
   100     *          }
   101     *              .
   102     *              .
   103     *              .
   104     *          return (Startup_DONE);
   105     *      }
   106     *  @p
   107     *
   108     *  @a(Examples)
   109     *  The following code shows how to add custom startup functions to this module.
   110     *  @p(code)
   111     *      var Startup = xdc.useModule('xdc.runtime.Startup');
   112     *      Startup.resetFxn = "&myResetFxn";
   113     *      Startup.firstFxns.$add("&myFirst");
   114     *      Startup.lastFxns.$add("&myLast");
   115     *  @p
   116     *
   117     */
   118    @Template("./Startup.xdt")
   119    @DirectCall
   120    
   121    module Startup {
   122    
   123        /*!
   124         *  ======== DONE ========
   125         *  Returned from module startup functions no further calls are required
   126         */
   127        const Int DONE = -1;
   128    
   129        /*!
   130         *  ======== NOTDONE ========
   131         *  Initial value of state argument passed to module startup functions
   132         */
   133        const Int NOTDONE = 0;
   134    
   135        /*!
   136         *  ======== ModuleView ========
   137         *  @_nodoc
   138         */
   139        metaonly struct ModuleView {
   140            Bool    rtsStartupDone;
   141            Bool    startupBegun;
   142            String  resetFxn;
   143            String  firstFxns[];
   144            String  lastFxns[];
   145        }
   146    
   147        /*!
   148         *  ======== StartupStateView ========
   149         *  @_nodoc
   150         */
   151        metaonly struct StartupStateView {
   152            Int     order;
   153            String  moduleName;
   154            String  done;
   155        }
   156    
   157        /*!
   158         *  ======== rovViewInfo ========
   159         *  @_nodoc
   160         */
   161        @Facet
   162        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
   163            xdc.rov.ViewInfo.create({
   164                viewMap: [
   165                    ['Module',
   166                        {
   167                            type: xdc.rov.ViewInfo.MODULE,
   168                            viewInitFxn: 'viewInitModule',
   169                            structName: 'ModuleView'
   170                        }
   171                    ],
   172                    ['Startup State',
   173                        {
   174                            type: xdc.rov.ViewInfo.MODULE_DATA,
   175                            viewInitFxn: 'viewInitStartupState',
   176                            structName: 'StartupStateView'
   177                        }
   178                    ]
   179                ]
   180            });
   181    
   182        /*!
   183         *  ======== maxPasses ========
   184         *  Max number of iterations over the set of startup functions
   185         */
   186        /* REQ_TAG(SYSBIOS-952) */
   187        config Int maxPasses = 32;
   188    
   189        /*!
   190         *  ======== InitFxn ========
   191         *  Type of function assignable to `firstFxns`, `lastFxns`, or `resetFxn`
   192         */
   193        typedef Void (*InitFxn)();
   194    
   195        /*!
   196         *  ======== firstFxns ========
   197         *  List of functions called before module startup
   198         *
   199         *  @see
   200         *      #xdoc-sect-2 Startup Sequence
   201         */
   202        /* REQ_TAG(SYSBIOS-955) */
   203        config InitFxn firstFxns[length] = [];
   204    
   205        /*!
   206         *  ======== lastFxns ========
   207         *  List of functions called after module startup
   208         *
   209         *  @see
   210         *      #xdoc-sect-2 Startup Sequence
   211         */
   212        /* REQ_TAG(SYSBIOS-956) */
   213        config InitFxn lastFxns[length] = [];
   214    
   215        /*!
   216         *  ======== resetFxn ========
   217         *  Function to be called during initialization
   218         *
   219         *  This function is called only on platforms where reset is performed
   220         *  before running the program. The purpose of this function is to set up
   221         *  the hardware registers (cache, external memory interface, etc.) before
   222         *  any other code executes.
   223         *
   224         *  This function is called as early as possible in the
   225         *  {@link #xdoc-sect-2 program initialization} process. For some targets,
   226         *  it is called before the C environment is fully initialized and static
   227         *  and global variables may not be fully initialized. To maximize
   228         *  portability, reset functions should only assume that a C stack is
   229         *  initialized.
   230         *
   231         *  @see
   232         *      #xdoc-sect-2 Startup Sequence
   233         */
   234        /* REQ_TAG(SYSBIOS-951) */
   235        metaonly config InitFxn resetFxn = null;
   236    
   237        /*!
   238         *  ======== exec ========
   239         *  Execute the startup functions of all resident modules
   240         *
   241         *  Note that this function is idempotent, and can be called at any point
   242         *  in the platform/target startup sequence in which "ordinary" C functions
   243         *  can execute.  By default, this function is called as part of the
   244         *  standard C++ static initialization sequence.
   245         *
   246         *  If your target compiler does not support C++, this function must be
   247         *  called at least once prior to using any `xdc.runtime` modules.
   248         *  Simply call this function at the very beginning of `main()`.
   249         */
   250        /* REQ_TAG(SYSBIOS-950) */
   251        Void exec();
   252    
   253        /*!
   254         *  ======== rtsDone ========
   255         *  Query the state of the `xdc.runtime` package
   256         *
   257         *  This function is used by module startup functions to determine when it
   258         *  is possible to use the `xdc.runtime` modules; e.g. to allocate memory,
   259         *  create instances managed by some module (even those outside the
   260         *  `xdc.runtime` package), call a `Log` function, etc.
   261         *
   262         *  @a(returns)
   263         *  Returns `TRUE` when all `xdc.runtime` modules have completed
   264         *  initialization.
   265         */
   266        /* REQ_TAG(SYSBIOS-954) */
   267        Bool rtsDone();
   268    
   269    internal:
   270    
   271        /*!
   272         *  ======== reset ========
   273         *  Application-specific reset function
   274         *
   275         *  This function is defined in `Reset.xdt`
   276         *  (`xdc_runtime_Startup_reset__I`) and is called as early as possible in
   277         *  the {@link #xdoc-sect-2 program initialization} process; for many
   278         *  platforms, it is called prior to the initialization of the C
   279         *  runtime environment.
   280         *
   281         *  @see
   282         *      #xdoc-sect-2 Startup Sequence
   283         */
   284        Void reset();
   285    
   286        Void startMods(Int state[], Int len);
   287        readonly config Void (*startModsFxn)(Int[], Int) = startMods;
   288    
   289        extern Void execImplFxn() = xdc_runtime_Startup_exec__I;
   290    
   291        readonly config Void (*execImpl)() = execImplFxn;
   292    
   293        typedef Int (*SFxn)(Int);
   294        /* REQ_TAG(SYSBIOS-949), REQ_TAG(SYSBIOS-953) */
   295        config SFxn sfxnTab[];
   296    
   297        /*!
   298         *  ======== sfxnRts ========
   299         *  Array of runtime modules' startup functions
   300         *
   301         *  This array also contains startup functions of the modules that inherit
   302         *  from interfaces in `xdc.runtime`. Functions added to this array are
   303         *  called only once before the startup procedure for all modules begins.
   304         *
   305         *  @see
   306         *      #xdoc-sect-2 Startup Sequence
   307         */
   308        config Bool sfxnRts[];
   309    
   310        /*!
   311         *  ======== getState ========
   312         *  Function that returns the value of the startup state.
   313         *
   314         *  Modules for which the config C code is generated separately, and
   315         *  possibly before the configuration step is run, must call a function
   316         *  to get their startup state. They cannot reach into the state array
   317         *  directly because they don't know their indices in that array.
   318         */
   319        Int getState(Types.ModuleId id);
   320    
   321        /*!
   322         *  ======== IdMap ========
   323         *  keeps track of modules in stateTab and their module IDs for purposes
   324         *  of the function getState.
   325         */
   326        struct IdMap {
   327            UInt           ind;
   328            Types.ModuleId modId;
   329        }
   330    
   331        struct Module_State {
   332            Int *stateTab;      /* initially null */
   333            Bool execFlag;      /* if true, startup code processing started */
   334            Bool rtsDoneFlag;
   335        };
   336    
   337    }
   338    /*
   339     *  @(#) xdc.runtime; 2, 1, 0,0; 10-3-2020 15:24:56; /db/ztree/library/trees/xdc/xdc-K04/src/packages/
   340     */
   341