1    /*
     2     * Copyright (c) 2012-2013, 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     * ======== UIAProfile.xdc ========
    35     */
    36    
    37    import xdc.runtime.Diags;
    38    import xdc.runtime.Types;
    39    import ti.uia.events.DvtTypes;
    40    
    41    /*!
    42     * UIA Profile Events
    43     *
    44     * The UIAProfile module defines events that allow
    45     * tooling to analyze the performance of the software
    46     * (processing time, latency, etc.).  These events are
    47     * designed to be logged from function-entry and function-exit
    48     * hook functions that are called by compiler-generated code
    49     *
    50     * TI compilers can be configured to either pass in a parameter
    51     * to the hook functions containing either the address
    52     * of the function or the name of the function.
    53     *
    54     * If the compiler is configured to pass in the address of the function,
    55     * the `UIAProfile_enterFunctionAdrs` event should be logged by the
    56     * entry hook function and the `UIAProfile_exitFunctionAdrs` event
    57     * should be logged by the exit hook function.
    58     *
    59     * If the compiler is configured to pass in the name of the function,
    60     * the `UIAProfile_enterFunctionName` event should be logged by the
    61     * entry hook function and the `UIAProfile_exitFunctionName` event
    62     * should be logged by the exit hook function.
    63     *
    64     * When logging events using the xdc.runtime.Log module, the generation
    65     * of UIAProfile events is controlled by the `Diags.ENTRY` and `Diags.EXIT`
    66     * flags in a module's diagnostics  mask.  (For more information on
    67     * diagnostics masks, please see the xdc.runtime.Diags documentation.)
    68     *
    69     * By default, the UIAProfile module will automatically set both the
    70     * `Main.common$.Diags_ENTRY` and `Main.common$.Diags_EXIT` flags to
    71     * `Diags.ALWAYS_ON` if these flags have not been previously configured.
    72     * To turn off these flags at configuration time, set
    73     * `UIAProfile.enable = false;`  To allow these flags to be configured
    74     * at run time, set `UIAProfile.runtimeControl = true;`
    75     *
    76     * @a(Examples)
    77     * Example 1: This is part of the XDC configuration file for the application:
    78     *
    79     *  @p(code)
    80     *  var UIAProfile = xdc.useModule('ti.uia.events.UIAProfile');
    81     *  var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    82     *  @p
    83     *
    84     *  @p(html)
    85     *  <hr />
    86     *  @p
    87     *
    88     *  Example 2: The following example configures a module to support logging
    89     *  of ENTRY and EXIT events, but defers the actual activation and deactivation of the
    90     *  logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
    91     *  function for details on specifying the control string.
    92     *
    93     *  This is a part of the XDC configuration file for the application:
    94     *
    95     *  @p(code)
    96     *  var UIAProfile = xdc.useModule('ti.uia.events.UIAProfile');
    97     *  UIAProfile.runtimeControl = true;
    98     *  UIAProfile.enable = false;
    99     *  @p
   100     *
   101     *  This is a part of the C code for the application.
   102     *  The diags_ENTRY mask is set by "E", and the diags_EXIT mask is set by "X".
   103     *
   104     *  @p(code)
   105     *  #include <xdc/runtime/Diags.h>
   106     *  #include <xdc/runtime/Main.h>
   107     *
   108     *  // turn on logging of ENTRY and EXIT events in the module
   109     *  Diags_setMask("xdc.runtime.Main+EX");
   110     *
   111     *  // turn off logging of ENTRY and EXIT events in the module
   112     *  Diags_setMask("xdc.runtime.Main-EX");
   113     *  @p
   114     *
   115     *
   116     */
   117    @Template("./UIAProfile.xdt")
   118    module UIAProfile inherits IUIAEvent {
   119    
   120        /*!
   121         *  ======== enterFunctionAdrs ========
   122         *  Profiling event used to log the entry point of a function
   123         *
   124         * @a(Example)
   125         * To add entry and exit hook functions to every function
   126         * 1. Use the following compiler options when compiling the source
   127         *  @p(code)
   128         *  --entry_hook=functionEntryHook
   129         *  --entry_param=address
   130         *  --exit_hook=functionExitHook
   131         *  --exit_param=address
   132         *  @p
   133         * 2. Add the following c code to implement the hook functions:
   134         *   The first parameter (the taskHandle) is set to  0 in this example.
   135         *   @see exitFunction for an example of how to log the current task ID
   136         *   for task-aware function profiling.
   137         *   In order to further reduce the CPU overhead of logging the
   138             *   UIAProfile events, you can use the LogUC.h APIs. For more info, please
   139             *   see @link http://processors.wiki.ti.com/index.php/SystemAnalyzerTutorial1F
   140         *  @p(code)
   141         *  #include <xdc/runtime/Log.h>
   142         *  #include <ti/uia/events/UIAProfile.h>
   143         *  ...
   144         * void functionEntryHook( void (*adrs)() ){
   145         *    Log_write2(UIAProfile_enterFunctionAdrs, 0,(IArg)adrs);
   146         *   ...
   147         * void functionExitHook( void (*adrs)() ){
   148         *    Log_write2(UIAProfile_exitFunctionAdrs, 0,(IArg)adrs);
   149         * }
   150         *  @p
   151         *  The following text will be displayed for the event:
   152         *  @p(code)
   153         *  enterFunctionAdrs: taskHandle=0x0, adrs=0x820060
   154         *  exitFunctionAdrs: taskHandle0x0, adrs=0x820060
   155         *  @p
   156         *  @param(taskHandle)   task handle that identifies the currently active task (use 0 if not required)
   157         *  @param(functionAdrs) the address of a function that can differentiate this pair of start and stop events from others
   158         */
   159        config xdc.runtime.Log.Event enterFunctionAdrs = {
   160            mask: Diags.ENTRY,
   161            msg: "enterFunctionAdrs: taskHandle=0x%x, adrs=0x%x"
   162        };
   163    
   164        /*!
   165         *  ======== metaEventEnterFunctionAdrs ========
   166         *  Metadata description of the enterFunctionAdrs event
   167         *
   168         *  @_nodoc
   169         */
   170        metaonly config DvtTypes.MetaEventDescriptor metaEventEnterFunctionAdrs = {
   171            versionId: "2.0",
   172            analysisType: DvtTypes.DvtAnalysisType_START,
   173            displayText: "enterFunctionAdrs",
   174            tooltipText: "function entry",
   175            numParameters: 2,
   176            paramInfo: [
   177            {   name: 'Qualifier',
   178                dataDesc: DvtTypes.DvtDataDesc_INSTANCE,
   179                dataTypeName: 'Int',
   180                units: 'none',
   181                isHidden: false
   182            },
   183            {   name: 'FunctionAdrs',
   184                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   185                dataTypeName: 'Int',
   186                units: 'none',
   187                isHidden: false
   188            }
   189            ]
   190        };
   191    
   192    
   193        /*!
   194         *  ======== exitFunctionAdrs ========
   195         *  Profiling event used to log the exit point of a function
   196         *
   197         * @a(Example)
   198         * To add entry and exit hook functions to every function
   199         * 1. Use the following compiler options when compiling the source
   200         *  @p(code)
   201         *  --entry_hook=functionEntryHook
   202         *  --entry_param=address
   203         *  --exit_hook=functionExitHook
   204         *  --exit_param=address
   205         *  @p
   206         * 2. Add the following c code to implement the hook functions:
   207         *   Task_selfMacro() is used to get the current task handle in this example.
   208         *   @see enterFunction for an example of how to save CPU by logging 0
   209         *   instead of the task handle if task-aware profiling is not required.
   210         *   In order to further reduce the CPU overhead of logging the
   211             *   UIAProfile events, you can use the LogUC.h APIs. For more info, please
   212             *   see @link http://processors.wiki.ti.com/index.php/SystemAnalyzerTutorial1F
   213         *  @p(code)
   214         *  #include <xdc/runtime/Log.h>
   215         *  #include <ti/uia/events/UIAProfile.h>
   216         *  #include <ti/sysbios/knl/Task.h>
   217         *  ...
   218         * void functionEntryHook( void (*adrs)() ){
   219         *    Log_write2(UIAProfile_enterFunctionAdrs, (IArg)Task_selfMacro(),(IArg)addr);
   220         *   ...
   221         * void functionExitHook( void (*adrs)() ){
   222         *    Log_write2(UIAProfile_exitFunctionAdrs, (IArg)Task_selfMacro(),(IArg)addr);
   223         * }
   224         *  @p
   225         *  The following text will be displayed for the event:
   226         *  @p(code)
   227         *  enterFunctionAdrs: taskHandle=0x0, adrs=0x820060
   228         *  exitFunctionAdrs: taskHandle=0x0, adrs=0x820060
   229         *  @p
   230         *  @param(taskHandle)   task handle that identifies the currently active task (use 0 if not required)
   231         *  @param(functionAdrs) the address of a function that can differentiate this pair of start and stop events from others
   232         */
   233        config xdc.runtime.Log.Event exitFunctionAdrs = {
   234            mask: Diags.EXIT,
   235            msg: "exitFunctionAdrs: taskHandle=0x%x, adrs=0x%x"
   236        };
   237    
   238        /*!
   239         *  ======== metaEventExitFunction ========
   240         *  Metadata description of the exitFunctionAdrs event
   241         *
   242         *  @_nodoc
   243         */
   244        metaonly config DvtTypes.MetaEventDescriptor metaEventExitFunctionAdrs = {
   245            versionId: "2.0",
   246            analysisType: DvtTypes.DvtAnalysisType_STOP,
   247            displayText: "exitFunctionAdrs",
   248            tooltipText: "Marks the end of analysis for a module instance",
   249            numParameters: 2,
   250            paramInfo: [
   251            {   name: 'Qualifier',
   252                dataDesc: DvtTypes.DvtDataDesc_INSTANCE,
   253                dataTypeName: 'Int',
   254                units: 'none',
   255                isHidden: false
   256            },
   257            {   name: 'FunctionAdrs',
   258                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   259                dataTypeName: 'Int',
   260                units: 'none',
   261                isHidden: false
   262            }
   263            ]
   264        };
   265    
   266        /*!
   267         *  ======== enterFunctionName ========
   268         *  Profiling event used to log the entry point of a function
   269         *
   270         * @a(Example)
   271         * To add entry and exit hook functions to every function
   272         * 1. Use the following compiler options when compiling the source
   273         *  @p(code)
   274         *  --entry_hook=functionEntryHook
   275         *  --entry_param=name
   276         *  --exit_hook=functionExitHook
   277         *  --exit_param=name
   278         *  @p
   279         * 2. Add the following c code to implement the hook functions:
   280         *   The first parameter (the taskHandle) is set to  0 in this example.
   281         *   @see exitFunction for an example of how to log the current task ID
   282         *   for task-aware function profiling.
   283         *   In order to further reduce the CPU overhead of logging the
   284         *   UIAProfile events, you can use the LogUC.h APIs. For more info, please
   285         *   see @link http://processors.wiki.ti.com/index.php/SystemAnalyzerTutorial1F
   286         *  @p(code)
   287         *  #include <xdc/runtime/Log.h>
   288         *  #include <ti/uia/events/UIAProfile.h>
   289         *  ...
   290         * void functionEntryHook(const char* name ){
   291         *    Log_write2(UIAProfile_enterFunctionName, 0,(IArg)name);
   292         *   ...
   293         * void functionExitHook(const char* name){
   294         *    Log_write2(UIAProfile_exitFunctionName, 0,(IArg)name);
   295         * }
   296         *  @p
   297         *  The following text will be displayed for the event:
   298         *  @p(code)
   299         *  enterFunctionName: taskHandle=0x0, name=myFunctionName
   300         *  exitFunctionName: taskHandle0x0, name=myFunctionName
   301         *  @p
   302         *  @param(taskHandle)   task handle that identifies the currently active task (use 0 if not required)
   303         *  @param(functionName) the (const char*) name of the function that is passed to the hook fn by the compiler
   304         */
   305        config xdc.runtime.Log.Event enterFunctionName = {
   306            mask: Diags.ENTRY,
   307            msg: "enterFunctionName: taskHandle=0x%x, name=%s"
   308        };
   309    
   310        /*!
   311         *  ======== metaEventEnterFunctionName ========
   312         *  Metadata description of the enterFunctionName event
   313         *
   314         *  @_nodoc
   315         */
   316        metaonly config DvtTypes.MetaEventDescriptor metaEventEnterFunctionName = {
   317            versionId: "2.0",
   318            analysisType: DvtTypes.DvtAnalysisType_START,
   319            displayText: "enterFunctionName",
   320            tooltipText: "function entry",
   321            numParameters: 2,
   322            paramInfo: [
   323            {   name: 'Qualifier',
   324                dataDesc: DvtTypes.DvtDataDesc_INSTANCE,
   325                dataTypeName: 'Int',
   326                units: 'none',
   327                isHidden: false
   328            },
   329            {   name: 'FunctionAdrs',
   330                dataDesc: DvtTypes.DvtDataDesc_STRINGADRS,
   331                dataTypeName: 'Int',
   332                units: 'none',
   333                isHidden: false
   334            }
   335            ]
   336        };
   337    
   338    
   339        /*!
   340         *  ======== exitFunctionName ========
   341         *  Profiling event used to log the exit point of a function
   342         *
   343         * @a(Example)
   344         * To add entry and exit hook functions to every function
   345         * 1. Use the following compiler options when compiling the source
   346         *  @p(code)
   347         *  --entry_hook=functionEntryHook
   348         *  --entry_param=name
   349         *  --exit_hook=functionExitHook
   350         *  --exit_param=name
   351         *  @p
   352         * 2. Add the following c code to implement the hook functions:
   353         *   Task_selfMacro() is used to get the current task handle in this example.
   354         *   @see enterFunction for an example of how to save CPU by logging 0
   355         *   instead of the task handle if task-aware profiling is not required.
   356         *   In order to further reduce the CPU overhead of logging the
   357         *   UIAProfile events, you can use the LogUC.h APIs. For more info, please
   358         *   see @link http://processors.wiki.ti.com/index.php/SystemAnalyzerTutorial1F
   359         *  @p(code)
   360         *  #include <xdc/runtime/Log.h>
   361         *  #include <ti/uia/events/UIAProfile.h>
   362         *  #include <ti/sysbios/knl/Task.h>
   363         *  ...
   364         * void functionEntryHook(const char* name){
   365         *    Log_write2(UIAProfile_enterFunctionName, (IArg)Task_selfMacro(),(IArg)name);
   366         *   ...
   367         * void functionExitHook(const char* name){
   368         *    Log_write2(UIAProfile_exitFunctionName, (IArg)Task_selfMacro(),(IArg)name);
   369         * }
   370         *  @p
   371         *  The following text will be displayed for the event:
   372         *  @p(code)
   373         *  enterFunctionName: taskHandle=0x0, adrs=myFunctionName
   374         *  exitFunctionName: taskHandle=0x0, name=myFunctionName
   375         *  @p
   376         *  @param(taskHandle)   task handle that identifies the currently active task (use 0 if not required)
   377         *  @param(functionName) the (const char*) name of the function that is passed to the hook fn by the compiler
   378         */
   379        config xdc.runtime.Log.Event exitFunctionName = {
   380            mask: Diags.EXIT,
   381            msg: "exitFunctionName: taskHandle=0x%x, name=%s"
   382        };
   383    
   384        /*!
   385         *  ======== metaEventExitFunctionName ========
   386         *  Metadata description of the exitFunctionName event
   387         *
   388         *  @_nodoc
   389         */
   390        metaonly config DvtTypes.MetaEventDescriptor metaEventExitFunctionName = {
   391            versionId: "2.0",
   392            analysisType: DvtTypes.DvtAnalysisType_STOP,
   393            displayText: "exitFunctionName",
   394            tooltipText: "Marks the end of analysis for a module instance",
   395            numParameters: 2,
   396            paramInfo: [
   397            {   name: 'Qualifier',
   398                dataDesc: DvtTypes.DvtDataDesc_INSTANCE,
   399                dataTypeName: 'Int',
   400                units: 'none',
   401                isHidden: false
   402            },
   403            {   name: 'FunctionAdrs',
   404                dataDesc: DvtTypes.DvtDataDesc_STRINGADRS,
   405                dataTypeName: 'Int',
   406                units: 'none',
   407                isHidden: false
   408            }
   409            ]
   410        };
   411    
   412        /*!
   413         *  ======== runtimeControl ========
   414         *  Specify whether profile events can be enabled / disabled at runtime.
   415         *  (set to false by default)
   416         *
   417         *  This determines what diags settings are applied to the module's diags
   418         *  mask.
   419         *  if the UIAProfile enable config property is true (default):
   420         *    If runtimeControl = 'false' the diags bits will be configured as
   421         *    ALWAYS_ON, meaning they can't be changed at runtime.
   422         *    If runtimeControl = 'true', the bits will be configured as 'RUNTIME_ON'.
   423         *
   424         * if the UIAProfile enable config property is false:
   425         *    If runtimeControl = 'false' the diags bits will be configured as
   426         *    ALWAYS_OFF, meaning they can't be changed at runtime.
   427         *    If runtimeControl = 'true', the bits will be configured as 'RUNTIME_OFF'.
   428         */
   429        metaonly config Bool runtimeControl = false;
   430    
   431        /*!
   432         *  ======== isContextAwareProfilingEnabled ========
   433         *  Specify whether the task context that the function is executing within is logged or not
   434         *  Set to false if not using Sys/BIOS or to reduce CPU overhead.
   435         */
   436            metaonly config Bool isContextAwareProfilingEnabled = true;
   437    
   438        /*!
   439         *  ======== enable ========
   440         *  Specify whether profile events are enabled or disabled
   441         *  (set to true by default)
   442         *
   443         *  if the UIAProfile enable config property is true (default):
   444         *    If runtimeControl = 'false' the diags bits will be configured as
   445         *    ALWAYS_ON, meaning they can't be changed at runtime.
   446         *    If runtimeControl = 'true', the bits will be configured as 'RUNTIME_ON'.
   447         *
   448         * if the UIAProfile enable config property is false:
   449         *    If runtimeControl = 'false' the diags bits will be configured as
   450         *    ALWAYS_OFF, meaning they can't be changed at runtime.
   451         *    If runtimeControl = 'true', the bits will be configured as 'RUNTIME_OFF'.
   452         */
   453        metaonly config Bool enable = true;
   454    }