1    /*
     2     * Copyright (c) 2012-2015, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== GateMP.xdc ========
    34     *
    35     */
    36    
    37    package ti.sdo.ipc;
    38    
    39    import xdc.runtime.Error;
    40    import xdc.runtime.Assert;
    41    import xdc.runtime.IGateProvider;
    42    import xdc.runtime.Log;
    43    import xdc.runtime.Diags;
    44    
    45    import ti.sdo.utils.NameServer;
    46    import ti.sdo.ipc.interfaces.IGateMPSupport;
    47    
    48    /*!
    49     *  ======== GateMP ========
    50     *  Multiple processor gate that provides local and remote context protection.
    51     *
    52     *  @p(html)
    53     *  This module has a common header that can be found in the {@link ti.ipc}
    54     *  package.  Application code should include the common header file (not the
    55     *  RTSC-generated one):
    56     *
    57     *  <PRE>#include &lt;ti/ipc/GateMP.h&gt;</PRE>
    58     *
    59     *  The RTSC module must be used in the application's RTSC configuration file
    60     *  (.cfg) if runtime APIs will be used in the application:
    61     *
    62     *  <PRE>GateMP = xdc.useModule('ti.sdo.ipc.GateMP');</PRE>
    63     *
    64     *  Documentation for all runtime APIs, instance configuration parameters,
    65     *  error codes macros and type definitions available to the application
    66     *  integrator can be found in the
    67     *  <A HREF="../../../../doxygen/html/files.html">Doxygen documentation</A>
    68     *  for the IPC product.  However, the documentation presented on this page
    69     *  should be referred to for information specific to the RTSC module, such as
    70     *  module configuration, Errors, and Asserts.
    71     *  @p
    72     */
    73    
    74    @InstanceInitError
    75    @InstanceFinalize
    76    
    77    @Template("./GateMP.xdt")
    78    module GateMP
    79    {
    80        /*!
    81         *  ======== BasicView ========
    82         *  @_nodoc
    83         */
    84        metaonly struct BasicView {
    85            String  name;
    86            String  remoteProtect;
    87            String  remoteStatus;
    88            String  localProtect;
    89            UInt    numOpens;
    90            Bits32  resourceId;
    91            UInt    creatorProcId;
    92            String  objType;
    93        }
    94    
    95        /*!
    96         *  ======== ModuleView ========
    97         *  @_nodoc
    98         */
    99        metaonly struct ModuleView {
   100            UInt    numGatesSystem;
   101            UInt    numUsedSystem;
   102            UInt    numGatesCustom1;
   103            UInt    numUsedCustom1;
   104            UInt    numGatesCustom2;
   105            UInt    numUsedCustom2;
   106        }
   107    
   108        /*!
   109         *  ======== rovViewInfo ========
   110         *  @_nodoc
   111         */
   112        @Facet
   113        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
   114            xdc.rov.ViewInfo.create({
   115                viewMap: [
   116                    ['Basic',
   117                        {
   118                            type: xdc.rov.ViewInfo.INSTANCE,
   119                            viewInitFxn: 'viewInitBasic',
   120                            structName: 'BasicView'
   121                        }
   122                    ],
   123                    ['Gate Resources',
   124                        {
   125                            type: xdc.rov.ViewInfo.MODULE,
   126                            viewInitFxn: 'viewInitModule',
   127                            structName: 'ModuleView'
   128                        }
   129                    ]
   130                ]
   131            });
   132    
   133        /*!
   134         *  ======== Reserved space at the top of SharedRegion0 ========
   135         */
   136        struct Reserved {
   137            Bits32  version;
   138        };
   139    
   140        /*!
   141         *  ======== E_gateUnavailable ========
   142         *  Error raised no gates of the requested type are available
   143         */
   144        config Error.Id E_gateUnavailable  = {
   145            msg: "E_gateUnavailable: No gates of requested type are available"
   146        };
   147    
   148        /*!
   149         *  ======== E_localGate ========
   150         *  Error raised when remote side tried to open local gate
   151         */
   152        config Error.Id E_localGate  = {
   153            msg: "E_localGate: Only creator can open local Gate"
   154        };
   155    
   156        /*!
   157         *  Assert raised when calling GateMP_close with the wrong handle
   158         */
   159        config Assert.Id A_invalidClose  = {
   160            msg: "A_invalidClose: Calling GateMP_close with the wrong handle"
   161        };
   162    
   163        /*!
   164         *  Assert raised when calling GateMP_delete incorrectly
   165         */
   166        config Assert.Id A_invalidDelete  = {
   167            msg: "A_invalidDelete: Calling GateMP_delete incorrectly"
   168        };
   169    
   170        /*!
   171         *  ======== LM_enter ========
   172         *  Logged on gate enter
   173         */
   174        config Log.Event LM_enter = {
   175            mask: Diags.USER1,
   176            msg: "LM_enter: Gate (remoteGate = %d, resourceId = %d) entered, returning key = %d"
   177        };
   178    
   179        /*!
   180         *  ======== LM_leave ========
   181         *  Logged on gate leave
   182         */
   183        config Log.Event LM_leave = {
   184            mask: Diags.USER1,
   185            msg: "LM_leave: Gate (remoteGate = %d, resourceId = %d) left using key = %d"
   186        };
   187    
   188        /*!
   189         *  ======== LM_create ========
   190         *  Logged on gate create
   191         */
   192        config Log.Event LM_create = {
   193            mask: Diags.USER1,
   194            msg: "LM_create: Gate (remoteGate = %d, resourceId = %d) created"
   195        };
   196    
   197        /*!
   198         *  ======== LM_open ========
   199         *  Logged on gate open
   200         */
   201        config Log.Event LM_open = {
   202            mask: Diags.USER1,
   203            msg: "LM_open: Remote gate (remoteGate = %d, resourceId = %d) opened"
   204        };
   205    
   206        /*!
   207         *  ======== LM_delete ========
   208         *  Logged on gate deletion
   209         */
   210        config Log.Event LM_delete = {
   211            mask: Diags.USER1,
   212            msg: "LM_delete: Gate (remoteGate = %d, resourceId = %d) deleted"
   213        };
   214    
   215        /*!
   216         *  ======== LM_close ========
   217         *  Logged on gate close
   218         */
   219        config Log.Event LM_close = {
   220            mask: Diags.USER1,
   221            msg: "LM_close: Gate (remoteGate = %d, resourceId = %d) closed"
   222        };
   223    
   224        /*!
   225         *  A set of local context protection levels
   226         *
   227         *  Each member corresponds to a specific local processor gates used for
   228         *  local protection.
   229         *
   230         *  For SYS/BIOS users, the following are the mappings for the constants
   231         *  @p(blist)
   232         * -INTERRUPT -> GateAll: disables interrupts
   233         * -TASKLET   -> GateSwi: disables Swis (software interrupts)
   234         * -THREAD    -> GateMutexPri: based on Semaphores
   235         * -PROCESS   -> GateMutexPri: based on Semaphores
   236         *  @p
   237         */
   238        enum LocalProtect {
   239            LocalProtect_NONE      = 0,
   240            LocalProtect_INTERRUPT = 1,
   241            LocalProtect_TASKLET   = 2,
   242            LocalProtect_THREAD    = 3,
   243            LocalProtect_PROCESS   = 4
   244        };
   245    
   246        /*!
   247         *  Type of remote Gate
   248         *
   249         *  Each member corresponds to a specific type of remote gate.
   250         *  Each enum value corresponds to the following remote protection levels:
   251         *  @p(blist)
   252         * -NONE      -> No remote protection (the GateMP instance will exclusively
   253         *               offer local protection configured in {@link #localProtect})
   254         * -SYSTEM    -> Use the SYSTEM remote protection level (default for remote
   255         *               protection
   256         * -CUSTOM1   -> Use the CUSTOM1 remote protection level
   257         * -CUSTOM2   -> Use the CUSTOM2 remote protection level
   258         *  @p
   259         */
   260        enum RemoteProtect {
   261            RemoteProtect_NONE     = 0,
   262            RemoteProtect_SYSTEM   = 1,
   263            RemoteProtect_CUSTOM1  = 2,
   264            RemoteProtect_CUSTOM2  = 3
   265        };
   266    
   267        /*!
   268         *  ======== maxRuntimeEntries ========
   269         *  Maximum runtime entries
   270         *
   271         *  Maximum number of GateMP's that can be dynamically created and
   272         *  added to the NameServer.
   273         *
   274         *  To minimize the amount of runtime allocation, this parameter allows
   275         *  the pre-allocation of memory for the GateMP's NameServer table.
   276         *  The default is to allow growth (i.e. memory allocation when
   277         *  creating a new instance).
   278         */
   279        metaonly config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
   280    
   281        /*!
   282         *  ======== maxNameLen ========
   283         *  Maximum length for names
   284         */
   285        config UInt maxNameLen = 32;
   286    
   287        /*!
   288         *  ======== hostSupport ========
   289         *  Support for host processor
   290         */
   291        metaonly config Bool hostSupport = false;
   292    
   293        /*!
   294         *  ======== tableSection ========
   295         *  Section name is used to place the names table
   296         */
   297        metaonly config String tableSection = null;
   298    
   299        /*!
   300         *  ======== RemoteSystemProxy ========
   301         *  System remote gate proxy
   302         *
   303         *  By default, GateMP instances use the 'System' proxy for locking between
   304         *  multiple processors by setting the 'localProtect' setting to .  This
   305         *  remote gate proxy defaults to a device-specific remote GateMP delegate
   306         *  and typically should not be modified.
   307         */
   308        proxy RemoteSystemProxy inherits IGateMPSupport;
   309    
   310        /*!
   311         *  ======== remoteCustom1Proxy ========
   312         *  Custom1 remote gate proxy
   313         *
   314         *  GateMP instances may use the 'Custom1' proxy for locking between
   315         *  multiple processors.  This proxy defaults to
   316         *  {@link ti.sdo.ipc.gates.GatePeterson}.
   317         */
   318        proxy RemoteCustom1Proxy inherits IGateMPSupport;
   319    
   320        /*!
   321         *  ======== remoteCustom2Proxy ========
   322         *  Custom2 remote gate proxy
   323         *
   324         *  GateMP instances may use the 'Custom2' proxy for locking between
   325         *  multiple processors.  This proxy defaults to
   326         *  {@link ti.sdo.ipc.gates.GateMPSupportNull}.
   327         */
   328        proxy RemoteCustom2Proxy inherits IGateMPSupport;
   329    
   330        /*!
   331         *  ======== createLocal ========
   332         *  @_nodoc
   333         *  Get a local IGateProvider instance
   334         *
   335         *  This function is designed to be used by the IGateMPSupport modules
   336         *  to get a local Gate easily.
   337         */
   338        IGateProvider.Handle createLocal(LocalProtect localProtect);
   339    
   340        /*! @_nodoc
   341         *  ======== attach ========
   342         */
   343        Int attach(UInt16 remoteProcId, Ptr sharedAddr);
   344    
   345        /*! @_nodoc
   346         *  ======== detach ========
   347         */
   348        Int detach(UInt16 remoteProcId);
   349    
   350        /*!
   351         *  ======== getRegion0ReservedSize ========
   352         *  @_nodoc
   353         *  Amount of shared memory to be reserved for GateMP in region 0.
   354         */
   355        SizeT getRegion0ReservedSize();
   356    
   357        /*!
   358         *  ======== setRegion0Reserved ========
   359         *  @_nodoc
   360         *  Set and initialize GateMP reserved memory in Region 0.
   361         */
   362        Void setRegion0Reserved(Ptr sharedAddr);
   363    
   364        /*!
   365         *  ======== openRegion0Reserved ========
   366         *  @_nodoc
   367         *  Open shared memory reserved for GateMP in region 0.
   368         */
   369        Void openRegion0Reserved(Ptr sharedAddr);
   370    
   371        /*!
   372         *  ======== setDefaultRemote ========
   373         *  @_nodoc
   374         *  Set the default Remote Gate. Called by SharedRegion_start().
   375         */
   376         Void setDefaultRemote(Handle handle);
   377    
   378        /*! @_nodoc
   379         *  ======== start ========
   380         */
   381        Int start(Ptr sharedAddr);
   382    
   383        /*! @_nodoc
   384         *  ======== stop ========
   385         */
   386        Int stop();
   387    
   388    instance:
   389    
   390        /*!
   391         *  ======== name ========
   392         *  Name of the instance
   393         *
   394         *  Name needs to be unique. Used only if {@link #useNameServer}
   395         *  is set to TRUE.
   396         */
   397        config String name = null;
   398    
   399        /*! @_nodoc
   400         *  Set to true by the open() call. No one else should touch this!
   401         */
   402        config Bool openFlag = false;
   403    
   404        /*! @_nodoc
   405         *  Set by the open() call. No one else should touch this!
   406         */
   407        config Bits32 resourceId = 0;
   408    
   409        /*!
   410         *  Shared Region Id
   411         *
   412         *  The ID corresponding to the shared region in which this shared instance
   413         *  is to be placed.
   414         */
   415        config UInt16 regionId = 0;
   416    
   417        /*!
   418         *  ======== sharedAddr ========
   419         *  Physical address of the shared memory
   420         *
   421         *  The creator must supply the shared memory that will be used
   422         *  for maintaining shared state information.  This parameter is used
   423         *  only when {@link #Type} is set to {@link #Type_SHARED}
   424         */
   425        config Ptr sharedAddr = null;
   426    
   427        /*!
   428         *  ======== localProtect ========
   429         */
   430        config LocalProtect localProtect = LocalProtect_THREAD;
   431    
   432        /*!
   433         *  ======== localProtect ========
   434         */
   435        config RemoteProtect remoteProtect = RemoteProtect_SYSTEM;
   436    
   437        /*!
   438         *  ======== getSharedAddr ========
   439         *  @_nodoc
   440         *  Return the SRPtr that points to a GateMP instance's shared memory
   441         *
   442         *  getSharedAddr is typically used internally by other IPC modules to save
   443         *  the shared address to a GateMP instance in the other modules' shared
   444         *  state.  This allows the other module's open() call to open the GateMP
   445         *  instance by address.
   446         */
   447        SharedRegion.SRPtr getSharedAddr();
   448    
   449    internal:
   450        const UInt32 VERSION = 1;
   451        const UInt32 CREATED = 0x11202009;
   452    
   453        const Int ProxyOrder_SYSTEM  = 0;
   454        const Int ProxyOrder_CUSTOM1 = 1;
   455        const Int ProxyOrder_CUSTOM2 = 2;
   456        const Int ProxyOrder_NUM     = 3;
   457    
   458        /*!
   459         *  ======== nameSrvPrms ========
   460         *  This Params object is used for temporary storage of the
   461         *  module wide parameters that are for setting the NameServer instance.
   462         */
   463        metaonly config NameServer.Params nameSrvPrms;
   464    
   465        UInt getFreeResource(UInt8 *inUse, Int num, Error.Block *eb);
   466    
   467        struct LocalGate {
   468            IGateProvider.Handle    localGate;
   469            Int                     refCount;
   470        }
   471    
   472        /* Structure of attributes in shared memory */
   473        struct Attrs {
   474            Bits16 mask;
   475            Bits16 creatorProcId;
   476            Bits32 arg;
   477            Bits32 status;                  /* Created stamp                 */
   478        };
   479    
   480        struct Instance_State {
   481            RemoteProtect           remoteProtect;
   482            LocalProtect            localProtect;
   483            Ptr                     nsKey;
   484            Int                     numOpens;
   485            Bool                    cacheEnabled;
   486            Attrs                   *attrs;
   487            UInt16                  regionId;
   488            SizeT                   allocSize;
   489            Ipc.ObjType             objType;
   490            Ptr                     proxyAttrs;
   491            UInt                    resourceId;
   492            IGateProvider.Handle    gateHandle;
   493        };
   494    
   495        struct Module_State {
   496            NameServer.Handle       nameServer;
   497            Int                     numRemoteSystem;
   498            Int                     numRemoteCustom1;
   499            Int                     numRemoteCustom2;
   500            UInt8                   remoteSystemInUse[];
   501            UInt8                   remoteCustom1InUse[];
   502            UInt8                   remoteCustom2InUse[];
   503            Handle                  remoteSystemGates[];
   504            Handle                  remoteCustom1Gates[];
   505            Handle                  remoteCustom2Gates[];
   506            IGateProvider.Handle    gateAll;
   507            IGateProvider.Handle    gateSwi;
   508            IGateProvider.Handle    gateMutexPri;
   509            IGateProvider.Handle    gateNull;
   510            Handle                  defaultGate;
   511            Ptr                     nsKey;
   512            Bool                    hostSupport;
   513            Int                     proxyMap[ProxyOrder_NUM];
   514        };
   515    }