os/kernelhwsrv/kerneltest/e32test/dmav2/t_dma2.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\dma\t_dma.cpp
    15 
    16 #include "d_dma2.h"
    17 #include "u32std.h"
    18 #include "t_dma2.h"
    19 #include "cap_reqs.h"
    20 
    21 #define __E32TEST_EXTENSION__
    22 #include <e32test.h>
    23 #include <e32debug.h>
    24 #include <e32svr.h>
    25 #include <e32def_private.h>
    26 
    27 // DMA test framework command  parameter options
    28 
    29 // SelfTest Option
    30 _LIT(KArgSelfTest, "/SELFTEST");  
    31 _LIT(KArgSelfTest2, "/S");		  
    32 
    33 //Verbose Option
    34 _LIT(KArgVerboseOutput, "/VERBOSE"); 
    35 _LIT(KArgVerboseOutput2, "/V");	     
    36   
    37 
    38 TBool gHelpRequested;   // print usage 
    39 TBool gVerboseOutput;   // enable verbose output 
    40 TBool gSelfTest;        // run SelfTest 
    41 
    42 /**
    43 This function prints out the PSL test Information
    44 */
    45 void Print(const TDmaV2TestInfo& aInfo)
    46 	{
    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++)
    52 		{
    53 		PRINT(aInfo.iSbChannels[i]);
    54 		}
    55 	PRINT(aInfo.iMaxDbChannels);
    56 	for(TInt j=0; j<aInfo.iMaxDbChannels; j++)
    57 		{
    58 		PRINT(aInfo.iDbChannels[j]);
    59 		}
    60 	PRINT(aInfo.iMaxSgChannels);
    61 	for(TInt k=0; k<aInfo.iMaxSgChannels; k++)
    62 		{
    63 		PRINT(aInfo.iSgChannels[k]);
    64 		}
    65 	}
    66 
    67 void CDmaTest::PrintTestInfo() const
    68 	{
    69 	TBuf<32> buf;
    70 	buf.AppendFormat(_L("DMA channel %d"), iChannelCookie);
    71 	RDebug::RawPrint(buf);
    72 	}
    73 
    74 //////////////////////////////////////////////////////////////////////
    75 // CDmaTest
    76 //////////////////////////////////////////////////////////////////////
    77 
    78 void CDmaTest::OpenDmaSession()
    79 	{
    80 	TInt r = iDmaSession.Open();
    81 	TEST_ASSERT(r == KErrNone);
    82 	r = iDmaSession.OpenSharedChunk(iChunk);
    83 	TEST_ASSERT(r == KErrNone);
    84 	}
    85 
    86 void CDmaTest::CloseDmaSession()
    87 	{
    88 	iChunk.Close();
    89 	iDmaSession.Close();
    90 	}
    91 
    92 //////////////////////////////////////////////////////////////////////
    93 // CSingleTransferTest
    94 //////////////////////////////////////////////////////////////////////
    95 void CSingleTransferTest::RunTest()
    96 	{
    97 	OpenDmaSession();
    98 	PreTransferSetup();
    99 
   100 	OpenChannel();
   101 	CreateDmaRequest();
   102 	Fragment();
   103 	Queue();
   104 	FreeRequest();
   105 	CloseChannel();
   106 	PostTransferCheck();
   107 
   108 	CloseDmaSession();
   109 	}
   110 
   111 void CSingleTransferTest::OpenChannel()
   112 	{
   113 	iActual.iChannelOpenResult =
   114 		iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
   115 	}
   116 
   117 void CSingleTransferTest::CreateDmaRequest()
   118 	{
   119 	if(iUseNewRequest)
   120 	{
   121 		if(gVerboseOutput)
   122 			{
   123 			RDebug::Printf("Calling New Request API\n");
   124 			}
   125 		iActual.iRequestResult.iCreate =
   126 			iDmaSession.RequestCreateNew(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
   127 		}
   128 	else
   129 		{
   130 		if(gVerboseOutput)
   131 			{
   132 			RDebug::Printf("Calling Old Request API\n");
   133 			}
   134 		iActual.iRequestResult.iCreate =
   135 			iDmaSession.RequestCreate(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
   136 		}
   137 	}
   138 
   139 void CSingleTransferTest::Fragment()
   140 	{
   141 	if(iActual.iRequestResult.iCreate != KErrNone)
   142 		return;
   143 
   144 	if(iUseNewFragment)
   145 		{
   146 		if(gVerboseOutput)
   147 			{
   148 			RDebug::Printf("Calling New Fragment API\n");
   149 			}
   150 		iActual.iRequestResult.iFragmentationResult =
   151 			iDmaSession.FragmentRequest(iRequestSessionCookie, iTransferArgs);
   152 		}
   153 	else
   154 		{
   155 		if(gVerboseOutput)
   156 			{
   157 			RDebug::Printf("Calling Old Fragment API\n");
   158 			}
   159 		iActual.iRequestResult.iFragmentationResult =
   160 			iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs);
   161 
   162 		}
   163 
   164 	const TInt fragmentCount = iDmaSession.RequestFragmentCount(iRequestSessionCookie);
   165 
   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;
   170 	}
   171 
   172 void CSingleTransferTest::Queue()
   173 	{
   174 	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   175 		{
   176 		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord);
   177 		}
   178 	}
   179 
   180 void CSingleTransferTest::PostTransferCheck()
   181 	{
   182 	if(iPostTransferCheck)
   183 		iActual.iPostTransferCheck = DoPostTransferCheck();
   184 	}
   185 
   186 TInt CSingleTransferTest::DoPostTransferCheck()
   187 	{
   188 	return iPostTransferCheck->Check(*this);
   189 	}
   190 
   191 void CSingleTransferTest::FreeRequest()
   192 	{
   193 	if(iActual.iRequestResult.iCreate == KErrNone)
   194 		{
   195 		TInt r = iDmaSession.RequestDestroy(iRequestSessionCookie);
   196 		TEST_ASSERT(r == KErrNone);
   197 		}
   198 	}
   199 
   200 void CSingleTransferTest::CloseChannel()
   201 	{
   202 	if(iActual.iChannelOpenResult == KErrNone)
   203 		{
   204 		TInt r = iDmaSession.ChannelClose(iChannelSessionCookie);
   205 		TEST_ASSERT(r == KErrNone);
   206 		}
   207 	}
   208 
   209 void CSingleTransferTest::PrintTestType() const
   210 	{
   211 	RDebug::RawPrint(_L("Single transfer"));
   212 	}
   213 
   214 void CSingleTransferTest::PreTransferSetup()
   215 	{
   216 	if(iPreTransfer)
   217 		iPreTransfer->Setup(*this); //initialize test
   218 	}
   219 
   220 TBool CSingleTransferTest::Result()
   221 	{
   222 	const TBool result = iExpected == iActual;
   223 	if(!result)
   224 		{
   225 		RDebug::Printf("TResultSets do not match");
   226 		}
   227 	if(!result || gVerboseOutput)
   228 		{
   229 		RDebug::Printf("\nExpected error codes:");
   230 		iExpected.Print();
   231 		RDebug::Printf("Expected callback record:");
   232 		iExpected.iCallbackRecord.Print();
   233 
   234 		RDebug::Printf("\nActual error codes:");
   235 		iActual.Print();
   236 		RDebug::Printf("Actual callback record:");
   237 		iActual.iCallbackRecord.Print();
   238 		}
   239 	return result;
   240 	}
   241 
   242 
   243 
   244 //////////////////////////////////////////////////////////////////////
   245 // CDmaBenchmark
   246 //////////////////////////////////////////////////////////////////////
   247 
   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)
   250 	{
   251 	UseNewDmaApi(EFalse);
   252 	}
   253 
   254 CDmaBenchmark::~CDmaBenchmark()
   255 	{
   256 	iResultArray.Close();
   257 	}
   258 
   259 TUint64 CDmaBenchmark::MeanResult()
   260 	{
   261 	if(gVerboseOutput)
   262 		RDebug::Printf("CDmaBenchmark::MeanResult\n");
   263 
   264 	const TInt count = iResultArray.Count();
   265 
   266 	TEST_ASSERT(count > 0);
   267 	TEST_ASSERT(count == iIterations);
   268 
   269 	TUint64 sum = 0;
   270 
   271 	for(TInt i = 0; i < count; i++)
   272 		{
   273 		const TUint64 value = iResultArray[i];
   274 		if(gVerboseOutput)
   275 			RDebug::Printf("iResultArray[%d]: %lu", i, value);
   276 
   277 		sum += value;
   278 		}
   279 
   280 	return sum / count;
   281 	}
   282 
   283 TBool CDmaBenchmark::Result()
   284 	{
   285 	const TBool result = CSingleTransferTest::Result();
   286 	if(result)
   287 		{
   288 		RDebug::Printf("  Mean time: %lu us", MeanResult());
   289 		}
   290 
   291 	//TODO this will be handled by the ctor later
   292 	iResultArray.Close();
   293 
   294 	return result;
   295 	}
   296 
   297 
   298 //////////////////////////////////////////////////////////////////////
   299 // CDmaBmFragmentation
   300 //////////////////////////////////////////////////////////////////////
   301 
   302 CDmaBmFragmentation::CDmaBmFragmentation(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
   303 	:CDmaBenchmark(aName, aIterations, ExpectedResults, aTransferArgs, aMaxFragmentSize)
   304 	{}
   305 
   306 const TResultSet CDmaBmFragmentation::ExpectedResults(KErrNone,
   307 		TRequestResults(KErrNone, 0, KErrNone, KErrUnknown),
   308 		KErrUnknown,
   309 		TCallbackRecord::Empty()
   310 		);
   311 
   312 void CDmaBmFragmentation::Fragment()
   313 	{
   314 	TUint64 time;
   315 	iActual.iRequestResult.iFragmentationResult =
   316 		iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs, &time);
   317 	iResultArray.Append(time);
   318 	}
   319 
   320 void CDmaBmFragmentation::PrintTestType() const
   321 	{
   322 	RDebug::RawPrint(_L("Fragmentation Benchmark"));
   323 	}
   324 
   325 void CDmaBmFragmentation::RunTest()
   326 	{
   327 	OpenDmaSession();
   328 
   329 	OpenChannel();
   330 	CreateDmaRequest();
   331 	Fragment();
   332 	FreeRequest();
   333 	CloseChannel();
   334 
   335 	CloseDmaSession();
   336 	}
   337 
   338 //////////////////////////////////////////////////////////////////////
   339 // CDmaBmTransfer
   340 //////////////////////////////////////////////////////////////////////
   341 
   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)
   346 	{}
   347 
   348 
   349 void CDmaBmTransfer::PrintTestType() const
   350 	{
   351 	RDebug::RawPrint(_L("Transfer Benchmark"));
   352 	}
   353 
   354 void CDmaBmTransfer::RunTest()
   355 	{
   356 	OpenDmaSession();
   357 
   358 	OpenChannel();
   359 	CreateDmaRequest();
   360 	Fragment();
   361 	Queue();
   362 	FreeRequest();
   363 	CloseChannel();
   364 
   365 	CloseDmaSession();
   366 	}
   367 
   368 void CDmaBmTransfer::Queue()
   369 	{
   370 	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   371 		{
   372 		TUint64 time;
   373 		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord, &time);
   374 		iResultArray.Append(time);
   375 		}
   376 	}
   377 
   378 
   379 //////////////////////////////////////////////////////////////////////
   380 // CMultiTransferTest
   381 //////////////////////////////////////////////////////////////////////
   382 
   383 //TODO
   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)
   389 	{}
   390 
   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
   396 	//array values
   397 	//TODO iRequestCookies(const_cast<TUint*>(&aOther.iRequestCookies[0]), aOther.iRequestCookies.Count())
   398 	{
   399 	}
   400 
   401 CMultiTransferTest::~CMultiTransferTest()
   402 	{
   403 	iRequestCookies.Close();
   404 	iActualResults.Close();
   405 	}
   406 
   407 TBool CMultiTransferTest::Result()
   408 	{
   409 	if(gVerboseOutput)
   410 		{
   411 		RDebug::Printf("Results for %d transfers:", iTransferArgsCount);
   412 		}
   413 
   414 	TBool result = EFalse;
   415 	for(TInt i=0; i<iTransferArgsCount; i++)
   416 		{
   417 		result = Result(i);
   418 		if(!result)
   419 			break;
   420 		}
   421 	return result;
   422 	}
   423 
   424 TBool CMultiTransferTest::Result(TInt aTransfer)
   425 	{
   426 	const TResultSet& expected = iExpectedArray[aTransfer];
   427 	const TResultSet& actual = iActualResults[aTransfer];
   428 	const TBool result = expected == actual;
   429 	if(!result || gVerboseOutput)
   430 		{
   431 		RDebug::Printf("Compairing results for transfer %d", aTransfer);
   432 		}
   433 
   434 	if(!result)
   435 		{
   436 		RDebug::Printf("TResultSets do not match");
   437 		}
   438 	if(!result || gVerboseOutput)
   439 		{
   440 		RDebug::Printf("\nExpected error codes:");
   441 		expected.Print();
   442 		RDebug::Printf("Expected callback record:");
   443 		expected.iCallbackRecord.Print();
   444 
   445 		RDebug::Printf("\nActual error codes:");
   446 		actual.Print();
   447 		RDebug::Printf("Actual callback record:");
   448 		actual.iCallbackRecord.Print();
   449 		}
   450 	return result;
   451 	}
   452 void CMultiTransferTest::RunTest()
   453 	{
   454 	OpenDmaSession();
   455 
   456 	PreTransferSetup();
   457 	OpenChannel();
   458 
   459 	CreateDmaRequests();
   460 	Fragment();
   461 
   462 	QueueRequests();
   463 
   464 	TInt r = DoPostTransferCheck();
   465 	TEST_ASSERT(r == KErrNone);
   466 
   467 	CloseDmaSession();
   468 	}
   469 
   470 void CMultiTransferTest::PrintTestType() const
   471 	{
   472 	RDebug::RawPrint(_L("Multi Transfer"));
   473 	}
   474 
   475 const TDmaTransferArgs& CMultiTransferTest::TransferArgs(TInt aIndex) const
   476 	{
   477 	TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
   478 
   479 	return iTransferArgs[aIndex];
   480 	}
   481 
   482 void CMultiTransferTest::SetPostTransferResult(TInt aIndex, TInt aErrorCode)
   483 	{
   484 	TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
   485 
   486 	iActualResults[aIndex].iPostTransferCheck = aErrorCode;
   487 	}
   488 
   489 void CMultiTransferTest::OpenChannel()
   490 	{
   491 	if(gVerboseOutput)
   492 		{
   493 		RDebug::Printf("CMultiTransferTest::OpenChannel()");
   494 		}
   495 	TInt r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
   496 
   497 	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   498 	for(TInt i=0; i<iTransferArgsCount; i++)
   499 		{
   500 		// Since all transfers will use the same channel,
   501 		// they all get the same result
   502 		// Arguably, iChannelOpenResult doesn't
   503 		// belong TResultSet
   504 		iActualResults[i].iChannelOpenResult = r;
   505 		}
   506 	}
   507 
   508 TInt CMultiTransferTest::CloseChannel()
   509 	{
   510 	return iDmaSession.ChannelClose(iChannelSessionCookie);
   511 	}
   512 
   513 void CMultiTransferTest::CreateDmaRequests()
   514 	{
   515 	if(gVerboseOutput)
   516 		{
   517 		RDebug::Printf("CMultiTransferTest::CreateDmaRequests() %d", iTransferArgsCount);
   518 		}
   519 	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   520 	//create a DMA request for each transfer arg struct
   521 	for(TInt i=0; i<iTransferArgsCount; i++)
   522 		{
   523 		if(iActualResults[i].iChannelOpenResult != KErrNone)
   524 			continue;
   525 
   526 		TUint cookie = 0;
   527 		TInt r = KErrGeneral;
   528 
   529 		if(iNewDmaApi)
   530 			{
   531 			r = iDmaSession.RequestCreateNew(iChannelSessionCookie, cookie);
   532 			}
   533 		else
   534 			{
   535 			r = iDmaSession.RequestCreate(iChannelSessionCookie, cookie);
   536 			}
   537 		iActualResults[i].iRequestResult.iCreate = r;
   538 
   539 		if(r == KErrNone)
   540 			{
   541 			r = iRequestCookies.Append(cookie);
   542 			TEST_ASSERT(r == KErrNone);
   543 			}
   544 		}
   545 	}
   546 
   547 void CMultiTransferTest::Fragment()
   548 	{
   549 	if(gVerboseOutput)
   550 		{
   551 		RDebug::Printf("CMultiTransferTest::Fragment() %d", iTransferArgsCount);
   552 		}
   553 	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   554 	// Fragment each dma request
   555 	for(TInt i=0; i<iTransferArgsCount; i++)
   556 		{
   557 		TRequestResults& result = iActualResults[i].iRequestResult;
   558 		if(result.iCreate != KErrNone)
   559 			continue;
   560 
   561 		TInt r = KErrGeneral;
   562 		if(iNewDmaApi)
   563 			r = iDmaSession.FragmentRequest(iRequestCookies[i], iTransferArgs[i]);
   564 		else
   565 			r = iDmaSession.FragmentRequestOld(iRequestCookies[i], iTransferArgs[i]);
   566 
   567 		result.iFragmentationResult = r;
   568 		}
   569 	}
   570 
   571 void CMultiTransferTest::QueueRequests()
   572 	{
   573 	if(iPauseWhileQueuing)
   574 		{
   575 		TInt r = iDmaSession.ChannelPause(iChannelSessionCookie);
   576 		TEST_ASSERT(r == KErrNone);
   577 		}
   578 
   579 	// Queue all the DMA requests asynchronously
   580 	TInt i;
   581 	RArray<TRequestStatus> requestStates;
   582 
   583 	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   584 	for(i=0; i<iTransferArgsCount; i++)
   585 		{
   586 		TResultSet& resultSet = iActualResults[i];
   587 		if(resultSet.iRequestResult.iFragmentationResult != KErrNone)
   588 			continue;
   589 
   590 		TInt r = requestStates.Append(TRequestStatus());
   591 		TEST_ASSERT(r == KErrNone);
   592 
   593 		r = iDmaSession.QueueRequest(iRequestCookies[i], requestStates[i], &resultSet.iCallbackRecord, NULL);
   594 		resultSet.iRequestResult.iQueueResult = r;
   595 		}
   596 
   597 	if(iPauseWhileQueuing)
   598 		{
   599 		TInt r = iDmaSession.ChannelResume(iChannelSessionCookie);
   600 		TEST_ASSERT(r == KErrNone);
   601 		}
   602 
   603 	// wait for all transfers to complete
   604 	const TInt count = requestStates.Count();
   605 
   606 	for(i=0; i<count; i++)
   607 		{
   608 		User::WaitForRequest(requestStates[i]);
   609 		}
   610 
   611 	requestStates.Close();
   612 	}
   613 
   614 //TODO support test setup for CMultiTransferTest
   615 void CMultiTransferTest::PreTransferSetup()
   616 	{
   617 	for(TInt i=0; i<iTransferArgsCount; i++)
   618 		{
   619 		//pre-fill actual results with error values
   620 		TInt r = iActualResults.Append(TResultSet(EFalse));
   621 		TEST_ASSERT(r == KErrNone);
   622 		}
   623 	if(iPreTransfer)
   624 		iPreTransfer->Setup(*this); //initialize test
   625 	}
   626 
   627 TInt CMultiTransferTest::DoPostTransferCheck()
   628 	{
   629 	if(iPostTransferCheck)
   630 		return iPostTransferCheck->Check(*this);
   631 	else
   632 		return KErrNone;
   633 	}
   634 //////////////////////////////////////////////////////////////////////
   635 // CIsrRequeTest
   636 //////////////////////////////////////////////////////////////////////
   637 
   638 
   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)
   643 	{}
   644 
   645 void CIsrRequeTest::Queue()
   646 	{
   647 	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   648 		{
   649 		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequestWithRequeue(iRequestSessionCookie, iRequeArgSet.iRequeArgs, iRequeArgSet.iCount, &iActual.iCallbackRecord);
   650 		}
   651 	}
   652 
   653 void CIsrRequeTest::PrintTestType() const
   654 	{
   655 	RDebug::RawPrint(_L("ISR Requeue"));
   656 	}
   657 
   658 /*
   659 //TODO will need to support buffer checking of the trasnfers
   660 TBool CIsrRequeTest::Result()
   661 	{
   662 	return CSingleTransferTest::Result();
   663 	}
   664 */
   665 
   666 void CIsrRequeTest::PreTransferSetup()
   667 	{
   668 	if(iPreTransfer)
   669 		iPreTransfer->Setup(*this); //initialize test
   670 	}
   671 
   672 TInt CIsrRequeTest::DoPostTransferCheck()
   673 	{
   674 	return iPostTransferCheck->Check(*this);
   675 	}
   676 
   677 //////////////////////////////////////////////////////////////////////
   678 // TResultSet
   679 //////////////////////////////////////////////////////////////////////
   680 
   681 void TResultSet::Print() const
   682 	{
   683 	PRINT(iChannelOpenResult);
   684 	PRINT(iRequestResult.iCreate);
   685 	PRINT(iRequestResult.iFragmentCount);
   686 	PRINT(iRequestResult.iFragmentationResult);
   687 	PRINT(iRequestResult.iQueueResult);
   688 	PRINT(iPostTransferCheck);
   689 	}
   690 
   691 TBool TResultSet::operator == (const TResultSet& aOther) const
   692 	{
   693 	return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0);
   694 	}
   695 
   696 //////////////////////////////////////////////////////////////////////
   697 // MPostTransferCheck classes
   698 //////////////////////////////////////////////////////////////////////
   699 
   700 TInt TCompareSrcDst::Check(const CSingleTransferTest& aTest) const
   701 	{
   702 	if(gVerboseOutput)
   703 		{
   704 		RDebug::Printf("Comparing CSingleTransferTest buffers");
   705 		}
   706 	return Check(aTest.TransferArgs(), aTest.Chunk().Base());
   707 	}
   708 
   709 //TODO
   710 //this check will not deal correctly transfers were subsequent
   711 //requeues overlap
   712 TInt TCompareSrcDst::Check(const CIsrRequeTest& aTest) const
   713 	{
   714 	if(gVerboseOutput)
   715 		{
   716 		RDebug::Printf("Comparing CIsrRequeTest buffers");
   717 		}
   718 	TUint8* chunkBase = aTest.Chunk().Base();
   719 	const TDmaTransferArgs& transferArgs = aTest.TransferArgs();
   720 	// check first transfer
   721 	TInt r = Check(transferArgs, chunkBase);
   722 
   723 	if(r != KErrNone)
   724 		return r;
   725 
   726 	// check re-queued transfers
   727 	const TIsrRequeArgsSet& requeueArgs = aTest.GetRequeueArgs();
   728 	return Check(requeueArgs, chunkBase, transferArgs);
   729 	}
   730 
   731 TInt TCompareSrcDst::Check(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const
   732 	{
   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;
   737 
   738 	const TUint8* src = srcOffset + aChunkBase;
   739 	const TUint8* dst = dstOffset + aChunkBase;
   740 
   741 	if(gVerboseOutput)
   742 		{
   743 		RDebug::Printf("Comparing TDmaTransferArgs buffers src=0x%08x dst=0x%08x size=0x%08x",
   744 				src, dst, size);
   745 		}
   746 
   747 	return memcompare(src, size, dst, size);
   748 	}
   749 
   750 TInt TCompareSrcDst::Check(const TIsrRequeArgsSet& aRequeueArgSet, TUint8* aChunkBase, const TDmaTransferArgs& aTferArgs) const
   751 	{
   752 	TIsrRequeArgsSet argSet(aRequeueArgSet); //copy since Fixup will mutate object
   753 
   754 	argSet.Substitute(aTferArgs); // replace any default (0) values with the values in aTferArgs
   755 
   756 	argSet.Fixup((TLinAddr)aChunkBase); //convert address offsets to virtual user mode addresses
   757 
   758 	TInt r = KErrCorrupt;
   759 	while(!argSet.IsEmpty())
   760 		{
   761 		r = Check(argSet.GetArgs());
   762 		if(r != KErrNone)
   763 			break;
   764 		}
   765 	return r;
   766 	}
   767 
   768 TInt TCompareSrcDst::Check(const TIsrRequeArgs& aRequeueArgs) const
   769 	{
   770 	const TUint8* src = (TUint8*)aRequeueArgs.iSrcAddr;
   771 	const TUint8* dst = (TUint8*)aRequeueArgs.iDstAddr;
   772 	const TInt size = aRequeueArgs.iTransferCount;
   773 
   774 	if(gVerboseOutput)
   775 		{
   776 		RDebug::Printf("Comparing TIsrRequeArgs: src=0x%08x dst=0x%08x size=0x%08x",
   777 				src, dst, size);
   778 		}
   779 
   780 	return memcompare(src, size, dst, size);
   781 	}
   782 
   783 TInt TCompareSrcDst::Check(CMultiTransferTest& aTest) const
   784 	{
   785 	if(gVerboseOutput)
   786 		{
   787 		RDebug::Printf("Comparing CMultiTransferTest buffers");
   788 		}
   789 
   790 	const TInt transferCount = aTest.TransferCount();
   791 	TUint8* const chunkBase = aTest.Chunk().Base();
   792 
   793 	// check buffers for each transfer
   794 	for(TInt i=0; i<transferCount; i++)
   795 		{
   796 		TInt r = Check(aTest.TransferArgs(i), chunkBase);
   797 		aTest.SetPostTransferResult(i, r);
   798 		}
   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
   803 	return KErrNone;
   804 	}
   805 
   806 TInt TCompare2D::Check(const CSingleTransferTest& aTest) const
   807 	{
   808 	const TDmaTransferArgs& args = aTest.TransferArgs();
   809 	TUint8* const chunkBase = aTest.Chunk().Base();
   810 
   811 	TInt ret = KErrNone;
   812 
   813 	TTransferIter src_iter(args.iSrcConfig, chunkBase);
   814 	TTransferIter dst_iter(args.iDstConfig, chunkBase);
   815 	TTransferIter end;
   816 	for (; (src_iter != end) && (dst_iter !=end); ++src_iter, ++dst_iter)
   817 		{
   818 		if(*src_iter != *dst_iter)
   819 			{
   820 			ret = KErrCorrupt;
   821 			break;
   822 			}
   823 		}
   824 	return ret;
   825 	}
   826 
   827 TInt TCompare2D::Check(const CIsrRequeTest&) const
   828 	{
   829 	return KErrNotSupported;
   830 	}
   831 
   832 TInt TCompare2D::Check(CMultiTransferTest&) const
   833 	{
   834 	return KErrNotSupported;
   835 	}
   836 //////////////////////////////////////////////////////////////////////
   837 // MPreTransfer classes
   838 //////////////////////////////////////////////////////////////////////
   839 
   840 void TPreTransferIncrBytes::Setup(const CSingleTransferTest& aTest) const
   841 	{
   842 	if(gVerboseOutput)
   843 		{
   844 		RDebug::Printf("TPreTransferIncrBytes(CSingleTransferTest)");
   845 		}
   846 	TAddressParms params = GetAddrParms(aTest.TransferArgs());
   847 
   848 	TUint8* const chunkBase = aTest.Chunk().Base();
   849 	params.Fixup((TLinAddr)chunkBase);
   850 
   851 
   852 	Setup(params);
   853 	}
   854 
   855 void TPreTransferIncrBytes::Setup(const TAddressParms& aParams) const
   856 	{
   857 	if(gVerboseOutput)
   858 		{
   859 		RDebug::Printf("TPreTransferIncrBytes: setup memory buffers: src=0x%08x dst=0x%08x size=0x%08x",
   860 				aParams.iSrcAddr, aParams.iDstAddr, aParams.iTransferCount);
   861 		}
   862 	TUint8* const src = (TUint8*) aParams.iSrcAddr;
   863 	const TInt size = aParams.iTransferCount;
   864 
   865 	for(TInt i=0; i<size; i++)
   866 		{src[i] = (TUint8)i;} //each src byte holds its own offset (mod 256)
   867 
   868 	TUint8* const dst = (TUint8*) aParams.iDstAddr;
   869 	memclr(dst, size); //clear destination
   870 	}
   871 
   872 void TPreTransferIncrBytes::Setup(const CIsrRequeTest& aTest) const
   873 	{
   874 	if(gVerboseOutput)
   875 		{
   876 		RDebug::Printf("TPreTransferIncrBytes(CIsrRequeTest)");
   877 		}
   878 	if(!CheckBuffers(aTest))
   879 		{
   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");
   882 		TEST_FAULT;
   883 		}
   884 
   885 	Setup(static_cast<CSingleTransferTest>(aTest)); // prepare the CSingleTransferTest parts
   886 
   887 	TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
   888 
   889 	requeSet.Substitute(aTest.TransferArgs());
   890 
   891 	const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
   892 	requeSet.Fixup(chunkBase);
   893 
   894 	while(!requeSet.IsEmpty())
   895 		{
   896 		TIsrRequeArgs args = requeSet.GetArgs();
   897 		Setup(args); // perform the setup operation for each TIsrRequeArgs
   898 		}
   899 	}
   900 
   901 void TPreTransferIncrBytes::Setup(const CMultiTransferTest& aTest) const
   902 	{
   903 	if(gVerboseOutput)
   904 		{
   905 		RDebug::Printf("TPreTransferIncrBytes(CMultiTransferTest)");
   906 		}
   907 	//TODO check for overlap
   908 
   909 	TUint8* const chunkBase = aTest.Chunk().Base();
   910 	const TInt transferCount = aTest.TransferCount();
   911 
   912 	// initialise buffers for each transfer
   913 	for(TInt i=0; i<transferCount; i++)
   914 		{
   915 		TAddressParms params = GetAddrParms(aTest.TransferArgs(i));
   916 
   917 		params.Fixup((TLinAddr)chunkBase);
   918 
   919 		Setup(params);
   920 		}
   921 	}
   922 
   923 TBool TPreTransferIncrBytes::CheckBuffers(const CIsrRequeTest& aTest) const
   924 	{
   925 	RArray<const TAddressParms> array;
   926 	array.AppendL(TAddressParms(aTest.TransferArgs()));
   927 
   928 	TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
   929 	requeSet.Substitute(aTest.TransferArgs());
   930 
   931 	const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
   932 	requeSet.Fixup(chunkBase);
   933 	while(!requeSet.IsEmpty())
   934 		{
   935 		const TIsrRequeArgs requeArgs = requeSet.GetArgs();
   936 		array.AppendL(requeArgs);
   937 		}
   938 
   939 	const TBool result = CheckBuffers(array);
   940 
   941 	array.Close();
   942 	return result;
   943 	}
   944 
   945 /**
   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
   948 matches.
   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
   954 */
   955 TBool TPreTransferIncrBytes::CheckBuffers(const RArray<const TAddressParms> aTransferParams) const
   956 	{
   957 	const TInt count = aTransferParams.Count();
   958 
   959 	for(TInt i=1; i<count; i++)
   960 		{
   961 		const TAddressParms& current = aTransferParams[i];
   962 		for(TInt j=0; j<i; j++)
   963 			{
   964 			const TAddressParms& previous = aTransferParams[j];
   965 			const TBool ok = !previous.Overlaps(current.DestRange()) || current == previous;
   966 			if(!ok)
   967 				return EFalse;
   968 			}
   969 		}
   970 	return ETrue;
   971 	}
   972 //////////////////////////////////////////////////////////////////////
   973 // TTransferIter class
   974 //////////////////////////////////////////////////////////////////////
   975 
   976 void TTransferIter::operator++ ()
   977 	{
   978 	iPtr++; //the standard post increment
   979 	if(iElem < (iCfg->iElementsPerFrame-1))
   980 		{
   981 		iPtr += iCfg->iElementSkip;
   982 		iElem++;
   983 		iBytes++;
   984 		}
   985 	else
   986 		{
   987 		TEST_ASSERT(iElem == iCfg->iElementsPerFrame-1);
   988 		if(iFrame < iCfg->iFramesPerTransfer-1)
   989 			{
   990 			iPtr += iCfg->iFrameSkip;
   991 			iFrame++;
   992 			iBytes++;
   993 			iElem = 0;
   994 			}
   995 		else
   996 			{
   997 			//we have reached the end
   998 			TEST_ASSERT(iFrame == iCfg->iFramesPerTransfer-1);
   999 			iPtr = NULL;
  1000 			}
  1001 		}
  1002 
  1003 	Invariant();
  1004 	}
  1005 
  1006 void TTransferIter::Invariant() const
  1007 	{
  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))
  1013 			);
  1014 	test_Equal(iBytes, bytesTransfered);
  1015 	test.Close();
  1016 	}
  1017 
  1018 ///////////////////////////////////////////////////////////
  1019 // TTestCase
  1020 ///////////////////////////////////////////////////////////
  1021 TTestCase::TTestCase(CDmaTest* aTest,
  1022    TBool aConcurrent,
  1023    const TDmaCapability aCap1,
  1024    const TDmaCapability aCap2,
  1025    const TDmaCapability aCap3,
  1026    const TDmaCapability aCap4,
  1027    const TDmaCapability aCap5
  1028    )
  1029 :
  1030 	iTest(aTest), iConcurrentTest(aConcurrent)
  1031 	{
  1032 	iChannelCaps[0] = aCap1;
  1033 	iChannelCaps[1] = aCap2;
  1034 	iChannelCaps[2] = aCap3;
  1035 	iChannelCaps[3] = aCap4;
  1036 	iChannelCaps[4] = aCap5;
  1037 	}
  1038 
  1039 TResult TTestCase::TestCaseValid(const SDmacCaps& aChannelCaps) const
  1040 	{
  1041 	const TDmaCapability* cap = &iChannelCaps[0];
  1042 
  1043 	TResult ret = ERun;
  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)
  1047 		{
  1048 		TResult t = cap->CompareToDmaCaps(aChannelCaps);
  1049 		if(t > ret) //this relies on the enum ordering
  1050 			ret = t;
  1051 		cap++;
  1052 		}
  1053 	return ret;
  1054 	}
  1055 
  1056 TResult TTestCase::TestCaseValid(const TDmacTestCaps& aChannelCaps) const
  1057 	{
  1058 	const TDmaCapability* cap = &iChannelCaps[0];
  1059 
  1060 	TResult ret = ERun;
  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)
  1064 		{
  1065 		TResult t = cap->CompareToDmaCaps(aChannelCaps);
  1066 		if(t > ret) //this relies on the enum ordering
  1067 			ret = t;
  1068 		cap++;
  1069 		}
  1070 	return ret;
  1071 	}
  1072 /**
  1073 Will report whether a value held in aChannelCaps satisfies a
  1074 requirement specfied by this object
  1075 */
  1076 TBool TDmaCapability::RequirementSatisfied(const SDmacCaps& aChannelCaps) const
  1077 	{
  1078 	switch(iCapsReq)
  1079 		{
  1080 	case ENone:
  1081 		return ETrue;
  1082 	case EChannelPriorities:
  1083 		TEST_FAULT;
  1084 	case EChannelPauseAndResume:
  1085 		return aChannelCaps.iChannelPauseAndResume == (TBool)iValue;
  1086 	case EAddrAlignedToElementSize:
  1087 		TEST_FAULT;
  1088 	case E1DAddressing:
  1089 		return aChannelCaps.i1DIndexAddressing == (TBool)iValue;
  1090 	case E2DAddressing:
  1091 		return aChannelCaps.i2DIndexAddressing == (TBool)iValue;
  1092 	case ESynchronizationTypes:
  1093 	case EBurstTransactions:
  1094 	case EDescriptorInterrupt:
  1095 	case EFrameInterrupt:
  1096 	case ELinkedListPausedInterrupt:
  1097 	case EEndiannessConversion:
  1098 	case EGraphicsOps:
  1099 	case ERepeatingTransfers:
  1100 	case EChannelLinking:
  1101 		TEST_FAULT;
  1102 	case EHwDescriptors:
  1103 		return aChannelCaps.iHwDescriptors == (TBool)iValue;
  1104 	case ESrcDstAsymmetry:
  1105 	case EAsymHwDescriptors:
  1106 		TEST_FAULT;
  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;
  1115 	default:
  1116 		TEST_FAULT;
  1117 		}
  1118 
  1119 	return EFalse;
  1120 	}
  1121 
  1122 /**
  1123 Will report whether a value held in aChannelCaps satisfies a
  1124 requirement specfied by this object
  1125 */
  1126 TBool TDmaCapability::RequirementSatisfied(const TDmacTestCaps& aChannelCaps) const
  1127 	{
  1128 	switch(iCapsReq)
  1129 		{
  1130 	case EPilVersion:
  1131 		return TestValue(aChannelCaps.iPILVersion);
  1132 	default:
  1133 		return RequirementSatisfied(static_cast<SDmacCaps>(aChannelCaps));
  1134 		}
  1135 	}
  1136 
  1137 TResult TDmaCapability::CompareToDmaCaps(const SDmacCaps& aChannelCaps) const
  1138 	{
  1139 	const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
  1140 	if(reqSatisfied)
  1141 		{
  1142 		return ERun;
  1143 		}
  1144 	else
  1145 		{
  1146 		return iFail ? EFail : ESkip;
  1147 		}
  1148 	}
  1149 
  1150 TResult TDmaCapability::CompareToDmaCaps(const TDmacTestCaps& aChannelCaps) const
  1151 	{
  1152 	const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
  1153 	if(reqSatisfied)
  1154 		{
  1155 		return ERun;
  1156 		}
  1157 	else
  1158 		{
  1159 		return iFail ? EFail : ESkip;
  1160 		}
  1161 	}
  1162 /**
  1163 Test that aValue satisfies the comparrison (iCapsReqType) with the
  1164 reference value held in iValue
  1165 */
  1166 TBool TDmaCapability::TestValue(TUint aValue) const
  1167 	{
  1168 	switch(iCapsReqType)
  1169 		{
  1170 	case EEqual:
  1171 		return aValue == iValue;
  1172 	case EGTE:
  1173 		return aValue >= iValue;
  1174 	case ELTE:
  1175 		return aValue <= iValue;
  1176 	case EBitsSet:
  1177 	case EBitsClear:
  1178 	default:
  1179 		TEST_FAULT;
  1180 		}
  1181 	return EFalse;
  1182 	}
  1183 
  1184 static RTest test(_L("DMAv2 test"));
  1185 
  1186 //////////////////////////////////////////////////////////////////////
  1187 // TTestRunner
  1188 //////////////////////////////////////////////////////////////////////
  1189 TTestRunner::TTestRunner()
  1190 	{
  1191 	// Open RDmaSession handle
  1192 	TInt r = iDmaSession.Open();
  1193 	TEST_ASSERT(r == KErrNone);
  1194 
  1195 	// Get PSI Test info
  1196 	r = iDmaSession.GetTestInfo(iPslTestInfo);
  1197 	TEST_ASSERT(r == KErrNone);
  1198 
  1199 	//Retrieve PSL cookies
  1200 	GetPslCookie();
  1201 
  1202 	//Generate the DMA channel records
  1203 	GenerateChannelRecord();
  1204 	}
  1205 
  1206 TTestRunner::~TTestRunner()
  1207 	{
  1208 	RTest::CloseHandleAndWaitForDestruction(iDmaSession);
  1209 	iTestCases.Close(); //TestRunner does not own test cases
  1210 	iChannelRecords.Close();
  1211 	iPslCookies.Close();
  1212 	}
  1213 
  1214 void TTestRunner::AddTestCases(RPointerArray<TTestCase>& aTTestCases)
  1215 	{
  1216 	const TInt count = aTTestCases.Count();
  1217 	for(TInt i=0; i < count; i++)
  1218 		{
  1219 		iTestCases.AppendL(aTTestCases[i]);
  1220 		}
  1221 	}
  1222 
  1223 void TTestRunner::RunTests()
  1224 	{
  1225 	//Print PslTestInfo
  1226 	if(gVerboseOutput)
  1227 		{
  1228 		Print(iPslTestInfo);
  1229 		}
  1230 
  1231 	//iterate through the test case array
  1232 	const TInt testCaseCount = iTestCases.Count();
  1233 	for(TInt i=0; i < testCaseCount; i++)
  1234 		{
  1235 		const TTestCase& testCase = *iTestCases[i];
  1236 
  1237 		//Here, we must create a test thread for each channel
  1238 		RPointerArray<CTest> concurrentTests;
  1239 
  1240 		if(testCase.iConcurrentTest)
  1241 			RDebug::Printf("== Begin concurrent test run ==");
  1242 
  1243 		const TInt chanRecCount = iChannelRecords.Count();
  1244 		for(TInt j=0; j < chanRecCount; j++)
  1245 			{
  1246 			const TChannelRecord& record = iChannelRecords[j];
  1247 			const TDmacTestCaps& caps = record.iChannelCaps;
  1248 
  1249 			const TResult t = testCase.TestCaseValid(caps);
  1250 
  1251 			switch(t)
  1252 				{
  1253 			case ERun:
  1254 				{
  1255 				CDmaTest* dmaTest = static_cast<CDmaTest*>(testCase.iTest->Clone());
  1256 				TEST_ASSERT(dmaTest != NULL);
  1257 
  1258 				dmaTest->SetChannelCookie(record.iCookie);
  1259 				dmaTest->Announce();
  1260 				if(testCase.iConcurrentTest)
  1261 					{
  1262 					//Add test to array to be run concurrently
  1263 					TInt r = concurrentTests.Append(dmaTest);
  1264 					TEST_ASSERT(r == KErrNone);
  1265 					}
  1266 				else
  1267 					{
  1268 					//Run test in this thread
  1269 					(*dmaTest)();
  1270 					//TTestThread(
  1271 					TBool result = dmaTest->Result();
  1272 					TEST_ASSERT(result);
  1273 
  1274 					delete dmaTest;
  1275 					}
  1276 
  1277 				break;
  1278 				}
  1279 			case ESkip:
  1280 				if(gVerboseOutput)
  1281 				{
  1282 				RDebug::Printf("Skipping test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
  1283 				}
  1284 				break;
  1285 			case EFail:
  1286 				if(gVerboseOutput)
  1287 				{
  1288 				RDebug::Printf("Failling test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
  1289 				}
  1290 				TEST_FAULT;
  1291 			default:
  1292 				TEST_FAULT;
  1293 				}
  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:
  1296 
  1297 			//if the test case has been run on all channels it will then  wait for all threads to complete.
  1298 			}
  1299 
  1300 		const TInt count = concurrentTests.Count();
  1301 		if(count>0)
  1302 			{
  1303 			MultipleTestRun(concurrentTests);
  1304 			for(TInt i=0; i<count; i++)
  1305 				{
  1306 				TBool result = static_cast<CDmaTest*>(concurrentTests[i])->Result();
  1307 				TEST_ASSERT(result);
  1308 				}
  1309 			RDebug::Printf("== End concurrent test run ==");
  1310 			}
  1311 
  1312 		concurrentTests.ResetAndDestroy();
  1313 		}
  1314 	}
  1315 
  1316 void TTestRunner::GetPslCookie()
  1317 	{
  1318 	//Get Sb Channel cookies
  1319 	for(TInt sb_channelcount=0; sb_channelcount<iPslTestInfo.iMaxSbChannels; sb_channelcount++)
  1320 		{
  1321 		iPslCookies.AppendL(iPslTestInfo.iSbChannels[sb_channelcount]);
  1322 		}
  1323 
  1324 	//Get Db Channel cookies
  1325 	for(TInt db_channelcount=0; db_channelcount<iPslTestInfo.iMaxDbChannels; db_channelcount++)
  1326 		{
  1327 		iPslCookies.AppendL(iPslTestInfo.iDbChannels[db_channelcount]);
  1328 		}
  1329 
  1330 	//Get Sg Channel cookies
  1331 	for(TInt sg_channelcount=0; sg_channelcount<iPslTestInfo.iMaxSgChannels; sg_channelcount++)
  1332 		{
  1333 		iPslCookies.AppendL(iPslTestInfo.iSgChannels[sg_channelcount]);
  1334 		}
  1335 	}
  1336 
  1337 void TTestRunner::GenerateChannelRecord()
  1338 	{
  1339 	//for each PSL cookie
  1340 	for(TInt count=0; count<iPslCookies.Count(); count++)
  1341 		{
  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);
  1347 		if(gVerboseOutput)
  1348 		{
  1349 		RDebug::Printf("Channel PSL Cookie[%d]  :0x%08x",count,pslCookie);
  1350 		}
  1351 
  1352 		TChannelRecord dmaChannelRecord;
  1353 		dmaChannelRecord.iCookie = pslCookie;
  1354 
  1355 		//Get Channel Caps
  1356 		r = iDmaSession.ChannelCaps(sessionCookie, dmaChannelRecord.iChannelCaps);
  1357 		TEST_ASSERT(r == KErrNone);
  1358 
  1359 		r = iDmaSession.ChannelClose(sessionCookie);
  1360 		TEST_ASSERT(r == KErrNone);
  1361 
  1362 		//Append array
  1363 		iChannelRecords.AppendL(dmaChannelRecord);
  1364 		}
  1365 	}
  1366 //////////////////////////////////////////////////////////////////////
  1367 // Global test functions and E32Main
  1368 //////////////////////////////////////////////////////////////////////
  1369 
  1370 /**
  1371 Displayed if used supplied no parameters, garbage, or a ? in the parameters
  1372 */
  1373 void PrintUsage()
  1374 	{
  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"));
  1380 	}
  1381 
  1382 void ProcessCommandLineL()
  1383 {
  1384 	test.Printf(_L("Process command line arguments\n"));
  1385 
  1386 	TInt cmdLineLength(User::CommandLineLength());
  1387 	HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength);
  1388 	TPtr cmdLinePtr = cmdLine->Des();
  1389 	User::CommandLine(cmdLinePtr);
  1390 	TBool  tokenParsed(EFalse);
  1391 
  1392 	TLex args(*cmdLine);
  1393 	args.SkipSpace(); // args are separated by spaces
  1394 	
  1395 	// first arg is the exe name, skip it
  1396 	TPtrC cmdToken = args.NextToken();
  1397 	HBufC* tc = HBufC::NewLC(KParameterTextLenMax);
  1398 	*tc = cmdToken;
  1399 	while (tc->Length())
  1400 		{
  1401 		tokenParsed = EFalse;
  1402 		
  1403 		// '/?' help wanted flag '?' or /? parameter
  1404 		if ((0== tc->FindF(_L("?"))) || (0==tc->FindF(_L("/?")))) 
  1405 			{
  1406 			gHelpRequested = ETrue;
  1407 			tokenParsed = ETrue;
  1408 			}	
  1409 		
  1410 		// '/SELFTEST'			
  1411 		if ((0== tc->FindF(KArgSelfTest)) || (0==tc->FindF(KArgSelfTest2))) 
  1412 			{
  1413 			// Run self test
  1414 			test.Printf(_L("Command Line Options:Selftest option specified.\n"));
  1415 			gSelfTest = ETrue;
  1416 			tokenParsed = ETrue;
  1417 			}
  1418 
  1419 		// '/VERBOSE' option	
  1420 		if ((0== tc->FindF(KArgVerboseOutput)) || (0==tc->FindF(KArgVerboseOutput2)))
  1421 			{ 
  1422 			test.Printf(_L("Command Line Options:Verbose option specified.\n"));
  1423 			gVerboseOutput = ETrue;
  1424 			tokenParsed = ETrue;			
  1425 			}
  1426 
  1427 		if (!tokenParsed)
  1428 			{
  1429 			// warn about unparsed parameter
  1430 			test.Printf(_L("Warning: '%lS'??? not parsed\n"), tc);
  1431 			gHelpRequested = ETrue;
  1432 			}
  1433 			
  1434 		// next parameter
  1435 		*tc = args.NextToken();
  1436 		}
  1437 	CleanupStack::PopAndDestroy(tc);
  1438 	CleanupStack::PopAndDestroy(cmdLine);
  1439 }
  1440 
  1441 void RunDMATests()
  1442 	{
  1443 	test.Start(_L("Creating test runner\n"));
  1444 	TTestRunner testRunner;
  1445 
  1446 	test.Next(_L("Add global test cases to test runner\n"));
  1447 	testRunner.AddTestCases(TestArray);
  1448 
  1449 	test.Next(_L("call TTestRunner::RunTests()\n"));
  1450 	testRunner.RunTests();
  1451 
  1452 	test.End();
  1453 	}
  1454 
  1455 TInt E32Main()
  1456 	{
  1457 	__UHEAP_MARK;
  1458 	//__KHEAP_MARK;
  1459 	test.Title();
  1460 
  1461 	gHelpRequested = EFalse;
  1462 	TInt r;
  1463 
  1464 	// Create the new trap-cleanup mechanism
  1465 	CTrapCleanup* cleanup = CTrapCleanup::New();
  1466 
  1467 	if (cleanup == NULL)
  1468 		{
  1469 		return KErrNoMemory;
  1470 		}
  1471 
  1472 	// Process the command line parameters for batch/etc
  1473 	TRAPD(err, ProcessCommandLineL());
  1474 	if (err != KErrNone)
  1475 		{
  1476 		User::Panic(_L("DMA test run memory failure"), KErrNoMemory);
  1477 		}
  1478 	
  1479 	if (gHelpRequested)
  1480 		{
  1481 		PrintUsage();
  1482 		User::Leave(-2);	// nothing to do!
  1483 		}
  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));
  1491 
  1492 	_LIT(KDma2Compat, "D_DMA2_COMPAT.LDD");
  1493 	r = User::LoadLogicalDevice(KDma2Compat);
  1494 	const TBool dma2CompatLoaded = ((r == KErrNone) || (r == KErrAlreadyExists));
  1495 
  1496 	if (!(dma2Loaded || dma2CompatLoaded))
  1497 		{
  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
  1500 		//missing?
  1501 		test.Printf(_L("DMA not supported - test skipped\n"));
  1502 		return 0;
  1503 		}
  1504 	else if (dma2Loaded && !dma2CompatLoaded)
  1505 		{
  1506 		test.Printf(_L("Loaded %S\n"), &KDma);
  1507 		}
  1508 	else if (!dma2Loaded && dma2CompatLoaded)
  1509 		{
  1510 		test.Printf(_L("Loaded %S\n"), &KDma2Compat);
  1511 		}
  1512 	else
  1513 		{
  1514 		test.Printf(_L("The ROM contains %S and %S - only one should be present\n"), &KDma, &KDma2Compat);
  1515 		TEST_FAULT;
  1516 		}
  1517 	// Turn off evil lazy dll unloading
  1518 	RLoader l;
  1519 	test(l.Connect()==KErrNone);
  1520 	test(l.CancelLazyDllUnload()==KErrNone);
  1521 	RTest::CloseHandleAndWaitForDestruction(l);
  1522 
  1523 	__KHEAP_MARK;
  1524 
  1525 	if (gSelfTest) //Run self tests if specified on command line
  1526 	{
  1527 	SelfTests(); 	
  1528 	}
  1529 
  1530 	ApiTests();
  1531 
  1532 	RunDMATests();
  1533 
  1534 	__KHEAP_MARKEND;
  1535 
  1536 	r = User::FreeLogicalDevice(KTestDmaLddName);
  1537 	test_KErrNone(r);
  1538 	test.End();
  1539 	test.Close();
  1540 
  1541 	delete cleanup;
  1542 
  1543 	//__KHEAP_MARKEND;
  1544 	__UHEAP_MARKEND;
  1545 	return 0;
  1546 	}