1    /*
     2     * Copyright (c) 2012, 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    /*
    34     *  ======== LogSync.xdc ========
    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      /* Initialize static instances */
   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    }