d7df795535beaf09ba55a5b2d785d24379a5c461
[ipc/ipcdev.git] / packages / ti / sdo / ipc / MessageQ.xdc
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  *  ======== MessageQ.xdc ========
34  *
35  */
37 package ti.sdo.ipc;
39 import xdc.runtime.IHeap;
40 import xdc.runtime.Assert;
41 import xdc.runtime.Error;
42 import xdc.runtime.Diags;
43 import xdc.runtime.Log;
44 import xdc.runtime.IGateProvider;
45 import xdc.runtime.knl.ISync;
47 import ti.sysbios.syncs.SyncSem;
49 import ti.sdo.ipc.interfaces.ITransport;
50 import ti.sdo.ipc.interfaces.IMessageQTransport;
51 import ti.sdo.utils.NameServer;
52 import ti.sdo.utils.List;
54 import xdc.rov.ViewInfo;
56 /*!
57  *  ======== MessageQ ========
58  *  Message-passing with queuing
59  *
60  *  The MessageQ module supports the structured sending and receiving of
61  *  variable length messages. This module can be used for homogeneous
62  *  (DSP to DSP)  or heterogeneous (Arm to DSP) multi-processor messaging.
63  *
64  *  MessageQ provides more sophisticated messaging than other modules. It is
65  *  typically used for complex situations such as multi-processor messaging.
66  *
67  *  The following are key features of the MessageQ module:
68  *  @p(blist)
69  *  -Writers and readers can be relocated to another processor with no
70  *   runtime code changes.
71  *  -Timeouts are allowed when receiving messages.
72  *  -Readers can determine the writer and reply back.
73  *  -Receiving a message is deterministic when the timeout is zero.
74  *  -Messages can reside on any message queue.
75  *  -Supports zero-copy transfers.
76  *  -Can send and receive from any type of thread.
77  *  -Notification mechanism is specified by application.
78  *  -Allows QoS (quality of service) on message buffer pools. For example,
79  *   using specific buffer pools for specific message queues.
80  *  @p
81  *
82  *  Messages are sent and received by being placed on and removed from a
83  *  message queue. A reader is a thread that gets (reads) messages from a
84  *  message queue. A writer is a thread that puts (writes) a message to a
85  *  message queue. Each message queue has one reader and can have many writers.
86  *  A thread may read from or write to multiple message queues.
87  *
88  *  Conceptually, the reader thread owns a message queue. The reader thread
89  *  creates a message queue. The writer threads open a created message queue
90  *  to get access to them.
91  *
92  *  Message queues are identified by a system-wide unique name. Internally,
93  *  MessageQ uses the {@link ti.sdo.utils.NameServer} module for managing
94  *  these names. The names are used for opening a message queue.
95  *
96  *  Messages must be allocated from the MessageQ module. Once a message is
97  *  allocated, it can be sent to any message queue. Once a message is sent, the
98  *  writer loses ownership of the message and should not attempt to modify the
99  *  message. Once the reader receives the message, it owns the message. It
100  *  may either free the message or re-use the message.
101  *
102  *  Messages in a message queue can be of variable length. The only
103  *  requirement is that the first field in the definition of a message must be a
104  *  {@link #MsgHeader} structure. For example:
105  *  @p(code)
106  *  typedef struct MyMsg {
107  *      MessageQ_MsgHeader header;
108  *      ...
109  *  } MyMsg;
110  *  @p
111  *
112  *  The MessageQ API uses the MessageQ_MsgHeader internally. Your application
113  *  should not modify or directly access the fields in the MessageQ_MsgHeader.
114  *
115  *  All messages sent via the MessageQ module must be allocated from a
116  *  {@link xdc.runtime.IHeap} implementation. The heap can also be used for
117  *  other memory allocation not related to MessageQ.
118  *
119  *  An application can use multiple heaps. The purpose of having multiple
120  *  heaps is to allow an application to regulate its message usage. For
121  *  example, an application can allocate critical messages from one heap of fast
122  *  on-chip memory and non-critical messages from another heap of slower
123  *  external memory.
124  *
125  *  The {@link #registerHeap} and {@link #registerHeapMeta} are APIs used to
126  *  assign a MessageQ heapId to a heap. When allocating a message, the heapId
127  *  is used, not the heap handle. This heapId is actually placed into the
128  *  message (part of the {@link #MsgHeader}). Care must be taken when assigning
129  *  heapIds. Refer to the {@link #registerHeap} and {@link #registerHeapMeta}
130  *  descriptions for more details.
131  *
132  *  MessageQ also supports the usage of messages that are not allocated via the
133  *  {@link #alloc} function. Please refer to the {@link #staticMsgInit}
134  *  function description for more details.
135  *
136  *  MessageQ supports reads/writes of different thread models. This is
137  *  accomplished by having the creator of the message queue specify a
138  *  {@link xdc.runtime.knl.ISync#Object} via the {@link #synchronizer}
139  *  configuration parameter. The {@link xdc.runtime.knl.ISync#signal}
140  *  portion of the ISync instance is called whenever the {@link #put}
141  *  is called. The {@link xdc.runtime.knl.ISync#wait} portion is
142  *  called in the {@link #get} if and only if there are no messages.
143  *
144  *  Since ISyncs are binary, the reader must drain the message queue of all
145  *  messages before waiting for another signal. For example, if the reader
146  *  was a SYSBIOS Swi, the {@link xdc.runtime.knl.ISync} instance
147  *  could be a SyncSwi. If a {@link #put} was called, the Swi_post() would
148  *  be called. The Swi would run and it must call {@link #get} until no
149  *  messages are returned.
150  *
151  *  In a multiple processor system, MessageQ communicates to other
152  *  processors via {@link ti.sdo.ipc.interfaces.IMessageQTransport} instances.
153  *  MessageQ supports a high priority and a normal priority transport between
154  *  any two processors. The IMessageQTransport instances are created via the
155  *  {@link #SetupTransportProxy}. The instances are responsible for
156  *  registering themselves with MessageQ. This is accomplished via the
157  *  {@link #registerTransport} function.
158  *
159  *  @a(Note)
160  *  This modules reflects upon the {@link ti.sdo.utils.MultiProc#procAddrMode}
161  *  configuration parameter. Some internal data structure allocations are
162  *  optimized for the given processor address mode. For example, when using
163  *  {@link ti.sdo.utils.MultiProc#ProcAddrMode_Global}, a message can be
164  *  addressed to any processor using only the destination queueId. However,
165  *  when using {@link ti.sdo.utils.MultiProc#ProcAddrMode_Cluster}, only
166  *  the processors within your cluster can be addressed using only the
167  *  destination queueId. For processors outside the cluster, you must also
168  *  specify the Transport ID.
169  */
171 @ModuleStartup
172 @InstanceInitError
173 @InstanceFinalize
175 module MessageQ
177     /*!
178      *  ======== QueuesView ========
179      *  @_nodoc
180      */
181     metaonly struct QueuesView {
182         String  name;
183         UInt    queueId;
184         Bool    reserved;
185     }
187     /*!
188      *  ======== MessagesView ========
189      *  @_nodoc
190      */
191     metaonly struct MessagesView {
192         Int          seqNum;
193         Int          msgSize;
194         String       priority;
195         String       srcProc;
196         String       replyProc;
197         String       replyId;
198         Int          msgId;
199         String       heap;
200         Bool         traceEnabled;
201         Int          version;
202     }
204     /*!
205      *  ======== ModuleView ========
206      *  @_nodoc
207      */
208     metaonly struct ModuleView {
209         String               heaps[];
210         String               gate;
211         UInt16               nextSeqNum;
212         String               freeHookFxn[];
213     }
215     /*!
216      *  ======== rovViewInfo ========
217      *  @_nodoc
218      */
219     @Facet
220     metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
221         xdc.rov.ViewInfo.create({
222             viewMap: [
223                 ['Queues',
224                     {
225                         type: xdc.rov.ViewInfo.INSTANCE,
226                         viewInitFxn: 'viewInitQueues',
227                         structName: 'QueuesView'
228                     }
229                 ],
230                 ['Messages',
231                     {
232                         type: xdc.rov.ViewInfo.INSTANCE_DATA,
233                         viewInitFxn: 'viewInitMessages',
234                         structName: 'MessagesView'
235                     }
236                 ],
237                 ['Module',
238                     {
239                         type: xdc.rov.ViewInfo.MODULE,
240                         viewInitFxn: 'viewInitModule',
241                         structName: 'ModuleView'
242                     }
243                 ]
244             ]
245         });
247     /*!
248      *  ======== LM_setTrace ========
249      *  Logged when setting the trace flag on a message
250      *
251      *  This is logged when tracing on a message is set via
252      *  {@link #setMsgTrace}.
253      */
254     config Log.Event LM_setTrace = {
255         mask: Diags.USER1,
256         msg: "LM_setTrace: Message 0x%x (seqNum = %d, srcProc = %d) traceFlag = %d"
257     };
259     /*!
260      *  ======== LM_alloc ========
261      *  Logged when allocating a message
262      *
263      *  When the {@link #traceFlag} is true, all message allocations
264      *  are logged.
265      */
266     config Log.Event LM_alloc = {
267         mask: Diags.USER1,
268         msg: "LM_alloc: Message 0x%x (seqNum = %d, srcProc = %d) was allocated"
269     };
271     /*!
272      *  ======== LM_staticMsgInit ========
273      *  Logged when statically initializing a message
274      *
275      *  When the {@link #traceFlag} is true, all messages that
276      *  are statically initialized via {@link #staticMsgInit} are logged.
277      */
278     config Log.Event LM_staticMsgInit = {
279         mask: Diags.USER1,
280         msg: "LM_staticMsgInit: Message 0x%x (seqNum = %d, srcProc = %d) was set in MessageQ_staticMsgInit"
281     };
283     /*!
284      *  ======== LM_free ========
285      *  Logged when freeing a message
286      *
287      *  When the {@link #traceFlag} is true, all freeing of messages
288      *  are logged. If an individual message's tracing was enabled
289      *  via {@link #setMsgTrace}, the MessageQ_free is also logged.
290      */
291     config Log.Event LM_free = {
292         mask: Diags.USER1,
293         msg: "LM_free: Message 0x%x (seqNum = %d, srcProc = %d) was freed"
294     };
296     /*!
297      *  ======== LM_putLocal ========
298      *  Logged when a message is placed onto a local queue
299      *
300      *  When the {@link #traceFlag} is true, all putting of messages
301      *  are logged. If an individual message's tracing was enabled
302      *  via {@link #setMsgTrace}, the MessageQ_put is also logged.
303      */
304     config Log.Event LM_putLocal = {
305         mask: Diags.USER1,
306         msg: "LM_putLocal: Message 0x%x (seqNum = %d, srcProc = %d) was placed onto queue 0x%x"
307     };
309     /*!
310      *  ======== LM_putRemote ========
311      *  Logged when a message is given to a transport
312      *
313      *  When the {@link #traceFlag} is true, all putting of messages
314      *  to a transport are logged. If an individual message's tracing
315      *  was enabled  via {@link #setMsgTrace}, the MessageQ_put is
316      *  also logged.
317      */
318     config Log.Event LM_putRemote = {
319         mask: Diags.USER1,
320         msg: "LM_putRemote: Message 0x%x (seqNum = %d, srcProc = %d) was given to processor %d transport"
321     };
323     /*!
324      *  ======== LM_rcvByTransport ========
325      *  Logged when a transport receives an incoming message
326      *
327      *  When the {@link #traceFlag} is true, all incoming messages
328      *  are logged. If an individual message's tracing
329      *  was enabled  via {@link #setMsgTrace}, the receiving of a message is
330      *  also logged.
331      */
332     config Log.Event LM_rcvByTransport = {
333         mask: Diags.USER1,
334         msg: "LM_rcvByTransport: Message 0x%x (seqNum = %d, srcProc = %d) was received"
335     };
337     /*!
338      *  ======== LM_get ========
339      *  Logged when a message is received off the queue
340      *
341      *  When the {@link #traceFlag} is true, all getting of messages
342      *  are logged. If an individual message's tracing
343      *  was enabled  via {@link #setMsgTrace}, the MessageQ_get is
344      *  also logged.
345      */
346     config Log.Event LM_get = {
347         mask: Diags.USER1,
348         msg: "LM_get: Message 0x%x (seqNum = %d, srcProc = %d) was received by queue 0x%x"
349     };
351     /*!
352      *  ======== FreeHookFxn ========
353      *  Function prototype for the MessageQ_free callback
354      *
355      *  @param(Bits16)  heapId of message that was freed
356      *  @param(Bits16)  msgId of message that was freed
357      */
358     typedef Void (*FreeHookFxn)(Bits16, Bits16);
360     /*!
361      *  ======== PutHookFxn ========
362      *  Function prototype for the MessageQ_put callback
363      *
364      *  @param(Bits32)  queueId of the destination message queue
365      *  @param(Ptr)     pointer to a message header structure
366      */
367     typedef Void (*PutHookFxn)(Bits32, Ptr);
369     /*! MessageQ ID */
370     typedef UInt32 QueueId;
372     /*!
373      *  ======== SetupTransportProxy ========
374      *  MessageQ transport setup proxy
375      */
376     proxy SetupTransportProxy inherits ti.sdo.ipc.interfaces.ITransportSetup;
378     /*!
379      *  Message priority values. These must match the values defined in
380      *  ti/ipc/MessageQ.h but are needed here for ROV.
381      */
382     const UInt NORMALPRI   = 0;
383     const UInt HIGHPRI     = 1;
384     const UInt RESERVEDPRI = 2;
385     const UInt URGENTPRI   = 3;
387     /*!
388      *  Denotes any queueId is acceptable
389      *
390      *  This constant is the default for the {@link #queueId} parameter.
391      *  This value must match ti/ipc/MessageQ.h but is needed to initialize
392      *  queueId.
393      */
394     const Bits16 ANY = ~(0);
396     /*!
397      *  Assert raised when calling API with wrong handle
398      *
399      *  Some APIs can only be called with an opened handle (e.g.
400      *  {@link #close}. Some can only be called with a created handle
401      *  (e.g. {@link #get}).
402      */
403     config Assert.Id A_invalidContext  = {
404         msg: "A_invalidContext: Cannot call with an open/create handle"
405     };
407     /*!
408      *  Assert raised when attempting to free a static message
409      */
410     config Assert.Id A_cannotFreeStaticMsg  = {
411         msg: "A_cannotFreeStaticMsg: Cannot call MessageQ_free with static msg"
412     };
414     /*!
415      *  Assert raised when an invalid message is supplied
416      */
417     config Assert.Id A_invalidMsg  = {
418         msg: "A_invalidMsg: Invalid message"
419     };
421     /*!
422      *  Assert raised when an invalid queueId is supplied
423      */
424     config Assert.Id A_invalidQueueId  = {
425         msg: "A_invalidQueueId: Invalid queueId is used"
426     };
428     /*!
429      *  Assert raised when using an invalid heapId
430      */
431     config Assert.Id A_heapIdInvalid  = {
432         msg: "A_heapIdInvalid: heapId is invalid"
433     };
435     /*!
436      *  Assert raised when using an invalid procId
437      */
438     config Assert.Id A_procIdInvalid  = {
439         msg: "A_procIdInvalid: procId is invalid"
440     };
442     /*!
443      *  Assert raised for an invalid MessageQ object
444      */
445     config Assert.Id A_invalidObj  = {
446         msg: "A_invalidObj: an invalid obj is used"
447     };
449     /*!
450      *  Assert raised for an invalid parameter
451      */
452     config Assert.Id A_invalidParam  = {
453         msg: "A_invalidParam: an invalid parameter was passed in"
454     };
456     /*!
457      *  Assert raised when attempting to send a message to a core
458      *  where a transport has not been registered.
459      */
460     config Assert.Id A_unregisteredTransport  = {
461         msg: "A_unregisteredTransport: transport is not registered"
462     };
464     /*!
465      *  Assert raised when attempting to unblock a remote MessageQ or one that
466      *  has been configured with a non-blocking synchronizer
467      */
468     config Assert.Id A_invalidUnblock  = {
469         msg: "A_invalidUnblock: Trying to unblock a remote MessageQ or a queue with non-blocking synchronizer"
470     };
472     /*!
473      *  Error raised if all the message queue objects are taken
474      */
475     config Error.Id E_maxReached  = {
476         msg: "E_maxReached: All objects in use. MessageQ.maxRuntimeEntries is %d"
477     };
479     /*!
480      *  Error raised when heapId has not been registered
481      */
482     config Error.Id E_unregisterHeapId  = {
483         msg: "E_unregisterHeapId: Heap id %d not registered"
484     };
486     /*!
487      *  Error raised in a create call when a name fails to be added
488      *  to the NameServer table.  This can be because the name already
489      *  exists, the table has reached its max length, or out of memory.
490      */
491     config Error.Id E_nameFailed  = {
492         msg: "E_nameFailed: '%s' name failed to be added to NameServer"
493     };
495     /*!
496      *  Error raised if the requested queueIndex is not available
497      */
498     config Error.Id E_indexNotAvailable  = {
499         msg: "E_indexNotAvailable: queueIndex %d not available"
500     };
502     /*!
503      *  Trace setting
504      *
505      *  This flag allows the configuration of the default module trace
506      *  settings.
507      */
508     config Bool traceFlag = false;
510     /*!
511      *  Number of heapIds in the system
512      *
513      *  This allows MessageQ to pre-allocate the heaps table.
514      *  The heaps table is used when registering heaps.
515      *
516      *  There is no default heap, so unless the system is only using
517      *  {@link #staticMsgInit}, the application must register a heap.
518      */
519     config UInt16 numHeaps = 8;
521     /*!
522      *  Maximum number of MessageQs that can be dynamically created
523      */
524     config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
526     /*!
527      *  Number of reserved MessageQ indexes
528      *
529      *  An application can request the first N message queue indexes be
530      *  reserved to be used by MessageQ_create2. MessageQ_create will
531      *  not use these slots. The application can use any index less than
532      *  the value of numReservedEntries for the queueIndex field in the
533      *  MessageQ_Params2 structure.
534      *
535      *  numReservedEntries must be equal or less than
536      *  {@link #maxRuntimeEntries}.
537      */
538     config UInt numReservedEntries = 0;
540     /*!
541      *  Gate used to make the name table thread safe
542      *
543      *  This gate is used when accessing the name table during
544      *  a {@link #create}, {@link #delete}, and {@link #open}.
545      *
546      *  This gate is also used to protect MessageQ when growing
547      *  internal tables in the {@link #create}.
548      *
549      *  The table is in local memory, not shared memory. So a
550      *  single processor gate will work.
551      *
552      *  The default will be {@link xdc.runtime.knl.GateThread}
553      *  instance.
554      */
555     config IGateProvider.Handle nameTableGate = null;
557     /*!
558      *  Maximum length for Message queue names
559      */
560     config UInt maxNameLen = 32;
562     /*!
563      *  Section name is used to place the names table
564      */
565     metaonly config String tableSection = null;
567     /*!
568      *  ======== freeHookFxn ========
569      *  Free function in MessageQ_free after message was freed back to the heap
570      */
571     config FreeHookFxn freeHookFxn = null;
573     /*!
574      *  ======== putHookFxn ========
575      *  Put function hook
576      */
577     config PutHookFxn putHookFxn = null;
579     /*!
580      *  ======== registerHeapMeta ========
581      *  Statically register a heap with MessageQ
582      *
583      *  Build error if heapId is in use.
584      *
585      *  @param(heap)        Heap to register
586      *  @param(heapId)      heapId associated with the heap
587      */
588     metaonly Void registerHeapMeta(IHeap.Handle heap, UInt16 heapId);
590      /*!
591      *  ======== registerTransportMeta ========
592      *  Statically register a transport with MessageQ
593      *
594      *  Build error if remote processor already has a transport
595      *  registered.
596      *
597      *  @param(transport)   transport to register
598      *  @param(procId)      procId that transport communicaties with
599      *  @param(priority)    priority of transport
600      */
601      metaonly Void registerTransportMeta(IMessageQTransport.Handle transport,
602              UInt16 procId, UInt priority);
604     /*!
605      *  ======== registerTransport ========
606      *  Register a transport with MessageQ
607      *
608      *  This API is called by the transport when it is created.
609      *
610      *  @param(transport)   transport to register
611      *  @param(procId)      MultiProc id that transport communicates with
612      *  @param(priority)    priority of transport
613      *
614      *  @b(returns)         Whether the register was successful.
615      */
616     Bool registerTransport(IMessageQTransport.Handle transport, UInt16 procId,
617         UInt priority);
619     /*!
620      *  ======== unregisterTransport ========
621      *  Unregister a transport with MessageQ
622      *
623      *  @param(procId)      unregister transport that communicates with
624      *                      this remote processor
625      *  @param(priority)    priority of transport
626      */
627     Void unregisterTransport(UInt16 procId, UInt priority);
629 instance:
631     /*!
632      *  ISync handle used to signal IO completion
633      *
634      *  The ISync instance is used in the {@link #get} and {@link #put}.
635      *  The {@link xdc.runtime.knl.ISync#signal} is called as part
636      *  of the {@link #put} call.  The {@link xdc.runtime.knl.ISync#wait} is
637      *  called in the {@link #get} if there are no messages present.
638      */
639     config ISync.Handle synchronizer = null;
641     /*!
642      *  Requested MessageQ_QueueIndex
643      *
644      *  This parameter allows an application to specify the queueIndex to
645      *  be used for a message queue. To use this functionality, the
646      *  MessageQ.numReservedEntries static configuration parameter must be
647      *  set to a specific value.
648      *
649      *  The default is {@link #ANY}. This means do that you are not asking for
650      *  an explicit index. MessageQ will find the first available one which is
651      *  equal or greater than MessageQ.numReservedEntries.
652      */
653     config UInt16 queueIndex = ANY;
655     /*! @_nodoc
656      *  ======== create ========
657      *  Create a message queue
658      *
659      *  @param(name)         Name of the message queue.
660      */
661     create(String name);
663 internal:
664     /*
665      *  The following describes the usage of the flag field
666      *  ---------------------------------
667      *  |V V V|T|  reserved   |t t t|P P|
668      *  ---------------------------------
669      *   F E D C B A 9 8 7 6 5 4 3 2 1 0
670      *
671      *  [15:13] V = version
672      *  [12]    T = trace flag
673      *  [11:5]  reserved
674      *  [4:2]   t = transport Id, zero = default
675      *  [1:0]   P = priority
676      */
678     /*! Mask to extract version setting */
679     const UInt VERSIONMASK = 0xE000;
681     /*! Version setting */
682     const UInt HEADERVERSION = 0x2000;
684     /*! Mask to extract Trace setting */
685     const UInt TRACEMASK = 0x1000;
687     /*! Shift for Trace setting */
688     const UInt TRACESHIFT = 12;
690     /*!
691      *  Mask to extract priority setting.
692      *  This is needed here for ROV but must match
693      *  the value defined in ti/ipc/MessageQ.h
694      */
695     const UInt PRIORITYMASK = 0x3;
697     /*! Mask to extract priority setting */
698     const UInt TRANSPORTPRIORITYMASK = 0x1;
700      /*! return code for Instance_init */
701     const Int PROXY_FAILURE = 1;
703     /*
704      *  Used to denote a message that was initialized
705      *  with the MessageQ_staticMsgInit function.
706      */
707     const UInt16 STATICMSG = 0xFFFF;
709     /*! Required first field in every message */
710     @Opaque struct MsgHeader {
711         Bits64       reserved0;         /* reserved for List.elem->next */
712         Bits64       reserved1;         /* reserved for List.elem->prev */
713         Bits32       msgSize;           /* message size                 */
714         Bits16       flags;             /* bitmask of different flags   */
715         Bits16       msgId;             /* message id                   */
716         Bits16       dstId;             /* destination queue id         */
717         Bits16       dstProc;           /* destination processor id     */
718         Bits16       replyId;           /* reply queue id               */
719         Bits16       replyProc;         /* reply processor id           */
720         Bits16       srcProc;           /* proc who initialized the msg */
721         Bits16       heapId;            /* heap id                      */
722         Bits16       seqNum;            /* sequence number              */
723         Bits16       reserved;          /* reserved                     */
724     };
726     struct HeapEntry {
727         IHeap.Handle  heap;
728         UInt16        heapId;
729     };
731     struct TransportEntry {
732         IMessageQTransport.Handle  transport;
733         UInt16             procId;
734     };
736     enum TransportType {
737         TransportType_IMessageQTransport,
738         TransportType_INetworkTransport,
739         TransportType_Invalid
740     };
742     struct RegisteredTransport {
743         ITransport.Handle transport;
744         TransportType type;
745     };
747     /*!
748      *  ======== nameSrvPrms ========
749      *  This Params object is used for temporary storage of the
750      *  module wide parameters that are for setting the NameServer instance.
751      */
752     metaonly config NameServer.Params nameSrvPrms;
754     /*!
755      *  Statically registered heaps
756      *
757      *  This configuration parameter allows the static registeration
758      *  of heaps. The index of the array corresponds to the heapId.
759      */
760     metaonly config HeapEntry staticHeaps[];
762     /*!
763      *  Statically registered transports
764      *
765      *  This configuration parameter allows the static registeration
766      *  of transports. The index of the array corresponds to the procId.
767      */
768     metaonly config TransportEntry staticTransports[];
770     /*!
771      *  Allows for the number of dynamically created message queues to grow.
772      */
773     UInt16 grow(Object *obj, Error.Block *eb);
775     struct Instance_State {
776         QueueId         queue;        /* Unique id                     */
777         ISync.Handle    synchronizer; /* completion synchronizer       */
778         List.Object     normalList;   /* Embedded List objects         */
779         List.Object     highList;     /* Embedded List objects         */
780         Ptr             nsKey;        /* unique NameServer key         */
781         SyncSem.Handle  syncSemHandle;/* for use in finalize           */
782         Bool            unblocked;    /* Whether MessageQ is unblocked */
783     };
785     struct Module_State {
786         IMessageQTransport.Handle transports[length][2];
787         Handle               queues[];
788         IHeap.Handle         heaps[];
789         IGateProvider.Handle gate;
790         UInt16               numQueues;
791         UInt16               numHeaps;
792         NameServer.Handle    nameServer;
793         FreeHookFxn          freeHookFxn;
794         PutHookFxn           putHookFxn;
795         Bool                 canFreeQueues;
796         UInt16               seqNum;
797         RegisteredTransport  regTrans[8];
798     };