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 /*!
226 * ======== isEnabled ========
227 * Configures whether sync logging is enabled (true) or disabled (false)
228 */
229 metaonly config Bool isEnabled = true;
230
231 /*!
232 * ======== syncLogger ========
233 * Configures the logger instance to use to log sync point events
234 *
235 * If left null, an instance of LoggerStopMode will be created for
236 * dedicated use by the LogSync module in order to log sync point events.
237 * (The ti.uia.services.Rta and ti.uia.sysbios.LoggerSetup modules
238 * can specify that the LoggerCircBuf module be used as the default
239 * if the user has specified a non-JTAG transport for event upload.)
240 */
241 metaonly config xdc.runtime.ILogger.Handle syncLogger;
242
243 /*!
244 * ======== defaultSyncLoggerSize ========
245 * Configures the size of the default syncLogger created by LogSync
246 *
247 * Only used if syncLogger is null.
248 */
249 metaonly config SizeT defaultSyncLoggerSize = 256;
250
251 /*!
252 * ======== CpuTimestampProxy ========
253 * CPU Timestamp Proxy
254 *
255 * This proxy provides a timestamp server that can be different
256 * from the one provided by `{@link xdc.runtime.Timestamp}`. However, if
257 * not supplied by a user, this proxy defaults to whichever timestamp
258 * server is provided by `xdc.runtime.Timestamp`.
259 * @p
260 * Configuring the CpuTimestampProxy with a local timestamp module
261 * allows applications that change the CPU frequency to report this
262 * information to System Analyzer so that event timestamps can
263 * be adjusted to accommodate the change in frequency.
264 * @a(Examples)
265 * Example: the following configuration script shows how to configure
266 * a C66X Local Timestamp module for use as the CpuTimestampProxy
267 * @p(code)
268 * var TimestampC66Local = xdc.useModule('ti.uia.family.c66.TimestampC66Local');
269 * TimestampC66Local.maxTimerClockFreq = {lo:1200000000,hi:0};
270 * var LogSync = xdc.useModule('ti.uia.runtime.LogSync');
271 * LogSync.CpuTimestampProxy = TimestampC66Local;
272 * @p
273 */
274 proxy CpuTimestampProxy inherits xdc.runtime.ITimestampClient;
275 /*!
276 * ======== cpuTimestampCyclesPerTick ========
277 * The number of CPU cycles each tick of the global timestamp corresponds to.
278 * 0 if no relation between clocks.
279 *
280 * If the module configured as the CpuTimestampProxy implements
281 * ti.uia.runtime.IUIATimestampProvider, the default value of this config
282 * option is derived at configuration time from that module's config data.
283 * Otherwise it is initialized to 0 to signify that there is no way to
284 * convert a number of global timestamp tick counts into an equivalent
285 * number of CPU cycles.
286 */
287 config UInt32 cpuTimestampCyclesPerTick = 1;
288
289 /*!
290 * ======== maxCpuClockFreq =========
291 * The highest bus clock frequency used to drive the timer.
292 *
293 * The default ticks per second rate of the timer is calculated by dividing
294 * the timer's bus clock frequency by the cpuTimestampCyclesPerTick
295 * config parameter.
296 *
297 * Defines the 32 MSBs of the highest bus clock frequency used to drive
298 * the timer.
299 */
300 metaonly config Types.FreqHz maxCpuClockFreq;
301
302 /*!
303 * ======== canCpuFrequencyBeChanged =========
304 * Indicates whether the timer frequency can be changed or not
305 *
306 * Set to true if the timer's clock frequency can be changed
307 */
308 metaonly config Bool canCpuFrequencyBeChanged = false;
309
310
311 /*!
312 * ======== canCpuCyclesPerTickBeChanged =========
313 * Indicates whether the CPU timer's cycles per tick divide down ratio can
314 * be changed or not
315 *
316 * Set to true if the timer's CPU cycles per tick can be changed
317 */
318 metaonly config Bool canCpuCyclesPerTickBeChanged = false;
319
320 /*!
321 * ======== GlobalTimestampProxy ========
322 * Global Timestamp Proxy
323 *
324 * This proxy provides a timestamp server that can be different
325 * from the server provided by `{@link xdc.runtime.Timestamp}`.
326 * This must be configured in order to use this module.
327 */
328 proxy GlobalTimestampProxy inherits xdc.runtime.ITimestampClient;
329
330 /*!
331 * ======== globalTimestampCyclesPerTick ========
332 * The number of CPU cycles each tick of the global timestamp corresponds
333 * to. 0 if no relation between clocks.
334 *
335 * A value of 0 signifies that there is no way to convert a number of
336 * global timestamp tick counts into an equivalent number of CPU cycles.
337 * Note that this value will be automatically copied from the
338 * GlobalTimestampProxy.cpuCyclesPerTick configuration value
339 * at configuration time if GlobalTimestampProxy.cpuCyclesPerTick > 0.
340 */
341 config UInt32 globalTimestampCpuCyclesPerTick = 0;
342
343 /*!
344 * ======== maxGlobalClockFreq =========
345 * The highest bus clock frequency used to drive the timer used for the global
346 * timestamp.
347 *
348 * The default ticks per second rate of the timer is calculated by dividing
349 * the timer's bus clock frequency by the globalTimestampCpuCyclesPerTick
350 * config parameter.
351 *
352 * Defines the highest bus clock frequency used to drive the shared timer used
353 * for the global timestamp.
354 */
355 config Types.FreqHz maxGlobalClockFreq;
356
357 /*!
358 * ======== enable ========
359 * Enables logging of sync point events
360 *
361 * @a(returns)
362 * The function returns the state of the module-level enable (`TRUE`
363 * if enabled,`FALSE` if disabled) before the call. This return value
364 * allows clients to restore the previous state.
365 * Note: not thread safe.
366 */
367
368 @DirectCall
369 Bool enable();
370
371 /*!
372 * ======== disable ========
373 * Disable logging of sync point events
374 *
375 * @a(returns)
376 * The function returns the state of the module-level enable (`TRUE`
377 * if enabled,`FALSE` if disabled) before the call. This return value
378 * allows clients to restore the previous state.
379 * Note: not thread safe.
380 */
381 @DirectCall
382 Bool disable();
383 /*!
384 * ======== LogSync_idleHook ========
385 * Hook function that can be called by SysBios when the Idle function.
386 * Logs a sync point event if required in order to enable multicore event correlation.
387 * Allows multicore event correlation to be re-established after the target
388 * has been halted and then resumed execution. (e.g. after CIO operation or breakpoint)
389 */
390 @DirectCall
391 Void idleHook();
392
393 /*!
394 * ======== LogSync_timerHook ========
395 * Hook function that can be called periodically by SysBios to enable correlation
396 * of CPU trace, STM trace and software instrumentation events.
397 */
398 @DirectCall
399 Void timerHook(UArg arg);
400 /*!
401 * ======== putSyncPoint ========
402 * Unconditionally put the specified `Types` event.
403 *
404 * This method unconditionally logs a sync point event. It is used
405 * internally by the writeSyncPoint() macro and typically should not be
406 * called directly.
407 *
408 */
409 @DirectCall
410 Void putSyncPoint();
411
412 /*!
413 * ======== writeSyncPoint ========
414 * Log a sync point event along with global timestamp, local CPU frequency
415 * and sync point serial number.
416 *
417 * This method logs a synchronization point event, local CPU timestamp and
418 * global timestamp into the log along with the fmt string a sync point
419 * serial number
420 *
421 * @param(fmt) a constant string that describes why the sync point was
422 * logged.
423 */
424 @Macro Void writeSyncPoint();
425
426 /*!
427 * ======== isSyncEventRequired ========
428 * Is Sync Event Required
429 *
430 * Checks whether the target has been halted since the
431 * last sync point event and returns true if it has.
432 *
433 * @a(return) true if a synchronization event should be logged
434 */
435 @DirectCall
436 Bool isSyncEventRequired();
437
438
439 /*!
440 * ======== enableEventCorrelationForJTAG ========
441 * Enable event correlation for JTAG Transports
442 *
443 * By default, event correlation is enabled for JTAG transports.
444 * In order for event correlation to work with JTAG transports,
445 * it is necessary for the target program to periodically execute
446 * LogSync_idleHook in order to log enough synchronization information
447 * to reestablish event correlation after a breakpoint has been hit.
448 * The following .cfg script snippet shows how to configure the
449 * ti.uia.sysbios.LoggingSetup module to enable this:
450 * @p(code)
451 * .cfg script:
452 * var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
453 * @p
454 * Since most JTAG debugging sessions start with a breakpoint being
455 * hit at main, event correlation will only be possible once a sync
456 * point event has been logged after running from main. Calling the
457 * following code snippet as part of the code that is run by main is
458 * highly recommended in order to establish synchronization information
459 * as early in the program's execution as possible.
460 *
461 * @p(code)
462 * C code:
463 * #include <xdc/std.h>
464 * #include <ti/uia/runtime/LogSync.h>
465 * ...
466 *
467 * if (LogSync_isSyncEventRequired()){
468 * LogSync_writeSyncPoint();
469 * }
470 * @p
471 */
472 metaonly config Bool enableEventCorrelationForJTAG = false;
473
474 /*! @_nodoc
475 * ======== hasMetaData ========
476 * Indicates that the LogSync module generates content for the uia.xml file.
477 */
478 override metaonly config Bool hasMetaData = true;
479
480 /*! @_nodoc
481 * ======== finalize ========
482 * get configured clock settings from timer modules and configure logger to log
483 * sync events with
484 */
485 metaonly function finalize();
486
487 /*! @_nodoc
488 * ======== isUsedByRta ========
489 * Called by the RTA module to indicate that it is in the .cfg file
490 *
491 * Sets an internal metaonly flag that helps select the appropriate type of logger
492 */
493 metaonly function isUsedByRta();
494
495 /*! @_nodoc
496 * ======== isUsedByLoggingSetup ========
497 * Called by the LoggingSetup module to indicate that it is in the .cfg file
498 *
499 * Sets internal metaonly flags that help select the appropriate type of logger
500 */
501 metaonly function isUsedByLoggingSetup(isNonJtagLogger, isProbePointLogger,
502 isStopModeLogger, isStreamLogger,
503 isIdleLogger);
504
505 /*! @_nodoc
506 * ======== setSyncLogger ========
507 * Called by the LoggingSetup module to specify the logger to use to log sync point events with
508 */
509 metaonly function setSyncLogger(loggerModuleName);
510
511
512 instance:
513
514 internal:
515 struct Module_State {
516 UInt32 numTimesHalted;
517 UInt32 serialNumber;
518 Bool isEnabled;
519 };
520
521 }