1    /* 
     2     * Copyright (c) 2012, 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     *  ======== Hwi.xdc ========
    34     *
    35     */
    36    
    37    
    38    package ti.sysbios.family.windows;
    39    
    40    import xdc.runtime.Assert;
    41    import xdc.runtime.Diags;
    42    import xdc.runtime.Error;
    43    import xdc.runtime.IHeap;
    44    import xdc.runtime.Log;
    45    
    46    /*!
    47     *  ======== Hwi ========
    48     *  Windows emulation Hardware Interrupt Support Module
    49     *
    50     *  This Hwi module provides Windows emulation specific implementations of 
    51     *  the APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
    52     *
    53     *  Additional Windows emulation specific APIs are also provided.
    54     *
    55     *  @a(NOTE)
    56     *  In this Hwi module implementation, the instance config parameter value
    57     *  {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
    58     *  Statically configuring a Hwi object's {@link #Params.maskSetting} to 
    59     *  {@link #MaskingOption_LOWER} will result in the generation of a benign
    60     *  build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
    61     *  silently converted to {@link #MaskingOption_SELF}.
    62     *
    63     *  @p(html)
    64     *  <h3> Calling Context </h3>
    65     *  <table border="1" cellpadding="3">
    66     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    67     *
    68     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    69     *    <!--                                                                                                                 -->
    70     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    71     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    73     *    <tr><td> {@link #disableIER}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    75     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    76     *    <tr><td> {@link #enableIER}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    77     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    78     *    <tr><td> {@link #getHandle}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    79     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    80     *    <tr><td> {@link #plug}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    81     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    82     *    <tr><td> {@link #restoreIER}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    83     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    85     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    87     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td> {@link #reconfig}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    89     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    91     *    <tr><td colspan="6"> Definitions: <br />
    92     *       <ul>
    93     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    94     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    95     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    96     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    97     *           <ul>
    98     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
    99     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   100     *             <li> During main().</li>
   101     *             <li> During BIOS.startupFxns.</li>
   102     *           </ul>
   103     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   104     *           <ul>
   105     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   106     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
   107     *           </ul>
   108     *       </ul>
   109     *    </td></tr>
   110     *  </table>
   111     *  @p
   112     *
   113     */
   114    
   115    @Template("./Hwi.xdt")  /* generates the dispatcher */
   116    @ModuleStartup          /* plugs signals statically plugged using Hwi_plug  */
   117    
   118    module Hwi inherits ti.sysbios.interfaces.IHwi
   119    {
   120        // -------- Module Constants --------
   121    
   122        //! Dispatcher supports 16 interrupts.
   123        const Int NUM_INTERRUPTS = 16;
   124    
   125        // -------- Module Types --------
   126    
   127        //! @_nodoc Hwi plug function type definition.
   128        typedef Void (*PlugFuncPtr)(UInt);
   129    
   130        //! Isr function type definition.
   131        typedef Void (*IsrFxn)(UInt);
   132    
   133        /*! Assert: invalid interrupt number.
   134         *
   135         *  Interrupt number must be greater than or equal to 0 and less
   136         *  than {@link #NUM_INTERRUPTS}.
   137         *
   138         *  @a(Raised_In)
   139         *  @p(html)
   140         *  {@link #disableInterrupt}<br />
   141         *  {@link #enableInterrupt}<br />
   142         *  {@link #plug}<br />
   143         *  {@link ti.sysbios.interfaces.IHwi#post}<br />
   144         *
   145         *  @a(See_Also)
   146         *  @p(html)
   147         *  {@link xdc.runtime.Assert}<br />
   148         *  {@link xdc.runtime.Diags}<br />
   149         *  @p
   150         */
   151        config Assert.Id A_interNum = {
   152            msg: "A_interNum: interrupt number must be less then NUM_INTERRUPTS"
   153        };
   154    
   155        /*! Assert: there must be a pending interrupt
   156         *
   157         *  The Hwi module decided to take an interrupt, but upon inspecting
   158         *  the IER and IFR registers did not find an enabled pending interrupt.
   159         */
   160        config Assert.Id A_noPendingIntr = {
   161            msg: "A_noPendingIntr: there must be a pending interrupt"
   162        };
   163    
   164        /*! Assert: an unplugged interrupt was raised.
   165         *
   166         *  An interrupt was raised which does not have an ISR plugged into
   167         *  the Interrupt Service Table (IST).
   168         *
   169         *  @a(Raised_In)
   170         *  @p(html)
   171         *  {@link #post}<br />
   172         *  @p
   173         */
   174        config Assert.Id A_pluggedIntr = {
   175            msg: "interrupt must be plugged"
   176        };
   177    
   178        /*! Error: memory allocation request failed.
   179         *
   180         *  A request into the Windows runtime library for memory has failed.
   181         *
   182         *  @a(Raised_In)
   183         *  @p(html)
   184         *  {@link #startup}<br />
   185         *  @p
   186         */
   187        config Error.Id E_calloc = {
   188            msg: "calloc failed"
   189        };
   190    
   191        /*! Error: CreateEvent failed.
   192         *
   193         *  A CreateEvent call into the Win32 API has failed.
   194         *
   195         *  @a(Raised_In)
   196         *  @p(html)
   197         *  {@link #startup}<br />
   198         *  @p
   199         */
   200        config Error.Id E_event = {
   201            msg: "CreateEvent failed"
   202        };
   203    
   204        /*!
   205         *  Error raised when Hwi is already defined
   206         */
   207        config Error.Id E_alreadyDefined = {
   208            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   209        };
   210    
   211        /*!
   212         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   213         */
   214        config Log.Event LM_begin = {
   215            mask: Diags.USER1 | Diags.USER2,
   216            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d"
   217        };
   218    
   219        /*!
   220         *  Issued just after return from Hwi function (with interrupts disabled)
   221         */
   222        config Log.Event LD_end = {
   223            mask: Diags.USER2,
   224            msg: "LD_end: hwi: 0x%x"
   225        };
   226    
   227        /*! Log: missed interrupt detected
   228         *
   229         *  An interrupt is being raised which has a previous instance
   230         *  recorded in the IFR register still waiting to be serviced.
   231         *
   232         *  @a(Raised_In)
   233         *  @p(html)
   234         *  {@link #post}<br />
   235         *  @p
   236         */
   237        config Log.Event LW_missedIntr = {
   238            mask: Diags.USER3,
   239            msg: "Warning: LW_missedIntr: missed interrupt detected: %d"
   240        };
   241    
   242        // -------- Module Parameters --------
   243    
   244        /*! Non-dispatched interrupt object.
   245         *
   246         *  Provided so that XGCONF users can easily plug non-dispatched
   247         *  interrupts.
   248         */
   249        metaonly struct NonDispatchedInterrupt {
   250            Int             intNum;         //! interrupt number
   251            PlugFuncPtr     fxn;            //! plugged ISR function
   252            Bool            enableInt;      //! interrupt enable flag
   253            Int             eventId;        //! source event id
   254        };
   255    
   256        /*! Non-dispatched interrupt array.
   257         *
   258         *  Provided so that XGCONF users can easily plug non-dispatched
   259         *  interrupts.
   260         */
   261        metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
   262    
   263        // -------- Module Functions --------
   264    
   265        /*!
   266         *  ======== disableIER ========
   267         *  Disable certain maskable interrupts.
   268         *
   269         *  Atomically disables specific interrupts by clearing the bits 
   270         *  specified by mask in the Interrupt Enable Register (IER).
   271         *
   272         *  The IER bits to be cleared should be set to 1 in the mask.
   273         *
   274         *  @param(mask)    Bitmask of interrupts to disable.
   275         *  @b(returns)     Previous IER settings bitmask.
   276         */
   277        Bits16 disableIER(Bits16 mask);
   278    
   279        /*!
   280         *  ======== enableIER ========
   281         *  Enable certain maskable interrupts.
   282         *
   283         *  Atomically enables specific interrupts by setting the bits 
   284         *  specified by mask in the Interrupt Enable Register (IER).
   285         *
   286         *  The IER bits to be set should be set to 1 in the mask.
   287         *
   288         *  @param(mask)    Bitmask of interrupts to enable.
   289         *  @b(returns)     Previous IER settings bitmask.
   290         */
   291        Bits16 enableIER(Bits16 mask);
   292    
   293        /*!
   294         *  ======== restoreIER ========
   295         *  Restore maskable interrupts to the state they were in 
   296         *  when either disableIER() or enableIER() was called.
   297         *
   298         *  Atomically writes the given mask to the IER register. Typically used
   299         *  to restore the IER register to the state returned from a call to
   300         *  either {@link #disableIER()} or {@link #enableIER()}.
   301         *
   302         *  @param(mask)    Bitmask of interrupts to restore.
   303         *  @b(returns)     Previous IER settings bitmask.
   304         */
   305        Bits16 restoreIER(Bits16 mask);
   306    
   307        /*!
   308         *  ======== getHandle ========
   309         *  Return a pointer to an Hwi instance object.
   310         *
   311         *  @param(intNum)  Interrupt number.
   312         */
   313        Handle getHandle(UInt intNum);
   314    
   315        /*!
   316         *  @_nodoc
   317         *  ======== inUseMeta ========
   318         *  Check for Hwi already in use.
   319         *
   320         *  For internal SYS/BIOS use only. Should be called prior
   321         *  to any internal Hwi.create().
   322         *
   323         *  @param(intNum)  Interrupt number.
   324         */
   325        metaonly Bool inUseMeta(UInt intNum);
   326    
   327        /*!
   328         *  @_nodoc
   329         *  ======== plug ========
   330         *  Plug an interrupt vector with an ISR address at runtime.
   331         *
   332         *  Writes the ISR address into the Interrupt Service Table (IST)
   333         *  at the address corresponding to the `intNum`. This function
   334         *  does not enable the interrupt. Use {@link #enableIER()} to
   335         *  enable the interrupt.
   336         *
   337         *  @param(intNum) Interrupt number. The interrupt number must be
   338         *      in the range 0 - ({@link #NUM_INTERRUPTS} - 1).
   339         *  @param(fxn) Pointer to ISR function. The ISR function
   340         *      pointer cannot be NULL.
   341         *
   342         *  @a(Asserts)
   343         *  @p(html)
   344         *  {@link #A_interNum}<br />
   345         *  @p
   346         *
   347         *  @a(See_Also)
   348         *  {@link #enableIER()}
   349         */
   350        Void plug(UInt intNum, PlugFuncPtr fxn);
   351    
   352        /*!
   353         *  ======== plugMeta ========
   354         *  Plug an interrupt vector with an ISR address at config time.
   355         *
   356         *  @param(intNum) Interrupt number. The interrupt number must be
   357         *      in the range 0 - ({@link #NUM_INTERRUPTS} - 1).
   358         *  @param(fxn) Pointer to ISR function. The ISR function
   359         *      pointer cannot be NULL.
   360         */
   361        metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
   362    
   363    instance:
   364    
   365        /*! 
   366         *  Dispatcher auto-nesting interrupt disable mask.
   367         * 
   368         *  When the dispatcher's auto interrupt nesting support feature 
   369         *  is enabled (see {@link #dispatcherAutoNestingSupport}), 
   370         *  this mask defines which IER bits are disabled prior to invoking
   371         *  the user's ISR function with GIE = 1.
   372         *  
   373         *  disableMask bits set to 1 correspond to IER bits that will be cleared
   374         *  prior to invoking the ISR.
   375         *
   376         *  The value of this mask is normally auto-calculated based on the
   377         *  value of the maskSetting. However, manual setting of this
   378         *  mask is enabled by setting the maskSetting to 
   379         *  {@link #MaskingOption MaskingOption_BITMASK}.
   380         *
   381         *  The default value is derived from the 
   382         *  {@link #MaskingOption MaskingOption_SELF}
   383         *  maskSetting.
   384         */
   385        config Bits16 disableMask = 0;
   386    
   387        /*! 
   388         *  Dispatcher auto-nesting interrupt restore mask.
   389         * 
   390         *  When the dispatcher's auto interrupt nesting support feature 
   391         *  is enabled (see {@link #dispatcherAutoNestingSupport}), 
   392         *  this mask defines which IER bits are restored to their previous
   393         *  setting upon return from the user's ISR function.
   394         *  
   395         *  restoreMask bits set to 1 correspond to IER bits that will be restored.
   396         *  
   397         *  The value of this mask is normally auto-calculated based on the
   398         *  value of the maskSetting. However, manual setting of this
   399         *  mask is enabled by setting the maskSetting to 
   400         *  {@link #MaskingOption MaskingOption_BITMASK}.
   401         *
   402         *  The default value is derived from the 
   403         *  {@link #MaskingOption MaskingOption_SELF}
   404         *  maskSetting.
   405         */
   406        config Bits16 restoreMask = 0;
   407    
   408        /*!
   409         *  Interrupt priority. Not supported on this target.
   410         */
   411        override config Int priority = 0;
   412    
   413        /*!
   414         *  ======== reconfig ========
   415         *  Reconfigure a dispatched interrupt.
   416         */
   417        Void reconfig(FuncPtr fxn, const Params *params);
   418    
   419    internal:   /* not for client use */
   420    
   421        /* 
   422         * Swi and Task module function pointers. 
   423         * Used to decouple Hwi from Swi and Task when 
   424         * dispatcherSwiSupport or
   425         * dispatcherTaskSupport is false.
   426         */
   427        config UInt (*swiDisable)();
   428        config Void (*swiRestoreHwi)(UInt);
   429        config UInt (*taskDisable)();
   430        config Void (*taskRestoreHwi)(UInt);
   431    
   432        /*
   433         *  ======== dispatch ========
   434         *  Interrupt Dispatcher
   435         */
   436        Void dispatch(UInt intNum);
   437    
   438        /*
   439         *  ======== init ========
   440         */
   441        Void init();
   442    
   443        /*
   444         *  ======== unPluggedInterrupt ========
   445         *  unPlugged interrupt handler
   446         */
   447        Void unPluggedInterrupt(UInt num);
   448    
   449        /* const array to hold all HookSet objects */
   450        config HookSet hooks[length] = [];
   451    
   452        /*! Meta World Only Hwi Configuration Object. */
   453        metaonly struct InterruptObj {
   454            String name;            /* symbol used for vector table entry */
   455            Bool        used;           /* Interrupt already defined? */
   456            Bool        useDispatcher;  /* Should dispatcher handle this intr?*/
   457            FuncPtr     fxn;            /* Dispatched ISR function. */
   458            PlugFuncPtr pfxn;           /* "Hwi_plug'd" ISR function. */
   459        };
   460    
   461        /*!
   462         *  Meta-only array of interrupt objects.
   463         *  This meta-only array of Hwi config objects is initialized
   464         *  in Hwi.xs:module$meta$init().
   465         */
   466        metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
   467    
   468        struct PrivateData;
   469    
   470        struct Instance_State {
   471            Bits16          disableMask;    /* Interrupts to mask during ISR.   */
   472            Bits16          restoreMask;    /* Interrupts to restore after ISR. */
   473            UArg            arg;            /* Argument to Hwi function.        */
   474            FuncPtr         fxn;            /* Hwi function.                    */
   475            Irp             irp;            /* current IRP                      */
   476            Ptr             hookEnv[];
   477        };
   478    
   479        struct Module_State {
   480            Bits16          ierMask;        /* Initial IER mask                 */
   481            Handle          dispatchTable[NUM_INTERRUPTS]; /* dispatch table   */
   482            Bool            GIE;
   483            Bits16          IER;
   484            Bits16          IFR;
   485            UInt            intrNum;
   486            IsrFxn          IST[NUM_INTERRUPTS];
   487            PrivateData     *privateData;   /* Windows types not allowed in xdc */
   488        };
   489    }
   490    /*
   491     *  @(#) ti.sysbios.family.windows; 2, 0, 0, 0,543; 2-24-2012 11:40:28; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   492    
   493     */
   494