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    import xdc.rov.ViewInfo;
    38    
    39    import xdc.runtime.Diags;
    40    import xdc.runtime.Log;
    41    import xdc.runtime.Assert;
    42    import xdc.runtime.Error;
    43    
    44    /*!
    45     *  ======== Hwi ========
    46     *  ARP32 Hardware Interrupt Support Module.
    47     *  
    48     *  This Hwi module provides ARP32 family-specific implementations of the
    49     *  APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
    50     *
    51     *  Additional ARP32 device-specific APIs are also provided.
    52     *
    53     *  @a(NOTE)
    54     *  In this Hwi module implementation, the instance config parameter value
    55     *  {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
    56     *  Statically configuring a Hwi object's {@link #Params.maskSetting} to 
    57     *  {@link #MaskingOption_LOWER} will result in the generation of a benign
    58     *  build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
    59     *  silently converted to {@link #MaskingOption_SELF}.
    60     *
    61     *  @p(html)
    62     *  <h3> Calling Context </h3>
    63     *  <table border="1" cellpadding="3">
    64     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    65     *
    66     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    67     *    <!--                                                                                                                 -->
    68     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    69     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    70     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    71     *    <tr><td> {@link #disableIER}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    73     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #enableIER}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    75     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    76     *    <tr><td> {@link #getHandle}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    77     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    78     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    79     *    <tr><td> {@link #restoreIER}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    80     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    81     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    82     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    83     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    85     *    <tr><td> {@link #reconfig}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    87     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td colspan="6"> Definitions: <br />
    89     *       <ul>
    90     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    91     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    92     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    93     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    94     *           <ul>
    95     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
    96     *             <li> During xdc.runtime.Startup.lastFxns. </li>
    97     *             <li> During main().</li>
    98     *             <li> During BIOS.startupFxns.</li>
    99     *           </ul>
   100     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   101     *           <ul>
   102     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   103     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
   104     *           </ul>
   105     *       </ul>
   106     *    </td></tr>
   107     *
   108     *  </table>
   109     *  @p
   110     *
   111     */
   112    
   113    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   114    @ModuleStartup         /* generate a call to Hwi_init at startup */
   115    
   116    module Hwi inherits ti.sysbios.interfaces.IHwi
   117    {
   118        // -------- Module Constants --------
   119    
   120        /*! ARP32 supports 32 interrupt events */
   121        const Int NUM_INTERRUPTS = 32;
   122        
   123        /*! ARP32 supports 8 interrupt vectors */
   124        const Int NUM_VECTORS = 8;
   125    
   126        // -------- Module Types --------
   127    
   128        /*! @_nodoc Hwi plug function type definition. */
   129        typedef Void (*PlugFuncPtr)(void);
   130    
   131        /*!
   132         *  ======== BasicView ========
   133         *  @_nodoc
   134         */
   135        metaonly struct BasicView {
   136            Ptr         halHwiHandle;
   137            String      label;
   138            UInt        intNum;
   139            UInt        vector;
   140            String      fxn; 
   141            UArg        arg;           // Argument to Hwi function.
   142            Ptr         irp; 
   143            String      disableIerMask;   // Interrupts to mask during ISR.
   144            String      restoreIerMask;   // Interrupts to restore after ISR.
   145        };
   146    
   147        /*!
   148         *  ======== ModuleView ========
   149         *  @_nodoc
   150         */
   151        metaonly struct ModuleView {
   152            String      options[4];
   153            SizeT       hwiStackPeak;
   154            SizeT       hwiStackSize;
   155            Ptr         hwiStackBase;
   156        };
   157    
   158        /*!
   159         *  ======== rovViewInfo ========
   160         *  @_nodoc
   161         */
   162        @Facet
   163        metaonly config ViewInfo.Instance rovViewInfo = 
   164            ViewInfo.create({
   165                viewMap: [
   166                    ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',    structName: 'BasicView'}],
   167                    ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule',   structName: 'ModuleView'}]
   168                ]
   169            });
   170    
   171        // -------- Module Parameters --------
   172    
   173        /*!
   174         *  non-dispatched interrupt object.
   175         *  provided so that XGCONF users can easily plug non-dispatched interrupts
   176         */
   177        metaonly struct NonDispatchedInterrupt {
   178            Int             vectorNum;
   179            PlugFuncPtr     fxn;        /*! "Hwi_plug'd" ISR function. */
   180            Bool            enableInt;
   181        };
   182    
   183        /*!
   184         *  non-dispatched interrupt array.
   185         *  provided so that XGCONF users can easily plug non-dispatched interrupts
   186         */
   187        metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
   188    
   189        /*!
   190         *  Alternate reset vector address. Default is undefined.
   191         *
   192         *  if initialized by the user then an additional reset vector
   193         *  is created and placed in the ".resetVector" section.
   194         *  To place the .resetVector section into a specific memory section,
   195         *  add the following command to your config script:
   196         *  @p(code)
   197         *  Program.sectMap[".resetVector"] = YourMemorySection;
   198         *  @p
   199         */
   200        metaonly config Ptr resetVectorAddress;
   201        
   202        /*!
   203         *  Error raised when Hwi is already defined
   204         */
   205        config Error.Id E_alreadyDefined = {
   206            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   207        };
   208    
   209        /*!
   210         *  Error raised when a Hwi function that has not been implemented
   211         *  for the arp32 has been called
   212         */
   213        config Error.Id E_notImplemented = {
   214            msg: "E_notImplemented: Function not implemented: %s"
   215        };
   216    
   217        /*!
   218         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   219         */
   220        config Log.Event LM_begin = {
   221            mask: Diags.USER1 | Diags.USER2,
   222            msg: "LM_begin: hwi: 0x%x, func: 0x%x, intNum: %d, irp: 0x%x"
   223        };
   224    
   225        /*!
   226         *  Issued just after return from Hwi function (with interrupts disabled)
   227         */
   228        config Log.Event LD_end = {
   229            mask: Diags.USER2,
   230            msg: "LD_end: hwi: 0x%x"
   231        };
   232    
   233        // -------- Module Functions --------
   234    
   235        /*!
   236         *  ======== disable ========
   237         */
   238        @Macro
   239        override UInt disable();
   240    
   241        /*!
   242         *  ======== enable ========
   243         */
   244        @Macro
   245        override UInt enable();
   246    
   247        /*!
   248         *  ======== restore ========
   249         */
   250        @Macro
   251        override Void restore(UInt key);
   252    
   253        /*! Stub to be plugged for dsp-eve interrupts */
   254        Void selfLoop(UArg arg);
   255    
   256        /*!
   257         *  ======== inUseMeta ========
   258         *  @_nodoc
   259         *  Check for Hwi already in use.
   260         *  For internal SYS/BIOS use only. 
   261         *  Should be called prior to any internal Hwi.create().
   262         *
   263         *  @param(intNum)  interrupt number
   264         */
   265        metaonly Bool inUseMeta(UInt intNum);
   266    
   267        /*!
   268         *  ======== plugMeta ========
   269         *  Statically plug an interrupt vector with an ISR address.
   270         *
   271         *  @param(intNum)  interrupt number
   272         *  @param(fxn)     pointer to ISR function
   273         */
   274        metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
   275    
   276        /*!
   277         *  ======== getHandle ========
   278         *  Returns Hwi_handle associated with interrupt number
   279         *
   280         *  @param(intNum)  interrupt number
   281         *  @b(returns)     handle associated with intNum
   282         */
   283        Handle getHandle(UInt intNum);
   284    
   285        /*!
   286         *  ======== disableIER ========
   287         *  Disable certain maskable interrupts.
   288         *
   289         *  Atomically disables specific interrupts by clearing the bits 
   290         *  specified by mask in the Interrupt Enable Register (IER).
   291         *
   292         *  The IER bits to be cleared should be set to 1 in the mask.
   293         *
   294         *  @param(mask)    bitmask of interrupts to disable
   295         *  @b(returns)     previous IER settings bitmask
   296         */
   297        Bits16 disableIER(Bits16 mask);
   298    
   299        /*!
   300         *  ======== enableIER ========
   301         *  Enable certain maskable interrupts.
   302         *
   303         *  Atomically enables specific interrupts by setting the bits 
   304         *  specified by mask in the Interrupt Enable Register (IER).
   305         *
   306         *  The IER bits to be set should be set to 1 in the mask.
   307         *
   308         *  @param(mask)    bitmask of interrupts to enable
   309         *  @b(returns)     previous IER settings bitmask
   310         */
   311        Bits16 enableIER(Bits16 mask);
   312    
   313        /*!
   314         *  ======== restoreIER ========
   315         *  Restore maskable interrupts to the state they were in 
   316         *  when either disableIER() or enableIER() was called.
   317         *
   318         *  Atomically writes the given mask to the IER register. Typically used
   319         *  to restore the IER register to the state returned from a call to
   320         *  either {@link #disableIER()} or {@link #enableIER()}.
   321         *
   322         *  @param(mask)    bitmask of interrupts to restore
   323         *  @b(returns)     previous IER settings bitmask
   324         */
   325        Bits16 restoreIER(Bits16 mask);
   326    
   327    instance:
   328    
   329        /*! 
   330         *  Dispatcher auto-nesting interrupt disable mask.
   331         * 
   332         *  When the dispatcher's auto interrupt nesting support feature 
   333         *  is enabled (see {@link #dispatcherAutoNestingSupport}), 
   334         *  this mask defines which IER bits are disabled prior to invoking
   335         *  the user's ISR function with GIE = 1.
   336         *  
   337         *  disableIerMask bits set to 1 correspond to IER bits that will be cleared
   338         *  prior to invoking the ISR.
   339         *
   340         *  The value of this mask is normally auto-calculated based on the
   341         *  value of the maskSetting. However, manual setting of this
   342         *  mask is enabled by setting the maskSetting to 
   343         *  {@link #MaskingOption MaskingOption_BITMASK}.
   344         *
   345         *  The default value is derived from the 
   346         *  {@link #MaskingOption MaskingOption_SELF}
   347         *  maskSetting.
   348         */
   349        config Bits16 disableIerMask = 0;
   350    
   351        /*! 
   352         *  Dispatcher auto-nesting interrupt restore mask.
   353         * 
   354         *  When the dispatcher's auto interrupt nesting support feature 
   355         *  is enabled (see {@link #dispatcherAutoNestingSupport}), 
   356         *  this mask defines which IER bits are restored to their previous
   357         *  setting upon return from the user's ISR function.
   358         *  
   359         *  restoreIerMask bits set to 1 correspond to IER bits that will be restored.
   360         *  
   361         *  The value of this mask is normally auto-calculated based on the
   362         *  value of the maskSetting. However, manual setting of this
   363         *  mask is enabled by setting the maskSetting to 
   364         *  {@link #MaskingOption MaskingOption_BITMASK}.
   365         *
   366         *  The default value is derived from the 
   367         *  {@link #MaskingOption MaskingOption_SELF}
   368         *  maskSetting.
   369         */
   370        config Bits16 restoreIerMask = 0;
   371    
   372        /*!
   373         *  Interrupt priority. Not supported on this target.
   374         */
   375        override config Int priority = 0;
   376    
   377        /*! 
   378         *  The interrupt vector where the event is enabled.
   379         */
   380        config Bits16 vectorNum = 4;
   381    
   382        /*!
   383         *  ======== reconfig ========
   384         *  Reconfigures a dispatched interrupt.
   385         *
   386         *  This function reconfigures the dispatched interrupt so the
   387         *  specified function is called with the specified parameters.
   388         *
   389         *  @param(fxn)     pointer to ISR function
   390         *  @param(params)  pointer to Hwi parameter structure
   391         */
   392        Void reconfig(FuncPtr fxn, const Params *params);
   393    
   394    internal:   /* not for client use */
   395    
   396        config Bits32 initialIerMask = 0;
   397    
   398        /* Interrupt Controller registers */
   399        struct IntcRegs {
   400            Bits32 rawStatus;   /* IRQ raw status */
   401            Bits32 status;      /* IRQ status     */
   402            Bits32 set;         /* IRQ set        */
   403            Bits32 clr;         /* IRQ clear      */
   404        };
   405    
   406        /* Interrupt Controller base address */
   407        config IntcRegs* INTCREGSBASEADDR = 0x40080200;
   408    
   409        /* 
   410         * Swi and Task module function pointers. 
   411         * Used to decouple Hwi from Swi and Task when 
   412         * dispatcherSwiSupport or
   413         * dispatcherTaskSupport is false.
   414         */
   415        config UInt (*swiDisable)();
   416        config Void (*swiRestoreHwi)(UInt);
   417        config UInt (*taskDisable)();
   418        config Void (*taskRestoreHwi)(UInt);
   419    
   420        /*!
   421         *  const array to hold all HookSet objects.
   422         */
   423        config HookSet hooks[length] = [];
   424    
   425        /* 
   426         *  ======== getIsrStackAddress ========
   427         *  Returns initial isrStack address.
   428         *  This API was developed solely for the Exception module
   429         *  to allow removal of the Hwi_link.xdt template definition
   430         *  of ti_sysbios_family_c64p_Hwi_isrStack which was not
   431         *  ROM-able
   432         */
   433        Char *getIsrStackAddress();
   434    
   435        /* Interrupt Dispatcher */
   436        Void dispatchC(Int vectorNum);
   437    
   438        /* unPlugged interrupt handler */
   439        Void unPluggedInterrupt();
   440        Void nmiInterrupt();
   441        Void swiInterrupt();
   442        Void undefInterrupt();
   443    
   444        /* stubs which call the dispatcher and pass intnum */
   445        Void dispIsr4();
   446        Void dispIsr5();
   447        Void dispIsr6();
   448        Void dispIsr7();
   449        
   450        /*! Meta World Only Hwi Configuration Object. */
   451        metaonly struct VectorObj {
   452            String name;            /* symbol used for vector table entry */
   453            Bool used;              /* Interrupt already defined? */
   454            Bool useDispatcher;     /* Should dispatcher handle this Int? */
   455            FuncPtr fxn;            /* Dispatched ISR function */
   456            PlugFuncPtr pfxn;       /* "Hwi_plug'd" ISR function. */
   457        };
   458    
   459        /*!
   460         * Meta-only array of interrupt objects.
   461         * This meta-only array of Hwi config objects is initialized
   462         * in Hwi.xs:module$meta$init().
   463         */
   464        metaonly config VectorObj vectors[NUM_VECTORS];
   465    
   466        /*! Meta World Only Hwi Configuration Object. */
   467        metaonly struct InterruptObj {
   468            Bool used;              /* Interrupt already defined? */
   469            Bool useDispatcher;     /* Should dispatcher handle this Int? */
   470            FuncPtr fxn;            /* Dispatched ISR function */
   471        };
   472    
   473        /*!
   474         * Meta-only array of interrupt objects.
   475         * This meta-only array of Hwi config objects is initialized
   476         * in Hwi.xs:module$meta$init().
   477         */
   478        metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
   479    
   480        struct Instance_State {
   481            Bits16  disableIerMask; // Interrupts to mask during ISR.
   482            Bits16  restoreIerMask; // Interrupts to restore after ISR.
   483            UInt16  vectorNum;      // Interrupt vector
   484            UInt16  index;          // ARP32 Interrupt controller index
   485            UArg    arg;            // Argument to Hwi function.
   486            FuncPtr fxn;            // Hwi function.
   487            Irp         irp;                // current IRP
   488            Ptr         hookEnv[];
   489        };
   490     
   491        struct Module_State {
   492            Bits32  interruptMask;  // Initial interrupt mask
   493            Bits16  disableIerMask; // Interrupts to mask during ISR.
   494            Bits16  restoreIerMask; // Interrupts to restore after ISR.
   495            volatile Int vectNum;   // Interrupt vector number
   496            Char    *taskSP;        // temporary storage of interrupted
   497                                    // Task's SP during ISR execution
   498            /* ROM */
   499            Char    *isrStack;      // Points to isrStack address
   500            Ptr         bss;                // bss address
   501    
   502            Irp     irp[NUM_VECTORS];               // current irp;
   503            Handle  dispatchTable[NUM_INTERRUPTS];  // dispatch table
   504        };
   505    }
   506    /*
   507     *  @(#) ti.sysbios.family.arp32; 2, 0, 0, 0,69; 2-24-2012 11:39:49; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   508    
   509     */
   510