1    /* 
     2     * Copyright (c) 2009
     3     * Texas Instruments
     4     *
     5     *  All rights reserved.  Property of Texas Instruments
     6     *  Restricted rights to use, duplicate or disclose this code are
     7     *  granted through contract.
     8     * 
     9     * */
    10    /*
    11     *  ======== Swi.xdc ========
    12     *
    13     */
    14    
    15    package ti.sysbios.knl;
    16    
    17    import xdc.rov.ViewInfo;
    18    
    19    import xdc.runtime.Error;
    20    import xdc.runtime.Assert;
    21    import xdc.runtime.Diags;
    22    import xdc.runtime.Log;
    23    
    24    import ti.sysbios.misc.Queue;
    25    
    26    /*!
    27     *  ======== Swi ========
    28     *  Software Interrupt Manager.
    29     *
    30     *  The Swi module manages software interrupt service routines, which are
    31     *  patterned after hardware interrupt service routines.
    32    
    33     *  DSP/BIOS manages four distinct levels of execution threads: hardware
    34     *  interrupt service routines, software interrupt routines, tasks, and
    35     *  background idle functions. A software interrupt is an object that
    36     *  encapsulates a function to be executed and a priority. 
    37     *  Software interrupts are prioritized, preempt tasks, and are preempted 
    38     *  by hardware interrupt service routines.
    39     *
    40     *  Each software interrupt has a priority level. A software interrupt 
    41     *  preempts any lower-priority software interrupt currently executing.
    42     *
    43     *  A target program uses an API call to post a Swi object. This causes the
    44     *  Swi module to schedule execution of the software interrupt's function.
    45     *  When a Swi is posted by an API call, the Swi object's function is not
    46     *  executed immediately. Instead, the function is scheduled for execution.
    47     *  DSP/BIOS uses the Swi's priority to determine whether to preempt the
    48     *  thread currently running. Note that if a Swi is posted several times 
    49     *  before it begins running, (because Hwis and higher priority interrupts 
    50     *  are running,) when the Swi does eventually run, it will run only one time.
    51     *
    52     *  Software interrupts can be posted for execution with a call to {@link #post}
    53     *  or a number of other Swi functions. Each Swi object has a "trigger"
    54     *  which is used either to determine whether to post the Swi or as a value
    55     *  that can be evaluated within the Swi's function. {@link #andn} and 
    56     *  {@link #dec}
    57     *  post the Swi if the trigger value transitions to 0. {@link #or} and 
    58     *  {@link #inc}
    59     *  also modify the trigger value. ({@link #or} sets bits, and {@link #andn}
    60     *  clears bits.)
    61     *  
    62     *  The {@link #disable} and {@link #restore} operations allow you to post several
    63     *  Swis and enable them all for execution at the same time. The Swi
    64     *  priorities then determine which Swi runs first.
    65     *
    66     *  All Swis run to completion; you cannot suspend a Swi while it waits for
    67     *  something (for example, a device) to be ready. So, you can use the
    68     *  trigger to tell the Swi when all the devices and other conditions it 
    69     *  relies on are ready. Within a Swi processing function, a call to 
    70     *  Swi_getTrigger returns the value of the trigger when the Swi started running.
    71     *  Note that the trigger is automatically reset to its original value 
    72     *  when a Swi runs; however, {@link #getTrigger} will return the saved trigger 
    73     *  value from when the Swi started execution.
    74     *
    75     *  All Swis run with interrupts globally enabled (ie GIE = 1).
    76     *  Therefore, any Swi module API that results in a
    77     *  Swi being made ready to run (ie {@link #post}, {@link #inc}, {@link #andn}, 
    78     *  {@link #or}, {@link #restore}, or {@link #enable})
    79     *  will subsequently also cause interrupts to be enabled while the
    80     *  Swi function executes. Upon return from the Swi function,
    81     *  global interrupts are restored to their previous enabled/disabled
    82     *  state.
    83     *
    84     *  A Swi preempts any currently running Swi with a lower priority. If two
    85     *  Swis with the same priority level have been posted, the Swi that was
    86     *  posted first runs first. Hwis in turn preempt any currently running Swi,
    87     *  allowing the target to respond quickly to hardware peripherals.
    88     *
    89     *  Swi threads are executed using the ISR (or "Hwi") stack. Thus
    90     *  they share the ISR stack with Hwi threads.
    91     *
    92     *  {@link #disable} also disables the Task scheduler.
    93     *  Therefore, Task pre-emption and blocking is disabled while
    94     *  the Swi scheduler is disabled.
    95     *  {@link #restore} will re-enable and invoke the Task
    96     *  scheduler if the Task scheduler was not disabled prior
    97     *  to invoking {@link #disable}.
    98     *  The currently ready highest priority task will be immediately
    99     *  switched to or continue to run when the lowest order {@link #restore}
   100     *  invocation re-enables the Swi scheduler.
   101     *
   102     *  In the following example, the newly created task is not switched to
   103     *  until after the Swi_restore() call since Task scheduling is disabled
   104     *  while Swi scheduling is disabled:
   105     *
   106     *  @p(code)
   107     *  key = Swi_disable();
   108     *  // create a task of higher priority than the current task thread
   109     *  myTaskParams.priority = Task_getPri(Task_self()) + 1;
   110     *  myTask = Task_create(myTaskFunc, &myTaskParams, NULL);
   111     *  Swi_restore(key);
   112     *  @p
   113     *
   114     *  Hook Functions
   115     *
   116     *  Sets of hook functions can be specified for the Swi module.  Each set
   117     *  contains these hook functions:
   118     *  @p(blist)
   119     *  -Register:  A function called before all statically created swis
   120     *      are initialized at runtime.
   121     *  -Create:    A function that is called when a swi is created.
   122     *      This includes swis that are created statically and those
   123     *      created dynamically using {@link #create}.
   124     *  -Ready:     A function that is called when any swi becomes ready
   125     *      to run.
   126     *  -Begin:     A function that is called just prior to running a swi.
   127     *  -End:       A function that is called just after a swi finishes.
   128     *  -Delete:    A function that is called when a swi is deleted at
   129     *      run-time with {@link #delete}.
   130     *  @p
   131     *
   132     *  Register Function
   133     *
   134     *  The Register function is provided to allow a hook set to store its
   135     *  hookset ID.  This id can be passed to {@link #setHookContext} and
   136     *  {@link #getHookContext} to set or get hookset-specific context.  The
   137     *  Register function must be specified if the hook implementation
   138     *  needs to use {@link #setHookContext} or {@link #getHookContext}.
   139     *  The registerFxn hook function is called during system initialization
   140     *  before interrupts have been enabled. 
   141     *
   142     *  @p(code)
   143     *  Void myRegisterFxn(Int id);
   144     *  @p
   145     *
   146     *  Create and Delete Functions
   147     *
   148     *  The create and delete functions are called whenever a Swi is created
   149     *  or deleted.  They are called with interrupts enabled (unless called 
   150     *  at boot time or from main()).
   151     *
   152     *  @p(code)
   153     *  Void myCreateFxn(Swi_Handle swi, Error_Block *eb);
   154     *  @p
   155     *
   156     *  @p(code)
   157     *  Void myDeleteFxn(Swi_Handle swi);
   158     *  @p
   159     *
   160     *  Ready, Begin, and End Functions
   161     *
   162     *  The ready, begin and end functions are all called with interrupts
   163     *  enabled.  The ready function is called when a Swi is posted and made
   164     *  ready to run.  The begin function is called right before the function
   165     *  associated with the given Swi is run.  The end function is called
   166     *  right after this function returns.
   167     *
   168     *  @p(code)
   169     *  Void myReady(Swi_Handle swi);
   170     *  @p
   171     *
   172     *  @p(code)
   173     *  Void myBegin(Swi_Handle swi);
   174     *  @p
   175     *
   176     *  @p(code)
   177     *  Void myEnd(Swi_Handle swi);
   178     *  @p
   179     *
   180     *  @p(html)
   181     *  <h3> Calling Context </h3>
   182     *  <table border="1" cellpadding="3">
   183     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
   184     *
   185     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   186     *    <!--                                                                                                                          -->
   187     *    <tr><td> {@link #create}          </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   188     *    <tr><td> {@link #disable}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   189     *    <tr><td> {@link #getTrigger}      </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   190     *    <tr><td> {@link #Params_init}     </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   191     *    <tr><td> {@link #restore}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   192     *    <tr><td> {@link #self}            </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   193     *
   194     *    <tr><td> {@link #andn}            </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   195     *    <tr><td> {@link #construct}       </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   196     *    <tr><td> {@link #dec}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   197     *    <tr><td> {@link #delete}          </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   198     *    <tr><td> {@link #destruct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   199     *    <tr><td> {@link #getHookContext}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   200     *    <tr><td> {@link #getPri}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   201     *    <tr><td> {@link #inc}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   202     *    <tr><td> {@link #or}              </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   203     *    <tr><td> {@link #post}            </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   204     *    <tr><td> {@link #setHookContext}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   205     *    <tr><td colspan="6"> Definitions: <br />
   206     *       <ul>
   207     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   208     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   209     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   210     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   211     *           <ul>
   212     *             <li> In your module startup after this module is started (e.g. Swi_Module_startupDone() returns TRUE). </li>
   213     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   214     *             <li> During main().</li>
   215     *             <li> During BIOS.startupFxns.</li>
   216     *           </ul>
   217     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   218     *           <ul>
   219     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   220     *             <li> In your module startup before this module is started (e.g. Swi_Module_startupDone() returns FALSE).</li>
   221     *           </ul>
   222     *       </ul>
   223     *    </td></tr>
   224     *
   225     *  </table>
   226     *  @p 
   227     */
   228    
   229    @ModuleStartup      /* generate a call to Swi_Module_startup */
   230                        /* to initialize hooks in instances */
   231    @InstanceFinalize   /* generate call to Swi_Instance_finalize on delete */
   232    
   233    @InstanceInitError  /* instance init can fail, call finalize if so */
   234    
   235    
   236    module Swi
   237    {
   238    
   239        // -------- Module Constants --------
   240    
   241        // -------- Module Types --------
   242    
   243        /*! Swi function type definition. */
   244        typedef Void (*FuncPtr)(UArg, UArg);
   245    
   246        /*! Swi hook set type definition. */
   247        struct HookSet {
   248            Void (*registerFxn)(Int);
   249            Void (*createFxn)(Handle, Error.Block *);
   250            Void (*readyFxn)(Handle);
   251            Void (*beginFxn)(Handle);
   252            Void (*endFxn)(Handle);
   253            Void (*deleteFxn)(Handle);
   254        };
   255    
   256        metaonly struct BasicView {
   257                String          label;
   258            String          state;
   259            UInt            priority;
   260            String          fxn[];
   261            UArg            arg0;
   262            UArg            arg1;
   263            UInt            initTrigger;
   264            UInt            curTrigger;
   265            //Ptr           hookEnv[];
   266        };
   267        
   268        metaonly struct ModuleView {
   269            String      schedulerState;
   270            String      readyQMask;
   271            Ptr         currentSwi;
   272            String      currentFxn[];
   273        };
   274        
   275        /*! @_nodoc */
   276        @Facet
   277        metaonly config ViewInfo.Instance rovViewInfo = 
   278            xdc.rov.ViewInfo.create({
   279                viewMap: [
   280                    ['Basic',  {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   281                    ['Module', {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
   282                ]
   283             });
   284             
   285        // -------- Module Proxies --------
   286    
   287        // -------- Module Parameters --------
   288    
   289        /*! Logged just prior to invoking a Swi's function */
   290        config Log.Event LM_begin = {
   291            mask: Diags.USER1 | Diags.USER2,
   292            msg: "LM_begin: swi: 0x%x, func: 0x%x, preThread: %d"
   293        };
   294    
   295        /*! Logged just after returning from a Swi's function */
   296        config Log.Event LD_end = {
   297            mask: Diags.USER2,
   298            msg: "LD_end: swi: 0x%x"
   299        };
   300    
   301        /*! Logged when Swi_post() is called */
   302        config Log.Event LM_post = {
   303            mask: Diags.USER1 | Diags.USER2,
   304            msg: "LM_post: swi: 0x%x, func: 0x%x, pri: %d"
   305        };
   306    
   307        // Asserts
   308    
   309        /*! Asserted when Swi_create is called when {@link ti.sysbios.BIOS#swiEnabled} is false */
   310        config Assert.Id A_swiDisabled = {
   311            msg: "A_swiDisabled: Cannot create a Swi when Swi is disabled."
   312        };
   313    
   314        /*! Asserted when a Swi priority is not in the range of 0 and numPriorities-1 */
   315        config Assert.Id A_badPriority = {
   316            msg: "A_badPriority: An invalid Swi priority was used."
   317        };
   318    
   319        /*! 
   320         *  Number of Swi priorities supported. Default is 16.
   321         *
   322         *  The maximum number of priorities supported is
   323         *  target specific and depends on the number of
   324         *  bits in a UInt data type. For 6x and Arm devices
   325         *  the maximum number of priorities is therefore 32.
   326         *  For 28x, 55x, and MSP430 devices, the maximum number of
   327         *  priorities is 16.
   328         */
   329        config UInt numPriorities = 16;
   330    
   331        /*!
   332         *  const array to hold all HookSet objects.
   333         */
   334        config HookSet hooks[length] = [];
   335    
   336    
   337        // -------- Module Functions --------
   338    
   339        /*!
   340         *  ======== addHookSet ========
   341         *  addHookSet is used in a config file to add a hook set (defined
   342         *  by struct HookSet).
   343         *
   344         *  HookSet structure elements may be omitted, in which case those
   345         *  elements will not exist.
   346         *
   347         *  @param(hookSet)         structure of type HookSet
   348         */
   349        metaonly Void addHookSet(HookSet hookSet);
   350    
   351        /*!
   352         *  @_nodoc
   353         *  ======== Swi_startup ========
   354         *  Start the Swi scheduler.
   355         *  This function is called in BIOS_start() after Hwi_enable().
   356         */
   357        Void startup();
   358    
   359        /*!
   360         *  @_nodoc
   361         *  ======== Swi_enabled ========
   362         *  Returns TRUE if the Swi scheduler is enabled.
   363         */
   364        Bool enabled();
   365    
   366        /*!
   367         *  ======== disable ========
   368         *  Disable Swi Scheduling.
   369         *
   370         *  {@link #disable} and {@link #restore} control Swi scheduling.
   371         *  {@link #disable} disables all other Swi functions from running until
   372         *  {@link #restore} is called. Hardware interrupts can still run.
   373         *  
   374         *  {@link #disable} and {@link #restore} allow you to ensure that
   375         *  statements that must be performed together during critical 
   376         *  processing are not preempted by other Swis or Tasks.
   377         *
   378         *  The value of the key returned is opaque to applications and is meant
   379         *  to be passed to Swi_restore().
   380         *
   381         *  In the following example, the critical section cannot be preempted 
   382         *  by any Swis.
   383         *  
   384         *  @p(code)
   385         *  key = Swi_disable();
   386         *      `critical section`
   387         *  Swi_restore(key);
   388         *  @p
   389         *  
   390         *  @a(constraints)
   391         *  Swi_disable also disables the Task scheduler.
   392         *  Swi_restore will re-enable and invoke the Task
   393         *  scheduler if the Task scheduler was not disabled prior
   394         *  to invoking Swi_disable().
   395         *  
   396         *  @b(returns)     opaque key for use with Swi_restore()
   397         */
   398        UInt disable();
   399    
   400        /*!
   401         *  @_nodoc
   402         *  ======== enable ========
   403         *  Enable Swi Scheduling.
   404         *
   405         *  Swi_enable unconditionally enables Swis and invokes the Swi scheduler
   406         *  if any Swis are pending.
   407         *
   408         *  @a(constraints)
   409         *  Swi_enable will also invoke the Task scheduler if the
   410         *  Task scheduler is not currently disabled.
   411         *
   412         *  The {@link #post} discussion regarding global interrupts applies 
   413         *  to this API.
   414         *
   415         */
   416        Void enable();
   417    
   418        /*!
   419         *  ======== restore ========
   420         *  Restore Swi Scheduling state.
   421         *
   422         *  Swi_restore restores the Swi scheduler to the locked/unlocked state 
   423         *  it was in when Swi_disable was called. If the scheduler becomes
   424         *  unlocked and Swis of sufficient priority have been made ready to
   425         *  run by any of the posting APIs, then they are run at this time.
   426         *
   427         *  Swi_disable and Swi_restore control software interrupt processing.
   428         *  Swi_disable disables all other Swi functions from running until
   429         *  Swi_restore is called. Hardware interrupts can still run.
   430         *  
   431         *  Swi_disable and Swi_restore allow you to ensure that statements that
   432         *  must be performed together during critical processing are not 
   433         *  pre-empted by other Swis.
   434         *
   435         *  In the following example, the critical section can not be preempted
   436         *  by any Swis:
   437         *  
   438         *  @p(code)
   439         *  key = Swi_disable();
   440         *      `critical section`
   441         *  Swi_restore(key);
   442         *  @p
   443         *  
   444         *  @a(constraints)
   445         *  Swi_restore will also re-enable and invoke the Task
   446         *  scheduler if the Task scheduler was not disabled prior to 
   447         *  invoking Swi_disable().
   448         *  
   449         *  The {@link #post} discussion regarding global interrupts applies 
   450         *  to this API.
   451         *
   452         *  @param(key)     key to restore previous Swi scheduler state
   453         */
   454        Void restore(UInt key);
   455    
   456        /*!
   457         *  @_nodoc
   458         *  ======== restoreHwi ========
   459         *
   460         *  Restore Swi Scheduling state.
   461         *  Optimized version used by Hwi dispatcher.
   462         */
   463        Void restoreHwi(UInt key);
   464    
   465        /*!
   466         *  ======== self ========
   467         *  Return address of currently executing Swi object.
   468         *
   469         *  Swi_self returns the handle of the currently executing Swi.
   470         *
   471         *  @b(returns)     handle of currently running Swi
   472         */
   473        Handle self();
   474    
   475        /*!
   476         *  ======== getTrigger ========
   477         *  Return the trigger value of the currently executing Swi.
   478         *
   479         *  Swi_getTrigger returns the value that Swi's trigger had when the Swi
   480         *  started running. DSP/BIOS saves the trigger value internally so that
   481         *  Swi_getTrigger can access it at any point within a Swi object's function.
   482         *  DSP/BIOS then automatically resets the trigger to its initial value.
   483         *  
   484         *  Swi_getTrigger should only be called within a function run by a Swi 
   485         *  object.
   486         *  
   487         *  When called from within the context of a Swi, the value returned by
   488         *  Swi_getTrigger is zero if the Swi was posted by a call to Swi_andn,
   489         *  or Swi_dec. Therefore, Swi_getTrigger provides relevant information 
   490         *  only if the Swi was posted by a call to Swi_inc, Swi_or, Swi_orHook, 
   491         *  or Swi_post.
   492         *
   493         *  @b(returns)         trigger value
   494         */
   495        UInt getTrigger();
   496    
   497        /*!
   498         *  @_nodoc
   499         *  ======== raisePri ========
   500         *
   501         *  Raise a Swi's priority. (Provided for legacy compatibility)
   502         *
   503         *  Swi_raisePri is used to raise the priority of the currently running 
   504         *  Swi to the priority passed in as the argument. Swi_raisePri can be used
   505         *  in conjunction with Swi_restorePri to provide a mutual exclusion
   506         *  mechanism without disabling Swis.
   507         *  
   508         *  Swi_raisePri should be called before a shared resource is accessed, and
   509         *  Swi_restorePri should be called after the access to the shared resource.
   510         *  
   511         *  A call to Swi_raisePri not followed by a Swi_restorePri keeps the Swi's
   512         *  priority for the rest of the processing at the raised level. A Swi_post 
   513         *  of the Swi posts the Swi at its original priority level.
   514         *  
   515         *  A Swi object's execution priority must range from 0 to 
   516         *  Swi_numPriorities - 1
   517         *  
   518         *  Swi_raisePri never lowers the current Swi priority.
   519         *  
   520         *  Constraints and Calling Context
   521         *  @p(blist)
   522         *  - Swi_raisePri must only be called from a Swi context.
   523         *  @p
   524         *
   525         *  @b(returns)         key for use with restorePri()
   526         */
   527        UInt raisePri(UInt priority);
   528    
   529        /*!
   530         *  @_nodoc
   531         *  ======== restorePri ========
   532         *
   533         *  Restore a Swi's priority. (Provided for legacy compatibility)
   534         *
   535         *  Swi_restorePri restores the priority to the Swi's priority prior to the
   536         *  Swi_raisePri call. Swi_restorePri can be used in
   537         *  conjunction with Swi_raisePri to provide a mutual exclusion mechanism
   538         *  without disabling all Swis.
   539         *
   540         *  Swi_raisePri should be called right before the shared resource is
   541         *  referenced, and Swi_restorePri should be called after the reference to
   542         *  the shared resource.
   543         *
   544         *  Constraints and Calling Context
   545         *  
   546         *  @p(blist)
   547         *  - Swi_restorePri must only be called from a Swi context.
   548         *  @p
   549         *  
   550         *  @param(key)     key returned from Swi_raisePri
   551         */
   552        Void restorePri(UInt key);
   553    
   554    instance:
   555    
   556        /*!
   557         *  ======== create ========
   558         *  Create a software interrupt.
   559         *
   560         *  Swi_create creates a new Swi object. 
   561         *
   562         *  @param(fxn)     Swi Function
   563         */
   564        create(FuncPtr fxn);
   565    
   566        // -------- Handle Parameters --------
   567    
   568        /*! Swi function argument 0. Default is 0. */
   569        config UArg arg0 = 0;
   570    
   571        /*! Swi function argument 1. Default is 0. */
   572        config UArg arg1 = 0;
   573    
   574        /*! 
   575         *  Swi priority (0 to {@link #numPriorities} - 1). 
   576         *
   577         *  Default value of ~0 yields a Swi priority of 
   578         *  (numPriorities  - 1). 
   579         */
   580        config UInt priority = ~0;
   581    
   582        /*! Initial Swi trigger value. Default is 0. */
   583        config UInt trigger = 0;
   584    
   585        // -------- Handle Functions --------
   586    
   587        /*!
   588         *  ======== andn ========
   589         *  Clear bits in Swi's trigger; post if trigger becomes 0.
   590         *
   591         *  Swi_andn is used to conditionally post a software interrupt. 
   592         *  Swi_andn clears the bits specified by a mask from Swi's internal 
   593         *  trigger. If the Swi's trigger becomes 0, Swi_andn posts the Swi. 
   594         *  The bitwise logical operation performed is:
   595         *  
   596         *  trigger = trigger AND (NOT MASK)
   597         *  
   598         *  For example, if multiple conditions that all be met before a 
   599         *  Swi can run, you should use a different bit in the trigger for 
   600         *  each condition. When a condition is met, clear the bit for that 
   601         *  condition.
   602         *  
   603         *  Swi_andn results in a context switch if the Swi's trigger becomes 
   604         *  zero and the Swi has higher priority than the currently executing 
   605         *  thread.
   606         *  
   607         *  You specify a Swi's initial trigger value in the configuration. 
   608         *  The trigger value is automatically reset when the Swi executes.
   609         *  
   610         *  @a(constraints)
   611         *  The {@link #post} discussion regarding global interrupts applies 
   612         *  to this API.
   613         *
   614         *  @param(mask)    inverse value to be ANDed
   615         */
   616        Void andn(UInt mask);
   617    
   618        /*!
   619         *  ======== dec ========
   620         *  Decrement Swi's trigger value; post if trigger becomes 0.
   621         *
   622         *  Swi_dec is used to conditionally post a software interrupt. Swi_dec
   623         *  decrements the value in Swi's trigger by 1. If Swi's trigger value
   624         *  becomes 0, Swi_dec posts the Swi. You can increment a trigger value
   625         *  by using Swi_inc, which always posts the Swi.
   626         *
   627         *  For example, you would use Swi_dec if you wanted to post a Swi after
   628         *  a number of occurrences of an event.
   629         *
   630         *  You specify a Swi's initial trigger value in the configuration. The 
   631         *  trigger value is automatically reset when the Swi executes.
   632         *
   633         *  Swi_dec results in a context switch if the Swi's trigger becomes
   634         *  zero and the Swi has higher priority than the currently executing 
   635         *  thread.
   636         *
   637         *  @a(constraints)
   638         *  The {@link #post} discussion regarding global interrupts applies 
   639         *  to this API.
   640         */
   641        Void dec();
   642    
   643        /*!
   644         *  ======== getHookContext ========
   645         *  Get hook instance's context pointer for a swi.
   646         *
   647         *  @b(returns)     hook instance's context pointer for swi
   648         */
   649        Ptr getHookContext(Int id);
   650    
   651        /*!
   652         *  ======== setHookContext ========
   653         *  Set hook instance's context for a swi.
   654         *
   655         *  @param(id)              hook instance's ID
   656         *  @param(hookContext)     value to write to context
   657         */
   658        Void setHookContext(Int id, Ptr hookContext);
   659    
   660        /*!
   661         *  ======== getPri ========
   662         *  Return a Swi's priority.
   663         *
   664         *  Swi_getPri returns the priority of the Swi passed in as the
   665         *  argument.
   666         *
   667         *  @b(returns)     Priority of swi
   668         */
   669        UInt getPri();
   670    
   671        /*!
   672         *  ======== inc ========
   673         *  Increment Swi's trigger value and post the Swi.
   674         *
   675         *  Swi_inc increments the value in Swi's trigger by 1 and posts the Swi
   676         *  regardless of the resulting trigger value. You can decrement a 
   677         *  trigger value using Swi_dec, which only posts the Swi if the 
   678         *  trigger value is 0.
   679         *
   680         *  If a Swi is posted several times before it has a chance to begin
   681         *  executing (ie: when Hwis or higher priority Swis are running) the Swi
   682         *  only runs one time. If this situation occurs, you can use Swi_inc to 
   683         *  post the Swi. Within the Swi's function, you could then use 
   684         *  Swi_getTrigger to find out how many times this Swi has been posted 
   685         *  since the last time it was executed.
   686         *
   687         *  You specify a Swi's initial trigger value at Swi creation time.
   688         *  The trigger value is automatically reset when the Swi executes. 
   689         *  To get the trigger value, use Swi_getTrigger.
   690         *
   691         *  Swi_inc results in a context switch if the Swi is higher priority 
   692         *  than the currently executing thread.
   693         *
   694         *  @a(constraints)
   695         *  The {@link #post} discussion regarding global interrupts applies 
   696         *  to this API.
   697         */
   698        Void inc();
   699    
   700        /*!
   701         *  ======== or ========
   702         *  Or mask with value contained in Swi's trigger and post the
   703         *  Swi.
   704         *
   705         *  Swi_or is used to post a software interrupt. Swi_or sets the bits 
   706         *  specified by a mask in Swi's trigger. Swi_or posts the Swi 
   707         *  regardless of the resulting trigger value. The bitwise logical 
   708         *  operation performed on the trigger value is:
   709         *
   710         *  trigger = trigger OR mask
   711         *
   712         *  You specify a Swi's initial trigger value in the configuration. 
   713         *  The trigger value is automatically reset when the Swi executes. 
   714         *  To get the trigger value, use Swi_getTrigger.
   715         *
   716         *  For example, you might use Swi_or to post a Swi if any of three 
   717         *  events should cause a Swi to be executed, but you want the Swi's 
   718         *  function to be able to tell which event occurred. Each event 
   719         *  would correspond to a different bit in the trigger.
   720         *
   721         *  Swi_or results in a context switch if the Swi is higher priority 
   722         *  than the currently executing thread.
   723         *
   724         *  @a(constraints)
   725         *  The {@link #post} discussion regarding global interrupts applies 
   726         *  to this API.
   727         *
   728         *  @param(mask)    value to be ORed
   729         */
   730        Void or(UInt mask);
   731    
   732        /*!
   733         *  ======== post ========
   734         *  Unconditionally post a software interrupt.
   735         *
   736         *  Swi_post is used to post a software interrupt regardless of the 
   737         *  trigger value. No change is made to the Swi object's trigger value.
   738         *
   739         *  Swi_post results in a context switch if the Swi is higher priority 
   740         *  than the currently executing thread.
   741         *
   742         *  @a(constraints)
   743         *  Swis are ALWAYS run with interrupts enabled.
   744         *  If a Swi is made ready to run as a consequence of this
   745         *  API, interrupts will be globally enabled while the Swi function
   746         *  executes, regardless of the prior globally enabled/disabled state of interrupts. 
   747         *  Upon return from this API, the global interrupt enabled/disabled state
   748         *  is restored to its previous value.
   749         */
   750        Void post();
   751    
   752    internal:   /* not for client use */ 
   753    
   754        /* 
   755         * Swi and Task module function pointers. 
   756         * Used to decouple Hwi from Swi and Task when 
   757         * dispatcherSwiSupport or
   758         * dispatcherTaskSupport is false.
   759         */
   760        config UInt (*taskDisable)();
   761        config Void (*taskRestore)(UInt);
   762    
   763        /*
   764         *  ======== schedule ========
   765         *  Find highest priority Swi and invoke it.
   766         *  Called by Swi_restore() which is used
   767         *  in a task context.
   768         *
   769         *  Must be called with interrupts disabled.
   770         */
   771        Void schedule();
   772    
   773        /*
   774         *  ======== run ========
   775         *  Set up and run Swi.
   776         *  Enter with Hwi's disabled
   777         *  Exits with Hwi's enabled
   778         */
   779        Void run(Object *swi);
   780    
   781        /*
   782         *  ======== postInit ========
   783         *  finish initing static and dynamic Swis
   784         */
   785        Int postInit(Object *swi, Error.Block *eb);
   786    
   787        /*!
   788         *  @_nodoc
   789         *  Number of statically constructed Swi objects.
   790         *  Shouldn't be set directly by the user's
   791         *  config (it gets set by instance$static$init).
   792         */
   793        config UInt numConstructedSwis = 0;
   794    
   795        struct Instance_State {
   796            Queue.Elem      qElem;      // Link within readyQ
   797            FuncPtr         fxn;        // Swi function
   798            UArg            arg0;       // Swi function 1st arg
   799            UArg            arg1;       // Swi function 2nd arg
   800            UInt            priority;   // Swi priority
   801            UInt            mask;       // handy curSet orMask (= 1 << priority)
   802            Bool            posted;     // TRUE = Swi already posted.
   803            UInt            initTrigger;// Initial Trigger value
   804            UInt            trigger;    // Swi Trigger
   805            Queue.Handle    readyQ;     // This Swi's readyQ
   806            Ptr             hookEnv[];
   807        };
   808    
   809        struct Module_State {
   810            Bool            locked;     // TRUE = Swi scheduler locked
   811            UInt            curSet;     // Bitmask reflects readyQ states
   812            UInt            curTrigger; // current Swi's on-entry trigger
   813            Handle          curSwi;     // current Swi instance
   814            Queue.Handle    curQ;       // current Swi's readyQ,
   815                                        // when all posted Swis have run
   816            Queue.Object    readyQ[];   // Swi ready queues
   817            Handle          constructedSwis[]; // array of statically 
   818                                        // constructed Swis
   819        };
   820    }
   821    /*
   822     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,349; 12-18-2009 15:13:05; /db/vtree/library/trees/avala/avala-m19x/src/
   823     */
   824