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 + }