1    /*
     2     * Copyright (c) 2016-2019, 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     *  When {@link #enableLPI} is set to 'true', this Hwi module supports an
    74     *  additional set of interrupts, numbered starting from 8192, named
    75     *  Locality-specific Peripheral Interrupts or LPIs.  LPIs are driven by the
    76     *  GICv3 Interrupt Translation Service or ITS.  The ITS requires a number of
    77     *  SW-allocated tables, as does each CPU interface block when LPIs are in use.
    78     *  In addition to these LPI-related tables, general tables used by the Hwi
    79     *  dispatcher increase in size by a significant amount due to the much larger
    80     *  interrupt ID space that is available when LPIs are enabled.
    81     *
    82     *  @a(NOTE)
    83     *  In the SoC Technical Reference Manual, the MPU IRQs 0 to N map to
    84     *  GIC interrupt numbers 32 to (N+32) where (N+1) is the total number of
    85     *  Shared Peripheral Interrupts implemented.
    86     *  For instance on OMAP5430, MPU IRQ 0 to 159 maps to GIC interrupt number
    87     *  32 to 191.
    88     *
    89     *  @a(INTERRUPT GROUPING)
    90     *  GIC allows configuring an interrupt as a Group 0 or a Group 1 interrupt.
    91     *  Group 0 interrupts are Secure interrupts and Group 1 interrupts are
    92     *  Non-secure interrupts.
    93     *
    94     *  If {@link #enableSecureMode} is set to true, this module supports both
    95     *  Group0 and Group 1 interrupts. Group 0 interrupts are delivered to the CPU
    96     *  using FIQ signal whereas Group 1 interrupts are delivered using IRQ signal.
    97     *
    98     *  If {@link #enableSecureMode} is set to false, this module only supports
    99     *  Group 1 interrupts which are delivered to the target CPU using IRQ signal.
   100     *
   101     *  @a(INTERRUPT PRIORITIES)
   102     *  In general GIC supports priority values 0 thru 255.
   103     *
   104     *  In practice valid priority values depend on the particular device used,
   105     *  security mode and the Binary Point Register (see {@link #BPR} and
   106     *  {@link #ABPR}) value.
   107     *
   108     *  The device implementation and security mode decide the number of priority
   109     *  bits that are implemented (see {@link #NUM_PRIORITY_BITS}). Group 0
   110     *  interrupts always implement one more priority bit than Group 1 interrupts.
   111     *
   112     *  In GIC, interrupts with lower priority numbers have higher priority.
   113     *
   114     *  @a(NOTE)
   115     *  In this Hwi module implementation, the instance config parameter value
   116     *  {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
   117     *  Statically configuring a Hwi object's {@link #Params.maskSetting} to
   118     *  {@link #MaskingOption_LOWER} will result in the generation of a benign
   119     *  build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
   120     *  silently converted to {@link #MaskingOption_SELF}.
   121     *
   122     *  @a(ZERO LATENCY INTERRUPTS)
   123     *  On Keystone2 devices, this module supports zero-latency interrupts. A
   124     *  zero-latency interrupt does not go through the SYS/BIOS dispatcher and
   125     *  thus has a faster response time. Since zero-latency interrupts bypass the
   126     *  dispatcher, their handler function cannot call any SYS/BIOS APIs.
   127     *
   128     *  This module implements zero-latency interrupts by forwarding the interrupt
   129     *  to the target CPU using FIQ signal. Therefore, in order to configure an
   130     *  interrupt as a zero-latency interrupt, the Hwi type needs to be changed
   131     *  to FIQ when creating or constructing a Hwi.
   132     *
   133     *  Example showing how to create a zero-latency Hwi:
   134     *  @p(code)
   135     *  Void main(Void)
   136     *  {
   137     *      Hwi_Params hwiParams;
   138     *      Hwi_Params_init(&hwiParams);
   139     *      // Default Hwi type is IRQ
   140     *      hwiParams.type = Hwi_Type_FIQ;
   141     *      Hwi_create(INT_NUM_FIQ, myIsrFIQ, &hwiParams, NULL);
   142     *      ...
   143     *  }
   144     *  @p
   145     *
   146     *  FIQs run on their own stack. See {@link #fiqStack} and {@link #fiqStackSize}
   147     *  for more info on how to control the FIQ stack.
   148     *
   149     *  @a(NOTE)
   150     *  This module is written for GIC v2.0, however it is backwards compatible
   151     *  with GIC v1.0
   152     *
   153     *  @a(LPI INTERRUPTS)
   154     *  In order to generate LPI interrupt IDs the ITS needs to be programmed,
   155     *  using the Hwi_its*() APIs.  The Hwi_its*() APIs are C language
   156     *  implementations of the raw ITS commadns.  A typical sequence might be:
   157     *  @p(code)
   158     *      Hwi_itsMapDevice(0, 4, 2);
   159     *      Hwi_itsMapCollection(0, 0);
   160     *      Hwi_itsMapTranslatedInterrupt(0, 0, 0, 0x2000);
   161     *  @p
   162     *  The Hwi_its*() APIs are only available when {@link #enableLPI} = true.
   163     *
   164     *  See ARM GIC Architecture documentation for more details.
   165     */
   166    
   167    @ModuleStartup          /* generates call to Hwi_Module_startup at startup */
   168    @InstanceInitStatic     /* allow constructs in static only systems */
   169    @CustomHeader
   170    
   171    module Hwi inherits ti.sysbios.interfaces.IHwi
   172    {
   173        // -------- Module Constants --------
   174    
   175        /*!
   176         *  Number of interrupts implemented in GIC HW registers.  This is
   177         *  basically the number of SGI/PPI/SPI interrupts.
   178         *  
   179         */
   180        const UInt NUM_HWREG_INTERRUPTS = 992;
   181    
   182        /*!
   183         *  Number of interrupts implemented in GIC in total.  This includes
   184         *  the SGI/PPI/SPI interrupts, plus LPI if {@link #enableLPI} is true.
   185         *
   186         *  NUM_INTERRUPTS increases significantly if {@link #enableLPI} is true.
   187         */
   188        config UInt NUM_INTERRUPTS = NUM_HWREG_INTERRUPTS;
   189    
   190        /*!
   191         *  ======== enableLPI ========
   192         *  Enable LPI message-based interrupts
   193         *
   194         *  This setting enables the use of LPIs with the GIC.  LPIs use the ITS
   195         *  to translate DeviceID/EventID to an INTID in the LPI INTID space
   196         *  (8192 -> (<# supported INTIDs> - 1).
   197         *
   198         *  Enabling LPIs incurs a significant memory cost due to the much larger
   199         *  INTID space and the need for large SW-allocated tables.
   200         *  {@link #NUM_INTERRUPTS} becomes significantly larger when LPIs are
   201         *  enabled.
   202         */
   203        config Bool enableLPI = false;
   204    
   205        /*!
   206         *  Number of 4KB pages to allocate for the ITS command queue
   207         *
   208         *  The ITS command queue is used for performing ITS operations.
   209         */
   210        config Int NUM_ITS_CMD_PAGES = 1;
   211    
   212        /*!
   213         *  Enumeration of possible page sizes for the Device table
   214         */
   215        enum DeviceTablePageSize {
   216            DeviceTablePageSize_4KB,
   217            DeviceTablePageSize_16KB,
   218            DeviceTablePageSize_64KB
   219        };
   220    
   221        /*!
   222         *  Page size for ITS DeviceID table
   223         */
   224        config DeviceTablePageSize DEV_TBL_PAGESIZE = DeviceTablePageSize_4KB;
   225    
   226        /*!
   227         *  Number of pages of size {@link #DEV_TBL_PAGESIZE} for the ITS
   228         *  Device table
   229         */
   230        config Int DEV_TBL_NUMPAGES = 16;
   231    
   232        /*!
   233         *  Linker section to use for ITS/LPI table allocations
   234         */
   235        metaonly config String itsTableSection = ".itsTables";
   236    
   237        /*!
   238         *  Memory segment to use for ITS/LPI table allocations
   239         */
   240        metaonly config String itsTableMemory = "DDR";
   241    
   242        /*!
   243         *  Attributes for all ITS/LPI tables
   244         */
   245        struct ItsTableAttrs {
   246            UInt8 innerCache;
   247            UInt8 outerCache;
   248            UInt8 shareability;
   249        };
   250    
   251        /*!
   252         *  Enumeration of all possible ITS table inner cache settings
   253         */
   254        enum InnerCache {
   255            InnerCache_Device,           /*! Device-nGnRnE */
   256            InnerCache_NonCacheable,     /*! Normal Inner Non-cacheable */
   257            InnerCache_CacheableRAWT,    /*! Normal Inner Cacheable RA, WT */
   258            InnerCache_CacheableRAWB,    /*! Normal Inner Cacheable RA, WB */
   259            InnerCache_CacheableWAWT,    /*! Normal Inner Cacheable WA, WT */
   260            InnerCache_CacheableWAWB,    /*! Normal Inner Cacheable WA, WB */
   261            InnerCache_CacheableRAWAWT,  /*! Normal Inner Cacheable RA, WA, WT */
   262            InnerCache_CacheableRAWAWB   /*! Normal Inner Cacheable RA, WA, WB */
   263        };
   264    
   265        /*!
   266         *  Enumeration of all possible ITS table outer cache settings
   267         */
   268        enum OuterCache {
   269            OuterCache_SameAsInner,      /*! Same setting as InnerCache */
   270            OuterCache_NonCacheable,     /*! Normal Outer Non-cacheable */
   271            OuterCache_CacheableRAWT,    /*! Normal Outer Cacheable RA, WT */
   272            OuterCache_CacheableRAWB,    /*! Normal Outer Cacheable RA, WB */
   273            OuterCache_CacheableWAWT,    /*! Normal Outer Cacheable WA, WT */
   274            OuterCache_CacheableWAWB,    /*! Normal Outer Cacheable WA, WB */
   275            OuterCache_CacheableRAWAWT,  /*! Normal Outer Cacheable RA, WA, WT */
   276            OuterCache_CacheableRAWAWB   /*! Normal Outer Cacheable RA, WA, WB */
   277        };
   278    
   279        /*
   280         *  Enumeration of all possible ITS table shareability settings
   281         *
   282         *  Shareability field might be a fixed, read-only value.
   283         */
   284        enum Shareability {
   285            NonShareable,
   286            InnerShareable,
   287            OuterShareable
   288        };
   289    
   290        /*!
   291         *  Default settings for ITS tables
   292         */
   293        config ItsTableAttrs itsTableAttrs = {
   294            innerCache: InnerCache_CacheableWAWB,
   295            outerCache: OuterCache_SameAsInner,
   296            shareability: NonShareable,
   297        };
   298    
   299        /*!
   300         *  ======== enableSecureMode ========
   301         *  Security Mode
   302         *
   303         *  This field specifies the MPU's security mode. The MPU's security mode
   304         *  determines the type of accesses to the GIC i.e. if the MPU is in secure
   305         *  mode, all accesses to the GIC are secure and if the MPU is in non-secure
   306         *  mode, all accesses to the GIC are non-secure.
   307         *
   308         *  An exception to the above rule can be seen on certain devices like
   309         *  Keystone 2, where all GIC acceses are secure irrespective of the MPU's
   310         *  security state. {@link #enableSecureMode} should be set to true for such
   311         *  devices.
   312         */
   313        config Bool enableSecureMode = false;
   314    
   315        /*!
   316         *  Number of Priority bits implemented.
   317         *
   318         *  On OMAP543x running in non-secure mode, only most significant 4
   319         *  priority bits are available for use. The least significant 4 bits
   320         *  are always 0.
   321         */
   322        config UInt NUM_PRIORITY_BITS;
   323    
   324        /*!
   325         *  Minimum Interrupt Priority.
   326         */
   327        config UInt MIN_INT_PRIORITY;
   328    
   329        /*!
   330         *  Default Interrupt Priority.
   331         *
   332         *  Set to one level higher than minimum supported priority.
   333         */
   334        config UInt DEFAULT_INT_PRIORITY;
   335    
   336        /*!
   337         *  ======== BPR ========
   338         *  GIC Binary Point Register value
   339         *
   340         *  Defines the point at which the priority value fields split into
   341         *  two parts, the group priority field and the sub-priority field.
   342         *  When running in SECURE mode, BPR applies to Group 0 interrupts
   343         *  and when running in NON-SECURE mode, BPR applies to Group 1
   344         *  interrupts.
   345         *
   346         *  The group priority field determines interrupt preemption in case
   347         *  of nested interrupts whereas sub-priority field is used to determine
   348         *  priority within a group when multiple interrrupts belonging to the
   349         *  same group are pending.
   350         *
   351         *  Valid BPR values are from 0-7 with the minimum value supported being
   352         *  implementation defined and in the range 0-3.
   353         *
   354         *  @p(code)
   355         *   -------------------------------------------------------
   356         *  | BPR value | Group priority field | Sub-priority field |
   357         *   -------------------------------------------------------
   358         *  |     0     |         [7:1]        |         [0]        |
   359         *  |     1     |         [7:2]        |        [1:0]       |
   360         *  |     2     |         [7:3]        |        [2:0]       |
   361         *  |     3     |         [7:4]        |        [3:0]       |
   362         *  |     4     |         [7:5]        |        [4:0]       |
   363         *  |     5     |         [7:6]        |        [5:0]       |
   364         *  |     6     |          [7]         |        [6:0]       |
   365         *  |     7     |     No preemption    |        [7:0]       |
   366         *   -------------------------------------------------------
   367         *  @p
   368         *
   369         */
   370        config UInt BPR;
   371    
   372        /* Exception types */
   373        enum ExcType {
   374            ExcType_Synchronous,
   375            ExcType_SError
   376        };
   377    
   378        /*!
   379         *  ======== Type ========
   380         *  Interrupt type. IRQ or FIQ
   381         */
   382        enum Type {
   383            Type_IRQ,           /*! IRQ interrupt. */
   384            Type_FIQ            /*! FIQ interrupt. */
   385        };
   386    
   387        /*!
   388         *  ======== RoutingMode ========
   389         *  Routing mode. ANY or NODE
   390         */
   391        enum RoutingMode {
   392            RoutingMode_NODE,   /*! Route interrupt to node specified by
   393                                    affinity fields. */
   394            RoutingMode_ALL     /*! Route interrupt to all nodes. */
   395        };
   396    
   397        /*!
   398         *  ======== IntAffinity ========
   399         *  Interrupt affinity type. Stores the hierarchical address (composed
   400         *  of different affinity levels) that uniquely identifies the core or
   401         *  processing element (PE) an interrupt is routed to.
   402         *
   403         *  The routingMode field determines whether an interrupt is routed to
   404         *  all nodes or a node identified by the affinity fields. This field
   405         *  takes the value Hwi_RoutingMode_ANY and Hwi_RoutingMode_NODE.
   406         *
   407         *  If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is true then,
   408         *  all interrupts are forwarded to core 0 by default.
   409         *  If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is false then,
   410         *  all interrupts are forwarded to all participating nodes.
   411         *
   412         *  @a(constraints)
   413         *  This config param is ignored if
   414         *  {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
   415         *  set to false.
   416         */
   417        struct IntAffinity {
   418            UInt8       aff0;        /*! Affinity level 0 - CoreId within cluster */
   419            UInt8       aff1;        /*! Affinity level 1 - Cluster Id */
   420            RoutingMode routingMode; /*! Routing Mode - ALL or particular NODE */
   421        };
   422    
   423        /*!
   424         *  ======== SgiIntAffinity ========
   425         *  Sgi interrupt affinity type. Stores affinity and routing mode
   426         *  information that is used to determine which cores will the generated
   427         *  SGI be routed to.
   428         *
   429         *  The routingMode field determines whether a generated SGI is routed to
   430         *  all cores except the core generating the SGI (Hwi_RoutingMode_ALL) or
   431         *  to list of target cores identified by the "targetList" and "aff1"
   432         *  fields (Hwi_RoutingMode_NODE).
   433         */
   434        struct SgiIntAffinity {
   435            UInt8       targetList;  /*! Bit map of target cores */
   436            UInt8       aff1;        /*! Identifies the target cluster */
   437            RoutingMode routingMode; /*! Routing Mode - ALL or NODE target list */
   438        };
   439    
   440        // -------- Module Types --------
   441    
   442        /*! Exception hook function type definition. */
   443        typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
   444    
   445        /*!
   446         *  ======== BasicView ========
   447         *  @_nodoc
   448         */
   449        metaonly struct BasicView {
   450            Ptr         halHwiHandle;
   451            String      label;
   452            Int         intNum;
   453            String      absPri;
   454            UInt        relGrpPri;
   455            UInt        relSubPri;
   456            String      fxn;
   457            UArg        arg;
   458        };
   459    
   460        /*!
   461         *  ======== DetailedView ========
   462         *  @_nodoc
   463         */
   464        metaonly struct DetailedView {
   465            Ptr         halHwiHandle;
   466            String      label;
   467            Int         intNum;
   468            String      absPri;
   469            UInt        relGrpPri;
   470            UInt        relSubPri;
   471            String      fxn;
   472            UArg        arg;
   473            Ptr         irp;
   474            String      enabled;
   475            String      pending;
   476            String      active;
   477            String      triggerSensitivity;
   478        };
   479    
   480        /*!
   481         *  ======== ModuleView ========
   482         *  @_nodoc
   483         */
   484        metaonly struct ModuleView {
   485            String      options[4];
   486            UInt        spuriousInterrupts;
   487            UInt        lastSpuriousInterrupt;
   488            String      hwiStackPeak;
   489            SizeT       hwiStackSize;
   490            Ptr         hwiStackBase;
   491        };
   492    
   493        /*!
   494         *  ======== rovViewInfo ========
   495         *  @_nodoc
   496         */
   497        @Facet
   498        metaonly config ViewInfo.Instance rovViewInfo =
   499            ViewInfo.create({
   500                viewMap: [
   501                    [
   502                        'Basic',
   503                        {
   504                            type: ViewInfo.INSTANCE,
   505                            viewInitFxn: 'viewInitBasic',
   506                            structName: 'BasicView'
   507                        }
   508                    ],
   509                    [
   510                        'Detailed',
   511                        {
   512                            type: ViewInfo.INSTANCE,
   513                            viewInitFxn: 'viewInitDetailed',
   514                            structName: 'DetailedView'
   515                        }
   516                    ],
   517                    [
   518                        'Module',
   519                        {
   520                            type: ViewInfo.MODULE,
   521                            viewInitFxn: 'viewInitModule',
   522                            structName: 'ModuleView'
   523                        }
   524                    ]
   525                ]
   526            });
   527    
   528        /*!
   529         *  Exception Context - Register contents at the time of an exception.
   530         */
   531        struct ExcContext {
   532            /* Thread Context */
   533            BIOS.ThreadType threadType; /* Type of thread executing at */
   534                                        /* the time the exception occurred */
   535            Ptr     threadHandle;       /* Handle to thread executing at */
   536                                        /* the time the exception occurred */
   537            Ptr     threadStack;        /* Address of stack contents of thread */
   538                                        /* executing at the time the exception */
   539                                        /* occurred */
   540            SizeT   threadStackSize;    /* size of thread stack */
   541            ExcType type;               /* Synchronous or SError */
   542    
   543            /* Internal Registers */
   544            Ptr     x0;
   545            Ptr     x1;
   546            Ptr     x2;
   547            Ptr     x3;
   548            Ptr     x4;
   549            Ptr     x5;
   550            Ptr     x6;
   551            Ptr     x7;
   552            Ptr     x8;
   553            Ptr     x9;
   554            Ptr     x10;
   555            Ptr     x11;
   556            Ptr     x12;
   557            Ptr     x13;
   558            Ptr     x14;
   559            Ptr     x15;
   560            Ptr     x16;
   561            Ptr     x17;
   562            Ptr     x18;
   563            Ptr     x19;
   564            Ptr     x20;
   565            Ptr     x21;
   566            Ptr     x22;
   567            Ptr     x23;
   568            Ptr     x24;
   569            Ptr     x25;
   570            Ptr     x26;
   571            Ptr     x27;
   572            Ptr     x28;
   573            Ptr     x29;
   574            Ptr     x30;
   575            Ptr     sp;                 /* sp_EL0 or sp_EL1 */
   576            Ptr     elr;                /* elr_EL1 */
   577            Ptr     spsr;               /* spsr_EL1 */
   578    
   579            /* Fault registers */
   580            Ptr     esr;                /* esr_EL1 */
   581        }
   582    
   583        /*!
   584         * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
   585         * a physical device
   586         */
   587        struct Gicd {
   588            UInt32 CTLR;            /*! 0x0000 Distributor Control Register */
   589            UInt32 TYPER;           /*! 0x0004 Interrupt Controller Type Register */
   590            UInt32 IIDR;            /*! 0x0008 Distributor Implementor Id Register */
   591            UInt32 hole0[13];       /*! 0x000C-0x03C */
   592            UInt32 SETSPI_NSR;      /*! 0x0040 Set SPI Register */
   593            UInt32 hole1;           /*! 0x0044 */
   594            UInt32 CLRSPI_NSR;      /*! 0x0048 Clear SPI Register */
   595            UInt32 hole2;           /*! 0x004C */
   596            UInt32 SETSPI_SR;       /*! 0x0050 Set SPI Register */
   597            UInt32 hole3;           /*! 0x0054 */
   598            UInt32 CLRSPI_SR;       /*! 0x0058 Clear SPI Register */
   599            UInt32 hole4[9];        /*! 0x005C-0x007C */
   600            UInt32 IGROUPR[32];     /*! 0x0080 Interrupt Group Registers */
   601            UInt32 ISENABLER[32];   /*! 0x0100 Interrupt Set-Enable Registers */
   602            UInt32 ICENABLER[32];   /*! 0x0180 Interrupt Clear-Enable Registers */
   603            UInt32 ISPENDR[32];     /*! 0x0200 Interrupt Set-Pending Registers */
   604            UInt32 ICPENDR[32];     /*! 0x0280 Interrupt Clear-Pending Registers */
   605            UInt32 ISACTIVER[32];   /*! 0x0300 Interrupt Set-Active Registers */
   606            UInt32 ICACTIVER[32];   /*! 0x0380 Interrupt Clear-Active Registers */
   607            UInt8  IPRIORITYR[992]; /*! 0x0400 Interrupt Priority Registers */
   608            UInt32 hole5[8];        /*! 0x07E0-0x07FC */
   609            UInt32 ITARGETSR[8];    /*! 0x0800 Interrupt Processor Targets
   610                                               Register */
   611            UInt32 hole6[248];      /*! 0x0820-0x0BFC */
   612            UInt32 ICFGR[64];       /*! 0x0C00 Interrupt Configuration Registers */
   613            UInt32 IGRPMODR[32];    /*! 0x0D00 Interrupt Group Modifier Registers */
   614            UInt32 hole7[32];       /*! 0x0D80-0x0DFC */
   615            UInt32 NSACR[64];       /*! 0x0E00 NonSecure Access Control Registers */
   616            UInt32 SGIR;            /*! 0x0F00 Software Generated Interrupt
   617                                               Register */
   618            UInt32 hole8[3];        /*! 0x0F04-0x0F0C */
   619            UInt32 CPENDSGIR[4];    /*! 0x0F10 SGI Clear-Pending Registers */
   620            UInt32 SPENDSGIR[4];    /*! 0x0F20 SGI Set-Pending Registers */
   621            UInt32 hole9[5172];     /*! 0x0F30-0x5FFC */
   622            UInt64 IROUTER[992];    /*! 0x6000 Interrupt Routing Registers */
   623            UInt32 hole10[4160];    /*! 0x7F00-0xBFFC */
   624            UInt32 ESTATUSR;        /*! 0xC000 Extended Status Register */
   625            UInt32 ERRTESTR;        /*! 0xC004 Error Test Register */
   626            UInt32 hole11[31];      /*! 0xC008-0xC080 */
   627            UInt32 SPISR[30];       /*! 0xC084 SPI Status Registers */
   628            UInt32 hole12[4021];    /*! 0xC0FC-0xFFCC */
   629            UInt32 PIDR4;           /*! 0xFFD0 Peripheral ID4 Register */
   630            UInt32 PIDR5;           /*! 0xFFD4 Peripheral ID5 Register */
   631            UInt32 PIDR6;           /*! 0xFFD8 Peripheral ID6 Register */
   632            UInt32 PIDR7;           /*! 0xFFDC Peripheral ID7 Register */
   633            UInt32 PIDR0;           /*! 0xFFE0 Peripheral ID0 Register */
   634            UInt32 PIDR1;           /*! 0xFFE4 Peripheral ID1 Register */
   635            UInt32 PIDR2;           /*! 0xFFE8 Peripheral ID2 Register */
   636            UInt32 PIDR3;           /*! 0xFFEC Peripheral ID3 Register */
   637            UInt32 CIDR0;           /*! 0xFFF0 Component  ID0 Register */
   638            UInt32 CIDR1;           /*! 0xFFF4 Component  ID1 Register */
   639            UInt32 CIDR2;           /*! 0xFFF8 Component  ID2 Register */
   640            UInt32 CIDR3;           /*! 0xFFFC Component  ID3 Register */
   641        };
   642    
   643        extern volatile Gicd gicd;
   644    
   645        /*!
   646         * Generic Interrupt Controller Redistributor Interface (RD_base).
   647         * Symbol "Hwi_gicr" is a physical device.
   648         */
   649        struct Gicr {
   650            UInt32 CTLR;            /*! 0x0000 Redistributor Control Register */
   651            UInt32 IIDR;            /*! 0x0004 Implementor Id Register */
   652            UInt64 TYPER;           /*! 0x0008 Redistributor Type Register */
   653            UInt32 hole0;           /*! 0x0010 */
   654            UInt32 WAKER;           /*! 0x0014 Power Management Control Register */
   655            UInt32 hole1[22];       /*! 0x0018-0x006C */
   656            UInt64 PROPBASER;       /*! 0x0070 LPI Config Table Base Register */
   657            UInt64 PENDBASER;       /*! 0x0078 LPI Pending Table Base Register */
   658        };
   659    
   660        /*!
   661         * Generic Interrupt Controller Redistributor Interface (SGI_base).
   662         * Symbol "Hwi_gics" is a physical device.
   663         */
   664        struct Gics {
   665            UInt32 hole0[32];       /*! 0x0000-0x007C */
   666            UInt32 IGROUPR0;        /*! 0x0080 Interrupt Group Register */
   667            UInt32 hole1[31];       /*! 0x0084-0x00FC */
   668            UInt32 ISENABLER0;      /*! 0x0100 Interrupt Set-Enable Register */
   669            UInt32 hole2[31];       /*! 0x0104-0x017C */
   670            UInt32 ICENABLER0;      /*! 0x0180 Interrupt Set-Enable Register */
   671            UInt32 hole3[31];       /*! 0x0184-0x01FC */
   672            UInt32 ISPENDR0;        /*! 0x0200 Interrupt Set-Enable Register */
   673            UInt32 hole4[31];       /*! 0x0204-0x027C */
   674            UInt32 ICPENDR0;        /*! 0x0280 Interrupt Set-Enable Register */
   675            UInt32 hole5[31];       /*! 0x0284-0x02FC */
   676            UInt32 ISACTIVER0;      /*! 0x0300 Interrupt Set-Enable Register */
   677            UInt32 hole6[31];       /*! 0x0304-0x037C */
   678            UInt32 ICACTIVER0;      /*! 0x0380 Interrupt Set-Enable Register */
   679            UInt32 hole7[31];       /*! 0x0384-0x03FC */
   680            UInt8  IPRIORITYR[32];  /*! 0x0400 Interrupt Priority Registers */
   681            UInt32 hole8[504];      /*! 0x0420-0x0BFC */
   682            UInt32 ICFGR[2];        /*! 0x0C00 Interrupt Configuration Registers */
   683            UInt32 hole9[62];       /*! 0x0C08-0x0CFC */
   684            UInt32 IGRPMODR0;       /*! 0x0D00 Interrupt Group Modifier Register */
   685            UInt32 hole10[63];      /*! 0x0D04-0x0DFC */
   686            UInt32 NSACR;           /*! 0x0E00 NonSecure Access Control Register */
   687        };
   688    
   689        /*!
   690         * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
   691         * a physical device.
   692         */
   693        struct Gicc {
   694            UInt32 CTLR;            /*! 0x0000 CPU Interface Control Register */
   695            UInt32 PMR;             /*! 0x0004 Interrupt Priority Mask Register */
   696            UInt32 BPR;             /*! 0x0008 Binary Point Register */
   697            UInt32 IAR;             /*! 0x000C Interrupt Acknowledge Register */
   698            UInt32 EOIR;            /*! 0x0010 End Of Interrupt Register */
   699            UInt32 RPR;             /*! 0x0014 Running Priority Register */
   700            UInt32 HPPIR;           /*! 0x0018 Highest Priority Pending Interrupt
   701                                        Register */
   702            UInt32 ABPR;            /*! 0x001C Aliased Binary Point Register */
   703            UInt32 AIAR;            /*! 0x0020 Aliased IAR Register */
   704            UInt32 AEOIR;           /*! 0x0024 Aliased EOI Register */
   705            UInt32 AHPPIR;          /*! 0x0028 Aliased HPPI Register */
   706            UInt32 hole0[41];       /*! 0x002C-0x00CC */
   707            UInt32 APR0;            /*! 0x00D0 Active Priority Register */
   708            UInt32 hole1[3];        /*! 0x00D4-0x00DC */
   709            UInt32 NSAPR0;          /*! 0x00E0 Non-secure Active Priority Register */
   710            UInt32 hole2[6];        /*! 0x00E4-0x00F8 */
   711            UInt32 IIDR;            /*! 0x00FC CPU Interface Id Register */
   712            UInt32 hole3[960];      /*! 0x0100-0x0FFC */
   713            UInt32 DIR;             /*! 0x1000 Deactivate Interrupt Register */
   714        };
   715    
   716        /*!
   717         * Generic Interrupt Controller ITS Interface. Symbol "Hwi_gits" is
   718         * a physical device.
   719         */
   720        struct Gits {
   721            UInt32 CTLR;            /*! 0x00000 ITS control register */
   722            UInt32 IIDR;            /*! 0x00004 ITS ID register */
   723            UInt64 TYPER;           /*! 0x00008 ITS Type register */
   724            UInt32 hole0[28];       /*! 0x00010-0x0007C */
   725            UInt64 CBASER;          /*! 0x00080 ITS Command Queue Descriptor */
   726            UInt64 CWRITER;         /*! 0x00088 ITS Write register */
   727            UInt64 CREADR;          /*! 0x00090 ITS Read register */
   728            UInt32 hole1[26];       /*! 0x00098-0x000FC */
   729            UInt64 BASER[8];        /*! 0x00100 ITS Translation Table Descriptors */
   730            UInt32 hole2[944];      /*! 0x00140-0x0FFFC */
   731            UInt32 hole3[16];       /*! 0x10000-0x1003C */
   732            UInt32 TRANSLATER;      /*! 0x10040 ITS Translation Register */
   733        };
   734    
   735        extern volatile Gits gits;
   736    
   737        // -------- Module Parameters --------
   738    
   739        /*!
   740         *  Enable full exception decoding, default is true.
   741         *
   742         *  When enabled, the exception handler will fully
   743         *  decode an exception and dump the registers to the
   744         *  system console.
   745         *
   746         *  When set to false, only an Error is printed on the console.
   747         *
   748         *  In either case, the full exception context is always
   749         *  saved and visible with ROV.
   750         */
   751        config Bool enableDecode = true;
   752    
   753        /*!
   754         *  User Exception Context Buffer Address
   755         *
   756         *  By default, when an exception occurs, an {@link #ExcContext}
   757         *  structure is allocated on the ISR stack and filled in within the
   758         *  exception handler.
   759         *
   760         *  If {@link #excContextBuffer} is initialized by the user, the
   761         *  {@link #ExcContext} structure will be placed at that address instead.
   762         *
   763         *  The buffer must be large enough to contain an {@link #ExcContext}
   764         *  structure.
   765         */
   766        metaonly config Ptr excContextBuffer[];
   767    
   768        /*!
   769         *  User Synchronous Exception hook function.
   770         *
   771         *  Called just after the exception context has been initialized.
   772         *
   773         *  This function will be run on the ISR stack.
   774         *
   775         *  This function must run to completion.
   776         *
   777         *  It is called without any Task or Swi scheduling protection
   778         *  and therefore can not call any functions that may cause a Swi or Task
   779         *  scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
   780         */
   781        config ExceptionHookFuncPtr syncExcHookFunc[];
   782    
   783        /*!
   784         *  User SError Exception hook function.
   785         *
   786         *  Called just after the exception context has been initialized.
   787         *
   788         *  This function will be run on the ISR stack.
   789         *
   790         *  This function must run to completion.
   791         *
   792         *  It is called without any Task or Swi scheduling protection
   793         *  and therefore can not call any functions that may cause a Swi or Task
   794         *  scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
   795         */
   796        config ExceptionHookFuncPtr sErrorExcHookFunc[];
   797    
   798        /*!
   799         *  @_nodoc
   800         *  ======== irqStackSection ========
   801         *  Memory section used for IRQ stack on each core
   802         *  Default is null.
   803         */
   804        metaonly config String irqStackSection = null;
   805    
   806        /*!
   807         *  ======== A_badSGIIntNum ========
   808         *  Assert raised when an interrupt number >= 16 is
   809         *  passed to Hwi_raiseSGI() function.
   810         */
   811        config xdc.runtime.Assert.Id A_badSGIIntNum  = {
   812            msg: "A_badSGIIntNum: SGI intNum should be <= 15."
   813        };
   814    
   815        /*!
   816         *  Error raised when an attempt is made to create a Hwi
   817         *  that has already been created.
   818         */
   819        config Error.Id E_alreadyDefined = {
   820            msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
   821        };
   822    
   823        /*!
   824         *  Error raised when Hwi handle referenced in Hwi_delete()
   825         *  is not found in the Hwi dispatch table
   826         */
   827        config Error.Id E_handleNotFound = {
   828            msg: "E_handleNotFound: Hwi handle not found: 0x%x"
   829        };
   830    
   831        /*!
   832         *  Error raised when an undefined interrupt has fired.
   833         */
   834        config Error.Id E_undefined = {
   835            msg: "E_undefined: Hwi undefined, intnum: %d"
   836        };
   837    
   838        /*!
   839         *  Error raised if an attempt is made to create a Hwi
   840         *  with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
   841         */
   842        config Error.Id E_badIntNum = {
   843            msg: "E_badIntNum, intnum: %d is out of range"
   844        };
   845    
   846        /*!
   847         *  Error raised when an exception occurs.
   848         */
   849        config Error.Id E_exception = {
   850            msg: "E_exception: A hardware exception has occurred."
   851        };
   852    
   853        /*!
   854         *  Error raised if {@link #post post()} is called for an LPI
   855         */
   856        config Error.Id E_cantPostLPI = {
   857            msg: "E_cantPostLPI: intNum %d is an LPI and can't be posted.  Use Hwi_itsInt() instead."
   858        };
   859    
   860        /*!
   861         *  Error raised if {@link #clearInterrupt clearInterrupt()} is called for
   862         *  an LPI
   863         */
   864        config Error.Id E_cantClearLPI = {
   865            msg: "E_cantClearLPI: intNum %d is an LPI and can't be cleared. Use Hwi_itsClear() instead."
   866        };
   867    
   868        /*!
   869         *  Error raised if {@link #enableLPI} = true and Affinity Routing is
   870         *  not enabled
   871         */
   872        config Error.Id E_affRoutingNotEnabled = {
   873            msg: "E_affRoutingNotEnabled: "
   874        };
   875    
   876        /*!
   877         *  Error raised if {@link #enableLPI} = true and LPIs are not enabled
   878         */
   879        config Error.Id E_LPISNotEnabled = {
   880            msg: "E_LPISNotEnabled: "
   881        };
   882    
   883        /*!
   884         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   885         */
   886        config Log.Event LM_begin = {
   887            mask: Diags.USER1 | Diags.USER2,
   888            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   889        };
   890    
   891        /*!
   892         *  Issued just after return from Hwi function (with interrupts disabled)
   893         */
   894        config Log.Event LD_end = {
   895            mask: Diags.USER2,
   896            msg: "LD_end: hwi: 0x%x"
   897        };
   898    
   899    
   900        // -------- Module Functions --------
   901    
   902        /*!
   903         *  ======== disable ========
   904         *  Globally disable interrupts.
   905         *
   906         *  Hwi_disable globally disables hardware interrupts and returns an
   907         *  opaque key indicating whether interrupts were globally enabled or
   908         *  disabled on entry to Hwi_disable().
   909         *  The actual value of the key is target/device specific and is meant
   910         *  to be passed to Hwi_restore().
   911         *
   912         *  Call Hwi_disable before a portion of a function that needs
   913         *  to run without interruption. When critical processing is complete, call
   914         *  Hwi_restore or Hwi_enable to reenable hardware interrupts.
   915         *
   916         *  Servicing of interrupts that occur while interrupts are disabled is
   917         *  postponed until interrupts are reenabled. However, if the same type
   918         *  of interrupt occurs several times while interrupts are disabled,
   919         *  the interrupt's function is executed only once when interrupts are
   920         *  reenabled.
   921         *
   922         *  A context switch can occur when calling Hwi_enable or Hwi_restore if
   923         *  an enabled interrupt occurred while interrupts are disabled.
   924         *
   925         *  Hwi_disable may be called from main(). However, since Hwi interrupts
   926         *  are already disabled in main(), such a call has no effect.
   927         *
   928         *  @a(NOTE)
   929         *  Disables only IRQ interrupts
   930         *
   931         *  @a(constraints)
   932         *  If a Task switching API such as
   933         *  {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
   934         *  {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
   935         *  {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
   936         *  {@link ti.sysbios.knl.Task#yield Task_yield()}
   937         *  is invoked which results in a context switch while
   938         *  interrupts are disabled, an embedded call to
   939         *  {@link #enable Hwi_enable} occurs
   940         *  on the way to the new thread context which unconditionally re-enables
   941         *  interrupts. Interrupts will remain enabled until a subsequent
   942         *  {@link #disable Hwi_disable}
   943         *  invocation.
   944         *
   945         *  Swis always run with interrupts enabled.
   946         *  See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
   947         *  interrupts.
   948         *
   949         *  @b(returns)     opaque key for use by Hwi_restore()
   950         */
   951        @Macro
   952        override UInt disable();
   953    
   954        /*!
   955         *  ======== enable ========
   956         *
   957         *  @a(NOTE)
   958         *  Enables only IRQ interrupts
   959         */
   960        @Macro
   961        override UInt enable();
   962    
   963        /*!
   964         *  ======== restore ========
   965         *
   966         *  @a(NOTE)
   967         *  Restores only IRQ interrupts
   968         */
   969        @Macro
   970        override Void restore(UInt key);
   971    
   972        /*!
   973         *  ======== enableIRQ ========
   974         *  Enable IRQ interrupts.
   975         *
   976         *  @a(NOTE)
   977         *  Same as Hwi_enable()
   978         *
   979         *  @b(returns)     previous IRQ interrupt enable/disable state
   980         */
   981        @Macro
   982        UInt enableIRQ();
   983    
   984        /*!
   985         *  ======== disableIRQ ========
   986         *  Disable IRQ interrupts.
   987         *
   988         *  @a(NOTE)
   989         *  Same as Hwi_disable()
   990         *
   991         *  @b(returns)     previous IRQ interrupt enable/disable state
   992         */
   993        @Macro
   994        UInt disableIRQ();
   995    
   996        /*!
   997         *  ======== restoreIRQ ========
   998         *  Restore IRQ interrupts.
   999         *
  1000         *  @a(NOTE)
  1001         *  Same as Hwi_restore()
  1002         *
  1003         *  @param(key)     enable/disable state to restore
  1004         */
  1005        @Macro
  1006        Void restoreIRQ(UInt key);
  1007    
  1008        /*!
  1009         *  @_nodoc
  1010         *  ======== disableFxn ========
  1011         *  function call implementation
  1012         */
  1013        UInt disableFxn();
  1014    
  1015        /*!
  1016         *  @_nodoc
  1017         *  ======== enableFxn ========
  1018         *  function call implementation
  1019         */
  1020        UInt enableFxn();
  1021    
  1022        /*!
  1023         *  @_nodoc
  1024         *  ======== restoreFxn ========
  1025         *  function call implementation
  1026         */
  1027        Void restoreFxn(UInt key);
  1028    
  1029        /*!
  1030         *  ======== getHandle ========
  1031         *  Returns Hwi_Handle associated with intNum
  1032         *
  1033         *  @param(intNum)  interrupt number
  1034         */
  1035        Handle getHandle(UInt intNum);
  1036    
  1037        /*!
  1038         *  @_nodoc
  1039         *  ======== init ========
  1040         *  assembly code mode registers setup
  1041         */
  1042        Void init();
  1043    
  1044        /*!
  1045         *  @_nodoc
  1046         *  ======== initIntControllerCoreX ========
  1047         */
  1048        Void initIntControllerCoreX();
  1049    
  1050        /*!
  1051         *  ======== intAffinity ========
  1052         *  SMP Interrupt affinity mappings
  1053         *
  1054         *  In SMP mode, this array maps the interrupt number to the
  1055         *  core it is to be tied to. By default, all interrupts
  1056         *  are routed to Core0.
  1057         *
  1058         *  For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
  1059         *  module interrupt to core 1 rather than core 0, add the following to
  1060         *  your config file:
  1061         *
  1062         *  @p(code)
  1063         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
  1064         *     Hwi.intAffinity[<intNum>] = 1;
  1065         *  @p
  1066         *
  1067         *  @a(constraints)
  1068         *  Interrupt numbers below 32 are ignored. This config param only
  1069         *  allows routing interrupt numbers greater than or equal to #32.
  1070         */
  1071        metaonly config UInt8 intAffinity[];
  1072    
  1073        /*!
  1074         *  ======== intRouting ========
  1075         *  SMP Interrupt routing mappings
  1076         *
  1077         *  In SMP mode, this array maps the interrupt number to the
  1078         *  core or cores it is to be tied to. By default, all interrupts
  1079         *  are routed to Core0.
  1080         *
  1081         *  For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
  1082         *  module interrupt to core 1 rather than core 0, add the following to
  1083         *  your config file:
  1084         *
  1085         *  @p(code)
  1086         *     var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
  1087         *     Hwi.intRouting[<intNum>] = {aff0: 1, aff1: 0,
  1088                                            routingMode: Hwi.RoutingMode_NODE};
  1089         *  @p
  1090         *
  1091         *  @a(constraints)
  1092         *  Interrupt numbers below 32 are ignored. This config param only
  1093         *  allows routing interrupt numbers greater than or equal to #32.
  1094         */
  1095        metaonly config IntAffinity intRouting[];
  1096    
  1097        /*!
  1098         *  @_nodoc
  1099         *  ======== raiseSGI ========
  1100         *  Generate an SGI interrupt and route it to CPUs specified by the
  1101         *  affinity field.
  1102         *
  1103         *  @param(affinity)    If the "routingMode" field is set to
  1104         *                      Hwi_RoutingMode_ANY, then the interrupt is routed to
  1105         *                      all cores except this core. Else, if "routingMode"
  1106         *                      is set to Hwi_RoutingMode_NODE, the affinity fields
  1107         *                      are used to determine which cores the interrupt
  1108         *                      should be routed to. "aff0" field is a bit mapped
  1109         *                      target list identifying all cores within the cluster
  1110         *                      identified by "aff1".
  1111         *  @param(intNum)      Interrupt number
  1112         */
  1113        Void raiseSGI(SgiIntAffinity affinity, UInt intNum);
  1114    
  1115        /*!
  1116         *  ======== setPriority ========
  1117         *  Set an interrupt's priority.
  1118         *
  1119         *  Not an instance function so that it can be used
  1120         *  with non-dispatched interrupts.
  1121         *
  1122         *  @param(intNum)      ID of interrupt
  1123         *  @param(priority)    priority
  1124         */
  1125        Void setPriority(UInt intNum, UInt priority);
  1126    
  1127        /*!
  1128         *  ======== itsInv ========
  1129         *  Implements ITS command INV
  1130         */
  1131        Bool itsInv(Int deviceId, Int eventId);
  1132    
  1133        /*!
  1134         *  ======== itsInvall ========
  1135         *  Implements ITS command INVALL
  1136         */
  1137        Bool itsInvall(Int icId);
  1138    
  1139        /*!
  1140         *  ======== itsSync ========
  1141         *  Implements ITS command SYNC
  1142         */
  1143        Bool itsSync(Int cpuNum);
  1144    
  1145        /*!
  1146         *  ======== itsMapDevice ========
  1147         *  Implements ITS command MAPD
  1148         */
  1149        Bool itsMapDevice(Int deviceId, Int nEvents, Int size);
  1150    
  1151        /*!
  1152         *  ======== itsMapCollection ========
  1153         *  Implements ITS command MAPC
  1154         */
  1155        Bool itsMapCollection(Int icId, Int cpuNum);
  1156    
  1157        /*!
  1158         *  ========  itsMapInterrupt ========
  1159         *  Implements ITS command MAPI
  1160         */
  1161        Bool itsMapInterrupt(Int deviceId, Int eventId, Int icId);
  1162    
  1163        /*!
  1164         *  ======== itsMapTranslatedInterrupt ========
  1165         *  Implements ITS command MAPTI
  1166         */
  1167        Bool itsMapTranslatedInterrupt(Int deviceId, Int eventId, Int icId,
  1168                                       Int intId);
  1169    
  1170        /*!
  1171         *  ======== istMoveInterrupt ========
  1172         *  Implements ITS command MOVI
  1173         */
  1174        Bool itsMoveInterrupt(Int deviceId, Int eventId, Int icId);
  1175    
  1176        /*!
  1177         *  ======== itsMoveAll ========
  1178         *  Implements ITS command MOVALL
  1179         */
  1180        Bool itsMoveAll(Int fromCpuNum, Int toCpuNum);
  1181    
  1182        /*!
  1183         *  ======== itsInt ========
  1184         *  Implements ITS command INT
  1185         */
  1186        Bool itsInt(Int deviceId, Int eventId);
  1187    
  1188        /*!
  1189         *  ======== itsClear ========
  1190         *  Implements ITS command CLEAR
  1191         */
  1192        Bool itsClear(Int deviceId, Int eventId);
  1193    
  1194        /*!
  1195         *  ======== itsDiscard ========
  1196         *  Implements ITS command DISCARD
  1197         */
  1198        Bool itsDiscard(Int deviceId, Int eventId);
  1199    
  1200    instance:
  1201    
  1202        /*!
  1203         *  ======== type ========
  1204         *  Interrupt type (IRQ/FIQ). Default is IRQ.
  1205         *
  1206         *  @a(NOTE)
  1207         *  FIQs are only supported when {@link #enableSecureMode} is set to
  1208         *  true.
  1209         */
  1210        config Type type = Type_IRQ;
  1211    
  1212        /*!
  1213         *  ======== triggerSensitivity ========
  1214         *  Set an interrupt's trigger sensitivity
  1215         *
  1216         *  2-bit field that configures the trigger sensitivity of an
  1217         *  interrupt.
  1218         *
  1219         *  On the Cortex-A15, all software generated interrupts (SGI)
  1220         *  are edge-triggered (b10) and all private peripheral interrupts (PPI)
  1221         *  are level-sensitive (b01). The trigger sensitivity of these
  1222         *  interrupt types cannot be changed.
  1223         *
  1224         *  For shared peripheral interrupts (SPI), the LSB of the bit-pair
  1225         *  is read only and is always 1. The MSB of the bit-pair can be
  1226         *  altered to change trigger sensitivity.
  1227         *
  1228         *  Possible bit-pair encodings for Cortex-A15 SPIs:
  1229         *      b01    Interrupt is active-High level-sensitive (default)
  1230         *      b11    Interrupt is rising edge-sensitive
  1231         *
  1232         *  For more information please refer section 4.3.13 on
  1233         *  Interrupt Configuration Registers (GICD_ICFGRn) in
  1234         *  ARM Generic Interrupt Controller Architecure Spec v2.0
  1235         *
  1236         *  @a(constraints)
  1237         *  This Hwi param is ignored if
  1238         *  {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
  1239         *  set to false.
  1240         */
  1241        config UInt triggerSensitivity = ~(0);
  1242    
  1243        /*!
  1244         *  ======== Interrupt priority ========
  1245         *  Hwi instance interrupt priority.
  1246         *
  1247         *  Valid priorities are device dependent and their
  1248         *  nesting behaviors depend on the {@link #BPR} setting.
  1249         *
  1250         *  See the ARM GIC Architecture Specification v2.0 document for more
  1251         *  details.
  1252         */
  1253        override config Int priority = -1;
  1254    
  1255        /*! The interrupt controller is designed for priority based interrupts */
  1256        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
  1257    
  1258        /*!
  1259         *  ======== reconfig ========
  1260         *  Reconfigure a dispatched interrupt.
  1261         */
  1262        Void reconfig(FuncPtr fxn, const Params *params);
  1263    
  1264    internal:   /* not for client use */
  1265    
  1266        struct GicRegisterMap {
  1267            volatile Gicr *gicr;
  1268            volatile Gics *gics;
  1269        };
  1270    
  1271        config GicRegisterMap gicMap[];
  1272    
  1273        /*
  1274         *  Number of GICD Enable registers
  1275         */
  1276        config UInt NUM_GICD_ENABLE_REGS;
  1277    
  1278        config SizeT isrStackSize;
  1279    
  1280        /*
  1281         *  ======== initGicd ========
  1282         *  Flag determines whether to initialize global gic distributor
  1283         *  registers. It is set to false if this core is not the boot master.
  1284         */
  1285        config Bool initGicd = true;
  1286    
  1287        /*
  1288         *  ======== inUseMeta ========
  1289         *  @_nodoc
  1290         *  Check for Hwi already in use.
  1291         *  For internal SYS/BIOS use only.
  1292         *  Should be called prior to any internal Hwi.create().
  1293         *
  1294         *  @param(intNum)  interrupt number
  1295         */
  1296        metaonly Bool inUseMeta(UInt intNum);
  1297    
  1298        /*
  1299         * Swi and Task module function pointers.
  1300         * Used to decouple Hwi from Swi and Task when
  1301         * dispatcherSwiSupport or
  1302         * dispatcherTaskSupport is false.
  1303         */
  1304        config UInt (*swiDisable)();
  1305        config Void (*swiRestoreHwi)(UInt);
  1306        config UInt (*taskDisable)();
  1307        config Void (*taskRestoreHwi)(UInt);
  1308    
  1309        /*
  1310         *  ======== dispatchIRQ ========
  1311         *  Interrupt Dispatcher assembly code wrapper
  1312         */
  1313        Void dispatchIRQ(Bool usingEL0Stack);
  1314    
  1315        /*
  1316         *  ======== dispatchIRQC ========
  1317         *  Interrupt Dispatcher C code
  1318         */
  1319        Void dispatchIRQC(Irp irp, Bool rootISR, Char *taskSP);
  1320    
  1321        /*!
  1322         *  ======== excDumpContext ========
  1323         */
  1324        Void excDumpContext();
  1325    
  1326        /*
  1327         *  ======== excHandler ========
  1328         */
  1329        Void excHandler(UInt64 *excStack, ExcType excType);
  1330    
  1331        /*
  1332         *  ======== initIntController ========
  1333         */
  1334        Void initIntControllerCore0();
  1335    
  1336        /*
  1337         *  ======== initStacks ========
  1338         *  set up split stacks
  1339         */
  1340        Void initStacks(Ptr hwiStack);
  1341    
  1342        /*
  1343         *  ======== nonPluggedHwiHandler ========
  1344         *  Non-plugged interrupt handler
  1345         */
  1346        Void nonPluggedHwiHandler();
  1347    
  1348        /*
  1349         *  ======== postInit ========
  1350         *  finish initializing static and dynamic Hwis
  1351         */
  1352        Int postInit(Object *hwi, Error.Block *eb);
  1353    
  1354        /*
  1355         *  ======== initLPI ========
  1356         */
  1357        Bool initLPI();
  1358    
  1359        /*
  1360         *  ======== issueITSCommand ========
  1361         */
  1362        Bool issueITSCommand();
  1363    
  1364        /*
  1365         *  ======== enableInterruptLPI ========
  1366         */
  1367        UInt enableInterruptLPI(Int intId);
  1368    
  1369        /*
  1370         *  ======== disableInterruptLPI ========
  1371         */
  1372        UInt disableInterruptLPI(Int intId);
  1373    
  1374        /*
  1375         *  ======== setPriorityLPI ========
  1376         */
  1377        Void setPriorityLPI(Int intId, Int priority);
  1378    
  1379        /*
  1380         *  ======== ItsCmdStruct ========
  1381         */
  1382        struct ItsCmd {
  1383            UInt64 words[4];
  1384        };
  1385    
  1386        /*!
  1387         *  const array to hold all HookSet objects.
  1388         */
  1389        config HookSet hooks[length] = [];
  1390    
  1391        /*! Meta World Only Hwi Configuration Object. */
  1392        metaonly struct InterruptObj {
  1393            Bool used;              /* Interrupt already defined? */
  1394            FuncPtr fxn;            /* Dispatched ISR function */
  1395        };
  1396    
  1397        /*!
  1398         * Meta-only array of interrupt objects.
  1399         * This meta-only array of Hwi config objects is initialized
  1400         * in Hwi.xs:module$meta$init().
  1401         */
  1402        metaonly config InterruptObj interrupt[];
  1403    
  1404        /*!
  1405         * GIC Distributor base address
  1406         */
  1407        metaonly config Ptr gicdBaseAddress;
  1408    
  1409        /*!
  1410         * GIC Redistributor base address
  1411         */
  1412        metaonly config Ptr gicrBaseAddress;
  1413    
  1414        /*!
  1415         * GIC ITS base address
  1416         */
  1417        metaonly config Ptr gitsBaseAddress;
  1418    
  1419    
  1420        struct Instance_State {
  1421            Type        type;             /* Interrupt Type */
  1422            UInt        priority;         /* Interrupt Priority */
  1423            UArg        arg;              /* Argument to Hwi function */
  1424            FuncPtr     fxn;              /* Hwi function */
  1425            Irp         irp;              /* current IRP */
  1426            Ptr         hookEnv[];
  1427            UInt        triggerSensitivity;
  1428        };
  1429    
  1430        struct Module_State {
  1431            Char         *isrStack[];     /* Points to isrStack address */
  1432            Char          hwiStack[][];   /* IRQ stack for each core */
  1433            UInt          irp[];          /* temp irp storage for IRQ handler */
  1434            Char         *taskSP[];       /* Interrupted Task's Stack Pointer */
  1435            Ptr           isrStackSize;   /* = Program.stack */
  1436                                          /*
  1437                                           * !!! The above three fields MUST be kept
  1438                                           * !!! at the base of the module state
  1439                                           * !!! GNU switchAndRunFunc and
  1440                                           * !!! SMP Core module assumes it
  1441                                           */
  1442            UInt32        iser[32];       /* Initial Interrupt enable reg values */
  1443            UInt32        icfgr[];        /* Initial Trigger sensitivity values */
  1444            UInt          spuriousInts;   /* Count of spurious interrupts */
  1445            UInt          lastSpuriousInt;/* Most recent spurious interrupt */
  1446            Ptr           isrStackBase;   /* = __TI_STACK_BASE */
  1447            Handle        dispatchTable[];/* dispatch table */
  1448            volatile UInt curIntId;       /* current Interrupt Id */
  1449            IntAffinity   intAffinity[];  /* smp int-to-coreId mappings */
  1450            Bool          excActive[];    /* TRUE if an exception has occurred */
  1451            ExcContext   *excContext[];   /* Exception context */
  1452            /* ITS/LPI tables */
  1453            Char          itsDeviceTable[];
  1454            ItsCmd        itsCommandQueue[];
  1455            Char          itsLPIConfigTable[];
  1456            Char          itsLPIPendTable[][];
  1457            ItsCmd        *curCmd;
  1458            ItsCmd        *lastCmd;
  1459            Int           ittEntrySize;
  1460        };
  1461    
  1462    }