1    /*
     2     * Copyright (c) 2015-2017, 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         *  ======== initGicd ========
   508         *  Initialize all GIC Distributor registers. True by default.
   509         *
   510         *  Flag determines whether to initialize certain global GIC distributor
   511         *  registers. It is set to false when running under a hypervisor and
   512         *  should be true if not running under a hypervisor.
   513         */
   514        config Bool initGicd = true;
   515    
   516        /*!
   517         *  @_nodoc
   518         *  ======== irqStackSection ========
   519         *  Memory section used for IRQ stack on each core
   520         *  Default is null.
   521         */
   522        metaonly config String irqStackSection = null;
   523    
   524        /*!
   525         *  @_nodoc
   526         *  ======== fiqStack ========
   527         *  FIQ stack pointer. Default = null.
   528         *  (Indicates that stack is to be created internally)
   529         *
   530         *  @a(Note)
   531         *  If running in SMP mode and both fiqStack and fiqStacks[0]
   532         *  are set, then fiqStack is used on Core0.
   533         */
   534        metaonly config Ptr fiqStack = null;
   535        metaonly config Ptr fiqStacks[];
   536    
   537        /*!
   538         *  ======== fiqStackSize ========
   539         *  FIQ stack size in MAUs.
   540         *  Default is 1024 bytes.
   541         *
   542         *  If running in SMP mode, the FIQ stacks on all cores are
   543         *  set to this size.
   544         */
   545        metaonly config SizeT fiqStackSize = 1024;
   546    
   547        /*!
   548         *  ======== fiqStackSection ========
   549         *  Memory section used for FIQ stack
   550         *  Default is null.
   551         */
   552        metaonly config String fiqStackSection = null;
   553    
   554        /*!
   555         *  ======== A_badSGIIntNum ========
   556         *  Assert raised when an interrupt number >= 16 is
   557         *  passed to Hwi_raiseSGI() function.
   558         */
   559        config xdc.runtime.Assert.Id A_badSGIIntNum  = {
   560            msg: "A_badSGIIntNum: SGI intNum should be <= 15."
   561        };
   562    
   563        /*!
   564         *  Error raised when an attempt is made to create a Hwi
   565         *  that has already been created.
   566         */
   567        config Error.Id E_alreadyDefined = {
   568            msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
   569        };
   570    
   571        /*!
   572         *  Error raised when Hwi handle referenced in Hwi_delete()
   573         *  is not found in the Hwi dispatch table
   574         */
   575        config Error.Id E_handleNotFound = {
   576            msg: "E_handleNotFound: Hwi handle not found: 0x%x"
   577        };
   578    
   579        /*!
   580         *  Error raised when an undefined interrupt has fired.
   581         */
   582        config Error.Id E_undefined = {
   583            msg: "E_undefined: Hwi undefined, intnum: %d"
   584        };
   585    
   586        /*!
   587         *  Error raised if an attempt is made to create a Hwi
   588         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   589         */
   590        config Error.Id E_badIntNum = {
   591            msg: "E_badIntNum, intnum: %d is out of range"
   592        };
   593    
   594        /*!
   595         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   596         */
   597        config Log.Event LM_begin = {
   598            mask: Diags.USER1 | Diags.USER2,
   599            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   600        };
   601    
   602        /*!
   603         *  Issued just after return from Hwi function (with interrupts disabled)
   604         */
   605        config Log.Event LD_end = {
   606            mask: Diags.USER2,
   607            msg: "LD_end: hwi: 0x%x"
   608        };
   609    
   610    
   611        // -------- Module Functions --------
   612    
   613        /*!
   614         *  ======== disable ========
   615         *  Globally disable interrupts.
   616         *
   617         *  Hwi_disable globally disables hardware interrupts and returns an
   618         *  opaque key indicating whether interrupts were globally enabled or
   619         *  disabled on entry to Hwi_disable(). 
   620         *  The actual value of the key is target/device specific and is meant 
   621         *  to be passed to Hwi_restore(). 
   622         *
   623         *  Call Hwi_disable before a portion of a function that needs
   624         *  to run without interruption. When critical processing is complete, call
   625         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   626         *
   627         *  Servicing of interrupts that occur while interrupts are disabled is
   628         *  postponed until interrupts are reenabled. However, if the same type 
   629         *  of interrupt occurs several times while interrupts are disabled, 
   630         *  the interrupt's function is executed only once when interrupts are 
   631         *  reenabled.
   632         *
   633         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   634         *  an enabled interrupt occurred while interrupts are disabled.
   635         *
   636         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   637         *  are already disabled in main(), such a call has no effect.
   638         *
   639         *  @a(NOTE)
   640         *  Disables only IRQ interrupts
   641         *
   642         *  @a(constraints)
   643         *  If a Task switching API such as 
   644         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()}, 
   645         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   646         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   647         *  {@link ti.sysbios.knl.Task#yield Task_yield()} 
   648         *  is invoked which results in a context switch while
   649         *  interrupts are disabled, an embedded call to 
   650         *  {@link #enable Hwi_enable} occurs
   651         *  on the way to the new thread context which unconditionally re-enables
   652         *  interrupts. Interrupts will remain enabled until a subsequent 
   653         *  {@link #disable Hwi_disable}
   654         *  invocation.
   655         *
   656         *  Swis always run with interrupts enabled.
   657         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   658         *  interrupts.
   659         *
   660         *  @b(returns)     opaque key for use by Hwi_restore()
   661         */
   662        @Macro
   663        override UInt disable();
   664    
   665        /*!
   666         *  ======== enable ========
   667         *
   668         *  @a(NOTE)
   669         *  Enables only IRQ interrupts
   670         */
   671        @Macro
   672        override UInt enable();
   673    
   674        /*!
   675         *  ======== restore ========
   676         *
   677         *  @a(NOTE)
   678         *  Restores only IRQ interrupts
   679         */
   680        @Macro
   681        override Void restore(UInt key);
   682    
   683        /*!
   684         *  ======== enableIRQ ========
   685         *  Enable IRQ interrupts.
   686         *
   687         *  @a(NOTE)
   688         *  Same as Hwi_enable()
   689         *
   690         *  @b(returns)     previous IRQ interrupt enable/disable state
   691         */
   692        @Macro
   693        UInt enableIRQ();
   694    
   695        /*!
   696         *  ======== disableIRQ ========
   697         *  Disable IRQ interrupts.
   698         *
   699         *  @a(NOTE)
   700         *  Same as Hwi_disable()
   701         *
   702         *  @b(returns)     previous IRQ interrupt enable/disable state
   703         */
   704        @Macro
   705        UInt disableIRQ();
   706    
   707        /*!
   708         *  ======== restoreIRQ ========
   709         *  Restore IRQ interrupts.
   710         *
   711         *  @a(NOTE)
   712         *  Same as Hwi_restore()
   713         *
   714         *  @param(key)     enable/disable state to restore
   715         */
   716        @Macro
   717        Void restoreIRQ(UInt key);
   718    
   719        /*!
   720         *  ======== enableFIQ ========
   721         *  Enable FIQ interrupts.
   722         *
   723         *  @b(returns)     previous FIQ interrupt enable/disable state
   724         */
   725        @Macro
   726        UInt enableFIQ();
   727    
   728        /*!
   729         *  ======== disableFIQ ========
   730         *  Disable FIQ interrupts.
   731         *
   732         *  @b(returns)     previous FIQ interrupt enable/disable state
   733         */
   734        @Macro
   735        UInt disableFIQ();
   736    
   737        /*!
   738         *  ======== restoreFIQ ========
   739         *  Restore FIQ interrupts.
   740         *
   741         *  @param(key)     enable/disable state to restore
   742         */
   743        @Macro
   744        Void restoreFIQ(UInt key);
   745    
   746        /*!
   747         *  @_nodoc
   748         *  ======== disableFxn ========
   749         *  function call implementation
   750         */
   751        UInt disableFxn();
   752    
   753        /*!
   754         *  @_nodoc
   755         *  ======== enableFxn ========
   756         *  function call implementation
   757         */
   758        UInt enableFxn();
   759    
   760        /*!
   761         *  @_nodoc
   762         *  ======== restoreFxn ========
   763         *  function call implementation
   764         */
   765        Void restoreFxn(UInt key);
   766    
   767        /*!
   768         *  ======== getHandle ========
   769         *  Returns Hwi_Handle associated with intNum
   770         *
   771         *  @param(intNum)  interrupt number
   772         */
   773        Handle getHandle(UInt intNum);
   774    
   775        /*!
   776         *  @_nodoc
   777         *  ======== init ========
   778         *  assembly code mode registers setup
   779         */
   780        Void init();
   781    
   782        /*!
   783         *  @_nodoc
   784         *  ======== initIntControllerCoreX ========
   785         */
   786        Void initIntControllerCoreX();
   787    
   788        /*!
   789         *  ======== intAffinity ========
   790         *  SMP Interrupt affinity mappings
   791         *
   792         *  In SMP mode, this array maps an interrupt number to the
   793         *  coreId it is to be tied to. By default, all ints are mapped to
   794         *  core 0.
   795         *
   796         *  For example, to make Timer 1 from the ti.sysbios.timers.dmtimer.Timer
   797         *  module interrupt on core 1 rather than core 0, add the following to
   798         *  your config file:
   799         *
   800         *  @p(code)
   801         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gic.Hwi');
   802         *     Hwi.intAffinity[<intNum>] = 1;
   803         *  @p
   804         *
   805         *  @a(constraints)
   806         *  Interrupt numbers below 32 are ignored. This config param only
   807         *  allows routing interrupt numbers greater than or equal to #32.
   808         */
   809        metaonly config UInt8 intAffinity[];
   810    
   811        /*!
   812         *  @_nodoc
   813         *  ======== raiseSGI ========
   814         */
   815        Void raiseSGI(UInt mask, UInt intNum);
   816    
   817        /*!
   818         *  ======== setPriority ========
   819         *  Set an interrupt's priority.
   820         *
   821         *  Not an instance function so that it can be used
   822         *  with non-dispatched interrupts.
   823         *
   824         *  @param(intNum)      ID of interrupt
   825         *  @param(priority)    priority
   826         */
   827        Void setPriority(UInt intNum, UInt priority);
   828    
   829    instance:
   830    
   831        /*!
   832         *  ======== type ========
   833         *  Interrupt type (IRQ/FIQ). Default is IRQ.
   834         *
   835         *  @a(NOTE)
   836         *  FIQs are only supported when {@link #enableSecureMode} is set to
   837         *  true.
   838         */
   839        config Type type = Type_IRQ;
   840    
   841        /*!
   842         *  ======== triggerSensitivity ========
   843         *  Set an interrupt's trigger sensitivity
   844         *
   845         *  2-bit field that configures the trigger sensitivity of an
   846         *  interrupt.
   847         *
   848         *  On the Cortex-A15, all software generated interrupts (SGI)
   849         *  are edge-triggered (b10) and all private peripheral interrupts (PPI)
   850         *  are level-sensitive (b01). The trigger sensitivity of these
   851         *  interrupt types cannot be changed.
   852         *
   853         *  For shared peripheral interrupts (SPI), the LSB of the bit-pair
   854         *  is read only and is always 1. The MSB of the bit-pair can be
   855         *  altered to change trigger sensitivity.
   856         *
   857         *  Possible bit-pair encodings for Cortex-A15 SPIs:
   858         *      b01    Interrupt is active-High level-sensitive (default)
   859         *      b11    Interrupt is rising edge-sensitive
   860         *
   861         *  For more information please refer section 4.3.13 on
   862         *  Interrupt Configuration Registers (GICD_ICFGRn) in
   863         *  ARM Generic Interrupt Controller Architecure Spec v2.0
   864         */
   865        config UInt triggerSensitivity = ~(0);
   866    
   867        /*!
   868         *  ======== targetProcList ========
   869         *  Set an interrupt's target processor list.
   870         *
   871         *  This is an 8-bit CPU targets field that stores the list of target
   872         *  processors for the interrupt. That is, it holds the list of CPU
   873         *  interfaces to which the GIC Distributor will forward the interrupt
   874         *  if it is asserted and has sufficient priority.
   875         *
   876         *  Each bit in targetProcList refers to the corresponding processor.
   877         *  For instance, a value of 0x3 means the pending interrupt is
   878         *  forwarded to processor 0 and 1.
   879         *
   880         *  For more information please refer section 4.3.12 on
   881         *  Interrupt Processor Targets Registers (GICD_ITARGETSRn) in
   882         *  ARM Generic Interrupt Controller Architecure Spec v2.0
   883         *
   884         *  If running in {@link ti.sysbios.BIOS#smpEnabled SMP mode}
   885         *  and both the targetProcList Hwi param as well as the
   886         *  {@link #intAffinity}[] array entry for the intNum are set,
   887         *  targetProcList is given precedence and is used to configure
   888         *  the interrupt's target processors.
   889         *
   890         *  @a(NOTE)
   891         *  Target processor list is read-only for the first 32 interrupts.
   892         *  Therefore, this field will have no effect for interrupt numbers
   893         *  less than 32 (intNum 0-31).
   894         */
   895        config UInt targetProcList = 0x0;
   896    
   897        /*!
   898         *  ======== Interrupt priority ========
   899         *  Hwi instance interrupt priority.
   900         *
   901         *  Valid priorities are device dependent and their
   902         *  nesting behaviors depend on the {@link #BPR} setting.
   903         *
   904         *  See the ARM GIC Architecture Specification v2.0 document for more
   905         *  details.
   906         */
   907        override config Int priority = -1;
   908    
   909        /*! The interrupt controller is designed for priority based interrupts */
   910        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
   911    
   912        /*!
   913         *  ======== reconfig ========
   914         *  Reconfigure a dispatched interrupt.
   915         */
   916        Void reconfig(FuncPtr fxn, const Params *params);
   917    
   918    internal:   /* not for client use */
   919    
   920        /*!
   921         *  ======== inUseMeta ========
   922         *  @_nodoc
   923         *  Check for Hwi already in use.
   924         *  For internal SYS/BIOS use only.
   925         *  Should be called prior to any internal Hwi.create().
   926         *
   927         *  @param(intNum)  interrupt number
   928         */
   929        metaonly Bool inUseMeta(UInt intNum);
   930    
   931        /*
   932         * Swi and Task module function pointers.
   933         * Used to decouple Hwi from Swi and Task when
   934         * dispatcherSwiSupport or
   935         * dispatcherTaskSupport is false.
   936         */
   937        config UInt (*swiDisable)();
   938        config Void (*swiRestoreHwi)(UInt);
   939        config UInt (*taskDisable)();
   940        config Void (*taskRestoreHwi)(UInt);
   941    
   942        /*
   943         *  ======== postInit ========
   944         *  finish initializing static and dynamic Hwis
   945         */
   946        Int postInit(Object *hwi, Error.Block *eb);
   947    
   948        /*
   949         *  ======== initIntControllerCore0 ========
   950         */
   951        Void initIntControllerCore0();
   952    
   953        /* setup FIQ stack pointer */
   954        Void initFIQStack(Ptr fiqStack);
   955    
   956        /* default FIQ Interrupt Dispatcher */
   957        Void dispatchFIQC();
   958    
   959        /* Interrupt Dispatcher assembly code wrapper */
   960        Void dispatchIRQ();
   961    
   962        /* Interrupt Dispatcher C code */
   963        Void dispatchIRQC(Irp irp);
   964    
   965        /* non plugged interrupt handler */
   966        Void nonPluggedHwiHandler(UArg arg);
   967    
   968        /*!
   969         *  const array to hold all HookSet objects.
   970         */
   971        config HookSet hooks[length] = [];
   972    
   973        /*! Meta World Only Hwi Configuration Object. */
   974        metaonly struct InterruptObj {
   975            Bool used;              /* Interrupt already defined? */
   976            FuncPtr fxn;            /* Dispatched ISR function */
   977        };
   978    
   979        /*!
   980         * Meta-only array of interrupt objects.
   981         * This meta-only array of Hwi config objects is initialized
   982         * in Hwi.xs:module$meta$init().
   983         */
   984        metaonly config InterruptObj interrupt[];
   985    
   986        /*!
   987         * GIC Distributor base address
   988         */
   989        metaonly config Ptr gicdBaseAddress;
   990    
   991        /*!
   992         * GIC cpu interface base address
   993         */
   994        metaonly config Ptr giccBaseAddress;
   995    
   996        struct Instance_State {
   997            Type        type;             // Interrupt Type
   998            UInt        priority;         // Interrupt Priority
   999            UArg        arg;              // Argument to Hwi function.
  1000            FuncPtr     fxn;              // Hwi function.
  1001            Irp         irp;              // current IRP
  1002            Ptr         hookEnv[];
  1003            UInt        triggerSensitivity;
  1004            UInt        targetProcList;
  1005        };
  1006    
  1007        struct Module_State {
  1008            Char         *taskSP[];       // temporary storage of interrupted
  1009                                          // Task's SP during ISR execution
  1010            Char         *isrStack[];     // Points to isrStack address
  1011            Char          hwiStack[][];   // IRQ stack for each core
  1012            Ptr           isrStackSize;   // = Program.stack
  1013                                          // !!! The above three fields MUST be kept
  1014                                          // !!! at the base of the module state
  1015                                          // !!! GNU switchAndRunFunc and
  1016                                          // !!! SMP Core module assumes it
  1017            UInt32        iser[32];       // Initial Interrupt Set Enable Reg values
  1018            UInt32        icfgr[];        // Initial Trigger sensitivity values
  1019            UInt32        itargetsr[];    // Initial interrupt target processors
  1020            UInt          spuriousInts;   // Count of spurious interrupts
  1021            UInt          lastSpuriousInt;// Most recent spurious interrupt
  1022            UInt          irp;            // temporary irp storage for IRQ handler
  1023            Ptr           isrStackBase;   // = __TI_STACK_BASE
  1024            Hwi.Object    nonPluggedHwi;  // default Hwi object
  1025            Handle        dispatchTable[];// dispatch table
  1026            volatile UInt curIntId;       // current Interrupt Id
  1027            UInt32        igroupr[];      // Initial Interrupt Group (0/1)
  1028            Char          fiqStack[][];   // buffers used for FIQ stacks
  1029            SizeT         fiqStackSize;   // FIQ stack size
  1030            UInt8         intAffinity[];  // smp int-to-coreId mappings
  1031        };
  1032    }