1    /*
     2     * Copyright (c) 2016, 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.pl192;
    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     *  This Hwi module provides PL192 Vectored Interrupt Controller (VIC)
    49     *  specific implementations of the APIs defined in
    50     *  {@link ti.sysbios.interfaces.IHwi IHwi}.
    51     *
    52     *  Additional ARM device-specific APIs are also provided.
    53     *
    54     *  @a(Minimal Latency Interrupts)
    55     *  For applications requiring extremely low interrupt latency, this Hwi module
    56     *  allows the user to create FIQ interrupts that have a light weight interrupt
    57     *  dispatcher. Though not a precisely correct classification, these interrupts
    58     *  are referred to as "Zero latency" interrupts.
    59     *
    60     *  "FIQ" aka "Zero latency" interrupts can be created by setting the Hwi_Param
    61     *  {@link #type} to Hwi_Type_FIQ. FIQ interrupts offer low interrupt latency
    62     *  as they do not have to pass through the regular SYS/BIOS interrupt
    63     *  dispatcher and are always enabled. When auto nesting is enabled and masking
    64     *  option ALL or LOWER is used, some or all of the VIC interrupts will
    65     *  be disabled while the interrupt is being serviced. However, none of the
    66     *  "Zero latency" interrupts are disabled (masked).
    67     *
    68     *  Unlike regular IRQ interrupts, FIQ interrupts do not run on the System stack
    69     *  but on their own FIQ stack. The stack pointer, size and section name for the
    70     *  FIQ stack can be set using the {@link #fiqStack}, {@link #fiqStackSize}
    71     *  and {@link #fiqStackSection} module wide configuration params.
    72     *
    73     *  @a(Constraints of using FIQ aka Zero latency interrupts)
    74     *  FIQ Interrupts bypass the regular SYS/BIOS interrupt dispatcher and are
    75     *  therefore not allowed to call ANY SYS/BIOS APIs that affect thread
    76     *  scheduling. Examples of API that should not be invoked are:
    77     *
    78     *  @p(dlist)
    79     *    - Swi_post(),
    80     *    - Semaphore_post(),
    81     *    - Event_post(),
    82     *    - Task_yield()
    83     *  @p
    84     *
    85     *  Here's an example showing how to create a Hwi of FIQ type:
    86     *
    87     *  @p(code)
    88     *  *.cfg:
    89     *  var Hwi = xdc.useModule('ti.sysbios.family.arm.pl192.Hwi');
    90     *  Hwi.fiqStackSize = 2048;
    91     *  Hwi.fiqStackSection = ".myFiqStack"
    92     *  Program.sectMap[".myFiqStack"] = "RAM";
    93     *
    94     *  *.c:
    95     *  #include <xdc/std.h>
    96     *  #include <xdc/runtime/System.h>
    97     *
    98     *  #include <ti/sysbios/BIOS.h>
    99     *  #include <ti/sysbios/family/arm/pl192/Hwi.h>
   100     *
   101     *  #include <xdc/cfg/global.h>
   102     *
   103     *  Void myIsrFIQ(UArg arg)
   104     *  {
   105     *      ...
   106     *  }
   107     *
   108     *  Void main(Void)
   109     *  {
   110     *      Hwi_Params hwiParams;
   111     *
   112     *      Hwi_Params_init(&hwiParams);
   113     *      hwiParams.type = Hwi_Type_FIQ;
   114     *      Hwi_create(INT_NUM_FIQ, myIsrFIQ, &hwiParams, NULL);
   115     *      ...
   116     *
   117     *      BIOS_start();
   118     *  }
   119     *  @p
   120     *
   121     *  @a(Interrupt Latency)
   122     *  This module supports daisy-chained Vectored Interrupt Controllers (VICs).
   123     *  In a daisy-chained configuration, the VIC closest to the core has the lowest
   124     *  interrupt latency. In other words, lower interrupt numbers have lower
   125     *  latency.
   126     *
   127     *  @a(Interrupt Priorities)
   128     *  FIQ interrupts have the highest priority i.e. any interrupt of FIQ type will
   129     *  have a higher priority than any other interrupt of IRQ type.
   130     *
   131     *  IRQ interrupts (or vectored interrupts in PL192 VIC terminology) can be
   132     *  assigned different priority levels, ranging from 0-15. Lower priority levels
   133     *  imply a higher effective interrupt priority. Priority level can be set by
   134     *  writing to the {@link #priority} Hwi param. By default, all interrupts are
   135     *  set to the lowest priority level.
   136     *
   137     *  If multiple interrupts that are at the same priority level and belong to
   138     *  the same VIC, occur at the time, the fixed hardware priority levels are
   139     *  used to determine the order in which the interrupts are serviced. In this
   140     *  case, lower interrupts have a higher priority i.e. interrupt 0 will have
   141     *  a higher priority than interrupt 31.
   142     *
   143     *  @a(Interrupt Masking Options)
   144     *  In this Hwi module, the {@link #maskSetting} instance configuration
   145     *  parameter is ignored.
   146     *  Effectively, only the {@link #MaskingOption_LOWER} is supported.
   147     *
   148     *  @a(More Hwi examples)
   149     *  Here's an example showing how to construct a Hwi at runtime:
   150     *  @p(code)
   151     *  *.c:
   152     *  #include <ti/sysbios/family/arm/pl192/Hwi.h>
   153     *
   154     *  Hwi_Struct hwiStruct;
   155     *
   156     *  Void myIsrIRQ(UArg arg)
   157     *  {
   158     *      ...
   159     *  }
   160     *
   161     *  Void main(Void)
   162     *  {
   163     *      Hwi_Params hwiParams;
   164     *
   165     *      Hwi_Params_init(&hwiParams);
   166     *      Hwi_construct(&hwiStruct, INT_NUM_IRQ, myIsrIRQ, &hwiParams, NULL);
   167     *      ...
   168     *      BIOS_start();
   169     *  }
   170     *  @p
   171     *
   172     *  @p(html)
   173     *  <h3> Calling Context </h3>
   174     *  <table border="1" cellpadding="3">
   175     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
   176     *
   177     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   178     *    <!--                                                                                                                 -->
   179     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   180     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   181     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   182     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   183     *    <tr><td> {@link #disableIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   184     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   185     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   186     *    <tr><td> {@link #enableIRQ}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   187     *    <tr><td> {@link #getHandle}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   188     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   189     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   190     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   191     *    <tr><td> {@link #restoreIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   192     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   193     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   194     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   195     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   196     *    <tr><td> {@link #reconfig}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   197     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   198     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   199     *    <tr><td colspan="6"> Definitions: <br />
   200     *       <ul>
   201     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   202     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   203     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   204     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   205     *           <ul>
   206     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
   207     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   208     *             <li> During main().</li>
   209     *             <li> During BIOS.startupFxns.</li>
   210     *           </ul>
   211     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   212     *           <ul>
   213     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   214     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
   215     *           </ul>
   216     *       </ul>
   217     *    </td></tr>
   218     *
   219     *
   220     *  </table>
   221     *  @p
   222     */
   223    
   224    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   225    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   226    @InstanceInitStatic     /* allow constructs in static only systems */
   227    @CustomHeader
   228    
   229    module Hwi inherits ti.sysbios.interfaces.IHwi
   230    {
   231    
   232        // -------- Module Constants --------
   233    
   234        config UInt DEFAULT_INT_PRIORITY = 0xF;
   235    
   236        config UInt NUM_INTERRUPTS;
   237    
   238        config UInt NUM_VICS;
   239    
   240        // -------- Module Types --------
   241    
   242        /*! Hwi vector function type definition. */
   243        typedef Void (*VectorFuncPtr)(void);
   244    
   245        /*! @_nodoc Hwi plug function type definition. */
   246        typedef Void (*PlugFuncPtr)(void);
   247    
   248        /*! Interrupt type. IRQ or FIQ */
   249        enum Type {
   250            Type_IRQ,                /*! IRQ interrupt. */
   251            Type_FIQ                 /*! FIQ interrupt. */
   252        };
   253    
   254        /*! @_nodoc */
   255        metaonly struct BasicView {
   256            Ptr         halHwiHandle;
   257            String      label;
   258            String      type;
   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, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
   280                    ['ChannelMap', {type: ViewInfo.MODULE_DATA, viewInitFxn: 'viewChannelMap', structName: 'ChannelMapView'}],
   281                    ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
   282                ]
   283            });
   284    
   285        // -------- Module Parameters --------
   286    
   287        /*!
   288         *  ======== core0VectorTableAddress ========
   289         *  Determines the location of Core0's Interrupt Vector Table on a
   290         *  Dual-Core device. Default is device dependent.
   291         *
   292         *  On Dual-Core devices, both Cortex-R5 cores share a common reset
   293         *  vector table. In order to allow the 2 cores to register their own
   294         *  exception handlers, each core generates its own clone of the reset
   295         *  vector table and initializes it with its own exception handler
   296         *  addresses. The core specific vector tables are placed at fixed
   297         *  addresses so that the exception handler functions called by the
   298         *  common reset vector table known each core's vector table address
   299         *  and are able to reference it once they detect which core the
   300         *  application is currently running on.
   301         *
   302         *  The address of Core0's vector table is determined by this parameter.
   303         *
   304         *  Here are the default Core0 vector table addresses for all supported
   305         *  Dual-Core devices:
   306         *  @p(code)
   307         *   ----------------------------------------------------
   308         *  | Device name | Core0's default vector table address |
   309         *   ----------------------------------------------------
   310         *  | RM57D8xx    | 0x100                                |
   311         *   ----------------------------------------------------
   312         *  @p
   313         *
   314         *  @a(Note)
   315         *  If changing Core0's vector table address, it is not necessary to
   316         *  rebuild Core1's application as it does not need to know the location
   317         *  of Core0's vector table.
   318         */
   319        metaonly config Ptr core0VectorTableAddress;
   320    
   321        /*!
   322         *  ======== core1VectorTableAddress ========
   323         *  Determines the location of Core1's Interrupt Vector Table on a
   324         *  Dual-Core device. Default is device dependent.
   325         *
   326         *  On Dual-Core devices, both Cortex-R5 cores share a common reset
   327         *  vector table. In order to allow the 2 cores to register their own
   328         *  exception handlers, each core generates its own clone of the reset
   329         *  vector table and initializes it with its own exception handler
   330         *  addresses. The core specific vector tables are placed at fixed
   331         *  addresses so that the exception handler functions called by the
   332         *  common reset vector table known each core's vector table address
   333         *  and are able to reference it once they detect which core the
   334         *  application is currently running on.
   335         *
   336         *  Core0's vector table is always placed at 0x100 while the address of
   337         *  Core1's vector table is determined by this parameter.
   338         *
   339         *  Here are the default Core1 vector table addresses for all supported
   340         *  Dual-Core devices:
   341         *  @p(code)
   342         *   ----------------------------------------------------
   343         *  | Device name | Core1's default vector table address |
   344         *   ----------------------------------------------------
   345         *  | RM57D8xx    | 0x200000                             |
   346         *   ----------------------------------------------------
   347         *  @p
   348         *
   349         *  @a(Note)
   350         *  If changing Core1's vector table address, it is important to rebuild
   351         *  Core0's application with the same change as Core0 owns the common
   352         *  reset vector table and the common exception handler functions need
   353         *  to know Core1's vector table address so they can determine the
   354         *  address of the handler function they need to jump to.
   355         */
   356        metaonly config Ptr core1VectorTableAddress;
   357    
   358        /*!
   359         *  ======== resetVectorHandlerAddress ========
   360         *  Determines the location of the common reset vector handlers on a
   361         *  Dual-Core device. Default is device dependent.
   362         *
   363         *  On Dual-Core devices, both Cortex-R5 cores share a common reset
   364         *  vector table which points to a set of common vector handler
   365         *  functions. These vector handler functions are placed at a fixed
   366         *  address determined by this parameter.
   367         *
   368         *  @p(code)
   369         *   ----------------------------------------------------
   370         *  | Device name | Default reset vector handler address |
   371         *   ----------------------------------------------------
   372         *  | KEYSTONE3   | 0x00550000                           |
   373         *   ----------------------------------------------------
   374         *  @p
   375         */
   376        config Ptr resetVectorHandlerAddress;
   377    
   378        /*! Reset Handler. Default is c_int00 */
   379        metaonly config VectorFuncPtr resetFunc;
   380    
   381        /*!
   382         *  Undefined instruction exception handler.
   383         *  Default is set to an internal exception handler.
   384         */
   385        metaonly config VectorFuncPtr undefinedInstFunc;
   386    
   387        /*! SWI Handler. Default is internal SWI handler */
   388        metaonly config VectorFuncPtr swiFunc;
   389    
   390        /*!
   391         *  Prefetch abort exception handler.
   392         *  Default is set to an internal exception handler.
   393         */
   394        metaonly config VectorFuncPtr prefetchAbortFunc;
   395    
   396        /*!
   397         *  Data abort exception handler.
   398         *  Default is set to an internal exception handler.
   399         */
   400        metaonly config VectorFuncPtr dataAbortFunc;
   401    
   402        /*!
   403         *  Reserved exception handler.
   404         *  Default is set to an internal exception handler.
   405         */
   406        metaonly config VectorFuncPtr reservedFunc;
   407    
   408        /*!
   409         *  @_nodoc
   410         *  IRQ interrupt handler.
   411         *  Default is set to an internal exception dispatcher.
   412         */
   413        metaonly config VectorFuncPtr irqFunc;
   414    
   415        /*!
   416         *  FIQ interrupt handler.
   417         *  Default is set to an internal FIQ dispatcher.
   418         */
   419        metaonly config VectorFuncPtr fiqFunc;
   420    
   421        /*!
   422         *  FIQ stack pointer. Default = null.
   423         *  (Indicates that stack is to be created using
   424         *  staticPlace())
   425         */
   426        config Ptr fiqStack = null;
   427    
   428        /*!
   429         *  FIQ stack size in MAUs.
   430         *  Default is 1024 bytes.
   431         */
   432        metaonly config SizeT fiqStackSize = 1024;
   433    
   434        /*!
   435         *  Memory section used for FIQ stack
   436         *  Default is null.
   437         */
   438        metaonly config String fiqStackSection = null;
   439    
   440        /*!
   441         *  Non dispatched IRQ stack pointer. Default = null.
   442         *  (Indicates that stack is to be created using
   443         *  staticPlace())
   444         */
   445        config Ptr irqStack = null;
   446    
   447        /*!
   448         *  Non dispatched IRQ stack size in MAUs.
   449         *  Default is 1024 bytes.
   450         */
   451        metaonly config SizeT irqStackSize = 1024;
   452    
   453        /*!
   454         *  Memory section used for non dispatched IRQ stack
   455         *  Default is null.
   456         */
   457        metaonly config String irqStackSection = null;
   458    
   459        /*!
   460         * @_nodoc
   461         * VIC base address
   462         */
   463        metaonly config Ptr vicBaseAddress;
   464    
   465        /*!
   466         *  ======== A_badChannelId ========
   467         *  Assert raised when an invalid channelId is passed to Hwi_mapChannel()
   468         *  function.
   469         */
   470        config xdc.runtime.Assert.Id A_badChannelId  = {
   471            msg: "A_badChannelId: ChannelId is either not re-mappable or invalid."
   472        };
   473    
   474        /*!
   475         *  Error raised when Hwi is already defined
   476         */
   477        config Error.Id E_alreadyDefined = {
   478            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   479        };
   480    
   481        /*!
   482         *  Error raised if an attempt is made to create a Hwi
   483         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   484         */
   485        config Error.Id E_badIntNum = {
   486            msg: "E_badIntNum, intnum: %d is out of range"
   487        };
   488    
   489        /*!
   490         *  Error raised when an undefined interrupt has fired.
   491         */
   492        config Error.Id E_undefined = {
   493            msg: "E_undefined: Hwi undefined, intNum: %d"
   494        };
   495    
   496        /*!
   497         *  Error raised when an unsupported Hwi.MaskingOption used.
   498         */
   499        config Error.Id E_unsupportedMaskingOption = {
   500            msg: "E_unsupportedMaskingOption: Unsupported masking option passed."
   501        };
   502    
   503        /*!
   504         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   505         */
   506        config Log.Event LM_begin = {
   507            mask: Diags.USER1 | Diags.USER2,
   508            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   509        };
   510    
   511        /*!
   512         *  Issued just after return from Hwi function (with interrupts disabled)
   513         */
   514        config Log.Event LD_end = {
   515            mask: Diags.USER2,
   516            msg: "LD_end: hwi: 0x%x"
   517        };
   518    
   519    
   520        // -------- Module Functions --------
   521    
   522        /*!
   523         *  ======== disable ========
   524         *  Globally disable interrupts.
   525         *
   526         *  Hwi_disable globally disables hardware interrupts and returns an
   527         *  opaque key indicating whether interrupts were globally enabled or
   528         *  disabled on entry to Hwi_disable().
   529         *  The actual value of the key is target/device specific and is meant
   530         *  to be passed to Hwi_restore().
   531         *
   532         *  Call Hwi_disable before a portion of a function that needs
   533         *  to run without interruption. When critical processing is complete, call
   534         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   535         *
   536         *  Servicing of interrupts that occur while interrupts are disabled is
   537         *  postponed until interrupts are reenabled. However, if the same type
   538         *  of interrupt occurs several times while interrupts are disabled,
   539         *  the interrupt's function is executed only once when interrupts are
   540         *  reenabled.
   541         *
   542         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   543         *  an enabled interrupt occurred while interrupts are disabled.
   544         *
   545         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   546         *  are already disabled in main(), such a call has no effect.
   547         *
   548         *  @a(constraints)
   549         *  If a Task switching API such as
   550         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
   551         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   552         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   553         *  {@link ti.sysbios.knl.Task#yield Task_yield()}
   554         *  is invoked which results in a context switch while
   555         *  interrupts are disabled, an embedded call to
   556         *  {@link #enable Hwi_enable} occurs
   557         *  on the way to the new thread context which unconditionally re-enables
   558         *  interrupts. Interrupts will remain enabled until a subsequent
   559         *  {@link #disable Hwi_disable}
   560         *  invocation.
   561         *
   562         *  Swis always run with interrupts enabled.
   563         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   564         *  interrupts.
   565         *
   566         *  @b(returns)     opaque key for use by Hwi_restore()
   567         */
   568        @Macro
   569        override UInt disable();
   570    
   571        /*!
   572         *  ======== enable ========
   573         */
   574        @Macro
   575        override UInt enable();
   576    
   577        /*!
   578         *  ======== restore ========
   579         */
   580        @Macro
   581        override Void restore(UInt key);
   582    
   583        /*!
   584         *  @_nodoc
   585         *  ======== inUseMeta ========
   586         *  Check for Hwi already in use.
   587         *  For internal SYS/BIOS use only.
   588         *  Should be called prior to any internal Hwi.create().
   589         *
   590         *  @param(intNum)  interrupt number
   591         */
   592        metaonly Bool inUseMeta(UInt intNum);
   593    
   594        /*!
   595         *  ======== getHandle ========
   596         *  Returns pointer to Hwi instance object.
   597         *
   598         *  @param(intNum)  interrupt number
   599         */
   600        Object *getHandle(UInt intNum);
   601    
   602        /*!
   603         *  ======== enableIRQ ========
   604         *  Enable IRQ interrupts.
   605         *
   606         *  @param(key)     enable/disable state to restore
   607         */
   608        UInt enableIRQ();
   609    
   610        /*!
   611         *  ======== disableIRQ ========
   612         *  Disable IRQ interrupts.
   613         *
   614         *  @b(returns)     previous IRQ interrupt enable/disable state
   615         */
   616        UInt disableIRQ();
   617    
   618        /*!
   619         *  ======== restoreIRQ ========
   620         *  Restore IRQ interrupts.
   621         *
   622         *  @param(key)     enable/disable state to restore
   623         */
   624        Void restoreIRQ(UInt key);
   625    
   626        /*!
   627         *  ======== setPriority ========
   628         *  Set an interrupt's priority.
   629         *
   630         *  Not an instance function so that it can be used
   631         *  with non-dispatched interrupts.
   632         *
   633         *  @param(intNum)      ID of interrupt
   634         *  @param(priority)    priority
   635         */
   636        Void setPriority(UInt intNum, UInt priority);
   637    
   638        /*!
   639         *  @_nodoc
   640         *  ======== setType ========
   641         *  Set an interrupt's type (FIQ/IRQ).
   642         *
   643         *  Not an instance function so that it can be used
   644         *  with non-dispatched interrupts.
   645         *
   646         *  @param(intNum)      ID of interrupt
   647         *  @param(type)        type = FIQ/IRQ
   648         */
   649        Void setType(UInt intNum, Type type);
   650    
   651    instance:
   652    
   653        /*!
   654         *  Interrupt priority.
   655         *
   656         *  The Vectored Interrupt Controllers (VIC) on Keystone3 are
   657         *  connected in a daisy-chain configuration (i.e. VIC1's output
   658         *  line is connected to VIC0's input line and so on) with each VIC
   659         *  having its own priority hardware.
   660         *
   661         *  On each VIC, FIQ interrupts have the highest priority, followed by
   662         *  the IRQ interrupts and the daisy-chained interrupt.
   663         *  The daisy-chained interrupt has the lowest priority.
   664         *
   665         *  There are a total of 16 different priority levels and therefore
   666         *  the priority field can take a value from 0-15.
   667         *
   668         *  Each vectored interrupt source can
   669         *  The default value of -1 is used as a flag to indicate
   670         *  the lowest (logical) device-specific priority value.
   671         *
   672         *  Not all targets/devices support this instance parameter.
   673         *  On those that don't, this parameter is ignored.
   674         */
   675        override config Int priority = -1;
   676    
   677        /*! Interrupt type (IRQ/FIQ). Default is IRQ. */
   678        config Type type = Type_IRQ;
   679    
   680        /*!
   681         *  Default setting for this Hwi module is IHwi.MaskingOption_LOWER
   682         */
   683        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
   684    
   685        /*!
   686         *  ======== reconfig ========
   687         *  Reconfigure a dispatched interrupt.
   688         */
   689        Void reconfig(FuncPtr fxn, const Params *params);
   690    
   691    internal:   /* not for client use */
   692    
   693        /*
   694         *  Vectored Interrupt Controller (VIC) Registers
   695         */
   696        struct VIC {
   697            volatile UInt32 IRQSTATUS;        /*! IRQ Status Reg */
   698            volatile UInt32 FIQSTATUS;        /*! FIQ Status Reg */
   699            volatile UInt32 RAWINTR;          /*! Raw Interrupt Status Reg */
   700            volatile UInt32 INTSELECT;        /*! Interrupt Select Reg */
   701            volatile UInt32 INTENABLE;        /*! Interrupt Enable Reg */
   702            volatile UInt32 INTENCLEAR;       /*! Interrupt Enable Clear Reg */
   703            volatile UInt32 SOFTINT;          /*! Software Interrupt Reg */
   704            volatile UInt32 SOFTINTCLEAR;     /*! Software Interrupt Clear Reg */
   705            volatile UInt32 PROTECTION;       /*! Protection Enable Reg */
   706            volatile UInt32 SWPRIORITYMASK;   /*! Software Priority Mask Reg */
   707            volatile UInt32 PRIORITYDAISY;    /*! Vector Priority Reg for Daisy Chain */
   708            volatile UInt32 hole0[53];        /*! 0x02C-0x100 */
   709            volatile UInt32 VECTADDR[32];     /*! Vector n Address Reg */
   710            volatile UInt32 hole1[32];        /*! 0x180-0x200 */
   711            volatile UInt32 VECTPRIORITY[32]; /*! Vector n Priority Reg */
   712            volatile UInt32 hole2[800];       /*! 0x280-0xF00 */
   713            volatile UInt32 ADDRESS;          /*! Vector Address Reg */
   714            volatile UInt32 hole3[55];        /*! 0xF04-0xFE0 */
   715            volatile UInt32 PERIPHID0;        /*! Peripheral Id Reg bits 7:0 */
   716            volatile UInt32 PERIPHID1;        /*! Peripheral Id Reg bits 15:8 */
   717            volatile UInt32 PERIPHID2;        /*! Peripheral Id Reg bits 23:16 */
   718            volatile UInt32 PERIPHID3;        /*! Peripheral Id Reg bits 31:24 */
   719            volatile UInt32 PCELLID0;         /*! PrimeCell Id Reg bits 7:0 */
   720            volatile UInt32 PCELLID1;         /*! PrimeCell Id Reg bits 15:8 */
   721            volatile UInt32 PCELLID2;         /*! PrimeCell Id Reg bits 23:16 */
   722            volatile UInt32 PCELLID3;         /*! PrimeCell Id Reg bits 31:24 */
   723        };
   724    
   725        metaonly config Bool lockstepDevice;
   726    
   727        /*
   728         *  ======== intEnable ========
   729         *  Initial interrupt enable register value
   730         */
   731        config UInt32 intEnable[];
   732    
   733        /*
   734         *  ======== vic ========
   735         */
   736        config VIC *vic;
   737    
   738        /*
   739         * Swi and Task module function pointers.
   740         * Used to decouple Hwi from Swi and Task when
   741         * dispatcherSwiSupport or
   742         * dispatcherTaskSupport is false.
   743         */
   744        config UInt (*swiDisable)();
   745        config Void (*swiRestoreHwi)(UInt);
   746        config UInt (*taskDisable)();
   747        config Void (*taskRestoreHwi)(UInt);
   748    
   749        config VectorFuncPtr dispatchIRQTable[];
   750    
   751        /*
   752         *  ======== postInit ========
   753         *  finish initializing static and dynamic Hwis
   754         */
   755        Int postInit(Object *hwi, Error.Block *eb);
   756    
   757        /*
   758         *  ======== initIntController ========
   759         */
   760        Void initIntController();
   761    
   762        /* assembly code mode registers setup */
   763        Void init();
   764    
   765        /* Interrupt Dispatcher assembly code wrapper */
   766        Void dispatchIRQ();
   767    
   768        /* FIQ Interrupt Dispatcher */
   769        Void dispatchFIQC();
   770    
   771        /* IRQ Interrupt Dispatcher */
   772        Void dispatchIRQC(Irp irp);
   773    
   774        /* non plugged interrupt handler */
   775        Void nonPluggedHwiHandler(UArg arg);
   776    
   777        /*
   778         *  ======== plug ========
   779         *  Plug an interrupt vector with an ISR address.
   780         *
   781         *  @param(intNum)  interrupt number
   782         *  @param(fxn)     pointer to ISR function
   783         */
   784        Void plug(UInt intNum, PlugFuncPtr fxn);
   785    
   786        /*!
   787         *  const array to hold all HookSet objects.
   788         */
   789        config HookSet hooks[length] = [];
   790    
   791        /*! Meta World Only Hwi Configuration Object. */
   792        metaonly struct InterruptObj {
   793            Bool used;              /* Interrupt already defined? */
   794            FuncPtr fxn;            /* Dispatched ISR function */
   795        };
   796    
   797        /*!
   798         * Meta-only array of interrupt objects.
   799         * This meta-only array of Hwi config objects is initialized
   800         * in Hwi.xs:module$meta$init().
   801         */
   802        metaonly config InterruptObj interrupt[];
   803    
   804        struct Instance_State {
   805            Type        type;                   // Interrupt Type
   806            UArg        arg;                    // Argument to Hwi function.
   807            FuncPtr     fxn;                    // Hwi function.
   808            Int         intNum;                 // Interrupt number
   809            Irp         irp;                    // current IRP
   810            Ptr         hookEnv[];
   811            Int         priority;               // Interript priority
   812            UInt        priorityMask;           // SW priority mask
   813        };
   814    
   815        struct Module_State {
   816            Char        *taskSP;                /* temporary storage of interrupted
   817                                                   Task's SP during ISR execution */
   818            Char        *isrStack;              /* Points to isrStack address */
   819            Ptr         isrStackBase;           /* _stack */
   820            Ptr         isrStackSize;           /* _STACK_SIZE */
   821            Char        fiqStack[];             /* buffer used for FIQ stack */
   822            SizeT       fiqStackSize;
   823            Char        irqStack[];             /* buffer used for non dispatched
   824                                                   IRQ stack */
   825            SizeT       irqStackSize;
   826            Handle      dispatchTable[];        /* dispatch table */
   827            Hwi.Object  nonPluggedHwi;          /* default Hwi object */
   828        };
   829    }