1    /* 
     2     * Copyright (c) 2011, 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     *  ======== NotifyDriverCirc.xdc ================
    34     */
    35    
    36    import ti.sdo.utils.MultiProc;
    37    import ti.sdo.ipc.interfaces.INotifyDriver;
    38    import ti.sdo.ipc.notifyDrivers.IInterrupt;
    39    import ti.sdo.ipc.Notify;
    40    
    41    import xdc.rov.ViewInfo;
    42    
    43    /*!
    44     *  ======== NotifyDriverCirc ========
    45     *  A shared memory driver using circular buffer for the Notify Module.
    46     *
    47     *  This is a {@link ti.sdo.ipc.Notify} driver that utilizes shared memory
    48     *  and inter-processor hardware interrupts for notification between cores.
    49     *  This driver supports caching.
    50     *
    51     *  This driver is designed to work with a variety of devices, each with
    52     *  distinct interrupt mechanisms.  Therefore, this module needs to be plugged
    53     *  with an appropriate module that implements the {@link IInterrupt} interface
    54     *  for a given device.
    55     *
    56     *  The driver utilizes shared memory in the manner indicated by the following
    57     *  diagram.
    58     *
    59     *  @p(code)
    60     *  
    61     *  NOTE: Processors '0' and '1' correspond to the processors with lower and
    62     *        higher MultiProc ids, respectively
    63     *
    64     * sharedAddr -> --------------------------- bytes
    65     *               |  eventEntry0  (0)       | 8  
    66     *               |  eventEntry1  (0)       | 8
    67     *               |  ...                    | 
    68     *               |  eventEntry15 (0)       | 8
    69     *               |  [align to cache size]  |
    70     *               |-------------------------|
    71     *               |  eventEntry16 (0)       | 8
    72     *               |  eventEntry17 (0)       | 8
    73     *               |  ...                    | 
    74     *               |  eventEntry31 (0)       | 8
    75     *               |  [align to cache size]  |
    76     *               |-------------------------|
    77     *               |  putWriteIndex (0)      | 4
    78     *               |  [align to cache size]  |
    79     *               |-------------------------|
    80     *               |  putReadIndex (0)       | 4
    81     *               |  [align to cache size]  |
    82     *               |-------------------------|
    83     *               |  eventEntry0  (1)       | 8  
    84     *               |  eventEntry1  (1)       | 8
    85     *               |  ...                    | 
    86     *               |  eventEntry15 (1)       | 8
    87     *               |  [align to cache size]  |
    88     *               |-------------------------|
    89     *               |  eventEntry16 (1)       | 8
    90     *               |  eventEntry17 (1)       | 8
    91     *               |  ...                    | 
    92     *               |  eventEntry31 (1)       | 8
    93     *               |  [align to cache size]  |
    94     *               |-------------------------|
    95     *               |  getWriteIndex (1)      | 4
    96     *               |  [align to cache size]  |
    97     *               |-------------------------|
    98     *               |  getReadIndex (1)       | 4
    99     *               |  [align to cache size]  |
   100     *               |-------------------------|
   101     *
   102     *
   103     *  Legend:
   104     *  (0), (1) : Memory that belongs to the proc with lower and higher 
   105     *             MultiProc.id, respectively
   106     *   |----|  : Cache line boundary
   107     *
   108     *  @p
   109     */
   110    
   111    @InstanceFinalize
   112    
   113    module NotifyDriverCirc inherits ti.sdo.ipc.interfaces.INotifyDriver
   114    {
   115        /*! @_nodoc */
   116        metaonly struct BasicView {
   117            String      remoteProcName;
   118            Bool        cacheEnabled;
   119            UInt        bufSize;
   120            UInt        spinCount;
   121            UInt        maxSpinWait;
   122        }
   123        
   124        /*! @_nodoc */
   125        metaonly struct EventDataView {
   126            UInt        index;
   127            String      buffer;
   128            Ptr         addr;
   129            UInt        eventId;
   130            Ptr         payload;
   131        }
   132        
   133        /*!
   134         *  ======== rovViewInfo ========
   135         */
   136        @Facet
   137        metaonly config ViewInfo.Instance rovViewInfo =
   138            ViewInfo.create({
   139                viewMap: [
   140                    ['Basic',
   141                        {
   142                            type: ViewInfo.INSTANCE,
   143                            viewInitFxn: 'viewInitBasic',
   144                            structName: 'BasicView'
   145                        }
   146                    ],
   147                    ['Events',
   148                        {
   149                            type: ViewInfo.INSTANCE_DATA,
   150                            viewInitFxn: 'viewInitData',
   151                            structName: 'EventDataView'
   152                        }
   153                    ],
   154                ]
   155            });
   156    
   157        
   158        /*! @_nodoc
   159         *  IInterrupt proxy that handles interrupts between multiple CPU cores
   160         */
   161        proxy InterruptProxy inherits IInterrupt;
   162        
   163        /*!
   164         *  ======== enableStats ========
   165         *  Enable statistics for sending an event
   166         *
   167         *  If this parameter is to 'TRUE' and 'waitClear' is also set to
   168         *  TRUE when calling (@link #sendEvent(), then the module keeps
   169         *  track of the number of times the processor spins waiting for
   170         *  an empty slot and the max amount of time it waits.
   171         */
   172        config Bool enableStats = false;
   173        
   174        /*!
   175         *  ======== numMsgs ========
   176         *  The number of messages or slots in the circular buffer
   177         *
   178         *  This is use to determine the size of the put and get buffers.
   179         *  Each eventEntry is two 32bits wide, therefore the total size
   180         *  of each circular buffer is [numMsgs * sizeof(eventEntry)].
   181         *  The total size of each buffer must be a multiple of the 
   182         *  the cache line size. For example, if the cacheLineSize = 128
   183         *  then numMsgs could be 16, 32, etc...
   184         */
   185        config UInt numMsgs = 32;
   186        
   187        /*!
   188         *  ======== sharedMemReq ========
   189         *  Amount of shared memory required for creation of each instance
   190         *
   191         *  @param(params)      Pointer to parameters that will be used in the
   192         *                      create
   193         *
   194         *  @a(returns)         Number of MAUs in shared memory needed to create 
   195         *                      the instance.
   196         */
   197        SizeT sharedMemReq(const Params *params);
   198        
   199    instance:
   200    
   201        /*!
   202         *  ======== sharedAddr ========
   203         *  Address in shared memory where this instance will be placed
   204         *
   205         *  Use {@link #sharedMemReq} to determine the amount of shared memory
   206         *  required.
   207         */
   208        config Ptr sharedAddr = null;
   209    
   210        /*!
   211         *  ======== cacheEnabled ========
   212         *  Whether cache operations will be performed
   213         *
   214         *  If it is known that no cache operations are needed for this instance
   215         *  set this flag to FALSE.  If {@link #sharedAddr} lies within a shared
   216         *  region and the cache enabled setting for the region is FALSE,
   217         *  then the value specified here will be overriden to FALSE.
   218         */
   219        config Bool cacheEnabled = true;
   220        
   221        /*!
   222         *  ======== cacheLineSize ========
   223         *  The cache line size of the shared memory
   224         *
   225         *  This value should be configured 
   226         */
   227        config SizeT cacheLineSize = 128;
   228        
   229        /*!
   230         *  ======== remoteProcId ========
   231         *  The MultiProc ID corresponding to the remote processor
   232         *
   233         *  This parameter must be set for every device.  The
   234         *  {@link ti.sdo.utils.MultiProc#getId} call can be used to obtain
   235         *  a MultiProc id given the remote processor's name.
   236         */
   237        config UInt16 remoteProcId = MultiProc.INVALIDID;
   238    
   239        /*!
   240         *  ======== intVectorId ========
   241         *  Interrupt vector ID to be used by the driver.
   242         *
   243         *  This parameter is only used by C64x+ targets
   244         */
   245        config UInt intVectorId = ~1u;
   246    
   247        /*!
   248         *  ======== localIntId ========
   249         *  Local interrupt ID for interrupt line
   250         *
   251         *  For devices that support multiple inter-processor interrupt lines, this
   252         *  configuration parameter allows selecting a specific line to use for
   253         *  receiving an interrupt.  The value specified here corresponds to the
   254         *  incoming interrupt line on the local processor.
   255         *
   256         *  If this configuration is not set, a default interrupt id is 
   257         *  typically chosen.
   258         */
   259        config UInt localIntId = -1u;
   260    
   261        /*!
   262         *  ======== remoteIntId ========
   263         *  Remote interrupt ID for interrupt line
   264         *
   265         *  For devices that support multiple inter-processor interrupt lines, this
   266         *  configuration parameter allows selecting a specific line to use for
   267         *  receiving an interrupt.  The value specified here corresponds to the
   268         *  incoming interrupt line on the remote processor.
   269         *
   270         *  If this configuration is not set, a default interrupt id is 
   271         *  typically chosen.
   272         */
   273        config UInt remoteIntId = -1u;
   274    
   275    internal:
   276    
   277        /*! The max index set to (numMsgs - 1) */
   278        config UInt maxIndex;
   279        
   280        /*!
   281         *  The modulo index value. Set to (numMsgs / 4).
   282         *  Used in the isr for doing cache_wb of readIndex.
   283         */
   284        config UInt modIndex;
   285        
   286        /*! 
   287         *  Plugs the interrupt and executes the callback functions according
   288         *  to event priority
   289         */
   290        Void isr(UArg arg);
   291    
   292        /*! 
   293         *  Structure for each event. This struct is placed in shared memory.
   294         */
   295        struct EventEntry {
   296            volatile Bits32 eventid;
   297            volatile Bits32 payload;
   298        }
   299    
   300        /*! Instance state structure */
   301        struct Instance_State {
   302            EventEntry       *putBuffer;     /* buffer used to put events        */
   303            Bits32           *putReadIndex;  /* ptr to readIndex for put buffer  */
   304            Bits32           *putWriteIndex; /* ptr to writeIndex for put buffer */
   305            EventEntry       *getBuffer;     /* buffer used to get events        */
   306            Bits32           *getReadIndex;  /* ptr to readIndex for get buffer  */
   307            Bits32           *getWriteIndex; /* ptr to writeIndex for put buffer */
   308            Bits32           evtRegMask;     /* local event register mask        */
   309            SizeT            opCacheSize;    /* optimized cache size for wb/inv  */
   310            UInt32           spinCount;      /* number of times sender waits     */
   311            UInt32           spinWaitTime;   /* largest wait time for sender     */
   312            Notify.Handle    notifyHandle;   /* Handle to front-end object       */
   313            IInterrupt.IntInfo intInfo;      /* Intr info passed to Interr mod   */
   314            UInt16           remoteProcId;   /* Remote MultiProc id              */
   315            Bool             cacheEnabled;   /* set by param or SharedRegion     */
   316        }
   317    }
   318    /*
   319     *  @(#) ti.sdo.ipc.notifyDrivers; 1, 0, 0, 0,398; 6-18-2011 17:33:12; /db/vtree/library/trees/ipc/ipc.git/src/ ipc-g26
   320     */
   321