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