sl@0: /* sl@0: * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: // D_FTRACE.CPP sl@0: // sl@0: // sl@0: // sl@0: #include "plat_priv.h" sl@0: #include sl@0: sl@0: #include "f32trace.h" sl@0: sl@0: DMutex* TheTraceMutex = NULL; sl@0: _LIT(KLitTraceMutexName, "FTRACE_MUTEX"); sl@0: sl@0: const TInt KMajorVersionNumber=1; sl@0: const TInt KMinorVersionNumber=0; sl@0: const TInt KBuildVersionNumber=0; sl@0: sl@0: sl@0: class DLddFactoryFTrace : public DLogicalDevice sl@0: { sl@0: public: sl@0: DLddFactoryFTrace(); sl@0: virtual ~DLddFactoryFTrace(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8 &aDes) const; sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual sl@0: }; sl@0: sl@0: class DLddFTrace : public DLogicalChannelBase sl@0: { sl@0: public: sl@0: DLddFTrace(); sl@0: ~DLddFTrace(); sl@0: protected: sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: sl@0: virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); sl@0: sl@0: private: sl@0: void DoCancel(TInt aReqNo); sl@0: TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); sl@0: TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); sl@0: sl@0: private: sl@0: }; sl@0: sl@0: DECLARE_STANDARD_LDD() sl@0: { sl@0: TInt r = Kern::MutexCreate(TheTraceMutex, KLitTraceMutexName, KMutexOrdNone); sl@0: if (r != KErrNone) sl@0: return NULL; sl@0: sl@0: return new DLddFactoryFTrace; sl@0: } sl@0: sl@0: DLddFactoryFTrace::DLddFactoryFTrace() sl@0: { sl@0: sl@0: iParseMask=KDeviceAllowUnit; // Pass stack number as unit sl@0: iUnitsMask=0xffffffff; sl@0: iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); sl@0: } sl@0: sl@0: TInt DLddFactoryFTrace::Create(DLogicalChannelBase*& aChannel) sl@0: { sl@0: aChannel=new DLddFTrace; sl@0: return aChannel ? KErrNone : KErrNoMemory; sl@0: } sl@0: sl@0: TInt DLddFactoryFTrace::Install() sl@0: { sl@0: TPtrC name=_L("FTrace"); sl@0: return(SetName(&name)); sl@0: } sl@0: sl@0: void DLddFactoryFTrace::GetCaps(TDes8& /*aDes*/) const sl@0: { sl@0: } sl@0: sl@0: DLddFactoryFTrace::~DLddFactoryFTrace() sl@0: { sl@0: } sl@0: sl@0: DLddFTrace::DLddFTrace() sl@0: { sl@0: } sl@0: sl@0: DLddFTrace::~DLddFTrace() sl@0: { sl@0: } sl@0: sl@0: TInt DLddFTrace::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) sl@0: { sl@0: sl@0: if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) sl@0: return(KErrNotSupported); sl@0: sl@0: return(KErrNone); sl@0: } sl@0: sl@0: void DLddFTrace::DoCancel(TInt /*aReqNo*/) sl@0: { sl@0: } sl@0: sl@0: TInt DLddFTrace::Request(TInt aReqNo, TAny* a1, TAny* a2) sl@0: { sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*TheTraceMutex); sl@0: TInt r = DoControl(aReqNo, a1, a2); sl@0: Kern::MutexSignal(*TheTraceMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: const TUint KTraceBufferSize = 4096; sl@0: TUint8 gTraceBuffer[KTraceBufferSize]; sl@0: sl@0: sl@0: #define MIN(a,b) ((a) < (b) ? (a) : (b)) sl@0: sl@0: TInt DLddFTrace::DoControl(TInt aFunction, TAny* a1, TAny* a2) sl@0: // sl@0: // Mostly requests (but some kernel server async ones) sl@0: // sl@0: { sl@0: TInt r=KErrNotSupported; sl@0: switch (aFunction) sl@0: { sl@0: case RFTrace::ETraceMultiple: sl@0: { sl@0: typedef struct { sl@0: TClassification iCategory; sl@0: TUint8 iPadding1[sizeof(TUint) - sizeof(TClassification)]; sl@0: sl@0: TFormatId iFormatId; sl@0: TUint8 iPadding2[sizeof(TUint) - sizeof(TFormatId)]; sl@0: sl@0: TUint32 iUid; sl@0: TInt iDescriptorCount; sl@0: } TraceArgs; sl@0: sl@0: TraceArgs args={0}; sl@0: sl@0: XTRAP(r, XT_DEFAULT, kumemget32(&args, a1, sizeof(args))); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // current descriptor - MUST be either a TPtr8 or a TBuf8<4> sl@0: TUint32 desc[2] = {0, 0}; sl@0: TUint32& desLength = desc[0]; sl@0: sl@0: TUint offset = 0; sl@0: sl@0: *((TUint*) (gTraceBuffer+offset)) = args.iFormatId; sl@0: offset+= sizeof(TUint); sl@0: sl@0: TDesC8* des = (TDesC8*) ((TUint8*) a2); sl@0: const TInt desSize = sizeof(TPtrC8); sl@0: for (TInt n=0; n< args.iDescriptorCount; n++, des = (TDesC8*) (((TUint8*) des) + desSize) ) sl@0: { sl@0: sl@0: XTRAP(r, XT_DEFAULT, kumemget32(desc, des, sizeof(desc))); sl@0: TUint32 desType = desLength >> KShiftDesType; sl@0: desLength &= (TUint) (KMaskDesLength); sl@0: if (desType == EPtrC) sl@0: { sl@0: *((TUint*) (gTraceBuffer+offset)) = desLength; sl@0: desLength = (desLength+3)&~3; sl@0: offset+= sizeof(TUint); sl@0: } sl@0: else if (desType == EBufC) sl@0: { sl@0: *((TUint*) (gTraceBuffer+offset)) = desc[1]; sl@0: offset+= sizeof(TUint); sl@0: if (desLength > 4) sl@0: return KErrArgument; sl@0: desLength = 0; sl@0: continue; sl@0: } sl@0: else sl@0: return KErrArgument; sl@0: sl@0: TUint len = MIN(KTraceBufferSize - offset, desLength); sl@0: XTRAP(r, XT_DEFAULT, kumemget(gTraceBuffer+offset, (const TUint8*) desc[1], len)); sl@0: offset+= len; sl@0: sl@0: } sl@0: sl@0: BTrace::OutFilteredBig sl@0: (BTRACE_HEADER_C(8,args.iCategory, 0), args.iUid, gTraceBuffer, offset); sl@0: sl@0: r=KErrNone; sl@0: break; sl@0: } sl@0: } sl@0: return(r); sl@0: } sl@0: