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 package ti.uia.runtime;
37 import xdc.runtime.Types;
38 import xdc.runtime.ILogger;
39 import xdc.runtime.IHeap;
40 import xdc.runtime.ILogger;
41 import xdc.runtime.Diags;
42 import xdc.runtime.Text;
43 import ti.uia.events.IUIAMetaProvider;
44 import xdc.rov.ViewInfo;
45
46 /*!
47 * ======== LogSync ========
48 * SyncPoint Event logging module for logging sync point events. Allows sync
49 * point events to use a different logger instance than used for other events.
50 *
51 * SyncPoint events are used to log timestamp values for two timebases: the
52 * local CPU timestamp that is used to timestamp events from this CPU, and a
53 * 'global' timestamp value that can be accessed by two or more CPUs.
54 * By logging the current timestamp values from these two timebase sources,
55 * the sync point events provide correlation points between the two timebases.
56 *
57 * In order to allow sync point information to be injected into hardware trace
58 * streams, the LogSync module supports a configuration parameter named
59 * injectIntoTraceFxn that allows the user to hook in a function pointer
60 * to a function that handles the (ISA specific) details of injecting whatever
61 * information is required into the trace stream. For C64X+ full gem devices,
62 * the address of the ti.uia.family.c64p.GemTraceSync module's
63 * GemTraceSync_injectIntoTrace function should be used.
64 *
65 * The sync point events are defined in the ti.uia.events.UIASync module
66 * (@see ti.uia.events.UIASync#syncPoint)
67 *
68 * A unique 'serial number' is assigned to each sync point event that is logged.
69 * The same serial number is logged as a parameter for all UIASync events that are
70 * used to log information related to the sync point, allowing host-side tooling to
71 * treat these separate events coherently. The serial number can optionally be injected
72 * into device-specific trace streams (e.g. CPU trace, System Trace, etc.) in order
73 * to enable host-side tooling to correlate these separate streams with the CPU and
74 * global timestamp information logged with the sync point events.
75 *
76 * @a(Examples)
77 * Example 1: This is part of the XDC configuration file for the application
78 * that demonstrates a standard configuration using default settings. In this
79 * example, the Rta module internally handles the logging of the sync point
80 * events. A timestamp module that implements the IUIATimestampProvider
81 * interface is used for the global timestamp. Default values are used for
82 * the CPU maxCpuClockFreq (700 MHz).
83 *
84 * @p(code)
85 * // By including Rta, Log records will be collected and sent to the
86 * // instrumentation host (once it is connected and started). The Rta module
87 * // logs sync point events upon receiving either the start or stop command,
88 * // and prior to sending up a new event packet if
89 * // LogSync_isSyncPointEventRequired() returns true.
90 * var Rta = xdc.useModule('ti.uia.services.Rta');
91 *
92 * // By default, the sync point events will be logged to a dedicated
93 * // LoggerCircBuf buffer named 'SyncLog' that is assigned to the LogSync
94 * // module. Using a dedicated event logger buffer is recommended
95 * // in order to ensure that sufficient timing information
96 * // is captured to enable accurate multicore event correlation.
97 * // Configure LogSync.defaultSyncLoggerSize to specify a custom buffer size.
98 * var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
99 *
100 * // For C64X+ and C66X devices that provide CPU trace hardware capabilities,
101 * // the following line will enable injection of correlation information into
102 * // the GEM CPU trace, enabling correlation of software events with the CPU
103 * // trace events.
104 * var GemTraceSync = xdc.useModule('ti.uia.family.c64p.GemTraceSync');
105 *
106 * // Configure a shared timer to act as a global time reference to enable
107 * // multicore correlation. The TimestampC6472Timer module implements the
108 * // IUIATimestampProvider interface, so assigning this timer to
109 * // LogSync.GlobalTimestampProxy will configure the LogSync module's global
110 * // clock parameters automatically. Exmaple 2 shows how to use other
111 * // types of timers.
112 * var TimestampC6472Timer =
113 * xdc.useModule('ti.uia.family.c64p.TimestampC6472Timer');
114 * LogSync.GlobalTimestampProxy = TimestampC6472Timer;
115 * @p(html)
116 * <hr />
117 * @p
118 *
119 * Example 2: Using a timer that does not implement the IUIATimestampProvider
120 * interface as the global timestamp timer. This example shows how to use,
121 * for example, timers that are provided by DSP/BIOS as the global timer
122 * source for event correlation 'sync point' timestamps.
123 * @p(code)
124 *
125 * var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
126 * var BiosTimer = xdc.useModule('ti.sysbios.family.c64p.TimestampProvider');
127 * LogSync.GlobalTimestampProxy = BiosTimer;
128 *
129 * // The following additional configuration code is required to use
130 * // a timer that does not implement the IUIATimeestampProvider interface
131 * // as the global timer for the LogSync module. If the maxGlobalClockFreq
132 * // config option is not initialized, the following warning message will be displayed
133 * // at build time: "Warning: UIA Event correlation disabled. Please
134 * // configure LogSync.globalClkFreq (.lo,.hi) to a non-zero value to enable."
135 * LogSync.maxGlobalClockFreq.lo = 700000000; // frequency in Hz - lower 32b
136 * LogSync.maxGlobalClockFreq.hi = 0; // frequency in Hz - upper 32b
137 *
138 * // Configure the LogSync module with CPU timestamp clock frequency info
139 * // for clock frequencies other than the default (700MHz).
140 * LogSync.maxCpuClockFreq.lo = 1000000000; // 1GHz CPU freq. - lower 32b
141 * LogSync.maxCpuClockFreq.hi = 0; // 1GHz CPU freq.- upper 32b
142 *
143 * // The globalTimestampCpuCyclesPerTick config option is optional.
144 * // It is used to convert global timestamp tick counts into CPU cycle counts
145 * // for devices where there is a fixed relationship between the global timer
146 * // frequency and the CPU clock.
147 * LogSync.globalTimestampCpuCyclesPerTick = 6;
148 * @p(html)
149 * <hr />
150 * @p *
151 * Example 3: Disabling LogSync module at configuation time
152 * The logging of sync point events can be disabled by adding the following
153 * to the configuration script:
154 * @p(code)
155 * LogSync.isEnabled = false;
156 * @p(html)
157 * <hr />
158 * @p *
159 * Example 4: This is a part of the C code for an application that does
160 * not use the Rta module, and so needs to log the sync point events itself:
161 *
162 * @p(code)
163 * #include <ti/uia/runtime/LogSync.h>
164 * ...
165 *
166 * // If the target has been suspended or halted
167 * // since the last time an event packet was sent to the
168 * // host, or the event transport has received a 'start' or
169 * // 'stop' command from the host, log a new sync point event to record
170 * // the current correlation info between the local
171 * // timestamp and the global timestamp.
172 * if ((LogSync_isSyncEventRequired())||( [starting/stopping event transport])){
173 * LogSync_writeSyncPoint();
174 * }
175 * @p
176 * <hr />
177 * @p *
178 * Example 5: The following configuration script snippet shows how to periodically
179 * log a sync point event. This allows System Analyzer to properly correlate UIA software
180 * instrumentation events with C6X CPU trace and STM (System Trace) events.
181 *
182 * @p(code)
183 * //Configure a Timer to interrupt every 100ms and call the LogSync_timerHook
184 * // function to log a sync point event
185 * var Timer = xdc.useModule('ti.sysbios.hal.Timer');
186 * var timerParams = new Timer.Params();
187 * timerParams.startMode = Timer.StartMode_AUTO;
188 * timerParams.period = 100000; // 100,000 uSecs = 100ms
189 * var timer0 = Timer.create(Timer.ANY, '&ti_uia_runtime_LogSync_timerHook', timerParams);
190 * @p
191 */
192 @ModuleStartup
193 @CustomHeader
194 module LogSync inherits ti.uia.runtime.IUIATraceSyncClient {
195
196 /*!
197 * @_nodoc
198 * ======== ModuleView ========
199 */
200 metaonly struct ModuleView {
201 UInt32 numTimesHalted;
202 UInt32 serialNumber;
203 Bool isEnabled;
204 }
205
206
207 /*!
208 * @_nodoc
209 * ======== rovViewInfo ========
210 */
211 @Facet
212 metaonly config ViewInfo.Instance rovViewInfo =
213 ViewInfo.create({
214 viewMap: [
215 ['Module',
216 {
217 type: ViewInfo.MODULE,
218 viewInitFxn: 'viewInitModule',
219 structName: 'ModuleView'
220 }
221 ]
222 ]
223 });
224
225 /*! @_nodoc
226 * ======== LoggerType ========
227 * Enum of the type of loggers that can be used to log sync point events.
228 */
229 metaonly enum LoggerType {
230 LoggerType_NONE,
231 LoggerType_MIN,
232 LoggerType_STOPMODE,
233 LoggerType_RUNMODE,
234 LoggerType_IDLE,
235 LoggerType_STREAMER,
236 LoggerType_STREAMER2
237 };
238
239 /*! @_nodoc
240 * ======== loggerType ========
241 * Configures the preferred type of logger to use to log sync point events
242 */
243 metaonly config LoggerType loggerType = LoggerType_NONE;
244
245
246 /*!
247 * ======== syncLogger ========
248 * Configures the logger instance to use to log sync point events
249 *
250 * If left null, an instance of LoggerStopMode will be created for
251 * dedicated use by the LogSync module in order to log sync point events.
252 * (The ti.uia.services.Rta and ti.uia.sysbios.LoggerSetup modules
253 * can specify that the LoggerCircBuf module be used as the default
254 * if the user has specified a non-JTAG transport for event upload.)
255 */
256 metaonly config xdc.runtime.ILogger.Handle syncLogger;
257
258 /*!
259 * ======== defaultSyncLoggerSize ========
260 * Configures the size of the default syncLogger created by LogSync
261 *
262 * Only used if syncLogger is null.
263 */
264 metaonly config SizeT defaultSyncLoggerSize = 256;
265
266 /*!
267 * ======== isEnabled ========
268 * Configures whether sync logging is enabled (true) or disabled (false)
269 */
270 metaonly config Bool isEnabled = true;
271
272 /*!
273 * ======== CpuTimestampProxy ========
274 * CPU Timestamp Proxy
275 *
276 * This proxy provides a timestamp server that can be different
277 * from the one provided by `{@link xdc.runtime.Timestamp}`. However, if
278 * not supplied by a user, this proxy defaults to whichever timestamp
279 * server is provided by `xdc.runtime.Timestamp`.
280 * @p
281 * Configuring the CpuTimestampProxy with a local timestamp module
282 * allows applications that change the CPU frequency to report this
283 * information to System Analyzer so that event timestamps can
284 * be adjusted to accommodate the change in frequency.
285 * @a(Examples)
286 * Example: the following configuration script shows how to configure
287 * a C66X Local Timestamp module for use as the CpuTimestampProxy
288 * @p(code)
289 * var TimestampC66Local = xdc.useModule('ti.uia.family.c66.TimestampC66Local');
290 * TimestampC66Local.maxTimerClockFreq = {lo:1200000000,hi:0};
291 * var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
292 * LogSync.CpuTimestampProxy = TimestampC66Local;
293 * @p
294 */
295 proxy CpuTimestampProxy inherits xdc.runtime.ITimestampClient;
296 /*!
297 * ======== cpuTimestampCyclesPerTick ========
298 * The number of CPU cycles each tick of the global timestamp corresponds to.
299 * 0 if no relation between clocks.
300 *
301 * If the module configured as the CpuTimestampProxy implements
302 * ti.uia.runtime.IUIATimestampProvider, the default value of this config
303 * option is derived at configuration time from that module's config data.
304 * Otherwise it is initialized to 0 to signify that there is no way to
305 * convert a number of global timestamp tick counts into an equivalent
306 * number of CPU cycles.
307 */
308 config UInt32 cpuTimestampCyclesPerTick = 1;
309
310 /*!
311 * ======== maxCpuClockFreq =========
312 * The highest bus clock frequency used to drive the timer.
313 *
314 * The default ticks per second rate of the timer is calculated by dividing
315 * the timer's bus clock frequency by the cpuTimestampCyclesPerTick
316 * config parameter.
317 *
318 * Defines the 32 MSBs of the highest bus clock frequency used to drive
319 * the timer.
320 */
321 metaonly config Types.FreqHz maxCpuClockFreq;
322
323 /*!
324 * ======== canCpuFrequencyBeChanged =========
325 * Indicates whether the timer frequency can be changed or not
326 *
327 * Set to true if the timer's clock frequency can be changed
328 */
329 metaonly config Bool canCpuFrequencyBeChanged = false;
330
331
332 /*!
333 * ======== canCpuCyclesPerTickBeChanged =========
334 * Indicates whether the CPU timer's cycles per tick divide down ratio can
335 * be changed or not
336 *
337 * Set to true if the timer's CPU cycles per tick can be changed
338 */
339 metaonly config Bool canCpuCyclesPerTickBeChanged = false;
340
341 /*!
342 * ======== GlobalTimestampProxy ========
343 * Global Timestamp Proxy
344 *
345 * This proxy provides a timestamp server that can be different
346 * from the server provided by `{@link xdc.runtime.Timestamp}`.
347 * This must be configured in order to use this module.
348 */
349 proxy GlobalTimestampProxy inherits xdc.runtime.ITimestampClient;
350
351 /*!
352 * ======== globalTimestampCyclesPerTick ========
353 * The number of CPU cycles each tick of the global timestamp corresponds
354 * to. 0 if no relation between clocks.
355 *
356 * A value of 0 signifies that there is no way to convert a number of
357 * global timestamp tick counts into an equivalent number of CPU cycles.
358 * Note that this value will be automatically copied from the
359 * GlobalTimestampProxy.cpuCyclesPerTick configuration value
360 * at configuration time if GlobalTimestampProxy.cpuCyclesPerTick > 0.
361 */
362 config UInt32 globalTimestampCpuCyclesPerTick = 0;
363
364 /*!
365 * ======== maxGlobalClockFreq =========
366 * The highest bus clock frequency used to drive the timer used for the global
367 * timestamp.
368 *
369 * The default ticks per second rate of the timer is calculated by dividing
370 * the timer's bus clock frequency by the globalTimestampCpuCyclesPerTick
371 * config parameter.
372 *
373 * Defines the highest bus clock frequency used to drive the shared timer used
374 * for the global timestamp.
375 */
376 config Types.FreqHz maxGlobalClockFreq;
377
378 /*!
379 * ======== enable ========
380 * Enables logging of sync point events
381 *
382 * @a(returns)
383 * The function returns the state of the module-level enable (`TRUE`
384 * if enabled,`FALSE` if disabled) before the call. This return value
385 * allows clients to restore the previous state.
386 * Note: not thread safe.
387 */
388
389 @DirectCall
390 Bool enable();
391
392 /*!
393 * ======== disable ========
394 * Disable logging of sync point events
395 *
396 * @a(returns)
397 * The function returns the state of the module-level enable (`TRUE`
398 * if enabled,`FALSE` if disabled) before the call. This return value
399 * allows clients to restore the previous state.
400 * Note: not thread safe.
401 */
402 @DirectCall
403 Bool disable();
404
405 /*!
406 * ======== LogSync_idleHook ========
407 * Hook function that can be called by SysBios when the Idle function.
408 * Logs a sync point event if required in order to enable multicore event correlation.
409 * Allows multicore event correlation to be re-established after the target
410 * has been halted and then resumed execution. (e.g. after CIO operation or breakpoint)
411 */
412 @DirectCall
413 Void idleHook();
414
415 /*!
416 * ======== LogSync_timerHook ========
417 * Hook function that can be called periodically by SysBios to enable correlation
418 * of CPU trace, STM trace and software instrumentation events.
419 */
420 @DirectCall
421 Void timerHook(UArg arg);
422
423 /*!
424 * ======== putSyncPoint ========
425 * Unconditionally put the specified `Types` event.
426 *
427 * This method unconditionally logs a sync point event. It is used
428 * internally by the writeSyncPoint() macro and typically should not be
429 * called directly.
430 *
431 */
432 @DirectCall
433 Void putSyncPoint();
434
435 /*!
436 * ======== writeSyncPoint ========
437 * Log a sync point event along with global timestamp, local CPU frequency
438 * and sync point serial number.
439 *
440 * This method logs a synchronization point event, local CPU timestamp and
441 * global timestamp into the log along with the fmt string a sync point
442 * serial number
443 *
444 * @param(fmt) a constant string that describes why the sync point was
445 * logged.
446 */
447 @Macro Void writeSyncPoint();
448
449 450 451 452
453 Void writeSyncPointRaw(const Types.Timestamp64 *cpuTS,
454 const Types.Timestamp64 *globalTS, const Types.FreqHz *globalTickFreq);
455
456 /*!
457 * ======== isSyncEventRequired ========
458 * Is Sync Event Required
459 *
460 * Checks whether the target has been halted since the
461 * last sync point event and returns true if it has.
462 *
463 * @a(return) true if a synchronization event should be logged
464 */
465 @DirectCall
466 Bool isSyncEventRequired();
467
468
469 /*!
470 * ======== enableEventCorrelationForJTAG ========
471 * Enable event correlation for JTAG Transports (deprecated)
472 *
473 * By default, event correlation is enabled for JTAG transports.
474 * In order for event correlation to work with JTAG transports,
475 * it is necessary for the target program to periodically execute
476 * LogSync_idleHook in order to log enough synchronization information
477 * to reestablish event correlation after a breakpoint has been hit.
478 * The following .cfg script snippet shows how to configure the
479 * ti.uia.sysbios.LoggingSetup module to enable this:
480 * @p(code)
481 * .cfg script:
482 * var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
483 * @p
484 * Since most JTAG debugging sessions start with a breakpoint being
485 * hit at main, event correlation will only be possible once a sync
486 * point event has been logged after running from main. Calling the
487 * following code snippet as part of the code that is run by main is
488 * highly recommended in order to establish synchronization information
489 * as early in the program's execution as possible.
490 *
491 * @p(code)
492 * C code:
493 * #include <xdc/std.h>
494 * #include <ti/uia/runtime/LogSync.h>
495 * ...
496 *
497 * if (LogSync_isSyncEventRequired()){
498 * LogSync_writeSyncPoint();
499 * }
500 * @p
501 */
502 metaonly config Bool enableEventCorrelationForJTAG = true;
503
504 /*! @_nodoc
505 * ======== hasMetaData ========
506 * Indicates that the LogSync module generates content for the uia.xml file.
507 */
508 override metaonly config Bool hasMetaData = true;
509
510 /*! @_nodoc
511 * ======== finalize ========
512 * get configured clock settings from timer modules and configure logger to log
513 * sync events with
514 */
515 metaonly function finalize();
516
517 /*! @_nodoc
518 * ======== isUsedByRta ========
519 * Called by the RTA module to indicate that it is in the .cfg file
520 *
521 * Sets an internal metaonly flag that helps select the appropriate type of logger
522 */
523 metaonly function isUsedByRta();
524
525
526 instance:
527
528 internal:
529 struct Module_State {
530 UInt32 numTimesHalted;
531 UInt32 serialNumber;
532 Bool isEnabled;
533 };
534
535 }