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