1    /*
     2     * Copyright (c) 2013-2016, 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        /*! @_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         *  ======== writeSyncPointRaw ========
   451         *  Write log sync events using given timestamps.
   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    }