1    /*
     2     * Copyright (c) 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     * ======== UIAThreadCtx.xdc ========
    35     */
    36    
    37    import xdc.runtime.Types;
    38    import xdc.runtime.Diags;
    39    import ti.uia.events.IUIACtx;
    40    import xdc.rov.ViewInfo;
    41    
    42    /*!
    43     * UIA Thread Context Instrumentation
    44     *
    45     * The UIAThreadCtx module defines context change events
    46     * and methods that allow tooling to identify thread context
    47     * switches and to enable thread-aware filtering, trace and
    48     * analysis.
    49     *
    50     * It inherits IUIACtx, which defines a function pointer to
    51     * an isLoggingEnabled function which, if configured to point to
    52     * a function, will evaluate the function prior to logging the context
    53     * change event and will determine whether to log the event based on the
    54     * return value of the function.  If the function is not configured,
    55     * logging will be conditional upon ti_uia_runtime_CtxFilter_module->mIsLoggingEnabled.
    56     *
    57     * The generation of UIAThreadCtx events is also controlled by a module's diagnostics
    58     * mask, which is described in details in `{@link xdc.runtime.Diags}`.
    59     * 'UIAThreadCtx` events are generated only when the Diags.ANALYSIS bit is set
    60     * in the module's diagnostics mask.
    61     *
    62     * The following configuration script demonstrates how the application might
    63     * control the logging of ANALYSIS events embedded in the `Mod` module at configuration
    64     * time. In this case, the configuration script arranges for the `Log`
    65     * statements within modules to always generate ANALYSIS events.
    66     * Without these configuration statements, no ANALYSIS events would be generated
    67     * by any modules.
    68     *
    69     * @a(Examples)
    70     * Example 1: This is part of the XDC configuration file for the application:
    71     *
    72     *  @p(code)
    73     *  var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
    74     *  var Diags = xdc.useModule('xdc.runtime.Diags');
    75     *  var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
    76     *  var Defaults = xdc.useModule('xdc.runtime.Defaults');
    77     *  var logger = LoggerSys.create();
    78     *
    79     *  Defaults.common$.diags_ANALYSIS = Diags.ALWAYS_ON;
    80     *  Defaults.common$.logger = logger;
    81     *  @p
    82     *
    83     *  @p(html)
    84     *  <hr />
    85     *  @p
    86     *
    87     * Example 2: The following example configures a module to support logging
    88     * of ANALYSIS events, but defers the actual activation and deactivation of the
    89     * logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
    90     * function for details on specifying the control string.
    91     *
    92     * This is a part of the XDC configuration file for the application:
    93     *
    94     *  @p(code)
    95     *  var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
    96     *  var Diags = xdc.useModule('xdc.runtime.Diags');
    97     *  var Mod = xdc.useModule('my.pkg.Mod');
    98     *
    99     *  Mod.common$.diags_ANALYSIS = Diags.RUNTIME_OFF;
   100     *  @p
   101     *
   102     *  This is a part of the C code for the application:
   103     *
   104     *  @p(code)
   105     *  // turn on logging of ANALYSIS events in the module
   106     *  Diags_setMask("my.pkg.Mod+Z");
   107     *
   108     *  // turn off logging of ANALYSIS events in the module
   109     *  Diags_setMask("my.pkg.Mod-Z");
   110     *  @p
   111     */
   112    @CustomHeader
   113    module UIAThreadCtx inherits IUIACtx {
   114    
   115        /*!
   116         *  @_nodoc
   117         *  ======== ModuleView ========
   118         */
   119        metaonly struct ModuleView {
   120            UInt mLastValue;
   121            UInt mEnableOnValue;
   122        }
   123    
   124        /*!
   125         *  @_nodoc
   126         *  ======== rovViewInfo ========
   127         */
   128        @Facet
   129        metaonly config ViewInfo.Instance rovViewInfo =
   130            ViewInfo.create({
   131                viewMap: [['Module',   {type: ViewInfo.MODULE,
   132                                        viewInitFxn: 'viewInitModule',
   133                                        structName: 'ModuleView'}
   134                          ]]
   135            });
   136    
   137        /*!
   138         *  ======== ctxChg ========
   139         *  threadSwitch Context Change event
   140         *
   141         *  Used to log a thread switch
   142         *  Note that the previous thread Id is logged automatically by the ti_uia_runtime_LogCtxChg_thread
   143         *  API.
   144         *  If ti_uia_events_UIAThreadCtx_isLoggingEnabledFxn is not NULL
   145         *  it is called and its return value determines whether logging is enabled or not.
   146         *
   147         *  @a(Example)
   148         *   The following C code shows how to log a Thread Context Change
   149         *   event that identifies a new thread using a BIOS task switch hook function
   150         *
   151         *  @p(code)
   152         *  #include <ti/uia/runtime/LogCtxChg.h>
   153         *  ...
   154         *  Void  tskSwitchHook(Task_Handle hOldTask,Task_Handle hNewTask){
   155         *          LogCtxChg_thread("thread: new = 0x%x",(Int)hNewTask);
   156         *  }
   157         *  @p
   158         *  This event prints the Log call site (%$F) and a format string (%$S)
   159         *  which is recursively formatted with any addition arguments.
   160         *  The following text is an example of what will be displayed for the event:
   161         *  @p(code)
   162         *  "Thread Ctx Change at Line 123 in demo.c [Prev. thread ID=0x1234] New thread ID=0x1235"
   163         *
   164         *  @param(fmt)   a constant string that describes the context change and provides a format specifier for newThreadId
   165         *  @param(newThreadId)   an integer which uniquely identifies the new context
   166         */
   167        config xdc.runtime.Log.Event ctxChg = {
   168            mask: Diags.ANALYSIS,
   169            msg: "Thread Ctx Change at %$F [Prev. thread ID = 0x%x] %$S"};
   170    
   171        /*!
   172         *  ======== metaEventThreadCtxChg ========
   173         *  Metadata description of the Thread Context Change event
   174         *
   175         *  @_nodoc
   176         */
   177        metaonly config DvtTypes.MetaEventDescriptor metaEventThreadCtxChg = {
   178            versionId: "2.0",
   179            analysisType: DvtTypes.DvtAnalysisType_CONTEXTCHANGE,
   180            displayText: "Thread Ctx Change",
   181            tooltipText: "Thread Context Change",
   182            numParameters: 5,
   183            paramInfo: [
   184            {   name: '__FILE__',
   185                dataDesc: DvtTypes.DvtDataDesc_FILENAMESTR,
   186                dataTypeName: 'String',
   187                units: 'none',
   188                isHidden: false
   189            },
   190            {   name: '__LINE__',
   191                dataDesc: DvtTypes.DvtDataDesc_LINENUM,
   192                dataTypeName: 'Int',
   193                units: 'none',
   194                isHidden: false
   195            },
   196            {   name: 'Prev. Thread ID',
   197                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   198                dataTypeName: 'Int',
   199                units: 'none',
   200                isHidden: false
   201            },
   202            {   name: 'fmt',
   203                dataDesc: DvtTypes.DvtDataDesc_FMTSTR,
   204                dataTypeName: 'String',
   205                units: 'none',
   206                isHidden: false
   207            },
   208            {   name: 'New Thread ID',
   209                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   210                dataTypeName: 'Int',
   211                units: 'none',
   212                isHidden: false
   213            }]
   214    
   215        };
   216        /*!
   217         *  ======== ctxChgWithFunc ========
   218         *  threadSwitch Context Change event with prempted function and resumed function addresses
   219         *
   220         *  Used to log a thread switch along with function info (preempted function and new function)
   221         *  Note that the previous thread Id is logged automatically by the ti_uia_runtime_LogCtxChg_threadAndFunc
   222         *  API.
   223         *  If ti_uia_events_UIAThreadCtx_isLoggingEnabledFxn is not NULL
   224         *  it is called and its return value determines whether logging is enabled or not.
   225         *
   226         *  @a(Example)
   227         *   The following C code shows how to log a Thread Context Change
   228         *   event that identifies a new thread, the preempted function and the preempting function.
   229         *
   230         *  @p(code)
   231         *  #include <ti/uia/runtime/LogCtxChg.h>
   232         *  ...
   233         *  LogCtxChg_threadAndFunc("New thread ID=0x%x, oldFunc=0x%x, newFunc=0x%x",(Int)hNewTask, (Int)&oldFunc,(Int)&newFunc);
   234         *
   235         *  @p
   236         *  This event prints the Log call site (%$F) and a format string (%$S)
   237         *  which is recursively formatted with any addition arguments.
   238         *  The following text is an example of what will be displayed for the event:
   239         *  @p(code)
   240         *  "Thread CtxChgWithFunc at Line 123 in demo.c [Prev. thread ID=0x1234] New thread ID=0x1235, oldFunc=0x80001200, newFunc=0x80001080"
   241         *
   242         *  @param(fmt)   a constant string that describes the context change and provides a format specifier for newThreadId
   243         *  @param(newThreadId)   an integer which uniquely identifies the new context
   244         *  @param(oldFunc)   the address of the function that was preempted
   245         *  @param(newFunc)   the address of the function that is being resumed
   246         */
   247        config xdc.runtime.Log.Event ctxChgWithFunc = {
   248            mask: Diags.ANALYSIS,
   249            msg: "Thread CtxChgWithFunc at %$F [Prev. threadId = 0x%x] %$S"};
   250    
   251        /*!
   252         *  ======== metaEventThreadCtxChgWithFunc ========
   253         *  Metadata description of the Application Context Change event
   254         *
   255         *  @_nodoc
   256         */
   257        metaonly config DvtTypes.MetaEventDescriptor metaEventThreadCtxChgWithFunc = {
   258            versionId: "2.0",
   259            analysisType: DvtTypes.DvtAnalysisType_CONTEXTCHANGE,
   260            displayText: "Thread Ctx Change with function addresses",
   261            tooltipText: "Thread Context Change with function addresses",
   262            numParameters: 7,
   263            paramInfo: [
   264            {   name: '__FILE__',
   265                dataDesc: DvtTypes.DvtDataDesc_FILENAMESTR,
   266                dataTypeName: 'String',
   267                units: 'none',
   268                isHidden: false
   269            },
   270            {   name: '__LINE__',
   271                dataDesc: DvtTypes.DvtDataDesc_LINENUM,
   272                dataTypeName: 'Int',
   273                units: 'none',
   274                isHidden: false
   275            },
   276            {   name: 'Prev. Thread ID',
   277                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   278                dataTypeName: 'Int',
   279                units: 'none',
   280                isHidden: false
   281            },
   282            {   name: 'fmt',
   283                dataDesc: DvtTypes.DvtDataDesc_FMTSTR,
   284                dataTypeName: 'String',
   285                units: 'none',
   286                isHidden: false
   287            },
   288            {   name: 'New Frame ID',
   289                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   290                dataTypeName: 'Int',
   291                units: 'none',
   292                isHidden: false
   293            },
   294            {   name: 'Preempted Function Address',
   295                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   296                dataTypeName: 'Int',
   297                units: 'none',
   298                isHidden: false
   299            },
   300            {   name: 'Resumed Function Address',
   301                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   302                dataTypeName: 'Int',
   303                units: 'none',
   304                isHidden: false
   305            }
   306            ]
   307    
   308        };
   309        /*!
   310         * ======== getCtxId ========
   311         * Get the ID for the current thread
   312         *
   313         *  @a(returns)
   314         *  returns the thread ID logged by the last call to UIAThreadCtx_logCtxChg.
   315         */
   316        @DirectCall
   317        UInt getCtxId();
   318    
   319        /*!
   320         * ======== getEnableOnValue ========
   321         * Get the EnableOn value
   322         *
   323         *  @a(returns) returns the thread ID value that logging will be enabled for.
   324         */
   325        @DirectCall
   326        UInt getEnableOnValue();
   327    
   328        /*!
   329         * ======== setEnableOnValue ========
   330         * Set the EnableOn value
   331         *
   332         *  @param(value) the CtxId value that logging will be enabled for.
   333         */
   334        @DirectCall
   335        Void setEnableOnValue(UInt value);
   336    
   337        /*!
   338         * ======== isLoggingEnabled ========
   339         * returns true if the new context matches the value to enable logging with.
   340         *
   341         *  Default implementation of the IUIACtx_IsLoggingEnabledFxn for user context.
   342         *  To enable context-aware filtering, in the .cfg script assign
   343         *    UIAThreadCtx_isLoggingEnabledFxn = '&UIAThreadCtx_isLoggingEnabled'
   344         *  or assign your own implementation of this function.
   345         *
   346         *  @param(newThreadId) the new thread ID
   347         *  @a(returns) true if logging is enabled
   348         */
   349         @DirectCall
   350         Bool isLoggingEnabled(UInt newThreadId);
   351    
   352        /*!
   353         * ======== setOldValue =========
   354         * sets ti_uia_events_UIAThreadCtx_gLastValue to the new value and returns the old value before it was updated.
   355         *
   356         * @param(newValue) the new value to save in the global variable
   357         * @a(return0       the original value of the global variable before it was updated.
   358         */
   359         @DirectCall
   360         UInt setOldValue(UInt newValue);
   361    
   362    internal:
   363    
   364            struct Module_State {
   365            UInt mLastValue;
   366            UInt mEnableOnValue;
   367        };
   368    }