1    /* --COPYRIGHT--,BSD
     2     * Copyright (c) $(CPYYEAR), 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     * --/COPYRIGHT--*/
    32    /*
    33     *  ======== NotifyDriverShm.xdc ================
    34     *
    35     *! Revision History
    36     *! ================
    37     *! 01-Feb-2010 skp      Fix SDOCM00066406 (Notify gracefully fail & cleanup)
    38     *! 21-Jan-2010 skp      Fix SDOCM00066064 (misc notify bugs)
    39     *! 18-Dec-2009 skp      Added ROV views
    40     *! 18-Nov-2009 skp      Added 'cacheEnabled' config
    41     *! 16-Nov-2009 skp      'Ctrl' struct removed, many other changes
    42     *! 13-Nov-2009 skp      Removed all callback related stuff from driver
    43     *! 05-Nov-2009 kw       major changes (keep List up in Notify)
    44     *! 31-Jul-2009 skp      static support added
    45     *! 06-Feb-2009 yogesh   modified to incorporate review comments
    46     *! 08-Jan-2009 yogesh   created
    47     */
    48     
    49    import xdc.runtime.Error;
    50    import ti.sdo.utils.MultiProc;
    51    import ti.sdo.ipc.interfaces.INotifyDriver;
    52    import ti.sdo.ipc.notifyDrivers.IInterrupt;
    53    import ti.sdo.ipc.Notify;
    54    
    55    import xdc.rov.ViewInfo;
    56    
    57    /*!
    58     *  ======== NotifyDriverShm ========
    59     *  A shared memory driver for the Notify Module.
    60     *
    61     *  This is a {@link ti.sdo.ipc.Notify} driver that utilizes shared memory
    62     *  and inter-processor hardware interrupts for notification between cores.
    63     *  This driver supports caching and currently expects a cache line size of 128
    64     *  Bytes. Event priorities are supported and correspond to event numbers used
    65     *  to register the events. 
    66     *
    67     *  This driver is designed to work with a variety of devices, each with
    68     *  distinct interrupt mechanisms.  Therefore, this module needs to be plugged
    69     *  with an appropriate module that implements the {@link IInterrupt} interface
    70     *  for a given device.
    71     *
    72     *  The driver utilizes shared memory in the manner indicated by the following
    73     *  diagram.
    74     *
    75     *  @p(code)
    76     *  
    77     *  NOTE: Processors '0' and '1' correspond to the processors with lower and
    78     *        higher MultiProc ids, respectively
    79     *
    80     * sharedAddr -> --------------------------- bytes
    81     *               |  recvInitStatus (0)     | 4  -\
    82     *               |  sendInitStatus (0)     | 4   |= sizeof(ProcCtrl)
    83     *               |  eventRegMask (0)       | 4   |
    84     *               |  eventEnableMask (0)    | 4  -/
    85     *               |  [PADDING] (if needed)  |
    86     *               |-------------------------|
    87     *               |  recvInitStatus (1)     | 4
    88     *               |  sendInitStatus (1)     | 4
    89     *               |  eventRegMask (1)       | 4
    90     *               |  eventEnableMask (1)    | 4
    91     *               |  [PADDING] (if needed)  |
    92     *               |-------------------------|
    93     *               |  eventEntry_0 (0)       | 12 -> sizeof(EventEntry)
    94     *               |  [PADDING] (if needed)  |
    95     *               |-------------------------|
    96     *               |  eventEntry_1 (0)       | 12
    97     *               |  [PADDING] (if needed)  |
    98     *               |-------------------------|
    99     *                       ... ...           
   100     *               |-------------------------|
   101     *               |  eventEntry_N (0)       | 12 
   102     *               |  [PADDING] (if needed)  |
   103     *               |-------------------------|
   104     *               |  eventEntry_0 (1)       | 12
   105     *               |  [PADDING] (if needed)  |
   106     *               |-------------------------|
   107     *               |  eventEntry_1 (1)       | 12
   108     *               |  [PADDING] (if needed)  |
   109     *               |-------------------------|
   110     *                       ... ...            
   111     *               |-------------------------|
   112     *               |  eventEntry_N (1)       | 12
   113     *               |  [PADDING] (if needed)  |
   114     *               |-------------------------|
   115     *
   116     *
   117     *  Legend:
   118     *  (0), (1) : Memory that belongs to the proc with lower and higher 
   119     *             MultiProc.id, respectively
   120     *   |----|  : Cache line boundary
   121     *   N       : Notify_numEvents - 1
   122     *
   123     *  @p
   124     */
   125     
   126    @InstanceInitError
   127    @InstanceFinalize
   128    
   129    module NotifyDriverShm inherits ti.sdo.ipc.interfaces.INotifyDriver
   130    {
   131        /*! @_nodoc */
   132        metaonly struct BasicView {
   133            String      remoteProcName;
   134            Bool        cacheEnabled;
   135        }
   136        
   137        /*! @_nodoc */
   138        metaonly struct EventDataView {
   139            UInt        eventId;
   140            String      procName;
   141            Bool        enabled;
   142            Bool        flagged;
   143            Ptr         payload;
   144        }
   145        
   146        /*!
   147         *  ======== rovViewInfo ========
   148         */
   149        @Facet
   150        metaonly config ViewInfo.Instance rovViewInfo =
   151            ViewInfo.create({
   152                viewMap: [
   153                    ['Basic',
   154                        {
   155                            type: ViewInfo.INSTANCE,
   156                            viewInitFxn: 'viewInitBasic',
   157                            structName: 'BasicView'
   158                        }
   159                    ],
   160                    ['Events',
   161                        {
   162                            type: ViewInfo.INSTANCE_DATA,
   163                            viewInitFxn: 'viewInitData',
   164                            structName: 'EventDataView'
   165                        }
   166                    ],
   167                ]
   168            });
   169    
   170        
   171        /*! @_nodoc
   172         *  IInterrupt proxy that handles interrupts between multiple CPU cores
   173         */
   174        proxy InterruptProxy inherits IInterrupt;
   175        
   176        /*!
   177         *  ======== sharedMemReq ========
   178         *  Amount of shared memory required for creation of each instance
   179         *
   180         *  @param(params)      Pointer to parameters that will be used in the
   181         *                      create
   182         *
   183         *  @a(returns)         Number of MAUs in shared memory needed to create 
   184         *                      the instance.
   185         */
   186        SizeT sharedMemReq(const Params *params);
   187        
   188    instance:
   189    
   190        /*!
   191         *  ======== sharedAddr ========
   192         *  Address in shared memory where this instance will be placed
   193         *
   194         *  Use {@link #sharedMemReq} to determine the amount of shared memory
   195         *  required.
   196         */
   197        config Ptr sharedAddr = null;
   198        
   199        /*!
   200         *  ======== cacheEnabled ========
   201         *  Whether cache operations will be performed
   202         *
   203         *  If it is known that no cache operations are needed for this instance
   204         *  set this flag to FALSE.  If {@link #sharedAddr} lies within a shared
   205         *  region and the cache enabled setting for the region is FALSE,
   206         *  then the value specified here will be overriden to FALSE.
   207         */
   208        config Bool cacheEnabled = true;
   209        
   210        /*!
   211         *  ======== cacheLineSize ========
   212         *  The cache line size of the shared memory
   213         *
   214         *  This value should be configured 
   215         */
   216        config SizeT cacheLineSize = 128;
   217        
   218        /*!
   219         *  ======== remoteProcId ========
   220         *  The MultiProc ID corresponding to the remote processor
   221         *
   222         *  This parameter must be set for every device.  The
   223         *  {@link ti.sdo.utils.MultiProc#getId} call can be used to obtain
   224         *  a MultiProc id given the remote processor's name.
   225         */
   226        config UInt16 remoteProcId = MultiProc.INVALIDID;
   227    
   228        /*!
   229         *  ======== intVectorId ========
   230         *  Interrupt vector ID to be used by the driver.
   231         *
   232         *  This parameter is only used by C64x+ targets
   233         */
   234        config UInt intVectorId = ~1u;
   235    
   236        /*!
   237         *  ======== localIntId ========
   238         *  Local interrupt ID for interrupt line
   239         *
   240         *  For devices that support multiple inter-processor interrupt lines, this
   241         *  configuration parameter allows selecting a specific line to use for
   242         *  receiving an interrupt.  The value specified here corresponds to the
   243         *  incoming interrupt line on the local processor.
   244         *
   245         *  If this configuration is not set, a default interrupt id is 
   246         *  typically chosen.
   247         */
   248        config UInt localIntId = -1u;
   249    
   250        /*!
   251         *  ======== remoteIntId ========
   252         *  Remote interrupt ID for interrupt line
   253         *
   254         *  For devices that support multiple inter-processor interrupt lines, this
   255         *  configuration parameter allows selecting a specific line to use for
   256         *  receiving an interrupt.  The value specified here corresponds to the
   257         *  incoming interrupt line on the remote processor.
   258         *
   259         *  If this configuration is not set, a default interrupt id is 
   260         *  typically chosen.
   261         */
   262        config UInt remoteIntId = -1u;
   263    
   264    internal:
   265    
   266        /*! Flag an event up/down in shared memory */
   267        const UInt16 DOWN = 0;
   268        const UInt16 UP   = 1;
   269    
   270        /*! Initialization stamp */
   271        const UInt32 INIT_STAMP = 0xA9C8B7D6;
   272    
   273        /*! 
   274         *  Plugs the interrupt and executes the callback functions according
   275         *  to event priority
   276         */
   277        Void isr(UArg arg);
   278    
   279        /*! 
   280         *  Used to flag a remote event and determine if a local event has been 
   281         *  flagged. This struct is placed in shared memory. 
   282         */
   283        struct EventEntry {
   284            volatile Bits32 flag;
   285            volatile Bits32 payload;
   286            volatile Bits32 reserved;
   287            /* Padding if necessary */
   288        }
   289    
   290        /*! 
   291         *  NotifyDriverShm state for a single processor in shared memory. 
   292         *  Only the processor that owns this memory may write to it.
   293         *  However, the contents may be read by both processors.
   294         *
   295         *  Two of these structs are place at the base of shared memory. Slots 
   296         *  [0] and [1] are respectively assigned to the processors with the 
   297         *  lower and higher MultiProc ids.
   298         *  
   299         *  Constraints: sizeof(NotifyDriverShm_ProcCtrl) must be a power of two
   300         *               and must be greater than sizeof(NotifyDriverShm_EventEntry)
   301         */
   302        struct ProcCtrl {
   303            volatile Bits32 recvInitStatus;   /* Whether ready to receive events  */
   304            volatile Bits32 sendInitStatus;   /* Whether ready to send events     */
   305            volatile Bits32 eventRegMask;     /* Event Registered mask            */
   306            volatile Bits32 eventEnableMask;  /* Event Enabled mask               */
   307        }
   308    
   309        struct Instance_State {
   310            ProcCtrl         *selfProcCtrl;    /* Control struct for local proc   */
   311            ProcCtrl         *otherProcCtrl;   /* Control struct for remote proc  */
   312            EventEntry       *selfEventChart;  /* flags, payload (local)          */
   313            EventEntry       *otherEventChart; /* flags, payload (remote)         */
   314            Notify.Handle    notifyHandle;     /* Handle to front-end object      */
   315            UInt32           regChart[];       /* Locally track registered events */
   316            UInt             selfId;           /* Which procCtrl to use           */
   317            UInt             otherId;          /* Which procCtrl to use           */
   318            IInterrupt.IntInfo intInfo;        /* Intr info passed to Interr mod  */
   319            UInt16           remoteProcId;     /* Remote MultiProc id             */
   320            UInt             nesting;          /* For disable/restore nesting     */
   321            Bool             cacheEnabled;     /* Whether to perform cache calls  */
   322            SizeT            eventEntrySize;   /* Spacing between event entries   */
   323        }
   324    }