tracesrv/tracecore/btrace_handler/src/TraceCoreBTraceHandler.cpp
changeset 56 aa2539c91954
--- /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( "<DTraceCoreBTraceHandler::Init - return %d", ret ) );
+    return ret;
+    }
+
+
+    
+/**
+ * Starts the OST category handler
+ */
+TInt DTraceCoreBTraceHandler::StartOstHandler()
+    {
+    TInt ret = KErrNoMemory;
+    iOstHandler = new DBTraceOstCategoryHandler();
+    if ( iOstHandler != NULL )
+        {
+        // Init calls RegisterCategoryHandler
+        ret = iOstHandler->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