diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecore/btrace_handler/src/TraceCoreBTraceHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracesrv/tracecore/btrace_handler/src/TraceCoreBTraceHandler.cpp Fri Oct 08 14:56:39 2010 +0300 @@ -0,0 +1,328 @@ +// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Trace Core +// + +#include "TraceCoreBTraceHandler.h" +#include "TraceCoreWriter.h" +#include "TraceCoreDebug.h" +#include "TraceCoreConstants.h" +#include "BTraceOstCategoryHandler.h" +#include "BTraceKernelCategoryHandler.h" +#include "OstTraceDefinitions.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "TraceCoreBTraceHandlerTraces.h" +#endif + + +/** + * Static instance is needed when calling traces from handler function + */ +DTraceCoreBTraceHandler* DTraceCoreBTraceHandler::iInstance = NULL; + + +/** + * Constructor + */ +DTraceCoreBTraceHandler::DTraceCoreBTraceHandler() +: iCategoryHandlers( NULL ) +, iOstHandler( NULL ) +, iKernelHandler( NULL ) + { + } + + +/** + * Destructor + */ +DTraceCoreBTraceHandler::~DTraceCoreBTraceHandler() + { + // Handlers are deleted first -> They call UnregisterCategoryHandler + delete iOstHandler; + delete iKernelHandler; + delete[] iCategoryHandlers; + DTraceCoreBTraceHandler::iInstance = NULL; + } + + +/** + * Initializes BTrace handler + */ +TInt DTraceCoreBTraceHandler::Init() + { + iCategoryHandlers = new DBTraceCategoryHandler*[ KBTraceCategoryCount ]; + TInt ret; + if ( iCategoryHandlers != NULL ) + { + memset( iCategoryHandlers, 0, sizeof ( DBTraceCategoryHandler* ) * KBTraceCategoryCount ); + // Registers this handler to TraceCore + ret = Register(); + if ( ret == KErrNone ) + { + // Registers the callback function to BTrace + BTrace::SetHandler( BTraceHandlerFunc ); + DTraceCoreBTraceHandler::iInstance = this; + } + } + else + { + ret = KErrNoMemory; + } + + // Autogen, OST and Symbian kernel category handlers are integrated to TraceCore + if ( ret == KErrNone ) + { + + ret = StartOstHandler(); + + if ( ret == KErrNone ) + { + ret = StartKernelHandler(); + } + } + + TC_TRACE( ETraceLevelFlow, Kern::Printf( "Init(); + } + TC_TRACE( ETraceLevelError,Kern::Printf( "DTraceCoreBTraceHandler::StartOstHandler - %d", ret ) ); + return ret; + } + + +/** + * Starts the kernel category handler + */ +TInt DTraceCoreBTraceHandler::StartKernelHandler() + { + TInt ret = KErrGeneral; + if ( iOstHandler != NULL ) + { + iKernelHandler = new DBTraceKernelCategoryHandler(); + if ( iKernelHandler != NULL ) + { + // Init calls RegisterCategoryHandler + ret = iKernelHandler->Init(); + } + // Memory allocation failed + else + { + ret = KErrNoMemory; + } + } + // noelse + + TC_TRACE( ETraceLevelError, Kern::Printf("DTraceCoreBTraceHandler::StartKernelHandler - %d", ret ) ); + return ret; + } + + +/** + * Called before SetWriter with interrupts enabled + * + * @param aWriter Pointer to writer + */ +void DTraceCoreBTraceHandler::PrepareSetWriter( DTraceCoreWriter* aWriter ) + { + if ( iCategoryHandlers != NULL ) + { + DTraceCoreHandler::PrepareSetWriter( aWriter ); + // Delegates the writer to category handlers + DBTraceCategoryHandler* previousHandler = NULL; + for ( TInt i = 0; i < KBTraceCategoryCount; i++ ) + { + DBTraceCategoryHandler* handler = iCategoryHandlers[ i ]; + if ( handler != NULL && handler != previousHandler ) + { + handler->PrepareSetWriter( aWriter ); + previousHandler = handler; + } + } + } + } + + +/** + * Sets the writer to be used for trace output + * + * @param aWriter Pointer to writer + */ +void DTraceCoreBTraceHandler::SetWriter( DTraceCoreWriter* aWriter ) + { + OstTrace1( TRACE_FLOW, DTRACECOREBTRACEHANDLER_SETWRITER_ENTRY, "> DTraceCoreBTraceHandler::SetWriter 0x%x", ( TUint )&( aWriter ) ); + if (aWriter) + { + OstTrace1( TRACE_INTERNALS, DTRACECOREBTRACEHANDLER_SETWRITER_WRITERTYPE, "Writer type: %d", aWriter->GetWriterType() ); + } + + if ( iCategoryHandlers != NULL ) + { + DTraceCoreHandler::SetWriter( aWriter ); + // Delegates the writer to category handlers + DBTraceCategoryHandler* previousHandler = NULL; + for ( TInt i = 0; i < KBTraceCategoryCount; i++ ) + { + DBTraceCategoryHandler* handler = iCategoryHandlers[ i ]; + if ( handler != NULL && handler != previousHandler ) + { + handler->SetWriter( aWriter ); + previousHandler = handler; + } + } + } + } + + +/** + * Sets settings + * + * @param aSettings Pointer to settings + */ +void DTraceCoreBTraceHandler::SetSettings( DTraceCoreSettings* aSettings ) + { + OstTrace1( TRACE_FLOW, DTRACECOREBTRACEHANDLER_SETSETTINGS_ENTRY, "> DTraceCoreBTraceHandler::SetSettings 0x%x", ( TUint )&( aSettings ) ); + if ( iCategoryHandlers != NULL ) + { + DTraceCoreHandler::SetSettings( aSettings ); + // Delegates the settings saver to category handlers + DBTraceCategoryHandler* previousHandler = NULL; + for ( TInt i = 0; i < KBTraceCategoryCount; i++ ) + { + DBTraceCategoryHandler* handler = iCategoryHandlers[ i ]; + if ( handler != NULL && handler != previousHandler ) + { + handler->SetSettings( aSettings ); + previousHandler = handler; + } + } + } + } + + + +/** + * Registers a category handler + * + * @param aCategory The category to be processed with the category handler + * @param aHandler The handler which processes the category + */ +void DTraceCoreBTraceHandler::RegisterCategoryHandler( TUint8 aCategory, DBTraceCategoryHandler& aHandler ) + { + OstTraceExt2( TRACE_FLOW, DTRACECOREBTRACEHANDLER_REGISTERCATEGORYHANDLER_ENTRY, "> DTraceCoreBTraceHandler::RegisterCategoryHandler. ID:0x%x Addr:0x%x", aCategory, ( TUint )&( aHandler ) ); + if ( iCategoryHandlers != NULL ) + { + iCategoryHandlers[ aCategory ] = &aHandler; + + // BTrace kernel categories are not enabled by default + // MF added - commented out this code + + if ( iWriter != NULL ) + { + aHandler.SetWriter( iWriter ); + } + if ( iSettings != NULL ) + { + aHandler.SetSettings( iSettings ); + } + OstTraceExt2( TRACE_NORMAL, DTRACECOREBTRACEHANDLER_REGISTERCATEGORYHANDLER_HANDLER_REGISTERED, "DTraceCoreBTraceHandler::RegisterCategoryHandler - Handler registered. ID:0x%x Addr:0x%x", aCategory, ( TUint )&( aHandler ) ); + } + } + + +/** + * Unregisters a category handler + * + * @param aCategory The category to be unregistered + */ +void DTraceCoreBTraceHandler::UnregisterCategoryHandler( TUint8 aCategory ) + { + OstTrace1( TRACE_FLOW, DTRACECOREBTRACEHANDLER_UNREGISTERCATEGORYHANDLER_ENTRY, "> DTraceCoreBTraceHandler::UnregisterCategoryHandler. ID:0x%x", aCategory ); + + // Unregister category handler + if ( iCategoryHandlers != NULL ) + { + iCategoryHandlers[ aCategory ] = NULL; + BTrace::SetFilter( aCategory, 0 ); + OstTrace1( TRACE_NORMAL, DTRACECOREBTRACEHANDLER_UNREGISTERCATEGORYHANDLER_UNREGISTERED, "DTraceCoreBTraceHandler::UnregisterCategoryHandler - Handler unregistered. ID:0x%x", aCategory ); + } + } + + +/** + * Callback function that is registered to BTrace. + * + * Tracing is not allowed from this method. + * + * @param aHeader BTrace header + * @param aHeader2 Extra header data + * @param aContext The thread context in which this function was called + * @param a1 The first trace parameter + * @param a2 The second trace parameter + * @param a3 The third trace parameter + * @param aExtra Extra trace data + * @param aPc The program counter value + * @return ETrue if trace was processed, EFalse if not + */ +TBool DTraceCoreBTraceHandler::BTraceHandlerFunc( TUint32 aHeader, TUint32 aHeader2, const TUint32 aContext, + const TUint32 a1, const TUint32 a2, const TUint32 a3, + const TUint32 aExtra, const TUint32 aPc ) + { + TBool retval; + DTraceCoreBTraceHandler* handler = DTraceCoreBTraceHandler::iInstance; + if ( handler != NULL && handler->iWriter != NULL ) + { + DBTraceCategoryHandler* categoryHandler = handler->GetCategoryHandler( aHeader ); + if ( categoryHandler != NULL ) + { + retval = categoryHandler->HandleFrame( aHeader, aHeader2, aContext, a1, a2, a3, aExtra, aPc ); + } + else + { + retval = EFalse; + } + } + else + { + retval = EFalse; + } + return retval; + } + + +/** + * Gets the category handler for given BTrace header + * + * @param aHeader BTrace header + */ +inline DBTraceCategoryHandler* DTraceCoreBTraceHandler::GetCategoryHandler( TUint32 aHeader ) + { + __ASSERT_DEBUG( iCategoryHandlers != NULL, Kern::Fault( "DTraceCoreBTraceHandler::GetCategoryHandler - NULL", KErrGeneral ) ); + return iCategoryHandlers[ ( aHeader >> ( BTrace::ECategoryIndex * KByteSize ) ) & KByteMask ]; + } + +// End of File