1    /*
     2     * Copyright (c) 2015, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== Hwi.xdc ========
    34     *
    35     */
    36    package ti.sysbios.family.arm.da830;
    37    
    38    import xdc.runtime.Diags;
    39    import xdc.runtime.Log;
    40    import xdc.runtime.Assert;
    41    import xdc.rov.ViewInfo;
    42    import xdc.runtime.Error;
    43    
    44    /*!
    45     *  ======== Hwi ========
    46     *  Hardware Interrupt Support Module.
    47     *
    48     *  This Hwi module provides ARM family-specific implementations of the
    49     *  APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
    50     *
    51     *  Additional ARM device-specific APIs are also provided.
    52     *
    53     *  IRQ Interrupts are nestable and can invoke SYS/BIOS functions.
    54     *  FIQ Interrupts are non-nestable and cannot invoke SYS/BIOS functions.
    55     *
    56     *  The IRQ dispatcher re-enables IRQ interrupts prior to invoking the
    57     *  ISR function associated with an interrupt but uses the CP INTC's
    58     *  Host Interrupt Nesting Level Register (HINLR) to suppress lower
    59     *  priority interrupts while the interrupt is being serviced.
    60     *
    61     *  The default FIQ handler does not re-enable FIQ interrupts nor
    62     *  use the HINLR. It simply calls the registered FIQ ISR and returns.
    63     *
    64     *  To statically configure a non-dispatched interrupt:
    65     *  To dynamically configure a non-dispatched interrupt:
    66     *
    67     *  @p(html)
    68     *  <h3> Calling Context </h3>
    69     *  <table border="1" cellpadding="3">
    70     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    71     *
    72     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    73     *    <!--                                                                                                                 -->
    74     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    75     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    76     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    77     *    <tr><td> {@link #disableFIQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    78     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    79     *    <tr><td> {@link #disableIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    80     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    81     *    <tr><td> {@link #enableFIQ}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    82     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    83     *    <tr><td> {@link #enableIRQ}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #getHandle}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    85     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    86     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    87     *    <tr><td> {@link #restoreFIQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    88     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    89     *    <tr><td> {@link #restoreIRQ}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    90     *    <tr><td> {@link #setPriority}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    91     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    93     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    94     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    95     *    <tr><td> {@link #reconfig}         </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    96     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    97     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    98     *    <tr><td colspan="6"> Definitions: <br />
    99     *       <ul>
   100     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   101     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   102     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   103     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   104     *           <ul>
   105     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
   106     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   107     *             <li> During main().</li>
   108     *             <li> During BIOS.startupFxns.</li>
   109     *           </ul>
   110     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   111     *           <ul>
   112     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   113     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
   114     *           </ul>
   115     *       </ul>
   116     *    </td></tr>
   117     *
   118     *
   119     *  </table>
   120     *  @p
   121     */
   122    
   123    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   124    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   125    @InstanceInitStatic     /* allow constructs in static only systems */
   126    
   127    module Hwi inherits ti.sysbios.interfaces.IHwi
   128    {
   129    
   130        // -------- Module Constants --------
   131    
   132        /*! The DA830 ARM Interrupt Controller has 101 defined interrupts. */
   133        const Int NUM_INTERRUPTS = 101;
   134    
   135        // -------- Module Types --------
   136    
   137        /*! Hwi vector function type definition. */
   138        typedef Void (*VectorFuncPtr)(void);
   139    
   140        /*! @_nodoc Hwi plug function type definition. */
   141        typedef Void (*PlugFuncPtr)(void);
   142    
   143        /*!
   144         * Common Platform Interrupt Controller.
   145         */
   146        struct CPINTC {
   147            UInt32 REV;         /*! 0x00 Revision Register */
   148            UInt32 CR;          /*! 0x04 Control Register */
   149            UInt32 RES_08;      /*! 0x08 reserved */
   150            UInt32 HCR;         /*! 0x0C Host Control Register */
   151            UInt32 GER;         /*! 0x10 Global Enable Register */
   152            UInt32 RES_14;      /*! 0x14 reserved */
   153            UInt32 RES_18;      /*! 0x18 reserved */
   154            UInt32 GNLR;        /*! 0x1C Global Nesting Level Register */
   155            UInt32 SISR;        /*! 0x20 Status Index Set Register */
   156            UInt32 SICR;        /*! 0x24 Status Index Clear Register */
   157            UInt32 EISR;        /*! 0x28 Enable Index Set Register */
   158            UInt32 EICR;        /*! 0x2C Enable Index Clear Register */
   159            UInt32 GWER;        /*! 0x30 Global Wakeup Enable Register */
   160            UInt32 HIEISR;      /*! 0x34 Host Int Enable Index Set Register */
   161            UInt32 HIDISR;      /*! 0x38 Host Int Disable Index Set Register */
   162            UInt32 RES_3C;      /*! 0x3C reserved */
   163            UInt32 PPR;         /*! 0x40 Pacer Prescale Register */
   164            UInt32 RES_44;      /*! 0x44 reserved */
   165            UInt32 RES_48;      /*! 0x48 reserved */
   166            UInt32 RES_4C;      /*! 0x4C reserved */
   167            Ptr   *VBR;         /*! 0x50 Vector Base Register */
   168            UInt32 VSR;         /*! 0x54 Vector Size Register */
   169            Ptr    VNR;         /*! 0x58 Vector Null Register */
   170            UInt32 RES_5C[9];   /*! 0x5C-0x7C reserved */
   171            Int32  GPIR;        /*! 0x80 Global Prioritized Index Register */
   172            Ptr   *GPVR;        /*! 0x84 Global Prioritized Vector Register */
   173            UInt32 RES_88;      /*! 0x88 reserved */
   174            UInt32 RES_8C;      /*! 0x8C reserved */
   175            UInt32 GSIER;       /*! 0x90 Global Secure Interrupt Enable Register */
   176            UInt32 SPIR;        /*! 0x94 Secure Prioritized Index Register */
   177            UInt32 RES_98[26];  /*! 0x98-0xFC reserved */
   178            UInt32 PPMR[64];    /*! 0x100-0x1FC Pacer Parameter/Map Registers */
   179            UInt32 SRSR[32];    /*! 0x200-0x27C Status Raw/Set Registers */
   180            UInt32 SECR[32];    /*! 0x280-0x2FC Status Enabled/Clear Registers */
   181            UInt32 ESR[32];     /*! 0x300-0x37C Enable Set Registers */
   182            UInt32 ECR[32];     /*! 0x380-0x3FC Enable Clear Registers */
   183            UInt8  CMR[1024];   /*! 0x400-0x7FC Channel Map Registers */
   184            UInt8  HIMR[256];   /*! 0x800-0x8FC Host Interrupt Map Registers */
   185            UInt32 HIPIR[256];  /*! 0x900-0xCFC Host Interrupt Pri Index Registers */
   186            UInt32 PR[32];      /*! 0xD00-0xD7C Polarity Registers */
   187            UInt32 TR[32];      /*! 0xD80-0xDFC Type Registers */
   188            UInt32 WER[64];     /*! 0xE00-0xEFC Wakeup Enable Registers */
   189            UInt32 DSR[64];     /*! 0xF00-0xFFC Debug Select Registers */
   190            UInt32 SER[32];     /*! 0x1000-0x107C Secure Enable Registers */
   191            UInt32 SDR[32];     /*! 0x1080-0x10FC Secure Disable Registers */
   192            UInt32 HINLR[256];  /*! 0x1100-0x14FC Host Interrupt Nesting Level Registers */
   193            UInt32 HIER[8];     /*! 0x1500-0x151F Host Interrupt Enable Registers */
   194            UInt32 RES_1520[56];/*! 0x1520-0x15fC Reserved */
   195            Ptr   *HIPVR[256];  /*! 0x1600-0x19fC Host Interrupt Prioritized Vector */
   196        };
   197    
   198        /*!
   199         * Physical Common Platform Interrupt Controller Device.
   200         * Short name is "Hwi_cpIntc"
   201         * Long name is "ti_sysbios_family_arm_da830_Hwi_cpIntc"
   202         */
   203        extern volatile CPINTC cpIntc;
   204    
   205        /*!
   206         *  ======== BasicView ========
   207         *  @_nodoc
   208         */
   209        metaonly struct BasicView {
   210            Ptr         halHwiHandle;
   211            String      label;
   212            Int         intNum;
   213            Int         priority;
   214            String      fxn;
   215            UArg        arg;
   216            Ptr         irp;
   217            String      status;
   218        };
   219    
   220        /*!
   221         *  ======== ModuleView ========
   222         *  @_nodoc
   223         */
   224        metaonly struct ModuleView {
   225            String      options[4];
   226            String      hwiStackPeak;
   227            SizeT       hwiStackSize;
   228            Ptr         hwiStackBase;
   229            UInt        priorities[256];
   230        };
   231    
   232        /*!
   233         *  ======== rovViewInfo ========
   234         *  @_nodoc
   235         */
   236        @Facet
   237        metaonly config ViewInfo.Instance rovViewInfo =
   238            ViewInfo.create({
   239                viewMap: [
   240                    ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
   241                    ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
   242                ]
   243            });
   244    
   245        // -------- Module Parameters --------
   246    
   247        /*! Assert when bad maskSetting parameter provided */
   248        config Assert.Id A_unsupportedMaskingOption = {
   249            msg: "A_unsupportedMaskingOption: unsupported maskSetting."
   250        };
   251    
   252        /*! Reset Handler. Default is c_int00 */
   253        metaonly config VectorFuncPtr resetFunc;
   254    
   255        /*! Undefined instruction exception handler. Default is self loop */
   256        metaonly config VectorFuncPtr undefinedInstFunc;
   257    
   258        /*! SWI Handler. Default is internal SWI handler */
   259        metaonly config VectorFuncPtr swiFunc;
   260    
   261        /*! Prefetch abort exception handler. Default is self loop */
   262        metaonly config VectorFuncPtr prefetchAbortFunc;
   263    
   264        /*! Data abort exception handler. Default is self loop */
   265        metaonly config VectorFuncPtr dataAbortFunc;
   266    
   267        /*! Reserved exception handler. Default is self loop */
   268        metaonly config VectorFuncPtr reservedFunc;
   269    
   270        /*! IRQ interrupt handler. Default is internal IRQ dispatcher */
   271        metaonly config VectorFuncPtr irqFunc;
   272    
   273        /*! FIQ interrupt handler. Default is internal FIQ dispatcher */
   274        metaonly config VectorFuncPtr fiqFunc;
   275    
   276        /*!
   277         *  non-dispatched interrupt object.
   278         *  provided so that XGCONF users can easily plug non-dispatched interrupts
   279         */
   280        metaonly struct NonDispatchedInterrupt {
   281            Int             intNum;
   282            PlugFuncPtr     fxn;            /*! "Hwi_plug'd" ISR function. */
   283            UInt            priority;
   284            Bool            enableInt;
   285        };
   286    
   287        /*!
   288         *  non-dispatched interrupt array.
   289         *  provided so that XGCONF users can easily plug non-dispatched interrupts
   290         */
   291        metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
   292    
   293        /*!
   294         *  FIQ stack pointer. Default = null.
   295         *  (Indicates that stack is to be created using
   296         *  staticPlace()
   297         */
   298        config Ptr fiqStack = null;
   299    
   300        /*!
   301         *  FIQ stack size in bytes.
   302         *  Default is 1024 bytes.
   303         */
   304        metaonly config SizeT fiqStackSize = 1024;
   305    
   306        /*!
   307         *  Memory section used for FIQ stack
   308         *  Default is null.
   309         */
   310        metaonly config String fiqStackSection = null;
   311    
   312        /*!
   313         *  IRQ stack pointer. Default = null.
   314         *  (Indicates that stack is to be created using
   315         *  staticPlace()
   316         */
   317        config Ptr irqStack = null;
   318    
   319        /*!
   320         *  IRQ stack size in bytes.
   321         *  Default is 256 bytes.
   322         *  This is enough room for 32 nested IRQ interrupts.
   323         *
   324         *  An IRQ interrupt pushes 2 32bit words onto the IRQ stack.
   325         */
   326        metaonly config SizeT irqStackSize = 256;
   327    
   328        /*!
   329         *  Memory section used for IRQ stack
   330         *  Default is null.
   331         */
   332        metaonly config String irqStackSection = null;
   333    
   334        /*!
   335         *  Location of the Interrupt Vector Table
   336         *
   337         *  The default placement of the Interrupt Vector Table
   338         *  is immediately after the ARM exception table located
   339         *  at 0xffff0000.
   340         *
   341         *  The vector table is internally assigned to the ".vectorTable"
   342         *  memory section.
   343         */
   344        metaonly config Ptr vectorTableAddress = 0xffff0040;
   345    
   346        /*!
   347         *  Error raised when Hwi is already defined
   348         */
   349        config Error.Id E_alreadyDefined = {
   350            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   351        };
   352    
   353        /*!
   354         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   355         */
   356        config Log.Event LM_begin = {
   357            mask: Diags.USER1 | Diags.USER2,
   358            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   359        };
   360    
   361        /*!
   362         *  Issued just after return from Hwi function (with interrupts disabled)
   363         */
   364        config Log.Event LD_end = {
   365            mask: Diags.USER2,
   366            msg: "LD_end: hwi: 0x%x"
   367        };
   368    
   369    
   370        // -------- Module Functions --------
   371    
   372        /*!
   373         *  ======== disable ========
   374         *  Globally disable interrupts.
   375         *
   376         *  Hwi_disable globally disables hardware interrupts and returns an
   377         *  opaque key indicating whether interrupts were globally enabled or
   378         *  disabled on entry to Hwi_disable(). 
   379         *  The actual value of the key is target/device specific and is meant 
   380         *  to be passed to Hwi_restore(). 
   381         *
   382         *  Call Hwi_disable before a portion of a function that needs
   383         *  to run without interruption. When critical processing is complete, call
   384         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   385         *
   386         *  Servicing of interrupts that occur while interrupts are disabled is
   387         *  postponed until interrupts are reenabled. However, if the same type 
   388         *  of interrupt occurs several times while interrupts are disabled, 
   389         *  the interrupt's function is executed only once when interrupts are 
   390         *  reenabled.
   391         *
   392         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   393         *  an enabled interrupt occurred while interrupts are disabled.
   394         *
   395         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   396         *  are already disabled in main(), such a call has no effect.
   397         *
   398         *  @a(constraints)
   399         *  If a Task switching API such as 
   400         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()}, 
   401         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   402         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   403         *  {@link ti.sysbios.knl.Task#yield Task_yield()} 
   404         *  is invoked which results in a context switch while
   405         *  interrupts are disabled, an embedded call to 
   406         *  {@link #enable Hwi_enable} occurs
   407         *  on the way to the new thread context which unconditionally re-enables
   408         *  interrupts. Interrupts will remain enabled until a subsequent 
   409         *  {@link #disable Hwi_disable}
   410         *  invocation.
   411         *
   412         *  Swis always run with interrupts enabled.
   413         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   414         *  interrupts.
   415         *
   416         *  @b(returns)     opaque key for use by Hwi_restore()
   417         */
   418        @Macro
   419        override UInt disable();
   420    
   421        /*!
   422         *  ======== enable ========
   423         */
   424        @Macro
   425        override UInt enable();
   426    
   427        /*!
   428         *  ======== restore ========
   429         */
   430        @Macro
   431        override Void restore(UInt key);
   432    
   433        /*!
   434         *  ======== inUseMeta ========
   435         *  @_nodoc
   436         *  Check for Hwi already in use.
   437         *  For internal SYS/BIOS use only.
   438         *  Should be called prior to any internal Hwi.create().
   439         *
   440         *  @param(intNum)  interrupt number
   441         */
   442        metaonly Bool inUseMeta(UInt intNum);
   443    
   444        /*!
   445         *  @_nodoc
   446         *  ======== plug ========
   447         *  Plug an interrupt vector with an ISR address.
   448         *
   449         *  Hwi_plug writes an Interrupt Service Fetch Packet (ISFP) into the
   450         *  Interrupt Service Table (IST), at the address corresponding to intNum
   451         *  The op-codes written in the ISFP create a branch to the function
   452         *  entry  point specified by fxn:
   453         *
   454         *  @p(code)
   455         *          stw     b0, *SP--[1]
   456         *          mvk     fxn, b0
   457         *          mvkh    fxn, b0
   458         *          b       b0
   459         *          ldw     *++SP[1],b0
   460         *          nop     4
   461         *  @p
   462         *
   463         *  Hwi_plug hooks up the specified function as the branch target of a
   464         *  hardware interrupt (fielded by the CPU) at the vector address
   465         *  specified in intNum. Hwi_plug does not enable the interrupt.
   466         *  Use Hwi_enableIER to enable specific interrupts.
   467         *
   468         *  For internal SYS/BIOS use only.
   469         *
   470         *  Constraints and Calling Context
   471         *  o vecid must be a valid interrupt ID in the range of 0-15.
   472         *
   473         *  @param(intNum)  interrupt number
   474         *  @param(fxn)     pointer to ISR function
   475         */
   476        Void plug(UInt intNum, PlugFuncPtr fxn);
   477    
   478        /*!
   479         *  ======== plugMeta ========
   480         *  Statically plug an interrupt vector with an ISR address.
   481         *
   482         *  @param(intNum)  interrupt number
   483         *  @param(fxn)     pointer to ISR function
   484         */
   485        metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
   486    
   487        /*!
   488         *  ======== getHandle ========
   489         *  Returns Hwi_handle associated with intNum
   490         *
   491         *  @param(intNum)  interrupt number
   492         */
   493        Handle getHandle(UInt intNum);
   494    
   495        /*!
   496         *  ======== enableFIQ ========
   497         *  Enable FIQ interrupts.
   498         *
   499         *  @b(returns)     previous FIQ interrupt enable/disable state
   500         */
   501        UInt enableFIQ();
   502    
   503        /*!
   504         *  ======== disableFIQ ========
   505         *  Disable FIQ interrupts.
   506         *
   507         *  @b(returns)     previous FIQ interrupt enable/disable state
   508         */
   509        UInt disableFIQ();
   510    
   511        /*!
   512         *  ======== restoreFIQ ========
   513         *  Restore FIQ interrupts.
   514         *
   515         *  @param(key)     enable/disable state to restore
   516         */
   517        Void restoreFIQ(UInt key);
   518    
   519        /*!
   520         *  ======== enableIRQ ========
   521         *  Enable IRQ interrupts.
   522         *
   523         *  @param(key)     enable/disable state to restore
   524         */
   525        UInt enableIRQ();
   526    
   527        /*!
   528         *  ======== disableIRQ ========
   529         *  Disable IRQ interrupts.
   530         *
   531         *  @b(returns)     previous IRQ interrupt enable/disable state
   532         */
   533        UInt disableIRQ();
   534    
   535        /*!
   536         *  ======== restoreIRQ ========
   537         *  Restore IRQ interrupts.
   538         *
   539         *  @param(key)     enable/disable state to restore
   540         */
   541        Void restoreIRQ(UInt key);
   542    
   543        /*!
   544         *  ======== beginIRQ ========
   545         *  Function to be invoked at the beginning of a
   546         *  non-dispatched IRQ handler. Services cpIntc.
   547         */
   548        Void beginIRQ();
   549    
   550        /*!
   551         *  ======== endIRQ ========
   552         *  Function to be invoked at the end of a
   553         *  non-dispatched IRQ handler. Services cpIntc.
   554         */
   555        Void endIRQ();
   556    
   557        /*!
   558         *  ======== beginFIQ ========
   559         *  Function to be invoked at the beginning of a
   560         *  non-dispatched FIQ handler. Services cpIntc.
   561         */
   562        Void beginFIQ();
   563    
   564        /*!
   565         *  ======== endFIQ ========
   566         *  Function to be invoked at the end of a
   567         *  non-dispatched FIQ handler. Services cpIntc.
   568         */
   569        Void endFIQ();
   570    
   571        /*!
   572         *  ======== setPriority ========
   573         *  Set an interrupt's relative priority.
   574         *
   575         *  Valid priorities are 0 - 31. 0 is highest priority.
   576         *  Priorities 0 - 1 are routed to the ARM's FIQ interrupt.
   577         *  Priorities 2 - 31 are routed to the ARM's IRQ interrupt.
   578         *
   579         *  @param(intNum)      ID of interrupt
   580         *  @param(priority)    priority
   581         */
   582        Void setPriority(UInt intNum, UInt priority);
   583    
   584    instance:
   585    
   586        /*!
   587         *  Interrupt priority.
   588         *  Valid priorities are 0 - 31. 0 is highest priority.
   589         *  Priorities 0 - 1 are routed to the ARM's FIQ interrupt.
   590         *  Priorities 2 - 31 are routed to the ARM's IRQ interrupt.
   591         *  The default is 31 which is the lowest priority IRQ interrupt.
   592         */
   593        override config Int priority = 31;
   594    
   595        /*!
   596         *  ======== reconfig ========
   597         *  Reconfigure a dispatched interrupt.
   598         */
   599        Void reconfig(FuncPtr fxn, const Params *params);
   600    
   601    internal:   /* not for client use */
   602    
   603        /*! Hwi vector function type definition. */
   604        typedef Void (*HandlerFuncPtr)(Handle, UInt);
   605    
   606        /*
   607         * Swi and Task module function pointers.
   608         * Used to decouple Hwi from Swi and Task when
   609         * dispatcherSwiSupport or
   610         * dispatcherTaskSupport is false.
   611         */
   612        config UInt (*swiDisable)();
   613        config Void (*swiRestoreHwi)(UInt);
   614        config UInt (*taskDisable)();
   615        config Void (*taskRestoreHwi)(UInt);
   616    
   617        /*
   618         *  ======== postInit ========
   619         *  finish initializing static and dynamic Hwis
   620         */
   621        Int postInit(Object *hwi, Error.Block *eb);
   622    
   623        /*
   624         *  ======== initIntController ========
   625         */
   626        Void initIntController();
   627    
   628        /* assembly code mode registers setup */
   629        Void init();
   630    
   631        /* Interrupt Dispatcher assembly code wrapper */
   632        Void dispatchIRQ();
   633    
   634        /* IRQ Interrupt Dispatcher */
   635        Void dispatchIRQC();
   636    
   637        /* default FIQ Interrupt Dispatcher */
   638        Void dispatchFIQC();
   639    
   640        /* spurious interrupt handler */
   641        Void spuriousInt();
   642    
   643        Void handlerNONE(Handle hwi, UInt intNum);
   644    
   645        Void handlerALL(Handle hwi, UInt intNum);
   646    
   647        Void handlerLOWER(Handle hwi, UInt intNum);
   648    
   649        Void handlerSELF(Handle hwi, UInt intNum);
   650    
   651        /*!
   652         *  const array to hold all HookSet objects.
   653         */
   654        config HookSet hooks[length] = [];
   655    
   656        /*! Meta World Only Hwi Configuration Object. */
   657        metaonly struct InterruptObj {
   658            String name;            /* symbol used for vector table entry */
   659            Bool used;              /* Interrupt already defined? */
   660            Bool useDispatcher;     /* Should dispatcher handle this Int? */
   661            UInt priority;          /* used to determine FIQ/IRQ type */
   662            FuncPtr fxn;            /* Dispatched ISR function */
   663            PlugFuncPtr pfxn;       /* "Hwi_plug'd" ISR function. */
   664        };
   665    
   666        /*!
   667         * Meta-only array of interrupt objects.
   668         * This meta-only array of Hwi config objects is initialized
   669         * in Hwi.xs:module$meta$init().
   670         */
   671        metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
   672    
   673        struct Instance_State {
   674            UArg            arg;            // Argument to Hwi function.
   675            FuncPtr         fxn;            // Hwi function.
   676            Int             intNum;         // Interrupt number
   677            HandlerFuncPtr  handler;        // MaskingOption-unique handler
   678            Irp             irp;            // current IRP
   679            Ptr             hookEnv[];
   680        };
   681    
   682        struct Module_State {
   683            Bits32      er[4];          // Initial Enable Reg values
   684            UInt        irp;            // temporary irp storage for IRQ handler
   685            UInt8       priorities[NUM_INTERRUPTS];
   686                                        // table of interrupt priorities
   687            Char        *taskSP;        // temporary storage of interrupted
   688                                        // Task's SP during ISR execution
   689            /* ROM */
   690            Ptr         vectorTableBase;// Points to base of vector table
   691            Char        *isrStack;      // Points to isrStack address
   692            Ptr         isrStackBase;   // _stack
   693            Ptr         isrStackSize;   // _STACK_SIZE
   694            Char        fiqStack[];     // buffer used for FIQ stack
   695            SizeT       fiqStackSize;
   696    
   697            Handle      dispatchTable[NUM_INTERRUPTS];
   698                                        // dispatch table
   699        };
   700    }
   701