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