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