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     *  ======== MultiProc.xdc ========
    34     *
    35     */
    36    
    37    import xdc.rov.ViewInfo;
    38    
    39    import xdc.runtime.Assert;
    40    
    41    /*!
    42     *  ======== MultiProc ========
    43     *  Processor Id Module Manager
    44     *
    45     *  Many IPC modules require identifying processors in a
    46     *  multi-processor environment. The MultiProc module centralizes
    47     *  processor id management into one module.  Since this configuration
    48     *  is almost always universally required, most IPC applications
    49     *  require supplying configuration of this module.
    50     *
    51     *  Each processor in the MultiProc module may be uniquely identified by
    52     *  either a name string or an integer ranging from 0 to MAXPROCESSORS - 1.
    53     *  Configuration is supplied using the {@link #setConfig} meta function,
    54     *  the {@link #numProcessors} and {@link #baseIdOfCluster}.
    55     *
    56     *  The setConfig function tells the MultiProc module:
    57     *  @p(blist)
    58     *      - The specific processor for which the application is being built
    59     *      - The number of processors in the cluster
    60     *  @p
    61     *
    62     *  A cluster is a set of processors within a system which share some share
    63     *  shared memory and supports notifications. Typically most systems contain
    64     *  one cluster.  When there are multiple clusters in the system, the
    65     *  {@link #numProcessors} and {@link #baseIdOfCluster} configuration
    66     *  paramaters are required to be set before calling {@link #setConfig}
    67     *
    68     *  For examle in a system with 2 C6678 devices [each C6678 contains 8
    69     *  homogeneuous cores].  For first C6678 device:
    70     *  @p(code)
    71     *  var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
    72     *  MultiProc.baseIdOfCluster = 0;
    73     *  MultiProc.numProcessors = 16;
    74     *  MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3",
    75     *                             "CORE4", "CORE5", "CORE6", "CORE7"]);
    76     *  @p
    77     *
    78     *  For second C6678 device:
    79     *  @p(code)
    80     *  var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
    81     *  MultiProc.baseIdOfCluster = 8;
    82     *  MultiProc.numProcessors = 16;
    83     *  MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3",
    84     *                             "CORE4", "CORE5", "CORE6", "CORE7"]);
    85     *  @p
    86     *
    87     *  Using the information supplied using the {@link #setConfig} meta function
    88     *  and the {@link #baseIdOfCluster} module configuration, the processor IDs
    89     *  are internally set.  Please refer to the documentation for
    90     *  {@link #setConfig} and {@link #baseIdOfCluster} for more details.
    91     *
    92     *  At runtime, the {@link #getId} call returns the MultiProc id of those
    93     *  processors within its cluster. At config-time, the {@link #getIdMeta}
    94     *  call returns the the same value.
    95     *
    96     */
    97    
    98    module MultiProc
    99    {
   100        metaonly struct ModuleView {
   101            UInt16       id;                /* Own ID                           */
   102            UInt16       numProcessors;     /* # of processors                  */
   103            String       nameList[];        /* Proc names ordered by procId     */
   104        }
   105    
   106        @Facet
   107        metaonly config ViewInfo.Instance rovViewInfo =
   108            ViewInfo.create({
   109                viewMap: [
   110                [
   111                    'Module',
   112                    {
   113                        type: ViewInfo.MODULE,
   114                        viewInitFxn: 'viewInitModule',
   115                        structName: 'ModuleView'
   116                    }
   117                ],
   118                ]
   119            });
   120    
   121        /*!
   122         *  Assert raised when an invalid processor id is used
   123         */
   124        config Assert.Id A_invalidMultiProcId  = {
   125            msg: "A_invalidMultiProcId: Invalid MultiProc id"
   126        };
   127    
   128        /*!
   129         *  Assert raised when a NULL processor name is encountered
   130         */
   131        config Assert.Id A_invalidProcName  = {
   132            msg: "A_invalidProcName: NULL MultiProc name encountered"
   133        };
   134    
   135        /*!
   136         *  Invalid processor id constant
   137         *
   138         *  This constant denotes that the processor id is not valid.
   139         */
   140        const UInt16 INVALIDID = 0xFFFF;
   141    
   142        /*! @_nodoc
   143         *  ======== nameList ========
   144         *  Unique name for the each processor used in a multi-processor app
   145         *
   146         *  This array should never be set or read directly by the MultiProc user.
   147         *  The nameList is used to store names configuration supplied via the
   148         *  {@link #setConfig} static function.
   149         *
   150         *  At runtime, the {@link #getName} function may be used to retrieve
   151         *  the name of any processor given it's MultiProc id.
   152         */
   153        config String nameList[];
   154    
   155        /*! @_nodoc
   156         *  ======== id ========
   157         *  Unique software id number for the processor
   158         *
   159         *  This value should never be set or read directly by the MultiProc user.
   160         *  Instead, the {@link #getId}, {@link #getIdMeta}, and
   161         *  {@link #setLocalId} calls should be used to respectively retrieve any
   162         *  processors' MultiProc ids or set the local processor's MultiProc id.
   163         */
   164        metaonly config UInt16 id = 0;
   165    
   166        /*! @_nodoc
   167         *  ======== numProcsInCluster ========
   168         *  Number of processors in a cluster
   169         *
   170         *  This parameter should never be set: numProcsInCluster is
   171         *  internally set by the {@link #setConfig} meta function.
   172         *  setConfig statically sets the value of this configuration to the
   173         *  length of the supplied nameList array.
   174         */
   175        config UInt16 numProcsInCluster = 1;
   176    
   177        /*!
   178         *  ======== baseIdOfCluster ========
   179         *  The base id of the cluster.
   180         *
   181         *  Using this base id, the id of each processor in the cluster
   182         *  is set based up its position in {@link #setConfig}. When more
   183         *  more than one cluster exists in the system, this parameter must
   184         *  be set before calling {@link #setConfig}.
   185         */
   186        metaonly config UInt16 baseIdOfCluster = 0;
   187    
   188        /*!
   189         *  ======== numProcessors ========
   190         *  Number of processors in the system
   191         *
   192         *  This configuration should only be set when there is more than one
   193         *  cluster in the system.  It must be set before calling
   194         *  {@link #setConfig}. If the system contains only one cluster,
   195         *  it is internally set by the {@link #setConfig} meta function to the
   196         *  length of the supplied nameList array.
   197         *  After {@link #setConfig} has been  called, it is possible to
   198         *  retrive the maximum # of processors by reading this module config
   199         *  either at run-time or at config time.
   200         */
   201        config UInt16 numProcessors = 1;
   202    
   203        /*! @_nodoc
   204         *  ======== getClusterId ========
   205         */
   206        UInt16 getClusterId(UInt16 procId);
   207    
   208        /*!
   209         *  ======== getIdMeta ========
   210         *  Meta version of {@link #getId}
   211         *
   212         *  Statically returns the internally set ID based on configuration
   213         *  supplied via {@link #setConfig}.
   214         *
   215         *  @param(name)        MultiProc procName
   216         */
   217        metaonly UInt16 getIdMeta(String name);
   218    
   219        /*!
   220         *  ======== getDeviceProcNames ========
   221         *  Returns an array of all possible processor names on the build device
   222         *
   223         *  @(return)           Array of valid MultiProc processor names
   224         */
   225        metaonly Any getDeviceProcNames();
   226    
   227        /*!
   228         *  ======== setConfig ========
   229         *  Configure the MultiProc module
   230         *
   231         *  Configuration of the MultiProc module is primarily accomplished using
   232         *  the setConfig API at config time.  The setConfig API allows the
   233         *  MultiProc module to identify:
   234         *  @p(blist)
   235         *      - Which is the local processor
   236         *      - Which processors are being used
   237         *      - Which processors can synchronize
   238         *  @p
   239         *  The second of these two pieces of information is supplied via the
   240         *  nameList argument.  The nameList is a non-empty set of distinct
   241         *  processors valid for the particular device.  For a list of valid
   242         *  processor names for a given device, please refer to the :
   243         *  {@link ./../ipc/family/doc-files/procNames.html Table of
   244         *   Valid Names for Each Device}.
   245         *
   246         *  The local processor is identified by using a single name from
   247         *  nameList.  A MultiProc id is internally set to the index of
   248         *  'name' in the supplied 'nameList'.  I.e. in the example:
   249         *
   250         *  @p(code)
   251         *  MultiProc.setConfig("DSP", ["HOST", "DSP", "OTHERCORE"]);
   252         *  @p
   253         *
   254         *  The processors, "HOST", "DSP" and "OTHERCORE" get assigned MultiProc
   255         *  IDs 0, 1, and 2, respectively.  The local processor, "DSP" is assigned
   256         *  an ID of '1'.
   257         *
   258         *  If the local processor is not known at static time, it is possible to
   259         *  supply a null name. MultiProc will set the local id to
   260         *  {@link #INVALIDID} until it is set at runtime using
   261         *  MultiProc_setLocalId.
   262         *
   263         *  @param(name)        MultiProc name for the local processor
   264         *  @param(nameList)    Array of all processors used by the application
   265         */
   266        metaonly Void setConfig(String name, String nameList[]);
   267    
   268        /*! @_nodoc
   269         *  ======== getName$view ========
   270         *  ROV-time version of {@link #getName}
   271         */
   272        metaonly String getName$view(UInt id);
   273    
   274        /*! @_nodoc
   275         *  ======== self$view ========
   276         *  ROV-time version of {@link #self}
   277         */
   278        metaonly UInt self$view();
   279    
   280        /*! @_nodoc
   281         *  This is needed to prevent the MultiProc module from being optimized away
   282         *  during the whole_program[_debug] partial link.
   283         */
   284        Void dummy();
   285    
   286    internal:
   287    
   288        /* list of processor id's in cluster */
   289        config UInt16 procIdList[];
   290    
   291        /* id is in Module_State to support the changing of it via setLocalId */
   292        struct Module_State {
   293            UInt16 id;
   294            UInt16 baseIdOfCluster;
   295        };
   296    }