tracesrv/tracecore/btrace_handler/src/BTraceKernelCategoryHandler.cpp
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
// Trace Core 
hgs
parents:
diff changeset
    15
//
hgs
parents:
diff changeset
    16
hgs
parents:
diff changeset
    17
// Include files
hgs
parents:
diff changeset
    18
#include "BTraceKernelCategoryHandler.h"
hgs
parents:
diff changeset
    19
#include "BTraceOstCategoryBitmap.h"
hgs
parents:
diff changeset
    20
#include "TraceCore.h"
hgs
parents:
diff changeset
    21
#include "TraceCoreDebug.h"
hgs
parents:
diff changeset
    22
#include "TraceCoreConstants.h"
hgs
parents:
diff changeset
    23
hgs
parents:
diff changeset
    24
#include "OstTraceDefinitions.h"
hgs
parents:
diff changeset
    25
hgs
parents:
diff changeset
    26
#ifdef OST_TRACE_COMPILER_IN_USE
hgs
parents:
diff changeset
    27
#include "BTraceKernelCategoryHandlerTraces.h"
hgs
parents:
diff changeset
    28
#endif
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
#include "TraceCoreTComArgMacro.h"
hgs
parents:
diff changeset
    31
hgs
parents:
diff changeset
    32
//Split: These needed from TraceCoreAutogen.h (which is removed):
hgs
parents:
diff changeset
    33
#define SYMBIAN_CF_SERVERDEN 0xC2
hgs
parents:
diff changeset
    34
#define SYMBIAN_CF_MESHMACHINE 0xC3
hgs
parents:
diff changeset
    35
#define SYMBIAN_CF_FACTORIES 0xC4
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
/**
hgs
parents:
diff changeset
    38
 * Length of BTrace header
hgs
parents:
diff changeset
    39
 */
hgs
parents:
diff changeset
    40
const TUint KBTraceHeaderLen = 4;
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
/**
hgs
parents:
diff changeset
    43
 * Length of single BTrace variable
hgs
parents:
diff changeset
    44
 */
hgs
parents:
diff changeset
    45
const TUint KBTraceVariableLen = 4;
hgs
parents:
diff changeset
    46
hgs
parents:
diff changeset
    47
/**
hgs
parents:
diff changeset
    48
 * Four bytes
hgs
parents:
diff changeset
    49
 */
hgs
parents:
diff changeset
    50
const TUint KFourBytes = 4;
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
// Trace group shift when checking if group is active
hgs
parents:
diff changeset
    53
#define GRP_SHIFT 16
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
// BTrace category shift for unknown categories
hgs
parents:
diff changeset
    56
#define CATEGORY_SHIFT 8
hgs
parents:
diff changeset
    57
hgs
parents:
diff changeset
    58
/**
hgs
parents:
diff changeset
    59
 * Constructor
hgs
parents:
diff changeset
    60
 */
hgs
parents:
diff changeset
    61
DBTraceKernelCategoryHandler::DBTraceKernelCategoryHandler()
hgs
parents:
diff changeset
    62
: iPrimeDfc( DBTraceKernelCategoryHandler::PrimeDfc, this, DTraceCore::GetActivationQ(), KDefaultDfcPriority )
hgs
parents:
diff changeset
    63
, iMultiPartActivationInfos(2, _FOFF( TMultiPartActivationInfo, iMultiPartId ))
hgs
parents:
diff changeset
    64
    {
hgs
parents:
diff changeset
    65
    }
hgs
parents:
diff changeset
    66
hgs
parents:
diff changeset
    67
hgs
parents:
diff changeset
    68
/**
hgs
parents:
diff changeset
    69
 * Destructor
hgs
parents:
diff changeset
    70
 */
hgs
parents:
diff changeset
    71
DBTraceKernelCategoryHandler::~DBTraceKernelCategoryHandler()
hgs
parents:
diff changeset
    72
    {
hgs
parents:
diff changeset
    73
    iMultiPartActivationInfos.Close();
hgs
parents:
diff changeset
    74
    }
hgs
parents:
diff changeset
    75
hgs
parents:
diff changeset
    76
hgs
parents:
diff changeset
    77
/**
hgs
parents:
diff changeset
    78
 * Initializes this handler
hgs
parents:
diff changeset
    79
 *
hgs
parents:
diff changeset
    80
 * @param aHandler The BTrace handler
hgs
parents:
diff changeset
    81
 */
hgs
parents:
diff changeset
    82
TInt DBTraceKernelCategoryHandler::Init()
hgs
parents:
diff changeset
    83
    {
hgs
parents:
diff changeset
    84
    TInt ret( KErrGeneral );
hgs
parents:
diff changeset
    85
hgs
parents:
diff changeset
    86
    DTraceCore* traceCore = DTraceCore::GetInstance();
hgs
parents:
diff changeset
    87
    if ( traceCore != NULL )
hgs
parents:
diff changeset
    88
        {
hgs
parents:
diff changeset
    89
        // Gets the Autogen category bitmap from the list of registered activation interfaces
hgs
parents:
diff changeset
    90
        iTraceBitmap = static_cast< DBTraceOstCategoryBitmap* >( 
hgs
parents:
diff changeset
    91
                traceCore->GetActivation( KKernelHooksOSTComponentUID ) );
hgs
parents:
diff changeset
    92
        if ( iTraceBitmap != NULL )
hgs
parents:
diff changeset
    93
            {
hgs
parents:
diff changeset
    94
            // Registers to bitmap for change notifications. The primary BTrace filters are
hgs
parents:
diff changeset
    95
            // updated when the bitmap changes
hgs
parents:
diff changeset
    96
            iTraceBitmap->RegisterActivationNotification( *this );
hgs
parents:
diff changeset
    97
            ret = KErrNone;
hgs
parents:
diff changeset
    98
            }
hgs
parents:
diff changeset
    99
        }
hgs
parents:
diff changeset
   100
    
hgs
parents:
diff changeset
   101
    // Registers kernel categories to BTrace
hgs
parents:
diff changeset
   102
    if ( ret == KErrNone )
hgs
parents:
diff changeset
   103
        {
hgs
parents:
diff changeset
   104
        for ( TInt i = KMinKernelCategory; ( ret == KErrNone ) && ( i <= KMaxKernelCategory ); i++ )
hgs
parents:
diff changeset
   105
            {
hgs
parents:
diff changeset
   106
            ret = AddCategory( i );
hgs
parents:
diff changeset
   107
            }
hgs
parents:
diff changeset
   108
hgs
parents:
diff changeset
   109
        if ( ret == KErrNone )
hgs
parents:
diff changeset
   110
            {
hgs
parents:
diff changeset
   111
            ret = Register();
hgs
parents:
diff changeset
   112
            }
hgs
parents:
diff changeset
   113
        }
hgs
parents:
diff changeset
   114
    TC_TRACE( ETraceLevelFlow, Kern::Printf( "<DBTraceKernelCategoryHandler::Init() - %d", ret ) );
hgs
parents:
diff changeset
   115
    return ret;
hgs
parents:
diff changeset
   116
    }
hgs
parents:
diff changeset
   117
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
/**
hgs
parents:
diff changeset
   120
 * Called before SetWriter with interrupts enabled
hgs
parents:
diff changeset
   121
 * 
hgs
parents:
diff changeset
   122
 * @param aWriter The new writer
hgs
parents:
diff changeset
   123
 */
hgs
parents:
diff changeset
   124
void DBTraceKernelCategoryHandler::PrepareSetWriter( DTraceCoreWriter* aWriter )
hgs
parents:
diff changeset
   125
    {
hgs
parents:
diff changeset
   126
    OstTrace1( TRACE_FLOW, DBTRACEKERNELCATEGORYHANDLER_PREPARESETWRITER_ENTRY,"> DBTraceKernelCategoryHandler::PrepareSetWriter 0x%x", ( TUint )( aWriter ) );
hgs
parents:
diff changeset
   127
    if ( iWriter == NULL && aWriter != NULL )
hgs
parents:
diff changeset
   128
        {
hgs
parents:
diff changeset
   129
        DBTraceCategoryHandler::PrepareSetWriter( aWriter );
hgs
parents:
diff changeset
   130
        // When writer is set, the kernel categories are primed
hgs
parents:
diff changeset
   131
        // Priming is done via DFC.
hgs
parents:
diff changeset
   132
        PrimeKernelCategories();
hgs
parents:
diff changeset
   133
        }
hgs
parents:
diff changeset
   134
    else
hgs
parents:
diff changeset
   135
        {
hgs
parents:
diff changeset
   136
        DBTraceCategoryHandler::PrepareSetWriter( aWriter );
hgs
parents:
diff changeset
   137
        if ( aWriter == NULL )
hgs
parents:
diff changeset
   138
            {
hgs
parents:
diff changeset
   139
            // If writer is set to NULL, the kernel categories are disabled. 
hgs
parents:
diff changeset
   140
            // This needs to be done immediately, not via timer
hgs
parents:
diff changeset
   141
            PrimeDfc();
hgs
parents:
diff changeset
   142
            }
hgs
parents:
diff changeset
   143
        }
hgs
parents:
diff changeset
   144
    if ( aWriter != NULL && aWriter->GetWriterType() == EWriterTypeUSBPhonet )
hgs
parents:
diff changeset
   145
        {
hgs
parents:
diff changeset
   146
        // CPU events must be disabled when using media writer
hgs
parents:
diff changeset
   147
        PrimeCategory( BTrace::ECpuUsage );
hgs
parents:
diff changeset
   148
        }
hgs
parents:
diff changeset
   149
    }
hgs
parents:
diff changeset
   150
hgs
parents:
diff changeset
   151
hgs
parents:
diff changeset
   152
/**
hgs
parents:
diff changeset
   153
 * Handler for KCategoryNokiaAutogen
hgs
parents:
diff changeset
   154
 *
hgs
parents:
diff changeset
   155
 * @param aHeader BTrace header
hgs
parents:
diff changeset
   156
 * @param aHeader2 Extra header data
hgs
parents:
diff changeset
   157
 * @param aContext The thread context in which this function was called
hgs
parents:
diff changeset
   158
 * @param a1 The first trace parameter
hgs
parents:
diff changeset
   159
 * @param a2 The second trace parameter
hgs
parents:
diff changeset
   160
 * @param a3 The third trace parameter
hgs
parents:
diff changeset
   161
 * @param aExtra Extra trace data
hgs
parents:
diff changeset
   162
 * @param aPc The program counter value
hgs
parents:
diff changeset
   163
 * @return ETrue if trace was processed, EFalse if not
hgs
parents:
diff changeset
   164
 */
hgs
parents:
diff changeset
   165
TBool DBTraceKernelCategoryHandler::HandleFrame( TUint32 aHeader, TUint32 aHeader2, const TUint32 aContext, 
hgs
parents:
diff changeset
   166
                                                  const TUint32 a1, const TUint32 a2, const TUint32 a3, 
hgs
parents:
diff changeset
   167
                                                  const TUint32 aExtra, const TUint32 aPc )
hgs
parents:
diff changeset
   168
    {
hgs
parents:
diff changeset
   169
    TBool retval;
hgs
parents:
diff changeset
   170
    if ( iWriter != NULL )
hgs
parents:
diff changeset
   171
        {
hgs
parents:
diff changeset
   172
        //deal with any possible missing traces
hgs
parents:
diff changeset
   173
        DTraceCore* tracecore = DTraceCore::GetInstance();
hgs
parents:
diff changeset
   174
        if(!tracecore)
hgs
parents:
diff changeset
   175
            return EFalse;
hgs
parents:
diff changeset
   176
        
hgs
parents:
diff changeset
   177
        // Check if tracing is certified
hgs
parents:
diff changeset
   178
        if (!tracecore->IsTraceCertified())
hgs
parents:
diff changeset
   179
            return EFalse;
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
        if ((tracecore->PreviousTraceDropped())) //if previous trace was dropped 
hgs
parents:
diff changeset
   182
            {
hgs
parents:
diff changeset
   183
            //set flags back to EFalse first
hgs
parents:
diff changeset
   184
            tracecore->SetPreviousTraceDropped(EFalse);
hgs
parents:
diff changeset
   185
hgs
parents:
diff changeset
   186
            //set missing flag in BTrace
hgs
parents:
diff changeset
   187
            aHeader |= BTrace::EMissingRecord<<(BTrace::EFlagsIndex * KByteSize);
hgs
parents:
diff changeset
   188
            }
hgs
parents:
diff changeset
   189
        
hgs
parents:
diff changeset
   190
        TUint8 category = ( aHeader >> ( BTrace::ECategoryIndex * KByteSize ) ) & KByteMask;
hgs
parents:
diff changeset
   191
        TUint8 subCategory = ( aHeader >> ( BTrace::ESubCategoryIndex * KByteSize ) ) & KByteMask;
hgs
parents:
diff changeset
   192
        TUint32 traceWord = MapCategoryToID( category, subCategory );
hgs
parents:
diff changeset
   193
        if ( traceWord > 0 )
hgs
parents:
diff changeset
   194
            {
hgs
parents:
diff changeset
   195
            
hgs
parents:
diff changeset
   196
            // Check if the trace is a multipart trace
hgs
parents:
diff changeset
   197
            TBool isMultiPart = CheckMultiPart(aHeader, aHeader2);
hgs
parents:
diff changeset
   198
            if (isMultiPart)
hgs
parents:
diff changeset
   199
                {
hgs
parents:
diff changeset
   200
                // Handle the multipart trace
hgs
parents:
diff changeset
   201
                retval = HandleMultiPart(aHeader, aHeader2, aContext, traceWord, a2, a3, aExtra, aPc);
hgs
parents:
diff changeset
   202
                }
hgs
parents:
diff changeset
   203
            
hgs
parents:
diff changeset
   204
            // Not a multipart trace
hgs
parents:
diff changeset
   205
            else 
hgs
parents:
diff changeset
   206
                {
hgs
parents:
diff changeset
   207
                // If previous trace was discarded, add info about it to the header
hgs
parents:
diff changeset
   208
                if (tracecore->PreviousTraceDropped())
hgs
parents:
diff changeset
   209
                    {
hgs
parents:
diff changeset
   210
                    aHeader |= BTrace::EMissingRecord<<(BTrace::EFlagsIndex * KByteSize);
hgs
parents:
diff changeset
   211
                    tracecore->SetPreviousTraceDropped(EFalse);
hgs
parents:
diff changeset
   212
                    }
hgs
parents:
diff changeset
   213
                
hgs
parents:
diff changeset
   214
                TUint8 recordSize = static_cast< TUint8 >( ( aHeader >> ( BTrace::ESizeIndex * KByteSize ) ) & KByteMask );
hgs
parents:
diff changeset
   215
                iWriter->WriteTraceCoreFrame( KKernelHooksOSTComponentUID, 
hgs
parents:
diff changeset
   216
                    traceWord, aHeader, aHeader2, aContext, a1, a2, a3, aExtra, aPc, recordSize );
hgs
parents:
diff changeset
   217
hgs
parents:
diff changeset
   218
                retval = ETrue;
hgs
parents:
diff changeset
   219
                }
hgs
parents:
diff changeset
   220
            }
hgs
parents:
diff changeset
   221
        else
hgs
parents:
diff changeset
   222
            {
hgs
parents:
diff changeset
   223
            retval = EFalse;
hgs
parents:
diff changeset
   224
            }
hgs
parents:
diff changeset
   225
        }
hgs
parents:
diff changeset
   226
    else
hgs
parents:
diff changeset
   227
        {
hgs
parents:
diff changeset
   228
        retval = EFalse;
hgs
parents:
diff changeset
   229
        }
hgs
parents:
diff changeset
   230
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf("<DBTraceKernelCategoryHandler::HandleFrame - return %d", retval ) );
hgs
parents:
diff changeset
   231
    return retval;
hgs
parents:
diff changeset
   232
    }
hgs
parents:
diff changeset
   233
hgs
parents:
diff changeset
   234
hgs
parents:
diff changeset
   235
/**
hgs
parents:
diff changeset
   236
 * Maps a BTrace category / sub-category to group / trace ID
hgs
parents:
diff changeset
   237
 *
hgs
parents:
diff changeset
   238
 * @param aCategory The BTrace category
hgs
parents:
diff changeset
   239
 * @param aSubCategory The BTrace sub-categoory
hgs
parents:
diff changeset
   240
 * @return The group / trace ID combination
hgs
parents:
diff changeset
   241
 */
hgs
parents:
diff changeset
   242
TUint32 DBTraceKernelCategoryHandler::MapCategoryToID( TUint8 aCategory, TUint8 aSubCategory )
hgs
parents:
diff changeset
   243
    {
hgs
parents:
diff changeset
   244
    TUint32 ret;
hgs
parents:
diff changeset
   245
    
hgs
parents:
diff changeset
   246
    switch( aCategory )
hgs
parents:
diff changeset
   247
        {
hgs
parents:
diff changeset
   248
        case BTrace::EThreadIdentification:
hgs
parents:
diff changeset
   249
        case BTrace::ECpuUsage:
hgs
parents:
diff changeset
   250
        case BTrace::EClientServer:
hgs
parents:
diff changeset
   251
        case BTrace::ERequests:
hgs
parents:
diff changeset
   252
        case BTrace::EChunks:
hgs
parents:
diff changeset
   253
        case BTrace::ECodeSegs:
hgs
parents:
diff changeset
   254
        case BTrace::EPaging:
hgs
parents:
diff changeset
   255
        case BTrace::EThreadPriority:
hgs
parents:
diff changeset
   256
        case BTrace::EPagingMedia:
hgs
parents:
diff changeset
   257
            ret = ( aCategory << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   258
            break;
hgs
parents:
diff changeset
   259
            
hgs
parents:
diff changeset
   260
        // Symbian 9.4 categories
hgs
parents:
diff changeset
   261
        case BTrace::EKernelMemory:
hgs
parents:
diff changeset
   262
        case BTrace::EHeap:
hgs
parents:
diff changeset
   263
        case BTrace::EMetaTrace:
hgs
parents:
diff changeset
   264
        case BTrace::ERamAllocator:
hgs
parents:
diff changeset
   265
        case BTrace::EFastMutex:     
hgs
parents:
diff changeset
   266
        case BTrace::EProfiling:
hgs
parents:
diff changeset
   267
            ret = ( aCategory << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   268
            break;
hgs
parents:
diff changeset
   269
            
hgs
parents:
diff changeset
   270
        // Symbian 9.5 categories            
hgs
parents:
diff changeset
   271
        case BTrace::EResourceManager:
hgs
parents:
diff changeset
   272
        case BTrace::EResourceManagerUs:
hgs
parents:
diff changeset
   273
        case BTrace::ERawEvent:
hgs
parents:
diff changeset
   274
        case BTrace::EUsb:
hgs
parents:
diff changeset
   275
        case BTrace::ESymbianKernelSync:
hgs
parents:
diff changeset
   276
        case BTrace::EFlexibleMemModel:
hgs
parents:
diff changeset
   277
            ret = ( aCategory << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   278
            break;
hgs
parents:
diff changeset
   279
            
hgs
parents:
diff changeset
   280
        // Symbian 9.6 categories            
hgs
parents:
diff changeset
   281
        case BTrace::EIic:
hgs
parents:
diff changeset
   282
            ret = ( aCategory << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   283
            break;                                                   
hgs
parents:
diff changeset
   284
hgs
parents:
diff changeset
   285
        // These are for Symbian for debugging purposes
hgs
parents:
diff changeset
   286
		case 194:
hgs
parents:
diff changeset
   287
			ret = ( SYMBIAN_CF_SERVERDEN << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   288
			break;
hgs
parents:
diff changeset
   289
		case 195:
hgs
parents:
diff changeset
   290
			ret = ( SYMBIAN_CF_MESHMACHINE << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   291
			break;
hgs
parents:
diff changeset
   292
		case 196:
hgs
parents:
diff changeset
   293
			ret = ( SYMBIAN_CF_FACTORIES << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   294
			break;
hgs
parents:
diff changeset
   295
				
hgs
parents:
diff changeset
   296
        default:
hgs
parents:
diff changeset
   297
            // Unknown category but let's still use the same ID as we received
hgs
parents:
diff changeset
   298
            ret = ( aCategory << GRP_SHIFT ) | aSubCategory;
hgs
parents:
diff changeset
   299
            break;
hgs
parents:
diff changeset
   300
        }
hgs
parents:
diff changeset
   301
hgs
parents:
diff changeset
   302
    return ret;
hgs
parents:
diff changeset
   303
    }
hgs
parents:
diff changeset
   304
hgs
parents:
diff changeset
   305
hgs
parents:
diff changeset
   306
/**
hgs
parents:
diff changeset
   307
 * Called when an activation bitmap state changes
hgs
parents:
diff changeset
   308
 * 
hgs
parents:
diff changeset
   309
 * @param aActivation the activation object
hgs
parents:
diff changeset
   310
 * @param aFromSettings ETrue if changes was due to settings read
hgs
parents:
diff changeset
   311
 * @param aComponentId Component ID of the activation
hgs
parents:
diff changeset
   312
 */
hgs
parents:
diff changeset
   313
void DBTraceKernelCategoryHandler::ActivationChanged( MTraceCoreActivation& TCOM_ARG(aActivation), TBool TCOM_ARG(aFromSettings),
hgs
parents:
diff changeset
   314
        TUint32 aComponentId)
hgs
parents:
diff changeset
   315
    {
hgs
parents:
diff changeset
   316
    OstTraceExt2( TRACE_FLOW, DBTRACEKERNELCATEGORYHANDLER_ACTIVATIONCHANGED_ENTRY,"> DBTraceKernelCategoryHandler::ActivationChanged 0x%x. FromSettings:%d",( TUint )( &aActivation ), aFromSettings );
hgs
parents:
diff changeset
   317
    
hgs
parents:
diff changeset
   318
    // Kernel categories are primed when activation bitmap changes
hgs
parents:
diff changeset
   319
    if (aComponentId == KOldNokiaAutogenOSTComponentUID || aComponentId == KKernelHooksOSTComponentUID)
hgs
parents:
diff changeset
   320
        {
hgs
parents:
diff changeset
   321
        PrimeKernelCategories();
hgs
parents:
diff changeset
   322
        }
hgs
parents:
diff changeset
   323
    }
hgs
parents:
diff changeset
   324
hgs
parents:
diff changeset
   325
hgs
parents:
diff changeset
   326
/**
hgs
parents:
diff changeset
   327
 * Primes the kernel categories    
hgs
parents:
diff changeset
   328
 */
hgs
parents:
diff changeset
   329
void DBTraceKernelCategoryHandler::PrimeKernelCategories()
hgs
parents:
diff changeset
   330
    {
hgs
parents:
diff changeset
   331
    // Priming is done asynchronously to avoid blocking this thread
hgs
parents:
diff changeset
   332
    iPrimeDfc.Enque();
hgs
parents:
diff changeset
   333
    }
hgs
parents:
diff changeset
   334
hgs
parents:
diff changeset
   335
hgs
parents:
diff changeset
   336
/**
hgs
parents:
diff changeset
   337
 * Dfc function to prime kernel categories
hgs
parents:
diff changeset
   338
 */
hgs
parents:
diff changeset
   339
void DBTraceKernelCategoryHandler::PrimeDfc( TAny* aHandler )
hgs
parents:
diff changeset
   340
    {
hgs
parents:
diff changeset
   341
    OstTrace1( TRACE_FLOW, DBTRACEKERNELCATEGORYHANDLER_PRIMEDFC_ENTRY,"> DBTraceKernelCategoryHandler::PrimeDfc 0x%x", ( TUint )( aHandler ) );
hgs
parents:
diff changeset
   342
    
hgs
parents:
diff changeset
   343
    // Get handler and prime kernel categories
hgs
parents:
diff changeset
   344
    DBTraceKernelCategoryHandler* handler = static_cast< DBTraceKernelCategoryHandler* >( aHandler );
hgs
parents:
diff changeset
   345
    handler->PrimeDfc();
hgs
parents:
diff changeset
   346
    }
hgs
parents:
diff changeset
   347
hgs
parents:
diff changeset
   348
hgs
parents:
diff changeset
   349
/**
hgs
parents:
diff changeset
   350
 * Called from the static DFC callback function
hgs
parents:
diff changeset
   351
 */
hgs
parents:
diff changeset
   352
void DBTraceKernelCategoryHandler::PrimeDfc()
hgs
parents:
diff changeset
   353
    {
hgs
parents:
diff changeset
   354
    OstTrace0( TRACE_FLOW, DBTRACEKERNELCATEGORYHANDLER_PRIMEDFC,
hgs
parents:
diff changeset
   355
    		"> DBTraceKernelCategoryHandler::PrimeDfc" );
hgs
parents:
diff changeset
   356
    		
hgs
parents:
diff changeset
   357
    // Start from Thread Identification as we don't want to active Printfs from the BTrace
hgs
parents:
diff changeset
   358
    for ( TInt i = KMinKernelCategory; i <= KMaxKernelCategory; i++ )
hgs
parents:
diff changeset
   359
        {
hgs
parents:
diff changeset
   360
        PrimeCategory( i );
hgs
parents:
diff changeset
   361
        }
hgs
parents:
diff changeset
   362
    }
hgs
parents:
diff changeset
   363
hgs
parents:
diff changeset
   364
hgs
parents:
diff changeset
   365
/**
hgs
parents:
diff changeset
   366
 * Primes a category
hgs
parents:
diff changeset
   367
 * 
hgs
parents:
diff changeset
   368
 * @param aCategory the category to be primed
hgs
parents:
diff changeset
   369
 */
hgs
parents:
diff changeset
   370
void DBTraceKernelCategoryHandler::PrimeCategory( TUint8 aCategory )
hgs
parents:
diff changeset
   371
    {
hgs
parents:
diff changeset
   372
    TUint32 traceWord = MapCategoryToID( aCategory, 0 );
hgs
parents:
diff changeset
   373
    // CPU events are not possible when using USB phonet writer
hgs
parents:
diff changeset
   374
    // They result in context switch trace loop
hgs
parents:
diff changeset
   375
    if ( iWriter != NULL &&
hgs
parents:
diff changeset
   376
         (iTraceBitmap->IsTraceActivated( KKernelHooksOSTComponentUID, traceWord ) )
hgs
parents:
diff changeset
   377
            && ( aCategory != BTrace::ECpuUsage || iWriter->GetWriterType() != EWriterTypeUSBPhonet ) )
hgs
parents:
diff changeset
   378
        {
hgs
parents:
diff changeset
   379
        TInt ret = BTrace::SetFilter( aCategory, 1 );
hgs
parents:
diff changeset
   380
        if ( ret == KErrNone )
hgs
parents:
diff changeset
   381
            {
hgs
parents:
diff changeset
   382
            OstTrace1( TRACE_NORMAL, DBTRACEKERNELCATEGORYHANDLER_PRIMEDFC__,"DBTraceKernelCategoryHandler::PrimeDfc - Priming 0x%x", aCategory );
hgs
parents:
diff changeset
   383
            BTrace::Prime( aCategory );
hgs
parents:
diff changeset
   384
            }
hgs
parents:
diff changeset
   385
        else if ( ret == KErrNotSupported )
hgs
parents:
diff changeset
   386
            {
hgs
parents:
diff changeset
   387
            OstTrace1( TRACE_INTERNAL, DBTRACEKERNELCATEGORYHANDLER_PRIMEDFC_NOT_SUPPORTED,"DBTraceKernelCategoryHandler::PrimeDfc - Category not supported 0x%x", aCategory );
hgs
parents:
diff changeset
   388
            }
hgs
parents:
diff changeset
   389
        }
hgs
parents:
diff changeset
   390
    else
hgs
parents:
diff changeset
   391
        {
hgs
parents:
diff changeset
   392
        (void) BTrace::SetFilter( aCategory, 0 );
hgs
parents:
diff changeset
   393
        }
hgs
parents:
diff changeset
   394
    }
hgs
parents:
diff changeset
   395
hgs
parents:
diff changeset
   396
/**
hgs
parents:
diff changeset
   397
 * Handles this Multipart trace
hgs
parents:
diff changeset
   398
 *
hgs
parents:
diff changeset
   399
 * @param aHeader BTrace header
hgs
parents:
diff changeset
   400
 * @param aHeader2 Extra header data
hgs
parents:
diff changeset
   401
 * @param aContext The thread context in which this function was called
hgs
parents:
diff changeset
   402
 * @param aTraceWord Trace Word
hgs
parents:
diff changeset
   403
 * @param a1 First parameter
hgs
parents:
diff changeset
   404
 * @param aData The data
hgs
parents:
diff changeset
   405
 * @param aExtra Extra trace data
hgs
parents:
diff changeset
   406
 * @param aPc The program counter value
hgs
parents:
diff changeset
   407
 * @return ETrue if trace was processed
hgs
parents:
diff changeset
   408
 */
hgs
parents:
diff changeset
   409
TBool DBTraceKernelCategoryHandler::HandleMultiPart( TUint32 aHeader, TUint32 aHeader2, const TUint32 aContext,
hgs
parents:
diff changeset
   410
                   const TUint32 aTraceWord, const TUint32 a1, const TUint32 aData, const TUint32 aExtra,
hgs
parents:
diff changeset
   411
                   const TUint32 aPc)
hgs
parents:
diff changeset
   412
    {
hgs
parents:
diff changeset
   413
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( ">DBTraceOstCategoryHandler::HandleMultiPart" ) );
hgs
parents:
diff changeset
   414
    TBool retval = ETrue;
hgs
parents:
diff changeset
   415
    TInt multiPartOffset = aHeader2 & BTrace::EMultipartFlagMask;
hgs
parents:
diff changeset
   416
    TUint8 recordSize = static_cast< TUint8 >( ( aHeader >> ( BTrace::ESizeIndex * KByteSize ) ) & KByteMask );
hgs
parents:
diff changeset
   417
    
hgs
parents:
diff changeset
   418
    // First part of multipart trace
hgs
parents:
diff changeset
   419
    if (multiPartOffset == BTrace::EMultipartFirst)
hgs
parents:
diff changeset
   420
        {
hgs
parents:
diff changeset
   421
        // Create new MultiPart activation info and save it to the array
hgs
parents:
diff changeset
   422
        TMultiPartActivationInfo activationInfo;
hgs
parents:
diff changeset
   423
        activationInfo.iComponentId = KKernelHooksOSTComponentUID;
hgs
parents:
diff changeset
   424
        activationInfo.iTraceWord = aTraceWord;
hgs
parents:
diff changeset
   425
        activationInfo.iMultiPartId = aExtra;
hgs
parents:
diff changeset
   426
   
hgs
parents:
diff changeset
   427
        // Insert the item to the array        
hgs
parents:
diff changeset
   428
        TInt ret = iMultiPartActivationInfos.InsertInUnsignedKeyOrder(activationInfo);
hgs
parents:
diff changeset
   429
        
hgs
parents:
diff changeset
   430
        if (KErrNone == ret)
hgs
parents:
diff changeset
   431
            {            
hgs
parents:
diff changeset
   432
            TUint32* ptr = reinterpret_cast< TUint32* >(aData);
hgs
parents:
diff changeset
   433
            TUint32 a2 = *ptr++;
hgs
parents:
diff changeset
   434
            
hgs
parents:
diff changeset
   435
            // Write the trace. Move pointer by 4 bytes because first 4 bytes is moved from aData
hgs
parents:
diff changeset
   436
            // to a2. Decrease record size by 4 bytes because the original a2 is not written
hgs
parents:
diff changeset
   437
            iWriter->WriteTraceCoreFrame( activationInfo.iComponentId, activationInfo.iTraceWord, 
hgs
parents:
diff changeset
   438
                    aHeader, aHeader2, aContext, a1, a2, 
hgs
parents:
diff changeset
   439
                    aData + 4, aExtra, aPc, recordSize - 4);
hgs
parents:
diff changeset
   440
            }
hgs
parents:
diff changeset
   441
        else
hgs
parents:
diff changeset
   442
            {
hgs
parents:
diff changeset
   443
            retval = EFalse;
hgs
parents:
diff changeset
   444
            DTraceCore* tcore = DTraceCore::GetInstance();
hgs
parents:
diff changeset
   445
            if(tcore)
hgs
parents:
diff changeset
   446
                tcore->SetPreviousTraceDropped(ETrue);
hgs
parents:
diff changeset
   447
            }
hgs
parents:
diff changeset
   448
        }
hgs
parents:
diff changeset
   449
     
hgs
parents:
diff changeset
   450
    // Middle or last part of multipart trace
hgs
parents:
diff changeset
   451
    else if (multiPartOffset == BTrace::EMultipartMiddle || multiPartOffset == BTrace::EMultipartLast)
hgs
parents:
diff changeset
   452
        {
hgs
parents:
diff changeset
   453
        // Check index of component id in array
hgs
parents:
diff changeset
   454
        TMultiPartActivationInfo tempInfo;
hgs
parents:
diff changeset
   455
        tempInfo.iMultiPartId = aExtra;
hgs
parents:
diff changeset
   456
        TInt index = iMultiPartActivationInfos.FindInUnsignedKeyOrder(tempInfo);
hgs
parents:
diff changeset
   457
        
hgs
parents:
diff changeset
   458
        if (index != KErrNotFound)
hgs
parents:
diff changeset
   459
            {
hgs
parents:
diff changeset
   460
            TMultiPartActivationInfo activationInfo = iMultiPartActivationInfos[index];
hgs
parents:
diff changeset
   461
hgs
parents:
diff changeset
   462
            TUint32 a1 = 0;
hgs
parents:
diff changeset
   463
            TUint32 a2 = 0;
hgs
parents:
diff changeset
   464
            TUint32 movePointerOffset = 0;
hgs
parents:
diff changeset
   465
            
hgs
parents:
diff changeset
   466
            // Calculate if we can move data from the aData to a1 and a2
hgs
parents:
diff changeset
   467
            TUint32 dataStartOffset = CalculateDataStartOffset(aHeader);
hgs
parents:
diff changeset
   468
            if ( recordSize - dataStartOffset >= 4 )
hgs
parents:
diff changeset
   469
                {
hgs
parents:
diff changeset
   470
                TUint32* ptr = reinterpret_cast< TUint32* >(aData);
hgs
parents:
diff changeset
   471
                a1 = *ptr++;
hgs
parents:
diff changeset
   472
                movePointerOffset += 4;
hgs
parents:
diff changeset
   473
                
hgs
parents:
diff changeset
   474
                if ( recordSize - dataStartOffset >= 8 )
hgs
parents:
diff changeset
   475
                    {
hgs
parents:
diff changeset
   476
                    a2 = *ptr++;
hgs
parents:
diff changeset
   477
                    movePointerOffset += 4;
hgs
parents:
diff changeset
   478
                    }
hgs
parents:
diff changeset
   479
                }
hgs
parents:
diff changeset
   480
                        
hgs
parents:
diff changeset
   481
            // Write the trace. Decrease the record size by 8 because of the original a1 and a2
hgs
parents:
diff changeset
   482
            // are not written
hgs
parents:
diff changeset
   483
            iWriter->WriteTraceCoreFrame( activationInfo.iComponentId, activationInfo.iTraceWord, 
hgs
parents:
diff changeset
   484
                    aHeader, aHeader2, aContext, a1, a2, 
hgs
parents:
diff changeset
   485
                    aData + movePointerOffset, aExtra, aPc, recordSize - 8);
hgs
parents:
diff changeset
   486
            
hgs
parents:
diff changeset
   487
            // Last part, remove the item from the array
hgs
parents:
diff changeset
   488
            if (multiPartOffset == BTrace::EMultipartLast)
hgs
parents:
diff changeset
   489
                {
hgs
parents:
diff changeset
   490
                iMultiPartActivationInfos.Remove(index);
hgs
parents:
diff changeset
   491
                }
hgs
parents:
diff changeset
   492
            }
hgs
parents:
diff changeset
   493
        }
hgs
parents:
diff changeset
   494
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( "<DBTraceOstCategoryHandler::HandleMultiPart > return %d", retval ) );
hgs
parents:
diff changeset
   495
    return retval;
hgs
parents:
diff changeset
   496
    }
hgs
parents:
diff changeset
   497
hgs
parents:
diff changeset
   498
/**
hgs
parents:
diff changeset
   499
 * Checks if the given trace is a Multipart trace
hgs
parents:
diff changeset
   500
 *
hgs
parents:
diff changeset
   501
 * @param aHeader Header data
hgs
parents:
diff changeset
   502
 * @param aHeader2 Extra header data
hgs
parents:
diff changeset
   503
 * @return ETrue if trace is a Multipart trace, EFalse if not
hgs
parents:
diff changeset
   504
 */
hgs
parents:
diff changeset
   505
inline TBool DBTraceKernelCategoryHandler::CheckMultiPart( TUint32 aHeader, TUint32 aHeader2 )
hgs
parents:
diff changeset
   506
    {
hgs
parents:
diff changeset
   507
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( ">DBTraceKernelCategoryHandler::CheckMultiPart()" ) );
hgs
parents:
diff changeset
   508
    TBool retval = EFalse;
hgs
parents:
diff changeset
   509
    TUint8 flags = static_cast< TUint8 >( ( aHeader >> ( BTrace::EFlagsIndex * KByteSize ) ) & KByteMask );
hgs
parents:
diff changeset
   510
    if (flags & BTrace::EHeader2Present)
hgs
parents:
diff changeset
   511
        {
hgs
parents:
diff changeset
   512
        // First, middle or last part of Multipart trace
hgs
parents:
diff changeset
   513
        if (aHeader2 & BTrace::EMultipartFlagMask)
hgs
parents:
diff changeset
   514
            {
hgs
parents:
diff changeset
   515
            retval = ETrue;
hgs
parents:
diff changeset
   516
            }
hgs
parents:
diff changeset
   517
        }
hgs
parents:
diff changeset
   518
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( "<DBTraceKernelCategoryHandler::CheckMultiPart > return %d", retval ) );
hgs
parents:
diff changeset
   519
    return retval;
hgs
parents:
diff changeset
   520
    }
hgs
parents:
diff changeset
   521
hgs
parents:
diff changeset
   522
/**
hgs
parents:
diff changeset
   523
 * Calculates data start offset
hgs
parents:
diff changeset
   524
 *
hgs
parents:
diff changeset
   525
 * @param aHeader BTrace header
hgs
parents:
diff changeset
   526
 */
hgs
parents:
diff changeset
   527
TUint32 DBTraceKernelCategoryHandler::CalculateDataStartOffset( TUint32 aHeader )
hgs
parents:
diff changeset
   528
    {
hgs
parents:
diff changeset
   529
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( ">DBTraceOstCategoryHandler::CalculateDataStartOffset()" ) );
hgs
parents:
diff changeset
   530
    TUint32 offset = 0;
hgs
parents:
diff changeset
   531
    TUint8 flags = static_cast< TUint8 >( ( aHeader >> ( BTrace::EFlagsIndex * KByteSize ) ) & KByteMask );
hgs
parents:
diff changeset
   532
    
hgs
parents:
diff changeset
   533
    // First add header length
hgs
parents:
diff changeset
   534
    offset += KBTraceHeaderLen;
hgs
parents:
diff changeset
   535
    
hgs
parents:
diff changeset
   536
    // Header2 is present
hgs
parents:
diff changeset
   537
    if ( flags & BTrace::EHeader2Present )
hgs
parents:
diff changeset
   538
        {
hgs
parents:
diff changeset
   539
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   540
        }
hgs
parents:
diff changeset
   541
    // Timestamp is present
hgs
parents:
diff changeset
   542
    if ( flags & BTrace::ETimestampPresent )
hgs
parents:
diff changeset
   543
        {
hgs
parents:
diff changeset
   544
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   545
        }
hgs
parents:
diff changeset
   546
    // Timestamp2 is present
hgs
parents:
diff changeset
   547
    if ( flags & BTrace::ETimestamp2Present )
hgs
parents:
diff changeset
   548
        {
hgs
parents:
diff changeset
   549
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   550
        }
hgs
parents:
diff changeset
   551
    // Context ID is present
hgs
parents:
diff changeset
   552
    if ( flags & BTrace::EContextIdPresent )
hgs
parents:
diff changeset
   553
        {
hgs
parents:
diff changeset
   554
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   555
        }
hgs
parents:
diff changeset
   556
    // Program counter is present
hgs
parents:
diff changeset
   557
    if ( flags & BTrace::EPcPresent )
hgs
parents:
diff changeset
   558
        {
hgs
parents:
diff changeset
   559
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   560
        }
hgs
parents:
diff changeset
   561
    // Extra value is present
hgs
parents:
diff changeset
   562
    if ( flags & BTrace::EExtraPresent )
hgs
parents:
diff changeset
   563
        {
hgs
parents:
diff changeset
   564
        offset += KBTraceVariableLen;
hgs
parents:
diff changeset
   565
        }
hgs
parents:
diff changeset
   566
    
hgs
parents:
diff changeset
   567
    // Next 8 bytes came with first and second parameter of the multipart trace
hgs
parents:
diff changeset
   568
    offset += KFourBytes;
hgs
parents:
diff changeset
   569
    offset += KFourBytes;
hgs
parents:
diff changeset
   570
    
hgs
parents:
diff changeset
   571
    TC_TRACE( ETraceLevelTraceFlow, Kern::Printf( "<DBTraceOstCategoryHandler::CalculateDataStartOffset > return %d", offset ) );
hgs
parents:
diff changeset
   572
    return offset;
hgs
parents:
diff changeset
   573
    }
hgs
parents:
diff changeset
   574
hgs
parents:
diff changeset
   575
// End of File