1    /*
     2     * Copyright (c) 2016-2018, 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.gicv3;
    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    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   147    @InstanceInitStatic     /* allow constructs in static only systems */
   148    @CustomHeader
   149    
   150    module Hwi inherits ti.sysbios.interfaces.IHwi
   151    {
   152        // -------- Module Constants --------
   153    
   154        /*!
   155         *  Number of interrupts implemented in GIC
   156         */
   157        const UInt NUM_INTERRUPTS = 992;
   158    
   159        /*!
   160         *  ======== enableSecureMode ========
   161         *  Security Mode
   162         *
   163         *  This field specifies the MPU's security mode. The MPU's security mode
   164         *  determines the type of accesses to the GIC i.e. if the MPU is in secure
   165         *  mode, all accesses to the GIC are secure and if the MPU is in non-secure
   166         *  mode, all accesses to the GIC are non-secure.
   167         *
   168         *  An exception to the above rule can be seen on certain devices like
   169         *  Keystone 2, where all GIC acceses are secure irrespective of the MPU's
   170         *  security state. {@link #enableSecureMode} should be set to true for such
   171         *  devices.
   172         */
   173        config Bool enableSecureMode = false;
   174    
   175        /*!
   176         *  Number of Priority bits implemented.
   177         *
   178         *  On OMAP543x running in non-secure mode, only most significant 4
   179         *  priority bits are available for use. The least significant 4 bits
   180         *  are always 0.
   181         */
   182        config UInt NUM_PRIORITY_BITS;
   183    
   184        /*!
   185         *  Minimum Interrupt Priority.
   186         */
   187        config UInt MIN_INT_PRIORITY;
   188    
   189        /*!
   190         *  Default Interrupt Priority.
   191         *
   192         *  Set to one level higher than minimum supported priority.
   193         */
   194        config UInt DEFAULT_INT_PRIORITY;
   195    
   196        /*!
   197         *  ======== BPR ========
   198         *  GIC Binary Point Register value
   199         *
   200         *  Defines the point at which the priority value fields split into
   201         *  two parts, the group priority field and the sub-priority field.
   202         *  When running in SECURE mode, BPR applies to Group 0 interrupts
   203         *  and when running in NON-SECURE mode, BPR applies to Group 1
   204         *  interrupts.
   205         *
   206         *  The group priority field determines interrupt preemption in case
   207         *  of nested interrupts whereas sub-priority field is used to determine
   208         *  priority within a group when multiple interrrupts belonging to the
   209         *  same group are pending.
   210         *
   211         *  Valid BPR values are from 0-7 with the minimum value supported being
   212         *  implementation defined and in the range 0-3.
   213         *
   214         *  @p(code)
   215         *   -------------------------------------------------------
   216         *  | BPR value | Group priority field | Sub-priority field |
   217         *   -------------------------------------------------------
   218         *  |     0     |         [7:1]        |         [0]        |
   219         *  |     1     |         [7:2]        |        [1:0]       |
   220         *  |     2     |         [7:3]        |        [2:0]       |
   221         *  |     3     |         [7:4]        |        [3:0]       |
   222         *  |     4     |         [7:5]        |        [4:0]       |
   223         *  |     5     |         [7:6]        |        [5:0]       |
   224         *  |     6     |          [7]         |        [6:0]       |
   225         *  |     7     |     No preemption    |        [7:0]       |
   226         *   -------------------------------------------------------
   227         *  @p
   228         *
   229         */
   230        config UInt BPR;
   231    
   232        /* Exception types */
   233        enum ExcType {
   234            ExcType_Synchronous,
   235            ExcType_SError
   236        };
   237    
   238        /*!
   239         *  ======== Type ========
   240         *  Interrupt type. IRQ or FIQ
   241         */
   242        enum Type {
   243            Type_IRQ,           /*! IRQ interrupt. */
   244            Type_FIQ            /*! FIQ interrupt. */
   245        };
   246    
   247        /*!
   248         *  ======== RoutingMode ========
   249         *  Routing mode. ANY or NODE
   250         */
   251        enum RoutingMode {
   252            RoutingMode_NODE,   /*! Route interrupt to node specified by
   253                                    affinity fields. */
   254            RoutingMode_ALL     /*! Route interrupt to all nodes. */
   255        };
   256    
   257        /*!
   258         *  ======== IntAffinity ========
   259         *  Interrupt affinity type. Stores the hierarchical address (composed
   260         *  of different affinity levels) that uniquely identifies the core or
   261         *  processing element (PE) an interrupt is routed to.
   262         *
   263         *  The routingMode field determines whether an interrupt is routed to
   264         *  all nodes or a node identified by the affinity fields. This field
   265         *  takes the value Hwi_RoutingMode_ANY and Hwi_RoutingMode_NODE.
   266         *
   267         *  If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is true then,
   268         *  all interrupts are forwarded to core 0 by default.
   269         *  If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is false then,
   270         *  all interrupts are forwarded to all participating nodes.
   271         *
   272         *  @a(constraints)
   273         *  This config param is ignored if
   274         *  {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
   275         *  set to false.
   276         */
   277        struct IntAffinity {
   278            UInt8       aff0;        /*! Affinity level 0 - CoreId within cluster */
   279            UInt8       aff1;        /*! Affinity level 1 - Cluster Id */
   280            RoutingMode routingMode; /*! Routing Mode - ALL or particular NODE */
   281        };
   282    
   283        /*!
   284         *  ======== SgiIntAffinity ========
   285         *  Sgi interrupt affinity type. Stores affinity and routing mode
   286         *  information that is used to determine which cores will the generated
   287         *  SGI be routed to.
   288         *
   289         *  The routingMode field determines whether a generated SGI is routed to
   290         *  all cores except the core generating the SGI (Hwi_RoutingMode_ALL) or
   291         *  to list of target cores identified by the "targetList" and "aff1"
   292         *  fields (Hwi_RoutingMode_NODE).
   293         */
   294        struct SgiIntAffinity {
   295            UInt8       targetList;  /*! Bit map of target cores */
   296            UInt8       aff1;        /*! Identifies the target cluster */
   297            RoutingMode routingMode; /*! Routing Mode - ALL or NODE target list */
   298        };
   299    
   300        // -------- Module Types --------
   301    
   302        /*! Exception hook function type definition. */
   303        typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
   304    
   305        /*!
   306         *  ======== BasicView ========
   307         *  @_nodoc
   308         */
   309        metaonly struct BasicView {
   310            Ptr         halHwiHandle;
   311            String      label;
   312            Int         intNum;
   313            String      absPri;
   314            UInt        relGrpPri;
   315            UInt        relSubPri;
   316            String      fxn;
   317            UArg        arg;
   318        };
   319    
   320        /*!
   321         *  ======== DetailedView ========
   322         *  @_nodoc
   323         */
   324        metaonly struct DetailedView {
   325            Ptr         halHwiHandle;
   326            String      label;
   327            Int         intNum;
   328            String      absPri;
   329            UInt        relGrpPri;
   330            UInt        relSubPri;
   331            String      fxn;
   332            UArg        arg;
   333            Ptr         irp;
   334            String      enabled;
   335            String      pending;
   336            String      active;
   337            String      triggerSensitivity;
   338        };
   339    
   340        /*!
   341         *  ======== ModuleView ========
   342         *  @_nodoc
   343         */
   344        metaonly struct ModuleView {
   345            String      options[4];
   346            UInt        spuriousInterrupts;
   347            UInt        lastSpuriousInterrupt;
   348            String      hwiStackPeak;
   349            SizeT       hwiStackSize;
   350            Ptr         hwiStackBase;
   351        };
   352    
   353        /*!
   354         *  ======== rovViewInfo ========
   355         *  @_nodoc
   356         */
   357        @Facet
   358        metaonly config ViewInfo.Instance rovViewInfo =
   359            ViewInfo.create({
   360                viewMap: [
   361                    [
   362                        'Basic',
   363                        {
   364                            type: ViewInfo.INSTANCE,
   365                            viewInitFxn: 'viewInitBasic',
   366                            structName: 'BasicView'
   367                        }
   368                    ],
   369                    [
   370                        'Detailed',
   371                        {
   372                            type: ViewInfo.INSTANCE,
   373                            viewInitFxn: 'viewInitDetailed',
   374                            structName: 'DetailedView'
   375                        }
   376                    ],
   377                    [
   378                        'Module',
   379                        {
   380                            type: ViewInfo.MODULE,
   381                            viewInitFxn: 'viewInitModule',
   382                            structName: 'ModuleView'
   383                        }
   384                    ]
   385                ]
   386            });
   387    
   388        /*!
   389         *  Exception Context - Register contents at the time of an exception.
   390         */
   391        struct ExcContext {
   392            /* Thread Context */
   393            BIOS.ThreadType threadType; /* Type of thread executing at */
   394                                        /* the time the exception occurred */
   395            Ptr     threadHandle;       /* Handle to thread executing at */
   396                                        /* the time the exception occurred */
   397            Ptr     threadStack;        /* Address of stack contents of thread */
   398                                        /* executing at the time the exception */
   399                                        /* occurred */
   400            SizeT   threadStackSize;    /* size of thread stack */
   401            ExcType type;               /* Synchronous or SError */
   402    
   403            /* Internal Registers */
   404            Ptr     x0;
   405            Ptr     x1;
   406            Ptr     x2;
   407            Ptr     x3;
   408            Ptr     x4;
   409            Ptr     x5;
   410            Ptr     x6;
   411            Ptr     x7;
   412            Ptr     x8;
   413            Ptr     x9;
   414            Ptr     x10;
   415            Ptr     x11;
   416            Ptr     x12;
   417            Ptr     x13;
   418            Ptr     x14;
   419            Ptr     x15;
   420            Ptr     x16;
   421            Ptr     x17;
   422            Ptr     x18;
   423            Ptr     x19;
   424            Ptr     x20;
   425            Ptr     x21;
   426            Ptr     x22;
   427            Ptr     x23;
   428            Ptr     x24;
   429            Ptr     x25;
   430            Ptr     x26;
   431            Ptr     x27;
   432            Ptr     x28;
   433            Ptr     x29;
   434            Ptr     x30;
   435            Ptr     sp;                 /* sp_EL0 or sp_EL1 */
   436            Ptr     elr;                /* elr_EL1 */
   437            Ptr     spsr;               /* spsr_EL1 */
   438    
   439            /* Fault registers */
   440            Ptr     esr;                /* esr_EL1 */
   441        }
   442    
   443        /*!
   444         * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
   445         * a physical device
   446         */
   447        struct Gicd {
   448            UInt32 CTLR;            /*! 0x0000 Distributor Control Register */
   449            UInt32 TYPER;           /*! 0x0004 Interrupt Controller Type Register */
   450            UInt32 IIDR;            /*! 0x0008 Distributor Implementor Id Register */
   451            UInt32 hole0[13];       /*! 0x000C-0x03C */
   452            UInt32 SETSPI_NSR;      /*! 0x0040 Set SPI Register */
   453            UInt32 hole1;           /*! 0x0044 */
   454            UInt32 CLRSPI_NSR;      /*! 0x0048 Clear SPI Register */
   455            UInt32 hole2;           /*! 0x004C */
   456            UInt32 SETSPI_SR;       /*! 0x0050 Set SPI Register */
   457            UInt32 hole3;           /*! 0x0054 */
   458            UInt32 CLRSPI_SR;       /*! 0x0058 Clear SPI Register */
   459            UInt32 hole4[9];        /*! 0x005C-0x007C */
   460            UInt32 IGROUPR[32];     /*! 0x0080 Interrupt Group Registers */
   461            UInt32 ISENABLER[32];   /*! 0x0100 Interrupt Set-Enable Registers */
   462            UInt32 ICENABLER[32];   /*! 0x0180 Interrupt Clear-Enable Registers */
   463            UInt32 ISPENDR[32];     /*! 0x0200 Interrupt Set-Pending Registers */
   464            UInt32 ICPENDR[32];     /*! 0x0280 Interrupt Clear-Pending Registers */
   465            UInt32 ISACTIVER[32];   /*! 0x0300 Interrupt Set-Active Registers */
   466            UInt32 ICACTIVER[32];   /*! 0x0380 Interrupt Clear-Active Registers */
   467            UInt8  IPRIORITYR[992]; /*! 0x0400 Interrupt Priority Registers */
   468            UInt32 hole5[8];        /*! 0x07E0-0x07FC */
   469            UInt32 ITARGETSR[8];    /*! 0x0800 Interrupt Processor Targets
   470                                               Register */
   471            UInt32 hole6[248];      /*! 0x0820-0x0BFC */
   472            UInt32 ICFGR[64];       /*! 0x0C00 Interrupt Configuration Registers */
   473            UInt32 IGRPMODR[32];    /*! 0x0D00 Interrupt Group Modifier Registers */
   474            UInt32 hole7[32];       /*! 0x0D80-0x0DFC */
   475            UInt32 NSACR[64];       /*! 0x0E00 NonSecure Access Control Registers */
   476            UInt32 SGIR;            /*! 0x0F00 Software Generated Interrupt
   477                                               Register */
   478            UInt32 hole8[3];        /*! 0x0F04-0x0F0C */
   479            UInt32 CPENDSGIR[4];    /*! 0x0F10 SGI Clear-Pending Registers */
   480            UInt32 SPENDSGIR[4];    /*! 0x0F20 SGI Set-Pending Registers */
   481            UInt32 hole9[5172];     /*! 0x0F30-0x5FFC */
   482            UInt64 IROUTER[992];    /*! 0x6000 Interrupt Routing Registers */
   483            UInt32 hole10[4160];    /*! 0x7F00-0xBFFC */
   484            UInt32 ESTATUSR;        /*! 0xC000 Extended Status Register */
   485            UInt32 ERRTESTR;        /*! 0xC004 Error Test Register */
   486            UInt32 hole11[31];      /*! 0xC008-0xC080 */
   487            UInt32 SPISR[30];       /*! 0xC084 SPI Status Registers */
   488            UInt32 hole12[4021];    /*! 0xC0FC-0xFFCC */
   489            UInt32 PIDR4;           /*! 0xFFD0 Peripheral ID4 Register */
   490            UInt32 PIDR5;           /*! 0xFFD4 Peripheral ID5 Register */
   491            UInt32 PIDR6;           /*! 0xFFD8 Peripheral ID6 Register */
   492            UInt32 PIDR7;           /*! 0xFFDC Peripheral ID7 Register */
   493            UInt32 PIDR0;           /*! 0xFFE0 Peripheral ID0 Register */
   494            UInt32 PIDR1;           /*! 0xFFE4 Peripheral ID1 Register */
   495            UInt32 PIDR2;           /*! 0xFFE8 Peripheral ID2 Register */
   496            UInt32 PIDR3;           /*! 0xFFEC Peripheral ID3 Register */
   497            UInt32 CIDR0;           /*! 0xFFF0 Component  ID0 Register */
   498            UInt32 CIDR1;           /*! 0xFFF4 Component  ID1 Register */
   499            UInt32 CIDR2;           /*! 0xFFF8 Component  ID2 Register */
   500            UInt32 CIDR3;           /*! 0xFFFC Component  ID3 Register */
   501        };
   502    
   503        extern volatile Gicd gicd;
   504    
   505        /*!
   506         * Generic Interrupt Controller Redistributor Interface (RD_base).
   507         * Symbol "Hwi_gicr" is a physical device.
   508         */
   509        struct Gicr {
   510            UInt32 CTLR;            /*! 0x0000 Redistributor Control Register */
   511            UInt32 IIDR;            /*! 0x0004 Implementor Id Register */
   512            UInt32 TYPER[2];        /*! 0x0008 Redistributor Type Register */
   513            UInt32 hole0;           /*! 0x0010 */
   514            UInt32 WAKER;           /*! 0x0014 Power Management Control Register */
   515            UInt32 hole1[22];       /*! 0x0018-0x006C */
   516            UInt32 PROPBASER[2];    /*! 0x0070 LPI Config Table Base Register */
   517            UInt32 PENDBASER[2];    /*! 0x0078 LPI Pending Table Base Register */
   518        };
   519    
   520        /*!
   521         * Generic Interrupt Controller Redistributor Interface (SGI_base).
   522         * Symbol "Hwi_gics" is a physical device.
   523         */
   524        struct Gics {
   525            UInt32 hole0[32];       /*! 0x0000-0x007C */
   526            UInt32 IGROUPR0;        /*! 0x0080 Interrupt Group Register */
   527            UInt32 hole1[31];       /*! 0x0084-0x00FC */
   528            UInt32 ISENABLER0;      /*! 0x0100 Interrupt Set-Enable Register */
   529            UInt32 hole2[31];       /*! 0x0104-0x017C */
   530            UInt32 ICENABLER0;      /*! 0x0180 Interrupt Set-Enable Register */
   531            UInt32 hole3[31];       /*! 0x0184-0x01FC */
   532            UInt32 ISPENDR0;        /*! 0x0200 Interrupt Set-Enable Register */
   533            UInt32 hole4[31];       /*! 0x0204-0x027C */
   534            UInt32 ICPENDR0;        /*! 0x0280 Interrupt Set-Enable Register */
   535            UInt32 hole5[31];       /*! 0x0284-0x02FC */
   536            UInt32 ISACTIVER0;      /*! 0x0300 Interrupt Set-Enable Register */
   537            UInt32 hole6[31];       /*! 0x0304-0x037C */
   538            UInt32 ICACTIVER0;      /*! 0x0380 Interrupt Set-Enable Register */
   539            UInt32 hole7[31];       /*! 0x0384-0x03FC */
   540            UInt8  IPRIORITYR[32];  /*! 0x0400 Interrupt Priority Registers */
   541            UInt32 hole8[504];      /*! 0x0420-0x0BFC */
   542            UInt32 ICFGR[2];        /*! 0x0C00 Interrupt Configuration Registers */
   543            UInt32 hole9[62];       /*! 0x0C08-0x0CFC */
   544            UInt32 IGRPMODR0;       /*! 0x0D00 Interrupt Group Modifier Register */
   545            UInt32 hole10[63];      /*! 0x0D04-0x0DFC */
   546            UInt32 NSACR;           /*! 0x0E00 NonSecure Access Control Register */
   547        };
   548    
   549        /*!
   550         * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
   551         * a physical device.
   552         */
   553        struct Gicc {
   554            UInt32 CTLR;            /*! 0x0000 CPU Interface Control Register */
   555            UInt32 PMR;             /*! 0x0004 Interrupt Priority Mask Register */
   556            UInt32 BPR;             /*! 0x0008 Binary Point Register */
   557            UInt32 IAR;             /*! 0x000C Interrupt Acknowledge Register */
   558            UInt32 EOIR;            /*! 0x0010 End Of Interrupt Register */
   559            UInt32 RPR;             /*! 0x0014 Running Priority Register */
   560            UInt32 HPPIR;           /*! 0x0018 Highest Priority Pending Interrupt
   561                                        Register */
   562            UInt32 ABPR;            /*! 0x001C Aliased Binary Point Register */
   563            UInt32 AIAR;            /*! 0x0020 Aliased IAR Register */
   564            UInt32 AEOIR;           /*! 0x0024 Aliased EOI Register */
   565            UInt32 AHPPIR;          /*! 0x0028 Aliased HPPI Register */
   566            UInt32 hole0[41];       /*! 0x002C-0x00CC */
   567            UInt32 APR0;            /*! 0x00D0 Active Priority Register */
   568            UInt32 hole1[3];        /*! 0x00D4-0x00DC */
   569            UInt32 NSAPR0;          /*! 0x00E0 Non-secure Active Priority Register */
   570            UInt32 hole2[6];        /*! 0x00E4-0x00F8 */
   571            UInt32 IIDR;            /*! 0x00FC CPU Interface Id Register */
   572            UInt32 hole3[960];      /*! 0x0100-0x0FFC */
   573            UInt32 DIR;             /*! 0x1000 Deactivate Interrupt Register */
   574        };
   575    
   576        // -------- Module Parameters --------
   577    
   578        /*!
   579         *  Enable full exception decoding, default is true.
   580         *
   581         *  When enabled, the exception handler will fully
   582         *  decode an exception and dump the registers to the
   583         *  system console.
   584         *
   585         *  When set to false, only an Error is printed on the console.
   586         *
   587         *  In either case, the full exception context is always
   588         *  saved and visible with ROV.
   589         */
   590        config Bool enableDecode = true;
   591    
   592        /*!
   593         *  User Exception Context Buffer Address
   594         *
   595         *  By default, when an exception occurs, an {@link #ExcContext}
   596         *  structure is allocated on the ISR stack and filled in within the
   597         *  exception handler.
   598         *
   599         *  If {@link #excContextBuffer} is initialized by the user, the
   600         *  {@link #ExcContext} structure will be placed at that address instead.
   601         *
   602         *  The buffer must be large enough to contain an {@link #ExcContext}
   603         *  structure.
   604         */
   605        metaonly config Ptr excContextBuffer[];
   606    
   607        /*!
   608         *  User Synchronous Exception hook function.
   609         *
   610         *  Called just after the exception context has been initialized.
   611         *
   612         *  This function will be run on the ISR stack.
   613         *
   614         *  This function must run to completion.
   615         *
   616         *  It is called without any Task or Swi scheduling protection
   617         *  and therefore can not call any functions that may cause a Swi or Task
   618         *  scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
   619         */
   620        config ExceptionHookFuncPtr syncExcHookFunc[];
   621    
   622        /*!
   623         *  User SError Exception hook function.
   624         *
   625         *  Called just after the exception context has been initialized.
   626         *
   627         *  This function will be run on the ISR stack.
   628         *
   629         *  This function must run to completion.
   630         *
   631         *  It is called without any Task or Swi scheduling protection
   632         *  and therefore can not call any functions that may cause a Swi or Task
   633         *  scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
   634         */
   635        config ExceptionHookFuncPtr sErrorExcHookFunc[];
   636    
   637        /*!
   638         *  @_nodoc
   639         *  ======== irqStackSection ========
   640         *  Memory section used for IRQ stack on each core
   641         *  Default is null.
   642         */
   643        metaonly config String irqStackSection = null;
   644    
   645        /*!
   646         *  ======== A_badSGIIntNum ========
   647         *  Assert raised when an interrupt number >= 16 is
   648         *  passed to Hwi_raiseSGI() function.
   649         */
   650        config xdc.runtime.Assert.Id A_badSGIIntNum  = {
   651            msg: "A_badSGIIntNum: SGI intNum should be <= 15."
   652        };
   653    
   654        /*!
   655         *  Error raised when an attempt is made to create a Hwi
   656         *  that has already been created.
   657         */
   658        config Error.Id E_alreadyDefined = {
   659            msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
   660        };
   661    
   662        /*!
   663         *  Error raised when Hwi handle referenced in Hwi_delete()
   664         *  is not found in the Hwi dispatch table
   665         */
   666        config Error.Id E_handleNotFound = {
   667            msg: "E_handleNotFound: Hwi handle not found: 0x%x"
   668        };
   669    
   670        /*!
   671         *  Error raised when an undefined interrupt has fired.
   672         */
   673        config Error.Id E_undefined = {
   674            msg: "E_undefined: Hwi undefined, intnum: %d"
   675        };
   676    
   677        /*!
   678         *  Error raised if an attempt is made to create a Hwi
   679         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   680         */
   681        config Error.Id E_badIntNum = {
   682            msg: "E_badIntNum, intnum: %d is out of range"
   683        };
   684    
   685        /*!
   686         *  Error raised when an exception occurs.
   687         */
   688        config Error.Id E_exception = {
   689            msg: "E_exception: A hardware exception has occurred."
   690        };
   691    
   692        /*!
   693         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   694         */
   695        config Log.Event LM_begin = {
   696            mask: Diags.USER1 | Diags.USER2,
   697            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   698        };
   699    
   700        /*!
   701         *  Issued just after return from Hwi function (with interrupts disabled)
   702         */
   703        config Log.Event LD_end = {
   704            mask: Diags.USER2,
   705            msg: "LD_end: hwi: 0x%x"
   706        };
   707    
   708    
   709        // -------- Module Functions --------
   710    
   711        /*!
   712         *  ======== disable ========
   713         *  Globally disable interrupts.
   714         *
   715         *  Hwi_disable globally disables hardware interrupts and returns an
   716         *  opaque key indicating whether interrupts were globally enabled or
   717         *  disabled on entry to Hwi_disable().
   718         *  The actual value of the key is target/device specific and is meant
   719         *  to be passed to Hwi_restore().
   720         *
   721         *  Call Hwi_disable before a portion of a function that needs
   722         *  to run without interruption. When critical processing is complete, call
   723         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   724         *
   725         *  Servicing of interrupts that occur while interrupts are disabled is
   726         *  postponed until interrupts are reenabled. However, if the same type
   727         *  of interrupt occurs several times while interrupts are disabled,
   728         *  the interrupt's function is executed only once when interrupts are
   729         *  reenabled.
   730         *
   731         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   732         *  an enabled interrupt occurred while interrupts are disabled.
   733         *
   734         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   735         *  are already disabled in main(), such a call has no effect.
   736         *
   737         *  @a(NOTE)
   738         *  Disables only IRQ interrupts
   739         *
   740         *  @a(constraints)
   741         *  If a Task switching API such as
   742         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
   743         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   744         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   745         *  {@link ti.sysbios.knl.Task#yield Task_yield()}
   746         *  is invoked which results in a context switch while
   747         *  interrupts are disabled, an embedded call to
   748         *  {@link #enable Hwi_enable} occurs
   749         *  on the way to the new thread context which unconditionally re-enables
   750         *  interrupts. Interrupts will remain enabled until a subsequent
   751         *  {@link #disable Hwi_disable}
   752         *  invocation.
   753         *
   754         *  Swis always run with interrupts enabled.
   755         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   756         *  interrupts.
   757         *
   758         *  @b(returns)     opaque key for use by Hwi_restore()
   759         */
   760        @Macro
   761        override UInt disable();
   762    
   763        /*!
   764         *  ======== enable ========
   765         *
   766         *  @a(NOTE)
   767         *  Enables only IRQ interrupts
   768         */
   769        @Macro
   770        override UInt enable();
   771    
   772        /*!
   773         *  ======== restore ========
   774         *
   775         *  @a(NOTE)
   776         *  Restores only IRQ interrupts
   777         */
   778        @Macro
   779        override Void restore(UInt key);
   780    
   781        /*!
   782         *  ======== enableIRQ ========
   783         *  Enable IRQ interrupts.
   784         *
   785         *  @a(NOTE)
   786         *  Same as Hwi_enable()
   787         *
   788         *  @b(returns)     previous IRQ interrupt enable/disable state
   789         */
   790        @Macro
   791        UInt enableIRQ();
   792    
   793        /*!
   794         *  ======== disableIRQ ========
   795         *  Disable IRQ interrupts.
   796         *
   797         *  @a(NOTE)
   798         *  Same as Hwi_disable()
   799         *
   800         *  @b(returns)     previous IRQ interrupt enable/disable state
   801         */
   802        @Macro
   803        UInt disableIRQ();
   804    
   805        /*!
   806         *  ======== restoreIRQ ========
   807         *  Restore IRQ interrupts.
   808         *
   809         *  @a(NOTE)
   810         *  Same as Hwi_restore()
   811         *
   812         *  @param(key)     enable/disable state to restore
   813         */
   814        @Macro
   815        Void restoreIRQ(UInt key);
   816    
   817        /*!
   818         *  @_nodoc
   819         *  ======== disableFxn ========
   820         *  function call implementation
   821         */
   822        UInt disableFxn();
   823    
   824        /*!
   825         *  @_nodoc
   826         *  ======== enableFxn ========
   827         *  function call implementation
   828         */
   829        UInt enableFxn();
   830    
   831        /*!
   832         *  @_nodoc
   833         *  ======== restoreFxn ========
   834         *  function call implementation
   835         */
   836        Void restoreFxn(UInt key);
   837    
   838        /*!
   839         *  ======== getHandle ========
   840         *  Returns Hwi_Handle associated with intNum
   841         *
   842         *  @param(intNum)  interrupt number
   843         */
   844        Handle getHandle(UInt intNum);
   845    
   846        /*!
   847         *  @_nodoc
   848         *  ======== init ========
   849         *  assembly code mode registers setup
   850         */
   851        Void init();
   852    
   853        /*!
   854         *  @_nodoc
   855         *  ======== initIntControllerCoreX ========
   856         */
   857        Void initIntControllerCoreX();
   858    
   859        /*!
   860         *  ======== intAffinity ========
   861         *  SMP Interrupt affinity mappings
   862         *
   863         *  In SMP mode, this array maps the interrupt number to the
   864         *  core it is to be tied to. By default, all interrupts
   865         *  are routed to Core0.
   866         *
   867         *  For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
   868         *  module interrupt to core 1 rather than core 0, add the following to
   869         *  your config file:
   870         *
   871         *  @p(code)
   872         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
   873         *     Hwi.intAffinity[<intNum>] = 1;
   874         *  @p
   875         *
   876         *  @a(constraints)
   877         *  Interrupt numbers below 32 are ignored. This config param only
   878         *  allows routing interrupt numbers greater than or equal to #32.
   879         */
   880        metaonly config UInt8 intAffinity[];
   881    
   882        /*!
   883         *  ======== intRouting ========
   884         *  SMP Interrupt routing mappings
   885         *
   886         *  In SMP mode, this array maps the interrupt number to the
   887         *  core or cores it is to be tied to. By default, all interrupts
   888         *  are routed to Core0.
   889         *
   890         *  For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
   891         *  module interrupt to core 1 rather than core 0, add the following to
   892         *  your config file:
   893         *
   894         *  @p(code)
   895         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
   896         *     Hwi.intRouting[<intNum>] = {aff0: 1, aff1: 0,
   897                                            routingMode: Hwi.RoutingMode_NODE};
   898         *  @p
   899         *
   900         *  @a(constraints)
   901         *  Interrupt numbers below 32 are ignored. This config param only
   902         *  allows routing interrupt numbers greater than or equal to #32.
   903         */
   904        metaonly config IntAffinity intRouting[];
   905    
   906        /*!
   907         *  @_nodoc
   908         *  ======== raiseSGI ========
   909         *  Generate an SGI interrupt and route it to CPUs specified by the
   910         *  affinity field.
   911         *
   912         *  @param(affinity)    If the "routingMode" field is set to
   913         *                      Hwi_RoutingMode_ANY, then the interrupt is routed to
   914         *                      all cores except this core. Else, if "routingMode"
   915         *                      is set to Hwi_RoutingMode_NODE, the affinity fields
   916         *                      are used to determine which cores the interrupt
   917         *                      should be routed to. "aff0" field is a bit mapped
   918         *                      target list identifying all cores within the cluster
   919         *                      identified by "aff1".
   920         *  @param(intNum)      Interrupt number
   921         */
   922        Void raiseSGI(SgiIntAffinity affinity, UInt intNum);
   923    
   924        /*!
   925         *  ======== setPriority ========
   926         *  Set an interrupt's priority.
   927         *
   928         *  Not an instance function so that it can be used
   929         *  with non-dispatched interrupts.
   930         *
   931         *  @param(intNum)      ID of interrupt
   932         *  @param(priority)    priority
   933         */
   934        Void setPriority(UInt intNum, UInt priority);
   935    
   936    instance:
   937    
   938        /*!
   939         *  ======== type ========
   940         *  Interrupt type (IRQ/FIQ). Default is IRQ.
   941         *
   942         *  @a(NOTE)
   943         *  FIQs are only supported when {@link #enableSecureMode} is set to
   944         *  true.
   945         */
   946        config Type type = Type_IRQ;
   947    
   948        /*!
   949         *  ======== triggerSensitivity ========
   950         *  Set an interrupt's trigger sensitivity
   951         *
   952         *  2-bit field that configures the trigger sensitivity of an
   953         *  interrupt.
   954         *
   955         *  On the Cortex-A15, all software generated interrupts (SGI)
   956         *  are edge-triggered (b10) and all private peripheral interrupts (PPI)
   957         *  are level-sensitive (b01). The trigger sensitivity of these
   958         *  interrupt types cannot be changed.
   959         *
   960         *  For shared peripheral interrupts (SPI), the LSB of the bit-pair
   961         *  is read only and is always 1. The MSB of the bit-pair can be
   962         *  altered to change trigger sensitivity.
   963         *
   964         *  Possible bit-pair encodings for Cortex-A15 SPIs:
   965         *      b01    Interrupt is active-High level-sensitive (default)
   966         *      b11    Interrupt is rising edge-sensitive
   967         *
   968         *  For more information please refer section 4.3.13 on
   969         *  Interrupt Configuration Registers (GICD_ICFGRn) in
   970         *  ARM Generic Interrupt Controller Architecure Spec v2.0
   971         *
   972         *  @a(constraints)
   973         *  This Hwi param is ignored if
   974         *  {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
   975         *  set to false.
   976         */
   977        config UInt triggerSensitivity = ~(0);
   978    
   979        /*!
   980         *  ======== Interrupt priority ========
   981         *  Hwi instance interrupt priority.
   982         *
   983         *  Valid priorities are device dependent and their
   984         *  nesting behaviors depend on the {@link #BPR} setting.
   985         *
   986         *  See the ARM GIC Architecture Specification v2.0 document for more
   987         *  details.
   988         */
   989        override config Int priority = -1;
   990    
   991        /*! The interrupt controller is designed for priority based interrupts */
   992        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
   993    
   994        /*!
   995         *  ======== reconfig ========
   996         *  Reconfigure a dispatched interrupt.
   997         */
   998        Void reconfig(FuncPtr fxn, const Params *params);
   999    
  1000    internal:   /* not for client use */
  1001    
  1002        struct GicRegisterMap {
  1003            volatile Gicr *gicr;
  1004            volatile Gics *gics;
  1005        };
  1006    
  1007        config GicRegisterMap gicMap[];
  1008    
  1009        /*
  1010         *  Number of GICD Enable registers
  1011         */
  1012        config UInt NUM_GICD_ENABLE_REGS;
  1013    
  1014        config SizeT isrStackSize;
  1015    
  1016        /*
  1017         *  ======== initGicd ========
  1018         *  Flag determines whether to initialize global gic distributor
  1019         *  registers. It is set to false if this core is not the boot master.
  1020         */
  1021        config Bool initGicd = true;
  1022    
  1023        /*
  1024         *  ======== inUseMeta ========
  1025         *  @_nodoc
  1026         *  Check for Hwi already in use.
  1027         *  For internal SYS/BIOS use only.
  1028         *  Should be called prior to any internal Hwi.create().
  1029         *
  1030         *  @param(intNum)  interrupt number
  1031         */
  1032        metaonly Bool inUseMeta(UInt intNum);
  1033    
  1034        /*
  1035         * Swi and Task module function pointers.
  1036         * Used to decouple Hwi from Swi and Task when
  1037         * dispatcherSwiSupport or
  1038         * dispatcherTaskSupport is false.
  1039         */
  1040        config UInt (*swiDisable)();
  1041        config Void (*swiRestoreHwi)(UInt);
  1042        config UInt (*taskDisable)();
  1043        config Void (*taskRestoreHwi)(UInt);
  1044    
  1045        /*
  1046         *  ======== dispatchIRQ ========
  1047         *  Interrupt Dispatcher assembly code wrapper
  1048         */
  1049        Void dispatchIRQ(Bool usingEL0Stack);
  1050    
  1051        /*
  1052         *  ======== dispatchIRQC ========
  1053         *  Interrupt Dispatcher C code
  1054         */
  1055        Void dispatchIRQC(Irp irp, Bool rootISR, Char *taskSP);
  1056    
  1057        /*!
  1058         *  ======== excDumpContext ========
  1059         */
  1060        Void excDumpContext();
  1061    
  1062        /*
  1063         *  ======== excHandler ========
  1064         */
  1065        Void excHandler(UInt64 *excStack, ExcType excType);
  1066    
  1067        /*
  1068         *  ======== initIntController ========
  1069         */
  1070        Void initIntControllerCore0();
  1071    
  1072        /*
  1073         *  ======== initStacks ========
  1074         *  set up split stacks
  1075         */
  1076        Void initStacks(Ptr hwiStack);
  1077    
  1078        /*
  1079         *  ======== nonPluggedHwiHandler ========
  1080         *  Non-plugged interrupt handler
  1081         */
  1082        Void nonPluggedHwiHandler();
  1083    
  1084        /*
  1085         *  ======== postInit ========
  1086         *  finish initializing static and dynamic Hwis
  1087         */
  1088        Int postInit(Object *hwi, Error.Block *eb);
  1089    
  1090        /*!
  1091         *  const array to hold all HookSet objects.
  1092         */
  1093        config HookSet hooks[length] = [];
  1094    
  1095        /*! Meta World Only Hwi Configuration Object. */
  1096        metaonly struct InterruptObj {
  1097            Bool used;              /* Interrupt already defined? */
  1098            FuncPtr fxn;            /* Dispatched ISR function */
  1099        };
  1100    
  1101        /*!
  1102         * Meta-only array of interrupt objects.
  1103         * This meta-only array of Hwi config objects is initialized
  1104         * in Hwi.xs:module$meta$init().
  1105         */
  1106        metaonly config InterruptObj interrupt[];
  1107    
  1108        /*!
  1109         * GIC Distributor base address
  1110         */
  1111        metaonly config Ptr gicdBaseAddress;
  1112    
  1113        /*!
  1114         * GIC Redistributor base address
  1115         */
  1116        metaonly config Ptr gicrBaseAddress;
  1117    
  1118        struct Instance_State {
  1119            Type        type;             /* Interrupt Type */
  1120            UInt        priority;         /* Interrupt Priority */
  1121            UArg        arg;              /* Argument to Hwi function */
  1122            FuncPtr     fxn;              /* Hwi function */
  1123            Irp         irp;              /* current IRP */
  1124            Ptr         hookEnv[];
  1125            UInt        triggerSensitivity;
  1126        };
  1127    
  1128        struct Module_State {
  1129            Char         *isrStack[];     /* Points to isrStack address */
  1130            Char          hwiStack[][];   /* IRQ stack for each core */
  1131            UInt          irp[];          /* temp irp storage for IRQ handler */
  1132            Char         *taskSP[];       /* Interrupted Task's Stack Pointer */
  1133            Ptr           isrStackSize;   /* = Program.stack */
  1134                                          /*
  1135                                           * !!! The above three fields MUST be kept
  1136                                           * !!! at the base of the module state
  1137                                           * !!! GNU switchAndRunFunc and
  1138                                           * !!! SMP Core module assumes it
  1139                                           */
  1140            UInt32        iser[32];       /* Initial Interrupt enable reg values */
  1141            UInt32        icfgr[];        /* Initial Trigger sensitivity values */
  1142            UInt          spuriousInts;   /* Count of spurious interrupts */
  1143            UInt          lastSpuriousInt;/* Most recent spurious interrupt */
  1144            Ptr           isrStackBase;   /* = __TI_STACK_BASE */
  1145            Handle        dispatchTable[];/* dispatch table */
  1146            volatile UInt curIntId;       /* current Interrupt Id */
  1147            IntAffinity   intAffinity[];  /* smp int-to-coreId mappings */
  1148            Bool          excActive[];    /* TRUE if an exception has occurred */
  1149            ExcContext   *excContext[];   /* Exception context */
  1150        };
  1151    }