1    /*
     2     * Copyright (c) 2016-2020, 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    /* REQ_TAG(SYSBIOS-1234) */
   222    module Hwi inherits ti.sysbios.interfaces.IHwi
   223    {
   224    
   225        // -------- Module Constants --------
   226    
   227        config UInt DEFAULT_INT_PRIORITY = 0xF;
   228    
   229        config UInt NUM_INTERRUPTS;
   230    
   231        config UInt dummyIRQ = 0x0;
   232    
   233        // -------- Module Types --------
   234    
   235        /*! Hwi vector function type definition. */
   236        typedef Void (*VectorFuncPtr)(void);
   237    
   238        /*! @_nodoc Hwi plug function type definition. */
   239        typedef Void (*PlugFuncPtr)(void);
   240    
   241        /*! Interrupt type. IRQ or FIQ */
   242        enum Type {
   243            Type_IRQ,                /*! IRQ interrupt. */
   244            Type_FIQ                 /*! FIQ interrupt. */
   245        };
   246    
   247        /*! Interrupt trigger type. Pulse or Level triggered */
   248        enum TriggerType {
   249            TriggerType_LEVEL,
   250            TriggerType_PULSE
   251        };
   252    
   253        /*! @_nodoc */
   254        metaonly struct BasicView {
   255            Ptr         halHwiHandle;
   256            String      label;
   257            String      type;
   258            String      triggerType;
   259            Int         intNum;
   260            String      fxn;
   261            UArg        arg;
   262            Ptr         irp;
   263            String      status;
   264        };
   265    
   266        /*! @_nodoc */
   267        metaonly struct ModuleView {
   268            String      options[4];
   269            SizeT       hwiStackPeak;
   270            SizeT       hwiStackSize;
   271            Ptr         hwiStackBase;
   272        };
   273    
   274        /*! @_nodoc */
   275        @Facet
   276        metaonly config ViewInfo.Instance rovViewInfo =
   277            ViewInfo.create({
   278                viewMap: [
   279                    ['Basic', {type: ViewInfo.INSTANCE,
   280                               viewInitFxn: 'viewInitBasic',
   281                               structName: 'BasicView'}],
   282                    ['Module', {type: ViewInfo.MODULE,
   283                                viewInitFxn: 'viewInitModule',
   284                                structName: 'ModuleView'}]
   285                ]
   286            });
   287    
   288        // -------- Module Parameters --------
   289    
   290        /*! Reset Handler. Default is c_int00 */
   291        metaonly config VectorFuncPtr resetFunc;
   292    
   293        /*!
   294         *  Undefined instruction exception handler.
   295         *  Default is set to an internal exception handler.
   296         */
   297        metaonly config VectorFuncPtr undefinedInstFunc;
   298    
   299        /*! SWI Handler. Default is internal SWI handler */
   300        metaonly config VectorFuncPtr swiFunc;
   301    
   302        /*!
   303         *  Prefetch abort exception handler.
   304         *  Default is set to an internal exception handler.
   305         */
   306        metaonly config VectorFuncPtr prefetchAbortFunc;
   307    
   308        /*!
   309         *  Data abort exception handler.
   310         *  Default is set to an internal exception handler.
   311         */
   312        metaonly config VectorFuncPtr dataAbortFunc;
   313    
   314        /*!
   315         *  Reserved exception handler.
   316         *  Default is set to an internal exception handler.
   317         */
   318        metaonly config VectorFuncPtr reservedFunc;
   319    
   320        /*!
   321         *  @_nodoc
   322         *  IRQ interrupt handler.
   323         *  Default is set to an internal exception dispatcher.
   324         */
   325        metaonly config VectorFuncPtr irqFunc;
   326    
   327        /*!
   328         *  FIQ interrupt handler.
   329         *  Default is set to an internal FIQ dispatcher.
   330         */
   331        metaonly config VectorFuncPtr fiqFunc;
   332    
   333        /*!
   334         *  FIQ stack pointer. Default = null.
   335         *  (Indicates that stack is to be created using
   336         *  staticPlace())
   337         */
   338        config Ptr fiqStack = null;
   339    
   340        /*!
   341         *  FIQ stack size in MAUs.
   342         *  Default is 1024 bytes.
   343         */
   344        metaonly config SizeT fiqStackSize = 1024;
   345    
   346        /*!
   347         *  Memory section used for FIQ stack
   348         *  Default is null.
   349         */
   350        metaonly config String fiqStackSection = null;
   351    
   352        /*!
   353         *  Non dispatched IRQ stack pointer. Default = null.
   354         *  (Indicates that stack is to be created using
   355         *  staticPlace())
   356         */
   357        config Ptr irqStack = null;
   358    
   359        /*!
   360         *  Non dispatched IRQ stack size in MAUs.
   361         *  Default is 1024 bytes.
   362         */
   363        metaonly config SizeT irqStackSize = 1024;
   364    
   365        /*!
   366         *  Memory section used for non dispatched IRQ stack
   367         *  Default is null.
   368         */
   369        metaonly config String irqStackSection = null;
   370    
   371        /*!
   372         *  SVC stack pointer. Default = null.
   373         *  (Indicates that stack is to be created using
   374         *  staticPlace())
   375         */
   376        config Ptr svcStack = null;
   377    
   378        /*!
   379         *  SVC stack size in MAUs.
   380         *  Default is 128 bytes.
   381         */
   382        metaonly config SizeT svcStackSize = 128;
   383    
   384        /*!
   385         *  Memory section used for SVC stack
   386         *  Default is null.
   387         */
   388        metaonly config String svcStackSection = null;
   389    
   390        /*!
   391         * @_nodoc
   392         * VIM base address
   393         */
   394        metaonly config Ptr vimBaseAddress;
   395    
   396        /*!
   397         *  Error raised when Hwi is already defined
   398         */
   399        config Error.Id E_alreadyDefined = {
   400            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   401        };
   402    
   403        /*!
   404         *  Error raised if an attempt is made to create a Hwi
   405         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   406         */
   407        config Error.Id E_badIntNum = {
   408            msg: "E_badIntNum, intnum: %d is out of range"
   409        };
   410    
   411        /*!
   412         *  Error raised when an undefined interrupt has fired.
   413         */
   414        config Error.Id E_undefined = {
   415            msg: "E_undefined: Hwi undefined, intNum: %d"
   416        };
   417    
   418        /*!
   419         *  Error raised when reserved priority 0 is used
   420         */
   421        config Error.Id E_reservedPriority = {
   422            msg: "E_reservedPriority: Hwi priority 0 reserved for workaround of Pulsar Dual R5F-SS interrupt preemption issue."
   423        };
   424    
   425        /*!
   426         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   427         */
   428        config Log.Event LM_begin = {
   429            mask: Diags.USER1 | Diags.USER2,
   430            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   431        };
   432    
   433        /*!
   434         *  Issued just after return from Hwi function (with interrupts disabled)
   435         */
   436        config Log.Event LD_end = {
   437            mask: Diags.USER2,
   438            msg: "LD_end: hwi: 0x%x"
   439        };
   440    
   441    
   442        // -------- Module Functions --------
   443    
   444        /*!
   445         *  ======== disable ========
   446         *  Globally disable interrupts.
   447         *
   448         *  Hwi_disable globally disables hardware interrupts and returns an
   449         *  opaque key indicating whether interrupts were globally enabled or
   450         *  disabled on entry to Hwi_disable().
   451         *  The actual value of the key is target/device specific and is meant
   452         *  to be passed to Hwi_restore().
   453         *
   454         *  Call Hwi_disable before a portion of a function that needs
   455         *  to run without interruption. When critical processing is complete, call
   456         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   457         *
   458         *  Servicing of interrupts that occur while interrupts are disabled is
   459         *  postponed until interrupts are reenabled. However, if the same type
   460         *  of interrupt occurs several times while interrupts are disabled,
   461         *  the interrupt's function is executed only once when interrupts are
   462         *  reenabled.
   463         *
   464         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   465         *  an enabled interrupt occurred while interrupts are disabled.
   466         *
   467         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   468         *  are already disabled in main(), such a call has no effect.
   469         *
   470         *  @a(constraints)
   471         *  If a Task switching API such as
   472         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
   473         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   474         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   475         *  {@link ti.sysbios.knl.Task#yield Task_yield()}
   476         *  is invoked which results in a context switch while
   477         *  interrupts are disabled, an embedded call to
   478         *  {@link #enable Hwi_enable} occurs
   479         *  on the way to the new thread context which unconditionally re-enables
   480         *  interrupts. Interrupts will remain enabled until a subsequent
   481         *  {@link #disable Hwi_disable}
   482         *  invocation.
   483         *
   484         *  Swis always run with interrupts enabled.
   485         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   486         *  interrupts.
   487         *
   488         *  @b(returns)     opaque key for use by Hwi_restore()
   489         */
   490        @Macro
   491        override UInt disable();
   492    
   493        /*!
   494         *  ======== enable ========
   495         */
   496        @Macro
   497        override UInt enable();
   498    
   499        /*!
   500         *  ======== restore ========
   501         */
   502        @Macro
   503        override Void restore(UInt key);
   504    
   505        /*!
   506         *  ======== getHandle ========
   507         *  Returns pointer to Hwi instance object.
   508         *
   509         *  @param(intNum)  interrupt number
   510         */
   511        Object *getHandle(UInt intNum);
   512    
   513        /*!
   514         *  ======== enableFIQ ========
   515         *  Enable FIQ interrupts.
   516         *
   517         *  @b(returns)     previous FIQ interrupt enable/disable state
   518         */
   519        @Macro
   520        UInt enableFIQ();
   521    
   522        /*!
   523         *  ======== disableFIQ ========
   524         *  Disable FIQ interrupts.
   525         *
   526         *  @b(returns)     previous FIQ interrupt enable/disable state
   527         */
   528        @Macro
   529        UInt disableFIQ();
   530    
   531        /*!
   532         *  ======== restoreFIQ ========
   533         *  Restore FIQ interrupts.
   534         *
   535         *  @param(key)     enable/disable state to restore
   536         */
   537        @Macro
   538        Void restoreFIQ(UInt key);
   539    
   540        /*!
   541         *  ======== enableIRQ ========
   542         *  Enable IRQ interrupts.
   543         *
   544         *  @param(key)     enable/disable state to restore
   545         */
   546        UInt enableIRQ();
   547    
   548        /*!
   549         *  ======== disableIRQ ========
   550         *  Disable IRQ interrupts.
   551         *
   552         *  @b(returns)     previous IRQ interrupt enable/disable state
   553         */
   554        UInt disableIRQ();
   555    
   556        /*!
   557         *  ======== restoreIRQ ========
   558         *  Restore IRQ interrupts.
   559         *
   560         *  @param(key)     enable/disable state to restore
   561         */
   562        Void restoreIRQ(UInt key);
   563    
   564        /*!
   565         *  ======== setPriority ========
   566         *  Set an interrupt's priority.
   567         *
   568         *  Not an instance function so that it can be used
   569         *  with non-dispatched interrupts.
   570         *
   571         *  @param(intNum)      ID of interrupt
   572         *  @param(priority)    priority
   573         */
   574        /* REQ_TAG(SYSBIOS-1269) */
   575        Void setPriority(UInt intNum, UInt priority);
   576    
   577        /*!
   578         *  @_nodoc
   579         *  ======== setType ========
   580         *  Set an interrupt's type (FIQ/IRQ).
   581         *
   582         *  Not an instance function so that it can be used
   583         *  with non-dispatched interrupts.
   584         *
   585         *  @param(intNum)      ID of interrupt
   586         *  @param(type)        type = FIQ/IRQ
   587         */
   588        Void setType(UInt intNum, Type type);
   589    
   590        /*!
   591         *  @_nodoc
   592         *  ======== setTriggerType ========
   593         *  Set an interrupt's trigger type (Pulse/Level).
   594         *
   595         *  @param(intNum)      ID of interrupt
   596         *  @param(triggerType) triggerType = Pulse/Level
   597         */
   598        Void setTriggerType(UInt intNum, TriggerType triggerType);
   599    
   600    instance:
   601    
   602        /*!
   603         *  Interrupt priority.
   604         *
   605         *  There are a total of 16 different priority levels and therefore
   606         *  the priority field can take a value from 0-15. Lower numeric
   607         *  value means a higher effective interrupt priority.
   608         *
   609         *  The default value of -1 is used as a flag to indicate
   610         *  the lowest (logical) device-specific priority value.
   611         *
   612         *  Not all targets/devices support this instance parameter.
   613         *  On those that don't, this parameter is ignored.
   614         */
   615        override config Int priority = -1;
   616    
   617        /*! Interrupt type (IRQ/FIQ). Default is IRQ. */
   618        config Type type = Type_IRQ;
   619    
   620        /*! Interrupt trigger type (Pulse/Level). Default is Level triggered. */
   621        config TriggerType triggerType = TriggerType_LEVEL;
   622    
   623        /*!
   624         *  ======== reconfig ========
   625         *  Reconfigure a dispatched interrupt.
   626         */
   627        Void reconfig(FuncPtr fxn, const Params *params);
   628    
   629    internal:   /* not for client use */
   630    
   631        struct InterruptGroup {
   632            UInt32 RAWSTATUSSET;              /*! Interrupt Raw Status/Set */
   633            UInt32 ENABLEDSTATUSCLEAR;        /*! Interrupt Enabled Status/Clear */
   634            UInt32 ENABLEDSET;                /*! Interrupt Enabled Set */
   635            UInt32 ENABLEDCLEAR;              /*! Interrupt Enabled Clear */
   636            UInt32 IRQENABLEDSTATUSCLEAR;     /*! IRQ Enabled Status/Clear */
   637            UInt32 FIQENABLEDSTATUSCLEAR;     /*! FIQ Enabled Status/Clear */
   638            UInt32 INTERRUPTMAP;              /*! Interrupt Map - IRQ or FIQ */
   639            UInt32 TYPEMAP;                   /*! Type Map - Level or Pulse */
   640        };
   641    
   642        /*
   643         *  Vectored Interrupt Manager (VIM) Registers
   644         */
   645        struct VIM {
   646            UInt32 REVISION;          /*! 0x0000 Revision Register */
   647            UInt32 INFO;              /*! 0x0004 Info Register */
   648            UInt32 PRIOIRQ;           /*! 0x0008 Prioritized IRQ */
   649            UInt32 PRIOFIQ;           /*! 0x000C Prioritized FIQ */
   650            UInt32 IRQGROUPSTATUS;    /*! 0x0010 IRQ Group Status */
   651            UInt32 FIQGROUPSTATUS;    /*! 0x0014 FIQ Group Status */
   652            UInt32 IRQVECADDRESS;     /*! 0x0018 IRQ Vector Address */
   653            UInt32 FIQVECADDRESS;     /*! 0x001C FIQ Vector Address */
   654            UInt32 ACTIVEIRQ;         /*! 0x0020 Active IRQ */
   655            UInt32 ACTIVEFIQ;         /*! 0x0024 Active FIQ */
   656            UInt32 hole0[2];          /*! 0x0028-0x002F Reserved */
   657            UInt32 DECVECADDRESS;     /*! 0x0030 DED Vector Address */
   658            UInt32 hole1[243];        /*! 0x0034-0x03FF Reserved */
   659            InterruptGroup GROUP[32]; /*! 0x0400-0x07FF Interrupt Group M Regs */
   660            UInt32 hole2[512];        /*! 0x0800-0x0FFF Reserved */
   661            UInt32 PRIORITY[1024];    /*! 0x1000-0x1FFF Interrupt N Priority Reg */
   662            UInt32 VECTOR[1024];      /*! 0x2000-0x2FFF Vector Register */
   663        };
   664    
   665        /*
   666         * VIM registers needed for ROV Hwi Basic view
   667         *
   668         * This is needed to avoid reading IRQ/FIQVECADDRESS.
   669         */
   670        struct VIM_GROUP {
   671            InterruptGroup GROUP[32]; /*! 0x0400-0x07FF Interrupt Group M Regs */
   672        };
   673    
   674        /*
   675         *  ======== vim ========
   676         *  Symbol "Hwi_vim" is a physical device
   677         */
   678        extern volatile VIM vim;
   679    
   680        /*
   681         *  ======== intEnable ========
   682         *  Initial interrupt enable register value
   683         */
   684        config UInt32 intEnable[];
   685    
   686        /*
   687         * Swi and Task module function pointers.
   688         * Used to decouple Hwi from Swi and Task when
   689         * dispatcherSwiSupport or
   690         * dispatcherTaskSupport is false.
   691         */
   692        config UInt (*swiDisable)();
   693        config Void (*swiRestoreHwi)(UInt);
   694        config UInt (*taskDisable)();
   695        config Void (*taskRestoreHwi)(UInt);
   696    
   697        /*
   698         *  ======== postInit ========
   699         *  finish initializing static and dynamic Hwis
   700         */
   701        Int postInit(Object *hwi, Error.Block *eb);
   702    
   703        /*
   704         *  ======== initIntController ========
   705         */
   706        Void initIntController();
   707    
   708        /* assembly code mode registers setup */
   709        Void init();
   710    
   711        /* Interrupt Dispatcher assembly code wrapper */
   712        Void dispatchIRQ();
   713    
   714        /* FIQ Interrupt Dispatcher */
   715        Void dispatchFIQC();
   716    
   717        /* IRQ Interrupt Dispatcher */
   718        Void dispatchIRQC(Irp irp);
   719    
   720        /* non plugged interrupt handler */
   721        Void nonPluggedHwiHandler();
   722    
   723        /*
   724         *  ======== plug ========
   725         *  Plug an interrupt vector with an ISR address.
   726         *
   727         *  @param(intNum)  interrupt number
   728         *  @param(fxn)     pointer to ISR function
   729         */
   730        Void plug(UInt intNum, PlugFuncPtr fxn);
   731    
   732        /*!
   733         *  const array to hold all HookSet objects.
   734         */
   735        config HookSet hooks[length] = [];
   736    
   737        /*! Meta World Only Hwi Configuration Object. */
   738        metaonly struct InterruptObj {
   739            Bool used;              /* Interrupt already defined? */
   740            FuncPtr fxn;            /* Dispatched ISR function */
   741        };
   742    
   743        /*!
   744         * Meta-only array of interrupt objects.
   745         * This meta-only array of Hwi config objects is initialized
   746         * in Hwi.xs:module$meta$init().
   747         */
   748        metaonly config InterruptObj interrupt[];
   749    
   750        struct Instance_State {
   751            Type        type;                   // Interrupt Type
   752            UArg        arg;                    // Argument to Hwi function.
   753            FuncPtr     fxn;                    // Hwi function.
   754            Int         intNum;                 // Interrupt number
   755            Irp         irp;                    // current IRP
   756            Ptr         hookEnv[];
   757            Int         priority;               // Interript priority
   758            TriggerType triggerType;            // Trigger Type
   759        };
   760    
   761        struct Module_State {
   762            Char        *taskSP;                /* temporary storage of interrupted
   763                                                   Task's SP during ISR execution */
   764            Char        *isrStack;              /* Points to isrStack address */
   765            Ptr         isrStackBase;           /* _stack */
   766            Ptr         isrStackSize;           /* _STACK_SIZE */
   767            Char        fiqStack[];             /* buffer used for FIQ stack */
   768            SizeT       fiqStackSize;
   769            Char        irqStack[];             /* buffer used for non dispatched
   770                                                   IRQ stack */
   771            SizeT       irqStackSize;
   772            Char        svcStack[];             /* buffer used for SVC stack */
   773            SizeT       svcStackSize;
   774            Handle      dispatchTable[];        /* dispatch table */
   775            UInt        spuriousInts;           /* Count of spurious interrupts */
   776        };
   777    }