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