kerneltest/e32test/dmav2/t_dma2.cpp
changeset 45 329ab0095843
child 130 c30940f6d922
equal deleted inserted replaced
44:36bfc973b146 45:329ab0095843
       
     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 	}