1    /*
     2     * Copyright (c) 2012-2013, 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     *  ======== GatePeterson.xdc ========
    34     *
    35     */
    36    
    37    package ti.sdo.ipc.gates;
    38    
    39    import xdc.runtime.Error;
    40    import xdc.runtime.Assert;
    41    import xdc.runtime.IGateProvider;
    42    import xdc.runtime.Diags;
    43    import xdc.runtime.Log;
    44    import xdc.rov.ViewInfo;
    45    
    46    import ti.sdo.utils.MultiProc;
    47    import ti.sdo.ipc.Ipc;
    48    
    49    import ti.sdo.ipc.interfaces.IGateMPSupport;
    50    
    51    /*!
    52     *  ======== GatePeterson ========
    53     *  IGateMPSupport gate based on the Peterson algorithm
    54     *
    55     *  This module implements the {@link ti.sdo.ipc.interfaces.IGateMPSupport}
    56     *  interface using the Peterson Algorithm in shared memory. This
    57     *  implementation works for only 2 processors.
    58     *
    59     *  Each GatePeterson instance requires a small piece of
    60     *  shared memory.  The base address of this shared memory is specified as
    61     *  the 'sharedAddr' argument to the create. The amount of shared memory
    62     *  consumed by a single instance can be obtained using the
    63     *  {@link #sharedMemReq} call.
    64     *
    65     *  Shared memory has to conform to the following specification.  Padding is
    66     *  added between certain elements in shared memory if cache alignment is
    67     *  required for the region in which the instance is placed.
    68     *
    69     *  @p(code)
    70     *
    71     *              shmBaseAddr -> --------------------------- bytes
    72     *                             |  version                | 4
    73     *              (Attrs struct) |  creatorProcId          | 2
    74     *                             |  openerProcId           | 2
    75     *                             |  (PADDING if aligned)   |
    76     *                             |-------------------------|
    77     *                             |  flag[0]                | 2
    78     *                             |  (PADDING if aligned)   |
    79     *                             |-------------------------|
    80     *                             |  flag[1]                | 2
    81     *                             |  (PADDING if aligned)   |
    82     *                             |-------------------------|
    83     *                             |  turn                   | 2
    84     *                             |  (PADDING if aligned)   |
    85     *                             |-------------------------|
    86     *  @p
    87     */
    88    @InstanceInitError
    89    @InstanceFinalize
    90    
    91    module GatePeterson inherits IGateMPSupport
    92    {
    93        /*! @_nodoc */
    94        metaonly struct BasicView {
    95            String  objType;
    96            Ptr     localGate;
    97            UInt    nested;
    98            UInt    creatorProcId;
    99            UInt    openerProcId;
   100            String  gateOwner;
   101        }
   102    
   103        /*! @_nodoc */
   104        @Facet
   105        metaonly config ViewInfo.Instance rovViewInfo =
   106            ViewInfo.create({
   107                viewMap: [
   108                    ['Basic',
   109                        {
   110                            type: ViewInfo.INSTANCE,
   111                            viewInitFxn: 'viewInitBasic',
   112                            structName: 'BasicView'
   113                        }
   114                    ],
   115                ]
   116            });
   117    
   118        /*!
   119         *  ======== E_gateRemotelyOpened ========
   120         *  Error raised when gate cannot be opened because of the opener's ID
   121         *
   122         *  Error raised in {@link #open} when trying to remotely open a
   123         *  GatePeterson instance whose configured opener processor Id does
   124         *  not match that of the opener's MultiProc id. but it has already been
   125         *  opened/created on two other processors.  GatePeterson only works with
   126         *  two processors.
   127         */
   128        config Error.Id E_gateRemotelyOpened  = {
   129            msg: "E_gateRemotelyOpened: Gate already in use by two other processors: creator: %d, opener: %d"
   130        };
   131    
   132        /*!
   133         *  ======== numInstances ========
   134         *  Maximum number of instances supported by the GatePeterson module
   135         */
   136        config UInt numInstances = 512;
   137    
   138    instance:
   139    
   140        /*!
   141         *  @_nodoc
   142         *  ======== enter ========
   143         *  Enter this gate
   144         */
   145        @DirectCall
   146        override IArg enter();
   147    
   148        /*!
   149         *  @_nodoc
   150         *  ======== leave ========
   151         *  Leave this gate
   152         */
   153        @DirectCall
   154        override Void leave(IArg key);
   155    
   156    internal:
   157    
   158        /* Used for the 'flag' in shared memory */
   159        const UInt32 FREE = 0;
   160        const UInt32 BUSY = 1;
   161    
   162        /* Stored in shared memory */
   163        struct Attrs {
   164            Bits16   creatorProcId;
   165            Bits16   openerProcId;
   166        };
   167    
   168        /* initializes shared memory */
   169        Void postInit(Object *obj);
   170    
   171        struct Instance_State {
   172            Attrs           *attrs;
   173            volatile Bits16 *flag[2];
   174            volatile Bits16 *turn;
   175            UInt16          selfId;
   176            UInt16          otherId;
   177            UInt            nested;    /* For nesting */
   178            IGateProvider.Handle localGate;
   179            Ipc.ObjType     objType;
   180            SizeT           cacheLineSize;
   181            Bool            cacheEnabled;
   182        };
   183    }