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