1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32
33 34 35
36 import xdc.runtime.ITimestampClient;
37 import xdc.runtime.IHeap;
38 import xdc.runtime.Types;
39 import xdc.runtime.Log;
40 import xdc.runtime.ILogger;
41 import xdc.runtime.Error;
42 import xdc.runtime.Diags;
43 import xdc.rov.ViewInfo;
44
45 /*!
46 * ======== LoggerCircBuf ========
47 * A logger which stores `Log` events in a non-blocking, streamable
48 * circular buffer.
49 */
50
51 @ModuleStartup
52 @InstanceFinalize
53 @InstanceInitError
54 module LoggerCircBuf inherits ILoggerSnapshot
55 {
56 /*!
57 * @_nodoc
58 * ======== ModuleView ========
59 */
60 metaonly struct ModuleView {
61 Bool isTimestampEnabled;
62 Bool enableFlush;
63 String statusLogger;
64 String moduleIdToRouteToStatusLogger;
65
66
67
68
69 }
70
71 /*!
72 * @_nodoc
73 * ======== InstanceView ========
74 */
75 metaonly struct InstanceView {
76 String label;
77 Bool enabled;
78 SizeT transferBufSize;
79 SizeT maxEventSize;
80 Bits16 serial;
81 Int numCores;
82 IUIATransfer.TransferType transferType;
83 Bool flush;
84 Int droppedEvents;
85 }
86
87 metaonly struct RecordView {
88 Int serial;
89 Long timestampRaw;
90 String modName;
91 String text;
92 Int eventId;
93 String eventName;
94 IArg arg0;
95 IArg arg1;
96 IArg arg2;
97 IArg arg3;
98 IArg arg4;
99 IArg arg5;
100 IArg arg6;
101 IArg arg7;
102 }
103
104 /*!
105 * @_nodoc
106 * ======== rovViewInfo ========
107 */
108 @Facet
109 metaonly config ViewInfo.Instance rovViewInfo =
110 ViewInfo.create({
111 viewMap: [
112 ['Module',
113 {
114 type: ViewInfo.MODULE,
115 viewInitFxn: 'viewInitModule',
116 structName: 'ModuleView'
117 }
118 ],
119 ['Instances',
120 {
121 type: ViewInfo.INSTANCE,
122 viewInitFxn: 'viewInitInstances',
123 structName: 'InstanceView'
124 }
125 ],
126 ['Records',
127 {
128 type: xdc.rov.ViewInfo.INSTANCE_DATA,
129 viewInitFxn: 'viewInitRecords',
130 structName: 'RecordView'
131 }
132 ]
133 ]
134 });
135
136 /*! Error raised if get or setFilterLevel receive a bad level value */
137 config Error.Id E_badLevel =
138 {msg: "E_badLevel: Bad filter level value: %d"};
139
140 /*!
141 * ======== isTimestampEnabled ========
142 * Enable or disable logging the 64b local CPU timestamp
143 * at the start of each event
144 */
145 config Bool isTimestampEnabled = true;
146
147 /*!
148 * ======== enableFlush ========
149 * Flush all logs at system exit
150 */
151 config Bool enableFlush = false;
152
153 /*!
154 * ======== statusLogger ========
155 * Route all 'STATUS' (error and warning) events to this logger.
156 *
157 * If a statusLogger is specified AND the filterByLevel is true,
158 * all LoggerCircBuf instances will check to determine if any of the events
159 * they receive are errors or warnings (if their diags mask includes the
160 * STATUS category) or if the event is from the module specified by
161 * moduleIdToRouteToStatusLogger, and if so, will log these
162 * events to the statusLogger.
163 *
164 * Error events are infrequent, but it's generally critical that they be
165 * seen. In a typical system, non-error events easily outnumber any error
166 * events, and the logger is likely to wrap, overwriting any error events.
167 * To protect these events from being overwritten and lost, they can be
168 * sent to their own separate logger to preserve them.
169 *
170 * The default value is null, indicating that the STATUS events will just
171 * be logged by the logger they were sent to.
172 */
173 config xdc.runtime.IFilterLogger.Handle statusLogger = null;
174
175 /*!
176 * ======== overflowLogger ========
177 * Route all events that cannot be stored in the main (transfer)
178 * event buffer to this logger
179 *
180 * If an overflowLogger is specified and there is not enough room in the
181 * instance's buffer, the event will be passed to this logger instead.
182 *
183 * The overflow Logger is intended to ensure that the last 'N' events
184 * leading up to a breakpoint are captured and are available for stop-mode
185 * debugging. The overflow logger should be designed to automatically
186 * wrap, overwriting the oldest events and preserving the most recent
187 * events. An example is xdc.runtime.LoggerBuf.
188 *
189 * The default value is null, indicating that overflow events that occur
190 * because the event transport is not fast enough to upload them will
191 * just be dropped.
192 */
193 config ILogger.Handle overflowLogger = null;
194
195 /*!
196 * ======== level1Mask ========
197 * Mask of diags categories whose initial filtering level is Diags.LEVEL1
198 *
199 * See '{@link #level4Mask}' for details.
200 */
201 config Diags.Mask level1Mask = 0;
202
203 /*!
204 * ======== level2Mask ========
205 * Mask of diags categories whose initial filtering level is Diags.LEVEL2
206 *
207 * See '{@link #level4Mask}' for details.
208 */
209 config Diags.Mask level2Mask = 0;
210
211 /*!
212 * ======== level3Mask ========
213 * Mask of diags categories whose initial filtering level is Diags.LEVEL3
214 *
215 * See '{@link #level4Mask}' for details.
216 */
217 config Diags.Mask level3Mask = 0;
218
219 /*!
220 * ======== level4Mask ========
221 * Mask of diags categories whose initial filtering level is Diags.LEVEL4
222 *
223 * If 'filterByLevel' is true, then all LoggerBuf instances will filter
224 * incoming events based on their event level.
225 *
226 * The LoggerCircBuf module allows for specifying a different filter level for
227 * every Diags bit. These filtering levels are module wide; LoggerBuf does
228 * not support specifying the levels on a per-instance basis.
229 *
230 * The setFilterLevel API can be used to change the filtering levels at
231 * runtime.
232 *
233 * The default filtering levels are assigned using the 'level1Mask' -
234 * 'level4Mask' config parameters. These are used to specify, for each of
235 * the four event levels, the set of bits which should filter at that
236 * level by default.
237 *
238 * The default filtering configuration sets the filter level to
239 * Diags.LEVEL4 for all logging-related diags bits so that all events are
240 * logged by default.
241 */
242 config Diags.Mask level4Mask = Diags.ALL_LOGGING;
243
244 /*!
245 * ======== moduleToRouteToStatusLogger ========
246 * events from this module will be routed to the statusLogger (if configured)
247 */
248 metaonly config String moduleToRouteToStatusLogger;
249
250 /*!
251 * ======== setModuleIdToRouteToStatusLogger ========
252 * Specifies which module to route events to the statusLogger for
253 *
254 * @param(mid) the module ID to route events for. Set to -1 for 'none'
255 */
256 @DirectCall
257 Void setModuleIdToRouteToStatusLogger(Types.ModuleId mid);
258
259 /*!
260 * ======== flushAll ========
261 * Flush logs of all instances of `LoggerCircBuf`
262 *
263 * The user is responsible for making sure that no `LoggerCircBuf`
264 * instances are created or deleted while in this API, by using an
265 * appropriate gate.
266 */
267 Void flushAll();
268
269 /*!
270 * ======== flushAllInternal ========
271 * @_nodoc
272 */
273 @DirectCall
274 Void flushAllInternal(Int stat);
275
276 /*!
277 * @_nodoc
278 * ======== initDecoder ========
279 * Initialize the Java LoggerCircBufDecoder for use in the LoggerCircBuf
280 * 'Records' ROV view.
281 */
282 function initDecoder();
283
284 instance:
285 /*!
286 * ======== create ========
287 * Create a `LoggerCircBuf` logger
288 *
289 * @see LoggerCircBuf#Params
290 */
291 @DirectCall
292 create();
293
294 /*!
295 * ======== transferBufSize ========
296 * Number of minimum addressable units (e.g. bytes) in transfer buffer
297 *
298 * The transfer buffer is used to store events that can be read by
299 * the transport. Since the transport is typically bandwidth limited,
300 * it is possible to drop events if the buffer fills up before the
301 * event can be transmitted. If this occurs and the
302 * `{@link #overflowLogger} is not null, the event will be written to
303 * the overflow buffer.
304 */
305 config SizeT transferBufSize = 512;
306
307 /*!
308 * ======== maxEventSize ========
309 * The maximum event size (in Maus) that can be written with a single event.
310 *
311 * Determines the size of the area following the circular buffer
312 * that is used to provide a linear copy space to speed up
313 * copying data into the buffer in a circular manner.
314 * Must be less than or equal to transferBufSize.
315 */
316 config SizeT maxEventSize = 128;
317
318 /*!
319 * ======== exitFlush ========
320 * Flush log at system exit
321 *
322 * Only used when module parameter `{@link #enableFlush}` is `true`.
323 */
324 config Bool exitFlush = true;
325
326 /*!
327 * ======== bufSection ========
328 * Section name for the buffer managed by the static instance.
329 *
330 * The default section is the 'dataMemory' in the platform.
331 */
332 metaonly config String bufSection = null;
333
334 /*!
335 * ======== bufHeap ========
336 * The heap that contains the `Log` buffer for dynamic instances.
337 *
338 * The default value `null` means the buffer will be allocated from
339 * the `{@link Memory#defaultHeapInstance}` heap.
340 */
341 config IHeap.Handle bufHeap = null;
342
343 /*!
344 * ======== numCores ========
345 * Number of cores running the same image with an instance in shared memory
346 *
347 * A common use case is to have the same binary image (e.g. .out file)
348 * run on multiple cores of multi-core device. This causes a problem if the
349 * logger's buffer is in shared memory (e.g. DDR). Since the image is the
350 * same for all the cores, each core will attempt to write to the same
351 * buffer in the shared memory. To avoid this, either the logger's buffers
352 * must be in non-shared memory or by setting the numCores parameter to
353 * the number of cores on the device.
354 *
355 * Note: the `{@link #bufSection}` along with the Program.sectMap is how
356 * a logger instance's buffer is placed into specific memory.
357 *
358 * Setting numCores to a value great than 1 signals LoggerCircBuf to
359 * statically set aside additional memory ((x numCores) to allow each
360 * core to have `{@link #transferBufSize}` amount of memory.
361 *
362 * Warning: setting this parameter to a value greater than one should only
363 * be done when there is a single image used on multiple cores of a
364 * multi-core device AND the logger instance's buffer is in shared memory.
365 * While functionally it will still work, memory will be wasted if both
366 * these conditions are not met.
367 *
368 * The default is 1, which means do not reserve any additional memory
369 * for the logger.
370 */
371 config Int numCores = 1;
372
373 /*!
374 * ======== flush ========
375 * Read, clear, and output the contents of the log
376 *
377 * This method reads, clears, and "prints" each `Log` event (via
378 * `{@link System#printf}`) in the log.
379 */
380 @DirectCall
381 Void flush();
382
383 /*!
384 * ======== getNumDropped =========
385 * Returns the number of dropped events for this logger instance
386 */
387 @DirectCall
388 Int getNumDropped();
389
390 /*!
391 * ======== enable ========
392 * Enable a log
393 *
394 * @a(returns)
395 * The function returns the state of the log (`TRUE` if enabled,
396 * `FALSE` if disabled) before the call. That allow clients to restore
397 * the previous state.
398 */
399 @DirectCall
400 override Bool enable();
401
402 /*!
403 * ======== disable ========
404 * Disable a log
405 *
406 * Events written to a disabled log are silently discarded.
407 *
408 * @a(returns)
409 * The function returns the state of the log (`TRUE` if enabled,
410 * `FALSE` if disabled) before the call. That allow clients to restore
411 * the previous state.
412 */
413 @DirectCall
414 override Bool disable();
415
416 /*!
417 * ======== write0 ========
418 * Process a log event with 0 arguments and the calling address.
419 *
420 * Same as `write4` except with 0 arguments rather than 4.
421 * @see #write4()
422 */
423 @DirectCall
424 override Void write0(Log.Event evt, Types.ModuleId mid);
425
426 /*!
427 * ======== write1 ========
428 * Process a log event with 1 arguments and the calling address.
429 *
430 * Same as `write4` except with 1 arguments rather than 4.
431 * @see #write4()
432 */
433 @DirectCall
434 override Void write1(Log.Event evt, Types.ModuleId mid, IArg a1);
435
436 /*!
437 * ======== write2 ========
438 * Process a log event with 2 arguments and the calling address.
439 *
440 * Same as `write4` except with 2 arguments rather than 4.
441 *
442 * @see #write4()
443 */
444 @DirectCall
445 override Void write2(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2);
446
447 /*!
448 * ======== write4 ========
449 * Process a log event with 4 arguments and the calling address.
450 *
451 * @see ILogger#write4()
452 */
453 @DirectCall
454 override Void write4(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
455 IArg a3, IArg a4);
456
457 /*!
458 * ======== write8 ========
459 * Process a log event with 8 arguments and the calling address.
460 *
461 * Same as `write4` except with 8 arguments rather than 4.
462 *
463 * @see #write4()
464 */
465 @DirectCall
466 override Void write8(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
467 IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
468
469 /*!
470 * ======== setFilterLevel ========
471 * Sets the level of detail that instances will log.
472 *
473 * Events with the specified level or higher will be logged, events
474 * below the specified level will be dropped.
475 *
476 * Events are filtered first by diags category, then by level. If an
477 * event's diags category is disabled in the module's diags mask, then it
478 * will be filtered out regardless of level. The event will not even be
479 * passed to the logger.
480 *
481 * This API allows for setting the filtering level for more than one
482 * diags category at a time. The mask parameter can be a single category
483 * or multiple categories combined, and the level will be set for all of
484 * those categories.
485 *
486 * @param(mask) The diags categories to set the level for
487 * @param(filterLevel) The new filtering level for the specified
488 * categories
489 */
490 @DirectCall
491 override Void setFilterLevel(Diags.Mask mask, Diags.EventLevel filterLevel);
492
493 /*!
494 * ======== getFilterLevel ========
495 * Returns the mask of diags categories currently set to the specified
496 * level.
497 *
498 * See '{@link #setFilterLevel}' for an explanation of level filtering.
499 */
500 @DirectCall
501 override Diags.Mask getFilterLevel(Diags.EventLevel level);
502
503 /*!
504 * ======== getFreeSize =========
505 * Determines how much free space exist (in Maus)
506 */
507 @DirectCall
508 SizeT getFreeSize();
509
510 /*!
511 * ======== getUnreadSize =========
512 * Determines how much unread data exist (in Maus)
513 */
514 @DirectCall
515 SizeT getUnreadSize();
516
517 internal:
518 /*!
519 * ======== readBlockOfMemory ========
520 */
521 @DirectCall
522 Bool readBlockOfMemory(Handle obj, Ptr pMemBlock, SizeT sizeToRead);
523
524 /*!
525 * ======== writeBlockOfMemory ========
526 */
527 @DirectCall
528 Bool writeBlockOfMemory(Handle obj, Ptr newWrPtr, Ptr pMemBlock,
529 SizeT size);
530
531 /*!
532 * ======== filterOutEvent ========
533 */
534 @DirectCall
535 Bool filterOutEvent(Diags.Mask mask);
536
537 struct Module_State {
538 Diags.Mask level1;
539 Diags.Mask level2;
540 Diags.Mask level3;
541 Types.ModuleId moduleIdToRouteToStatusLogger;
542 };
543
544 /*!
545 * @_nodoc
546 * ======== postIncrementPtr =========
547 * returns the buffer size in MAUs (min. addressable units)
548 */
549 @DirectCall
550 Bits32 *postIncrementPtr(Object *obj, UArg *myRdPtr);
551
552 struct Instance_State {
553 QueueDescriptor.Header hdr;
554 IHeap.Handle bufHeap;
555 SizeT maxEventSizeInBits32;
556 Bits16 serial;
557 IUIATransfer.TransferType transferType;
558 Bool enabled;
559 Bool flush;
560 Int droppedEvents;
561 Ptr queueStartAdrs;
562 SizeT queueSizeInMAUs;
563 Ptr endOfBufferAdrsPlus1; 564
565 Char bufferArray[];
566 Int numCores;
567 };
568 }