1    /*
     2     * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
     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     *  ======== NameServer.xdc ========
    34     *
    35     */
    36    
    37    import xdc.runtime.Error;
    38    import xdc.runtime.Assert;
    39    import xdc.runtime.IHeap;
    40    import ti.sysbios.gates.GateSwi;
    41    import xdc.rov.ViewInfo;
    42    
    43    /*!
    44     *  ======== NameServer ========
    45     *  Manages and serves names to remote/local processor
    46     *
    47     *  @p(html)
    48     *  This module has a common header that can be found in the {@link ti.ipc}
    49     *  package.  Application code should include the common header file (not the
    50     *  RTSC-generated one):
    51     *
    52     *  <PRE>#include &lt;ti/ipc/NameServer.h&gt;</PRE>
    53     *
    54     *  The RTSC module must be used in the application's RTSC configuration file
    55     *  (.cfg) if runtime APIs will be used in the application:
    56     *
    57     *  <PRE>NameServer = xdc.useModule('ti.sdo.ipc.NameServer');</PRE>
    58     *
    59     *  Documentation for all runtime APIs, instance configuration parameters,
    60     *  error codes macros and type definitions available to the application
    61     *  integrator can be found in the
    62     *  <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
    63     *  for the IPC product.  However, the documentation presented on this page
    64     *  should be referred to for information specific to the RTSC module, such as
    65     *  module configuration, Errors, and Asserts.
    66     *  @p
    67     *
    68     *  @a(Note)
    69     *  This modules reflects upon the {@link ti.sdo.utils.MultiProc#procAddrMode}
    70     *  configuration parameter. Some internal data structure allocations are
    71     *  optimized for the given processor address mode. For example, when using
    72     *  MultiProc.ProcAddrMode_Global, resource is allocated for every processor
    73     *  in the system. When using MultiProc.ProcAddrMode_Cluster, resources are
    74     *  only allocated for processors in the cluster. A side-effect is that when
    75     *  using Cluster mode, name queries cannot be addressed to processors
    76     *  outside of the cluster.
    77     */
    78    
    79    @ModuleStartup
    80    @InstanceInitError /* Initialization may throw errors */
    81    @InstanceFinalize
    82    
    83    module NameServer
    84    {
    85        /*!
    86         *  ======== BasicView ========
    87         *  @_nodoc
    88         */
    89        metaonly struct BasicView {
    90            String  name;
    91            Bool    checkExisting;
    92            UInt    maxNameLen;
    93            UInt    maxValueLen;
    94            UInt    numStatic;
    95            String  numDynamic;
    96        }
    97    
    98        /*!
    99         *  ======== NamesListView ========
   100         *  @_nodoc
   101         */
   102        metaonly struct NamesListView {
   103            String  name;
   104            String  value;
   105            UInt    len;
   106            Ptr     nsKey;
   107        }
   108    
   109        /*!
   110         *  ======== rovViewInfo ========
   111         *  @_nodoc
   112         */
   113        @Facet
   114        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
   115            xdc.rov.ViewInfo.create({
   116                viewMap: [
   117                    ['Basic',
   118                        {
   119                            type: xdc.rov.ViewInfo.INSTANCE,
   120                            viewInitFxn: 'viewInitBasic',
   121                            structName: 'BasicView'
   122                        }
   123                    ],
   124                    ['NamesValues',
   125                        {
   126                            type: xdc.rov.ViewInfo.INSTANCE_DATA,
   127                            viewInitFxn: 'viewInitData',
   128                            structName: 'NamesListView'
   129                        }
   130                    ]
   131                ]
   132            });
   133    
   134        /*!
   135         *  Assert raised when the name or value is too long
   136         */
   137        config Assert.Id A_invalidLen  = {
   138            msg: "A_invalidLen: Invalid length"
   139        };
   140    
   141        /*!
   142         *  ======== A_invArgument ========
   143         *  Assert raised when an argument is invalid
   144         */
   145        config Assert.Id A_invArgument  = {
   146            msg: "A_invArgument: Invalid argument supplied"
   147        };
   148    
   149        /*!
   150         *  Error raised if all the entries in the instance Name/Value table
   151         *  are taken
   152         */
   153        config Error.Id E_maxReached  = {
   154            msg: "E_maxReached: All entries in use. NameServer.maxRuntimeEntries is %d"
   155        };
   156    
   157        /*!
   158         *  Error raised when the name already exists in the instance
   159         *  Name/Value table
   160         */
   161        config Error.Id E_entryExists  = {
   162            msg: "E_entryExists: %s name already in table "
   163        };
   164    
   165        /*!
   166         *  Error raised when creation parameters do not match those of an
   167         *  existing NameServer
   168         */
   169        config Error.Id E_paramMismatch  = {
   170            msg: "E_paramMismatch: parameters do not match existing NameServer %s "
   171        };
   172    
   173        /*!
   174         *  Allow dynamic growth of the NameServer instance table
   175         *
   176         *  This value can be used to set the {@link #maxRuntimeEntries}.
   177         *  This flag tells NameServer to allow dynamic growth
   178         *  of the table.
   179         */
   180        const UInt ALLOWGROWTH = (~0);
   181    
   182        /*!
   183         *  Structure of entry in Name/Value table
   184         *
   185         *  This structure is returned from the {@link #getMeta}
   186         *  API.
   187         *
   188         *  @field(name)  Name portion of the name/value pair.
   189         *  @field(len)   Length of the value field.
   190         *  @field(value) Value portion of the name/value entry.
   191         */
   192        metaonly struct Entry {
   193            String      name;
   194            UInt        len;
   195            UArg        value;
   196        };
   197    
   198        /*!
   199         *  ======== SetupProxy ========
   200         *  NameServer setup proxy
   201         */
   202        proxy SetupProxy inherits INameServerRemote;
   203    
   204        /*!
   205         *  ======== isRegistered ========
   206         *  Determines if a remote driver is registered for the specified id.
   207         *
   208         *  @param(procId)  The remote processor id.
   209         */
   210        @DirectCall
   211        Bool isRegistered(UInt16 procId);
   212    
   213        /*!
   214         *  ======== registerRemoteDriver ========
   215         *  Register the NameServer remote handle for the specified processor id.
   216         *
   217         *  This function is used by NameServer remote driver to register
   218         *  themselves with NameServer. Only one remote driver can be registered
   219         *  with a remote processor. The API returns {@link #Status_FAIL} if there
   220         *  is already a registered remote driver for the processor id.
   221         *
   222         *  @param(handle)  The handle for a NameServer remote driver instance.
   223         *  @param(procId)  The remote processor id.
   224         *
   225         *  @b(returns)     Returns {@link #Status_SUCCESS} if successful or
   226         *                  {@link #Status_FAIL} if the processor id has already
   227         *                  been set.
   228         */
   229        @DirectCall
   230        Int registerRemoteDriver(INameServerRemote.Handle handle, UInt16 procId);
   231    
   232        /*!
   233         *  ======== unregisterRemoteDriver ========
   234         *  Unregister the NameServer remote handle for the specified processor id.
   235         *
   236         *  This function is used by NameServer Remote implementations to unregister
   237         *  themselves with NameServer.
   238         *
   239         *  @param(procId)  The remote processor id to unregister.
   240         */
   241        @DirectCall
   242        Void unregisterRemoteDriver(UInt16 procId);
   243    
   244        /*!
   245         *  ======== modAddMeta ========
   246         *  Add a name/value pair into the specified instance's table during
   247         *  configuration
   248         *
   249         *  This function adds any length value into the local table. The function
   250         *  makes sure the name does not already exist in the local table.
   251         *
   252         *  This function should be used by modules when adding into a NameServer
   253         *  instance. The application configuration file, should
   254         *  use {@link #addMeta}.
   255         *
   256         *  The function does not query remote processors to make sure the
   257         *  name is unique.
   258         *
   259         *  @param(instName)   NameServer instance name
   260         *  @param(name)       Name portion of the name/value pair
   261         *  @param(value)      Value portion of the name/value pair
   262         *  @param(len)        Length of the value buffer
   263         */
   264        metaonly Void modAddMeta(String instName, String name, Any value, UInt len);
   265    
   266        /*!
   267         *  ======== getName$view ========
   268         *  @_nodoc
   269         *  Used at ROV time to display reverse-lookup name from 32-bit value and
   270         *  tableName
   271         */
   272        metaonly String getName$view(String tableName, UInt32 value);
   273    
   274        /*!
   275         *  ======== getNameByKey$view ========
   276         *  @_nodoc
   277         *  ROV function for retrieving an entry by its address. Throws an exception
   278         *  if the name was not found
   279         */
   280        metaonly String getNameByKey$view(Ptr addr);
   281    
   282    
   283    instance:
   284    
   285        /*!
   286         *  Maximum number of name/value pairs that can be dynamically created.
   287         *
   288         *  This parameter allows NameServer to pre-allocate memory.
   289         *  When NameServer_add or NameServer_addUInt32 is called, no memory
   290         *  allocation occurs.
   291         *
   292         *  If the number of pairs is not known at configuration time, set this
   293         *  value to {@link #ALLOWGROWTH}. This instructs NameServer to grow the
   294         *  table as needed. NameServer will allocate memory from the
   295         *  {@link #tableHeap} when a name/value pair is added.
   296         *
   297         *  The default is {@link #ALLOWGROWTH}.
   298         */
   299        config UInt maxRuntimeEntries = ALLOWGROWTH;
   300    
   301        /*!
   302         *  Name/value table is allocated from this heap.
   303         *
   304         *  The instance table and related buffers are allocated out of this heap
   305         *  during the dynamic create. This heap is also used to allocate new
   306         *  name/value pairs when {@link #ALLOWGROWTH} for
   307         *  {@link #maxRuntimeEntries}
   308         *
   309         *  The default is to use the same heap that instances are allocated
   310         *  from which can be configured via the
   311         *  NameServer.common$.instanceHeap configuration parameter.
   312         */
   313        config IHeap.Handle tableHeap = null;
   314    
   315        /*!
   316         *  Name/value table is placed into this section on static creates.
   317         *
   318         *  The instance table and related buffers are placed into this section
   319         *  during the static create.
   320         *
   321         *  The default is no explicit section placement.
   322         */
   323        metaonly config String tableSection = null;
   324    
   325        /*!
   326         *  Check if a name already exists in the name/value table.
   327         *
   328         *  When a name/value pair is added during runtime, if this boolean is true,
   329         *  the table is searched to see if the name already exists. If it does,
   330         *  the name is not added and the {@link #E_entryExists} error is raised.
   331         *
   332         *  If this flag is false, the table will not be checked to see if the name
   333         *  already exists. It will simply be added. This mode has better
   334         *  performance at the expense of potentially having non-unique names in the
   335         *  table.
   336         *
   337         *  This flag is used for runtime adds only. Adding non-unique names during
   338         *  configuration results in a build error.
   339         */
   340        config Bool checkExisting = true;
   341    
   342        /*!
   343         *  Length, in MAUs, of the value field in the table.
   344         *
   345         *  Any value less than sizeof(UInt32) will be rounded up to sizeof(UInt32).
   346         */
   347        config UInt maxValueLen = 0;
   348    
   349        /*!
   350         *  Length, in MAUs, of the name field in the table.
   351         *
   352         *  The maximum length of the name portion of the name/value
   353         *  pair. The length includes the null terminator ('\0').
   354         */
   355        config UInt maxNameLen = 16;
   356    
   357        /*!
   358         *  ======== metaTable ========
   359         *  @_nodoc
   360         *  Table to hold the statically added name/value pairs until
   361         *  they ready to be added to the object.
   362         */
   363        metaonly config Entry metaTable[];
   364    
   365       /*!
   366         *  ======== create ========
   367         *  @_nodoc (Refer to doxygen for ti/ipc/NameServer.h)
   368         *  Create a NameServer instance
   369         *
   370         *  This function creates a NameServer instance. The name is
   371         *  used for remote processor queries and diagnostic tools. For
   372         *  single processor system (e.g. no remote queries), the name
   373         *  can be NULL.
   374         *
   375         *  @param(name)    Name of the instance
   376         */
   377        create(String name);
   378    
   379        /*!
   380         *  ======== addUInt32Meta ========
   381         *  Add a name/value pair into the instance's table during configuration
   382         *
   383         *  This function adds a UInt32 value into the local table. The function
   384         *  makes sure the name does not already exist in the local table.
   385         *
   386         *  The function does not query remote processors to make sure the
   387         *  name is unique.
   388         *
   389         *  @param(name)   Name portion of the name/value pair
   390         *  @param(value)  Value portion of the name/value pair
   391         */
   392        metaonly Void addUInt32Meta(String name, any value);
   393    
   394        /*!
   395         *  ======== addMeta ========
   396         *  Add a name/value pair into the instance's table during configuration
   397         *
   398         *  This function adds any length value into the local table. The function
   399         *  makes sure the name does not already exist in the local table.
   400         *
   401         *  This function should be used by within the application configuration
   402         *  file. XDC modules should use {@link #modAddMeta}.
   403         *
   404         *  The function does not query remote processors to make sure the
   405         *  name is unique.
   406         *
   407         *  @param(name)   Name portion of the name/value pair
   408         *  @param(value)  Value portion of the name/value pair
   409         *  @param(len)    Length of the value buffer
   410         */
   411        metaonly Void addMeta(String name, Any value, UInt len);
   412    
   413        /*!
   414         *  ======== getMeta ========
   415         *  Retrieves the name/value entry
   416         *
   417         *  If the name is found, the entry is returned. The caller can parse the
   418         *  entry as needed. If the name is not found, null is returned.
   419         *
   420         *  The search only occurs on the local table.
   421         *
   422         *  @param(name)     Name in question
   423         *
   424         *  @b(returns)      Name/value entry
   425         */
   426        metaonly Entry getMeta(String name);
   427    
   428        /*!
   429         *  ======== getKey ========
   430         *  @_nodoc
   431         *  Returns a pointer to the TableEntry containing the argument 'val'.
   432         *  This should only be used internally by Ipc modules during their
   433         *  initialization process.
   434         *
   435         *  This function can only be used when maxValueLen = sizeof(UInt32)
   436         */
   437        @DirectCall
   438        Ptr getKey(UInt32 val);
   439    
   440    internal:
   441    
   442        /* Used to eliminate code when doing whole-program */
   443        config Bool singleProcessor = true;
   444    
   445        metaonly typedef Entry EntryMap[];
   446    
   447        /*! Structure of entry in Name/Value table */
   448        struct TableEntry {
   449            List.Elem   elem;
   450            String      name;
   451            UInt        len;
   452            UArg        value;
   453        };
   454    
   455        /*!
   456         *  ======== metaModTable ========
   457         *  Table to hold the static added name/value pairs until
   458         *  they ready to be added to the object.
   459         */
   460        metaonly config EntryMap metaModTable[string];
   461    
   462        /*
   463         *  ======== postInit ========
   464         *  Finish initializing static and dynamic NameServer instances
   465         */
   466        Int postInit(Object *obj);
   467    
   468        /*
   469         *  ======== findLocal ========
   470         *  Searches to the local instance table.
   471         *
   472         *  This is an internal function because it returns an internal structure.
   473         */
   474        TableEntry *findLocal(Object *obj, String name);
   475    
   476        /*
   477         *  ======== removeLocal ========
   478         *  removes an entry from the local instance table.
   479         */
   480        Void removeLocal(Object *obj, TableEntry *entry);
   481    
   482        /*
   483         *  ======== editLocal ========
   484         *  replaces the value of an entry from the local instance table.
   485         */
   486        Void editLocal(Object *obj, TableEntry *entry, Ptr newValue);
   487    
   488        /* instance object */
   489        struct Instance_State {
   490            String       name;           /* Name of the instance           */
   491            List.Object  freeList;       /* Empty entries list             */
   492            List.Object  nameList;       /* Filled entries list            */
   493            UInt         maxNameLen;     /* Max name length                */
   494            UInt         maxValueLen;    /* Max value length               */
   495            UInt         numStatic;      /* Total static entries in table  */
   496            UInt         numDynamic;     /* Total dynamic entries in table */
   497            TableEntry   table[];        /* Table                          */
   498            Char         names[];        /* Buffer for names               */
   499            UInt8        values[];       /* Buffer for values              */
   500            IHeap.Handle tableHeap;      /* Heap used to alloc table       */
   501            Bool         checkExisting;  /* check ig name already exists   */
   502            UInt32       refCount;       /* reference count to this instance */
   503        };
   504    
   505        struct Module_State {
   506            INameServerRemote.Handle nsRemoteHandle[length];
   507            GateSwi.Handle gate;
   508        };
   509    }