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