1    /* 
     2     * Copyright (c) 2011, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     * */
    32    /*
    33     *  ======== Swi.xdc ========
    34     *
    35     */
    36    
    37    package ti.sysbios.knl;
    38    
    39    import xdc.rov.ViewInfo;
    40    
    41    import xdc.runtime.Error;
    42    import xdc.runtime.Assert;
    43    import xdc.runtime.Diags;
    44    import xdc.runtime.Log;
    45    
    46    import ti.sysbios.knl.Queue;
    47    
    48    /*!
    49     *  ======== Swi ========
    50     *  Software Interrupt Manager.
    51     *
    52     *  The Swi module manages software interrupt service routines, which are
    53     *  patterned after hardware interrupt service routines.
    54    
    55     *  SYS/BIOS manages four distinct levels of execution threads: hardware
    56     *  interrupt service routines, software interrupt routines, tasks, and
    57     *  background idle functions. A software interrupt is an object that
    58     *  encapsulates a function to be executed and a priority. 
    59     *  Software interrupts are prioritized, preempt tasks, and are preempted 
    60     *  by hardware interrupt service routines.
    61     *
    62     *  Each software interrupt has a priority level. A software interrupt 
    63     *  preempts any lower-priority software interrupt currently executing.
    64     *
    65     *  A target program uses an API call to post a Swi object. This causes the
    66     *  Swi module to schedule execution of the software interrupt's function.
    67     *  When a Swi is posted by an API call, the Swi object's function is not
    68     *  executed immediately. Instead, the function is scheduled for execution.
    69     *  SYS/BIOS uses the Swi's priority to determine whether to preempt the
    70     *  thread currently running. Note that if a Swi is posted several times 
    71     *  before it begins running, (because Hwis and higher priority interrupts 
    72     *  are running,) when the Swi does eventually run, it will run only one time.
    73     *
    74     *  Software interrupts can be posted for execution with a call to {@link #post}
    75     *  or a number of other Swi functions. Each Swi object has a "trigger"
    76     *  which is used either to determine whether to post the Swi or as a value
    77     *  that can be evaluated within the Swi's function. {@link #andn} and 
    78     *  {@link #dec}
    79     *  post the Swi if the trigger value transitions to 0. {@link #or} and 
    80     *  {@link #inc}
    81     *  also modify the trigger value. ({@link #or} sets bits, and {@link #andn}
    82     *  clears bits.)
    83     *  
    84     *  The {@link #disable} and {@link #restore} operations allow you to 
    85     *  post several
    86     *  Swis and enable them all for execution at the same time. The Swi
    87     *  priorities then determine which Swi runs first.
    88     *
    89     *  All Swis run to completion; you cannot suspend a Swi while it waits for
    90     *  something (for example, a device) to be ready. So, you can use the
    91     *  trigger to tell the Swi when all the devices and other conditions it 
    92     *  relies on are ready. Within a Swi processing function, a call to 
    93     *  Swi_getTrigger returns the value of the trigger when the Swi started 
    94     *  running.
    95     *  Note that the trigger is automatically reset to its original value 
    96     *  when a Swi runs; however, {@link #getTrigger} will return the saved 
    97     *  trigger 
    98     *  value from when the Swi started execution.
    99     *
   100     *  All Swis run with interrupts globally enabled (ie GIE = 1).
   101     *  Therefore, any Swi module API that results in a
   102     *  Swi being made ready to run (ie {@link #post}, {@link #inc}, {@link #andn}, 
   103     *  {@link #or}, {@link #restore}, or {@link #enable})
   104     *  will subsequently also cause interrupts to be enabled while the
   105     *  Swi function executes. Upon return from the Swi function,
   106     *  global interrupts are restored to their previous enabled/disabled
   107     *  state.
   108     *
   109     *  A Swi preempts any currently running Swi with a lower priority. 
   110     *  When multiple Swis of the same priority level have been posted, 
   111     *  their respective Swi functions are executed in the order the Swis 
   112     *  were posted.
   113     *  Hwis in turn preempt any currently running Swi,
   114     *  allowing the target to respond quickly to hardware peripherals.
   115     *
   116     *  Swi threads are executed using the ISR (or "Hwi") stack. Thus
   117     *  they share the ISR stack with Hwi threads.
   118     *
   119     *  {@link #disable} also disables the Task scheduler.
   120     *  Therefore, Task pre-emption and blocking is disabled while
   121     *  the Swi scheduler is disabled.
   122     *  {@link #restore} will re-enable and invoke the Task
   123     *  scheduler if the Task scheduler was not disabled prior
   124     *  to invoking {@link #disable}.
   125     *  The currently ready highest priority task will be immediately
   126     *  switched to or continue to run when the lowest order {@link #restore}
   127     *  invocation re-enables the Swi scheduler.
   128     *
   129     *  In the following example, the newly created task is not switched to
   130     *  until after the Swi_restore() call since Task scheduling is disabled
   131     *  while Swi scheduling is disabled:
   132     *
   133     *  @p(code)
   134     *  key = Swi_disable();
   135     *  // create a task of higher priority than the current task thread
   136     *  myTaskParams.priority = Task_getPri(Task_self()) + 1;
   137     *  myTask = Task_create(myTaskFunc, &myTaskParams, NULL);
   138     *  Swi_restore(key);
   139     *  @p
   140     *
   141     *  @p(html)
   142     *  <a name="hookfunc"></a>
   143     *  @p
   144     *
   145     *  @a(Hook Functions)
   146     *
   147     *  Sets of hook functions can be specified for the Swi module.  Each set
   148     *  contains these hook functions:
   149     *  @p(blist)
   150     *  -Register:  A function called before all statically-created Swis
   151     *      are initialized at runtime.
   152     *  -Create:    A function that is called when a Swi is created.
   153     *      This includes Swis that are created statically and those
   154     *      created dynamically using {@link #create}.
   155     *  -Ready:     A function that is called when any Swi becomes ready
   156     *      to run.
   157     *  -Begin:     A function that is called just prior to running a Swi.
   158     *  -End:       A function that is called just after a Swi finishes.
   159     *  -Delete:    A function that is called when a Swi is deleted at
   160     *      run-time with {@link #delete}.
   161     *  @p
   162     *  Hook functions can only be configured statically.
   163     *
   164     *  If you define more than one set of hook functions, all the functions
   165     *  of a particular type will be run when a Swi triggers that type of 
   166     *  hook.
   167     *
   168     *  @p(html)
   169     *  <B>Register Function</B>
   170     *  @p
   171     *
   172     *  The Register function is provided to allow a hook set to store its
   173     *  hookset ID.  This id can be passed to {@link #setHookContext} and
   174     *  {@link #getHookContext} to set or get hookset-specific context.  The
   175     *  Register function must be specified if the hook implementation
   176     *  needs to use {@link #setHookContext} or {@link #getHookContext}.
   177     *  The registerFxn hook function is called during system initialization
   178     *  before interrupts have been enabled. 
   179     *
   180     *  @p(code)
   181     *  Void myRegisterFxn(Int id);
   182     *  @p
   183     *
   184     *  @p(html)
   185     *  <B>Create and Delete Functions</B>
   186     *  @p
   187     *
   188     *  The create and delete functions are called whenever a Swi is created
   189     *  or deleted.  They are called with interrupts enabled (unless called 
   190     *  at boot time or from main()).
   191     *
   192     *  @p(code)
   193     *  Void myCreateFxn(Swi_Handle swi, Error_Block *eb);
   194     *  @p
   195     *
   196     *  @p(code)
   197     *  Void myDeleteFxn(Swi_Handle swi);
   198     *  @p
   199     *
   200     *  @p(html)
   201     *  <B>Ready, Begin, and End Functions</B>
   202     *  @p
   203     *
   204     *  The ready, begin and end functions are all called with interrupts
   205     *  enabled.  The ready function is called when a Swi is posted and made
   206     *  ready to run.  The begin function is called right before the function
   207     *  associated with the given Swi is run.  The end function is called
   208     *  right after this function returns.
   209     *
   210     *  @p(code)
   211     *  Void myReady(Swi_Handle swi);
   212     *  @p
   213     *
   214     *  @p(code)
   215     *  Void myBegin(Swi_Handle swi);
   216     *  @p
   217     *
   218     *  @p(code)
   219     *  Void myEnd(Swi_Handle swi);
   220     *  @p
   221     *
   222     *  @p(html)
   223     *  <h3> Calling Context </h3>
   224     *  <table border="1" cellpadding="3">
   225     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   226     *  </colgroup>
   227     *
   228     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
   229     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   230     *    <!--                                             -->
   231     *    <tr><td> {@link #create}          </td><td>   N    </td><td>   N    </td>
   232     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   233     *    <tr><td> {@link #disable}         </td><td>   Y    </td><td>   Y    </td>
   234     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   235     *    <tr><td> {@link #getTrigger}      </td><td>   Y    </td><td>   Y    </td>
   236     *  <td>   N    </td><td>   N    </td><td>   N    </td></tr>
   237     *    <tr><td> {@link #Params_init}     </td><td>   Y    </td><td>   Y    </td>
   238     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   239     *    <tr><td> {@link #restore}         </td><td>   Y    </td><td>   Y    </td>
   240     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   241     *    <tr><td> {@link #self}            </td><td>   Y    </td><td>   Y    </td>
   242     *  <td>   N    </td><td>   N    </td><td>   N    </td></tr>
   243     *
   244     *    <tr><td> {@link #andn}            </td><td>   Y    </td><td>   Y    </td>
   245     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   246     *    <tr><td> {@link #construct}       </td><td>   N    </td><td>   N    </td>
   247     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   248     *    <tr><td> {@link #dec}             </td><td>   Y    </td><td>   Y    </td>
   249     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   250     *    <tr><td> {@link #delete}          </td><td>   N    </td><td>   N    </td>
   251     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   252     *    <tr><td> {@link #destruct}        </td><td>   N    </td><td>   N    </td>
   253     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   254     *    <tr><td> {@link #getHookContext}  </td><td>   Y    </td><td>   Y    </td>
   255     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   256     *    <tr><td> {@link #getPri}          </td><td>   Y    </td><td>   Y    </td>
   257     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   258     *    <tr><td> {@link #getFunc}         </td><td>   Y    </td><td>   Y    </td>
   259     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   260     *    <tr><td> {@link #inc}             </td><td>   Y    </td><td>   Y    </td>
   261     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   262     *    <tr><td> {@link #or}              </td><td>   Y    </td><td>   Y    </td>
   263     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   264     *    <tr><td> {@link #post}            </td><td>   Y    </td><td>   Y    </td>
   265     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   266     *    <tr><td> {@link #setHookContext}  </td><td>   Y    </td><td>   Y    </td>
   267     *  <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   268     *    <tr><td colspan="6"> Definitions: <br />
   269     *       <ul>
   270     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   271     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   272     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   273     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   274     *           <ul>
   275     *             <li> In your module startup after this module is started 
   276     *  (e.g. Swi_Module_startupDone() returns TRUE). </li>
   277     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   278     *             <li> During main().</li>
   279     *             <li> During BIOS.startupFxns.</li>
   280     *           </ul>
   281     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   282     *           <ul>
   283     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   284     *             <li> In your module startup before this module is started 
   285     *  (e.g. Swi_Module_startupDone() returns FALSE).</li>
   286     *           </ul>
   287     *       </ul>
   288     *    </td></tr>
   289     *
   290     *  </table>
   291     *  @p 
   292     */
   293    
   294    @ModuleStartup      /* generate a call to Swi_Module_startup */
   295                        /* to initialize hooks in instances */
   296    @InstanceFinalize   /* generate call to Swi_Instance_finalize on delete */
   297    
   298    @InstanceInitError  /* instance init can fail, call finalize if so */
   299    
   300    
   301    module Swi
   302    {
   303    
   304        // -------- Module Constants --------
   305    
   306        // -------- Module Types --------
   307    
   308        /*! Swi function type definition. */
   309        typedef Void (*FuncPtr)(UArg, UArg);
   310    
   311        /*! 
   312         *  Swi hook set type definition.
   313         * 
   314         *  Sets of hook functions can be specified for the Swi module. 
   315         *  See {@link #hookfunc Hook Functions} for details. 
   316         */
   317        struct HookSet {
   318            Void (*registerFxn)(Int);
   319            Void (*createFxn)(Handle, Error.Block *);
   320            Void (*readyFxn)(Handle);
   321            Void (*beginFxn)(Handle);
   322            Void (*endFxn)(Handle);
   323            Void (*deleteFxn)(Handle);
   324        };
   325    
   326        metaonly struct BasicView {
   327                String          label;
   328            String          state;
   329            UInt            priority;
   330            String          fxn[];
   331            UArg            arg0;
   332            UArg            arg1;
   333            UInt            initTrigger;
   334            UInt            curTrigger;
   335            //Ptr           hookEnv[];
   336        };
   337        
   338        metaonly struct ModuleView {
   339            String      schedulerState;
   340            String      readyQMask;
   341            Ptr         currentSwi;
   342            String      currentFxn[];
   343        };
   344        
   345        /*! @_nodoc */
   346        @Facet
   347        metaonly config ViewInfo.Instance rovViewInfo = 
   348            xdc.rov.ViewInfo.create({
   349                viewMap: [
   350                    ['Basic',  {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   351                    ['Module', {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
   352                ]
   353             });
   354             
   355        // -------- Module Proxies --------
   356    
   357        // -------- Module Parameters --------
   358    
   359        /*! Logged just prior to invoking a Swi's function */
   360        config Log.Event LM_begin = {
   361            mask: Diags.USER1 | Diags.USER2,
   362            msg: "LM_begin: swi: 0x%x, func: 0x%x, preThread: %d"
   363        };
   364    
   365        /*! Logged just after returning from a Swi's function */
   366        config Log.Event LD_end = {
   367            mask: Diags.USER2,
   368            msg: "LD_end: swi: 0x%x"
   369        };
   370    
   371        /*! Logged when Swi_post() is called */
   372        config Log.Event LM_post = {
   373            mask: Diags.USER1 | Diags.USER2,
   374            msg: "LM_post: swi: 0x%x, func: 0x%x, pri: %d"
   375        };
   376    
   377        // Asserts
   378    
   379        /*! Asserted if Swi_create called & {@link ti.sysbios.BIOS#swiEnabled} false */
   380        config Assert.Id A_swiDisabled = {
   381            msg: "A_swiDisabled: Cannot create a Swi when Swi is disabled."
   382        };
   383    
   384        /*! Asserted if Swi priority is not in the range of 0 and numPriorities-1 */
   385        config Assert.Id A_badPriority = {
   386            msg: "A_badPriority: An invalid Swi priority was used."
   387        };
   388    
   389        /*! 
   390         *  Number of Swi priorities supported. Default is 16.
   391         *
   392         *  The maximum number of priorities supported is
   393         *  target-specific and depends on the number of
   394         *  bits in a UInt data type. For 6x and ARM devices
   395         *  the maximum number of priorities is therefore 32.
   396         *  For 28x, 55x, and MSP430 devices, the maximum number of
   397         *  priorities is 16.
   398         */
   399        config UInt numPriorities = 16;
   400    
   401        /*!
   402         *  const array to hold all HookSet objects.
   403         */
   404        config HookSet hooks[length] = [];
   405    
   406    
   407        // -------- Module Functions --------
   408    
   409        /*!
   410         *  ======== addHookSet ========
   411         *  addHookSet is used in a config file to add a hook set 
   412         *  
   413         *  Configures a set of hook functions for the 
   414         *  Swi module. Each set contains these hook functions:
   415         *
   416         *  @p(blist)
   417         *  -Register:  A function called before all statically-created Swis
   418         *      are initialized at runtime.
   419         *  -Create:    A function that is called when a Swi is created.
   420         *      This includes Swis that are created statically and those
   421         *      created dynamically using {@link #create}.
   422         *  -Ready:     A function that is called when any Swi becomes ready
   423         *      to run.
   424         *  -Begin:     A function that is called just prior to running a Swi.
   425         *  -End:       A function that is called just after a Swi finishes.
   426         *  -Delete:    A function that is called when a Swi is deleted at
   427         *  run-time with {@link #delete}.
   428         *  @p
   429         *
   430         *  See {@link #hookfunc Hook Functions} for more details. 
   431         *
   432         *  HookSet structure elements may be omitted, in which case those
   433         *  elements will not exist.
   434         * 
   435         *  For example, the following configuration code defines a 
   436         *  HookSet:
   437         * 
   438         *  @p(code)
   439         *  // Hook Set 1 
   440         *  Swi.addHookSet({
   441         *     registerFxn: '&myRegister1',
   442         *     createFxn:   '&myCreate1',
   443         *     readyFxn:    '&myReady1',
   444         *     beginFxn:    '&myBegin1',
   445         *     endFxn:      '&myEnd1',
   446         *     deleteFxn:   '&myDelete1'
   447         *  });
   448         *  @p
   449         *
   450         *  @param(hookSet)         structure of type HookSet
   451         */
   452        metaonly Void addHookSet(HookSet hookSet);
   453    
   454        /*!
   455         *  @_nodoc
   456         *  ======== Swi_startup ========
   457         *  Start the Swi scheduler.
   458         *  This function is called in 
   459         *  BIOS_start() after Hwi_enable().
   460         */
   461        @DirectCall
   462        Void startup();
   463    
   464        /*!
   465         *  @_nodoc
   466         *  ======== Swi_enabled ========
   467         *  Returns TRUE if the Swi scheduler is enabled.
   468         */
   469        @DirectCall
   470        Bool enabled();
   471    
   472        /*!
   473         *  ======== disable ========
   474         *  Disable Swi Scheduling.
   475         *
   476         *  {@link #disable} and {@link #restore} control Swi scheduling.
   477         *  {@link #disable} disables all other Swi functions from running until
   478         *  {@link #restore} is called. Hardware interrupts can still run.
   479         *  
   480         *  {@link #disable} and {@link #restore} allow you to ensure that
   481         *  statements that must be performed together during critical 
   482         *  processing are not preempted by other Swis or Tasks.
   483         *
   484         *  The value of the key returned is opaque to applications and is meant
   485         *  to be passed to Swi_restore().
   486         *
   487         *  In the following example, the critical section cannot be preempted 
   488         *  by any Swis.
   489         *  
   490         *  @p(code)
   491         *  key = Swi_disable();
   492         *      `critical section`
   493         *  Swi_restore(key);
   494         *  @p
   495         *  
   496         *  @a(constraints)
   497         *  Swi_disable also disables the Task scheduler.
   498         *  Swi_restore will re-enable and invoke the Task
   499         *  scheduler if the Task scheduler was not disabled prior
   500         *  to invoking Swi_disable().
   501         *  
   502         *  @b(returns)     opaque key for use with Swi_restore()
   503         */
   504        @DirectCall
   505        UInt disable();
   506    
   507        /*!
   508         *  @_nodoc
   509         *  ======== enable ========
   510         *  Enable Swi Scheduling.
   511         *
   512         *  Swi_enable unconditionally enables Swis and invokes the Swi scheduler
   513         *  if any Swis are pending.
   514         *
   515         *  @a(constraints)
   516         *  Swi_enable will also invoke the Task scheduler if the
   517         *  Task scheduler is not currently disabled.
   518         *
   519         *  The {@link #post} discussion regarding global interrupts applies 
   520         *  to this API.
   521         *
   522         */
   523        @DirectCall
   524        Void enable();
   525    
   526        /*!
   527         *  ======== restore ========
   528         *  Restore Swi Scheduling state.
   529         *
   530         *  Swi_restore restores the Swi scheduler to the locked/unlocked state 
   531         *  it was in when Swi_disable was called. If the scheduler becomes
   532         *  unlocked and Swis of sufficient priority have been made ready to
   533         *  run by any of the posting APIs, then they are run at this time.
   534         *
   535         *  Swi_disable and Swi_restore control software interrupt processing.
   536         *  Swi_disable disables all other Swi functions from running until
   537         *  Swi_restore is called. Hardware interrupts can still run.
   538         *  
   539         *  Swi_disable and Swi_restore allow you to ensure that statements that
   540         *  must be performed together during critical processing are not 
   541         *  pre-empted by other Swis.
   542         *
   543         *  In the following example, the critical section cannot be preempted
   544         *  by any Swis:
   545         *  
   546         *  @p(code)
   547         *  key = Swi_disable();
   548         *      `critical section`
   549         *  Swi_restore(key);
   550         *  @p
   551         *  
   552         *  @a(constraints)
   553         *  Swi_restore will also re-enable and invoke the Task
   554         *  scheduler if the Task scheduler was not disabled prior to 
   555         *  invoking Swi_disable().
   556         *  
   557         *  The {@link #post} discussion regarding global interrupts applies 
   558         *  to this API.
   559         *
   560         *  @param(key)     key to restore previous Swi scheduler state
   561         */
   562        @DirectCall
   563        Void restore(UInt key);
   564    
   565        /*!
   566         *  @_nodoc
   567         *  ======== restoreHwi ========
   568         *
   569         *  Restore Swi Scheduling state.
   570         *  Optimized version used by Hwi dispatcher.
   571         */
   572        @DirectCall
   573        Void restoreHwi(UInt key);
   574    
   575        /*!
   576         *  ======== self ========
   577         *  Return address of currently executing Swi object.
   578         *
   579         *  Swi_self returns the handle of the currently executing Swi.
   580         *
   581         *  For example, you can call Swi_self as follows if you want 
   582         *  a Swi to repost itself:
   583         *
   584         *  @p(code)
   585         *  Swi_post( Swi_self() );
   586         *  @p
   587         *
   588         *  @b(returns)     handle of currently running Swi
   589         */
   590        @DirectCall
   591        Handle self();
   592    
   593        /*!
   594         *  ======== getTrigger ========
   595         *  Return the trigger value of the currently executing Swi.
   596         *
   597         *  Swi_getTrigger returns the value that Swi's trigger had when the Swi
   598         *  started running. SYS/BIOS saves the trigger value internally so that
   599         *  Swi_getTrigger can access it at any point within a Swi object's 
   600         *  function.
   601         *  SYS/BIOS then automatically resets the trigger to its initial value.
   602         *  
   603         *  Swi_getTrigger should only be called within a function run by a Swi 
   604         *  object.
   605         *  
   606         *  When called from within the context of a Swi, the value returned by
   607         *  Swi_getTrigger is zero if the Swi was posted by a call to Swi_andn,
   608         *  or Swi_dec. Therefore, Swi_getTrigger provides relevant information 
   609         *  only if the Swi was posted by a call to Swi_inc, Swi_or, Swi_orHook, 
   610         *  or Swi_post.
   611         *
   612         *  For example, this API can be used within a Swi object?s function 
   613         *  to use the trigger
   614         *  value within the function. For example, if you use 
   615         *  Swi_or or Swi_inc to
   616         *  post a Swi, different trigger values can require different 
   617         *  processing.
   618         *
   619         *  @p(code)
   620         *  swicount = Swi_getTrigger();
   621         *  @p
   622         *
   623         *  @b(returns)         trigger value
   624         */
   625        @DirectCall
   626        UInt getTrigger();
   627    
   628        /*!
   629         *  @_nodoc
   630         *  ======== raisePri ========
   631         *
   632         *  Raise a Swi's priority. (Provided for legacy compatibility)
   633         *
   634         *  Swi_raisePri is used to raise the priority of the currently running 
   635         *  Swi to the priority passed in as the argument. Swi_raisePri can be used
   636         *  in conjunction with Swi_restorePri to provide a mutual exclusion
   637         *  mechanism without disabling Swis.
   638         *  
   639         *  Swi_raisePri should be called before a shared resource is accessed, and
   640         *  Swi_restorePri should be called after the access to the shared resource.
   641         *  
   642         *  A call to Swi_raisePri not followed by a Swi_restorePri keeps the Swi's
   643         *  priority for the rest of the processing at the raised level. A Swi_post 
   644         *  of the Swi posts the Swi at its original priority level.
   645         *  
   646         *  A Swi object's execution priority must range from 0 to 
   647         *  Swi_numPriorities - 1
   648         *  
   649         *  Swi_raisePri never lowers the current Swi priority.
   650         *  
   651         *  Constraints and Calling Context
   652         *  @p(blist)
   653         *  - Swi_raisePri must only be called from a Swi context.
   654         *  @p
   655         *
   656         *  @b(returns)         key for use with restorePri()
   657         */
   658        @DirectCall
   659        UInt raisePri(UInt priority);
   660    
   661        /*!
   662         *  @_nodoc
   663         *  ======== restorePri ========
   664         *
   665         *  Restore a Swi's priority. (Provided for legacy compatibility)
   666         *
   667         *  Swi_restorePri restores the priority to the Swi's priority prior to the
   668         *  Swi_raisePri call. Swi_restorePri can be used in
   669         *  conjunction with Swi_raisePri to provide a mutual exclusion mechanism
   670         *  without disabling all Swis.
   671         *
   672         *  Swi_raisePri should be called right before the shared resource is
   673         *  referenced, and Swi_restorePri should be called after the reference to
   674         *  the shared resource.
   675         *
   676         *  Constraints and Calling Context
   677         *  
   678         *  @p(blist)
   679         *  - Swi_restorePri must only be called from a Swi context.
   680         *  @p
   681         *  
   682         *  @param(key)     key returned from Swi_raisePri
   683         */
   684        @DirectCall
   685        Void restorePri(UInt key);
   686    
   687    instance:
   688    
   689        /*!
   690         *  ======== create ========
   691         *  Create a software interrupt.
   692         *
   693         *  Swi_create creates a new Swi object.
   694         *
   695         *  The following C code sets Swi parameters and 
   696         *  creates two Swi objects:
   697         *
   698         *  @p(code)
   699         *  Void main()
   700         *  {       
   701         *      Swi_Params swiParams;
   702         *  
   703         *      Swi_Params_init(&swiParams);
   704         *      swiParams.arg0 = 1;
   705         *      swiParams.arg1 = 0;
   706         *      swiParams.priority = 2;
   707         *      swiParams.trigger = 0;
   708         *  
   709         *      swi0 = Swi_create(swi0Fxn, &swiParams, NULL);
   710         *  
   711         *      swiParams.arg0 = 2;
   712         *      swiParams.arg1 = 0;
   713         *      swiParams.priority = 1;
   714         *      swiParams.trigger = 3;
   715         *  
   716         *      swi1 = Swi_create(swi1Fxn, &swiParams, NULL);
   717         *
   718         *      BIOS_start();
   719         *  }
   720         *  @p 
   721         *
   722         *  The following XDCscript statements set Swi parameters and 
   723         *  create two Swi objects:
   724         *
   725         *  @p(code)
   726         *  var Swi = xdc.useModule('ti.sysbios.knl.Swi');
   727         *  
   728         *  var swiParams = new Swi.Params();
   729         *  swiParams.arg0 = 1;
   730         *  swiParams.arg1 = 0;
   731         *  swiParams.priority = 2;
   732         *  swiParams.trigger = 0;
   733         *  Program.global.swi0 = Swi.create('&swi0Fxn', swiParams);
   734         *  
   735         *  swiParams.arg0 = 2;
   736         *  swiParams.priority = 1;
   737         *  swiParams.trigger = 3;
   738         *  Program.global.swi1 = Swi.create('&swi1Fxn', swiParams);
   739         *  @p
   740         *
   741         *  @param(fxn)     Swi Function
   742         */
   743        @DirectCall
   744        create(FuncPtr fxn);
   745        
   746    
   747    
   748        // -------- Handle Parameters --------
   749    
   750        /*! Swi function argument 0. Default is 0. */
   751        config UArg arg0 = 0;
   752    
   753        /*! Swi function argument 1. Default is 0. */
   754        config UArg arg1 = 0;
   755    
   756        /*! 
   757         *  Swi priority (0 to {@link #numPriorities} - 1). 
   758         *
   759         *  Default value of ~0 yields a Swi priority of 
   760         *  (numPriorities  - 1). 
   761         *
   762         *  Each software interrupt has a priority level. A software 
   763         *  interrupt 
   764         *  preempts any lower-priority software interrupt currently executing.
   765         *  When multiple Swis of the same priority level have been posted, 
   766         *  their respective Swi functions are executed in the order the Swis 
   767         *  were posted.
   768         */
   769        config UInt priority = ~0;
   770    
   771        /*! 
   772         *  Initial Swi trigger value. 
   773         *
   774         *  Default is 0. 
   775         *
   776         *  Each Swi object has a "trigger"
   777         *  used either to determine whether to post the Swi or as a value
   778         *  that can be evaluated within the Swi's function. The {@link #andn} and 
   779         *  {@link #dec} functions
   780         *  post the Swi if the trigger value transitions to 0. The 
   781         *  {@link #or} and 
   782         *  {@link #inc} functions
   783         *  also modify the trigger value. ({@link #or} sets bits, and {@link #andn}
   784         *  clears bits.)
   785         */
   786        config UInt trigger = 0;
   787    
   788        // -------- Handle Functions --------
   789    
   790        /*!
   791         *  ======== andn ========
   792         *  Clear bits in Swi's trigger; post if trigger becomes 0.
   793         *
   794         *  Swi_andn is used to conditionally post a software interrupt. 
   795         *  Swi_andn clears the bits specified by a mask from Swi's internal 
   796         *  trigger. If the Swi's trigger becomes 0, Swi_andn posts the Swi. 
   797         *  The bitwise logical operation performed is:
   798         *  
   799         *  @p(code)
   800         *  trigger = trigger AND (NOT MASK)
   801         *  @p
   802         *  
   803         *  If multiple conditions that all be met before a 
   804         *  Swi can run, you should use a different bit in the trigger for 
   805         *  each condition. When a condition is met, clear the bit for that 
   806         *  condition.
   807         *
   808         *  For example, if two events must happen before a Swi is to be
   809         *  triggered, the initial trigger value of the Swi can be 3 (binary 0011).
   810         *  One call to Swi_andn can have a mask value of 2 (binary 0010), and
   811         *  another call to Swi_andn can have a mask value of 1 (binary 0001).
   812         *  After both calls have been made, the trigger value will be 0.
   813         *
   814         *  @p(code)
   815         *  Swi_andn(swi0, 2);  // clear bit 1
   816         *  Swi_andn(swi0, 1);  // clear bit 0
   817         *  @p
   818         *  
   819         *  Swi_andn results in a context switch if the Swi's trigger becomes 
   820         *  zero and the Swi has higher priority than the currently executing 
   821         *  thread.
   822         *  
   823         *  You specify a Swi's initial trigger value at Swi creation time. 
   824         *  The trigger value is automatically reset when the Swi executes.
   825         *  
   826         *  @a(constraints)
   827         *  The {@link #post} discussion regarding global interrupts applies 
   828         *  to this API.
   829         *
   830         *  @param(mask)    inverse value to be ANDed
   831         */
   832        @DirectCall
   833        Void andn(UInt mask);
   834    
   835        /*!
   836         *  ======== dec ========
   837         *  Decrement Swi's trigger value; post if trigger becomes 0.
   838         *
   839         *  Swi_dec is used to conditionally post a software interrupt. Swi_dec
   840         *  decrements the value in Swi's trigger by 1. If Swi's trigger value
   841         *  becomes 0, Swi_dec posts the Swi. You can increment a trigger value
   842         *  by using Swi_inc, which always posts the Swi.
   843         *
   844         *  For example, you would use Swi_dec if you wanted to post a Swi after
   845         *  a number of occurrences of an event.
   846         *
   847         *  @p(code)
   848         *  // swi0's trigger is configured to start at 3
   849         *  Swi_dec(swi0);      // trigger = 2
   850         *  Swi_dec(swi0);      // trigger = 1
   851         *  Swi_dec(swi0);      // trigger = 0
   852         *  @p
   853         *
   854         *  You specify a Swi's initial trigger value at Swi creation time. The 
   855         *  trigger value is automatically reset when the Swi executes.
   856         *
   857         *  Swi_dec results in a context switch if the Swi's trigger becomes
   858         *  zero and the Swi has higher priority than the currently executing 
   859         *  thread.
   860         *
   861         *  @a(constraints)
   862         *  The {@link #post} discussion regarding global interrupts applies 
   863         *  to this API.
   864         */
   865        @DirectCall
   866        Void dec();
   867    
   868        /*!
   869         *  ======== getHookContext ========
   870         *  Get hook instance's context pointer for a Swi.
   871         *
   872         *  For example, this C code gets the HookContext, prints it,
   873         *  and sets a new value for the HookContext.
   874         *
   875         *  @p(code)
   876         *  Ptr pEnv;
   877         *  Swi_Handle mySwi;
   878         *  Int myHookSetId1;
   879         * 
   880         *  pEnv = Swi_getHookContext(swi, myHookSetId1);
   881         * 
   882         *  System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n", 
   883         *                (ULong)pEnv, (ULong)Timestamp_get32());
   884         * 
   885         *  Swi_setHookContext(swi, myHookSetId1, (Ptr)0xc0de1);
   886         *  @p
   887         *
   888         *  See {@link #hookfunc Hook Functions} for more details. 
   889         *
   890         *  @b(returns)     hook instance's context pointer for Swi
   891         */
   892        @DirectCall
   893        Ptr getHookContext(Int id);
   894    
   895        /*!
   896         *  ======== setHookContext ========
   897         *  Set hook instance's context for a swi.
   898         *
   899         *  For example, this C code gets the HookContext, prints it,
   900         *  and sets a new value for the HookContext.
   901         *
   902         *  @p(code)
   903         *  Ptr pEnv;
   904         *  Swi_Handle mySwi;
   905         *  Int myHookSetId1;
   906         * 
   907         *  pEnv = Swi_getHookContext(swi, myHookSetId1);
   908         * 
   909         *  System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n", 
   910         *                (ULong)pEnv, (ULong)Timestamp_get32());
   911         * 
   912         *  Swi_setHookContext(swi, myHookSetId1, (Ptr)0xc0de1);
   913         *  @p
   914         *
   915         *  See {@link #hookfunc Hook Functions} for more details. 
   916         *
   917         *  @param(id)              hook instance's ID
   918         *  @param(hookContext)     value to write to context
   919         */
   920        @DirectCall
   921        Void setHookContext(Int id, Ptr hookContext);
   922    
   923        /*!
   924         *  ======== getPri ========
   925         *  Return a Swi's priority.
   926         *
   927         *  Swi_getPri returns the priority of the Swi passed in as the
   928         *  argument.
   929         *
   930         *  @b(returns)     Priority of Swi
   931         */
   932        @DirectCall
   933        UInt getPri();
   934        
   935        /*!
   936         *  ======== getFunc ========
   937         *  Get Swi function and arguments
   938         *
   939         *  If either arg0 or arg1 is NULL, then the corresponding argument is not
   940         *  returned.
   941         *
   942         *  @param(arg0)     pointer for returning Swi's first function argument
   943         *  @param(arg1)     pointer for returning Swi's second function argument
   944         *
   945         *  @b(returns)     Swi function
   946         */
   947        @DirectCall
   948        FuncPtr getFunc(UArg *arg0, UArg *arg1);
   949    
   950        /*!
   951         *  ======== inc ========
   952         *  Increment Swi's trigger value and post the Swi.
   953         *
   954         *  Swi_inc increments the value in Swi's trigger by 1 and posts the Swi
   955         *  regardless of the resulting trigger value. You can decrement a 
   956         *  trigger value using Swi_dec, which only posts the Swi if the 
   957         *  trigger value is 0.
   958         *
   959         *  If a Swi is posted several times before it has a chance to begin
   960         *  executing (i.e. when Hwis or higher priority Swis are running) the Swi
   961         *  only runs one time. If this situation occurs, you can use Swi_inc to 
   962         *  post the Swi. Within the Swi's function, you could then use 
   963         *  Swi_getTrigger to find out how many times this Swi has been posted 
   964         *  since the last time it was executed.
   965         *
   966         *  You specify a Swi's initial trigger value at Swi creation time.
   967         *  The trigger value is automatically reset when the Swi executes. 
   968         *  To get the trigger value, use Swi_getTrigger.
   969         *
   970         *  Swi_inc results in a context switch if the Swi is higher priority 
   971         *  than the currently executing thread.
   972         *
   973         *  @a(constraints)
   974         *  The {@link #post} discussion regarding global interrupts applies 
   975         *  to this API.
   976         */
   977        @DirectCall
   978        Void inc();
   979    
   980        /*!
   981         *  ======== or ========
   982         *  Or mask with value contained in Swi's trigger and post the
   983         *  Swi.
   984         *
   985         *  Swi_or is used to post a software interrupt. Swi_or sets the bits 
   986         *  specified by a mask in Swi's trigger. Swi_or posts the Swi 
   987         *  regardless of the resulting trigger value. The bitwise logical 
   988         *  operation performed on the trigger value is:
   989         *
   990         *  @p(code)
   991         *  trigger = trigger OR mask
   992         *  @p
   993         *
   994         *  You specify a Swi's initial trigger value at Swi creation time. 
   995         *  The trigger value is automatically reset when the Swi executes. 
   996         *  To get the trigger value, use Swi_getTrigger.
   997         *
   998         *  For example, you might use Swi_or to post a Swi if any of three 
   999         *  events should cause a Swi to be executed, but you want the Swi's 
  1000         *  function to be able to tell which event occurred. Each event 
  1001         *  would correspond to a different bit in the trigger.
  1002         *
  1003         *  Swi_or results in a context switch if the Swi is higher priority 
  1004         *  than the currently executing thread.
  1005         *
  1006         *  @a(constraints)
  1007         *  The {@link #post} discussion regarding global interrupts applies 
  1008         *  to this API.
  1009         *
  1010         *  @param(mask)    value to be ORed
  1011         */
  1012        @DirectCall
  1013        Void or(UInt mask);
  1014    
  1015        /*!
  1016         *  ======== post ========
  1017         *  Unconditionally post a software interrupt.
  1018         *
  1019         *  Swi_post is used to post a software interrupt regardless of the 
  1020         *  trigger value. No change is made to the Swi object's trigger value.
  1021         *
  1022         *  Swi_post results in a context switch if the Swi is higher priority 
  1023         *  than the currently executing thread.
  1024         *
  1025         *  @a(constraints)
  1026         *  Swis are ALWAYS run with interrupts enabled.
  1027         *  If a Swi is made ready to run as a consequence of this
  1028         *  API, interrupts will be globally enabled while the Swi function
  1029         *  executes, regardless of the prior globally enabled/disabled 
  1030         *  state of interrupts. 
  1031         *  Upon return from this API, the global interrupt enabled/disabled state
  1032         *  is restored to its previous value.
  1033         */
  1034        @DirectCall
  1035        Void post();
  1036    
  1037    internal:   /* not for client use */ 
  1038    
  1039        /* 
  1040         * Swi and Task module function pointers. 
  1041         * Used to decouple Hwi from Swi and Task when 
  1042         * dispatcherSwiSupport or
  1043         * dispatcherTaskSupport is false.
  1044         */
  1045        config UInt (*taskDisable)();
  1046        config Void (*taskRestore)(UInt);
  1047    
  1048        /*
  1049         *  ======== schedule ========
  1050         *  Find highest priority Swi and invoke it.
  1051         *  Called by Swi_restore() which is used
  1052         *  in a task context.
  1053         *
  1054         *  Must be called with interrupts disabled.
  1055         */
  1056        Void schedule();
  1057    
  1058        /*
  1059         *  ======== run ========
  1060         *  Set up and run Swi.
  1061         *  Enter with Hwi's disabled
  1062         *  Exits with Hwi's enabled
  1063         */
  1064        Void run(Object *swi);
  1065    
  1066        /*
  1067         *  ======== postInit ========
  1068         *  finish initializing static and dynamic Swis
  1069         */
  1070        Int postInit(Object *swi, Error.Block *eb);
  1071    
  1072        /*!
  1073         *  @_nodoc
  1074         *  Number of statically constructed Swi objects.
  1075         *  Shouldn't be set directly by the user's
  1076         *  config (it gets set by instance$static$init).
  1077         */
  1078        config UInt numConstructedSwis = 0;
  1079    
  1080        struct Instance_State {
  1081            Queue.Elem      qElem;      // Link within readyQ
  1082            FuncPtr         fxn;        // Swi function
  1083            UArg            arg0;       // Swi function 1st arg
  1084            UArg            arg1;       // Swi function 2nd arg
  1085            UInt            priority;   // Swi priority
  1086            UInt            mask;       // handy curSet orMask (= 1 << priority)
  1087            Bool            posted;     // TRUE = Swi already posted.
  1088            UInt            initTrigger;// Initial Trigger value
  1089            UInt            trigger;    // Swi Trigger
  1090            Queue.Handle    readyQ;     // This Swi's readyQ
  1091            Ptr             hookEnv[];
  1092        };
  1093    
  1094        struct Module_State {
  1095            Bool            locked;     // TRUE = Swi scheduler locked
  1096            UInt            curSet;     // Bitmask reflects readyQ states
  1097            UInt            curTrigger; // current Swi's on-entry trigger
  1098            Handle          curSwi;     // current Swi instance
  1099            Queue.Handle    curQ;       // current Swi's readyQ,
  1100                                        // when all posted Swis have run
  1101            Queue.Object    readyQ[];   // Swi ready queues
  1102            Handle          constructedSwis[]; // array of statically 
  1103                                        // constructed Swis
  1104        };
  1105    }
  1106    /*
  1107     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,451; 2-2-2011 15:07:14; /db/vtree/library/trees/avala/avala-o27x/src/ xlibrary
  1108    
  1109     */
  1110