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    @ModuleStartup      /* generate a call to Swi_Module_startup */
   275                        /* to initialize hooks in instances */
   276    @InstanceFinalize   /* generate call to Swi_Instance_finalize on delete */
   277    
   278    @InstanceInitError  /* instance init can fail, call finalize if so */
   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        @DirectCall
   503        Void startup();
   504    
   505        /*!
   506         *  ======== Swi_enabled ========
   507         *  Returns TRUE if the Swi scheduler is enabled
   508         *
   509         *  @_nodoc
   510         */
   511        @DirectCall
   512        Bool enabled();
   513    
   514        /*!
   515         *  @_nodoc
   516         *  ======== unlockSched ========
   517         *  Force a Swi scheduler unlock. Used by Core_atExit() & Core_hwiFunc()
   518         *  to unlock Swi scheduler before exiting.
   519         *
   520         *  This function should only be called after a Hwi_disable() has entered
   521         *  the Inter-core gate and disabled interrupts locally.
   522         */
   523        @DirectCall
   524        Void unlockSched();
   525    
   526        /*!
   527         *  ======== disable ========
   528         *  Disable Swi Scheduling
   529         *
   530         *  Swi_disable() and {@link #restore Swi_restore()} control Swi
   531         *  scheduling.
   532         *  Swi_disable() disables all Swi functions from running until
   533         *  Swi_restore() is called. Hardware interrupts can still run.
   534         *
   535         *  Swi_disable() and Swi_restore() allow you to ensure that
   536         *  statements that must be performed together during critical
   537         *  processing are not preempted by other Swis or Tasks.
   538         *
   539         *  The value of the key returned by Swi_disable() is opaque to
   540         *  applications and is meant to be passed to Swi_restore().
   541         *
   542         *  In the following example, the critical section cannot be preempted
   543         *  by any Swis. Nor can it be pre-empted by other Tasks.
   544         *
   545         *  @p(code)
   546         *  key = Swi_disable();
   547         *      `critical section`
   548         *  Swi_restore(key);
   549         *  @p
   550         *
   551         *  @a(Side Effects of Disabling the Swi Scheduler)
   552         *
   553         *  {@link #disable Swi_disable()}, in addition to disabling Swis from
   554         *  pre-empting the  code which follows its invocation, has
   555         *  the side effect of also disabling the Task scheduler.
   556         *  Consequently, Task pre-emption and blocking is also disabled while
   557         *  the Swi scheduler is disabled.
   558         *  When {@link #restore Swi_restore()} is subsequently called, it will
   559         *  re-enable and invoke the Task scheduler if the Task scheduler was not
   560         *  already disabled prior to invoking Swi_disable().
   561         *
   562         *  The following code snippet:
   563         *  @p(code)
   564         *  key = Swi_disable();
   565         *  ...
   566         *  Swi_post(swi);        <-- 'swi' will not run
   567         *  ...
   568         *  Swi_restore(key);     <-- 'swi' runs now
   569         *  @p
   570         *  Should be thought of as equivalent to this:
   571         *  @p(code)
   572         *  tasKey = Task_disable();
   573         *  swiKey = Swi_disable();
   574         *  ...
   575         *  Swi_post(swi);        <-- 'swi' will not run
   576         *  ...
   577         *  Swi_restore(swiKey);  <-- 'swi' runs now
   578         *  Task_restore(taskKey);
   579         *  @p
   580         *
   581         *  In the following example, even though the Semaphore_post() call
   582         *  unblocks a task of higher priority, the local task is not pre-empted
   583         *  until after the Swi_restore() call is made:
   584         *
   585         *  @p(code)
   586         *  key = Swi_disable();
   587         *  ...
   588         *  Swi_post(swi);        <-- 'swi' will not run
   589         *  Semaphore_post(sem);  <-- readys a task of higher priority than current task
   590         *  ...
   591         *  Swi_restore(key);     <-- 'swi' runs now, then current task is pre-empted.
   592         *  @p
   593         *
   594         *  @p(html)
   595         *  <B>
   596         *  A common mistake that users make is to invoke a blocking
   597         *  API such as Semaphore_pend() after calling Swi_disable().
   598         *  This results in unrecoverable damage to the Task scheduler's internal
   599         *  state and will lead to unpredictable and usually catastrophic behavior:
   600         *  </B>
   601         *  @p
   602         *
   603         *  @p(code)
   604         *  key = Swi_disable();
   605         *  ...
   606         *  Semaphore_pend(sem, BIOS_WAIT_FOREVER);  <-- !!! DO NOT DO THIS !!!
   607         *  ...
   608         *  Swi_restore(key);   <-- !!! System failure guaranteed to follow !!!
   609         *  @p
   610         *
   611         *  @p(html)
   612         *  <B>
   613         *  A more subtle variant of the above problem occurs when an API such
   614         *  as GateMutex_enter() is invoked directly or indirectly while the
   615         *  Swi scheduler
   616         *  is disabled. If the GateMutex has already been entered by another thread,
   617         *  the current thread should block until the other thread calls
   618         *  GateMutex_leave().
   619         *  But because the Task scheduler is disabled, the local thread returns
   620         *  immediately from GateMutex_enter(), just as though it successfully
   621         *  entered the GateMutex! This usually leads to catastrophic results.
   622         *  </B>
   623         *  @p
   624         *
   625         *  @b(returns)     opaque key for use with Swi_restore()
   626         */
   627        @DirectCall
   628        UInt disable();
   629    
   630        /*!
   631         *  ======== enable ========
   632         *  Enable Swi Scheduling
   633         *
   634         *  @_nodoc
   635         *  Swi_enable unconditionally enables Swis and invokes the Swi scheduler
   636         *  if any Swis are pending.
   637         *
   638         *  @a(constraints)
   639         *  Swi_enable will also invoke the Task scheduler if the
   640         *  Task scheduler is not currently disabled.
   641         *
   642         *  The {@link #post} discussion regarding global interrupts also applies
   643         *  to this API.
   644         *
   645         */
   646        @DirectCall
   647        Void enable();
   648    
   649        /*!
   650         *  ======== restore ========
   651         *  Restore Swi Scheduling state
   652         *
   653         *  Swi_restore restores the Swi scheduler to the locked/unlocked state
   654         *  it was in when Swi_disable was called. If the scheduler becomes
   655         *  unlocked and Swis of sufficient priority have been made ready to
   656         *  run by any of the posting APIs, then they are run at this time.
   657         *
   658         *  Swi_disable and Swi_restore control software interrupt processing.
   659         *  Swi_disable disables all other Swi functions from running until
   660         *  Swi_restore is called. Hardware interrupts can still run.
   661         *
   662         *  Swi_disable and Swi_restore allow you to ensure that statements that
   663         *  must be performed together during critical processing are not
   664         *  pre-empted by other Swis.
   665         *
   666         *  In the following example, the critical section cannot be preempted
   667         *  by any Swis. Nor can it be pre-empted by other Tasks.
   668         *
   669         *  @p(code)
   670         *  key = Swi_disable();
   671         *      `critical section`
   672         *  Swi_restore(key);
   673         *  @p
   674         *
   675         *  Read the discussion of the side effects of disabling the Swi
   676         *  scheduler {@link #disable here}.
   677         *
   678         *  @a(constraints)
   679         *  Swi_restore will also re-enable and invoke the Task
   680         *  scheduler if the Task scheduler was not disabled prior to
   681         *  invoking Swi_disable().
   682         *
   683         *  The {@link #post} discussion regarding global interrupts applies
   684         *  to this API.
   685         *
   686         *  @param(key)     key to restore previous Swi scheduler state
   687         */
   688        @DirectCall
   689        Void restore(UInt key);
   690    
   691        /*!
   692         *  ======== restoreHwi ========
   693         *  Restore Swi Scheduling state
   694         *
   695         *  @_nodoc
   696         *  Optimized version used by Hwi dispatcher.
   697         */
   698        @DirectCall
   699        Void restoreHwi(UInt key);
   700    
   701        /*!
   702         *  ======== self ========
   703         *  Return address of currently executing Swi object
   704         *
   705         *  Swi_self returns the handle of the currently executing Swi.
   706         *
   707         *  For example, you can call Swi_self as follows if you want
   708         *  a Swi to repost itself:
   709         *
   710         *  @p(code)
   711         *  Swi_post( Swi_self() );
   712         *  @p
   713         *
   714         *  @b(returns)     handle of currently running Swi
   715         */
   716        @DirectCall
   717        Handle self();
   718    
   719        /*!
   720         *  ======== getTrigger ========
   721         *  Return the trigger value of the currently executing Swi
   722         *
   723         *  Swi_getTrigger returns the value that Swi's trigger had when the Swi
   724         *  started running. SYS/BIOS saves the trigger value internally, so that
   725         *  Swi_getTrigger can access it at any point within a Swi object's
   726         *  function, and then automatically resets the trigger to its initial
   727         *  value.
   728         *
   729         *  Swi_getTrigger should only be called within a function run by a Swi
   730         *  object.
   731         *
   732         *  When called from within the context of a Swi, the value returned by
   733         *  Swi_getTrigger is zero if the Swi was posted by a call to Swi_andn,
   734         *  or Swi_dec. Therefore, Swi_getTrigger provides relevant information
   735         *  only if the Swi was posted by a call to Swi_inc, Swi_or, Swi_orHook,
   736         *  or Swi_post.
   737         *
   738         *  This API is called within a Swi object's function to use the trigger
   739         *  value that caused the function to run. For example, if you use
   740         *  Swi_or or Swi_inc to post a Swi, different trigger values can require
   741         *  different processing.
   742         *
   743         *  @p(code)
   744         *  swicount = Swi_getTrigger();
   745         *  @p
   746         *
   747         *  @b(returns)         trigger value
   748         */
   749        @DirectCall
   750        UInt getTrigger();
   751    
   752        /*!
   753         *  ======== raisePri ========
   754         *  Raise a Swi's priority
   755         *
   756         *  @_nodoc
   757         *  This function is provided for legacy compatibility.
   758         *
   759         *  Swi_raisePri is used to raise the priority of the currently running
   760         *  Swi to the priority passed in as the argument. Swi_raisePri can be
   761         *  used in conjunction with Swi_restorePri to provide a mutual exclusion
   762         *  mechanism without disabling Swis.
   763         *
   764         *  Swi_raisePri should be called before a shared resource is accessed,
   765         *  and Swi_restorePri should be called after the access to the shared
   766         *  resource.
   767         *
   768         *  A call to Swi_raisePri not followed by a Swi_restorePri keeps the
   769         *  Swi's priority for the rest of the processing at the raised level. A
   770         *  Swi_post of the Swi posts the Swi at its original priority level.
   771         *
   772         *  A Swi object's execution priority must range from 0 to
   773         *  Swi_numPriorities - 1
   774         *
   775         *  Swi_raisePri never lowers the current Swi priority.
   776         *
   777         *  Constraints and Calling Context
   778         *  @p(blist)
   779         *  - Swi_raisePri must only be called from a Swi context.
   780         *  @p
   781         *
   782         *  @b(returns)         key for use with restorePri()
   783         */
   784        @DirectCall
   785        UInt raisePri(UInt priority);
   786    
   787        /*!
   788         *  ======== restorePri ========
   789         *  Restore a Swi's priority
   790         *
   791         *  @_nodoc
   792         *  This function is provided for legacy compatibility.
   793         *
   794         *  Swi_restorePri restores the priority to the Swi's priority prior to the
   795         *  Swi_raisePri call. Swi_restorePri can be used in
   796         *  conjunction with Swi_raisePri to provide a mutual exclusion mechanism
   797         *  without disabling all Swis.
   798         *
   799         *  Swi_raisePri should be called right before the shared resource is
   800         *  referenced, and Swi_restorePri should be called after the reference to
   801         *  the shared resource.
   802         *
   803         *  Constraints and Calling Context
   804         *
   805         *  @p(blist)
   806         *  - Swi_restorePri must only be called from a Swi context.
   807         *  @p
   808         *
   809         *  @param(key)     key returned from Swi_raisePri
   810         */
   811        @DirectCall
   812        Void restorePri(UInt key);
   813    
   814    instance:
   815    
   816        /*!
   817         *  ======== create ========
   818         *  Create a software interrupt
   819         *
   820         *  Swi_create creates a new Swi object.
   821         *
   822         *  The following C code sets Swi parameters and
   823         *  creates two Swi objects:
   824         *
   825         *  @p(code)
   826         *  Void main()
   827         *  {
   828         *      Swi_Params swiParams;
   829         *
   830         *      Swi_Params_init(&swiParams);
   831         *      swiParams.arg0 = 1;
   832         *      swiParams.arg1 = 0;
   833         *      swiParams.priority = 2;
   834         *      swiParams.trigger = 0;
   835         *
   836         *      swi0 = Swi_create(swi0Fxn, &swiParams, NULL);
   837         *
   838         *      swiParams.arg0 = 2;
   839         *      swiParams.arg1 = 0;
   840         *      swiParams.priority = 1;
   841         *      swiParams.trigger = 3;
   842         *
   843         *      swi1 = Swi_create(swi1Fxn, &swiParams, NULL);
   844         *
   845         *      BIOS_start();
   846         *  }
   847         *  @p
   848         *
   849         *  The following XDCscript statements set Swi parameters and
   850         *  create two Swi objects:
   851         *
   852         *  @p(code)
   853         *  var Swi = xdc.useModule('ti.sysbios.knl.Swi');
   854         *
   855         *  var swiParams = new Swi.Params();
   856         *  swiParams.arg0 = 1;
   857         *  swiParams.arg1 = 0;
   858         *  swiParams.priority = 2;
   859         *  swiParams.trigger = 0;
   860         *  Program.global.swi0 = Swi.create('&swi0Fxn', swiParams);
   861         *
   862         *  swiParams.arg0 = 2;
   863         *  swiParams.priority = 1;
   864         *  swiParams.trigger = 3;
   865         *  Program.global.swi1 = Swi.create('&swi1Fxn', swiParams);
   866         *  @p
   867         *
   868         *  @param(swiFxn)     Swi Function
   869         */
   870        @DirectCall
   871        create(FuncPtr swiFxn);
   872    
   873        // -------- Handle Parameters --------
   874    
   875        /*!
   876         *  ======== arg0 ========
   877         *  Swi function argument 0
   878         *
   879         *  The default value of this optional parameter is 0.
   880         *
   881         *  @see #FuncPtr
   882         */
   883        config UArg arg0 = 0;
   884    
   885        /*!
   886         *  ======== arg1 ========
   887         *  Swi function argument 1
   888         *
   889         *  The default value of this optional parameter is 0.
   890         *
   891         *  @see #FuncPtr
   892         */
   893        config UArg arg1 = 0;
   894    
   895        /*!
   896         *  ======== priority ========
   897         *  Swi priority
   898         *
   899         *  Each software interrupt has a priority level, 0 to
   900         *  ({@link #numPriorities} - 1). A software interrupt
   901         *  preempts any lower-priority software interrupt currently executing.
   902         *  When multiple Swis of the same priority level have been posted,
   903         *  their respective Swi functions are executed in the order the Swis
   904         *  were posted.
   905         *
   906         *  The default value of this optional parameter is ~0, which yields a
   907         *  Swi with the highest priority: ({@link #numPriorities} - 1).
   908         */
   909        config UInt priority = ~0;
   910    
   911        /*!
   912         *  ======== trigger ========
   913         *  Initial Swi trigger value
   914         *
   915         *  The default value of this optional parameter is 0.
   916         *
   917         *  Each Swi object has a "trigger" used either to determine whether to
   918         *  post the Swi or as a value that can be evaluated within the Swi's
   919         *  function.
   920         *
   921         *  The {@link #andn} and {@link #dec} functions post the Swi
   922         *  if the trigger value transitions to 0. The {@link #or} and
   923         *  {@link #inc} functions also modify the trigger value. ({@link #or}
   924         *  sets bits, and {@link #andn} clears bits.)
   925         */
   926        config UInt trigger = 0;
   927    
   928        // -------- Handle Functions --------
   929    
   930        /*!
   931         *  ======== andn ========
   932         *  Clear bits in Swi's trigger; post if trigger becomes 0
   933         *
   934         *  Swi_andn is used to conditionally post a software interrupt.
   935         *  Swi_andn clears the bits specified by a mask from Swi's internal
   936         *  trigger. If the Swi's trigger becomes 0, Swi_andn posts the Swi.
   937         *  The bitwise logical operation performed is:
   938         *
   939         *  @p(code)
   940         *  trigger = trigger AND (NOT MASK)
   941         *  @p
   942         *
   943         *  If multiple conditions that all be met before a
   944         *  Swi can run, you should use a different bit in the trigger for
   945         *  each condition. When a condition is met, clear the bit for that
   946         *  condition.
   947         *
   948         *  For example, if two events must happen before a Swi is to be
   949         *  triggered, the initial trigger value of the Swi can be 3 (binary 0011).
   950         *  One call to Swi_andn can have a mask value of 2 (binary 0010), and
   951         *  another call to Swi_andn can have a mask value of 1 (binary 0001).
   952         *  After both calls have been made, the trigger value will be 0.
   953         *
   954         *  @p(code)
   955         *  Swi_andn(swi0, 2);  // clear bit 1
   956         *  Swi_andn(swi0, 1);  // clear bit 0
   957         *  @p
   958         *
   959         *  Swi_andn results in a context switch if the Swi's trigger becomes
   960         *  zero and the Swi has higher priority than the currently executing
   961         *  thread.
   962         *
   963         *  You specify a Swi's initial trigger value at Swi creation time.
   964         *  The trigger value is automatically reset when the Swi executes.
   965         *
   966         *  @a(constraints)
   967         *  The {@link #post} discussion regarding global interrupts applies
   968         *  to this API.
   969         *
   970         *  @param(mask)    inverse value to be ANDed
   971         */
   972        @DirectCall
   973        Void andn(UInt mask);
   974    
   975        /*!
   976         *  ======== dec ========
   977         *  Decrement Swi's trigger value; post if trigger becomes 0
   978         *
   979         *  Swi_dec is used to conditionally post a software interrupt. Swi_dec
   980         *  decrements the value in Swi's trigger by 1. If Swi's trigger value
   981         *  becomes 0, Swi_dec posts the Swi. You can increment a trigger value
   982         *  by using Swi_inc, which always posts the Swi.
   983         *
   984         *  For example, you would use Swi_dec if you wanted to post a Swi after
   985         *  a number of occurrences of an event.
   986         *
   987         *  @p(code)
   988         *  // swi0's trigger is configured to start at 3
   989         *  Swi_dec(swi0);      // trigger = 2
   990         *  Swi_dec(swi0);      // trigger = 1
   991         *  Swi_dec(swi0);      // trigger = 0
   992         *  @p
   993         *
   994         *  You specify a Swi's initial trigger value at Swi creation time. The
   995         *  trigger value is automatically reset when the Swi executes.
   996         *
   997         *  Swi_dec results in a context switch if the Swi's trigger becomes
   998         *  zero and the Swi has higher priority than the currently executing
   999         *  thread.
  1000         *
  1001         *  @a(constraints)
  1002         *  The {@link #post} discussion regarding global interrupts applies
  1003         *  to this API.
  1004         */
  1005        @DirectCall
  1006        Void dec();
  1007    
  1008        /*!
  1009         *  ======== getHookContext ========
  1010         *  Get hook instance's context pointer for a Swi
  1011         *
  1012         *  For example, this C code gets the HookContext, prints it,
  1013         *  and sets a new value for the HookContext.
  1014         *
  1015         *  @p(code)
  1016         *  Ptr pEnv;
  1017         *  Swi_Handle mySwi;
  1018         *  Int myHookSetId1;
  1019         *
  1020         *  pEnv = Swi_getHookContext(swi, myHookSetId1);
  1021         *
  1022         *  System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
  1023         *                (ULong)pEnv, (ULong)Timestamp_get32());
  1024         *
  1025         *  Swi_setHookContext(swi, myHookSetId1, (Ptr)0xc0de1);
  1026         *  @p
  1027         *
  1028         *  See {@link #hookfunc Hook Functions} for more details.
  1029         *
  1030         *  @b(returns)     hook instance's context pointer for Swi
  1031         */
  1032        @DirectCall
  1033        Ptr getHookContext(Int id);
  1034    
  1035        /*!
  1036         *  ======== setHookContext ========
  1037         *  Set hook instance's context for a swi
  1038         *
  1039         *  For example, this C code gets the HookContext, prints it,
  1040         *  and sets a new value for the HookContext.
  1041         *
  1042         *  @p(code)
  1043         *  Ptr pEnv;
  1044         *  Swi_Handle mySwi;
  1045         *  Int myHookSetId1;
  1046         *
  1047         *  pEnv = Swi_getHookContext(swi, myHookSetId1);
  1048         *
  1049         *  System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
  1050         *                (ULong)pEnv, (ULong)Timestamp_get32());
  1051         *
  1052         *  Swi_setHookContext(swi, myHookSetId1, (Ptr)0xc0de1);
  1053         *  @p
  1054         *
  1055         *  See {@link #hookfunc Hook Functions} for more details.
  1056         *
  1057         *  @param(id)              hook instance's ID
  1058         *  @param(hookContext)     value to write to context
  1059         */
  1060        @DirectCall
  1061        Void setHookContext(Int id, Ptr hookContext);
  1062    
  1063        /*!
  1064         *  ======== getPri ========
  1065         *  Return a Swi's priority
  1066         *
  1067         *  Swi_getPri returns the priority of the Swi passed in as the
  1068         *  argument.
  1069         *
  1070         *  @b(returns)     Priority of Swi
  1071         */
  1072        @DirectCall
  1073        UInt getPri();
  1074    
  1075        /*!
  1076         *  ======== getFunc ========
  1077         *  Get Swi function and arguments
  1078         *
  1079         *  If either arg0 or arg1 is NULL, then the corresponding argument is not
  1080         *  returned.
  1081         *
  1082         *  @related {@link #getAttrs Swi_getAttrs()}
  1083         *
  1084         *  @param(arg0)     pointer for returning Swi's first function argument
  1085         *  @param(arg1)     pointer for returning Swi's second function argument
  1086         *
  1087         *  @b(returns)     Swi function
  1088         */
  1089        @DirectCall
  1090        FuncPtr getFunc(UArg *arg0, UArg *arg1);
  1091    
  1092        /*!
  1093         *  ======== getAttrs ========
  1094         *  Retrieve attributes of an existing Swi object.
  1095         *
  1096         *  The 'handle' argument specifies the address of the Swi object whose
  1097         *  attributes are to be retrieved.
  1098         *
  1099         *  The 'swiFxn' argument is the address of a function pointer where the
  1100         *  the Swi function address is to be written to. If NULL is passed for
  1101         *  'swiFxn', no attempt is made to return the Swi function.
  1102         *
  1103         *  The 'params' argument is a pointer to a Swi_Params structure that will
  1104         *  contain the retrieved Swi attributes.
  1105         *
  1106         *  @related {@link #setAttrs Swi_setAttrs()}
  1107         *
  1108         *  @param(swiFxn)     pointer to a Swi_FuncPtr
  1109         *  @param(params)     pointer for returning Swi's Params
  1110         */
  1111        @DirectCall
  1112        Void getAttrs(FuncPtr *swiFxn, Params *params);
  1113    
  1114        /*!
  1115         *  ======== setAttrs ========
  1116         *  Set the attributes of an existing Swi object.
  1117         *
  1118         *  The 'handle' argument specifies the address of the Swi object whose
  1119         *  attributes are to be set.
  1120         *
  1121         *  The 'swiFxn' argument is the address of the function to be invoked
  1122         *  when the Swi runs. If 'swiFxn' is NULL, no change is made to the Swi
  1123         *  function.
  1124         *
  1125         *  The 'params' argument, which can be either NULL or a pointer to
  1126         *  a Swi_Params structure that contains attributes for the
  1127         *  Swi object, facilitates setting the attributes of the Swi object.
  1128         *
  1129         *  If 'params' is NULL, the Swi object is assigned a default set of
  1130         *  attributes.
  1131         *  Otherwise, the Swi object's attributes are set according the values
  1132         *  passed within 'params'.
  1133         *
  1134         *  @Constraints
  1135         *  Swi_setParams() must not be used on a Swi that is preempted
  1136         *  or is ready to run.
  1137         *
  1138         *  @related {@link #getAttrs Swi_getAttrs()}
  1139         *
  1140         *  @param(swiFxn)     address of the Swi function
  1141         *  @param(params)     pointer for returning Swi's Params
  1142         */
  1143        @DirectCall
  1144        Void setAttrs(FuncPtr swiFxn, Params *params);
  1145    
  1146        /*!
  1147         *  ======== inc ========
  1148         *  Increment Swi's trigger value and post the Swi
  1149         *
  1150         *  Swi_inc increments the value in Swi's trigger by 1 and posts the Swi
  1151         *  regardless of the resulting trigger value. You can decrement a
  1152         *  trigger value using Swi_dec, which only posts the Swi if the
  1153         *  trigger value is 0.
  1154         *
  1155         *  If a Swi is posted several times before it has a chance to begin
  1156         *  executing (i.e. when Hwis or higher priority Swis are running) the Swi
  1157         *  only runs one time. If this situation occurs, you can use Swi_inc to
  1158         *  post the Swi. Within the Swi's function, you could then use
  1159         *  Swi_getTrigger to find out how many times this Swi has been posted
  1160         *  since the last time it was executed.
  1161         *
  1162         *  You specify a Swi's initial trigger value at Swi creation time.
  1163         *  The trigger value is automatically reset when the Swi executes.
  1164         *  To get the trigger value, use Swi_getTrigger.
  1165         *
  1166         *  Swi_inc results in a context switch if the Swi is higher priority
  1167         *  than the currently executing thread.
  1168         *
  1169         *  @a(constraints)
  1170         *  The {@link #post} discussion regarding global interrupts applies
  1171         *  to this API.
  1172         */
  1173        @DirectCall
  1174        Void inc();
  1175    
  1176        /*!
  1177         *  ======== or ========
  1178         *  Or mask with value contained in Swi's trigger and post the
  1179         *  Swi.
  1180         *
  1181         *  Swi_or is used to post a software interrupt. Swi_or sets the bits
  1182         *  specified by a mask in Swi's trigger. Swi_or posts the Swi
  1183         *  regardless of the resulting trigger value. The bitwise logical
  1184         *  operation performed on the trigger value is:
  1185         *
  1186         *  @p(code)
  1187         *  trigger = trigger OR mask
  1188         *  @p
  1189         *
  1190         *  You specify a Swi's initial trigger value at Swi creation time.
  1191         *  The trigger value is automatically reset when the Swi executes.
  1192         *  To get the trigger value, use Swi_getTrigger.
  1193         *
  1194         *  For example, you might use Swi_or to post a Swi if any of three
  1195         *  events should cause a Swi to be executed, but you want the Swi's
  1196         *  function to be able to tell which event occurred. Each event
  1197         *  would correspond to a different bit in the trigger.
  1198         *
  1199         *  Swi_or results in a context switch if the Swi is higher priority
  1200         *  than the currently executing thread.
  1201         *
  1202         *  @a(constraints)
  1203         *  The {@link #post} discussion regarding global interrupts applies
  1204         *  to this API.
  1205         *
  1206         *  @param(mask)    value to be ORed
  1207         */
  1208        @DirectCall
  1209        Void or(UInt mask);
  1210    
  1211        /*!
  1212         *  ======== post ========
  1213         *  Unconditionally post a software interrupt
  1214         *
  1215         *  Swi_post is used to post a software interrupt regardless of the
  1216         *  trigger value. No change is made to the Swi object's trigger value.
  1217         *
  1218         *  Swi_post results in a context switch if the Swi is higher priority
  1219         *  than the currently executing thread.
  1220         *
  1221         *  @a(constraints)
  1222         *  Swis are ALWAYS run with interrupts enabled.
  1223         *  If a Swi is made ready to run as a consequence of this
  1224         *  API, interrupts will be globally enabled while the Swi function
  1225         *  executes, regardless of the prior globally enabled/disabled
  1226         *  state of interrupts.
  1227         *  Upon return from this API, the global interrupt enabled/disabled state
  1228         *  is restored to its previous value.
  1229         */
  1230        @DirectCall
  1231        Void post();
  1232    
  1233    internal:   /* not for client use */
  1234    
  1235        /*
  1236         *  ======== taskDisable ========
  1237         *  Swi and Task module function pointers
  1238         *
  1239         *  Used to decouple Hwi from Swi and Task when
  1240         *  dispatcherSwiSupport or dispatcherTaskSupport is false.
  1241         */
  1242        config UInt (*taskDisable)();
  1243        config Void (*taskRestore)(UInt);
  1244    
  1245        /*
  1246         *  ======== schedule ========
  1247         *  Run the highest priority Swi
  1248         *
  1249         *  Called by Swi_restore() which is used
  1250         *  in a task context.
  1251         *
  1252         *  Must be called with interrupts disabled.
  1253         */
  1254        Void schedule();
  1255    
  1256        /*
  1257         *  ======== run ========
  1258         *  Set up and run Swi
  1259         *
  1260         *  Enter with Hwi's disabled.
  1261         *  Exits with Hwi's enabled
  1262         */
  1263        Void run(Object *swi);
  1264    
  1265        /*
  1266         *  ======== postInit ========
  1267         *  Finish initializing static and dynamic Swis
  1268         */
  1269        Int postInit(Object *swi, Error.Block *eb);
  1270    
  1271        /*
  1272         *  ======== restoreSMP ========
  1273         *  Swi restore invoked when core != 0 and swiKey == false.
  1274         */
  1275        Void restoreSMP();
  1276    
  1277        /*!
  1278         *  ======== numConstructedSwis ========
  1279         *  Number of statically constructed Swi objects
  1280         *
  1281         *  @_nodoc
  1282         *  Shouldn't be set directly by the user's
  1283         *  config (it gets set by instance$static$init).
  1284         */
  1285        config UInt numConstructedSwis = 0;
  1286    
  1287        /*!
  1288         *  ======== Instance_State ========
  1289         *  @_nodoc
  1290         */
  1291        struct Instance_State {
  1292            Queue.Elem      qElem;      // Link within readyQ
  1293            FuncPtr         fxn;        // Swi function
  1294            UArg            arg0;       // Swi function 1st arg
  1295            UArg            arg1;       // Swi function 2nd arg
  1296            UInt            priority;   // Swi priority
  1297            UInt            mask;       // handy curSet orMask (= 1 << priority)
  1298            Bool            posted;     // TRUE = Swi already posted.
  1299            UInt            initTrigger;// Initial Trigger value
  1300            UInt            trigger;    // Swi Trigger
  1301            Queue.Handle    readyQ;     // This Swi's readyQ
  1302            Ptr             hookEnv[];
  1303        };
  1304    
  1305        /*!
  1306         *  ======== Module_State ========
  1307         *  @_nodoc
  1308         */
  1309        struct Module_State {
  1310            volatile Bool   locked;     // TRUE = Swi scheduler locked
  1311            UInt            curSet;     // Bitmask reflects readyQ states
  1312            UInt            curTrigger; // current Swi's on-entry trigger
  1313            Handle          curSwi;     // current Swi instance
  1314            Queue.Handle    curQ;       // current Swi's readyQ,
  1315                                        // when all posted Swis have run
  1316            Queue.Object    readyQ[];   // Swi ready queues
  1317            Handle          constructedSwis[]; // array of statically
  1318                                        // constructed Swis
  1319        };
  1320    }