]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - src/ti/sdo/utils/NameServer.xs
c35933720e352c186cbf67a94db3b6f22d7f24cb
[ipc/ipcdev.git] / src / ti / sdo / utils / NameServer.xs
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.xs ========
34  *
35  */
37 var NameServer = null;
38 var GateSwi    = null;
39 var Memory     = null;
40 var List       = null;
41 var MultiProc  = null;
42 var Settings   = null;
44 /*
45  *  ======== module$meta$init ========
46  */
47 function module$meta$init()
48 {
49     /* Only process during "cfg" phase */
50     if (xdc.om.$name != "cfg") {
51         return;
52     }
54     NameServer = this;
55     NameServer.common$.namedInstance = false;
57     /*
58      *  Plug in the Remote Proxy 'NameServerRemoteNull' by default.
59      *  Ipc will plug in the real Remote Proxy when its used.
60      */
61     NameServer.SetupProxy = xdc.useModule('ti.sdo.utils.NameServerRemoteNull');
62 }
64 /*
65  *  ======== module$use ========
66  */
67 function module$use()
68 {
69     GateSwi    = xdc.useModule("ti.sysbios.gates.GateSwi");
70     Hwi        = xdc.useModule("ti.sysbios.hal.Hwi");
71     Memory     = xdc.useModule("xdc.runtime.Memory");
72     List       = xdc.useModule("ti.sdo.utils.List");
73     MultiProc  = xdc.useModule("ti.sdo.utils.MultiProc");
74     Settings   = xdc.useModule('ti.sdo.ipc.family.Settings');
75 }
77 /*
78  * ======== module$static$init ========
79  */
80 function module$static$init(mod, params)
81 {
82     /* This will result is some code reduction if building whole_program. */
83     if (MultiProc.numProcessors == 1) {
84         NameServer.singleProcessor = true;
85     }
86     else {
87         NameServer.singleProcessor = false;
88     }
90     /* Array of NameServerRemote instances */
91     mod.nsRemoteHandle.length = MultiProc.numProcessors;
93     /* Gate for all NameServer critical regions */
94     mod.gate = GateSwi.create();
95 }
97 /*
98  *  ======== instance$static$init ========
99  *  Initialize instance values.
100  */
101 function instance$static$init(obj, name, params)
103     var index;
104     var numModTable = 0;
105     var numStatic = params.metaTable.length;
107     if (NameServer.metaModTable[name]) {
108         numModTable = NameServer.metaModTable[name].length;
109         var numStatic = params.metaTable.length + numModTable;
110     }
112     /* Fill in the object */
113     obj.name          = name;
114     obj.maxNameLen    = params.maxNameLen;
115     obj.numDynamic    = params.maxRuntimeEntries;
116     obj.checkExisting = params.checkExisting;
117     obj.numStatic     = numStatic;
118     obj.table.length  = numStatic;
119     if (params.tableHeap == null) {
120         obj.tableHeap     = NameServer.common$.instanceHeap;
121     }
122     else {
123         obj.tableHeap     = params.tableHeap;
124     }
126     /* Make sure the minumim size is UInt32 */
127     var target  = Program.build.target;
128     if (params.maxValueLen < target.stdTypes["t_Int32"].size) {
129         obj.maxValueLen  = target.stdTypes["t_Int32"].size;
130     }
131     else {
132         obj.maxValueLen  = params.maxValueLen;
133     }
135     List.construct(obj.nameList);
136     List.construct(obj.freeList);
138     /* Move the metaTable into the object. */
139     for (index = 0; index < params.metaTable.length; index++) {
140         /* Make sure the name and value are not too long */
141         if (this.metaTable[index].len > obj.maxValueLen) {
142             NameServer.$logError("Value length "
143                                  + this.metaTable[index].len
144                                  + " is larger than maxValueLen value of "
145                                  + obj.maxValueLen, this);
146         }
147         if (this.metaTable[index].name.length > obj.maxNameLen) {
148             NameServer.$logError("Name length is of " +
149                                  this.metaTable[index].name.length +
150                                  " is larger than maxNameLen value of " +
151                                  obj.maxNameLen, this);
152         }
154         obj.table[index].name  = this.metaTable[index].name;
155         obj.table[index].len   = this.metaTable[index].len;
156         obj.table[index].value = this.metaTable[index].value;
157         obj.nameList.putMeta(obj.table[index].elem);
158     }
160     /* Move the metaModTable into the object. */
161     for (var k = 0; k < numModTable; k++) {
162         /* Make sure the name and value are no too long */
163         if (NameServer.metaModTable[name][k].len > obj.maxValueLen) {
164             NameServer.$logError("Value length is of "
165                                  + NameServer.metaModTable[name][k].len
166                                  + " is larger than maxValueLen value of "
167                                  + obj.maxValueLen, this);
168         }
169         if (NameServer.metaModTable[name][k].name.length > obj.maxNameLen) {
170             NameServer.$logError("Name length is of " +
171                             + NameServer.metaModTable[name][k].name.length
172                             + " is larger than maxNameLen value of "
173                             + obj.maxNameLen, this);
174         }
176         obj.table[index].name  = NameServer.metaModTable[name][k].name;
177         obj.table[index].len   = NameServer.metaModTable[name][k].len;
178         obj.table[index].value = NameServer.metaModTable[name][k].value;
179         obj.nameList.putMeta(obj.table[index].elem);
180         index++;
181     }
183     this.metaTable.$seal();
185     /* Handle the creation of the runtime entries */
186     if ((obj.numDynamic != 0) && (obj.numDynamic != NameServer.ALLOWGROWTH)) {
187         /* Create the table and place it */
188         obj.table.length += params.maxRuntimeEntries;
190         /*
191          *  Create the block that will contain a copy of the names and
192          *  place it.
193          */
194         obj.names.length  = params.maxRuntimeEntries * params.maxNameLen;
195         Memory.staticPlace(obj.names,  0, params.tableSection);
197         /*
198          *  Create the block that will contain a copy of the values and
199          *  place it.
200          *  If the values are small, simply use the values UArg to store
201          *  the UInt32. Thus no need for the block of memory.
202          */
203         if (params.maxValueLen == target.stdTypes["t_Int32"].size) {
204             obj.values.length = 0;
205         }
206         else {
207             obj.values.length = params.maxRuntimeEntries * params.maxValueLen;
208             Memory.staticPlace(obj.values, 0, params.tableSection);
209         }
211         /*
212          *  Need to fill in all values, else we get an undefined
213          *  The majority of the work in done in the Module_startup.
214          */
215         for (var j = numStatic; j < obj.table.length; j++) {
216             obj.table[j].name  = null;
217             obj.table[j].len   = 0;
218             obj.table[j].value = 0;
219             obj.freeList.putMeta(obj.table[j].elem);
220         }
221     }
222     Memory.staticPlace(obj.table,  0, params.tableSection);
225 /*
226  *  ======== addUInt32Meta ========
227  */
228 function addUInt32Meta(name, value)
230     var target  = Program.build.target;
231     this.addMeta(name, value, target.stdTypes["t_Int32"].size);
234 /*
235  *  ======== modAddMeta ========
236  */
237 function modAddMeta(instName, name, value, len)
239     /* Check to see if NameServer instance already exists */
240     if (!NameServer.metaModTable[instName]) {
241         NameServer.metaModTable[instName] = new NameServer.EntryMap();
242         var instLen = 0;
243     }
244     else {
245         var instLen = NameServer.metaModTable[instName].length;
247         /* Make sure the name does not already exist. */
248         for (var i = 0; i < instLen; i++) {
249             if (name == NameServer.metaModTable[instName][i].name) {
250                 NameServer.$logError("Cannot add \"" + name +
251                                  "\". It already exists.", NameServer);
252             }
253         }
254     }
255     NameServer.metaModTable[instName].length++;
257     /* Add it into this table */
258     NameServer.metaModTable[instName][instLen].name = name;
259     NameServer.metaModTable[instName][instLen].len = len;
260     NameServer.metaModTable[instName][instLen].value = value;
264 /*
265  *  ======== addMeta ========
266  */
267 function addMeta(name, value, len)
269     if (this.metaTable.$sealed() == true) {
270         NameServer.$logError("Cannot add into the NameServer during " +
271                              "this phase (" + xdc.om.$$phase + ")" , this);
272     }
274     NameServer = xdc.module('ti.sdo.utils.NameServer');
276     /* Make sure the name does not already exist. */
277     for (var i = 0; i < this.metaTable.length; i++) {
278         if (name == this.metaTable[i].name) {
279             NameServer.$logError("Cannot add \"" + name +
280                                  "\". It already exists.", this);
281         }
282     }
284     var entry = new NameServer.Entry();
286     entry.name  = name;
287     entry.len   = len;
288     entry.value = value;
290     /* Add it into this table */
291     this.metaTable.$add(entry);
294 /*
295  *  ======== getMeta ========
296  *  Return the entry
297  */
298 function getMeta(name, value)
300     for (var i = 0; i < this.metaTable.length; i++) {
301         if (this.metaTable[i].name == name) {
302             return (this.metaTable[i])
303         }
304     }
307 /*
308  *  ======== viewInitBasic ========
309  *  Processes the 'Basic' view for a NameServer instance.
310  */
311 function viewInitBasic(view, obj)
313     var NameServer = xdc.useModule('ti.sdo.utils.NameServer');
314     var Program = xdc.useModule('xdc.rov.Program');
316     view.name = Program.fetchString(obj.name);
317     view.checkExisting = obj.checkExisting;
318     view.maxNameLen    = obj.maxNameLen;
319     view.maxValueLen   = obj.maxValueLen;
320     view.numStatic     = obj.numStatic;
321     if (obj.numDynamic == 0xffffffff) {
322         view.numDynamic = "ALLOWGROWTH";
323     }
324     else {
325         view.numDynamic = "0x" + Number(obj.numDynamic).toString(16);
326     }
329 /*
330  *  ======== viewInitData ========
331  *  Processes the 'NamesValues' view for a NameServer instance.
332  */
333 function viewInitData(view, obj)
335     /* Retrieve the instance name. */
336     view.label = Program.fetchString(obj.name);
337     view.elements = getNameList(obj);
338     return(view);
341 /*
342  *  ======== getNameList ========
343  */
344 function getNameList(obj)
346     var NameServer      = xdc.useModule('ti.sdo.utils.NameServer');
347     var List            = xdc.useModule('ti.sdo.utils.List');
348     var Program         = xdc.useModule('xdc.rov.Program');
350     var nameList = new Array();
352     /* List Object is the head */
353     var head = obj.nameList.elem;
355     /* Get the first entry on the List */
356     try {
357         // elem is the current element
358         var elem = Program.fetchStruct(List.Elem$fetchDesc, head.next);
359     }
360     catch (error) {
361         view.$status["freeList"] = "Error fetching List Elem struct: " + error.toString(); // TODO freeList -> ?
362         throw (error);
363     }
365     /*
366      * Maintain a map of the entries by their address to
367      * support 'getEntryByKey'.
368      */
369     var data = Program.getPrivateData('ti.sdo.utils.NameServer');
370     if (data.entryMap == undefined) {
371         data.entryMap = {};
372     }
374     /* While the entry is not the head */
375     while (Number(elem.$addr) != Number(head.$addr)) {
376         /* Fetch the next block */
377         try {
378             var nameEntry = Program.fetchStruct(NameServer.TableEntry$fetchDesc,
379                 elem.$addr);
380         }
381         catch (elem) {
382             print("Error: Caught exception from fetchStruct: " +
383                 elem.toString());
384             throw (elem);
385         }
387         /* Add this block to the list */
388         var entry = Program.newViewStruct('ti.sdo.utils.NameServer',
389             'NamesValues');
390         entry.name = Program.fetchString(nameEntry.name);
392         var int32len = Program.build.target.stdTypes["t_Int32"].size;
393         if (obj.maxValueLen > int32len) {
394             entry.value = "[large value]";
395         }
396         else {
397             entry.value = "0x" + Number(nameEntry.value).toString(16);
398         }
399         entry.len = nameEntry.len;
400         entry.nsKey = nameEntry.elem.$addr;
402         /* Add the entry to the view. */
403         nameList[nameList.length] = entry;
405         /* Add the view to the map. */
406         data.entryMap[Number(elem.$addr)] = entry;
408         elem = Program.fetchStruct(List.Elem$fetchDesc, elem.next);
409     }
411     return (nameList);
414 /*
415  *  ======== getNameByKey$view ========
416  *  In ROV, returns a NameServer name given its key.
417  *  Throws an exception if there is no entry at the given address.
418  */
419 function getNameByKey$view(addr)
421     var Program = xdc.useModule('xdc.rov.Program');
423     /*
424      *  Scan the instance view to retrieve all of the entries.
425      *  This function may throw an exception, let it propogate to the caller.
426      */
427     Program.scanInstanceDataView('ti.sdo.utils.NameServer', 'NamesValues');
429     /* Retrieve the private data. */
430     var data = Program.getPrivateData('ti.sdo.utils.NameServer');
432     /* Get the entry from the map. */
433     var entry = data.entryMap[Number(addr)];
435     /* Throw an exception if there's no entry at this address. */
436     if (entry == undefined) {
437         throw (new Error("There is no NameServer entry at the address: 0x" +
438                          Number(addr).toString(16)));
439     }
441     var name = entry.name;
443     return (name);
446 /*
447  *  ======== getName$view ========
448  *  Only used for ROV. Returns a name in a supplied 'tableName' corresponding
449  *  to 'value'.
450  */
451 function getName$view(tableName, value)
453     var name = null;
455     try {
456         var NamesValuesView = Program.scanInstanceDataView(
457             'ti.sdo.utils.NameServer',
458             'NamesValues');
460         for (var i in NamesValuesView) {
461             if (NamesValuesView[i].label == tableName) {
462                 elements = NamesValuesView[i].elements;
463                 for (var j in elements) {
464                     if (elements[j].value == "0x" + value.toString(16)) {
465                         /* elem found */
466                         name = elements[j].name;
467                     }
468                 }
469             }
470         }
471     }
472     catch(e) {
473         var msg = "error when scaning NameServer instance data view: " + e;
474         throw(msg);
475     }
477     return (name);