1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/demandpaging/t_mmcpaging.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,697 @@
1.4 +// Copyright (c) 2006-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 the License "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\mmu\t_mmcpaging.cpp
1.18 +// Suite of tests specifically to test the demand paging subsystem when
1.19 +// booted from MMC rather than NAND.
1.20 +// 002 Read/Write and Page test
1.21 +//
1.22 +//
1.23 +
1.24 +//! @SYMTestCaseID KBASE-T_MMCPAGING-0331
1.25 +//! @SYMTestType UT
1.26 +//! @SYMPREQ PREQ1110
1.27 +//! @SYMTestCaseDesc Demand Paging MMC Paging tests.
1.28 +//! @SYMTestActions 001 Check that the rom is paged
1.29 +//! @SYMTestExpectedResults All tests should pass.
1.30 +//! @SYMTestPriority High
1.31 +//! @SYMTestStatus Implemented
1.32 +
1.33 +#include <e32test.h>
1.34 +RTest test(_L("T_MMCPAGING"));
1.35 +
1.36 +#include <e32rom.h>
1.37 +#include <e32svr.h>
1.38 +#include <u32hal.h>
1.39 +#include <f32file.h>
1.40 +#include <f32dbg.h>
1.41 +#include <d32locd.h>
1.42 +#include <hal.h>
1.43 +#define __TEST_PAGING_MEDIA_DRIVER__
1.44 +#include "mmcdp.h"
1.45 +
1.46 +
1.47 +
1.48 +TInt DriveNumber=-1; // Parameter - Which drive? -1 = autodetect.
1.49 +TInt locDriveNumber;
1.50 +
1.51 +TInt MaxDeferLoops=40; // Parameter - Defer test, for how long?
1.52 +TInt Maxloops=400; // Parameter - RW Soak, for how long?
1.53 +TBool Forever=EFalse; // Parameter - RW Soak forever?
1.54 +
1.55 +TBool Testing=ETrue; // Used to communicate when testing has finished between threads.
1.56 +
1.57 +RFs TheFs;
1.58 +TBusLocalDrive Drive;
1.59 +TLocalDriveCapsV4 DriveCaps;
1.60 +
1.61 +TInt PagedTrashCount=0; // Incremented by threads, is used to detect preemption.
1.62 +TInt GlobError=KErrNone; // To communicate an error between threads.
1.63 +TBool CtrlIOSupported=ETrue;
1.64 +
1.65 +
1.66 +//const TInt KDiskSectorShift = 9;
1.67 +const TInt KBufSizeInBytes = (32 * 1024);
1.68 +
1.69 +LOCAL_D TBuf8<KBufSizeInBytes> Buffer;
1.70 +
1.71 +
1.72 +
1.73 +// Three functions for the garbage test.
1.74 +// CreateFile creates a file, and sets up the buffer for WriteNumber.
1.75 +// After the code has finished writing numbers to the start,
1.76 +// CloseAndDestroy cleans up.
1.77 +
1.78 +void CreateFile(RFile &aFile,const TDesC& aFileName)
1.79 + {
1.80 + TBuf<256> fileName;
1.81 + fileName.Append((TChar)('A'+DriveNumber));
1.82 + fileName+=_L(":\\f32-tst\\");
1.83 + TInt r=TheFs.MkDirAll(fileName);
1.84 + test(r==KErrNone || r== KErrAlreadyExists);
1.85 +
1.86 + fileName += aFileName;
1.87 +
1.88 + r=aFile.Replace(TheFs,fileName,EFileWrite);
1.89 + if (r!=KErrNone)
1.90 + test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
1.91 + test(r==KErrNone);
1.92 + Buffer.SetLength(4);
1.93 + }
1.94 +
1.95 +void CloseAndDestroy(RFile &aFile)
1.96 + {
1.97 + TBuf<256> fileName;
1.98 + aFile.FullName(fileName);
1.99 + aFile.Close();
1.100 + TheFs.Delete(fileName);
1.101 + }
1.102 +
1.103 +TInt WriteNumber(RFile &aFile)
1.104 + {
1.105 + TInt r;
1.106 + Buffer[0]++;
1.107 + r = aFile.Write(0,Buffer);
1.108 + if (r==KErrNone)
1.109 + return aFile.Flush();
1.110 + else
1.111 + return r;
1.112 + }
1.113 +
1.114 +
1.115 +
1.116 +// Finds the 1st MMC drive, or checks the specified one fits requirements
1.117 +
1.118 +static TInt FindFsMMCDrive()
1.119 + {
1.120 + TDriveList driveList;
1.121 + TDriveInfo driveInfo;
1.122 + TInt r=TheFs.DriveList(driveList);
1.123 + test(r == KErrNone);
1.124 +
1.125 + TInt drvNum = DriveNumber;
1.126 + if (drvNum<0)
1.127 + drvNum = 0;
1.128 + do
1.129 + {
1.130 + if(!driveList[drvNum])
1.131 + continue; //-- skip unexisting drive
1.132 +
1.133 + test(TheFs.Drive(driveInfo, drvNum) == KErrNone);
1.134 +
1.135 + if(driveInfo.iMediaAtt&KMediaAttPageable)
1.136 + {
1.137 + // Internal MMC ?
1.138 + if (driveInfo.iType == EMediaHardDisk &&
1.139 + (driveInfo.iDriveAtt & KDriveAttInternal) &&
1.140 + (!(driveInfo.iDriveAtt & KDriveAttRemovable)))
1.141 + return (drvNum);
1.142 + }
1.143 + }
1.144 + while(DriveNumber<0 && ++drvNum<KMaxDrives);
1.145 +
1.146 + return (-1);
1.147 + }
1.148 +
1.149 +
1.150 +//
1.151 +// Writes to main area for the entire disk and reads back to verify.
1.152 +// The function is called from TestMmcAccuratcy, which will have also
1.153 +// started the background RepeatedPagingThread
1.154 +//
1.155 +void testWriteMain()
1.156 + {
1.157 + TInt i;
1.158 + TInt r;
1.159 + TInt changeCount=0;
1.160 + TInt totChangeCount=0;
1.161 + TInt cCount=0;
1.162 + TInt fullcCount=0;
1.163 + TInt oldPagedTrashCount=0;
1.164 + TInt delta=0;
1.165 + TInt high=0;
1.166 + TInt tot=0;
1.167 + TInt fullTot=0;
1.168 + TInt blockNo;
1.169 +
1.170 + SMmcStats stats;
1.171 + TInt reqPageCount=0;
1.172 + TInt reqNormalCount=0;
1.173 +
1.174 +
1.175 + TInt readSize = KBufSizeInBytes/2;
1.176 + TInt writeSize = KBufSizeInBytes/2;
1.177 +
1.178 + Buffer.SetLength(2*readSize);
1.179 +
1.180 + TPtr8 subBuf1(&Buffer[0],readSize);
1.181 + TPtrC8 subBuf2(&Buffer[readSize], readSize);
1.182 +
1.183 + test.Printf(_L("writeSize = %d\n"), writeSize);
1.184 +
1.185 +// TInt64 size = DriveCaps.iSize - (DriveCaps.iSize % readSize);
1.186 +
1.187 + for(i = 0; i<readSize; i++)
1.188 + Buffer[readSize+i] = (char)(i%100);
1.189 +
1.190 + // Zero Stats
1.191 + if(CtrlIOSupported)
1.192 + {
1.193 + TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
1.194 + test(Drive.ControlIO(KMmcGetStats,statsBuf,0) == KErrNone);
1.195 + }
1.196 +
1.197 +
1.198 + TFileName fileName = _L("?:\\f32-tst\\mmcpage.txt");
1.199 + fileName[0] = (TText) ('A'+DriveNumber);
1.200 +
1.201 +
1.202 + r = TheFs.MkDirAll(fileName);
1.203 + test(r==KErrNone || r== KErrAlreadyExists);
1.204 +// fileName += KTempFileName;
1.205 + RFile tempFile;
1.206 + r=tempFile.Replace(TheFs,fileName,EFileWrite);
1.207 + if (r!=KErrNone)
1.208 + test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
1.209 + test(r==KErrNone);
1.210 +
1.211 + TVolumeInfo volInfo;
1.212 + r = TheFs.Volume(volInfo, DriveNumber);
1.213 + test (r == KErrNone);
1.214 +
1.215 +
1.216 + TInt64 size = volInfo.iFree - (volInfo.iFree % readSize);
1.217 + TInt maxFileSize = (size > KMaxTInt) ? KMaxTInt : (TInt) size;
1.218 +
1.219 + test.Printf(_L("Volume size %ld, free %ld maxFileSize %d file '%S'\n"), volInfo.iSize, volInfo.iFree, maxFileSize, &fileName);
1.220 +
1.221 + while (((totChangeCount<Maxloops) || Forever) && (GlobError==KErrNone))
1.222 + {
1.223 +
1.224 + for(TInt pos=0;
1.225 + ((pos+writeSize) < maxFileSize) && ((totChangeCount<Maxloops) || Forever) && (GlobError==KErrNone);
1.226 + pos+=(TUint)(readSize))
1.227 + {
1.228 + blockNo=I64LOW(pos / writeSize);
1.229 + if (pos % (writeSize) == 0)
1.230 + test.Printf(_L("Block %d at %u \r"), blockNo, I64LOW(pos));
1.231 +
1.232 + //write the pattern
1.233 + r = tempFile.Write(pos,subBuf2);
1.234 + if (r != KErrNone)
1.235 + test.Printf(_L("Write failed %d"), r);
1.236 + test(r==KErrNone);
1.237 +
1.238 + //read back and verify
1.239 + r = tempFile.Read(pos,subBuf1,readSize);
1.240 + test(r==KErrNone);
1.241 +
1.242 + for(i=0;i<readSize;i++)
1.243 + if(Buffer[i]!=Buffer[readSize+i])
1.244 + {
1.245 + r = KErrCorrupt;
1.246 + break;
1.247 + }
1.248 + delta = PagedTrashCount-oldPagedTrashCount;
1.249 + cCount++;
1.250 + if (delta)
1.251 + {
1.252 + if (delta>high)
1.253 + high=delta;
1.254 + tot+=delta;
1.255 +
1.256 + oldPagedTrashCount=PagedTrashCount;
1.257 + changeCount++;
1.258 + }
1.259 + if (pos % (writeSize) == 0)
1.260 + {
1.261 +
1.262 + if ((blockNo%80==0) && (blockNo!=0))
1.263 + {
1.264 + totChangeCount+=changeCount;
1.265 + if(CtrlIOSupported)
1.266 + {
1.267 + test.Printf(_L("High%4d Avg%2d %d%% CC=%4d \n"), high, (TInt) (tot/cCount), (TInt)(changeCount*100)/cCount, totChangeCount);
1.268 +
1.269 + TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
1.270 + Drive.ControlIO(KMmcGetStats,statsBuf,0);
1.271 + test.Printf(_L("PR %d(%d%%) NR %d\n"), stats.iReqPage, (TInt) ((stats.iReqPage*100)/cCount), stats.iReqNormal);
1.272 +
1.273 + test(stats.iReqPage>0);
1.274 + reqPageCount+=stats.iReqPage;
1.275 + reqNormalCount+=stats.iReqNormal;
1.276 + }
1.277 +
1.278 + high=0;
1.279 +
1.280 + fullTot+=tot;
1.281 + tot=0;
1.282 +
1.283 + fullcCount+=cCount;
1.284 + cCount=0;
1.285 + changeCount=0;
1.286 + }
1.287 +
1.288 + }
1.289 + test(r==KErrNone);
1.290 + }
1.291 + if(CtrlIOSupported)
1.292 + {
1.293 + test.Printf(_L("Totals: Avg %2d %d%% CC=%4d \n"), fullTot/fullcCount, (TInt)(totChangeCount*100)/fullcCount, totChangeCount);
1.294 + test.Printf(_L("PR %d(%d%%) NR %d\n"), reqPageCount,(TInt) (reqPageCount*100/fullcCount), reqNormalCount );
1.295 + }
1.296 +
1.297 + // If totChangeCount does not change, mmc maybe busy waiting.
1.298 + test(totChangeCount>0);
1.299 + }
1.300 +
1.301 +
1.302 + tempFile.Close();
1.303 + r = TheFs.Delete(fileName);
1.304 + test (r == KErrNone);
1.305 +
1.306 + if (GlobError!=KErrNone)
1.307 + {
1.308 + test.Printf(_L("\nPageing failed with %x\n"), GlobError);
1.309 + test(0);
1.310 + }
1.311 + else
1.312 + test.Printf(_L("\ndone\n"));
1.313 + }
1.314 +
1.315 +
1.316 +TUint8 ReadByte(volatile TUint8* aPtr)
1.317 + {
1.318 + return *aPtr;
1.319 + }
1.320 +
1.321 +#define READ(a) ReadByte((volatile TUint8*)(a))
1.322 +
1.323 +TUint32 RandomNo =0;
1.324 +
1.325 +TUint32 Random()
1.326 + {
1.327 + RandomNo = RandomNo*69069+1;
1.328 + return RandomNo;
1.329 + }
1.330 +
1.331 +
1.332 +// Many instances of this run while testWriteMain runs,
1.333 +// to cause random background paging.
1.334 +
1.335 +LOCAL_C TInt RepeatedPagingThread(TAny* aUseTb)
1.336 + {
1.337 +// RTest test(_L("RepeatedPagingThread"));
1.338 + TBool trashBurst = EFalse;
1.339 + // This makes the paging system continually page stuff.
1.340 + // get info about a paged ROM...
1.341 +
1.342 + TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1.343 + TUint8* start = (TUint8*)romHeader+romHeader->iPageableRomStart;
1.344 + TUint size = romHeader->iPageableRomSize;
1.345 + TInt pageSize = 0;
1.346 + PagedTrashCount=1;
1.347 +
1.348 + UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0);
1.349 + RandomNo=123;
1.350 + PagedTrashCount++;
1.351 +
1.352 + while (Testing)
1.353 + {
1.354 + TInt r=UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
1.355 + if (Random() & 1)
1.356 + User::AfterHighRes(500+Random() & 2047);
1.357 +
1.358 + if (r<0)
1.359 + {
1.360 + GlobError=r;
1.361 + PagedTrashCount=99;
1.362 + return (KErrNone);
1.363 + }
1.364 + if (trashBurst)
1.365 + {
1.366 + if ((Random() & 0xf) == 0xf)
1.367 + trashBurst=EFalse;
1.368 + PagedTrashCount++;
1.369 + }
1.370 + else
1.371 + {
1.372 +
1.373 + for(TInt i=size/(pageSize); (i>0) && !trashBurst; --i)
1.374 + {
1.375 + READ(start+((TInt64(Random())*TInt64(size))>>32));
1.376 + if ((RandomNo & 0x3f) == 0x3f)
1.377 + {
1.378 + trashBurst= (TBool) aUseTb;
1.379 + }
1.380 + PagedTrashCount++;
1.381 + if (RandomNo & 1)
1.382 + User::AfterHighRes(500+Random() & 2047);
1.383 + }
1.384 + }
1.385 +
1.386 + }
1.387 + return(KErrNone);
1.388 + }
1.389 +
1.390 +
1.391 +// This starts up multiple instances of repeatedPagingThread, and runs testWriteMain.
1.392 +// After its done, it calls format, to clean up the drive.
1.393 +
1.394 +void TestMmcAccuratcy()
1.395 + {
1.396 + RThread thisThread;
1.397 + const TInt KNoThreads=10;
1.398 + TInt i;
1.399 + test.Printf(_L("Reset stats\n"));
1.400 +
1.401 + i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalResetConcurrencyInfo,(TAny*)locDriveNumber,(TAny*)EMediaPagingStatsRom);
1.402 + test(i==KErrNone || i==KErrNotSupported);
1.403 + if(i==KErrNotSupported)
1.404 + test.Printf(_L("Concurrency stats not supported on this build\n"));
1.405 + i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalResetPagingBenchmark,(TAny*)locDriveNumber,(TAny*)EMediaPagingStatsRom);
1.406 + test(i==KErrNone || i==KErrNotSupported);
1.407 + if(i==KErrNotSupported)
1.408 + test.Printf(_L("Benchmark stats not supported on this build\n"));
1.409 +
1.410 + if (Maxloops>0)
1.411 + {
1.412 + TRequestStatus stat[KNoThreads];
1.413 + // Start Read Test
1.414 + RThread repeatedPagingThread[KNoThreads];
1.415 +
1.416 + test.Next(_L("Read/Write and Page test"));
1.417 +
1.418 + for (i=0; i<KNoThreads; i++)
1.419 + {
1.420 + test(repeatedPagingThread[i].Create(_L(""),RepeatedPagingThread,KDefaultStackSize,NULL,(TAny*) ETrue)==KErrNone);
1.421 + repeatedPagingThread[i].Logon(stat[i]);
1.422 + test(stat[i]==KRequestPending);
1.423 + repeatedPagingThread[i].Resume();
1.424 + }
1.425 + // Start repeated paging.
1.426 + thisThread.SetPriority(EPriorityMore);
1.427 + Testing=ETrue;
1.428 + testWriteMain();
1.429 + Testing = 0;
1.430 + thisThread.SetPriority(EPriorityNormal);
1.431 + for (i=0; i<KNoThreads; i++)
1.432 + User::WaitForRequest(stat[i]);
1.433 +
1.434 + test.Printf(_L("Collect concurrency stats\n"));
1.435 + SMediaROMPagingConcurrencyInfo info;
1.436 + SPagingBenchmarkInfo infoBench;
1.437 + i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalGetROMConcurrencyInfo,(TAny*)locDriveNumber,&info);
1.438 + test(i==KErrNone || i==KErrNotSupported);
1.439 + TInt r=UserSvr::HalFunction(EHalGroupMedia,EMediaHalGetROMPagingBenchmark,(TAny*)locDriveNumber,&infoBench);
1.440 + test(r==KErrNone || r==KErrNotSupported);
1.441 + if(i==KErrNone)
1.442 + {
1.443 + test.Printf(_L("Media concurrency stats:\n\n"));
1.444 + test.Printf(_L("The total number of page in requests issued whilst processing other page in requests: %d\n"),info.iTotalConcurrentReqs);
1.445 + test.Printf(_L("The total number of page in requests issued with at least one queue not empty: %d\n"),info.iTotalReqIssuedNonEmptyQ);
1.446 + test.Printf(_L("The maximum number of pending page in requests in the main queue any time during this session: %d\n"),info.iMaxReqsInPending);
1.447 + test.Printf(_L("The maximum number of pending page in requests in the deferred queue any time during this session: %d\n"),info.iMaxReqsInDeferred);
1.448 + test.Printf(_L("The total number of page in requests first-time deferred during this session: %d\n"),info.iTotalFirstTimeDeferrals);
1.449 + test.Printf(_L("The total number of page in requests re-deferred during this session: %d\n"),info.iTotalReDeferrals);
1.450 + test.Printf(_L("The maximum number of deferrals of any single page in request during this session: %d\n"),info.iMaxDeferrals);
1.451 + test.Printf(_L("The total number of times the main queue was emptied when completing an asynchronous request during this session: %d\n"),info.iTotalSynchEmptiedMainQ);
1.452 + test.Printf(_L("The total number of page in requests serviced from main queue when completing an asynchronous request: %d\n"),info.iTotalSynchServicedFromMainQ);
1.453 + test.Printf(_L("The total number of page in requests deferred after being picked out of main queue when completing an asynchronous request: %d\n"),info.iTotalSynchDeferredFromMainQ);
1.454 + test.Printf(_L("The total number of times the page in DFC run with an empty main queue during this session: %d\n"),info.iTotalRunDry);
1.455 + test.Printf(_L("The total number of dry runs of paging DFC avoided during this session: %d\n"),info.iTotalDryRunsAvoided);
1.456 + }
1.457 +
1.458 + if(r==KErrNone)
1.459 + {
1.460 + TInt freq = 0;
1.461 + r = HAL::Get(HAL::EFastCounterFrequency, freq);
1.462 + if (r==KErrNone)
1.463 + {
1.464 + TReal mult = 1000000.0 / freq;
1.465 + TReal min = 0.0;
1.466 + TReal max = 0.0;
1.467 + TReal avg = 0.0;
1.468 + if (infoBench.iCount != 0)
1.469 + {
1.470 + min = infoBench.iMinTime * mult;
1.471 + max = infoBench.iMaxTime * mult;
1.472 + avg = (infoBench.iTotalTime * mult) / infoBench.iCount;
1.473 + }
1.474 + test.Printf(_L("Media benchmarks:\n\n"));
1.475 + test.Printf(_L("The total number of page in requests issued: %d\n"),infoBench.iCount);
1.476 + test.Printf(_L("The average latency of any page in request in the Media subsystem: %9.1f(us)\n"),avg);
1.477 + test.Printf(_L("The maximum latency of any page in request in the Media subsystem: %9.1f(us)\n"),max);
1.478 + test.Printf(_L("The minimum latency of any page in request in the Media subsystem: %9.1f(us)\n"),min);
1.479 + }
1.480 + }
1.481 + }
1.482 + else
1.483 + test.Next(_L("Read/Write test - Skipped!"));
1.484 +
1.485 + }
1.486 +
1.487 +
1.488 +// ************************************************************************************
1.489 +
1.490 +
1.491 +/*
1.492 +// This code causes a flush
1.493 +// It is done in a second thread to see if you really do get just
1.494 +// one deferral, with the other page requests just waiting in line.
1.495 +// (Paging is not re-entrant)
1.496 +
1.497 +TInt PagesBeingPaged=0;
1.498 +RMutex PageMutex;
1.499 +RSemaphore PageSemaphore;
1.500 +RSemaphore PageDoneSemaphore;
1.501 +
1.502 +LOCAL_C TInt CausePage(TAny*)
1.503 + {
1.504 + TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1.505 + TUint8* start = (TUint8*)romHeader+romHeader->iPageableRomStart;
1.506 + TUint size = romHeader->iPageableRomSize;
1.507 + TUint8* addr=NULL;
1.508 + TBool flush;
1.509 + while (Testing)
1.510 + {
1.511 + // Wait on semaphore
1.512 + PageSemaphore.Wait();
1.513 + flush = (PagesBeingPaged==0);
1.514 + PagesBeingPaged++;
1.515 + addr=start+((TInt64(Random())*TInt64(size))>>32);
1.516 + PageDoneSemaphore.Signal();
1.517 + if (flush)
1.518 + UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
1.519 + READ(addr);
1.520 + PageMutex.Wait();
1.521 + PagesBeingPaged--;
1.522 + PageMutex.Signal();
1.523 + }
1.524 + return 0;
1.525 + }
1.526 +*/
1.527 +
1.528 +// ************************************************************************************
1.529 +
1.530 +//
1.531 +// The gubbins that starts all the tests
1.532 +//
1.533 +// ParseCommandLine reads the arguments and sets globals accordingly.
1.534 +//
1.535 +
1.536 +void ParseCommandLine()
1.537 + {
1.538 + TBuf<32> args;
1.539 + User::CommandLine(args);
1.540 + TLex lex(args);
1.541 +
1.542 + FOREVER
1.543 + {
1.544 +
1.545 + TPtrC token=lex.NextToken();
1.546 + if(token.Length()!=0)
1.547 + {
1.548 + if ((token.Length()==2) && (token[1]==':'))
1.549 + DriveNumber=User::UpperCase(token[0])-'A';
1.550 + else if (token.Length()==1)
1.551 + {
1.552 + TChar driveLetter = User::UpperCase(token[0]);
1.553 + if ((driveLetter>='A') && (driveLetter<='Z'))
1.554 + DriveNumber=driveLetter - (TChar) 'A';
1.555 + else
1.556 + test.Printf(_L("Unknown argument '%S' was ignored.\n"), &token);
1.557 + }
1.558 + else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?")))
1.559 + {
1.560 + test.Printf(_L("\nUsage: t_mmcpaging <driveletter> [rwsoak <cc>] [defer <c>]\n'-' indicated infinity.\n\n"));
1.561 + test.Getch();
1.562 + Maxloops=0;
1.563 + }
1.564 + else if (token==_L("rwsoak"))
1.565 + {
1.566 + TPtrC val=lex.NextToken();
1.567 + TLex lexv(val);
1.568 + TInt v;
1.569 +
1.570 + if (val==_L("-"))
1.571 + Forever=ETrue;
1.572 + else
1.573 + if (lexv.Val(v)==KErrNone)
1.574 + Maxloops=v;
1.575 + else
1.576 + test.Printf(_L("Bad value for rwsoak '%S' was ignored.\n"), &val);
1.577 + }
1.578 + else if (token==_L("defer"))
1.579 + {
1.580 + TPtrC val=lex.NextToken();
1.581 + TLex lexv(val);
1.582 + TInt v;
1.583 +
1.584 + if (val==_L("-"))
1.585 + MaxDeferLoops=KMaxTInt;
1.586 + else
1.587 + if (lexv.Val(v)==KErrNone)
1.588 + MaxDeferLoops=v;
1.589 + else
1.590 + test.Printf(_L("Bad value for defer '%S' was ignored.\n"), &val);
1.591 + }
1.592 + else
1.593 + test.Printf(_L("Unknown argument '%S' was ignored.\n"), &token);
1.594 + }
1.595 + else
1.596 + break;
1.597 +
1.598 + }
1.599 + }
1.600 +
1.601 +//
1.602 +// E32Main
1.603 +//
1.604 +
1.605 +TInt E32Main()
1.606 + {
1.607 + TInt r;
1.608 + test.Title();
1.609 +
1.610 + test.Printf(_L("key\n---\n"));
1.611 + test.Printf(_L("PR: Paging requests\n"));
1.612 + test.Printf(_L("NR: Normal requests\n\n"));
1.613 +
1.614 +
1.615 + test.Start(_L("Check that the rom is paged"));
1.616 + TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1.617 + if (romHeader->iPageableRomStart==NULL)
1.618 + test.Printf(_L("Test ROM is not paged - test skipped!\r\n"));
1.619 + else
1.620 + {
1.621 + ParseCommandLine();
1.622 + test(TheFs.Connect()==KErrNone);
1.623 +
1.624 + r=UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
1.625 + if(r<0)
1.626 + {
1.627 + test.Printf(_L("DemandPagingFlushPages Error = %d\n"),r);
1.628 + test(0);
1.629 + }
1.630 +
1.631 + DriveNumber = FindFsMMCDrive();
1.632 +
1.633 + if(DriveNumber<0)
1.634 + test.Printf(_L("MMC Flash not found - test skipped!\r\n"));
1.635 + else
1.636 + {
1.637 + RFile file;
1.638 + TBuf<256> fileName;
1.639 + fileName.Append((TChar)('A'+DriveNumber));
1.640 + fileName+=_L(":\\f32-tst\\");
1.641 + TInt r=TheFs.MkDirAll(fileName);
1.642 + test(r==KErrNone || r== KErrAlreadyExists);
1.643 + fileName += _L("redglare.txt");
1.644 + r=file.Replace(TheFs,fileName,EFileWrite);
1.645 + if (r!=KErrNone)
1.646 + test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
1.647 + test(r==KErrNone);
1.648 + r=file.Write(_L8("The red glare of an ancient sun reflecting on the leaden surface of a primeval soup of decomposing matter"));
1.649 + if (r!=KErrNone)
1.650 + test.Printf(_L("Error %d: could not write to file\n"),r);
1.651 + test(r==KErrNone);
1.652 +
1.653 + test(file.Flush() == KErrNone);
1.654 +
1.655 + SBlockMapInfo info;
1.656 + TInt64 start=0;
1.657 + r=file.BlockMap(info,start, -1,ETestDebug);
1.658 + if (r!=KErrNone && r!=KErrCompletion)
1.659 + test.Printf(_L("Error %d: could not obtain block map\n"),r);
1.660 + test(r==KErrNone || r==KErrCompletion);
1.661 + locDriveNumber=info.iLocalDriveNumber;
1.662 + test.Printf(_L("Found drive: %c (MMC drive %d)\r\n"), DriveNumber+'A',locDriveNumber);
1.663 + file.Close();
1.664 +
1.665 + TDriveInfo driveInfo;
1.666 + test(TheFs.Drive(driveInfo, DriveNumber) == KErrNone);
1.667 +
1.668 + // Connect to device driver
1.669 + TBool changeFlag = EFalse;
1.670 + r = Drive.Connect(locDriveNumber,changeFlag);
1.671 + TPckg<TLocalDriveCapsV4> capsPack(DriveCaps);
1.672 + Drive.Caps(capsPack);
1.673 + test(r == KErrNone);
1.674 +
1.675 + SMmcStats stats;
1.676 + TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
1.677 + r = Drive.ControlIO(KMmcGetStats,statsBuf,0);
1.678 +
1.679 +
1.680 + if (r!=KErrNone)
1.681 + {
1.682 + test.Printf(_L("LocalDrive does not support testing IO Requests\n"));
1.683 + CtrlIOSupported=EFalse;
1.684 + }
1.685 + test.Printf(_L("LocalDrive Connected\n"));
1.686 + //
1.687 + // Run tests
1.688 + //
1.689 + TestMmcAccuratcy();
1.690 + //
1.691 + // Free device and end test program
1.692 + //
1.693 + Drive.Disconnect();
1.694 + }
1.695 + }
1.696 +
1.697 + test.End();
1.698 + return 0;
1.699 + }
1.700 +