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    package ti.sysbios.family.arm.gic;
    36    
    37    import xdc.rov.ViewInfo;
    38    
    39    import xdc.runtime.Diags;
    40    import xdc.runtime.Log;
    41    import xdc.runtime.Error;
    42    
    43    import ti.sysbios.BIOS;
    44    import ti.sysbios.interfaces.IHwi;
    45    
    46    /*!
    47     *  ======== Hwi ========
    48     *  Hardware Interrupt Support Module.
    49     *
    50     *  This Hwi module provides ARM cortex-A Generic Interrupt Controller(GIC) v2.0
    51     *  specific implementations and extensions of the APIs defined in
    52     *  {@link ti.sysbios.interfaces.IHwi IHwi}.
    53     *
    54     *  The GIC is logically partitioned into 2 blocks, the Distributor block
    55     *  and CPU interface block. The Distributor block interfaces with the interrupt
    56     *  sources, prioritizes interrupts and distributes them to the CPU interface
    57     *  block. The CPU interface block connects to the processors in the system
    58     *  and is responsible for priority masking and preemption handling for
    59     *  the processor it is connected to.
    60     *
    61     *  The GIC can implement up to 8 CPU interfaces with each CPU interface
    62     *  being able to see up to 1020 interrupts. The GIC assigns interrupt ID
    63     *  numbers 0-1019 as follows:
    64     *   - Interrupt numbers 0-31 are used for interrupts private to a
    65     *     CPU interface. These private interrupts are banked in the Distributor.
    66     *   - Banked interrupt number 0-15 are used for Software Generated Interrupts
    67     *     or SGIs.
    68     *   - Banked interrupt number 16-31 are used for Private Peripheral Interrupts
    69     *     or PPIs.
    70     *   - Interrupt numbers 32-1019 are used for Shared Peripheral Interrupts
    71     *     or SPIs.
    72     *   - Interrupt numbers 1020-1023 are reserved.
    73     *
    74     *  @a(NOTE)
    75     *  In the SoC Technical Reference Manual, the MPU IRQs 0 to N map to
    76     *  GIC interrupt numbers 32 to (N+32) where (N+1) is the total number of
    77     *  Shared Peripheral Interrupts implemented.
    78     *  For instance on OMAP5430, MPU IRQ 0 to 159 maps to GIC interrupt number
    79     *  32 to 191.
    80     *
    81     *  @a(INTERRUPT GROUPING)
    82     *  GIC allows configuring an interrupt as a Group 0 or a Group 1 interrupt.
    83     *  Group 0 interrupts are Secure interrupts and Group 1 interrupts are
    84     *  Non-secure interrupts.
    85     *
    86     *  If {@link #enableSecureMode} is set to true, this module supports both
    87     *  Group0 and Group 1 interrupts. Group 0 interrupts are delivered to the CPU
    88     *  using FIQ signal whereas Group 1 interrupts are delivered using IRQ signal.
    89     *
    90     *  If {@link #enableSecureMode} is set to false, this module only supports
    91     *  Group 1 interrupts which are delivered to the target CPU using IRQ signal.
    92     *
    93     *  @a(INTERRUPT PRIORITIES)
    94     *  In general GIC supports priority values 0 thru 255.
    95     *
    96     *  In practice valid priority values depend on the particular device used,
    97     *  security mode and the Binary Point Register (see {@link #BPR} and
    98     *  {@link #ABPR}) value.
    99     *
   100     *  The device implementation and security mode decide the number of priority
   101     *  bits that are implemented (see {@link #NUM_PRIORITY_BITS}). Group 0
   102     *  interrupts always implement one more priority bit than Group 1 interrupts.
   103     *
   104     *  In GIC, interrupts with lower priority numbers have higher priority.
   105     *
   106     *  @a(NOTE)
   107     *  In this Hwi module implementation, the instance config parameter value
   108     *  {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
   109     *  Statically configuring a Hwi object's {@link #Params.maskSetting} to
   110     *  {@link #MaskingOption_LOWER} will result in the generation of a benign
   111     *  build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
   112     *  silently converted to {@link #MaskingOption_SELF}.
   113     *
   114     *  @a(ZERO LATENCY INTERRUPTS)
   115     *  On Keystone2 devices, this module supports zero-latency interrupts. A
   116     *  zero-latency interrupt does not go through the SYS/BIOS dispatcher and
   117     *  thus has a faster response time. Since zero-latency interrupts bypass the
   118     *  dispatcher, their handler function cannot call any SYS/BIOS APIs.
   119     *
   120     *  This module implements zero-latency interrupts by forwarding the interrupt
   121     *  to the target CPU using FIQ signal. Therefore, in order to configure an
   122     *  interrupt as a zero-latency interrupt, the Hwi type needs to be changed
   123     *  to FIQ when creating or constructing a Hwi.
   124     *
   125     *  Example showing how to create a zero-latency Hwi:
   126     *  @p(code)
   127     *  Void main(Void)
   128     *  {
   129     *      Hwi_Params hwiParams;
   130     *      Hwi_Params_init(&hwiParams);
   131     *      // Default Hwi type is IRQ
   132     *      hwiParams.type = Hwi_Type_FIQ;
   133     *      Hwi_create(INT_NUM_FIQ, myIsrFIQ, &hwiParams, NULL);
   134     *      ...
   135     *  }
   136     *  @p
   137     *
   138     *  FIQs run on their own stack. See {@link #fiqStack} and {@link #fiqStackSize}
   139     *  for more info on how to control the FIQ stack.
   140     *
   141     *  @a(NOTE)
   142     *  This module is written for GIC v2.0, however it is backwards compatible
   143     *  with GIC v1.0
   144     */
   145    
   146    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   147    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   148    @InstanceInitStatic     /* allow constructs in static only systems */
   149    @CustomHeader
   150    
   151    module Hwi inherits ti.sysbios.interfaces.IHwi
   152    {
   153        // -------- Module Constants --------
   154    
   155        /*!
   156         *  ======== enableSecureMode ========
   157         *  Security Mode
   158         *
   159         *  This field specifies the MPU's security mode. The MPU's security mode
   160         *  determines the type of accesses to the GIC i.e. if the MPU is in secure
   161         *  mode, all accesses to the GIC are secure and if the MPU is in non-secure
   162         *  mode, all accesses to the GIC are non-secure.
   163         *
   164         *  An exception to the above rule can be seen on certain devices like
   165         *  Keystone 2, where all GIC acceses are secure irrespective of the MPU's
   166         *  security state. {@link #enableSecureMode} should be set to true for such
   167         *  devices.
   168         */
   169        config Bool enableSecureMode = false;
   170    
   171        /*!
   172         *  Number of interrupts implemented in GIC
   173         *
   174         *  On OMAP543x GIC implements 192 interrupts.
   175         *
   176         *  See the OMAP543x_ES1 Technical Reference Manual pg 5280 for more
   177         *  details.
   178         */
   179        config UInt NUM_INTERRUPTS;
   180    
   181        /*!
   182         *  Number of Priority bits implemented.
   183         *
   184         *  On OMAP543x running in non-secure mode, only most significant 4
   185         *  priority bits are available for use. The least significant 4 bits
   186         *  are always 0.
   187         */
   188        config UInt NUM_PRIORITY_BITS;
   189    
   190        /*!
   191         *  Minimum Interrupt Priority.
   192         */
   193        config UInt MIN_INT_PRIORITY;
   194    
   195        /*!
   196         *  Default Interrupt Priority.
   197         *
   198         *  Set to one level higher than minimum supported priority.
   199         */
   200        config UInt DEFAULT_INT_PRIORITY;
   201    
   202        /*!
   203         *  ======== BPR ========
   204         *  GIC Binary Point Register value
   205         *
   206         *  Defines the point at which the priority value fields split into
   207         *  two parts, the group priority field and the sub-priority field.
   208         *  When running in SECURE mode, BPR applies to Group 0 interrupts
   209         *  and when running in NON-SECURE mode, BPR applies to Group 1
   210         *  interrupts.
   211         *
   212         *  The group priority field determines interrupt preemption in case
   213         *  of nested interrupts whereas sub-priority field is used to determine
   214         *  priority within a group when multiple interrrupts belonging to the
   215         *  same group are pending.
   216         *
   217         *  Valid BPR values are from 0-7 with the minimum value supported being
   218         *  implementation defined and in the range 0-3.
   219         *
   220         *  @p(code)
   221         *   -------------------------------------------------------
   222         *  | BPR value | Group priority field | Sub-priority field |
   223         *   -------------------------------------------------------
   224         *  |     0     |         [7:1]        |         [0]        |
   225         *  |     1     |         [7:2]        |        [1:0]       |
   226         *  |     2     |         [7:3]        |        [2:0]       |
   227         *  |     3     |         [7:4]        |        [3:0]       |
   228         *  |     4     |         [7:5]        |        [4:0]       |
   229         *  |     5     |         [7:6]        |        [5:0]       |
   230         *  |     6     |          [7]         |        [6:0]       |
   231         *  |     7     |     No preemption    |        [7:0]       |
   232         *   -------------------------------------------------------
   233         *  @p
   234         *
   235         */
   236        config UInt BPR;
   237    
   238        /*!
   239         *  ======== ABPR ========
   240         *  GIC Aliased Binary Point Register value for Grourp 1 interrupts
   241         *
   242         *  Defines the point at which the priority value fields split into
   243         *  two parts, the group priority field and the sub-priority field.
   244         *  ABPR is used only when {@link #enableSecureMode} set to true and
   245         *  is ignored when security mode is set to false. ABPR applies to
   246         *  Group 1 interrupts.
   247         *
   248         *  The group priority field determines interrupt preemption in case
   249         *  of nested interrupts whereas sub-priority field is used to determine
   250         *  priority within a group when multiple interrrupts belonging to the
   251         *  same group are pending.
   252         *
   253         *  Valid ABPR values are from 1-7 with the minimum value supported being
   254         *  implementation defined and in the range 1-4. Minimum ABPR value is
   255         *  1 more than the minimum BPR value.
   256         *
   257         *  @p(code)
   258         *   --------------------------------------------------------
   259         *  | ABPR value | Group priority field | Sub-priority field |
   260         *   --------------------------------------------------------
   261         *  |     0      |          --          |         --         |
   262         *  |     1      |         [7:1]        |         [0]        |
   263         *  |     2      |         [7:2]        |        [1:0]       |
   264         *  |     3      |         [7:3]        |        [2:0]       |
   265         *  |     4      |         [7:4]        |        [3:0]       |
   266         *  |     5      |         [7:5]        |        [4:0]       |
   267         *  |     6      |         [7:6]        |        [5:0]       |
   268         *  |     7      |          [7]         |        [6:0]       |
   269         *   --------------------------------------------------------
   270         *  @p
   271         *
   272         */
   273        config UInt ABPR;
   274    
   275        /*!
   276         *  ======== Type ========
   277         *  Interrupt type. IRQ or FIQ
   278         */
   279        enum Type {
   280            Type_IRQ,               /*! IRQ interrupt. */
   281            Type_FIQ                /*! FIQ interrupt. */
   282        };
   283    
   284        // -------- Module Types --------
   285    
   286        /*! Hwi vector function type definition. */
   287        typedef Void (*VectorFuncPtr)(void);
   288    
   289        /*!
   290         *  ======== BasicView ========
   291         *  @_nodoc
   292         */
   293        metaonly struct BasicView {
   294            Ptr         halHwiHandle;
   295            String      label;
   296            Int         intNum;
   297            String      absolutePriority;
   298            UInt        relativeGrpPriority;
   299            UInt        relativeSubPriority;
   300            String      fxn;
   301            UArg        arg;
   302        };
   303    
   304        /*!
   305         *  ======== DetailedView ========
   306         *  @_nodoc
   307         */
   308        metaonly struct DetailedView {
   309            Ptr         halHwiHandle;
   310            String      label;
   311            Int         intNum;
   312            String      absolutePriority;
   313            UInt        relativeGrpPriority;
   314            UInt        relativeSubPriority;
   315            String      fxn;
   316            UArg        arg;
   317            Ptr         irp;
   318            Bool        enabled;
   319            Bool        pending;
   320            String      triggerSensitivity;
   321            String      targetProcList;
   322        };
   323    
   324        /*!
   325         *  ======== ModuleView ========
   326         *  @_nodoc
   327         */
   328        metaonly struct ModuleView {
   329            String      options[4];
   330            UInt        spuriousInterrupts;
   331            UInt        lastSpuriousInterrupt;
   332            String      hwiStackPeak;
   333            SizeT       hwiStackSize;
   334            Ptr         hwiStackBase;
   335        };
   336    
   337        /*!
   338         *  ======== rovViewInfo ========
   339         *  @_nodoc
   340         */
   341        @Facet
   342        metaonly config ViewInfo.Instance rovViewInfo =
   343            ViewInfo.create({
   344                viewMap: [
   345                    [
   346                        'Basic',
   347                        {
   348                            type: ViewInfo.INSTANCE,
   349                            viewInitFxn: 'viewInitBasic',
   350                            structName: 'BasicView'
   351                        }
   352                    ],
   353                    [
   354                        'Detailed',
   355                        {
   356                            type: ViewInfo.INSTANCE,
   357                            viewInitFxn: 'viewInitDetailed',
   358                            structName: 'DetailedView'
   359                        }
   360                    ],
   361                    [
   362                        'Module',
   363                        {
   364                            type: ViewInfo.MODULE,
   365                            viewInitFxn: 'viewInitModule',
   366                            structName: 'ModuleView'
   367                        }
   368                    ]
   369                ]
   370            });
   371    
   372        /*!
   373         * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
   374         * a physical device
   375         */
   376        struct Gicd {
   377            UInt32 CTLR;            /*! 0x000 Distributor Control Register */
   378            UInt32 TYPER;           /*! 0x004 Interrupt Controller Type Register */
   379            UInt32 IIDR;            /*! 0x008 Distributor Implementor Id Register */
   380            UInt32 hole0[29];       /*! 0x00C-0x07C */
   381            UInt32 IGROUPR[32];     /*! 0x080 Interrupt Group Registers */
   382            UInt32 ISENABLER[32];   /*! 0x100 Interrupt Set-Enable Registers */
   383            UInt32 ICENABLER[32];   /*! 0x180 Interrupt Clear-Enable Registers */
   384            UInt32 ISPENDR[32];     /*! 0x200 Interrupt Set-Pending Registers */
   385            UInt32 ICPENDR[32];     /*! 0x280 Interrupt Clear-Pending Registers */
   386            UInt32 ISACTIVER[32];   /*! 0x300 Interrupt Set-Active Registers */
   387            UInt32 ICACTIVER[32];   /*! 0x380 Interrupt Clear-Active Registers */
   388            UInt32 IPRIORITYR[255]; /*! 0x400 Interrupt Priority Registers */
   389            UInt32 hole1[1];        /*! 0x7FC */
   390            UInt32 ITARGETSR[255];  /*! 0x800 Interrupt Processor Targets Register */
   391            UInt32 hole2[1];        /*! 0xBFC */
   392            UInt32 ICFGR[64];       /*! 0xC00 Interrupt Configuration Registers */
   393            UInt32 PPISR;           /*! 0xD00 PPI Status Register */
   394            UInt32 SPISR[7];        /*! 0xD04 SPI Status Registers */
   395            UInt32 hole3[120];      /*! 0xD20-0xEFC */
   396            UInt32 SGIR;            /*! 0xF00 Software Generated Interrupt
   397                                              Registers */
   398            UInt32 hole4[3];        /*! 0xF04-0xF0C */
   399            UInt32 CPENDSGIR[4];    /*! 0xF10 SGI Clear-Pending Registers */
   400            UInt32 SPENDSGIR[4];    /*! 0xF20 SGI Set-Pending Registers */
   401            UInt32 hole5[40];       /*! 0xF30-0xFCC */
   402            UInt32 PIDR4;           /*! 0xFD0 Peripheral ID4 Register */
   403            UInt32 PIDR5;           /*! 0xFD4 Peripheral ID5 Register */
   404            UInt32 PIDR6;           /*! 0xFD8 Peripheral ID6 Register */
   405            UInt32 PIDR7;           /*! 0xFDC Peripheral ID7 Register */
   406            UInt32 PIDR0;           /*! 0xFE0 Peripheral ID0 Register */
   407            UInt32 PIDR1;           /*! 0xFE4 Peripheral ID1 Register */
   408            UInt32 PIDR2;           /*! 0xFE8 Peripheral ID2 Register */
   409            UInt32 PIDR3;           /*! 0xFEC Peripheral ID3 Register */
   410            UInt32 CIDR0;           /*! 0xFF0 Component  ID0 Register */
   411            UInt32 CIDR1;           /*! 0xFF4 Component  ID1 Register */
   412            UInt32 CIDR2;           /*! 0xFF8 Component  ID2 Register */
   413            UInt32 CIDR3;           /*! 0xFFC Component  ID3 Register */
   414        };
   415    
   416        extern volatile Gicd gicd;
   417    
   418        /*!
   419         * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
   420         * a physical device.
   421         */
   422        struct Gicc {
   423            UInt32 CTLR;            /*! 0x0000 CPU Interface Control Register */
   424            UInt32 PMR;             /*! 0x0004 Interrupt Priority Mask Register */
   425            UInt32 BPR;             /*! 0x0008 Binary Point Register */
   426            UInt32 IAR;             /*! 0x000C Interrupt Acknowledge Register */
   427            UInt32 EOIR;            /*! 0x0010 End Of Interrupt Register */
   428            UInt32 RPR;             /*! 0x0014 Running Priority Register */
   429            UInt32 HPPIR;           /*! 0x0018 Highest Priority Pending Interrupt
   430                                        Register */
   431            UInt32 ABPR;            /*! 0x001C Aliased Binary Point Register */
   432            UInt32 AIAR;            /*! 0x0020 Aliased IAR Register */
   433            UInt32 AEOIR;           /*! 0x0024 Aliased EOI Register */
   434            UInt32 AHPPIR;          /*! 0x0028 Aliased HPPI Register */
   435            UInt32 hole0[41];       /*! 0x002C-0x00CC */
   436            UInt32 APR0;            /*! 0x00D0 Active Priority Register */
   437            UInt32 hole1[3];        /*! 0x00D4-0x00DC */
   438            UInt32 NSAPR0;          /*! 0x00E0 Non-secure Active Priority Register */
   439            UInt32 hole2[6];        /*! 0x00E4-0x00F8 */
   440            UInt32 IIDR;            /*! 0x00FC CPU Interface Id Register */
   441            UInt32 hole3[960];      /*! 0x0100-0x0FFC */
   442            UInt32 DIR;             /*! 0x1000 Deactivate Interrupt Register */
   443        };
   444    
   445        extern volatile Gicc gicc;
   446    
   447        // -------- Module Parameters --------
   448    
   449        /*! Reset Handler. Default is _c_int00 */
   450        metaonly config VectorFuncPtr resetFunc;
   451    
   452        /*!
   453         * Undefined instruction exception handler.
   454         * Default is an internal exception handler.
   455         */
   456        metaonly config VectorFuncPtr undefinedInstFunc;
   457    
   458        /*!
   459         * SVC Handler. Supervisor Call exception handler.
   460         * (previously called Software Interrupt or SWI)
   461         * Default is an internal exception handler.
   462         */
   463        metaonly config VectorFuncPtr svcFunc;
   464    
   465        /*!
   466         * Prefetch abort exception handler.
   467         * Default is an internal exception handler.
   468         */
   469        metaonly config VectorFuncPtr prefetchAbortFunc;
   470    
   471        /*!
   472         * Data abort exception handler.
   473         * Default is an internal exception handler.
   474         */
   475        metaonly config VectorFuncPtr dataAbortFunc;
   476    
   477        /*!
   478         * Reserved exception handler.
   479         * Default is an internal exception handler.
   480         */
   481        metaonly config VectorFuncPtr reservedFunc;
   482    
   483        /*! IRQ interrupt handler.
   484         *  Default is internal IRQ dispatcher
   485         */
   486        metaonly config VectorFuncPtr irqFunc;
   487    
   488        /*! FIQ interrupt handler.
   489         *  Default is internal exception handler.
   490         */
   491        metaonly config VectorFuncPtr fiqFunc;
   492    
   493        /*!
   494         *  @_nodoc
   495         *  ======== enableAsidTagging ========
   496         *  Flag to enable/disable ASID tagging
   497         *
   498         *  If ASID tagging is enabled, the Hwi dispatcher will switch
   499         *  to ASID 0 (and change the MMU table base address to match
   500         *  kernel MMU table address) in the Hwi dispatcher prolog
   501         *  and restore the ASID (and MMU table base address) in the
   502         *  Hwi dispatcher epilog.
   503         */
   504        config Bool enableAsidTagging = false;
   505    
   506        /*!
   507         *  @_nodoc
   508         *  ======== irqStackSection ========
   509         *  Memory section used for IRQ stack on each core
   510         *  Default is null.
   511         */
   512        metaonly config String irqStackSection = null;
   513    
   514        /*!
   515         *  @_nodoc
   516         *  ======== fiqStack ========
   517         *  FIQ stack pointer. Default = null.
   518         *  (Indicates that stack is to be created internally)
   519         *
   520         *  @a(Note)
   521         *  If running in SMP mode and both fiqStack and fiqStacks[0]
   522         *  are set, then fiqStack is used on Core0.
   523         */
   524        metaonly config Ptr fiqStack = null;
   525        metaonly config Ptr fiqStacks[];
   526    
   527        /*!
   528         *  ======== fiqStackSize ========
   529         *  FIQ stack size in MAUs.
   530         *  Default is 1024 bytes.
   531         *
   532         *  If running in SMP mode, the FIQ stacks on all cores are
   533         *  set to this size.
   534         */
   535        metaonly config SizeT fiqStackSize = 1024;
   536    
   537        /*!
   538         *  ======== fiqStackSection ========
   539         *  Memory section used for FIQ stack
   540         *  Default is null.
   541         */
   542        metaonly config String fiqStackSection = null;
   543    
   544        /*!
   545         *  ======== A_badSGIIntNum ========
   546         *  Assert raised when an interrupt number >= 16 is
   547         *  passed to Hwi_raiseSGI() function.
   548         */
   549        config xdc.runtime.Assert.Id A_badSGIIntNum  = {
   550            msg: "A_badSGIIntNum: SGI intNum should be <= 15."
   551        };
   552    
   553        /*!
   554         *  Error raised when an attempt is made to create a Hwi
   555         *  that has already been created.
   556         */
   557        config Error.Id E_alreadyDefined = {
   558            msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
   559        };
   560    
   561        /*!
   562         *  Error raised when Hwi handle referenced in Hwi_delete()
   563         *  is not found in the Hwi dispatch table
   564         */
   565        config Error.Id E_handleNotFound = {
   566            msg: "E_handleNotFound: Hwi handle not found: 0x%x"
   567        };
   568    
   569        /*!
   570         *  Error raised when an undefined interrupt has fired.
   571         */
   572        config Error.Id E_undefined = {
   573            msg: "E_undefined: Hwi undefined, intnum: %d"
   574        };
   575    
   576        /*!
   577         *  Error raised if an attempt is made to create a Hwi
   578         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   579         */
   580        config Error.Id E_badIntNum = {
   581            msg: "E_badIntNum, intnum: %d is out of range"
   582        };
   583    
   584        /*!
   585         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   586         */
   587        config Log.Event LM_begin = {
   588            mask: Diags.USER1 | Diags.USER2,
   589            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   590        };
   591    
   592        /*!
   593         *  Issued just after return from Hwi function (with interrupts disabled)
   594         */
   595        config Log.Event LD_end = {
   596            mask: Diags.USER2,
   597            msg: "LD_end: hwi: 0x%x"
   598        };
   599    
   600    
   601        // -------- Module Functions --------
   602    
   603        /*!
   604         *  ======== disable ========
   605         *  Globally disable interrupts.
   606         *
   607         *  Hwi_disable globally disables hardware interrupts and returns an
   608         *  opaque key indicating whether interrupts were globally enabled or
   609         *  disabled on entry to Hwi_disable(). 
   610         *  The actual value of the key is target/device specific and is meant 
   611         *  to be passed to Hwi_restore(). 
   612         *
   613         *  Call Hwi_disable before a portion of a function that needs
   614         *  to run without interruption. When critical processing is complete, call
   615         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   616         *
   617         *  Servicing of interrupts that occur while interrupts are disabled is
   618         *  postponed until interrupts are reenabled. However, if the same type 
   619         *  of interrupt occurs several times while interrupts are disabled, 
   620         *  the interrupt's function is executed only once when interrupts are 
   621         *  reenabled.
   622         *
   623         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   624         *  an enabled interrupt occurred while interrupts are disabled.
   625         *
   626         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   627         *  are already disabled in main(), such a call has no effect.
   628         *
   629         *  @a(NOTE)
   630         *  Disables only IRQ interrupts
   631         *
   632         *  @a(constraints)
   633         *  If a Task switching API such as 
   634         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()}, 
   635         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   636         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   637         *  {@link ti.sysbios.knl.Task#yield Task_yield()} 
   638         *  is invoked which results in a context switch while
   639         *  interrupts are disabled, an embedded call to 
   640         *  {@link #enable Hwi_enable} occurs
   641         *  on the way to the new thread context which unconditionally re-enables
   642         *  interrupts. Interrupts will remain enabled until a subsequent 
   643         *  {@link #disable Hwi_disable}
   644         *  invocation.
   645         *
   646         *  Swis always run with interrupts enabled.
   647         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   648         *  interrupts.
   649         *
   650         *  @b(returns)     opaque key for use by Hwi_restore()
   651         */
   652        @Macro
   653        override UInt disable();
   654    
   655        /*!
   656         *  ======== enable ========
   657         *
   658         *  @a(NOTE)
   659         *  Enables only IRQ interrupts
   660         */
   661        @Macro
   662        override UInt enable();
   663    
   664        /*!
   665         *  ======== restore ========
   666         *
   667         *  @a(NOTE)
   668         *  Restores only IRQ interrupts
   669         */
   670        @Macro
   671        override Void restore(UInt key);
   672    
   673        /*!
   674         *  ======== enableIRQ ========
   675         *  Enable IRQ interrupts.
   676         *
   677         *  @a(NOTE)
   678         *  Same as Hwi_enable()
   679         *
   680         *  @b(returns)     previous IRQ interrupt enable/disable state
   681         */
   682        @Macro
   683        UInt enableIRQ();
   684    
   685        /*!
   686         *  ======== disableIRQ ========
   687         *  Disable IRQ interrupts.
   688         *
   689         *  @a(NOTE)
   690         *  Same as Hwi_disable()
   691         *
   692         *  @b(returns)     previous IRQ interrupt enable/disable state
   693         */
   694        @Macro
   695        UInt disableIRQ();
   696    
   697        /*!
   698         *  ======== restoreIRQ ========
   699         *  Restore IRQ interrupts.
   700         *
   701         *  @a(NOTE)
   702         *  Same as Hwi_restore()
   703         *
   704         *  @param(key)     enable/disable state to restore
   705         */
   706        @Macro
   707        Void restoreIRQ(UInt key);
   708    
   709        /*!
   710         *  ======== enableFIQ ========
   711         *  Enable FIQ interrupts.
   712         *
   713         *  @b(returns)     previous FIQ interrupt enable/disable state
   714         */
   715        @Macro
   716        UInt enableFIQ();
   717    
   718        /*!
   719         *  ======== disableFIQ ========
   720         *  Disable FIQ interrupts.
   721         *
   722         *  @b(returns)     previous FIQ interrupt enable/disable state
   723         */
   724        @Macro
   725        UInt disableFIQ();
   726    
   727        /*!
   728         *  ======== restoreFIQ ========
   729         *  Restore FIQ interrupts.
   730         *
   731         *  @param(key)     enable/disable state to restore
   732         */
   733        @Macro
   734        Void restoreFIQ(UInt key);
   735    
   736        /*!
   737         *  @_nodoc
   738         *  ======== disableFxn ========
   739         *  function call implementation
   740         */
   741        UInt disableFxn();
   742    
   743        /*!
   744         *  @_nodoc
   745         *  ======== enableFxn ========
   746         *  function call implementation
   747         */
   748        UInt enableFxn();
   749    
   750        /*!
   751         *  @_nodoc
   752         *  ======== restoreFxn ========
   753         *  function call implementation
   754         */
   755        Void restoreFxn(UInt key);
   756    
   757        /*!
   758         *  ======== getHandle ========
   759         *  Returns Hwi_Handle associated with intNum
   760         *
   761         *  @param(intNum)  interrupt number
   762         */
   763        Handle getHandle(UInt intNum);
   764    
   765        /*!
   766         *  @_nodoc
   767         *  ======== init ========
   768         *  assembly code mode registers setup
   769         */
   770        Void init();
   771    
   772        /*!
   773         *  @_nodoc
   774         *  ======== initIntControllerCoreX ========
   775         */
   776        Void initIntControllerCoreX();
   777    
   778        /*!
   779         *  ======== intAffinity ========
   780         *  SMP Interrupt affinity mappings
   781         *
   782         *  In SMP mode, this array maps an interrupt number to the
   783         *  coreId it is to be tied to. By default, all ints are mapped to
   784         *  core 0.
   785         *
   786         *  For example, to make Timer 1 from the ti.sysbios.timers.dmtimer.Timer
   787         *  module interrupt on core 1 rather than core 0, add the following to
   788         *  your config file:
   789         *
   790         *  @p(code)
   791         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gic.Hwi');
   792         *     Hwi.intAffinity[<intNum>] = 1;
   793         *  @p
   794         *
   795         *  @a(constraints)
   796         *  Interrupt numbers below 32 are ignored. This config param only
   797         *  allows routing interrupt numbers greater than or equal to #32.
   798         */
   799        metaonly config UInt8 intAffinity[];
   800    
   801        /*!
   802         *  @_nodoc
   803         *  ======== raiseSGI ========
   804         */
   805        Void raiseSGI(UInt mask, UInt intNum);
   806    
   807        /*!
   808         *  ======== setPriority ========
   809         *  Set an interrupt's priority.
   810         *
   811         *  Not an instance function so that it can be used
   812         *  with non-dispatched interrupts.
   813         *
   814         *  @param(intNum)      ID of interrupt
   815         *  @param(priority)    priority
   816         */
   817        Void setPriority(UInt intNum, UInt priority);
   818    
   819    instance:
   820    
   821        /*!
   822         *  ======== type ========
   823         *  Interrupt type (IRQ/FIQ). Default is IRQ.
   824         *
   825         *  @a(NOTE)
   826         *  FIQs are only supported when {@link #enableSecureMode} is set to
   827         *  true.
   828         */
   829        config Type type = Type_IRQ;
   830    
   831        /*!
   832         *  ======== triggerSensitivity ========
   833         *  Set an interrupt's trigger sensitivity
   834         *
   835         *  2-bit field that configures the trigger sensitivity of an
   836         *  interrupt.
   837         *
   838         *  On the Cortex-A15, all software generated interrupts (SGI)
   839         *  are edge-triggered (b10) and all private peripheral interrupts (PPI)
   840         *  are level-sensitive (b01). The trigger sensitivity of these
   841         *  interrupt types cannot be changed.
   842         *
   843         *  For shared peripheral interrupts (SPI), the LSB of the bit-pair
   844         *  is read only and is always 1. The MSB of the bit-pair can be
   845         *  altered to change trigger sensitivity.
   846         *
   847         *  Possible bit-pair encodings for Cortex-A15 SPIs:
   848         *      b01    Interrupt is active-High level-sensitive (default)
   849         *      b11    Interrupt is rising edge-sensitive
   850         *
   851         *  For more information please refer section 4.3.13 on
   852         *  Interrupt Configuration Registers (GICD_ICFGRn) in
   853         *  ARM Generic Interrupt Controller Architecure Spec v2.0
   854         */
   855        config UInt triggerSensitivity = ~(0);
   856    
   857        /*!
   858         *  ======== targetProcList ========
   859         *  Set an interrupt's target processor list.
   860         *
   861         *  This is an 8-bit CPU targets field that stores the list of target
   862         *  processors for the interrupt. That is, it holds the list of CPU
   863         *  interfaces to which the GIC Distributor will forward the interrupt
   864         *  if it is asserted and has sufficient priority.
   865         *
   866         *  Each bit in targetProcList refers to the corresponding processor.
   867         *  For instance, a value of 0x3 means the pending interrupt is
   868         *  forwarded to processor 0 and 1.
   869         *
   870         *  For more information please refer section 4.3.12 on
   871         *  Interrupt Processor Targets Registers (GICD_ITARGETSRn) in
   872         *  ARM Generic Interrupt Controller Architecure Spec v2.0
   873         *
   874         *  If running in {@link ti.sysbios.BIOS#smpEnabled SMP mode}
   875         *  and both the targetProcList Hwi param as well as the
   876         *  {@link #intAffinity}[] array entry for the intNum are set,
   877         *  targetProcList is given precedence and is used to configure
   878         *  the interrupt's target processors.
   879         *
   880         *  @a(NOTE)
   881         *  Target processor list is read-only for the first 32 interrupts.
   882         *  Therefore, this field will have no effect for interrupt numbers
   883         *  less than 32 (intNum 0-31).
   884         */
   885        config UInt targetProcList = 0x0;
   886    
   887        /*!
   888         *  ======== Interrupt priority ========
   889         *  Hwi instance interrupt priority.
   890         *
   891         *  Valid priorities are device dependent and their
   892         *  nesting behaviors depend on the {@link #BPR} setting.
   893         *
   894         *  See the ARM GIC Architecture Specification v2.0 document for more
   895         *  details.
   896         */
   897        override config Int priority = -1;
   898    
   899        /*! The interrupt controller is designed for priority based interrupts */
   900        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
   901    
   902        /*!
   903         *  ======== reconfig ========
   904         *  Reconfigure a dispatched interrupt.
   905         */
   906        Void reconfig(FuncPtr fxn, const Params *params);
   907    
   908    internal:   /* not for client use */
   909    
   910        /*!
   911         *  ======== inUseMeta ========
   912         *  @_nodoc
   913         *  Check for Hwi already in use.
   914         *  For internal SYS/BIOS use only.
   915         *  Should be called prior to any internal Hwi.create().
   916         *
   917         *  @param(intNum)  interrupt number
   918         */
   919        metaonly Bool inUseMeta(UInt intNum);
   920    
   921        /*
   922         * Swi and Task module function pointers.
   923         * Used to decouple Hwi from Swi and Task when
   924         * dispatcherSwiSupport or
   925         * dispatcherTaskSupport is false.
   926         */
   927        config UInt (*swiDisable)();
   928        config Void (*swiRestoreHwi)(UInt);
   929        config UInt (*taskDisable)();
   930        config Void (*taskRestoreHwi)(UInt);
   931    
   932        /*
   933         *  ======== postInit ========
   934         *  finish initializing static and dynamic Hwis
   935         */
   936        Int postInit(Object *hwi, Error.Block *eb);
   937    
   938        /*
   939         *  ======== initIntControllerCore0 ========
   940         */
   941        Void initIntControllerCore0();
   942    
   943        /* setup FIQ stack pointer */
   944        Void initFIQStack(Ptr fiqStack);
   945    
   946        /* default FIQ Interrupt Dispatcher */
   947        Void dispatchFIQC();
   948    
   949        /* Interrupt Dispatcher assembly code wrapper */
   950        Void dispatchIRQ();
   951    
   952        /* Interrupt Dispatcher C code */
   953        Void dispatchIRQC(Irp irp);
   954    
   955        /* non plugged interrupt handler */
   956        Void nonPluggedHwiHandler(UArg arg);
   957    
   958        /*!
   959         *  const array to hold all HookSet objects.
   960         */
   961        config HookSet hooks[length] = [];
   962    
   963        /*! Meta World Only Hwi Configuration Object. */
   964        metaonly struct InterruptObj {
   965            Bool used;              /* Interrupt already defined? */
   966            FuncPtr fxn;            /* Dispatched ISR function */
   967        };
   968    
   969        /*!
   970         * Meta-only array of interrupt objects.
   971         * This meta-only array of Hwi config objects is initialized
   972         * in Hwi.xs:module$meta$init().
   973         */
   974        metaonly config InterruptObj interrupt[];
   975    
   976        /*!
   977         * GIC Distributor base address
   978         */
   979        metaonly config Ptr gicdBaseAddress;
   980    
   981        /*!
   982         * GIC cpu interface base address
   983         */
   984        metaonly config Ptr giccBaseAddress;
   985    
   986        struct Instance_State {
   987            Type        type;             // Interrupt Type
   988            UInt        priority;         // Interrupt Priority
   989            UArg        arg;              // Argument to Hwi function.
   990            FuncPtr     fxn;              // Hwi function.
   991            Irp         irp;              // current IRP
   992            Ptr         hookEnv[];
   993            UInt        triggerSensitivity;
   994            UInt        targetProcList;
   995        };
   996    
   997        struct Module_State {
   998            Char         *taskSP[];       // temporary storage of interrupted
   999                                          // Task's SP during ISR execution
  1000            Char         *isrStack[];     // Points to isrStack address
  1001            Char          hwiStack[][];   // IRQ stack for each core
  1002            Ptr           isrStackSize;   // = Program.stack
  1003                                          // !!! The above three fields MUST be kept
  1004                                          // !!! at the base of the module state
  1005                                          // !!! GNU switchAndRunFunc and
  1006                                          // !!! SMP Core module assumes it
  1007            UInt32        iser[32];       // Initial Interrupt Set Enable Reg values
  1008            UInt32        icfgr[];        // Initial Trigger sensitivity values
  1009            UInt32        itargetsr[];    // Initial interrupt target processors
  1010            UInt          spuriousInts;   // Count of spurious interrupts
  1011            UInt          lastSpuriousInt;// Most recent spurious interrupt
  1012            UInt          irp;            // temporary irp storage for IRQ handler
  1013            Ptr           isrStackBase;   // = __TI_STACK_BASE
  1014            Hwi.Object    nonPluggedHwi;  // default Hwi object
  1015            Handle        dispatchTable[];// dispatch table
  1016            volatile UInt curIntId;       // current Interrupt Id
  1017            UInt32        igroupr[];      // Initial Interrupt Group (0/1)
  1018            Char          fiqStack[][];   // buffers used for FIQ stacks
  1019            SizeT         fiqStackSize;   // FIQ stack size
  1020            UInt8         intAffinity[];  // smp int-to-coreId mappings
  1021        };
  1022    }