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