1    /*
     2     * Copyright (c) 2016-2018, 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    package ti.sysbios.family.arm.v7r.keystone3;
    36    
    37    import xdc.runtime.Diags;
    38    import xdc.runtime.Error;
    39    import xdc.runtime.Log;
    40    import xdc.rov.ViewInfo;
    41    
    42    import ti.sysbios.interfaces.IHwi;
    43    
    44    /*!
    45     *  ======== Hwi ========
    46     *  Hardware Interrupt Support Module.
    47     *
    48     *  //TODO Note: FIQ interrupt handler must save FIQ context before using FPU
    49     *
    50     *  This Hwi module provides Keystone3 Vectored Interrupt Manager (VIM)
    51     *  specific implementations of the APIs defined in
    52     *  {@link ti.sysbios.interfaces.IHwi IHwi}.
    53     *
    54     *  Additional device-specific APIs are also provided.
    55     *
    56     *  @a(Minimal Latency Interrupts)
    57     *  For applications requiring extremely low interrupt latency, this Hwi module
    58     *  allows the user to create FIQ interrupts that have a light weight interrupt
    59     *  dispatcher. Though not a precisely correct classification, these interrupts
    60     *  are referred to as "Zero latency" interrupts.
    61     *
    62     *  "FIQ" aka "Zero latency" interrupts can be created by setting the Hwi_Param
    63     *  {@link #type} to Hwi_Type_FIQ. FIQ interrupts offer low interrupt latency
    64     *  as they do not have to pass through the regular SYS/BIOS interrupt
    65     *  dispatcher and are always enabled. When auto nesting is enabled, all
    66     *  VIM interrupts of equal or lower priority will be disabled while the
    67     *  interrupt is being serviced. However, none of the "Zero latency" interrupts
    68     *  are disabled (masked).
    69     *
    70     *  Unlike regular IRQ interrupts, FIQ interrupts do not run on the System stack
    71     *  but on their own FIQ stack. The stack pointer, size and section name for the
    72     *  FIQ stack can be set using the {@link #fiqStack}, {@link #fiqStackSize}
    73     *  and {@link #fiqStackSection} module wide configuration params.
    74     *
    75     *  @a(Constraints of using FIQ aka Zero latency interrupts)
    76     *  FIQ Interrupts bypass the regular SYS/BIOS interrupt dispatcher and are
    77     *  therefore not allowed to call ANY SYS/BIOS APIs that affect thread
    78     *  scheduling. Examples of API that should not be invoked are:
    79     *
    80     *  @p(dlist)
    81     *    - Swi_post(),
    82     *    - Semaphore_post(),
    83     *    - Event_post(),
    84     *    - Task_yield()
    85     *  @p
    86     *
    87     *  Here's an example showing how to create a Hwi of FIQ type:
    88     *
    89     *  @p(code)
    90     *  *.cfg:
    91     *  var Hwi = xdc.useModule('ti.sysbios.family.arm.v7r.keystone3.Hwi');
    92     *  Hwi.fiqStackSize = 2048;
    93     *  Hwi.fiqStackSection = ".myFiqStack"
    94     *  Program.sectMap[".myFiqStack"] = "RAM";
    95     *
    96     *  *.c:
    97     *  #include <xdc/std.h>
    98     *  #include <xdc/runtime/System.h>
    99     *
   100     *  #include <ti/sysbios/BIOS.h>
   101     *  #include <ti/sysbios/family/arm/v7r/keystone3/Hwi.h>
   102     *
   103     *  #include <xdc/cfg/global.h>
   104     *
   105     *  Void myIsrFIQ(UArg arg)
   106     *  {
   107     *      ...
   108     *  }
   109     *
   110     *  Void main(Void)
   111     *  {
   112     *      Hwi_Params hwiParams;
   113     *
   114     *      Hwi_Params_init(&hwiParams);
   115     *      hwiParams.type = Hwi_Type_FIQ;
   116     *      Hwi_create(INT_NUM_FIQ, myIsrFIQ, &hwiParams, NULL);
   117     *      ...
   118     *
   119     *      BIOS_start();
   120     *  }
   121     *  @p
   122     *
   123     *  @a(Interrupt Priorities)
   124     *  FIQ interrupts have the highest priority i.e. any interrupt of FIQ type will
   125     *  have a higher priority than any other interrupt of IRQ type.
   126     *
   127     *  IRQ interrupts (or vectored interrupts) can be assigned different priority
   128     *  levels, ranging from 0-15. Lower priority levels imply a higher effective
   129     *  interrupt priority. Priority level can be set by writing to the
   130     *  {@link #priority} Hwi param. By default, all interrupts are set to the
   131     *  lowest priority (highest priority value).
   132     *
   133     *  If multiple interrupts that are at the same priority level occur at the
   134     *  same time, the smaller lower interrupt number wins arbitration.
   135     *
   136     *  @a(Interrupt Masking Options)
   137     *  In this Hwi module, the maskSetting instance configuration parameter is
   138     *  ignored. Effectively, only the {@link #MaskingOption_LOWER} is supported.
   139     *
   140     *  @a(More Hwi examples)
   141     *  Here's an example showing how to construct a Hwi at runtime:
   142     *  @p(code)
   143     *  *.c:
   144     *  #include <ti/sysbios/family/arm/v7r/keystone3/Hwi.h>
   145     *
   146     *  Hwi_Struct hwiStruct;
   147     *
   148     *  Void myIsrIRQ(UArg arg)
   149     *  {
   150     *      ...
   151     *  }
   152     *
   153     *  Void main(Void)
   154     *  {
   155     *      Hwi_Params hwiParams;
   156     *
   157     *      Hwi_Params_init(&hwiParams);
   158     *      Hwi_construct(&hwiStruct, INT_NUM_IRQ, myIsrIRQ, &hwiParams, NULL);
   159     *      ...
   160     *      BIOS_start();
   161     *  }
   162     *  @p
   163     *
   164     *  @p(html)
   165     *  <h3> Calling Context </h3>
   166     *  <table border="1" cellpadding="3">
   167     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
   168     *
   169     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   170     *    <!--                                                                                                                 -->
   171     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   172     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   173     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   174     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   175     *    <tr><td> {@link #disableIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   176     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   177     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   178     *    <tr><td> {@link #enableIRQ}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   179     *    <tr><td> {@link #getHandle}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   180     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   181     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   182     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   183     *    <tr><td> {@link #restoreIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   184     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   185     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   186     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   187     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   188     *    <tr><td> {@link #reconfig}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   189     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   190     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   191     *    <tr><td colspan="6"> Definitions: <br />
   192     *       <ul>
   193     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   194     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   195     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   196     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   197     *           <ul>
   198     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
   199     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   200     *             <li> During main().</li>
   201     *             <li> During BIOS.startupFxns.</li>
   202     *           </ul>
   203     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   204     *           <ul>
   205     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   206     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
   207     *           </ul>
   208     *       </ul>
   209     *    </td></tr>
   210     *
   211     *
   212     *  </table>
   213     *  @p
   214     */
   215    
   216    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   217    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   218    @InstanceInitStatic     /* allow constructs in static only systems */
   219    @CustomHeader
   220    
   221    module Hwi inherits ti.sysbios.interfaces.IHwi
   222    {
   223    
   224        // -------- Module Constants --------
   225    
   226        config UInt DEFAULT_INT_PRIORITY = 0xF;
   227    
   228        config UInt NUM_INTERRUPTS;
   229    
   230        // -------- Module Types --------
   231    
   232        /*! Hwi vector function type definition. */
   233        typedef Void (*VectorFuncPtr)(void);
   234    
   235        /*! @_nodoc Hwi plug function type definition. */
   236        typedef Void (*PlugFuncPtr)(void);
   237    
   238        /*! Interrupt type. IRQ or FIQ */
   239        enum Type {
   240            Type_IRQ,                /*! IRQ interrupt. */
   241            Type_FIQ                 /*! FIQ interrupt. */
   242        };
   243    
   244        /*! Interrupt trigger type. Pulse or Level triggered */
   245        enum TriggerType {
   246            TriggerType_LEVEL,
   247            TriggerType_PULSE
   248        };
   249    
   250        /*! @_nodoc */
   251        metaonly struct BasicView {
   252            Ptr         halHwiHandle;
   253            String      label;
   254            String      type;
   255            String      triggerType;
   256            Int         intNum;
   257            String      fxn;
   258            UArg        arg;
   259            Ptr         irp;
   260            String      status;
   261        };
   262    
   263        /*! @_nodoc */
   264        metaonly struct ModuleView {
   265            String      options[4];
   266            SizeT       hwiStackPeak;
   267            SizeT       hwiStackSize;
   268            Ptr         hwiStackBase;
   269        };
   270    
   271        /*! @_nodoc */
   272        @Facet
   273        metaonly config ViewInfo.Instance rovViewInfo =
   274            ViewInfo.create({
   275                viewMap: [
   276                    ['Basic', {type: ViewInfo.INSTANCE,
   277                               viewInitFxn: 'viewInitBasic',
   278                               structName: 'BasicView'}],
   279                    ['Module', {type: ViewInfo.MODULE,
   280                                viewInitFxn: 'viewInitModule',
   281                                structName: 'ModuleView'}]
   282                ]
   283            });
   284    
   285        // -------- Module Parameters --------
   286    
   287        /*! Reset Handler. Default is c_int00 */
   288        metaonly config VectorFuncPtr resetFunc;
   289    
   290        /*!
   291         *  Undefined instruction exception handler.
   292         *  Default is set to an internal exception handler.
   293         */
   294        metaonly config VectorFuncPtr undefinedInstFunc;
   295    
   296        /*! SWI Handler. Default is internal SWI handler */
   297        metaonly config VectorFuncPtr swiFunc;
   298    
   299        /*!
   300         *  Prefetch abort exception handler.
   301         *  Default is set to an internal exception handler.
   302         */
   303        metaonly config VectorFuncPtr prefetchAbortFunc;
   304    
   305        /*!
   306         *  Data abort exception handler.
   307         *  Default is set to an internal exception handler.
   308         */
   309        metaonly config VectorFuncPtr dataAbortFunc;
   310    
   311        /*!
   312         *  Reserved exception handler.
   313         *  Default is set to an internal exception handler.
   314         */
   315        metaonly config VectorFuncPtr reservedFunc;
   316    
   317        /*!
   318         *  @_nodoc
   319         *  IRQ interrupt handler.
   320         *  Default is set to an internal exception dispatcher.
   321         */
   322        metaonly config VectorFuncPtr irqFunc;
   323    
   324        /*!
   325         *  FIQ interrupt handler.
   326         *  Default is set to an internal FIQ dispatcher.
   327         */
   328        metaonly config VectorFuncPtr fiqFunc;
   329    
   330        /*!
   331         *  FIQ stack pointer. Default = null.
   332         *  (Indicates that stack is to be created using
   333         *  staticPlace())
   334         */
   335        config Ptr fiqStack = null;
   336    
   337        /*!
   338         *  FIQ stack size in MAUs.
   339         *  Default is 1024 bytes.
   340         */
   341        metaonly config SizeT fiqStackSize = 1024;
   342    
   343        /*!
   344         *  Memory section used for FIQ stack
   345         *  Default is null.
   346         */
   347        metaonly config String fiqStackSection = null;
   348    
   349        /*!
   350         *  Non dispatched IRQ stack pointer. Default = null.
   351         *  (Indicates that stack is to be created using
   352         *  staticPlace())
   353         */
   354        config Ptr irqStack = null;
   355    
   356        /*!
   357         *  Non dispatched IRQ stack size in MAUs.
   358         *  Default is 1024 bytes.
   359         */
   360        metaonly config SizeT irqStackSize = 1024;
   361    
   362        /*!
   363         *  Memory section used for non dispatched IRQ stack
   364         *  Default is null.
   365         */
   366        metaonly config String irqStackSection = null;
   367    
   368        /*!
   369         * @_nodoc
   370         * VIM base address
   371         */
   372        metaonly config Ptr vimBaseAddress;
   373    
   374        /*!
   375         *  Error raised when Hwi is already defined
   376         */
   377        config Error.Id E_alreadyDefined = {
   378            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   379        };
   380    
   381        /*!
   382         *  Error raised if an attempt is made to create a Hwi
   383         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   384         */
   385        config Error.Id E_badIntNum = {
   386            msg: "E_badIntNum, intnum: %d is out of range"
   387        };
   388    
   389        /*!
   390         *  Error raised when an undefined interrupt has fired.
   391         */
   392        config Error.Id E_undefined = {
   393            msg: "E_undefined: Hwi undefined, intNum: %d"
   394        };
   395    
   396        /*!
   397         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   398         */
   399        config Log.Event LM_begin = {
   400            mask: Diags.USER1 | Diags.USER2,
   401            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   402        };
   403    
   404        /*!
   405         *  Issued just after return from Hwi function (with interrupts disabled)
   406         */
   407        config Log.Event LD_end = {
   408            mask: Diags.USER2,
   409            msg: "LD_end: hwi: 0x%x"
   410        };
   411    
   412    
   413        // -------- Module Functions --------
   414    
   415        /*!
   416         *  ======== disable ========
   417         *  Globally disable interrupts.
   418         *
   419         *  Hwi_disable globally disables hardware interrupts and returns an
   420         *  opaque key indicating whether interrupts were globally enabled or
   421         *  disabled on entry to Hwi_disable().
   422         *  The actual value of the key is target/device specific and is meant
   423         *  to be passed to Hwi_restore().
   424         *
   425         *  Call Hwi_disable before a portion of a function that needs
   426         *  to run without interruption. When critical processing is complete, call
   427         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   428         *
   429         *  Servicing of interrupts that occur while interrupts are disabled is
   430         *  postponed until interrupts are reenabled. However, if the same type
   431         *  of interrupt occurs several times while interrupts are disabled,
   432         *  the interrupt's function is executed only once when interrupts are
   433         *  reenabled.
   434         *
   435         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   436         *  an enabled interrupt occurred while interrupts are disabled.
   437         *
   438         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   439         *  are already disabled in main(), such a call has no effect.
   440         *
   441         *  @a(constraints)
   442         *  If a Task switching API such as
   443         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
   444         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   445         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   446         *  {@link ti.sysbios.knl.Task#yield Task_yield()}
   447         *  is invoked which results in a context switch while
   448         *  interrupts are disabled, an embedded call to
   449         *  {@link #enable Hwi_enable} occurs
   450         *  on the way to the new thread context which unconditionally re-enables
   451         *  interrupts. Interrupts will remain enabled until a subsequent
   452         *  {@link #disable Hwi_disable}
   453         *  invocation.
   454         *
   455         *  Swis always run with interrupts enabled.
   456         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   457         *  interrupts.
   458         *
   459         *  @b(returns)     opaque key for use by Hwi_restore()
   460         */
   461        @Macro
   462        override UInt disable();
   463    
   464        /*!
   465         *  ======== enable ========
   466         */
   467        @Macro
   468        override UInt enable();
   469    
   470        /*!
   471         *  ======== restore ========
   472         */
   473        @Macro
   474        override Void restore(UInt key);
   475    
   476        /*!
   477         *  ======== getHandle ========
   478         *  Returns pointer to Hwi instance object.
   479         *
   480         *  @param(intNum)  interrupt number
   481         */
   482        Object *getHandle(UInt intNum);
   483    
   484        /*!
   485         *  ======== enableFIQ ========
   486         *  Enable FIQ interrupts.
   487         *
   488         *  @b(returns)     previous FIQ interrupt enable/disable state
   489         */
   490        @Macro
   491        UInt enableFIQ();
   492    
   493        /*!
   494         *  ======== disableFIQ ========
   495         *  Disable FIQ interrupts.
   496         *
   497         *  @b(returns)     previous FIQ interrupt enable/disable state
   498         */
   499        @Macro
   500        UInt disableFIQ();
   501    
   502        /*!
   503         *  ======== restoreFIQ ========
   504         *  Restore FIQ interrupts.
   505         *
   506         *  @param(key)     enable/disable state to restore
   507         */
   508        @Macro
   509        Void restoreFIQ(UInt key);
   510    
   511        /*!
   512         *  ======== enableIRQ ========
   513         *  Enable IRQ interrupts.
   514         *
   515         *  @param(key)     enable/disable state to restore
   516         */
   517        UInt enableIRQ();
   518    
   519        /*!
   520         *  ======== disableIRQ ========
   521         *  Disable IRQ interrupts.
   522         *
   523         *  @b(returns)     previous IRQ interrupt enable/disable state
   524         */
   525        UInt disableIRQ();
   526    
   527        /*!
   528         *  ======== restoreIRQ ========
   529         *  Restore IRQ interrupts.
   530         *
   531         *  @param(key)     enable/disable state to restore
   532         */
   533        Void restoreIRQ(UInt key);
   534    
   535        /*!
   536         *  ======== setPriority ========
   537         *  Set an interrupt's priority.
   538         *
   539         *  Not an instance function so that it can be used
   540         *  with non-dispatched interrupts.
   541         *
   542         *  @param(intNum)      ID of interrupt
   543         *  @param(priority)    priority
   544         */
   545        Void setPriority(UInt intNum, UInt priority);
   546    
   547        /*!
   548         *  @_nodoc
   549         *  ======== setType ========
   550         *  Set an interrupt's type (FIQ/IRQ).
   551         *
   552         *  Not an instance function so that it can be used
   553         *  with non-dispatched interrupts.
   554         *
   555         *  @param(intNum)      ID of interrupt
   556         *  @param(type)        type = FIQ/IRQ
   557         */
   558        Void setType(UInt intNum, Type type);
   559    
   560        /*!
   561         *  @_nodoc
   562         *  ======== setTriggerType ========
   563         *  Set an interrupt's trigger type (Pulse/Level).
   564         *
   565         *  @param(intNum)      ID of interrupt
   566         *  @param(triggerType) triggerType = Pulse/Level
   567         */
   568        Void setTriggerType(UInt intNum, TriggerType triggerType);
   569    
   570    instance:
   571    
   572        /*!
   573         *  Interrupt priority.
   574         *
   575         *  There are a total of 16 different priority levels and therefore
   576         *  the priority field can take a value from 0-15. Lower numeric
   577         *  value means a higher effective interrupt priority.
   578         *
   579         *  The default value of -1 is used as a flag to indicate
   580         *  the lowest (logical) device-specific priority value.
   581         *
   582         *  Not all targets/devices support this instance parameter.
   583         *  On those that don't, this parameter is ignored.
   584         */
   585        override config Int priority = -1;
   586    
   587        /*! Interrupt type (IRQ/FIQ). Default is IRQ. */
   588        config Type type = Type_IRQ;
   589    
   590        /*! Interrupt trigger type (Pulse/Level). Default is Level triggered. */
   591        config TriggerType triggerType = TriggerType_LEVEL;
   592    
   593        /*!
   594         *  ======== reconfig ========
   595         *  Reconfigure a dispatched interrupt.
   596         */
   597        Void reconfig(FuncPtr fxn, const Params *params);
   598    
   599    internal:   /* not for client use */
   600    
   601        struct InterruptGroup {
   602            UInt32 RAWSTATUSSET;              /*! Interrupt Raw Status/Set */
   603            UInt32 ENABLEDSTATUSCLEAR;        /*! Interrupt Enabled Status/Clear */
   604            UInt32 ENABLEDSET;                /*! Interrupt Enabled Set */
   605            UInt32 ENABLEDCLEAR;              /*! Interrupt Enabled Clear */
   606            UInt32 IRQENABLEDSTATUSCLEAR;     /*! IRQ Enabled Status/Clear */
   607            UInt32 FIQENABLEDSTATUSCLEAR;     /*! FIQ Enabled Status/Clear */
   608            UInt32 INTERRUPTMAP;              /*! Interrupt Map - IRQ or FIQ */
   609            UInt32 TYPEMAP;                   /*! Type Map - Level or Pulse */
   610        };
   611    
   612        /*
   613         *  Vectored Interrupt Manager (VIM) Registers
   614         */
   615        struct VIM {
   616            UInt32 REVISION;          /*! 0x0000 Revision Register */
   617            UInt32 INFO;              /*! 0x0004 Info Register */
   618            UInt32 PRIOIRQ;           /*! 0x0008 Prioritized IRQ */
   619            UInt32 PRIOFIQ;           /*! 0x000C Prioritized FIQ */
   620            UInt32 IRQGROUPSTATUS;    /*! 0x0010 IRQ Group Status */
   621            UInt32 FIQGROUPSTATUS;    /*! 0x0014 FIQ Group Status */
   622            UInt32 IRQVECADDRESS;     /*! 0x0018 IRQ Vector Address */
   623            UInt32 FIQVECADDRESS;     /*! 0x001C FIQ Vector Address */
   624            UInt32 ACTIVEIRQ;         /*! 0x0020 Active IRQ */
   625            UInt32 ACTIVEFIQ;         /*! 0x0024 Active FIQ */
   626            UInt32 hole0[2];          /*! 0x0028-0x002F Reserved */
   627            UInt32 DECVECADDRESS;     /*! 0x0030 DED Vector Address */
   628            UInt32 hole1[243];        /*! 0x0034-0x03FF Reserved */
   629            InterruptGroup GROUP[32]; /*! 0x0400-0x07FF Interrupt Group M Regs */
   630            UInt32 hole2[512];        /*! 0x0800-0x0FFF Reserved */
   631            UInt32 PRIORITY[1024];    /*! 0x1000-0x1FFF Interrupt N Priority Reg */
   632            UInt32 VECTOR[1024];      /*! 0x2000-0x2FFF Vector Register */
   633        };
   634    
   635        /*
   636         *  ======== vim ========
   637         *  Symbol "Hwi_vim" is a physical device
   638         */
   639        extern volatile VIM vim;
   640    
   641        /*
   642         *  ======== intEnable ========
   643         *  Initial interrupt enable register value
   644         */
   645        config UInt32 intEnable[];
   646    
   647        /*
   648         * Swi and Task module function pointers.
   649         * Used to decouple Hwi from Swi and Task when
   650         * dispatcherSwiSupport or
   651         * dispatcherTaskSupport is false.
   652         */
   653        config UInt (*swiDisable)();
   654        config Void (*swiRestoreHwi)(UInt);
   655        config UInt (*taskDisable)();
   656        config Void (*taskRestoreHwi)(UInt);
   657    
   658        /*
   659         *  ======== postInit ========
   660         *  finish initializing static and dynamic Hwis
   661         */
   662        Int postInit(Object *hwi, Error.Block *eb);
   663    
   664        /*
   665         *  ======== initIntController ========
   666         */
   667        Void initIntController();
   668    
   669        /* assembly code mode registers setup */
   670        Void init();
   671    
   672        /* Interrupt Dispatcher assembly code wrapper */
   673        Void dispatchIRQ();
   674    
   675        /* FIQ Interrupt Dispatcher */
   676        Void dispatchFIQC();
   677    
   678        /* IRQ Interrupt Dispatcher */
   679        Void dispatchIRQC(Irp irp);
   680    
   681        /* non plugged interrupt handler */
   682        Void nonPluggedHwiHandler();
   683    
   684        /*
   685         *  ======== plug ========
   686         *  Plug an interrupt vector with an ISR address.
   687         *
   688         *  @param(intNum)  interrupt number
   689         *  @param(fxn)     pointer to ISR function
   690         */
   691        Void plug(UInt intNum, PlugFuncPtr fxn);
   692    
   693        /*!
   694         *  const array to hold all HookSet objects.
   695         */
   696        config HookSet hooks[length] = [];
   697    
   698        /*! Meta World Only Hwi Configuration Object. */
   699        metaonly struct InterruptObj {
   700            Bool used;              /* Interrupt already defined? */
   701            FuncPtr fxn;            /* Dispatched ISR function */
   702        };
   703    
   704        /*!
   705         * Meta-only array of interrupt objects.
   706         * This meta-only array of Hwi config objects is initialized
   707         * in Hwi.xs:module$meta$init().
   708         */
   709        metaonly config InterruptObj interrupt[];
   710    
   711        struct Instance_State {
   712            Type        type;                   // Interrupt Type
   713            UArg        arg;                    // Argument to Hwi function.
   714            FuncPtr     fxn;                    // Hwi function.
   715            Int         intNum;                 // Interrupt number
   716            Irp         irp;                    // current IRP
   717            Ptr         hookEnv[];
   718            Int         priority;               // Interript priority
   719            TriggerType triggerType;            // Trigger Type
   720        };
   721    
   722        struct Module_State {
   723            Char        *taskSP;                /* temporary storage of interrupted
   724                                                   Task's SP during ISR execution */
   725            Char        *isrStack;              /* Points to isrStack address */
   726            Ptr         isrStackBase;           /* _stack */
   727            Ptr         isrStackSize;           /* _STACK_SIZE */
   728            Char        fiqStack[];             /* buffer used for FIQ stack */
   729            SizeT       fiqStackSize;
   730            Char        irqStack[];             /* buffer used for non dispatched
   731                                                   IRQ stack */
   732            SizeT       irqStackSize;
   733            Handle      dispatchTable[];        /* dispatch table */
   734            UInt        spuriousInts;           /* Count of spurious interrupts */
   735        };
   736    }