--- /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 <platform.h>
+#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<iCount; i++)
+ {
+ iRequeArgs[i].Substitute(aTransferArgs);
+ }
+ }
+void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
+ {
+ for(TInt i=0; i<iCount; i++)
+ {
+ iRequeArgs[i].Fixup(aChunkBase);
+ }
+ }