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