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     *  ======== IHwi.xdc ========
    12     *
    13     */
    14    
    15    import xdc.runtime.Error;
    16    
    17    
    18    /*!
    19     *  ======== Hwi ========
    20     *  Hardware Interrupt Support Module.
    21     *
    22     *  The IHwi interface specifies APIs for globally enabling, disabling, and
    23     *  restoring interrupts.
    24     *
    25     *  Additionally, management of individual, device specific hardware 
    26     *  interrupts is provided.
    27     *
    28     *  The user can statically or dynamically assign routines that run when 
    29     *  specific hardware interrupts occur. 
    30     *
    31     *  Dynamic assignment of Hwi routines to interrupts at run-time is done 
    32     *  using the Hwi_create function.
    33     *
    34     *  Interrupt routines can be written completely in assembly, completely in 
    35     *  C, or in a mix of assembly and C. In order to support interrupt routines
    36     *  written completely in C, an interrupt dispatcher is provided that performs
    37     *  the requisite prolog and epilog for an interrupt routine.
    38     *
    39     *  Some routines are assigned to interrupts by the other BIOS
    40     *  modules. For example, the Clock module configures its own timer interrupt
    41     *  handler. See the Clock Module for more details.
    42     *
    43     *  Hook Functions
    44     *
    45     *  Sets of hook functions can be specified for the Hwi module
    46     *  using the configuration tool.  Each set contains these hook
    47     *  functions:
    48     *  @p(blist)
    49     *  -Register:  A function called before any statically created hwis
    50     *      are initialized at runtime.  The register hook is called at boot time
    51     *      before main() and before interrupts are enabled.
    52     *  -Create:    A function that is called when a hwi is created.
    53     *      This includes hwis that are created statically and those
    54     *      created dynamically using {@link #create Hwi_create}.
    55     *  -Begin:     A function that is called just prior to running a hwi.
    56     *  -End:       A function that is called just after a hwi finishes.
    57     *  -Delete:    A function that is called when a hwi is deleted at
    58     *      run-time with {@link #delete Hwi_delete}.
    59     *  @p
    60     *
    61     *  Register Function
    62     *
    63     *  The Register function is provided to allow a hook set to store its
    64     *  hookset ID.  This id can be passed to {@link #setHookContext Hwi_setHookContext} and
    65     *  {@link #getHookContext Hwi_getHookContext} to set or get hookset-specific context.  The
    66     *  Register function must be specified if the hook implementation
    67     *  needs to use {@link #setHookContext  Hwi_setHookContext} or {@link #getHookContext  Hwi_getHookContext}.
    68     *  The registerFxn hook function is called during system initialization
    69     *  before interrupts have been enabled.
    70     *
    71     *  @p(code)
    72     *  Void myRegisterFxn(Int id);
    73     *  @p
    74     *
    75     *  Create and Delete Functions
    76     * 
    77     *  The create and delete functions are called whenever a Hwi is created
    78     *  or deleted.  They are called with interrupts enabled (unless called 
    79     *  at boot time or from main()).
    80     *
    81     *  @p(code)
    82     *  Void myCreateFxn(Hwi_Handle hwi, Error_Block *eb);
    83     *  @p
    84     *
    85     *  @p(code)
    86     *  Void myDeleteFxn(Hwi_Handle hwi);
    87     *  @p
    88     *
    89     *  Begin and End Functions
    90     *
    91     *  The beginFxn and endFxn function hooks are called with interrupts
    92     *  globally disabled, therefore any hook processing function will contribute
    93     *  to the overall system interrupt response latency.  In order to minimize
    94     *  this impact, carefully consider the processing time spent in an Hwi
    95     *  beginFxn or endFxn function hook.
    96     *
    97     *  @p(code)
    98     *  Void myBeginFxn(Hwi_Handle hwi);
    99     *  @p
   100     *
   101     *  @p(code)
   102     *  Void myEndFxn(Hwi_Handle hwi);
   103     *  @p
   104     *
   105     *  Hook functions can only be configured statically.
   106     */
   107    
   108    @InstanceFinalize
   109    @InstanceInitError
   110    
   111    interface IHwi {
   112    
   113        // -------- Module Types --------
   114    
   115        /*! Hwi create function type definition. */
   116        typedef Void (*FuncPtr)(UArg);
   117        
   118        /*! 
   119         * Interrupt Return Pointer. 
   120         * This is the address of the interrupted instruction.
   121         */
   122        typedef UArg Irp;
   123        
   124        /*! Hwi hook set type definition. */
   125        struct HookSet {
   126            Void (*registerFxn)(Int);
   127            Void (*createFxn)(Handle, Error.Block *);
   128            Void (*beginFxn)(Handle);
   129            Void (*endFxn)(Handle);
   130            Void (*deleteFxn)(Handle);
   131        };
   132    
   133        /*! Shorthand interrupt masking options. */
   134        enum MaskingOption {
   135            MaskingOption_NONE,     /*! No interrupts are disabled. */
   136            MaskingOption_ALL,      /*! All interrupts are disabled. */
   137            MaskingOption_SELF,     /*! Only this interrupt is disabled. */
   138            MaskingOption_BITMASK,  /*! User supplies IER masks. */
   139            MaskingOption_LOWER     /*! All current and lower priority 
   140                                        interrupts are disabled. Only a few
   141                                        targets/devices truly support this 
   142                                        masking option. For those that don't,
   143                                        this setting is treated the same as
   144                                        MaskingOption_SELF */
   145        };
   146    
   147        /*!
   148         *  @_nodoc
   149         *  returned by getStackInfo()
   150         */
   151        metaonly struct StackInfo {
   152            SizeT hwiStackPeak;
   153            SizeT hwiStackSize;
   154            Ptr hwiStackBase;
   155        };
   156    
   157        // -------- Module Parameters --------
   158    
   159        /*!
   160         *  Include interrupt nesting logic in interrupt dispatcher?
   161         *  Default is true.
   162         *
   163         *  This option provides the user with the ability to optimize
   164         *  interrupt dispatcher performance when support for interrupt
   165         *  nesting is not required.
   166         *
   167         *  Setting this parameter to false will disable the logic in
   168         *  the interrupt dispatcher that manipulates interrupt mask
   169         *  registers and enables and disables interrupts before and
   170         *  after invoking the user's Hwi function. 
   171         *
   172         *  Set this parameter to false if you don't need interrupts 
   173         *  enabled during the execution of your Hwi functions.
   174         */
   175        config Bool dispatcherAutoNestingSupport = true;
   176    
   177        /*!
   178         *  Include Swi scheduling logic in interrupt dispatcher?
   179         *  Default is inherited from {@link ti.sysbios.BIOS#swiEnabled 
   180         *  BIOS.swiEnabled}, which is true by default.
   181         *
   182         *  This option provides the user with the ability to optimize
   183         *  interrupt dispatcher performance when it is known that Swi's
   184         *  will not be posted from any of their Hwi threads.
   185         *
   186         *  Setting this parameter to false will disable the logic in
   187         *  the interrupt dispatcher that invokes the Swi scheduler
   188         *  prior to returning from an interrupt.
   189         */
   190        config Bool dispatcherSwiSupport;
   191    
   192        /*!
   193         *  Include Task scheduling logic in interrupt dispatcher?
   194         *  Default is inherited from {@link ti.sysbios.BIOS#taskEnabled 
   195         *  BIOS.taskEnabled}, which is true by default.
   196         *
   197         *  This option provides the user with the ability to optimize
   198         *  interrupt dispatcher performance when it is known that no
   199         *  Task scheduling APIs (ie {@link ti.sysbios.ipc.Semaphore#post 
   200         *  Semaphore_post()}) will be executed from any of their Hwi threads.
   201         *
   202         *  Setting this parameter to false will disable the logic in
   203         *  the interrupt dispatcher that invokes the Task scheduler
   204         *  prior to returning from an interrupt.
   205         */
   206        config Bool dispatcherTaskSupport;
   207    
   208        /*!
   209         *  This dispatcher configuration option controls whether the
   210         *  dispatcher retains the interrupted thread's return address.
   211         *  This option is enabled by default.
   212         *
   213         *  Setting this parameter to false will disable the logic in
   214         *  the interrupt dispatcher that keeps track of the interrupt's
   215         *  return address and provide a small savings in interrupt latency.
   216         *
   217         *  The application can get an interrupt's most recent return
   218         *  address using the {@link #getIrp} API.
   219         */
   220        config Bool dispatcherIrpTrackingSupport = true;
   221    
   222        // -------- Module Functions --------
   223    
   224        /*!
   225         *  ======== addHookSet ========
   226         *  addHookSet is used in a config file to add a hook set (defined
   227         *  by struct HookSet).
   228         *
   229         *  HookSet structure elements may be omitted, in which case those
   230         *  elements will not exist.
   231         *
   232         *  @param(hook)    structure of type HookSet
   233         */
   234        metaonly Void addHookSet(HookSet hook);
   235    
   236        /*!
   237         *  ======== getStackInfo ========
   238         *  @_nodoc
   239         *  Returns the Hwi stack usage info. Used at ROV time.
   240         *
   241         *  @b(returns)     Hwi stack base, size, peak
   242         */
   243        metaonly StackInfo getStackInfo();
   244    
   245        /*!
   246         *  ======== startup ========
   247         *  Initially enable interrupts
   248         *
   249         *  Called within BIOS_start
   250         */
   251        @DirectCall
   252        Void startup();
   253    
   254        /*!
   255         *  ======== disable ========
   256         *  Globally disable interrupts.
   257         *
   258         *  Hwi_disable globally disables hardware interrupts and returns an
   259         *  opaque key indicating whether interrupts were globally enabled or
   260         *  disabled on entry to Hwi_disable(). 
   261         *  The actual value of the key is target/device specific and is meant 
   262         *  to be passed to Hwi_restore(). 
   263         *
   264         *  Call Hwi_disable before a portion of a function that needs
   265         *  to run without interruption. When critical processing is complete, call
   266         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   267         *
   268         *  Servicing of interrupts that occur while interrupts are disabled is
   269         *  postponed until interrupts are reenabled. However, if the same type 
   270         *  of interrupt occurs several times while interrupts are disabled, 
   271         *  the interrupt's function is executed only once when interrupts are 
   272         *  reenabled.
   273         *
   274         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   275         *  an enabled interrupt occurred while interrupts are disabled.
   276         *
   277         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   278         *  are already disabled in main(), such a call has no effect.
   279         *
   280         *  @a(constraints)
   281         *  If a Task switching API such as 
   282         *  {@link ti.sysbios.ipc.Semaphore#pend Semaphore_pend()}, 
   283         *  {@link ti.sysbios.ipc.Semaphore#post Semaphore_post()},
   284         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   285         *  {@link ti.sysbios.knl.Task#yield Task_yield()} 
   286         *  is invoked which results in a context switch while
   287         *  interrupts are disabled, an embedded call to {@link #enable Hwi_enable} occurs
   288         *  on the way to the new thread context which unconditionally re-enables
   289         *  interrupts. Interrupts will remain enabled until a subsequent {@link #disable Hwi_disable}
   290         *  invocation.
   291         *
   292         *  Swis always run with interrupts enabled.
   293         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   294         *  interrupts.
   295         *
   296         *  @b(returns)     opaque key for use by Hwi_restore()
   297         */
   298        UInt disable();
   299    
   300        /*!
   301         *  ======== enable ========
   302         *  Globally enable interrupts.
   303         *
   304         *  Hwi_enable globally enables hardware interrupts and returns an
   305         *  opaque key indicating whether interrupts were globally enabled or
   306         *  disabled on entry to Hwi_enable(). 
   307         *  The actual value of the key is target/device specific and is meant 
   308         *  to be passed to Hwi_restore(). 
   309         *
   310         *
   311         *  This function is 
   312         *  called as part of BIOS Startup_POST_APP_MAIN phase.
   313         *
   314         *  Hardware interrupts are enabled unless a call to Hwi_disable disables
   315         *  them. 
   316         *
   317         *  Servicing of interrupts that occur while interrupts are disabled is
   318         *  postponed until interrupts are reenabled. However, if the same type 
   319         *  of interrupt occurs several times while interrupts are disabled, 
   320         *  the interrupt's function is executed only once when interrupts are 
   321         *  reenabled.
   322         *
   323         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   324         *  an enabled interrupt occurred while interrupts are disabled.
   325         *
   326         *  Any call to Hwi_enable enables interrupts, even if Hwi_disable has 
   327         *  been called several times.
   328         *
   329         *  Hwi_enable must not be called from main().
   330         *
   331         *  @b(returns)     opaque key for use by Hwi_restore()
   332         */
   333        UInt enable();
   334    
   335        /*!
   336         *  ======== restore ========
   337         *  Globally restore interrupts.
   338         *
   339         *  Hwi_restore globally restores interrupts to the state determined 
   340         *  by the key argument provided by a previous invocation of Hwi_disable.
   341         *
   342         *  A context switch may occur when calling Hwi_restore if Hwi_restore
   343         *  reenables interrupts and another Hwi occurred while interrupts were 
   344         *  disabled.
   345         *
   346         *  Hwi_restore may be called from main(). However, since Hwi_enable
   347         *  cannot be called from main(), interrupts are always disabled in 
   348         *  main(), and a call to Hwi_restore has no effect.
   349         *
   350         *  @param(key)     enable/disable state to restore
   351         */
   352        Void restore(UInt key);
   353    
   354        /*!
   355         *  @_nodoc
   356         *  ======== switchFromBootStack ========
   357         *  Indicate that we are leaving the boot stack and
   358         *  are about to switch to a task stack.
   359         *  Used by Task_startup()
   360         */
   361        Void switchFromBootStack();
   362    
   363        /*!
   364         *  @_nodoc
   365         *  ======== post ========
   366         *  Generate an interrupt for test purposes.
   367         *
   368         *  @param(intNum)      ID of interrupt to generate
   369         */
   370        Void post(UInt intNum);
   371    
   372        /*
   373         *  @_nodoc
   374         *  The following two target-unique Hwi APIs must be called
   375         *  directly in order to work properly. Thus they are not
   376         *  published here in order to bypass the multi-layered indirect function
   377         *  calls (__E, __F) that would arise if they appeared in this spec file.
   378         *
   379         *  These APIs must be implemented by the target Hwi modules and must be
   380         *  given these EXACT names.
   381         *
   382         *  The two functions, switchToIsrStack() and switchToTaskStack() must
   383         *  work in tandem to insure that only the first order (ie non nested) 
   384         *  invocation of these APIs result in the switch to the ISR stack and 
   385         *  the switch back to the task stack. The opaque char * token returned 
   386         *  by switchToIsrStack() and passed to switchToTaskStack() is provided
   387         *  purely for implementation efficiency and thus can have implementation
   388         *  dependent definitions.
   389         */
   390    
   391        /*
   392         *  @_nodoc
   393         *  ======== switchToIsrStack ========
   394         *  If not on ISR stack already, switch to it.
   395         *  Used by the Swi scheduler and interrupt dispatcher.
   396         *
   397         *  This function must be implemented by all Hwi modules
   398         *  name) because it can't be _E and _F'd due to its
   399         *  inherent stack switching behavior.
   400         *  
   401         *  @b(returns)     token to use with 
   402         *                  switchToTaskStack()
   403         */
   404        /*  Char *ti_bios_family_xxx_Hwi_switchToIsrStack(); */
   405    
   406        /*
   407         *  @_nodoc
   408         *  ======== switchToTaskStack ========
   409         *  If at bottom of ISR stack, switch to Task stack.
   410         *  Used by the Swi scheduler and interrupt dispatcher.
   411         *  
   412         *  This function must be implemented by all Hwi modules
   413         *  and be given this exact name (without a target specific
   414         *  name) because it can't be _E and _F'd due to its
   415         *  inherent stack switching behavior.
   416         *  
   417         *  @param(key)     token returned by
   418         *                  switchToIsrStack()
   419         */
   420        /*  Void ti_bios_family_xxx_Hwi_switchToTaskStack(Char *key); */
   421    
   422        /*!
   423         *  ======== disableInterrupt ========
   424         *  Disable a specific interrupt.
   425         *
   426         *  Disable a specific interrupt identified by an interrupt number.
   427         *
   428         *  @param(intNum)  interrupt number to disable
   429         *  @b(returns)     key to restore previous enable/disable state
   430         */
   431        UInt disableInterrupt(UInt intNum);
   432    
   433        /*!
   434         *  ======== enableInterrupt ========
   435         *  Enable a specific interrupt.
   436         *
   437         *  Enables a specific interrupt identified by an interrupt number.
   438         *
   439         *  @param(intNum)  interrupt number to enable
   440         *  @b(returns)     key to restore previous enable/disable state
   441         */
   442        UInt enableInterrupt(UInt intNum);
   443    
   444        /*!
   445         *  ======== restoreInterrupt ========
   446         *  Restore a specific interrupt's enabled/disabled state.
   447         *
   448         *  Restores a specific interrupt identified by an interrupt number.
   449         *  restoreInterrupt is generally used to restore an interrupt to its state
   450         *  before {@link #disableInterrupt} or {@link #enableInterrupt} was
   451         *  invoked
   452         *
   453         *  @param(intNum)  interrupt number to restore
   454         *  @param(key)     key returned from enableInt or disableInt
   455         */
   456        Void restoreInterrupt(UInt intNum, UInt key);
   457    
   458        /*!
   459         *  ======== clearInterrupt ========
   460         *  Clear a specific interrupt.
   461         *
   462         *  Clears a specific interrupt's pending status.
   463         *  The implementation is family specific.
   464         *
   465         *  @param(intNum)  interrupt number to enable
   466         */
   467        Void clearInterrupt(UInt intNum);
   468    
   469    instance:
   470    
   471        /*!
   472         *  ======== create ========
   473         *  Create a dispatched interrupt.
   474         *
   475         *  A Hwi dispatcher table entry is created and filled with the 
   476         *  function specified by the fxn parameter and the attributes 
   477         *  specified by the params parameter.
   478         *
   479         *  If params is NULL, the Hwi's dispatcher properties are assigned a 
   480         *  default set of values. Otherwise, the Hwi's dispatcher properties
   481         *  are specified by a structure of type Hwi_Params.
   482         *
   483         *  The maskSetting element defines the dispatcherAutoNestingSupport 
   484         *  behavior of the interrupt.
   485         *
   486         *  The arg element is a generic argument that is passed to the plugged
   487         *  function as its only parameter. The default value is 0.
   488         *
   489         *  The enableInt element determines whether the interrupt should be
   490         *  enabled in the IER by create.
   491         *
   492         *  Hwi_create returns a pointer to the created Hwi object.
   493         *
   494         *  @param(intNum)  interrupt number
   495         *  @param(hwiFxn)  pointer to ISR function
   496         */
   497        create(Int intNum, FuncPtr hwiFxn);
   498    
   499        /*! maskSetting. Default is {@link #MaskingOption Hwi_MaskingOption_SELF}. */
   500        config MaskingOption maskSetting = MaskingOption_SELF;
   501    
   502        /*! ISR function argument. Default is 0. */
   503        config UArg arg = 0;
   504    
   505        /*! Enable this interrupt now? Default is true. */
   506        config Bool enableInt = true;
   507        
   508        /*! 
   509         *  Interrupt event ID (Interrupt Selection Number) 
   510         *  Default is -1. 
   511         *  Not all targets/devices support this instance parameter. 
   512         *  On those that don't, this parameter is ignored.
   513         */
   514        config Int eventId = -1;
   515    
   516        /*! 
   517         *  Interrupt priority. 
   518         *  Default is -1.
   519         *  Not all targets/devices support this instance parameter. 
   520         *  On those that don't, this parameter is ignored.
   521         */
   522        config Int priority = -1;
   523    
   524        /*!
   525         *  ======== getFunc ========
   526         *  Get Hwi function and arg
   527         *
   528         *  @param(arg)     pointer for returning hwi's ISR function argument
   529         *  @b(returns)     hwi's ISR function
   530         */
   531        FuncPtr getFunc(UArg *arg);
   532    
   533        /*!
   534         *  ======== setFunc ========
   535         *  Overwrite Hwi function and arg
   536         *
   537         *  Replaces a Hwi object's hwiFxn function originally
   538         *  provided in {@link #create}.
   539         *
   540         *  @param(fxn)     pointer to ISR function
   541         *  @param(arg)     argument to ISR function
   542         */
   543        Void setFunc(FuncPtr fxn, UArg arg);
   544    
   545        /*!
   546         *  ======== getHookContext ========
   547         *  Get hook instance's context for a hwi.
   548         *
   549         *  @b(returns)     hook instance's context for hwi
   550         */
   551        Ptr getHookContext(Int id);
   552    
   553        /*!
   554         *  ======== setHookContext ========
   555         *  Set hook instance's context for a hwi.
   556         *
   557         *  @param(id)            hook instance's ID
   558         *  @param(hookContext)   value to write to context
   559         */
   560        Void setHookContext(Int id, Ptr hookContext);
   561    
   562        /*!
   563         *  ======== getIrp ========
   564         *  Get address of interrupted instruction.
   565         *
   566         *  @b(returns)     most current IRP of a hwi
   567         */
   568        Irp getIrp();
   569    }
   570    /*
   571     *  @(#) ti.sysbios.interfaces; 2, 0, 0, 0,350; 12-18-2009 15:12:57; /db/vtree/library/trees/avala/avala-m19x/src/
   572     */
   573