os/kernelhwsrv/kerneltest/e32test/dmav2/t_dma2.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/dmav2/t_dma2.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1546 @@
     1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test\dma\t_dma.cpp
    1.18 +
    1.19 +#include "d_dma2.h"
    1.20 +#include "u32std.h"
    1.21 +#include "t_dma2.h"
    1.22 +#include "cap_reqs.h"
    1.23 +
    1.24 +#define __E32TEST_EXTENSION__
    1.25 +#include <e32test.h>
    1.26 +#include <e32debug.h>
    1.27 +#include <e32svr.h>
    1.28 +#include <e32def_private.h>
    1.29 +
    1.30 +// DMA test framework command  parameter options
    1.31 +
    1.32 +// SelfTest Option
    1.33 +_LIT(KArgSelfTest, "/SELFTEST");  
    1.34 +_LIT(KArgSelfTest2, "/S");		  
    1.35 +
    1.36 +//Verbose Option
    1.37 +_LIT(KArgVerboseOutput, "/VERBOSE"); 
    1.38 +_LIT(KArgVerboseOutput2, "/V");	     
    1.39 +  
    1.40 +
    1.41 +TBool gHelpRequested;   // print usage 
    1.42 +TBool gVerboseOutput;   // enable verbose output 
    1.43 +TBool gSelfTest;        // run SelfTest 
    1.44 +
    1.45 +/**
    1.46 +This function prints out the PSL test Information
    1.47 +*/
    1.48 +void Print(const TDmaV2TestInfo& aInfo)
    1.49 +	{
    1.50 +	PRINT(aInfo.iMaxTransferSize);
    1.51 +	PRINT(aInfo.iMemAlignMask);
    1.52 +	PRINT(aInfo.iMemMemPslInfo);
    1.53 +	PRINT(aInfo.iMaxSbChannels);
    1.54 +	for(TInt i=0; i<aInfo.iMaxSbChannels; i++)
    1.55 +		{
    1.56 +		PRINT(aInfo.iSbChannels[i]);
    1.57 +		}
    1.58 +	PRINT(aInfo.iMaxDbChannels);
    1.59 +	for(TInt j=0; j<aInfo.iMaxDbChannels; j++)
    1.60 +		{
    1.61 +		PRINT(aInfo.iDbChannels[j]);
    1.62 +		}
    1.63 +	PRINT(aInfo.iMaxSgChannels);
    1.64 +	for(TInt k=0; k<aInfo.iMaxSgChannels; k++)
    1.65 +		{
    1.66 +		PRINT(aInfo.iSgChannels[k]);
    1.67 +		}
    1.68 +	}
    1.69 +
    1.70 +void CDmaTest::PrintTestInfo() const
    1.71 +	{
    1.72 +	TBuf<32> buf;
    1.73 +	buf.AppendFormat(_L("DMA channel %d"), iChannelCookie);
    1.74 +	RDebug::RawPrint(buf);
    1.75 +	}
    1.76 +
    1.77 +//////////////////////////////////////////////////////////////////////
    1.78 +// CDmaTest
    1.79 +//////////////////////////////////////////////////////////////////////
    1.80 +
    1.81 +void CDmaTest::OpenDmaSession()
    1.82 +	{
    1.83 +	TInt r = iDmaSession.Open();
    1.84 +	TEST_ASSERT(r == KErrNone);
    1.85 +	r = iDmaSession.OpenSharedChunk(iChunk);
    1.86 +	TEST_ASSERT(r == KErrNone);
    1.87 +	}
    1.88 +
    1.89 +void CDmaTest::CloseDmaSession()
    1.90 +	{
    1.91 +	iChunk.Close();
    1.92 +	iDmaSession.Close();
    1.93 +	}
    1.94 +
    1.95 +//////////////////////////////////////////////////////////////////////
    1.96 +// CSingleTransferTest
    1.97 +//////////////////////////////////////////////////////////////////////
    1.98 +void CSingleTransferTest::RunTest()
    1.99 +	{
   1.100 +	OpenDmaSession();
   1.101 +	PreTransferSetup();
   1.102 +
   1.103 +	OpenChannel();
   1.104 +	CreateDmaRequest();
   1.105 +	Fragment();
   1.106 +	Queue();
   1.107 +	FreeRequest();
   1.108 +	CloseChannel();
   1.109 +	PostTransferCheck();
   1.110 +
   1.111 +	CloseDmaSession();
   1.112 +	}
   1.113 +
   1.114 +void CSingleTransferTest::OpenChannel()
   1.115 +	{
   1.116 +	iActual.iChannelOpenResult =
   1.117 +		iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
   1.118 +	}
   1.119 +
   1.120 +void CSingleTransferTest::CreateDmaRequest()
   1.121 +	{
   1.122 +	if(iUseNewRequest)
   1.123 +	{
   1.124 +		if(gVerboseOutput)
   1.125 +			{
   1.126 +			RDebug::Printf("Calling New Request API\n");
   1.127 +			}
   1.128 +		iActual.iRequestResult.iCreate =
   1.129 +			iDmaSession.RequestCreateNew(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
   1.130 +		}
   1.131 +	else
   1.132 +		{
   1.133 +		if(gVerboseOutput)
   1.134 +			{
   1.135 +			RDebug::Printf("Calling Old Request API\n");
   1.136 +			}
   1.137 +		iActual.iRequestResult.iCreate =
   1.138 +			iDmaSession.RequestCreate(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
   1.139 +		}
   1.140 +	}
   1.141 +
   1.142 +void CSingleTransferTest::Fragment()
   1.143 +	{
   1.144 +	if(iActual.iRequestResult.iCreate != KErrNone)
   1.145 +		return;
   1.146 +
   1.147 +	if(iUseNewFragment)
   1.148 +		{
   1.149 +		if(gVerboseOutput)
   1.150 +			{
   1.151 +			RDebug::Printf("Calling New Fragment API\n");
   1.152 +			}
   1.153 +		iActual.iRequestResult.iFragmentationResult =
   1.154 +			iDmaSession.FragmentRequest(iRequestSessionCookie, iTransferArgs);
   1.155 +		}
   1.156 +	else
   1.157 +		{
   1.158 +		if(gVerboseOutput)
   1.159 +			{
   1.160 +			RDebug::Printf("Calling Old Fragment API\n");
   1.161 +			}
   1.162 +		iActual.iRequestResult.iFragmentationResult =
   1.163 +			iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs);
   1.164 +
   1.165 +		}
   1.166 +
   1.167 +	const TInt fragmentCount = iDmaSession.RequestFragmentCount(iRequestSessionCookie);
   1.168 +
   1.169 +	// Record the fragment count if a non-zero value was expected,
   1.170 +	// or if it was an error value
   1.171 +	if(iExpected.iRequestResult.iFragmentCount != 0 || fragmentCount < 0)
   1.172 +		iActual.iRequestResult.iFragmentCount = fragmentCount;
   1.173 +	}
   1.174 +
   1.175 +void CSingleTransferTest::Queue()
   1.176 +	{
   1.177 +	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   1.178 +		{
   1.179 +		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord);
   1.180 +		}
   1.181 +	}
   1.182 +
   1.183 +void CSingleTransferTest::PostTransferCheck()
   1.184 +	{
   1.185 +	if(iPostTransferCheck)
   1.186 +		iActual.iPostTransferCheck = DoPostTransferCheck();
   1.187 +	}
   1.188 +
   1.189 +TInt CSingleTransferTest::DoPostTransferCheck()
   1.190 +	{
   1.191 +	return iPostTransferCheck->Check(*this);
   1.192 +	}
   1.193 +
   1.194 +void CSingleTransferTest::FreeRequest()
   1.195 +	{
   1.196 +	if(iActual.iRequestResult.iCreate == KErrNone)
   1.197 +		{
   1.198 +		TInt r = iDmaSession.RequestDestroy(iRequestSessionCookie);
   1.199 +		TEST_ASSERT(r == KErrNone);
   1.200 +		}
   1.201 +	}
   1.202 +
   1.203 +void CSingleTransferTest::CloseChannel()
   1.204 +	{
   1.205 +	if(iActual.iChannelOpenResult == KErrNone)
   1.206 +		{
   1.207 +		TInt r = iDmaSession.ChannelClose(iChannelSessionCookie);
   1.208 +		TEST_ASSERT(r == KErrNone);
   1.209 +		}
   1.210 +	}
   1.211 +
   1.212 +void CSingleTransferTest::PrintTestType() const
   1.213 +	{
   1.214 +	RDebug::RawPrint(_L("Single transfer"));
   1.215 +	}
   1.216 +
   1.217 +void CSingleTransferTest::PreTransferSetup()
   1.218 +	{
   1.219 +	if(iPreTransfer)
   1.220 +		iPreTransfer->Setup(*this); //initialize test
   1.221 +	}
   1.222 +
   1.223 +TBool CSingleTransferTest::Result()
   1.224 +	{
   1.225 +	const TBool result = iExpected == iActual;
   1.226 +	if(!result)
   1.227 +		{
   1.228 +		RDebug::Printf("TResultSets do not match");
   1.229 +		}
   1.230 +	if(!result || gVerboseOutput)
   1.231 +		{
   1.232 +		RDebug::Printf("\nExpected error codes:");
   1.233 +		iExpected.Print();
   1.234 +		RDebug::Printf("Expected callback record:");
   1.235 +		iExpected.iCallbackRecord.Print();
   1.236 +
   1.237 +		RDebug::Printf("\nActual error codes:");
   1.238 +		iActual.Print();
   1.239 +		RDebug::Printf("Actual callback record:");
   1.240 +		iActual.iCallbackRecord.Print();
   1.241 +		}
   1.242 +	return result;
   1.243 +	}
   1.244 +
   1.245 +
   1.246 +
   1.247 +//////////////////////////////////////////////////////////////////////
   1.248 +// CDmaBenchmark
   1.249 +//////////////////////////////////////////////////////////////////////
   1.250 +
   1.251 +CDmaBenchmark::CDmaBenchmark(const TDesC& aName, TInt aIterations, const TResultSet& aExpectedResults, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
   1.252 +	:CSingleTransferTest(aName, aIterations, aTransferArgs, aExpectedResults, aMaxFragmentSize, NULL, NULL)
   1.253 +	{
   1.254 +	UseNewDmaApi(EFalse);
   1.255 +	}
   1.256 +
   1.257 +CDmaBenchmark::~CDmaBenchmark()
   1.258 +	{
   1.259 +	iResultArray.Close();
   1.260 +	}
   1.261 +
   1.262 +TUint64 CDmaBenchmark::MeanResult()
   1.263 +	{
   1.264 +	if(gVerboseOutput)
   1.265 +		RDebug::Printf("CDmaBenchmark::MeanResult\n");
   1.266 +
   1.267 +	const TInt count = iResultArray.Count();
   1.268 +
   1.269 +	TEST_ASSERT(count > 0);
   1.270 +	TEST_ASSERT(count == iIterations);
   1.271 +
   1.272 +	TUint64 sum = 0;
   1.273 +
   1.274 +	for(TInt i = 0; i < count; i++)
   1.275 +		{
   1.276 +		const TUint64 value = iResultArray[i];
   1.277 +		if(gVerboseOutput)
   1.278 +			RDebug::Printf("iResultArray[%d]: %lu", i, value);
   1.279 +
   1.280 +		sum += value;
   1.281 +		}
   1.282 +
   1.283 +	return sum / count;
   1.284 +	}
   1.285 +
   1.286 +TBool CDmaBenchmark::Result()
   1.287 +	{
   1.288 +	const TBool result = CSingleTransferTest::Result();
   1.289 +	if(result)
   1.290 +		{
   1.291 +		RDebug::Printf("  Mean time: %lu us", MeanResult());
   1.292 +		}
   1.293 +
   1.294 +	//TODO this will be handled by the ctor later
   1.295 +	iResultArray.Close();
   1.296 +
   1.297 +	return result;
   1.298 +	}
   1.299 +
   1.300 +
   1.301 +//////////////////////////////////////////////////////////////////////
   1.302 +// CDmaBmFragmentation
   1.303 +//////////////////////////////////////////////////////////////////////
   1.304 +
   1.305 +CDmaBmFragmentation::CDmaBmFragmentation(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
   1.306 +	:CDmaBenchmark(aName, aIterations, ExpectedResults, aTransferArgs, aMaxFragmentSize)
   1.307 +	{}
   1.308 +
   1.309 +const TResultSet CDmaBmFragmentation::ExpectedResults(KErrNone,
   1.310 +		TRequestResults(KErrNone, 0, KErrNone, KErrUnknown),
   1.311 +		KErrUnknown,
   1.312 +		TCallbackRecord::Empty()
   1.313 +		);
   1.314 +
   1.315 +void CDmaBmFragmentation::Fragment()
   1.316 +	{
   1.317 +	TUint64 time;
   1.318 +	iActual.iRequestResult.iFragmentationResult =
   1.319 +		iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs, &time);
   1.320 +	iResultArray.Append(time);
   1.321 +	}
   1.322 +
   1.323 +void CDmaBmFragmentation::PrintTestType() const
   1.324 +	{
   1.325 +	RDebug::RawPrint(_L("Fragmentation Benchmark"));
   1.326 +	}
   1.327 +
   1.328 +void CDmaBmFragmentation::RunTest()
   1.329 +	{
   1.330 +	OpenDmaSession();
   1.331 +
   1.332 +	OpenChannel();
   1.333 +	CreateDmaRequest();
   1.334 +	Fragment();
   1.335 +	FreeRequest();
   1.336 +	CloseChannel();
   1.337 +
   1.338 +	CloseDmaSession();
   1.339 +	}
   1.340 +
   1.341 +//////////////////////////////////////////////////////////////////////
   1.342 +// CDmaBmTransfer
   1.343 +//////////////////////////////////////////////////////////////////////
   1.344 +
   1.345 +CDmaBmTransfer::CDmaBmTransfer(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
   1.346 +	:CDmaBenchmark(aName, aIterations,
   1.347 +		TResultSet(KErrNone, TRequestResults(),	KErrUnknown, TCallbackRecord(TCallbackRecord::EThread,1)),
   1.348 +		aTransferArgs, aMaxFragmentSize)
   1.349 +	{}
   1.350 +
   1.351 +
   1.352 +void CDmaBmTransfer::PrintTestType() const
   1.353 +	{
   1.354 +	RDebug::RawPrint(_L("Transfer Benchmark"));
   1.355 +	}
   1.356 +
   1.357 +void CDmaBmTransfer::RunTest()
   1.358 +	{
   1.359 +	OpenDmaSession();
   1.360 +
   1.361 +	OpenChannel();
   1.362 +	CreateDmaRequest();
   1.363 +	Fragment();
   1.364 +	Queue();
   1.365 +	FreeRequest();
   1.366 +	CloseChannel();
   1.367 +
   1.368 +	CloseDmaSession();
   1.369 +	}
   1.370 +
   1.371 +void CDmaBmTransfer::Queue()
   1.372 +	{
   1.373 +	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   1.374 +		{
   1.375 +		TUint64 time;
   1.376 +		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequest(iRequestSessionCookie, &iActual.iCallbackRecord, &time);
   1.377 +		iResultArray.Append(time);
   1.378 +		}
   1.379 +	}
   1.380 +
   1.381 +
   1.382 +//////////////////////////////////////////////////////////////////////
   1.383 +// CMultiTransferTest
   1.384 +//////////////////////////////////////////////////////////////////////
   1.385 +
   1.386 +//TODO
   1.387 +// Add pre and post transfer for CMultiTransferTest
   1.388 +CMultiTransferTest::CMultiTransferTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs,
   1.389 +		const TResultSet* aResultSets, TInt aCount)
   1.390 +	: CDmaTest(aName, aIterations, NULL, NULL), iTransferArgs(aTransferArgs), iTransferArgsCount(aCount), iNewDmaApi(ETrue),
   1.391 +	iChannelSessionCookie(0), iExpectedArray(aResultSets), iPauseWhileQueuing(EFalse)
   1.392 +	{}
   1.393 +
   1.394 +CMultiTransferTest::CMultiTransferTest(const CMultiTransferTest& aOther)
   1.395 +	: CDmaTest(aOther), iTransferArgs(aOther.iTransferArgs), iTransferArgsCount(aOther.iTransferArgsCount),
   1.396 +	iNewDmaApi(aOther.iNewDmaApi),
   1.397 +	iExpectedArray(aOther.iExpectedArray), iPauseWhileQueuing(aOther.iPauseWhileQueuing)
   1.398 +	//const cast is required because their isn't a ctor taking const
   1.399 +	//array values
   1.400 +	//TODO iRequestCookies(const_cast<TUint*>(&aOther.iRequestCookies[0]), aOther.iRequestCookies.Count())
   1.401 +	{
   1.402 +	}
   1.403 +
   1.404 +CMultiTransferTest::~CMultiTransferTest()
   1.405 +	{
   1.406 +	iRequestCookies.Close();
   1.407 +	iActualResults.Close();
   1.408 +	}
   1.409 +
   1.410 +TBool CMultiTransferTest::Result()
   1.411 +	{
   1.412 +	if(gVerboseOutput)
   1.413 +		{
   1.414 +		RDebug::Printf("Results for %d transfers:", iTransferArgsCount);
   1.415 +		}
   1.416 +
   1.417 +	TBool result = EFalse;
   1.418 +	for(TInt i=0; i<iTransferArgsCount; i++)
   1.419 +		{
   1.420 +		result = Result(i);
   1.421 +		if(!result)
   1.422 +			break;
   1.423 +		}
   1.424 +	return result;
   1.425 +	}
   1.426 +
   1.427 +TBool CMultiTransferTest::Result(TInt aTransfer)
   1.428 +	{
   1.429 +	const TResultSet& expected = iExpectedArray[aTransfer];
   1.430 +	const TResultSet& actual = iActualResults[aTransfer];
   1.431 +	const TBool result = expected == actual;
   1.432 +	if(!result || gVerboseOutput)
   1.433 +		{
   1.434 +		RDebug::Printf("Compairing results for transfer %d", aTransfer);
   1.435 +		}
   1.436 +
   1.437 +	if(!result)
   1.438 +		{
   1.439 +		RDebug::Printf("TResultSets do not match");
   1.440 +		}
   1.441 +	if(!result || gVerboseOutput)
   1.442 +		{
   1.443 +		RDebug::Printf("\nExpected error codes:");
   1.444 +		expected.Print();
   1.445 +		RDebug::Printf("Expected callback record:");
   1.446 +		expected.iCallbackRecord.Print();
   1.447 +
   1.448 +		RDebug::Printf("\nActual error codes:");
   1.449 +		actual.Print();
   1.450 +		RDebug::Printf("Actual callback record:");
   1.451 +		actual.iCallbackRecord.Print();
   1.452 +		}
   1.453 +	return result;
   1.454 +	}
   1.455 +void CMultiTransferTest::RunTest()
   1.456 +	{
   1.457 +	OpenDmaSession();
   1.458 +
   1.459 +	PreTransferSetup();
   1.460 +	OpenChannel();
   1.461 +
   1.462 +	CreateDmaRequests();
   1.463 +	Fragment();
   1.464 +
   1.465 +	QueueRequests();
   1.466 +
   1.467 +	TInt r = DoPostTransferCheck();
   1.468 +	TEST_ASSERT(r == KErrNone);
   1.469 +
   1.470 +	CloseDmaSession();
   1.471 +	}
   1.472 +
   1.473 +void CMultiTransferTest::PrintTestType() const
   1.474 +	{
   1.475 +	RDebug::RawPrint(_L("Multi Transfer"));
   1.476 +	}
   1.477 +
   1.478 +const TDmaTransferArgs& CMultiTransferTest::TransferArgs(TInt aIndex) const
   1.479 +	{
   1.480 +	TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
   1.481 +
   1.482 +	return iTransferArgs[aIndex];
   1.483 +	}
   1.484 +
   1.485 +void CMultiTransferTest::SetPostTransferResult(TInt aIndex, TInt aErrorCode)
   1.486 +	{
   1.487 +	TEST_ASSERT(Rng(0, aIndex, iTransferArgsCount-1));
   1.488 +
   1.489 +	iActualResults[aIndex].iPostTransferCheck = aErrorCode;
   1.490 +	}
   1.491 +
   1.492 +void CMultiTransferTest::OpenChannel()
   1.493 +	{
   1.494 +	if(gVerboseOutput)
   1.495 +		{
   1.496 +		RDebug::Printf("CMultiTransferTest::OpenChannel()");
   1.497 +		}
   1.498 +	TInt r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
   1.499 +
   1.500 +	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   1.501 +	for(TInt i=0; i<iTransferArgsCount; i++)
   1.502 +		{
   1.503 +		// Since all transfers will use the same channel,
   1.504 +		// they all get the same result
   1.505 +		// Arguably, iChannelOpenResult doesn't
   1.506 +		// belong TResultSet
   1.507 +		iActualResults[i].iChannelOpenResult = r;
   1.508 +		}
   1.509 +	}
   1.510 +
   1.511 +TInt CMultiTransferTest::CloseChannel()
   1.512 +	{
   1.513 +	return iDmaSession.ChannelClose(iChannelSessionCookie);
   1.514 +	}
   1.515 +
   1.516 +void CMultiTransferTest::CreateDmaRequests()
   1.517 +	{
   1.518 +	if(gVerboseOutput)
   1.519 +		{
   1.520 +		RDebug::Printf("CMultiTransferTest::CreateDmaRequests() %d", iTransferArgsCount);
   1.521 +		}
   1.522 +	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   1.523 +	//create a DMA request for each transfer arg struct
   1.524 +	for(TInt i=0; i<iTransferArgsCount; i++)
   1.525 +		{
   1.526 +		if(iActualResults[i].iChannelOpenResult != KErrNone)
   1.527 +			continue;
   1.528 +
   1.529 +		TUint cookie = 0;
   1.530 +		TInt r = KErrGeneral;
   1.531 +
   1.532 +		if(iNewDmaApi)
   1.533 +			{
   1.534 +			r = iDmaSession.RequestCreateNew(iChannelSessionCookie, cookie);
   1.535 +			}
   1.536 +		else
   1.537 +			{
   1.538 +			r = iDmaSession.RequestCreate(iChannelSessionCookie, cookie);
   1.539 +			}
   1.540 +		iActualResults[i].iRequestResult.iCreate = r;
   1.541 +
   1.542 +		if(r == KErrNone)
   1.543 +			{
   1.544 +			r = iRequestCookies.Append(cookie);
   1.545 +			TEST_ASSERT(r == KErrNone);
   1.546 +			}
   1.547 +		}
   1.548 +	}
   1.549 +
   1.550 +void CMultiTransferTest::Fragment()
   1.551 +	{
   1.552 +	if(gVerboseOutput)
   1.553 +		{
   1.554 +		RDebug::Printf("CMultiTransferTest::Fragment() %d", iTransferArgsCount);
   1.555 +		}
   1.556 +	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   1.557 +	// Fragment each dma request
   1.558 +	for(TInt i=0; i<iTransferArgsCount; i++)
   1.559 +		{
   1.560 +		TRequestResults& result = iActualResults[i].iRequestResult;
   1.561 +		if(result.iCreate != KErrNone)
   1.562 +			continue;
   1.563 +
   1.564 +		TInt r = KErrGeneral;
   1.565 +		if(iNewDmaApi)
   1.566 +			r = iDmaSession.FragmentRequest(iRequestCookies[i], iTransferArgs[i]);
   1.567 +		else
   1.568 +			r = iDmaSession.FragmentRequestOld(iRequestCookies[i], iTransferArgs[i]);
   1.569 +
   1.570 +		result.iFragmentationResult = r;
   1.571 +		}
   1.572 +	}
   1.573 +
   1.574 +void CMultiTransferTest::QueueRequests()
   1.575 +	{
   1.576 +	if(iPauseWhileQueuing)
   1.577 +		{
   1.578 +		TInt r = iDmaSession.ChannelPause(iChannelSessionCookie);
   1.579 +		TEST_ASSERT(r == KErrNone);
   1.580 +		}
   1.581 +
   1.582 +	// Queue all the DMA requests asynchronously
   1.583 +	TInt i;
   1.584 +	RArray<TRequestStatus> requestStates;
   1.585 +
   1.586 +	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
   1.587 +	for(i=0; i<iTransferArgsCount; i++)
   1.588 +		{
   1.589 +		TResultSet& resultSet = iActualResults[i];
   1.590 +		if(resultSet.iRequestResult.iFragmentationResult != KErrNone)
   1.591 +			continue;
   1.592 +
   1.593 +		TInt r = requestStates.Append(TRequestStatus());
   1.594 +		TEST_ASSERT(r == KErrNone);
   1.595 +
   1.596 +		r = iDmaSession.QueueRequest(iRequestCookies[i], requestStates[i], &resultSet.iCallbackRecord, NULL);
   1.597 +		resultSet.iRequestResult.iQueueResult = r;
   1.598 +		}
   1.599 +
   1.600 +	if(iPauseWhileQueuing)
   1.601 +		{
   1.602 +		TInt r = iDmaSession.ChannelResume(iChannelSessionCookie);
   1.603 +		TEST_ASSERT(r == KErrNone);
   1.604 +		}
   1.605 +
   1.606 +	// wait for all transfers to complete
   1.607 +	const TInt count = requestStates.Count();
   1.608 +
   1.609 +	for(i=0; i<count; i++)
   1.610 +		{
   1.611 +		User::WaitForRequest(requestStates[i]);
   1.612 +		}
   1.613 +
   1.614 +	requestStates.Close();
   1.615 +	}
   1.616 +
   1.617 +//TODO support test setup for CMultiTransferTest
   1.618 +void CMultiTransferTest::PreTransferSetup()
   1.619 +	{
   1.620 +	for(TInt i=0; i<iTransferArgsCount; i++)
   1.621 +		{
   1.622 +		//pre-fill actual results with error values
   1.623 +		TInt r = iActualResults.Append(TResultSet(EFalse));
   1.624 +		TEST_ASSERT(r == KErrNone);
   1.625 +		}
   1.626 +	if(iPreTransfer)
   1.627 +		iPreTransfer->Setup(*this); //initialize test
   1.628 +	}
   1.629 +
   1.630 +TInt CMultiTransferTest::DoPostTransferCheck()
   1.631 +	{
   1.632 +	if(iPostTransferCheck)
   1.633 +		return iPostTransferCheck->Check(*this);
   1.634 +	else
   1.635 +		return KErrNone;
   1.636 +	}
   1.637 +//////////////////////////////////////////////////////////////////////
   1.638 +// CIsrRequeTest
   1.639 +//////////////////////////////////////////////////////////////////////
   1.640 +
   1.641 +
   1.642 +CIsrRequeTest::CIsrRequeTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs,
   1.643 +			TIsrRequeArgs* aRequeueArgs, TInt aCount,
   1.644 +			const TResultSet& aExpected,const MPreTransfer* aPreTfer,const MPostTransferCheck* aPostTferChk, TUint aMaxFragmentSize)
   1.645 +	:CSingleTransferTest(aName, aIterations, aArgs, aExpected, aMaxFragmentSize, aPostTferChk, aPreTfer), iRequeArgSet(aRequeueArgs, aCount)
   1.646 +	{}
   1.647 +
   1.648 +void CIsrRequeTest::Queue()
   1.649 +	{
   1.650 +	if(iActual.iRequestResult.iFragmentationResult == KErrNone)
   1.651 +		{
   1.652 +		iActual.iRequestResult.iQueueResult = iDmaSession.QueueRequestWithRequeue(iRequestSessionCookie, iRequeArgSet.iRequeArgs, iRequeArgSet.iCount, &iActual.iCallbackRecord);
   1.653 +		}
   1.654 +	}
   1.655 +
   1.656 +void CIsrRequeTest::PrintTestType() const
   1.657 +	{
   1.658 +	RDebug::RawPrint(_L("ISR Requeue"));
   1.659 +	}
   1.660 +
   1.661 +/*
   1.662 +//TODO will need to support buffer checking of the trasnfers
   1.663 +TBool CIsrRequeTest::Result()
   1.664 +	{
   1.665 +	return CSingleTransferTest::Result();
   1.666 +	}
   1.667 +*/
   1.668 +
   1.669 +void CIsrRequeTest::PreTransferSetup()
   1.670 +	{
   1.671 +	if(iPreTransfer)
   1.672 +		iPreTransfer->Setup(*this); //initialize test
   1.673 +	}
   1.674 +
   1.675 +TInt CIsrRequeTest::DoPostTransferCheck()
   1.676 +	{
   1.677 +	return iPostTransferCheck->Check(*this);
   1.678 +	}
   1.679 +
   1.680 +//////////////////////////////////////////////////////////////////////
   1.681 +// TResultSet
   1.682 +//////////////////////////////////////////////////////////////////////
   1.683 +
   1.684 +void TResultSet::Print() const
   1.685 +	{
   1.686 +	PRINT(iChannelOpenResult);
   1.687 +	PRINT(iRequestResult.iCreate);
   1.688 +	PRINT(iRequestResult.iFragmentCount);
   1.689 +	PRINT(iRequestResult.iFragmentationResult);
   1.690 +	PRINT(iRequestResult.iQueueResult);
   1.691 +	PRINT(iPostTransferCheck);
   1.692 +	}
   1.693 +
   1.694 +TBool TResultSet::operator == (const TResultSet& aOther) const
   1.695 +	{
   1.696 +	return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0);
   1.697 +	}
   1.698 +
   1.699 +//////////////////////////////////////////////////////////////////////
   1.700 +// MPostTransferCheck classes
   1.701 +//////////////////////////////////////////////////////////////////////
   1.702 +
   1.703 +TInt TCompareSrcDst::Check(const CSingleTransferTest& aTest) const
   1.704 +	{
   1.705 +	if(gVerboseOutput)
   1.706 +		{
   1.707 +		RDebug::Printf("Comparing CSingleTransferTest buffers");
   1.708 +		}
   1.709 +	return Check(aTest.TransferArgs(), aTest.Chunk().Base());
   1.710 +	}
   1.711 +
   1.712 +//TODO
   1.713 +//this check will not deal correctly transfers were subsequent
   1.714 +//requeues overlap
   1.715 +TInt TCompareSrcDst::Check(const CIsrRequeTest& aTest) const
   1.716 +	{
   1.717 +	if(gVerboseOutput)
   1.718 +		{
   1.719 +		RDebug::Printf("Comparing CIsrRequeTest buffers");
   1.720 +		}
   1.721 +	TUint8* chunkBase = aTest.Chunk().Base();
   1.722 +	const TDmaTransferArgs& transferArgs = aTest.TransferArgs();
   1.723 +	// check first transfer
   1.724 +	TInt r = Check(transferArgs, chunkBase);
   1.725 +
   1.726 +	if(r != KErrNone)
   1.727 +		return r;
   1.728 +
   1.729 +	// check re-queued transfers
   1.730 +	const TIsrRequeArgsSet& requeueArgs = aTest.GetRequeueArgs();
   1.731 +	return Check(requeueArgs, chunkBase, transferArgs);
   1.732 +	}
   1.733 +
   1.734 +TInt TCompareSrcDst::Check(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const
   1.735 +	{
   1.736 +	//TODO could make use of Fixup() method
   1.737 +	const TUint32 srcOffset = aTransferArgs.iSrcConfig.iAddr;
   1.738 +	const TUint32 dstOffset = aTransferArgs.iDstConfig.iAddr;
   1.739 +	const TInt size = aTransferArgs.iTransferCount;
   1.740 +
   1.741 +	const TUint8* src = srcOffset + aChunkBase;
   1.742 +	const TUint8* dst = dstOffset + aChunkBase;
   1.743 +
   1.744 +	if(gVerboseOutput)
   1.745 +		{
   1.746 +		RDebug::Printf("Comparing TDmaTransferArgs buffers src=0x%08x dst=0x%08x size=0x%08x",
   1.747 +				src, dst, size);
   1.748 +		}
   1.749 +
   1.750 +	return memcompare(src, size, dst, size);
   1.751 +	}
   1.752 +
   1.753 +TInt TCompareSrcDst::Check(const TIsrRequeArgsSet& aRequeueArgSet, TUint8* aChunkBase, const TDmaTransferArgs& aTferArgs) const
   1.754 +	{
   1.755 +	TIsrRequeArgsSet argSet(aRequeueArgSet); //copy since Fixup will mutate object
   1.756 +
   1.757 +	argSet.Substitute(aTferArgs); // replace any default (0) values with the values in aTferArgs
   1.758 +
   1.759 +	argSet.Fixup((TLinAddr)aChunkBase); //convert address offsets to virtual user mode addresses
   1.760 +
   1.761 +	TInt r = KErrCorrupt;
   1.762 +	while(!argSet.IsEmpty())
   1.763 +		{
   1.764 +		r = Check(argSet.GetArgs());
   1.765 +		if(r != KErrNone)
   1.766 +			break;
   1.767 +		}
   1.768 +	return r;
   1.769 +	}
   1.770 +
   1.771 +TInt TCompareSrcDst::Check(const TIsrRequeArgs& aRequeueArgs) const
   1.772 +	{
   1.773 +	const TUint8* src = (TUint8*)aRequeueArgs.iSrcAddr;
   1.774 +	const TUint8* dst = (TUint8*)aRequeueArgs.iDstAddr;
   1.775 +	const TInt size = aRequeueArgs.iTransferCount;
   1.776 +
   1.777 +	if(gVerboseOutput)
   1.778 +		{
   1.779 +		RDebug::Printf("Comparing TIsrRequeArgs: src=0x%08x dst=0x%08x size=0x%08x",
   1.780 +				src, dst, size);
   1.781 +		}
   1.782 +
   1.783 +	return memcompare(src, size, dst, size);
   1.784 +	}
   1.785 +
   1.786 +TInt TCompareSrcDst::Check(CMultiTransferTest& aTest) const
   1.787 +	{
   1.788 +	if(gVerboseOutput)
   1.789 +		{
   1.790 +		RDebug::Printf("Comparing CMultiTransferTest buffers");
   1.791 +		}
   1.792 +
   1.793 +	const TInt transferCount = aTest.TransferCount();
   1.794 +	TUint8* const chunkBase = aTest.Chunk().Base();
   1.795 +
   1.796 +	// check buffers for each transfer
   1.797 +	for(TInt i=0; i<transferCount; i++)
   1.798 +		{
   1.799 +		TInt r = Check(aTest.TransferArgs(i), chunkBase);
   1.800 +		aTest.SetPostTransferResult(i, r);
   1.801 +		}
   1.802 +	// CMultiTransferTest is handled differently to the others.
   1.803 +	// Whereas CSingleTransferTest logs just the return value
   1.804 +	// of the check, here, we write back a result for each transfer
   1.805 +	// so the return value from this function is not important
   1.806 +	return KErrNone;
   1.807 +	}
   1.808 +
   1.809 +TInt TCompare2D::Check(const CSingleTransferTest& aTest) const
   1.810 +	{
   1.811 +	const TDmaTransferArgs& args = aTest.TransferArgs();
   1.812 +	TUint8* const chunkBase = aTest.Chunk().Base();
   1.813 +
   1.814 +	TInt ret = KErrNone;
   1.815 +
   1.816 +	TTransferIter src_iter(args.iSrcConfig, chunkBase);
   1.817 +	TTransferIter dst_iter(args.iDstConfig, chunkBase);
   1.818 +	TTransferIter end;
   1.819 +	for (; (src_iter != end) && (dst_iter !=end); ++src_iter, ++dst_iter)
   1.820 +		{
   1.821 +		if(*src_iter != *dst_iter)
   1.822 +			{
   1.823 +			ret = KErrCorrupt;
   1.824 +			break;
   1.825 +			}
   1.826 +		}
   1.827 +	return ret;
   1.828 +	}
   1.829 +
   1.830 +TInt TCompare2D::Check(const CIsrRequeTest&) const
   1.831 +	{
   1.832 +	return KErrNotSupported;
   1.833 +	}
   1.834 +
   1.835 +TInt TCompare2D::Check(CMultiTransferTest&) const
   1.836 +	{
   1.837 +	return KErrNotSupported;
   1.838 +	}
   1.839 +//////////////////////////////////////////////////////////////////////
   1.840 +// MPreTransfer classes
   1.841 +//////////////////////////////////////////////////////////////////////
   1.842 +
   1.843 +void TPreTransferIncrBytes::Setup(const CSingleTransferTest& aTest) const
   1.844 +	{
   1.845 +	if(gVerboseOutput)
   1.846 +		{
   1.847 +		RDebug::Printf("TPreTransferIncrBytes(CSingleTransferTest)");
   1.848 +		}
   1.849 +	TAddressParms params = GetAddrParms(aTest.TransferArgs());
   1.850 +
   1.851 +	TUint8* const chunkBase = aTest.Chunk().Base();
   1.852 +	params.Fixup((TLinAddr)chunkBase);
   1.853 +
   1.854 +
   1.855 +	Setup(params);
   1.856 +	}
   1.857 +
   1.858 +void TPreTransferIncrBytes::Setup(const TAddressParms& aParams) const
   1.859 +	{
   1.860 +	if(gVerboseOutput)
   1.861 +		{
   1.862 +		RDebug::Printf("TPreTransferIncrBytes: setup memory buffers: src=0x%08x dst=0x%08x size=0x%08x",
   1.863 +				aParams.iSrcAddr, aParams.iDstAddr, aParams.iTransferCount);
   1.864 +		}
   1.865 +	TUint8* const src = (TUint8*) aParams.iSrcAddr;
   1.866 +	const TInt size = aParams.iTransferCount;
   1.867 +
   1.868 +	for(TInt i=0; i<size; i++)
   1.869 +		{src[i] = (TUint8)i;} //each src byte holds its own offset (mod 256)
   1.870 +
   1.871 +	TUint8* const dst = (TUint8*) aParams.iDstAddr;
   1.872 +	memclr(dst, size); //clear destination
   1.873 +	}
   1.874 +
   1.875 +void TPreTransferIncrBytes::Setup(const CIsrRequeTest& aTest) const
   1.876 +	{
   1.877 +	if(gVerboseOutput)
   1.878 +		{
   1.879 +		RDebug::Printf("TPreTransferIncrBytes(CIsrRequeTest)");
   1.880 +		}
   1.881 +	if(!CheckBuffers(aTest))
   1.882 +		{
   1.883 +		RDebug::Printf("Successive transfer destinations may not overlap previous src or dst buffers");
   1.884 +		RDebug::Printf("unless the whole transfer is an exact repeat of a previous one");
   1.885 +		TEST_FAULT;
   1.886 +		}
   1.887 +
   1.888 +	Setup(static_cast<CSingleTransferTest>(aTest)); // prepare the CSingleTransferTest parts
   1.889 +
   1.890 +	TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
   1.891 +
   1.892 +	requeSet.Substitute(aTest.TransferArgs());
   1.893 +
   1.894 +	const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
   1.895 +	requeSet.Fixup(chunkBase);
   1.896 +
   1.897 +	while(!requeSet.IsEmpty())
   1.898 +		{
   1.899 +		TIsrRequeArgs args = requeSet.GetArgs();
   1.900 +		Setup(args); // perform the setup operation for each TIsrRequeArgs
   1.901 +		}
   1.902 +	}
   1.903 +
   1.904 +void TPreTransferIncrBytes::Setup(const CMultiTransferTest& aTest) const
   1.905 +	{
   1.906 +	if(gVerboseOutput)
   1.907 +		{
   1.908 +		RDebug::Printf("TPreTransferIncrBytes(CMultiTransferTest)");
   1.909 +		}
   1.910 +	//TODO check for overlap
   1.911 +
   1.912 +	TUint8* const chunkBase = aTest.Chunk().Base();
   1.913 +	const TInt transferCount = aTest.TransferCount();
   1.914 +
   1.915 +	// initialise buffers for each transfer
   1.916 +	for(TInt i=0; i<transferCount; i++)
   1.917 +		{
   1.918 +		TAddressParms params = GetAddrParms(aTest.TransferArgs(i));
   1.919 +
   1.920 +		params.Fixup((TLinAddr)chunkBase);
   1.921 +
   1.922 +		Setup(params);
   1.923 +		}
   1.924 +	}
   1.925 +
   1.926 +TBool TPreTransferIncrBytes::CheckBuffers(const CIsrRequeTest& aTest) const
   1.927 +	{
   1.928 +	RArray<const TAddressParms> array;
   1.929 +	array.AppendL(TAddressParms(aTest.TransferArgs()));
   1.930 +
   1.931 +	TIsrRequeArgsSet requeSet(aTest.GetRequeueArgs());
   1.932 +	requeSet.Substitute(aTest.TransferArgs());
   1.933 +
   1.934 +	const TLinAddr chunkBase = (TLinAddr) aTest.Chunk().Base();
   1.935 +	requeSet.Fixup(chunkBase);
   1.936 +	while(!requeSet.IsEmpty())
   1.937 +		{
   1.938 +		const TIsrRequeArgs requeArgs = requeSet.GetArgs();
   1.939 +		array.AppendL(requeArgs);
   1.940 +		}
   1.941 +
   1.942 +	const TBool result = CheckBuffers(array);
   1.943 +
   1.944 +	array.Close();
   1.945 +	return result;
   1.946 +	}
   1.947 +
   1.948 +/**
   1.949 +Check that the destination of each TAddressParms does not overlap with
   1.950 +any previous source or destination or that if it does the whole transfer
   1.951 +matches.
   1.952 +This is so that successive transfers do not overwrite the destinations or
   1.953 +sources of preceeding ones.
   1.954 +Exactly matching transfers are allowed to test the case that a repeat
   1.955 +transfer is required - though it can't then be determined just from
   1.956 +looking at the buffers that the repeat was successful
   1.957 +*/
   1.958 +TBool TPreTransferIncrBytes::CheckBuffers(const RArray<const TAddressParms> aTransferParams) const
   1.959 +	{
   1.960 +	const TInt count = aTransferParams.Count();
   1.961 +
   1.962 +	for(TInt i=1; i<count; i++)
   1.963 +		{
   1.964 +		const TAddressParms& current = aTransferParams[i];
   1.965 +		for(TInt j=0; j<i; j++)
   1.966 +			{
   1.967 +			const TAddressParms& previous = aTransferParams[j];
   1.968 +			const TBool ok = !previous.Overlaps(current.DestRange()) || current == previous;
   1.969 +			if(!ok)
   1.970 +				return EFalse;
   1.971 +			}
   1.972 +		}
   1.973 +	return ETrue;
   1.974 +	}
   1.975 +//////////////////////////////////////////////////////////////////////
   1.976 +// TTransferIter class
   1.977 +//////////////////////////////////////////////////////////////////////
   1.978 +
   1.979 +void TTransferIter::operator++ ()
   1.980 +	{
   1.981 +	iPtr++; //the standard post increment
   1.982 +	if(iElem < (iCfg->iElementsPerFrame-1))
   1.983 +		{
   1.984 +		iPtr += iCfg->iElementSkip;
   1.985 +		iElem++;
   1.986 +		iBytes++;
   1.987 +		}
   1.988 +	else
   1.989 +		{
   1.990 +		TEST_ASSERT(iElem == iCfg->iElementsPerFrame-1);
   1.991 +		if(iFrame < iCfg->iFramesPerTransfer-1)
   1.992 +			{
   1.993 +			iPtr += iCfg->iFrameSkip;
   1.994 +			iFrame++;
   1.995 +			iBytes++;
   1.996 +			iElem = 0;
   1.997 +			}
   1.998 +		else
   1.999 +			{
  1.1000 +			//we have reached the end
  1.1001 +			TEST_ASSERT(iFrame == iCfg->iFramesPerTransfer-1);
  1.1002 +			iPtr = NULL;
  1.1003 +			}
  1.1004 +		}
  1.1005 +
  1.1006 +	Invariant();
  1.1007 +	}
  1.1008 +
  1.1009 +void TTransferIter::Invariant() const
  1.1010 +	{
  1.1011 +	const TInt elemSize = iCfg->iElementSize;
  1.1012 +	RTest test(_L("TTransferIter invariant"));
  1.1013 +	const TInt bytesTransfered = (
  1.1014 +			elemSize * (iFrame * iCfg->iElementsPerFrame + iElem)
  1.1015 +			+ ((TUint)iPtr % (elemSize))
  1.1016 +			);
  1.1017 +	test_Equal(iBytes, bytesTransfered);
  1.1018 +	test.Close();
  1.1019 +	}
  1.1020 +
  1.1021 +///////////////////////////////////////////////////////////
  1.1022 +// TTestCase
  1.1023 +///////////////////////////////////////////////////////////
  1.1024 +TTestCase::TTestCase(CDmaTest* aTest,
  1.1025 +   TBool aConcurrent,
  1.1026 +   const TDmaCapability aCap1,
  1.1027 +   const TDmaCapability aCap2,
  1.1028 +   const TDmaCapability aCap3,
  1.1029 +   const TDmaCapability aCap4,
  1.1030 +   const TDmaCapability aCap5
  1.1031 +   )
  1.1032 +:
  1.1033 +	iTest(aTest), iConcurrentTest(aConcurrent)
  1.1034 +	{
  1.1035 +	iChannelCaps[0] = aCap1;
  1.1036 +	iChannelCaps[1] = aCap2;
  1.1037 +	iChannelCaps[2] = aCap3;
  1.1038 +	iChannelCaps[3] = aCap4;
  1.1039 +	iChannelCaps[4] = aCap5;
  1.1040 +	}
  1.1041 +
  1.1042 +TResult TTestCase::TestCaseValid(const SDmacCaps& aChannelCaps) const
  1.1043 +	{
  1.1044 +	const TDmaCapability* cap = &iChannelCaps[0];
  1.1045 +
  1.1046 +	TResult ret = ERun;
  1.1047 +	//We assume that the array is empty at the first ENone found
  1.1048 +	//any caps after this wil be ignored
  1.1049 +	while(cap->iCapsReq != ENone)
  1.1050 +		{
  1.1051 +		TResult t = cap->CompareToDmaCaps(aChannelCaps);
  1.1052 +		if(t > ret) //this relies on the enum ordering
  1.1053 +			ret = t;
  1.1054 +		cap++;
  1.1055 +		}
  1.1056 +	return ret;
  1.1057 +	}
  1.1058 +
  1.1059 +TResult TTestCase::TestCaseValid(const TDmacTestCaps& aChannelCaps) const
  1.1060 +	{
  1.1061 +	const TDmaCapability* cap = &iChannelCaps[0];
  1.1062 +
  1.1063 +	TResult ret = ERun;
  1.1064 +	//We assume that the array is empty at the first ENone found
  1.1065 +	//any caps after this wil be ignored
  1.1066 +	while(cap->iCapsReq != ENone)
  1.1067 +		{
  1.1068 +		TResult t = cap->CompareToDmaCaps(aChannelCaps);
  1.1069 +		if(t > ret) //this relies on the enum ordering
  1.1070 +			ret = t;
  1.1071 +		cap++;
  1.1072 +		}
  1.1073 +	return ret;
  1.1074 +	}
  1.1075 +/**
  1.1076 +Will report whether a value held in aChannelCaps satisfies a
  1.1077 +requirement specfied by this object
  1.1078 +*/
  1.1079 +TBool TDmaCapability::RequirementSatisfied(const SDmacCaps& aChannelCaps) const
  1.1080 +	{
  1.1081 +	switch(iCapsReq)
  1.1082 +		{
  1.1083 +	case ENone:
  1.1084 +		return ETrue;
  1.1085 +	case EChannelPriorities:
  1.1086 +		TEST_FAULT;
  1.1087 +	case EChannelPauseAndResume:
  1.1088 +		return aChannelCaps.iChannelPauseAndResume == (TBool)iValue;
  1.1089 +	case EAddrAlignedToElementSize:
  1.1090 +		TEST_FAULT;
  1.1091 +	case E1DAddressing:
  1.1092 +		return aChannelCaps.i1DIndexAddressing == (TBool)iValue;
  1.1093 +	case E2DAddressing:
  1.1094 +		return aChannelCaps.i2DIndexAddressing == (TBool)iValue;
  1.1095 +	case ESynchronizationTypes:
  1.1096 +	case EBurstTransactions:
  1.1097 +	case EDescriptorInterrupt:
  1.1098 +	case EFrameInterrupt:
  1.1099 +	case ELinkedListPausedInterrupt:
  1.1100 +	case EEndiannessConversion:
  1.1101 +	case EGraphicsOps:
  1.1102 +	case ERepeatingTransfers:
  1.1103 +	case EChannelLinking:
  1.1104 +		TEST_FAULT;
  1.1105 +	case EHwDescriptors:
  1.1106 +		return aChannelCaps.iHwDescriptors == (TBool)iValue;
  1.1107 +	case ESrcDstAsymmetry:
  1.1108 +	case EAsymHwDescriptors:
  1.1109 +		TEST_FAULT;
  1.1110 +	case EBalancedAsymSegments:
  1.1111 +		return aChannelCaps.iBalancedAsymSegments == (TBool)iValue;
  1.1112 +	case EAsymCompletionInterrupt:
  1.1113 +		return aChannelCaps.iAsymCompletionInterrupt == (TBool)iValue;
  1.1114 +	case EAsymDescriptorInterrupt:
  1.1115 +		return aChannelCaps.iAsymDescriptorInterrupt == (TBool)iValue;
  1.1116 +	case EAsymFrameInterrupt:
  1.1117 +		return aChannelCaps.iAsymFrameInterrupt == (TBool)iValue;
  1.1118 +	default:
  1.1119 +		TEST_FAULT;
  1.1120 +		}
  1.1121 +
  1.1122 +	return EFalse;
  1.1123 +	}
  1.1124 +
  1.1125 +/**
  1.1126 +Will report whether a value held in aChannelCaps satisfies a
  1.1127 +requirement specfied by this object
  1.1128 +*/
  1.1129 +TBool TDmaCapability::RequirementSatisfied(const TDmacTestCaps& aChannelCaps) const
  1.1130 +	{
  1.1131 +	switch(iCapsReq)
  1.1132 +		{
  1.1133 +	case EPilVersion:
  1.1134 +		return TestValue(aChannelCaps.iPILVersion);
  1.1135 +	default:
  1.1136 +		return RequirementSatisfied(static_cast<SDmacCaps>(aChannelCaps));
  1.1137 +		}
  1.1138 +	}
  1.1139 +
  1.1140 +TResult TDmaCapability::CompareToDmaCaps(const SDmacCaps& aChannelCaps) const
  1.1141 +	{
  1.1142 +	const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
  1.1143 +	if(reqSatisfied)
  1.1144 +		{
  1.1145 +		return ERun;
  1.1146 +		}
  1.1147 +	else
  1.1148 +		{
  1.1149 +		return iFail ? EFail : ESkip;
  1.1150 +		}
  1.1151 +	}
  1.1152 +
  1.1153 +TResult TDmaCapability::CompareToDmaCaps(const TDmacTestCaps& aChannelCaps) const
  1.1154 +	{
  1.1155 +	const TBool reqSatisfied = RequirementSatisfied(aChannelCaps);
  1.1156 +	if(reqSatisfied)
  1.1157 +		{
  1.1158 +		return ERun;
  1.1159 +		}
  1.1160 +	else
  1.1161 +		{
  1.1162 +		return iFail ? EFail : ESkip;
  1.1163 +		}
  1.1164 +	}
  1.1165 +/**
  1.1166 +Test that aValue satisfies the comparrison (iCapsReqType) with the
  1.1167 +reference value held in iValue
  1.1168 +*/
  1.1169 +TBool TDmaCapability::TestValue(TUint aValue) const
  1.1170 +	{
  1.1171 +	switch(iCapsReqType)
  1.1172 +		{
  1.1173 +	case EEqual:
  1.1174 +		return aValue == iValue;
  1.1175 +	case EGTE:
  1.1176 +		return aValue >= iValue;
  1.1177 +	case ELTE:
  1.1178 +		return aValue <= iValue;
  1.1179 +	case EBitsSet:
  1.1180 +	case EBitsClear:
  1.1181 +	default:
  1.1182 +		TEST_FAULT;
  1.1183 +		}
  1.1184 +	return EFalse;
  1.1185 +	}
  1.1186 +
  1.1187 +static RTest test(_L("DMAv2 test"));
  1.1188 +
  1.1189 +//////////////////////////////////////////////////////////////////////
  1.1190 +// TTestRunner
  1.1191 +//////////////////////////////////////////////////////////////////////
  1.1192 +TTestRunner::TTestRunner()
  1.1193 +	{
  1.1194 +	// Open RDmaSession handle
  1.1195 +	TInt r = iDmaSession.Open();
  1.1196 +	TEST_ASSERT(r == KErrNone);
  1.1197 +
  1.1198 +	// Get PSI Test info
  1.1199 +	r = iDmaSession.GetTestInfo(iPslTestInfo);
  1.1200 +	TEST_ASSERT(r == KErrNone);
  1.1201 +
  1.1202 +	//Retrieve PSL cookies
  1.1203 +	GetPslCookie();
  1.1204 +
  1.1205 +	//Generate the DMA channel records
  1.1206 +	GenerateChannelRecord();
  1.1207 +	}
  1.1208 +
  1.1209 +TTestRunner::~TTestRunner()
  1.1210 +	{
  1.1211 +	RTest::CloseHandleAndWaitForDestruction(iDmaSession);
  1.1212 +	iTestCases.Close(); //TestRunner does not own test cases
  1.1213 +	iChannelRecords.Close();
  1.1214 +	iPslCookies.Close();
  1.1215 +	}
  1.1216 +
  1.1217 +void TTestRunner::AddTestCases(RPointerArray<TTestCase>& aTTestCases)
  1.1218 +	{
  1.1219 +	const TInt count = aTTestCases.Count();
  1.1220 +	for(TInt i=0; i < count; i++)
  1.1221 +		{
  1.1222 +		iTestCases.AppendL(aTTestCases[i]);
  1.1223 +		}
  1.1224 +	}
  1.1225 +
  1.1226 +void TTestRunner::RunTests()
  1.1227 +	{
  1.1228 +	//Print PslTestInfo
  1.1229 +	if(gVerboseOutput)
  1.1230 +		{
  1.1231 +		Print(iPslTestInfo);
  1.1232 +		}
  1.1233 +
  1.1234 +	//iterate through the test case array
  1.1235 +	const TInt testCaseCount = iTestCases.Count();
  1.1236 +	for(TInt i=0; i < testCaseCount; i++)
  1.1237 +		{
  1.1238 +		const TTestCase& testCase = *iTestCases[i];
  1.1239 +
  1.1240 +		//Here, we must create a test thread for each channel
  1.1241 +		RPointerArray<CTest> concurrentTests;
  1.1242 +
  1.1243 +		if(testCase.iConcurrentTest)
  1.1244 +			RDebug::Printf("== Begin concurrent test run ==");
  1.1245 +
  1.1246 +		const TInt chanRecCount = iChannelRecords.Count();
  1.1247 +		for(TInt j=0; j < chanRecCount; j++)
  1.1248 +			{
  1.1249 +			const TChannelRecord& record = iChannelRecords[j];
  1.1250 +			const TDmacTestCaps& caps = record.iChannelCaps;
  1.1251 +
  1.1252 +			const TResult t = testCase.TestCaseValid(caps);
  1.1253 +
  1.1254 +			switch(t)
  1.1255 +				{
  1.1256 +			case ERun:
  1.1257 +				{
  1.1258 +				CDmaTest* dmaTest = static_cast<CDmaTest*>(testCase.iTest->Clone());
  1.1259 +				TEST_ASSERT(dmaTest != NULL);
  1.1260 +
  1.1261 +				dmaTest->SetChannelCookie(record.iCookie);
  1.1262 +				dmaTest->Announce();
  1.1263 +				if(testCase.iConcurrentTest)
  1.1264 +					{
  1.1265 +					//Add test to array to be run concurrently
  1.1266 +					TInt r = concurrentTests.Append(dmaTest);
  1.1267 +					TEST_ASSERT(r == KErrNone);
  1.1268 +					}
  1.1269 +				else
  1.1270 +					{
  1.1271 +					//Run test in this thread
  1.1272 +					(*dmaTest)();
  1.1273 +					//TTestThread(
  1.1274 +					TBool result = dmaTest->Result();
  1.1275 +					TEST_ASSERT(result);
  1.1276 +
  1.1277 +					delete dmaTest;
  1.1278 +					}
  1.1279 +
  1.1280 +				break;
  1.1281 +				}
  1.1282 +			case ESkip:
  1.1283 +				if(gVerboseOutput)
  1.1284 +				{
  1.1285 +				RDebug::Printf("Skipping test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
  1.1286 +				}
  1.1287 +				break;
  1.1288 +			case EFail:
  1.1289 +				if(gVerboseOutput)
  1.1290 +				{
  1.1291 +				RDebug::Printf("Failling test-case %S, PSL channel %d", &testCase.iTest->Name(), record.iCookie);
  1.1292 +				}
  1.1293 +				TEST_FAULT;
  1.1294 +			default:
  1.1295 +				TEST_FAULT;
  1.1296 +				}
  1.1297 +			//Depending on the value of iConcurrentTest the test runner will either block until the thread has completed or
  1.1298 +			//alternatively run the current test case on the next channel:
  1.1299 +
  1.1300 +			//if the test case has been run on all channels it will then  wait for all threads to complete.
  1.1301 +			}
  1.1302 +
  1.1303 +		const TInt count = concurrentTests.Count();
  1.1304 +		if(count>0)
  1.1305 +			{
  1.1306 +			MultipleTestRun(concurrentTests);
  1.1307 +			for(TInt i=0; i<count; i++)
  1.1308 +				{
  1.1309 +				TBool result = static_cast<CDmaTest*>(concurrentTests[i])->Result();
  1.1310 +				TEST_ASSERT(result);
  1.1311 +				}
  1.1312 +			RDebug::Printf("== End concurrent test run ==");
  1.1313 +			}
  1.1314 +
  1.1315 +		concurrentTests.ResetAndDestroy();
  1.1316 +		}
  1.1317 +	}
  1.1318 +
  1.1319 +void TTestRunner::GetPslCookie()
  1.1320 +	{
  1.1321 +	//Get Sb Channel cookies
  1.1322 +	for(TInt sb_channelcount=0; sb_channelcount<iPslTestInfo.iMaxSbChannels; sb_channelcount++)
  1.1323 +		{
  1.1324 +		iPslCookies.AppendL(iPslTestInfo.iSbChannels[sb_channelcount]);
  1.1325 +		}
  1.1326 +
  1.1327 +	//Get Db Channel cookies
  1.1328 +	for(TInt db_channelcount=0; db_channelcount<iPslTestInfo.iMaxDbChannels; db_channelcount++)
  1.1329 +		{
  1.1330 +		iPslCookies.AppendL(iPslTestInfo.iDbChannels[db_channelcount]);
  1.1331 +		}
  1.1332 +
  1.1333 +	//Get Sg Channel cookies
  1.1334 +	for(TInt sg_channelcount=0; sg_channelcount<iPslTestInfo.iMaxSgChannels; sg_channelcount++)
  1.1335 +		{
  1.1336 +		iPslCookies.AppendL(iPslTestInfo.iSgChannels[sg_channelcount]);
  1.1337 +		}
  1.1338 +	}
  1.1339 +
  1.1340 +void TTestRunner::GenerateChannelRecord()
  1.1341 +	{
  1.1342 +	//for each PSL cookie
  1.1343 +	for(TInt count=0; count<iPslCookies.Count(); count++)
  1.1344 +		{
  1.1345 +		//Get channel cookie
  1.1346 +		const TUint pslCookie = iPslCookies[count];
  1.1347 +		TUint sessionCookie;
  1.1348 +		TInt r = iDmaSession.ChannelOpen(pslCookie, sessionCookie);
  1.1349 +		TEST_ASSERT(r == KErrNone);
  1.1350 +		if(gVerboseOutput)
  1.1351 +		{
  1.1352 +		RDebug::Printf("Channel PSL Cookie[%d]  :0x%08x",count,pslCookie);
  1.1353 +		}
  1.1354 +
  1.1355 +		TChannelRecord dmaChannelRecord;
  1.1356 +		dmaChannelRecord.iCookie = pslCookie;
  1.1357 +
  1.1358 +		//Get Channel Caps
  1.1359 +		r = iDmaSession.ChannelCaps(sessionCookie, dmaChannelRecord.iChannelCaps);
  1.1360 +		TEST_ASSERT(r == KErrNone);
  1.1361 +
  1.1362 +		r = iDmaSession.ChannelClose(sessionCookie);
  1.1363 +		TEST_ASSERT(r == KErrNone);
  1.1364 +
  1.1365 +		//Append array
  1.1366 +		iChannelRecords.AppendL(dmaChannelRecord);
  1.1367 +		}
  1.1368 +	}
  1.1369 +//////////////////////////////////////////////////////////////////////
  1.1370 +// Global test functions and E32Main
  1.1371 +//////////////////////////////////////////////////////////////////////
  1.1372 +
  1.1373 +/**
  1.1374 +Displayed if used supplied no parameters, garbage, or a ? in the parameters
  1.1375 +*/
  1.1376 +void PrintUsage()
  1.1377 +	{
  1.1378 +	test.Printf(_L("*** DMA TEST FRAMEWORK ***\n"));
  1.1379 +	test.Printf(_L("Usage : t_dma2.exe [/option]\n"));
  1.1380 +	test.Printf(_L("  /V  or /VERBOSE    = Control test output\n"));
  1.1381 +	test.Printf(_L("  /S  or /SELFTEST   = Run DMA self test\n"));
  1.1382 +	test.Printf(_L("\n"));
  1.1383 +	}
  1.1384 +
  1.1385 +void ProcessCommandLineL()
  1.1386 +{
  1.1387 +	test.Printf(_L("Process command line arguments\n"));
  1.1388 +
  1.1389 +	TInt cmdLineLength(User::CommandLineLength());
  1.1390 +	HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength);
  1.1391 +	TPtr cmdLinePtr = cmdLine->Des();
  1.1392 +	User::CommandLine(cmdLinePtr);
  1.1393 +	TBool  tokenParsed(EFalse);
  1.1394 +
  1.1395 +	TLex args(*cmdLine);
  1.1396 +	args.SkipSpace(); // args are separated by spaces
  1.1397 +	
  1.1398 +	// first arg is the exe name, skip it
  1.1399 +	TPtrC cmdToken = args.NextToken();
  1.1400 +	HBufC* tc = HBufC::NewLC(KParameterTextLenMax);
  1.1401 +	*tc = cmdToken;
  1.1402 +	while (tc->Length())
  1.1403 +		{
  1.1404 +		tokenParsed = EFalse;
  1.1405 +		
  1.1406 +		// '/?' help wanted flag '?' or /? parameter
  1.1407 +		if ((0== tc->FindF(_L("?"))) || (0==tc->FindF(_L("/?")))) 
  1.1408 +			{
  1.1409 +			gHelpRequested = ETrue;
  1.1410 +			tokenParsed = ETrue;
  1.1411 +			}	
  1.1412 +		
  1.1413 +		// '/SELFTEST'			
  1.1414 +		if ((0== tc->FindF(KArgSelfTest)) || (0==tc->FindF(KArgSelfTest2))) 
  1.1415 +			{
  1.1416 +			// Run self test
  1.1417 +			test.Printf(_L("Command Line Options:Selftest option specified.\n"));
  1.1418 +			gSelfTest = ETrue;
  1.1419 +			tokenParsed = ETrue;
  1.1420 +			}
  1.1421 +
  1.1422 +		// '/VERBOSE' option	
  1.1423 +		if ((0== tc->FindF(KArgVerboseOutput)) || (0==tc->FindF(KArgVerboseOutput2)))
  1.1424 +			{ 
  1.1425 +			test.Printf(_L("Command Line Options:Verbose option specified.\n"));
  1.1426 +			gVerboseOutput = ETrue;
  1.1427 +			tokenParsed = ETrue;			
  1.1428 +			}
  1.1429 +
  1.1430 +		if (!tokenParsed)
  1.1431 +			{
  1.1432 +			// warn about unparsed parameter
  1.1433 +			test.Printf(_L("Warning: '%lS'??? not parsed\n"), tc);
  1.1434 +			gHelpRequested = ETrue;
  1.1435 +			}
  1.1436 +			
  1.1437 +		// next parameter
  1.1438 +		*tc = args.NextToken();
  1.1439 +		}
  1.1440 +	CleanupStack::PopAndDestroy(tc);
  1.1441 +	CleanupStack::PopAndDestroy(cmdLine);
  1.1442 +}
  1.1443 +
  1.1444 +void RunDMATests()
  1.1445 +	{
  1.1446 +	test.Start(_L("Creating test runner\n"));
  1.1447 +	TTestRunner testRunner;
  1.1448 +
  1.1449 +	test.Next(_L("Add global test cases to test runner\n"));
  1.1450 +	testRunner.AddTestCases(TestArray);
  1.1451 +
  1.1452 +	test.Next(_L("call TTestRunner::RunTests()\n"));
  1.1453 +	testRunner.RunTests();
  1.1454 +
  1.1455 +	test.End();
  1.1456 +	}
  1.1457 +
  1.1458 +TInt E32Main()
  1.1459 +	{
  1.1460 +	__UHEAP_MARK;
  1.1461 +	//__KHEAP_MARK;
  1.1462 +	test.Title();
  1.1463 +
  1.1464 +	gHelpRequested = EFalse;
  1.1465 +	TInt r;
  1.1466 +
  1.1467 +	// Create the new trap-cleanup mechanism
  1.1468 +	CTrapCleanup* cleanup = CTrapCleanup::New();
  1.1469 +
  1.1470 +	if (cleanup == NULL)
  1.1471 +		{
  1.1472 +		return KErrNoMemory;
  1.1473 +		}
  1.1474 +
  1.1475 +	// Process the command line parameters for batch/etc
  1.1476 +	TRAPD(err, ProcessCommandLineL());
  1.1477 +	if (err != KErrNone)
  1.1478 +		{
  1.1479 +		User::Panic(_L("DMA test run memory failure"), KErrNoMemory);
  1.1480 +		}
  1.1481 +	
  1.1482 +	if (gHelpRequested)
  1.1483 +		{
  1.1484 +		PrintUsage();
  1.1485 +		User::Leave(-2);	// nothing to do!
  1.1486 +		}
  1.1487 +	test.Start(_L("Loading test LDD"));
  1.1488 +	//load either the new test ldd, d_dma2.ldd,
  1.1489 +	//or d_dma2_compat.ldd - an ldd linked against
  1.1490 +	//the old DMA framework
  1.1491 +	_LIT(KDma, "D_DMA2.LDD");
  1.1492 +	r = User::LoadLogicalDevice(KDma);
  1.1493 +	const TBool dma2Loaded = ((r == KErrNone) || (r == KErrAlreadyExists));
  1.1494 +
  1.1495 +	_LIT(KDma2Compat, "D_DMA2_COMPAT.LDD");
  1.1496 +	r = User::LoadLogicalDevice(KDma2Compat);
  1.1497 +	const TBool dma2CompatLoaded = ((r == KErrNone) || (r == KErrAlreadyExists));
  1.1498 +
  1.1499 +	if (!(dma2Loaded || dma2CompatLoaded))
  1.1500 +		{
  1.1501 +		//TODO how can we distinguish this case from a platform where
  1.1502 +		//dma is supposed to be supported but the dma test ldd is
  1.1503 +		//missing?
  1.1504 +		test.Printf(_L("DMA not supported - test skipped\n"));
  1.1505 +		return 0;
  1.1506 +		}
  1.1507 +	else if (dma2Loaded && !dma2CompatLoaded)
  1.1508 +		{
  1.1509 +		test.Printf(_L("Loaded %S\n"), &KDma);
  1.1510 +		}
  1.1511 +	else if (!dma2Loaded && dma2CompatLoaded)
  1.1512 +		{
  1.1513 +		test.Printf(_L("Loaded %S\n"), &KDma2Compat);
  1.1514 +		}
  1.1515 +	else
  1.1516 +		{
  1.1517 +		test.Printf(_L("The ROM contains %S and %S - only one should be present\n"), &KDma, &KDma2Compat);
  1.1518 +		TEST_FAULT;
  1.1519 +		}
  1.1520 +	// Turn off evil lazy dll unloading
  1.1521 +	RLoader l;
  1.1522 +	test(l.Connect()==KErrNone);
  1.1523 +	test(l.CancelLazyDllUnload()==KErrNone);
  1.1524 +	RTest::CloseHandleAndWaitForDestruction(l);
  1.1525 +
  1.1526 +	__KHEAP_MARK;
  1.1527 +
  1.1528 +	if (gSelfTest) //Run self tests if specified on command line
  1.1529 +	{
  1.1530 +	SelfTests(); 	
  1.1531 +	}
  1.1532 +
  1.1533 +	ApiTests();
  1.1534 +
  1.1535 +	RunDMATests();
  1.1536 +
  1.1537 +	__KHEAP_MARKEND;
  1.1538 +
  1.1539 +	r = User::FreeLogicalDevice(KTestDmaLddName);
  1.1540 +	test_KErrNone(r);
  1.1541 +	test.End();
  1.1542 +	test.Close();
  1.1543 +
  1.1544 +	delete cleanup;
  1.1545 +
  1.1546 +	//__KHEAP_MARKEND;
  1.1547 +	__UHEAP_MARKEND;
  1.1548 +	return 0;
  1.1549 +	}