First public contribution.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\dma\t_dma.cpp
21 #define __E32TEST_EXTENSION__
25 #include <e32def_private.h>
27 // DMA test framework command parameter options
30 _LIT(KArgSelfTest, "/SELFTEST");
31 _LIT(KArgSelfTest2, "/S");
34 _LIT(KArgVerboseOutput, "/VERBOSE");
35 _LIT(KArgVerboseOutput2, "/V");
38 TBool gHelpRequested; // print usage
39 TBool gVerboseOutput; // enable verbose output
40 TBool gSelfTest; // run SelfTest
43 This function prints out the PSL test Information
45 void Print(const TDmaV2TestInfo& aInfo)
47 PRINT(aInfo.iMaxTransferSize);
48 PRINT(aInfo.iMemAlignMask);
49 PRINT(aInfo.iMemMemPslInfo);
50 PRINT(aInfo.iMaxSbChannels);
51 for(TInt i=0; i<aInfo.iMaxSbChannels; i++)
53 PRINT(aInfo.iSbChannels[i]);
55 PRINT(aInfo.iMaxDbChannels);
56 for(TInt j=0; j<aInfo.iMaxDbChannels; j++)
58 PRINT(aInfo.iDbChannels[j]);
60 PRINT(aInfo.iMaxSgChannels);
61 for(TInt k=0; k<aInfo.iMaxSgChannels; k++)
63 PRINT(aInfo.iSgChannels[k]);
67 void CDmaTest::PrintTestInfo() const
70 buf.AppendFormat(_L("DMA channel %d"), iChannelCookie);
71 RDebug::RawPrint(buf);
74 //////////////////////////////////////////////////////////////////////
76 //////////////////////////////////////////////////////////////////////
78 void CDmaTest::OpenDmaSession()
80 TInt r = iDmaSession.Open();
81 TEST_ASSERT(r == KErrNone);
82 r = iDmaSession.OpenSharedChunk(iChunk);
83 TEST_ASSERT(r == KErrNone);
86 void CDmaTest::CloseDmaSession()
92 //////////////////////////////////////////////////////////////////////
93 // CSingleTransferTest
94 //////////////////////////////////////////////////////////////////////
95 void CSingleTransferTest::RunTest()
111 void CSingleTransferTest::OpenChannel()
113 iActual.iChannelOpenResult =
114 iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
117 void CSingleTransferTest::CreateDmaRequest()
123 RDebug::Printf("Calling New Request API\n");
125 iActual.iRequestResult.iCreate =
126 iDmaSession.RequestCreateNew(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
132 RDebug::Printf("Calling Old Request API\n");
134 iActual.iRequestResult.iCreate =
135 iDmaSession.RequestCreate(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
139 void CSingleTransferTest::Fragment()
141 if(iActual.iRequestResult.iCreate != KErrNone)
148 RDebug::Printf("Calling New Fragment API\n");
150 iActual.iRequestResult.iFragmentationResult =
151 iDmaSession.FragmentRequest(iRequestSessionCookie, iTransferArgs);
157 RDebug::Printf("Calling Old Fragment API\n");
159 iActual.iRequestResult.iFragmentationResult =
160 iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs);
164 const TInt fragmentCount = iDmaSession.RequestFragmentCount(iRequestSessionCookie);
166 // Record the fragment count if a non-zero value was expected,
167 // or if it was an error value
168 if(iExpected.iRequestResult.iFragmentCount != 0 || fragmentCount < 0)
169 iActual.iRequestResult.iFragmentCount = fragmentCount;
172 void CSingleTransferTest::Queue()
174 if(iActual.iRequestResult.iFragmentationResult == KErrNone)
176 iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord);
180 void CSingleTransferTest::PostTransferCheck()
182 if(iPostTransferCheck)
183 iActual.iPostTransferCheck = DoPostTransferCheck();
186 TInt CSingleTransferTest::DoPostTransferCheck()
188 return iPostTransferCheck->Check(*this);
191 void CSingleTransferTest::FreeRequest()
193 if(iActual.iRequestResult.iCreate == KErrNone)
195 TInt r = iDmaSession.RequestDestroy(iRequestSessionCookie);
196 TEST_ASSERT(r == KErrNone);
200 void CSingleTransferTest::CloseChannel()
202 if(iActual.iChannelOpenResult == KErrNone)
204 TInt r = iDmaSession.ChannelClose(iChannelSessionCookie);
205 TEST_ASSERT(r == KErrNone);
209 void CSingleTransferTest::PrintTestType() const
211 RDebug::RawPrint(_L("Single transfer"));
214 void CSingleTransferTest::PreTransferSetup()
217 iPreTransfer->Setup(*this); //initialize test
220 TBool CSingleTransferTest::Result()
222 const TBool result = iExpected == iActual;
225 RDebug::Printf("TResultSets do not match");
227 if(!result || gVerboseOutput)
229 RDebug::Printf("\nExpected error codes:");
231 RDebug::Printf("Expected callback record:");
232 iExpected.iCallbackRecord.Print();
234 RDebug::Printf("\nActual error codes:");
236 RDebug::Printf("Actual callback record:");
237 iActual.iCallbackRecord.Print();
244 //////////////////////////////////////////////////////////////////////
246 //////////////////////////////////////////////////////////////////////
248 CDmaBenchmark::CDmaBenchmark(const TDesC& aName, TInt aIterations, const TResultSet& aExpectedResults, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
249 :CSingleTransferTest(aName, aIterations, aTransferArgs, aExpectedResults, aMaxFragmentSize, NULL, NULL)
251 UseNewDmaApi(EFalse);
254 CDmaBenchmark::~CDmaBenchmark()
256 iResultArray.Close();
259 TUint64 CDmaBenchmark::MeanResult()
262 RDebug::Printf("CDmaBenchmark::MeanResult\n");
264 const TInt count = iResultArray.Count();
266 TEST_ASSERT(count > 0);
267 TEST_ASSERT(count == iIterations);
271 for(TInt i = 0; i < count; i++)
273 const TUint64 value = iResultArray[i];
275 RDebug::Printf("iResultArray[%d]: %lu", i, value);
283 TBool CDmaBenchmark::Result()
285 const TBool result = CSingleTransferTest::Result();
288 RDebug::Printf(" Mean time: %lu us", MeanResult());
291 //TODO this will be handled by the ctor later
292 iResultArray.Close();
298 //////////////////////////////////////////////////////////////////////
299 // CDmaBmFragmentation
300 //////////////////////////////////////////////////////////////////////
302 CDmaBmFragmentation::CDmaBmFragmentation(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
303 :CDmaBenchmark(aName, aIterations, ExpectedResults, aTransferArgs, aMaxFragmentSize)
306 const TResultSet CDmaBmFragmentation::ExpectedResults(KErrNone,
307 TRequestResults(KErrNone, 0, KErrNone, KErrUnknown),
309 TCallbackRecord::Empty()
312 void CDmaBmFragmentation::Fragment()
315 iActual.iRequestResult.iFragmentationResult =
316 iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs, &time);
317 iResultArray.Append(time);
320 void CDmaBmFragmentation::PrintTestType() const
322 RDebug::RawPrint(_L("Fragmentation Benchmark"));
325 void CDmaBmFragmentation::RunTest()
338 //////////////////////////////////////////////////////////////////////
340 //////////////////////////////////////////////////////////////////////
342 CDmaBmTransfer::CDmaBmTransfer(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
343 :CDmaBenchmark(aName, aIterations,
344 TResultSet(KErrNone, TRequestResults(), KErrUnknown, TCallbackRecord(TCallbackRecord::EThread,1)),
345 aTransferArgs, aMaxFragmentSize)
349 void CDmaBmTransfer::PrintTestType() const
351 RDebug::RawPrint(_L("Transfer Benchmark"));
354 void CDmaBmTransfer::RunTest()
368 void CDmaBmTransfer::Queue()
370 if(iActual.iRequestResult.iFragmentationResult == KErrNone)
373 iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord, &time);
374 iResultArray.Append(time);
379 //////////////////////////////////////////////////////////////////////
380 // CMultiTransferTest
381 //////////////////////////////////////////////////////////////////////
384 // Add pre and post transfer for CMultiTransferTest
385 CMultiTransferTest::CMultiTransferTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs,
386 const TResultSet* aResultSets, TInt aCount)
387 : CDmaTest(aName, aIterations, NULL, NULL), iTransferArgs(aTransferArgs), iTransferArgsCount(aCount), iNewDmaApi(ETrue),
388 iChannelSessionCookie(0), iExpectedArray(aResultSets), iPauseWhileQueuing(EFalse)
391 CMultiTransferTest::CMultiTransferTest(const CMultiTransferTest& aOther)
392 : CDmaTest(aOther), iTransferArgs(aOther.iTransferArgs), iTransferArgsCount(aOther.iTransferArgsCount),
393 iNewDmaApi(aOther.iNewDmaApi),
394 iExpectedArray(aOther.iExpectedArray), iPauseWhileQueuing(aOther.iPauseWhileQueuing)
395 //const cast is required because their isn't a ctor taking const
397 //TODO iRequestCookies(const_cast<TUint*>(&aOther.iRequestCookies[0]), aOther.iRequestCookies.Count())
401 CMultiTransferTest::~CMultiTransferTest()
403 iRequestCookies.Close();
404 iActualResults.Close();
407 TBool CMultiTransferTest::Result()
411 RDebug::Printf("Results for %d transfers:", iTransferArgsCount);
414 TBool result = EFalse;
415 for(TInt i=0; i<iTransferArgsCount; i++)
424 TBool CMultiTransferTest::Result(TInt aTransfer)
426 const TResultSet& expected = iExpectedArray[aTransfer];
427 const TResultSet& actual = iActualResults[aTransfer];
428 const TBool result = expected == actual;
429 if(!result || gVerboseOutput)
431 RDebug::Printf("Compairing results for transfer %d", aTransfer);
436 RDebug::Printf("TResultSets do not match");
438 if(!result || gVerboseOutput)
440 RDebug::Printf("\nExpected error codes:");
442 RDebug::Printf("Expected callback record:");
443 expected.iCallbackRecord.Print();
445 RDebug::Printf("\nActual error codes:");
447 RDebug::Printf("Actual callback record:");
448 actual.iCallbackRecord.Print();
452 void CMultiTransferTest::RunTest()
464 TInt r = DoPostTransferCheck();
465 TEST_ASSERT(r == KErrNone);
470 void CMultiTransferTest::PrintTestType() const
472 RDebug::RawPrint(_L("Multi Transfer"));
475 const TDmaTransferArgs& CMultiTransferTest::TransferArgs(TInt aIndex) const
477 TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
479 return iTransferArgs[aIndex];
482 void CMultiTransferTest::SetPostTransferResult(TInt aIndex, TInt aErrorCode)
484 TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
486 iActualResults[aIndex].iPostTransferCheck = aErrorCode;
489 void CMultiTransferTest::OpenChannel()
493 RDebug::Printf("CMultiTransferTest::OpenChannel()");
495 TInt r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
497 TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
498 for(TInt i=0; i<iTransferArgsCount; i++)
500 // Since all transfers will use the same channel,
501 // they all get the same result
502 // Arguably, iChannelOpenResult doesn't
504 iActualResults[i].iChannelOpenResult = r;
508 TInt CMultiTransferTest::CloseChannel()
510 return iDmaSession.ChannelClose(iChannelSessionCookie);
513 void CMultiTransferTest::CreateDmaRequests()
517 RDebug::Printf("CMultiTransferTest::CreateDmaRequests() %d", iTransferArgsCount);
519 TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
520 //create a DMA request for each transfer arg struct
521 for(TInt i=0; i<iTransferArgsCount; i++)
523 if(iActualResults[i].iChannelOpenResult != KErrNone)
527 TInt r = KErrGeneral;
531 r = iDmaSession.RequestCreateNew(iChannelSessionCookie, cookie);
535 r = iDmaSession.RequestCreate(iChannelSessionCookie, cookie);
537 iActualResults[i].iRequestResult.iCreate = r;
541 r = iRequestCookies.Append(cookie);
542 TEST_ASSERT(r == KErrNone);
547 void CMultiTransferTest::Fragment()
551 RDebug::Printf("CMultiTransferTest::Fragment() %d", iTransferArgsCount);
553 TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
554 // Fragment each dma request
555 for(TInt i=0; i<iTransferArgsCount; i++)
557 TRequestResults& result = iActualResults[i].iRequestResult;
558 if(result.iCreate != KErrNone)
561 TInt r = KErrGeneral;
563 r = iDmaSession.FragmentRequest(iRequestCookies[i], iTransferArgs[i]);
565 r = iDmaSession.FragmentRequestOld(iRequestCookies[i], iTransferArgs[i]);
567 result.iFragmentationResult = r;
571 void CMultiTransferTest::QueueRequests()
573 if(iPauseWhileQueuing)
575 TInt r = iDmaSession.ChannelPause(iChannelSessionCookie);
576 TEST_ASSERT(r == KErrNone);
579 // Queue all the DMA requests asynchronously
581 RArray<TRequestStatus> requestStates;
583 TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
584 for(i=0; i<iTransferArgsCount; i++)
586 TResultSet& resultSet = iActualResults[i];
587 if(resultSet.iRequestResult.iFragmentationResult != KErrNone)
590 TInt r = requestStates.Append(TRequestStatus());
591 TEST_ASSERT(r == KErrNone);
593 r = iDmaSession.QueueRequest(iRequestCookies[i], requestStates[i], &resultSet.iCallbackRecord, NULL);
594 resultSet.iRequestResult.iQueueResult = r;
597 if(iPauseWhileQueuing)
599 TInt r = iDmaSession.ChannelResume(iChannelSessionCookie);
600 TEST_ASSERT(r == KErrNone);
603 // wait for all transfers to complete
604 const TInt count = requestStates.Count();
606 for(i=0; i<count; i++)
608 User::WaitForRequest(requestStates[i]);
611 requestStates.Close();
614 //TODO support test setup for CMultiTransferTest
615 void CMultiTransferTest::PreTransferSetup()
617 for(TInt i=0; i<iTransferArgsCount; i++)
619 //pre-fill actual results with error values
620 TInt r = iActualResults.Append(TResultSet(EFalse));
621 TEST_ASSERT(r == KErrNone);
624 iPreTransfer->Setup(*this); //initialize test
627 TInt CMultiTransferTest::DoPostTransferCheck()
629 if(iPostTransferCheck)
630 return iPostTransferCheck->Check(*this);
634 //////////////////////////////////////////////////////////////////////
636 //////////////////////////////////////////////////////////////////////
639 CIsrRequeTest::CIsrRequeTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs,
640 TIsrRequeArgs* aRequeueArgs, TInt aCount,
641 const TResultSet& aExpected,const MPreTransfer* aPreTfer,const MPostTransferCheck* aPostTferChk, TUint aMaxFragmentSize)
642 :CSingleTransferTest(aName, aIterations, aArgs, aExpected, aMaxFragmentSize, aPostTferChk, aPreTfer), iRequeArgSet(aRequeueArgs, aCount)
645 void CIsrRequeTest::Queue()
647 if(iActual.iRequestResult.iFragmentationResult == KErrNone)
649 iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequestWithRequeue(iRequestSessionCookie, iRequeArgSet.iRequeArgs, iRequeArgSet.iCount, &iActual.iCallbackRecord);
653 void CIsrRequeTest::PrintTestType() const
655 RDebug::RawPrint(_L("ISR Requeue"));
659 //TODO will need to support buffer checking of the trasnfers
660 TBool CIsrRequeTest::Result()
662 return CSingleTransferTest::Result();
666 void CIsrRequeTest::PreTransferSetup()
669 iPreTransfer->Setup(*this); //initialize test
672 TInt CIsrRequeTest::DoPostTransferCheck()
674 return iPostTransferCheck->Check(*this);
677 //////////////////////////////////////////////////////////////////////
679 //////////////////////////////////////////////////////////////////////
681 void TResultSet::Print() const
683 PRINT(iChannelOpenResult);
684 PRINT(iRequestResult.iCreate);
685 PRINT(iRequestResult.iFragmentCount);
686 PRINT(iRequestResult.iFragmentationResult);
687 PRINT(iRequestResult.iQueueResult);
688 PRINT(iPostTransferCheck);
691 TBool TResultSet::operator == (const TResultSet& aOther) const
693 return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0);
696 //////////////////////////////////////////////////////////////////////
697 // MPostTransferCheck classes
698 //////////////////////////////////////////////////////////////////////
700 TInt TCompareSrcDst::Check(const CSingleTransferTest& aTest) const
704 RDebug::Printf("Comparing CSingleTransferTest buffers");
706 return Check(aTest.TransferArgs(), aTest.Chunk().Base());
710 //this check will not deal correctly transfers were subsequent
712 TInt TCompareSrcDst::Check(const CIsrRequeTest& aTest) const
716 RDebug::Printf("Comparing CIsrRequeTest buffers");
718 TUint8* chunkBase = aTest.Chunk().Base();
719 const TDmaTransferArgs& transferArgs = aTest.TransferArgs();
720 // check first transfer
721 TInt r = Check(transferArgs, chunkBase);
726 // check re-queued transfers
727 const TIsrRequeArgsSet& requeueArgs = aTest.GetRequeueArgs();
728 return Check(requeueArgs, chunkBase, transferArgs);
731 TInt TCompareSrcDst::Check(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const
733 //TODO could make use of Fixup() method
734 const TUint32 srcOffset = aTransferArgs.iSrcConfig.iAddr;
735 const TUint32 dstOffset = aTransferArgs.iDstConfig.iAddr;
736 const TInt size = aTransferArgs.iTransferCount;
738 const TUint8* src = srcOffset + aChunkBase;
739 const TUint8* dst = dstOffset + aChunkBase;
743 RDebug::Printf("Comparing TDmaTransferArgs buffers src=0x%08x dst=0x%08x size=0x%08x",
747 return memcompare(src, size, dst, size);
750 TInt TCompareSrcDst::Check(const TIsrRequeArgsSet& aRequeueArgSet, TUint8* aChunkBase, const TDmaTransferArgs& aTferArgs) const
752 TIsrRequeArgsSet argSet(aRequeueArgSet); //copy since Fixup will mutate object
754 argSet.Substitute(aTferArgs); // replace any default (0) values with the values in aTferArgs
756 argSet.Fixup((TLinAddr)aChunkBase); //convert address offsets to virtual user mode addresses
758 TInt r = KErrCorrupt;
759 while(!argSet.IsEmpty())
761 r = Check(argSet.GetArgs());
768 TInt TCompareSrcDst::Check(const TIsrRequeArgs& aRequeueArgs) const
770 const TUint8* src = (TUint8*)aRequeueArgs.iSrcAddr;
771 const TUint8* dst = (TUint8*)aRequeueArgs.iDstAddr;
772 const TInt size = aRequeueArgs.iTransferCount;
776 RDebug::Printf("Comparing TIsrRequeArgs: src=0x%08x dst=0x%08x size=0x%08x",
780 return memcompare(src, size, dst, size);
783 TInt TCompareSrcDst::Check(CMultiTransferTest& aTest) const
787 RDebug::Printf("Comparing CMultiTransferTest buffers");
790 const TInt transferCount = aTest.TransferCount();
791 TUint8* const chunkBase = aTest.Chunk().Base();
793 // check buffers for each transfer
794 for(TInt i=0; i<transferCount; i++)
796 TInt r = Check(aTest.TransferArgs(i), chunkBase);
797 aTest.SetPostTransferResult(i, r);
799 // CMultiTransferTest is handled differently to the others.
800 // Whereas CSingleTransferTest logs just the return value
801 // of the check, here, we write back a result for each transfer
802 // so the return value from this function is not important
806 TInt TCompare2D::Check(const CSingleTransferTest& aTest) const
808 const TDmaTransferArgs& args = aTest.TransferArgs();
809 TUint8* const chunkBase = aTest.Chunk().Base();
813 TTransferIter src_iter(args.iSrcConfig, chunkBase);
814 TTransferIter dst_iter(args.iDstConfig, chunkBase);
816 for (; (src_iter != end) && (dst_iter !=end); ++src_iter, ++dst_iter)
818 if(*src_iter != *dst_iter)
827 TInt TCompare2D::Check(const CIsrRequeTest&) const
829 return KErrNotSupported;
832 TInt TCompare2D::Check(CMultiTransferTest&) const
834 return KErrNotSupported;
836 //////////////////////////////////////////////////////////////////////
837 // MPreTransfer classes
838 //////////////////////////////////////////////////////////////////////
840 void TPreTransferIncrBytes::Setup(const CSingleTransferTest& aTest) const
844 RDebug::Printf("TPreTransferIncrBytes(CSingleTransferTest)");
846 TAddressParms params = GetAddrParms(aTest.TransferArgs());
848 TUint8* const chunkBase = aTest.Chunk().Base();
849 params.Fixup((TLinAddr)chunkBase);
855 void TPreTransferIncrBytes::Setup(const TAddressParms& aParams) const
859 RDebug::Printf("TPreTransferIncrBytes: setup memory buffers: src=0x%08x dst=0x%08x size=0x%08x",
860 aParams.iSrcAddr, aParams.iDstAddr, aParams.iTransferCount);
862 TUint8* const src = (TUint8*) aParams.iSrcAddr;
863 const TInt size = aParams.iTransferCount;
865 for(TInt i=0; i<size; i++)
866 {src[i] = (TUint8)i;} //each src byte holds its own offset (mod 256)
868 TUint8* const dst = (TUint8*) aParams.iDstAddr;
869 memclr(dst, size); //clear destination
872 void TPreTransferIncrBytes::Setup(const CIsrRequeTest& aTest) const
876 RDebug::Printf("TPreTransferIncrBytes(CIsrRequeTest)");
878 if(!CheckBuffers(aTest))
880 RDebug::Printf("Successive transfer destinations may not overlap previous src or dst buffers");
881 RDebug::Printf("unless the whole transfer is an exact repeat of a previous one");
885 Setup(static_cast<CSingleTransferTest>(aTest)); // prepare the CSingleTransferTest parts
887 TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
889 requeSet.Substitute(aTest.TransferArgs());
891 const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
892 requeSet.Fixup(chunkBase);
894 while(!requeSet.IsEmpty())
896 TIsrRequeArgs args = requeSet.GetArgs();
897 Setup(args); // perform the setup operation for each TIsrRequeArgs
901 void TPreTransferIncrBytes::Setup(const CMultiTransferTest& aTest) const
905 RDebug::Printf("TPreTransferIncrBytes(CMultiTransferTest)");
907 //TODO check for overlap
909 TUint8* const chunkBase = aTest.Chunk().Base();
910 const TInt transferCount = aTest.TransferCount();
912 // initialise buffers for each transfer
913 for(TInt i=0; i<transferCount; i++)
915 TAddressParms params = GetAddrParms(aTest.TransferArgs(i));
917 params.Fixup((TLinAddr)chunkBase);
923 TBool TPreTransferIncrBytes::CheckBuffers(const CIsrRequeTest& aTest) const
925 RArray<const TAddressParms> array;
926 array.AppendL(TAddressParms(aTest.TransferArgs()));
928 TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
929 requeSet.Substitute(aTest.TransferArgs());
931 const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
932 requeSet.Fixup(chunkBase);
933 while(!requeSet.IsEmpty())
935 const TIsrRequeArgs requeArgs = requeSet.GetArgs();
936 array.AppendL(requeArgs);
939 const TBool result = CheckBuffers(array);
946 Check that the destination of each TAddressParms does not overlap with
947 any previous source or destination or that if it does the whole transfer
949 This is so that successive transfers do not overwrite the destinations or
950 sources of preceeding ones.
951 Exactly matching transfers are allowed to test the case that a repeat
952 transfer is required - though it can't then be determined just from
953 looking at the buffers that the repeat was successful
955 TBool TPreTransferIncrBytes::CheckBuffers(const RArray<const TAddressParms> aTransferParams) const
957 const TInt count = aTransferParams.Count();
959 for(TInt i=1; i<count; i++)
961 const TAddressParms& current = aTransferParams[i];
962 for(TInt j=0; j<i; j++)
964 const TAddressParms& previous = aTransferParams[j];
965 const TBool ok = !previous.Overlaps(current.DestRange()) || current == previous;
972 //////////////////////////////////////////////////////////////////////
973 // TTransferIter class
974 //////////////////////////////////////////////////////////////////////
976 void TTransferIter::operator++ ()
978 iPtr++; //the standard post increment
979 if(iElem < (iCfg->iElementsPerFrame-1))
981 iPtr += iCfg->iElementSkip;
987 TEST_ASSERT(iElem == iCfg->iElementsPerFrame-1);
988 if(iFrame < iCfg->iFramesPerTransfer-1)
990 iPtr += iCfg->iFrameSkip;
997 //we have reached the end
998 TEST_ASSERT(iFrame == iCfg->iFramesPerTransfer-1);
1006 void TTransferIter::Invariant() const
1008 const TInt elemSize = iCfg->iElementSize;
1009 RTest test(_L("TTransferIter invariant"));
1010 const TInt bytesTransfered = (
1011 elemSize * (iFrame * iCfg->iElementsPerFrame + iElem)
1012 + ((TUint)iPtr % (elemSize))
1014 test_Equal(iBytes, bytesTransfered);
1018 ///////////////////////////////////////////////////////////
1020 ///////////////////////////////////////////////////////////
1021 TTestCase::TTestCase(CDmaTest* aTest,
1023 const TDmaCapability aCap1,
1024 const TDmaCapability aCap2,
1025 const TDmaCapability aCap3,
1026 const TDmaCapability aCap4,
1027 const TDmaCapability aCap5
1030 iTest(aTest), iConcurrentTest(aConcurrent)
1032 iChannelCaps[0] = aCap1;
1033 iChannelCaps[1] = aCap2;
1034 iChannelCaps[2] = aCap3;
1035 iChannelCaps[3] = aCap4;
1036 iChannelCaps[4] = aCap5;
1039 TResult TTestCase::TestCaseValid(const SDmacCaps& aChannelCaps) const
1041 const TDmaCapability* cap = &iChannelCaps[0];
1044 //We assume that the array is empty at the first ENone found
1045 //any caps after this wil be ignored
1046 while(cap->iCapsReq != ENone)
1048 TResult t = cap->CompareToDmaCaps(aChannelCaps);
1049 if(t > ret) //this relies on the enum ordering
1056 TResult TTestCase::TestCaseValid(const TDmacTestCaps& aChannelCaps) const
1058 const TDmaCapability* cap = &iChannelCaps[0];
1061 //We assume that the array is empty at the first ENone found
1062 //any caps after this wil be ignored
1063 while(cap->iCapsReq != ENone)
1065 TResult t = cap->CompareToDmaCaps(aChannelCaps);
1066 if(t > ret) //this relies on the enum ordering
1073 Will report whether a value held in aChannelCaps satisfies a
1074 requirement specfied by this object
1076 TBool TDmaCapability::RequirementSatisfied(const SDmacCaps& aChannelCaps) const
1082 case EChannelPriorities:
1084 case EChannelPauseAndResume:
1085 return aChannelCaps.iChannelPauseAndResume == (TBool)iValue;
1086 case EAddrAlignedToElementSize:
1089 return aChannelCaps.i1DIndexAddressing == (TBool)iValue;
1091 return aChannelCaps.i2DIndexAddressing == (TBool)iValue;
1092 case ESynchronizationTypes:
1093 case EBurstTransactions:
1094 case EDescriptorInterrupt:
1095 case EFrameInterrupt:
1096 case ELinkedListPausedInterrupt:
1097 case EEndiannessConversion:
1099 case ERepeatingTransfers:
1100 case EChannelLinking:
1102 case EHwDescriptors:
1103 return aChannelCaps.iHwDescriptors == (TBool)iValue;
1104 case ESrcDstAsymmetry:
1105 case EAsymHwDescriptors:
1107 case EBalancedAsymSegments:
1108 return aChannelCaps.iBalancedAsymSegments == (TBool)iValue;
1109 case EAsymCompletionInterrupt:
1110 return aChannelCaps.iAsymCompletionInterrupt == (TBool)iValue;
1111 case EAsymDescriptorInterrupt:
1112 return aChannelCaps.iAsymDescriptorInterrupt == (TBool)iValue;
1113 case EAsymFrameInterrupt:
1114 return aChannelCaps.iAsymFrameInterrupt == (TBool)iValue;
1123 Will report whether a value held in aChannelCaps satisfies a
1124 requirement specfied by this object
1126 TBool TDmaCapability::RequirementSatisfied(const TDmacTestCaps& aChannelCaps) const
1131 return TestValue(aChannelCaps.iPILVersion);
1133 return RequirementSatisfied(static_cast<SDmacCaps>(aChannelCaps));
1137 TResult TDmaCapability::CompareToDmaCaps(const SDmacCaps& aChannelCaps) const
1139 const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
1146 return iFail ? EFail : ESkip;
1150 TResult TDmaCapability::CompareToDmaCaps(const TDmacTestCaps& aChannelCaps) const
1152 const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
1159 return iFail ? EFail : ESkip;
1163 Test that aValue satisfies the comparrison (iCapsReqType) with the
1164 reference value held in iValue
1166 TBool TDmaCapability::TestValue(TUint aValue) const
1168 switch(iCapsReqType)
1171 return aValue == iValue;
1173 return aValue >= iValue;
1175 return aValue <= iValue;
1184 static RTest test(_L("DMAv2 test"));
1186 //////////////////////////////////////////////////////////////////////
1188 //////////////////////////////////////////////////////////////////////
1189 TTestRunner::TTestRunner()
1191 // Open RDmaSession handle
1192 TInt r = iDmaSession.Open();
1193 TEST_ASSERT(r == KErrNone);
1195 // Get PSI Test info
1196 r = iDmaSession.GetTestInfo(iPslTestInfo);
1197 TEST_ASSERT(r == KErrNone);
1199 //Retrieve PSL cookies
1202 //Generate the DMA channel records
1203 GenerateChannelRecord();
1206 TTestRunner::~TTestRunner()
1208 RTest::CloseHandleAndWaitForDestruction(iDmaSession);
1209 iTestCases.Close(); //TestRunner does not own test cases
1210 iChannelRecords.Close();
1211 iPslCookies.Close();
1214 void TTestRunner::AddTestCases(RPointerArray<TTestCase>& aTTestCases)
1216 const TInt count = aTTestCases.Count();
1217 for(TInt i=0; i < count; i++)
1219 iTestCases.AppendL(aTTestCases[i]);
1223 void TTestRunner::RunTests()
1228 Print(iPslTestInfo);
1231 //iterate through the test case array
1232 const TInt testCaseCount = iTestCases.Count();
1233 for(TInt i=0; i < testCaseCount; i++)
1235 const TTestCase& testCase = *iTestCases[i];
1237 //Here, we must create a test thread for each channel
1238 RPointerArray<CTest> concurrentTests;
1240 if(testCase.iConcurrentTest)
1241 RDebug::Printf("== Begin concurrent test run ==");
1243 const TInt chanRecCount = iChannelRecords.Count();
1244 for(TInt j=0; j < chanRecCount; j++)
1246 const TChannelRecord& record = iChannelRecords[j];
1247 const TDmacTestCaps& caps = record.iChannelCaps;
1249 const TResult t = testCase.TestCaseValid(caps);
1255 CDmaTest* dmaTest = static_cast<CDmaTest*>(testCase.iTest->Clone());
1256 TEST_ASSERT(dmaTest != NULL);
1258 dmaTest->SetChannelCookie(record.iCookie);
1259 dmaTest->Announce();
1260 if(testCase.iConcurrentTest)
1262 //Add test to array to be run concurrently
1263 TInt r = concurrentTests.Append(dmaTest);
1264 TEST_ASSERT(r == KErrNone);
1268 //Run test in this thread
1271 TBool result = dmaTest->Result();
1272 TEST_ASSERT(result);
1282 RDebug::Printf("Skipping test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
1288 RDebug::Printf("Failling test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
1294 //Depending on the value of iConcurrentTest the test runner will either block until the thread has completed or
1295 //alternatively run the current test case on the next channel:
1297 //if the test case has been run on all channels it will then wait for all threads to complete.
1300 const TInt count = concurrentTests.Count();
1303 MultipleTestRun(concurrentTests);
1304 for(TInt i=0; i<count; i++)
1306 TBool result = static_cast<CDmaTest*>(concurrentTests[i])->Result();
1307 TEST_ASSERT(result);
1309 RDebug::Printf("== End concurrent test run ==");
1312 concurrentTests.ResetAndDestroy();
1316 void TTestRunner::GetPslCookie()
1318 //Get Sb Channel cookies
1319 for(TInt sb_channelcount=0; sb_channelcount<iPslTestInfo.iMaxSbChannels; sb_channelcount++)
1321 iPslCookies.AppendL(iPslTestInfo.iSbChannels[sb_channelcount]);
1324 //Get Db Channel cookies
1325 for(TInt db_channelcount=0; db_channelcount<iPslTestInfo.iMaxDbChannels; db_channelcount++)
1327 iPslCookies.AppendL(iPslTestInfo.iDbChannels[db_channelcount]);
1330 //Get Sg Channel cookies
1331 for(TInt sg_channelcount=0; sg_channelcount<iPslTestInfo.iMaxSgChannels; sg_channelcount++)
1333 iPslCookies.AppendL(iPslTestInfo.iSgChannels[sg_channelcount]);
1337 void TTestRunner::GenerateChannelRecord()
1339 //for each PSL cookie
1340 for(TInt count=0; count<iPslCookies.Count(); count++)
1342 //Get channel cookie
1343 const TUint pslCookie = iPslCookies[count];
1344 TUint sessionCookie;
1345 TInt r = iDmaSession.ChannelOpen(pslCookie, sessionCookie);
1346 TEST_ASSERT(r == KErrNone);
1349 RDebug::Printf("Channel PSL Cookie[%d] :0x%08x",count,pslCookie);
1352 TChannelRecord dmaChannelRecord;
1353 dmaChannelRecord.iCookie = pslCookie;
1356 r = iDmaSession.ChannelCaps(sessionCookie, dmaChannelRecord.iChannelCaps);
1357 TEST_ASSERT(r == KErrNone);
1359 r = iDmaSession.ChannelClose(sessionCookie);
1360 TEST_ASSERT(r == KErrNone);
1363 iChannelRecords.AppendL(dmaChannelRecord);
1366 //////////////////////////////////////////////////////////////////////
1367 // Global test functions and E32Main
1368 //////////////////////////////////////////////////////////////////////
1371 Displayed if used supplied no parameters, garbage, or a ? in the parameters
1375 test.Printf(_L("*** DMA TEST FRAMEWORK ***\n"));
1376 test.Printf(_L("Usage : t_dma2.exe [/option]\n"));
1377 test.Printf(_L(" /V or /VERBOSE = Control test output\n"));
1378 test.Printf(_L(" /S or /SELFTEST = Run DMA self test\n"));
1379 test.Printf(_L("\n"));
1382 void ProcessCommandLineL()
1384 test.Printf(_L("Process command line arguments\n"));
1386 TInt cmdLineLength(User::CommandLineLength());
1387 HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength);
1388 TPtr cmdLinePtr = cmdLine->Des();
1389 User::CommandLine(cmdLinePtr);
1390 TBool tokenParsed(EFalse);
1392 TLex args(*cmdLine);
1393 args.SkipSpace(); // args are separated by spaces
1395 // first arg is the exe name, skip it
1396 TPtrC cmdToken = args.NextToken();
1397 HBufC* tc = HBufC::NewLC(KParameterTextLenMax);
1399 while (tc->Length())
1401 tokenParsed = EFalse;
1403 // '/?' help wanted flag '?' or /? parameter
1404 if ((0== tc->FindF(_L("?"))) || (0==tc->FindF(_L("/?"))))
1406 gHelpRequested = ETrue;
1407 tokenParsed = ETrue;
1411 if ((0== tc->FindF(KArgSelfTest)) || (0==tc->FindF(KArgSelfTest2)))
1414 test.Printf(_L("Command Line Options:Selftest option specified.\n"));
1416 tokenParsed = ETrue;
1419 // '/VERBOSE' option
1420 if ((0== tc->FindF(KArgVerboseOutput)) || (0==tc->FindF(KArgVerboseOutput2)))
1422 test.Printf(_L("Command Line Options:Verbose option specified.\n"));
1423 gVerboseOutput = ETrue;
1424 tokenParsed = ETrue;
1429 // warn about unparsed parameter
1430 test.Printf(_L("Warning: '%lS'??? not parsed\n"), tc);
1431 gHelpRequested = ETrue;
1435 *tc = args.NextToken();
1437 CleanupStack::PopAndDestroy(tc);
1438 CleanupStack::PopAndDestroy(cmdLine);
1443 test.Start(_L("Creating test runner\n"));
1444 TTestRunner testRunner;
1446 test.Next(_L("Add global test cases to test runner\n"));
1447 testRunner.AddTestCases(TestArray);
1449 test.Next(_L("call TTestRunner::RunTests()\n"));
1450 testRunner.RunTests();
1461 gHelpRequested = EFalse;
1464 // Create the new trap-cleanup mechanism
1465 CTrapCleanup* cleanup = CTrapCleanup::New();
1467 if (cleanup == NULL)
1469 return KErrNoMemory;
1472 // Process the command line parameters for batch/etc
1473 TRAPD(err, ProcessCommandLineL());
1474 if (err != KErrNone)
1476 User::Panic(_L("DMA test run memory failure"), KErrNoMemory);
1482 User::Leave(-2); // nothing to do!
1484 test.Start(_L("Loading test LDD"));
1485 //load either the new test ldd, d_dma2.ldd,
1486 //or d_dma2_compat.ldd - an ldd linked against
1487 //the old DMA framework
1488 _LIT(KDma, "D_DMA2.LDD");
1489 r = User::LoadLogicalDevice(KDma);
1490 const TBool dma2Loaded = ((r == KErrNone) || (r == KErrAlreadyExists));
1492 _LIT(KDma2Compat, "D_DMA2_COMPAT.LDD");
1493 r = User::LoadLogicalDevice(KDma2Compat);
1494 const TBool dma2CompatLoaded = ((r == KErrNone) || (r == KErrAlreadyExists));
1496 if (!(dma2Loaded || dma2CompatLoaded))
1498 //TODO how can we distinguish this case from a platform where
1499 //dma is supposed to be supported but the dma test ldd is
1501 test.Printf(_L("DMA not supported - test skipped\n"));
1504 else if (dma2Loaded && !dma2CompatLoaded)
1506 test.Printf(_L("Loaded %S\n"), &KDma);
1508 else if (!dma2Loaded && dma2CompatLoaded)
1510 test.Printf(_L("Loaded %S\n"), &KDma2Compat);
1514 test.Printf(_L("The ROM contains %S and %S - only one should be present\n"), &KDma, &KDma2Compat);
1517 // Turn off evil lazy dll unloading
1519 test(l.Connect()==KErrNone);
1520 test(l.CancelLazyDllUnload()==KErrNone);
1521 RTest::CloseHandleAndWaitForDestruction(l);
1525 if (gSelfTest) //Run self tests if specified on command line
1536 r = User::FreeLogicalDevice(KTestDmaLddName);