kerneltest/e32test/dma/t_dma.cpp
changeset 90 947f0dc9f7a8
parent 36 538db54a451d
child 102 ef2a444a7410
child 119 6e99f362aa46
equal deleted inserted replaced
52:2d65c2f76d7b 90:947f0dc9f7a8
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    67 
    67 
    68 // Test macro used inside tester threads
    68 // Test macro used inside tester threads
    69 _LIT(KTestFailure, "XTEST");
    69 _LIT(KTestFailure, "XTEST");
    70 static void TestPanic(TInt aLine, TUint32 a1, TUint32 a2, TUint32 a3)
    70 static void TestPanic(TInt aLine, TUint32 a1, TUint32 a2, TUint32 a3)
    71 	{
    71 	{
    72 	RDebug::Printf("Line %d test failed a1=%08x a2=%08x a3=%08x", aLine, a1, a2, a3);
    72 	RDebug::Printf("Line %d test failed a1=%08x (%d) a2=%08x (%d) a3=%08x (%d)", aLine, a1, a1, a2, a2, a3, a3);
    73 	RThread().Panic(KTestFailure, aLine);
    73 	RThread().Panic(KTestFailure, aLine);
    74 	}
    74 	}
    75 #define XTEST(e)				if (!(e)) TestPanic(__LINE__, 0, 0, 0)
    75 #define XTEST(e)				if (!(e)) TestPanic(__LINE__, 0, 0, 0)
    76 #define XTEST1(e,a1)			if (!(e)) TestPanic(__LINE__, (a1), 0, 0)
    76 #define XTEST1(e,a1)			if (!(e)) TestPanic(__LINE__, (a1), 0, 0)
    77 #define XTEST2(e,a1,a2)			if (!(e)) TestPanic(__LINE__, (a1), (a2), 0)
    77 #define XTEST2(e,a1,a2)			if (!(e)) TestPanic(__LINE__, (a1), (a2), 0)
   191 		{return new CDefaultFragTest(*this);}
   191 		{return new CDefaultFragTest(*this);}
   192 
   192 
   193 	const TInt iTotalTransferSize;
   193 	const TInt iTotalTransferSize;
   194 	};
   194 	};
   195 
   195 
       
   196 /**
       
   197 Test that it is possible to close a channel from a callback
       
   198 */
       
   199 class CCloseInCb : public CTest
       
   200 	{
       
   201 public:
       
   202 	CCloseInCb()
       
   203 		: CTest(NULL, 1), iTransferSize(4 * KKilo)
       
   204 		{}
       
   205 
       
   206 	TInt virtual DoRunTest();
       
   207 
       
   208 	virtual void AnnounceTest(TDes& aDes)
       
   209 		{
       
   210 		aDes.AppendFormat(_L("CCloseInCb"));
       
   211 		CTest::AnnounceTest(aDes);
       
   212 		}
       
   213 
       
   214 	CTest* Clone() const
       
   215 		{return new CCloseInCb(*this);}
       
   216 private:
       
   217 	const TInt iTransferSize;
       
   218 
       
   219 	};
       
   220 
       
   221 /**
       
   222 Perform multiple transfers with different fragment counts and with smaller
       
   223 and smaller fragment size
       
   224 
       
   225 This checks that the PSL's ISR(s) are properly written, and do not miss interrupts
       
   226 or notify the PIL spuriously.
       
   227 */
       
   228 class CFragSizeRange : public CTest
       
   229 	{
       
   230 public:
       
   231 	CFragSizeRange(TInt aMaxIter, TInt aFragCount, TInt aInitialFragmentSize, TInt aInnerIteraions)
       
   232 		: CTest(NULL, aMaxIter), iMaxFragCount(aFragCount), iFragCount(1), iInitialFragmentSize(aInitialFragmentSize),
       
   233 		iInnerIterations(aInnerIteraions)
       
   234 		{}
       
   235 
       
   236 	TInt virtual DoRunTest();
       
   237 
       
   238 	virtual void AnnounceTest(TDes& aDes)
       
   239 		{
       
   240 		aDes.AppendFormat(_L("CFragSizeRange: Fragments %d, intital frag size %d, inner iters %d "), iFragCount, iInitialFragmentSize, iInnerIterations);
       
   241 		CTest::AnnounceTest(aDes);
       
   242 		}
       
   243 
       
   244 	CTest* Clone() const
       
   245 		{return new CFragSizeRange(*this);}
       
   246 
       
   247 private:
       
   248 	/**
       
   249 	Run the transfer
       
   250 	*/
       
   251 	TInt Transfer(TInt aFragSize);
       
   252 
       
   253 
       
   254 	TInt iMaxFragCount;
       
   255 	TInt iFragCount;
       
   256 	const TInt iInitialFragmentSize;
       
   257 	const TInt iInnerIterations;
       
   258 
       
   259 	RTimer iTimer;
       
   260 	};
   196 
   261 
   197 //
   262 //
   198 // Active object used to create a tester thread, log on to it and
   263 // Active object used to create a tester thread, log on to it and
   199 // interpret its exit status.
   264 // interpret its exit status.
   200 //
   265 //
   344 	
   409 	
   345 	iChannel.Close();
   410 	iChannel.Close();
   346 	return KErrNone;
   411 	return KErrNone;
   347 	}
   412 	}
   348 
   413 
       
   414 TInt CCloseInCb::DoRunTest()
       
   415 	{
       
   416 	TInt r = KErrNone;
       
   417 	RTest test(_L("CCloseInCb test"));
       
   418 
       
   419 	r = OpenChannel(1);
       
   420 	test_KErrNone(r);
       
   421 
       
   422 	const TInt KRequest = 0;
       
   423 	const TInt KSrcBuf = 0;
       
   424 	const TInt KDestBuf = 1;
       
   425 
       
   426 	const TInt size = Min(iTransferSize, Info.iMaxTransferSize);
       
   427 
       
   428 	r = iChannel.AllocBuffer(KSrcBuf, size);
       
   429 	test_KErrNone(r);
       
   430 	iChannel.FillBuffer(KSrcBuf, 'A');
       
   431 	r = iChannel.AllocBuffer(KDestBuf, size);
       
   432 	test_KErrNone(r);
       
   433 	iChannel.FillBuffer(KDestBuf, '\0');
       
   434 
       
   435 	TRequestStatus rs = KRequestPending;
       
   436 	r = iChannel.Fragment(KRequest, KSrcBuf, KDestBuf, size, &rs);
       
   437 	test_KErrNone(r);
       
   438 
       
   439 	// "X" will cause channel to be closed during callback
       
   440 	r = iChannel.Execute(_L8("QX0"));
       
   441 	test_KErrNone(r);
       
   442 
       
   443 	User::WaitForRequest(rs);
       
   444 	test_KErrNone(rs.Int());
       
   445 
       
   446 	test(iChannel.CheckBuffer(KDestBuf, 'A'));
       
   447 	iChannel.FreeAllBuffers();
       
   448 
       
   449 	test.Close();
       
   450 	return KErrNone;
       
   451 	}
       
   452 
       
   453 TInt CFragSizeRange::DoRunTest()
       
   454 	{
       
   455 	const TInt initialFragmentSize = Min(iInitialFragmentSize, Info.iMaxTransferSize);
       
   456 
       
   457 	TInt r = KErrNone;
       
   458 	RTest test(_L("CFragSizeRange test"));
       
   459 
       
   460 	r = iTimer.CreateLocal();
       
   461 	test_KErrNone(r);
       
   462 
       
   463 
       
   464 	TInt fragSize = initialFragmentSize;
       
   465 	TInt step = 0;
       
   466 	do
       
   467 		{
       
   468 		fragSize -= step;
       
   469 		// make sure size is aligned
       
   470 		fragSize = fragSize & ~Info.iMemAlignMask;
       
   471 
       
   472 		r = OpenChannel(iMaxFragCount, fragSize);
       
   473 		test_KErrNone(r);
       
   474 
       
   475 		for(iFragCount=1; iFragCount <= iMaxFragCount; iFragCount++)
       
   476 			{
       
   477 			test.Printf(_L("Fragment size %d bytes, %d fragments\nIter: "), fragSize, iFragCount);
       
   478 			for(TInt i=0; i<iInnerIterations; i++)
       
   479 				{
       
   480 
       
   481 				test.Printf(_L("%d "), i);
       
   482 				r = Transfer(fragSize);
       
   483 				test_KErrNone(r);
       
   484 
       
   485 				}
       
   486 			test.Printf(_L("\n"));
       
   487 			}
       
   488 		iChannel.Close();
       
   489 		// Reduce frag size by an eigth each iteration
       
   490 		step = (fragSize/8);
       
   491 		} while (step > 0);
       
   492 
       
   493 	iTimer.Close();
       
   494 
       
   495 	test.Close();
       
   496 	return r;
       
   497 	}
       
   498 
       
   499 TInt CFragSizeRange::Transfer(TInt aFragmentSize)
       
   500 	{
       
   501 	const TInt KRequest = 0;
       
   502 	const TInt KSrcBuf = 0;
       
   503 	const TInt KDestBuf = 1;
       
   504 
       
   505 	const TInt size = aFragmentSize * iFragCount;
       
   506 
       
   507 	TInt r = iChannel.AllocBuffer(KSrcBuf, size);
       
   508 	test_KErrNone(r);
       
   509 	iChannel.FillBuffer(KSrcBuf, 'A');
       
   510 	r = iChannel.AllocBuffer(KDestBuf, size);
       
   511 	XTEST2(r == KErrNone, r, size);
       
   512 	iChannel.FillBuffer(KDestBuf, '\0');
       
   513 
       
   514 	// Test simple transfer
       
   515 	TRequestStatus rs = KRequestPending;
       
   516 	r = iChannel.Fragment(KRequest, KSrcBuf, KDestBuf, size, &rs);
       
   517 	test_KErrNone(r);
       
   518 
       
   519 	test(iChannel.FragmentCheck(KRequest, iFragCount));
       
   520 	r = iChannel.Execute(_L8("Q0"));
       
   521 	test_KErrNone(r);
       
   522 
       
   523 	const TInt microSecTimeout = 1000000; // 1s
       
   524 	TRequestStatus timerStatus;
       
   525 	iTimer.After(timerStatus, microSecTimeout);
       
   526 
       
   527 	User::WaitForRequest(rs, timerStatus);
       
   528 	if(rs.Int() == KRequestPending)
       
   529 		{
       
   530 		RDebug::Print(_L("Transfer timed out!"));
       
   531 		// timed out
       
   532 		test(EFalse);
       
   533 		}
       
   534 	iTimer.Cancel();
       
   535 	test_KErrNone(rs.Int());
       
   536 	test(iChannel.CheckBuffer(KDestBuf, 'A'));
       
   537 
       
   538 	// Queue, then cancel request - Checks
       
   539 	// that there there is no spurious callback
       
   540 	// to the PIL
       
   541 	r = iChannel.Execute(_L8("Q0C"));
       
   542 	test_KErrNone(r);
       
   543 
       
   544 	iChannel.FreeAllBuffers();
       
   545 	return KErrNone;
       
   546 	}
       
   547 
   349 
   548 
   350 // Called when thread completed.
   549 // Called when thread completed.
   351 void CTesterThread::RunL()
   550 void CTesterThread::RunL()
   352 	{
   551 	{
   353 	TExitType et = iThread.ExitType();
   552 	TExitType et = iThread.ExitType();
   412 	{
   611 	{
   413 	test_NotNull(aTest);
   612 	test_NotNull(aTest);
   414 
   613 
   415 	if (aMaxThread == 0)
   614 	if (aMaxThread == 0)
   416 		{
   615 		{
   417 		delete aTest;
       
   418 		test.Printf(_L("transfer mode not supported - skipped\n"));
   616 		test.Printf(_L("transfer mode not supported - skipped\n"));
   419 		return;
   617 		return;
   420 		}
   618 		}
   421 
   619 
   422 	test.Printf(_L("Using %d thread(s)\n"), aMaxThread);
   620 	test.Printf(_L("Using %d thread(s)\n"), aMaxThread);
   442 		test.Printf(_L("Thread %d: %S\n"), i, &buffer);
   640 		test.Printf(_L("Thread %d: %S\n"), i, &buffer);
   443 		
   641 		
   444 		test(new CTesterThread(i, dmaTest) != NULL);
   642 		test(new CTesterThread(i, dmaTest) != NULL);
   445 		dmaTest = NULL; //ownership transferred to CTesterThread
   643 		dmaTest = NULL; //ownership transferred to CTesterThread
   446 		}
   644 		}
       
   645 
       
   646 	const TTimeIntervalMicroSeconds32 KPeriod = 1000000;	// 1s
       
   647 	Bipper->Start(KPeriod, KPeriod, Bip);
       
   648 
       
   649 	CActiveScheduler::Start();
       
   650 
       
   651 	User::SetJustInTime(JitEnabled);
       
   652 	}
       
   653 
       
   654 
       
   655 inline void RunSbTest(TInt aMaxThread, CTest* aTest)
       
   656 	{
       
   657 	RunTest(Info.iSbChannels, Min(1,Info.iMaxSbChannels), aTest);
       
   658 	RunTest(Info.iSbChannels, Min(aMaxThread,Info.iMaxSbChannels), aTest);
       
   659 
   447 	//the orginal isn't needed
   660 	//the orginal isn't needed
   448 	delete aTest;
   661 	delete aTest;
   449 	aTest = NULL;
       
   450 
       
   451 	const TTimeIntervalMicroSeconds32 KPeriod = 1000000;	// 1s
       
   452 	Bipper->Start(KPeriod, KPeriod, Bip);
       
   453 
       
   454 	CActiveScheduler::Start();
       
   455 
       
   456 	User::SetJustInTime(JitEnabled);
       
   457 	}
       
   458 
       
   459 
       
   460 inline void RunSbTest(TInt aMaxThread, CTest* aTest)
       
   461 	{
       
   462 	RunTest(Info.iSbChannels, Min(aMaxThread,Info.iMaxSbChannels), aTest);
       
   463 	}
   662 	}
   464 
   663 
   465 inline void RunDbTest(TInt aMaxThread, CTest* aTest)
   664 inline void RunDbTest(TInt aMaxThread, CTest* aTest)
   466 	{
   665 	{
       
   666 	RunTest(Info.iDbChannels, Min(1,Info.iMaxDbChannels), aTest);
   467 	RunTest(Info.iDbChannels, Min(aMaxThread,Info.iMaxDbChannels), aTest);
   667 	RunTest(Info.iDbChannels, Min(aMaxThread,Info.iMaxDbChannels), aTest);
       
   668 
       
   669 	//the orginal isn't needed
       
   670 	delete aTest;
   468 	}
   671 	}
   469 
   672 
   470 inline void RunSgTest(TInt aMaxThread, CTest* aTest)
   673 inline void RunSgTest(TInt aMaxThread, CTest* aTest)
   471 	{
   674 	{
       
   675 	RunTest(Info.iSgChannels, Min(1,Info.iMaxSgChannels), aTest);
   472 	RunTest(Info.iSgChannels, Min(aMaxThread,Info.iMaxSgChannels), aTest);
   676 	RunTest(Info.iSgChannels, Min(aMaxThread,Info.iMaxSgChannels), aTest);
       
   677 
       
   678 	//the orginal isn't needed
       
   679 	delete aTest;
   473 	}
   680 	}
   474 //////////////////////////////////////////////////////////////////////////////
   681 //////////////////////////////////////////////////////////////////////////////
   475 
   682 
   476 static void GetChannelInfo()
   683 static void GetChannelInfo()
   477 	{
   684 	{
   962 	test(Bipper != NULL);
  1169 	test(Bipper != NULL);
   963 
  1170 
   964 	test.Next(_L("Getting channel info"));
  1171 	test.Next(_L("Getting channel info"));
   965 	GetChannelInfo();
  1172 	GetChannelInfo();
   966 
  1173 
       
  1174 	test.Next(_L("Test that channel can be closed from callback"));
       
  1175 	test.Next(_L("sb"));
       
  1176 	RunSbTest(maxchannel, new CCloseInCb() );
       
  1177 	test.Next(_L("db"));
       
  1178 	RunDbTest(maxchannel, new CCloseInCb() );
       
  1179 	test.Next(_L("sg"));
       
  1180 	RunSgTest(maxchannel, new CCloseInCb() );
       
  1181 
       
  1182 	test.Next(_L("Testing different fragment sizes"));
       
  1183 
       
  1184 	const TInt rangeFragSize = 4096;
       
  1185 #ifdef __DMASIM__
       
  1186 	// Use fewer iterations on the emulator
       
  1187 	// since it is slower. Also this test is really
       
  1188 	// intended to find errors in PSL implmentations
       
  1189 	const TInt iterPerFragSize = 1;
       
  1190 #else
       
  1191 	const TInt iterPerFragSize = 30;
       
  1192 #endif
       
  1193 	const TInt rangeMaxFragCount = 8;
       
  1194 
       
  1195 	test.Next(_L("sb"));
       
  1196 	RunSbTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
       
  1197 	test.Next(_L("db"));
       
  1198 	RunDbTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
       
  1199 	test.Next(_L("sg"));
       
  1200 	RunSgTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
       
  1201 
       
  1202 
   967 	// Size for the single transfer test
  1203 	// Size for the single transfer test
   968 	TInt totalTransferSize = 64 * KKilo;
  1204 	TInt totalTransferSize = 64 * KKilo;
   969 
  1205 
   970 	test.Next(_L("Testing one shot single buffer transfer"));
  1206 	test.Next(_L("Testing one shot single buffer transfer"));
   971 	RunSbTest(maxchannel, new CFragmentationTest(TestOneShot, maxIter, maxfrag, maxFragSize));
  1207 	RunSbTest(maxchannel, new CFragmentationTest(TestOneShot, maxIter, maxfrag, maxFragSize));