1    /* 
     2     * Copyright (c) 2009
     3     * Texas Instruments
     4     *
     5     *  All rights reserved.  Property of Texas Instruments
     6     *  Restricted rights to use, duplicate or disclose this code are
     7     *  granted through contract.
     8     * 
     9     * */
    10    /*
    11     *  ======== BIOS.xdc ========
    12     *
    13     */
    14    
    15    package ti.sysbios;
    16    
    17    import xdc.rov.ViewInfo;
    18    
    19    import xdc.runtime.Types;
    20    
    21    /*! ======== BIOS ========
    22     *  BIOS Master Manager
    23     *
    24     *  Responsible for setting up global parameters pertaining to DSP/BIOS.
    25     *
    26     *  Responsible for BIOS startup.
    27     *
    28     *  The BIOS startup sequence is logically divided into two phases: those 
    29     *  operations that occur prior to the application's "main()" function being 
    30     *  called, and those operations that are performed after the application's 
    31     *  "main()" function is invoked.
    32     *  
    33     *  The "before main()" startup sequence is governed completely by the RTSC 
    34     *  runtime package.
    35     *  
    36     *  The "after main()" startup sequence is governed by BIOS and is initiated
    37     *  by an explicit call to the {@link #start BIOS_start()} function at the 
    38     *  end of the application's main() function.
    39     *  
    40     *  Control points are provided at various places in each of the two startup 
    41     *  sequences for user startup operations to be inserted.
    42     *  
    43     *  The RTSC runtime startup sequence is as follows:
    44     *  
    45     *  1) Immediately after CPU reset, perform target-specific CPU 
    46     *     initialization (beginning at c_int00).
    47     *  
    48     *  2) Prior to cinit(), run the single user-supplied "reset function" 
    49     *     (see {@link xdc.runtime.Startup#resetFxn Startup.resetFxn}).
    50     *  
    51     *  3) Run cinit() to initialize C runtime environment.
    52     *  
    53     *  4) Run the user-supplied "first functions" 
    54     *     (See {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}).
    55     *  
    56     *  5) Run all the module initialization functions.
    57     *  
    58     *  6) Run pinit().
    59     *  
    60     *  7) Run the user-supplied "last functions"
    61     *     (See {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}).
    62     *  
    63     *  8) Run main().
    64     *  
    65     *  The BIOS startup sequence begins at the end of main() when BIOS_start() 
    66     *  is called:
    67     *  
    68     *  1) Run the user-supplied "startup functions" 
    69     *    (see {@link #startupFxns BIOS.startupFxns}).
    70     *  
    71     *  2) Enable Hardware Interrupts.
    72     *  
    73     *  3) Enable Software Interrupts. If the system supports Software Interrupts 
    74     *     (Swis) (see {@link #swiEnabled BIOS.swiEnabled}), then the DSP/BIOS 
    75     *     startup sequence enables Swis at this point.
    76     *  
    77     *  4) Timer Startup. If the system supports Timers, then at this point all 
    78     *     statically configured timers are initialized per their user-configuration.
    79     *     If a timer was configured to start "automatically", it is started here.
    80     *  
    81     *  5) Task Startup. If the system supports Tasks 
    82     *    (see {@link #taskEnabled BIOS.taskEnabled}),
    83     *     then task scheduling begins here. If there are no statically or 
    84     *     dynamically created Tasks in the system, then execution proceeds 
    85     *     directly to the idle loop.
    86     *  
    87     *  Below is a configuration script excerpt that installs a user-supplied
    88     *  startup function at every possible control point in the RTSC/BIOS startup
    89     *  sequence:
    90     *  
    91     *  @p(code)
    92     *  // get handle to xdc Startup module
    93     *  var Startup = xdc.useModule('xdc.runtime.Startup');
    94     *  
    95     *  // install "reset function"
    96     *  Startup.resetFxn = '&myReset';
    97     *  
    98     *  // install a "first function"
    99     *  var len = Startup.firstFxns.length
   100     *  Startup.firstFxns.length++;
   101     *  Startup.firstFxns[len] = '&myFirst';
   102     *  
   103     *  // install a "last function"
   104     *  var len = Startup.lastFxns.length
   105     *  Startup.lastFxns.length++;
   106     *  Startup.lastFxns[len] = '&myLast';
   107     *  
   108     *  // get handle to BIOS module
   109     *  var BIOS = xdc.useModule('ti.sysbios.BIOS');
   110     *  
   111     *  // install a BIOS startup function
   112     *  BIOS.addUserStartupFunction('&myBiosStartup');
   113     *  @p
   114     *
   115     *  @p(html)
   116     *  <h3> Calling Context </h3>
   117     *  <table border="1" cellpadding="3">
   118     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
   119     *
   120     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   121     *    <!--                                                                                                                 -->
   122     *    <tr><td> {@link #getCpuFreq}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   123     *    <tr><td> {@link #getThreadType}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   124     *    <tr><td> {@link #setCpuFreq}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   125     *    <tr><td> {@link #start}      </td><td>   N    </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   N    </td></tr>
   126     *    <tr><td colspan="6"> Definitions: <br />
   127     *       <ul>
   128     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   129     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   130     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   131     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   132     *           <ul>
   133     *             <li> In your module startup after this module is started (e.g. BIOS_Module_startupDone() returns TRUE). </li>
   134     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   135     *             <li> During main().</li>
   136     *             <li> During BIOS.startupFxns.</li>
   137     *           </ul>
   138     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   139     *           <ul>
   140     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   141     *             <li> In your module startup before this module is started (e.g. BIOS_Module_startupDone() returns FALSE).</li>
   142     *           </ul>
   143     *       </ul>
   144     *    </td></tr>
   145     *
   146     *  </table>
   147     *  @p
   148     */
   149    
   150    @Template("./BIOS.xdt")
   151    
   152    module BIOS
   153    {
   154        /*! Current thread type definitions. Returned by {@link #getThreadType} */
   155        enum ThreadType {
   156            ThreadType_Hwi,         /*! Current thread is a Hwi */
   157            ThreadType_Swi,         /*! Current thread is a Swi */
   158            ThreadType_Task,        /*! Current thread is a Task */
   159            ThreadType_Main         /*! Current thread is Boot/Main */
   160        };
   161    
   162        /*! type of Gate to use in the TI RTS library */
   163        enum RtsLockType {
   164            NoLocking,
   165            GateHwi,
   166            GateSwi,
   167            GateMutex,
   168            GateMutexPri
   169        };
   170    
   171        /*! Used in APIs that take a timeout to specify wait forever */
   172        const UInt WAIT_FOREVER = ~(0);
   173    
   174        /*! Used in APIs that take a timeout to specify no waiting */
   175        const UInt NO_WAIT = 0;
   176    
   177        /*! User startup function type definition. */
   178        typedef Void (*StartupFuncPtr)(Void);
   179    
   180        metaonly struct ModuleView {
   181            String       currentThreadType;
   182            String       rtsGateType;
   183            Int          cpuFreqLow;
   184            Int          cpuFreqHigh;
   185            Bool         clockEnabled;
   186            Bool         swiEnabled;
   187            Bool         taskEnabled;
   188            String       startFunc;
   189        }
   190    
   191        @Facet
   192        metaonly config ViewInfo.Instance rovViewInfo = 
   193            ViewInfo.create({
   194                viewMap: [
   195                [
   196                    'Module',
   197                    {
   198                        type: ViewInfo.MODULE,
   199                        viewInitFxn: 'viewInitModule',
   200                        structName: 'ModuleView'
   201                    }
   202                ],
   203                ]
   204            });
   205    
   206        /*! 
   207         * CPU frequency in Hz 
   208         *
   209         * Example: If CPU frequency is 720MHz, do the following
   210         * in configuration script.
   211         * var BIOS = xdc.useModule('ti.sysbios.BIOS');
   212         * BIOS.cpuFreq.hi = 0;
   213         * BIOS.cpuFreq.lo = 720000000;
   214         */
   215        config Types.FreqHz cpuFreq;
   216    
   217        /*! 
   218         *  BIOS Task services enable flag.  Default is true. 
   219         *
   220         *  The following behaviors occur when {@link #taskEnabled} is
   221         *  set to false:
   222         *
   223         *  @p(blist)
   224         *  - Static {@link ti.sysbios.knl.Task Task} creation will 
   225         *    result in a fatal build error.
   226         *  - The Idle task object is not created. 
   227         *    (The Idle functions are invoked within the {@link #start()}
   228         *    thread.)
   229         *  - Runtime Task create will assert.
   230         *  @p
   231         */
   232        config Bool taskEnabled = true;
   233    
   234        /*! 
   235         *  BIOS Swi services enable flag. Default is true.
   236         *
   237         *  The following behaviors occur when {@link #swiEnabled} is 
   238         *  set to false:
   239         *
   240         *  @p(blist)
   241         *  - Static {@link ti.sysbios.knl.Swi Swi} creation will 
   242         *    result in a fatal build error.
   243         *  - The {@link ti.sysbios.knl.Clock Clock module} is 
   244         *    effectively disabled as it uses a Swi
   245         *    to process the Clock objects. 
   246         *  - See other effects as noted for {@link #clockEnabled} = false;
   247         *  - Runtime Swi create will assert.
   248         *  @p
   249         */
   250        config Bool swiEnabled = true;
   251    
   252        /*! 
   253         *  BIOS Clock services enable flag. Default is true. 
   254         *
   255         *  The following behaviors occur when {@link #clockEnabled} is 
   256         *  set to false:
   257         *
   258         *  @p(blist)
   259         *  - Static Clock creation will result in a fatal build error.
   260         *  - No Clock Swi is created.
   261         *  - The {@link ti.sysbios.knl.Clock#tickSource Clock_tickSource} 
   262         *    is set to 
   263         *    {@link ti.sysbios.knl.Clock#TickSource_NULL Clock_TickSource_NULL}
   264         *    to prevent a Timer object from being created.
   265         *  - For APIs that take a timeout, values other than {@link #NO_WAIT} 
   266         *    will be equivalent to {@link #WAIT_FOREVER}.
   267         *  @p
   268         */
   269        config Bool clockEnabled = true;
   270    
   271        /*!
   272         *  Gate to make sure TI RTS library APIs are re-entrant.
   273         *  
   274         *  The application gets to determine the type of gate (lock) that is used
   275         *  in the TI RTS library. The gate will be used to guarantee re-entrancy
   276         *  of the RTS APIs.
   277         *
   278         *  The type of gate depends on the type of threads that are going to
   279         *  be calling into the RTS library.  For example, if both Swi and Task
   280         *  threads are going to be calling the RTS library's printf, GateSwi
   281         *  should be used. Then Hwi threads are not impacted (i.e disabled)
   282         *  during the printf calls from the Swi or Task threads.
   283         *
   284         *  If NoLocking is used, the RTS lock is not plugged and re-entrancy for 
   285         *  the TI RTS library calls are not guaranteed. The application can plug
   286         *  the RTS locks directly if it wants.
   287         *
   288         *  Gate Type
   289         * 
   290         *  {@link #GateHwi}: Interrupts are disabled and restored to maintain 
   291         *  re-entrancy in RTS.
   292         *  Use if only making RTS calls from a Hwi, Swi and/or Task.  
   293         *
   294         *  {@link #GateSwi}: Swis are disabled and restored to maintain 
   295         *  re-entrancy in RTS
   296         *  Use if only making RTS calls from a Swi and/or Task.  
   297         *
   298         *  {@link #GateMutex}: A single mutex is used to maintain re-entrancy 
   299         *  in RTS. 
   300         *  Use if only making RTS calls from a Task.  Blocks only Tasks that are 
   301         *  also trying to execute critical regions of RTS library.
   302         *
   303         *  {@link #GateMutexPri}: A priority inheriting mutex is used to maintain 
   304         *  re-entracy in RTS. Use if only making RTS calls from a Task.  
   305         *  Blocks only Tasks that are also trying to execute critical regions of 
   306         *  RTS library.  Raises the priority of the Task that is executing the
   307         *  critical region in the RTS library to the level of the higher 
   308         *  priority Task that is trying to execute a critical region of the RTS
   309         *  library also.
   310         *
   311         *  The default is to use depends on the type of threading model. 
   312         *  If {@link #taskEnabled} is true, {@link #GateMutex} is used.
   313         *  If {@link #swiEnabled} is true and {@link #taskEnabled} is false: 
   314         *  {@link #GateSwi} is used.
   315         *  If both {@link #swiEnabled} and {@link #taskEnabled} are false: 
   316         *  {@link #GateHwi} is used.
   317         *
   318         *  If {@link #taskEnabled} is false, the user should not select 
   319         *  {@link #GateMutex} (orother Task level gates). Similarly, if 
   320         *  {@link #taskEnabled} and {@link #swiEnabled}are false, the user 
   321         *  should not select {@link #GateSwi} or the Task level gates.
   322         */
   323        metaonly config RtsLockType rtsGateType;
   324        
   325        /*!
   326         *  ======== startupFxns ========
   327         *  The array of user (and middleware) provided functions to be executed
   328         *  at the beginning of BIOS_start().
   329         *
   330         *  These functions are executed before Hwis, Swis, and Tasks are 
   331         *  started.
   332         */
   333        metaonly config StartupFuncPtr startupFxns[] = [];
   334    
   335        /*!
   336         *  ======== addUserStartupFunction ========
   337         *  @_nodoc
   338         *  Statically add a function to the startupFxns table.
   339         */
   340        metaonly Void addUserStartupFunction(StartupFuncPtr func);
   341    
   342        /*!
   343         *  ======== start ========
   344         *  Start bios.
   345         *
   346         *  The user's main() function is required to call this function
   347         *  after all other user initializations have been performed.
   348         *
   349         *  This function does not return.
   350         *
   351         *  This function performs any remaining BIOS initializations 
   352         *  and then transfers control to the highest priority ready
   353         *  task if {@link #taskEnabled} is true. If {@link #taskEnabled}
   354         *  is false, control is transferred directly to the Idle Loop.
   355         *
   356         *  The BIOS start sequence is as follows:
   357         *  @p(blist)
   358         *  - Invoke all the functions in the {@link #startupFxns} array.
   359         *  - call {@link ti.sysbios.hal.Hwi#enable Hwi_startup()} 
   360         *    to enable interrupts.
   361         *  - if {@link #swiEnabled} is true, call 
   362         *    {@link ti.sysbios.knl.Swi#enable Swi_startup()} to enable
   363         *    the Swi scheduler.
   364         *  - Start any statically created or constructed Timers
   365         *    in the {@link ti.sysbios.hal.Timer#StartMode Timer_StartMode_AUTO} 
   366         *    mode.
   367         *  - if {@link #taskEnabled} is true, enable the Task scheduler 
   368         *    and transfer the execution thread to the highest priority 
   369         *    task in the {@link ti.sysbios.knl.Task#Mode Task_Mode_READY} 
   370         *    mode.
   371         *  - Otherwise, fall directly into the Idle Loop.
   372         *  @p
   373         *  
   374         */
   375        Void start();
   376    
   377        /*!
   378         *  ======== getThreadType ========
   379         *  Get the current threadType.
   380         *
   381         *  @b(returns)     Previous threadType
   382         */
   383        ThreadType getThreadType();
   384    
   385        /*!
   386         *  @_nodoc
   387         *  ======== setThreadType ========
   388         *  Set the current threadType.
   389         *
   390         *  Called by the various threadType owners.
   391         *
   392         *  @param(ttype)   New threadType value
   393         *  @b(returns)     Previous threadType
   394         */
   395        ThreadType setThreadType(ThreadType ttype);
   396    
   397        /*!
   398         *  ======== setCpuFrequnecy ========
   399         *  Set CPU Frequency in Hz.
   400         *
   401         *  This API is not thread safe. Please use appropriate locks.
   402         */
   403        Void setCpuFreq(Types.FreqHz *freq);
   404    
   405        /*!
   406         *  ======== getCpuFrequency ========
   407         *  Get CPU frequency in Hz
   408         *
   409         *  This API is not thread safe. Please use appropriate locks.
   410         */
   411        Void getCpuFreq(Types.FreqHz *freq);
   412    
   413        /*!
   414         *  @_nodoc
   415         *  ======== registerRTSLock ========
   416         *  Register the rts lock. Added as a startup function in BIOS.xs.
   417         */
   418        Void registerRTSLock();
   419    
   420    internal:
   421    
   422        /* Generated start function */
   423        Void startFunc();
   424    
   425        /*! Gate proxy to be used for the rts gate */
   426        proxy RtsGateProxy inherits xdc.runtime.IGateProvider;
   427    
   428        /*! Function type for BIOS_start generation */
   429        typedef Void (*StartFuncPtr)(void);
   430    
   431        struct Module_State {
   432            Types.FreqHz                    cpuFreq;        /* in KHz */
   433            UInt                            rtsGateCount;   /* count for nesting */
   434            IArg                            rtsGateKey;     /* count for nesting */
   435            RtsGateProxy.Handle             rtsGate;
   436            ThreadType                      threadType;     /* Curr Thread Type */
   437                                                            /* (Hwi, Swi, Task) */
   438            StartFuncPtr                    startFunc;
   439        };
   440    }
   441    /*
   442     *  @(#) ti.sysbios; 2, 0, 0, 0,365; 12-18-2009 15:11:41; /db/vtree/library/trees/avala/avala-m19x/src/
   443     */
   444