diff -r f497542af8e4 -r 538db54a451d kerneltest/e32test/dmav2/d_dma2_cmn.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dmav2/d_dma2_cmn.cpp Mon Jan 18 21:31:10 2010 +0200 @@ -0,0 +1,328 @@ +/* +* Copyright (c) 2009 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: Implmentation of DMAv2 test code, common +* to both user and kernel side +* +*/ +#ifdef __KERNEL_MODE__ +#include +#endif + +#include "d_dma2.h" + +TInt Log2(TInt aNum) + { + TInt res = -1; + while(aNum) + { + res++; + aNum >>= 1; + } + return res; + } + +TCallbackRecord::TCallbackRecord( + TCbContext aContext, + TInt aReq, + TInt aReqSrc, + TInt aReqDst, + TInt aDes, + TInt aDesSrc, + TInt aDesDst, + TInt aFrame, + TInt aFrameSrc, + TInt aFrameDst, + TInt aPause, + TInt aPauseSrc, + TInt aPauseDst, + TDmaResult aResult + ) + //Default iIsrRedoRequestResult is 1 as this is an invalid error code + :iResult(aResult), iContext(aContext), iIsrRedoRequestResult(1) + { + SetCount(EDmaCallbackRequestCompletion, aReq); + SetCount(EDmaCallbackRequestCompletion_Src, aReqSrc); + SetCount(EDmaCallbackRequestCompletion_Dst, aReqDst); + SetCount(EDmaCallbackDescriptorCompletion, aDes); + SetCount(EDmaCallbackDescriptorCompletion_Src, aDesSrc); + SetCount(EDmaCallbackDescriptorCompletion_Dst, aDesDst); + SetCount(EDmaCallbackFrameCompletion, aFrame); + SetCount(EDmaCallbackFrameCompletion_Src, aFrameSrc); + SetCount(EDmaCallbackFrameCompletion_Dst, aFrameDst); + SetCount(EDmaCallbackLinkedListPaused, aPause); + SetCount(EDmaCallbackLinkedListPaused_Src, aPauseSrc); + SetCount(EDmaCallbackLinkedListPaused_Dst, aPauseDst); + } + +TCallbackRecord TCallbackRecord::Empty() + { + return TCallbackRecord(EInvalid,0,0,0,0,0,0,0,0,0,0,0,0,EDmaResultError); + } + +void TCallbackRecord::Reset() + { + new (this) TCallbackRecord(); + } + +TBool TCallbackRecord::operator == (const TCallbackRecord aOther) const + { + return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0); + } + +TInt TCallbackRecord::GetCount(TDmaCallbackType aCbType) const + { + const TInt index = BitToIndex(aCbType); + return iCallbackLog[index]; + } + +void TCallbackRecord::SetCount(TDmaCallbackType aCbType, TInt aCount) + { + const TInt index = BitToIndex(aCbType); + iCallbackLog[index] = aCount; + } + +TInt TCallbackRecord::BitToIndex(TDmaCallbackType aCbType) const + { + const TInt index = Log2(aCbType); + TEST_ASSERT(index >=0 && index < KNumberOfCallbacks); + + return index; + } + +void TCallbackRecord::ProcessCallback(TUint aCallbackMask, TDmaResult aResult) + { + // This function may be called several + // times and will accumulate the number of each callback + // received. However, it will only ever remember the last + // result and context value, + iResult = aResult; + iContext = CurrentContext(); + TEST_ASSERT(iContext != EInvalid); + + for(TInt i=0; i < KNumberOfCallbacks; i++) + { + if(aCallbackMask & 1) + { + iCallbackLog[i]++; + } + aCallbackMask >>= 1; + } + // Assert that we have handled all bits + // if not then maybe KNumberOfCallbacks is too small + // or there is a spurious bit in aCallbackMask + TEST_ASSERT(aCallbackMask == 0); + } + +TCallbackRecord::TCbContext TCallbackRecord::CurrentContext() const + { +#ifdef __KERNEL_MODE__ + switch(NKern::CurrentContext()) + { + case NKern::EThread: + return EThread; + case NKern::EInterrupt: + return EIsr; + case NKern::EIDFC: //fall-through + case NKern::EEscaped: + default: + return EInvalid; + } +#else + //for the benefit of user-mode testing + return EThread; +#endif + } + +void TCallbackRecord::Print() const + { + PRINT(GetCount(EDmaCallbackRequestCompletion)); + PRINT(GetCount(EDmaCallbackRequestCompletion_Src)); + PRINT(GetCount(EDmaCallbackRequestCompletion_Dst)); + PRINT(GetCount(EDmaCallbackDescriptorCompletion)); + PRINT(GetCount(EDmaCallbackDescriptorCompletion_Src)); + PRINT(GetCount(EDmaCallbackDescriptorCompletion_Dst)); + PRINT(GetCount(EDmaCallbackFrameCompletion)); + PRINT(GetCount(EDmaCallbackFrameCompletion_Src)); + PRINT(GetCount(EDmaCallbackFrameCompletion_Dst)); + PRINT(GetCount(EDmaCallbackLinkedListPaused)); + PRINT(GetCount(EDmaCallbackLinkedListPaused_Src)); + PRINT(GetCount(EDmaCallbackLinkedListPaused_Dst)); + PRINT(iResult); + PRINT(iContext); + PRINT(iIsrRedoRequestResult); + } + +TDmacTestCaps::TDmacTestCaps() + :iPILVersion(1) + { + } + +TDmacTestCaps::TDmacTestCaps(const SDmacCaps& aDmacCaps, TInt aVersion) + :SDmacCaps(aDmacCaps), iPILVersion(aVersion) + {} + +TAddrRange::TAddrRange(TUint aStart, TUint aLength) + :iStart(aStart), iLength(aLength) + { + TEST_ASSERT(iLength > 0); + } + +TBool TAddrRange::Contains(TAddrRange aRange) const + { + return Contains(aRange.Start()) && Contains(aRange.End()); + } + +TBool TAddrRange::Overlaps(const TAddrRange& aRange) const + { + return (aRange.Contains(iStart) || aRange.Contains(End()) || + Contains(aRange.Start()) || Contains(aRange.End())); + } +/** +If addresses have been left as KPhysAddrInvalid or the count as 0 +(ie. the default values used for IsrRedoRequest) +then substitute the values from aTransferArgs. +*/ +void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs) + { + if(iSrcAddr == KPhysAddrInvalidUser) + iSrcAddr = aTransferArgs.iSrcConfig.iAddr; + + if(iDstAddr == KPhysAddrInvalidUser) + iDstAddr = aTransferArgs.iDstConfig.iAddr; + + if(iTransferCount == 0) + iTransferCount = aTransferArgs.iTransferCount; + } + +/** +Addresses are converted into absolute, +addresses (virtual in user mode, physical in kernel) +unless they are KPhysAddrInvalid +*/ +void TAddressParms::Fixup(TLinAddr aChunkBase) + { + if(iSrcAddr != KPhysAddrInvalidUser) + { + iSrcAddr += aChunkBase; + +#ifdef __KERNEL_MODE__ + iSrcAddr = Epoc::LinearToPhysical(iSrcAddr); + TEST_ASSERT(iSrcAddr != KPhysAddrInvalid); +#endif + } +#ifndef __KERNEL_MODE__ + else + { + // Substitute must be called before + // Fixup on user side + TEST_FAULT; + } +#endif + + if(iDstAddr != KPhysAddrInvalidUser) + { + iDstAddr += aChunkBase; + +#ifdef __KERNEL_MODE__ + iDstAddr = Epoc::LinearToPhysical(iDstAddr); + TEST_ASSERT(iDstAddr != KPhysAddrInvalid); +#endif + } +#ifndef __KERNEL_MODE__ + else + { + // Substitute must be called before + // Fixup on user side + TEST_FAULT; + } +#endif + } + +TBool TAddressParms::CheckRange(TLinAddr aStart, TUint aSize) + { + TAddrRange chunk(aStart, aSize); + return chunk.Contains(SourceRange()) && chunk.Contains(DestRange()); + } + +/** +@return ETrue if the source or destination range of this object +overlaps with aRange +*/ +TBool TAddressParms::Overlaps(const TAddrRange aRange) const + { + return SourceRange().Overlaps(aRange) || DestRange().Overlaps(aRange); + } + +/** +@return ETrue if either the source or dest range of this +overlap with either of those of aParm +*/ +TBool TAddressParms::Overlaps(const TAddressParms aParm) const + { + return Overlaps(aParm.SourceRange()) || Overlaps(aParm.DestRange()); + } + +TBool TAddressParms::operator==(const TAddressParms& aOther) const + { + return iSrcAddr == aOther.iSrcAddr && + iDstAddr == aOther.iDstAddr && + iTransferCount == aOther.iTransferCount; + } + +TAddressParms GetAddrParms(const TDmaTransferArgs& aArgs) + { + return TAddressParms(aArgs); + } + +TAddrRange TAddressParms::SourceRange() const + { + return TAddrRange(iSrcAddr, iTransferCount); + } + +TAddrRange TAddressParms::DestRange() const + { + return TAddrRange(iDstAddr, iTransferCount); + } + +void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams) + { + aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr; + aTransferArgs.iDstConfig.iAddr = aAddrParams.iDstAddr; + aTransferArgs.iTransferCount = aAddrParams.iTransferCount; + } + +TIsrRequeArgs TIsrRequeArgsSet::GetArgs() + { + TEST_ASSERT(!IsEmpty()); + const TIsrRequeArgs args(iRequeArgs[iIndex]); + iIndex++; + iCount--; + return args; + } + + +void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs) + { + for(TInt i=0; i