os/kernelhwsrv/kerneltest/f32test/demandpaging/t_mmcpaging.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\mmu\t_mmcpaging.cpp
sl@0
    15
// Suite of tests specifically to test the demand paging subsystem when
sl@0
    16
// booted from MMC rather than NAND.
sl@0
    17
// 002 Read/Write and Page test
sl@0
    18
// 
sl@0
    19
//
sl@0
    20
sl@0
    21
//! @SYMTestCaseID			KBASE-T_MMCPAGING-0331
sl@0
    22
//! @SYMTestType			UT
sl@0
    23
//! @SYMPREQ				PREQ1110
sl@0
    24
//! @SYMTestCaseDesc		Demand Paging MMC Paging tests.
sl@0
    25
//! @SYMTestActions			001 Check that the rom is paged
sl@0
    26
//! @SYMTestExpectedResults All tests should pass.
sl@0
    27
//! @SYMTestPriority        High
sl@0
    28
//! @SYMTestStatus          Implemented
sl@0
    29
sl@0
    30
#include <e32test.h>
sl@0
    31
RTest test(_L("T_MMCPAGING"));
sl@0
    32
sl@0
    33
#include <e32rom.h>
sl@0
    34
#include <e32svr.h>
sl@0
    35
#include <u32hal.h>
sl@0
    36
#include <f32file.h>
sl@0
    37
#include <f32dbg.h>
sl@0
    38
#include <d32locd.h>
sl@0
    39
#include <hal.h>
sl@0
    40
#define __TEST_PAGING_MEDIA_DRIVER__
sl@0
    41
#include "mmcdp.h"
sl@0
    42
sl@0
    43
sl@0
    44
sl@0
    45
TInt DriveNumber=-1;   // Parameter - Which drive?  -1 = autodetect.
sl@0
    46
TInt locDriveNumber;
sl@0
    47
sl@0
    48
TInt MaxDeferLoops=40; // Parameter - Defer test, for how long?
sl@0
    49
TInt Maxloops=400;	   // Parameter - RW Soak, for how long?
sl@0
    50
TBool Forever=EFalse;  // Parameter - RW Soak forever?
sl@0
    51
sl@0
    52
TBool Testing=ETrue;	// Used to communicate when testing has finished between threads.
sl@0
    53
sl@0
    54
RFs TheFs;
sl@0
    55
TBusLocalDrive Drive;
sl@0
    56
TLocalDriveCapsV4 DriveCaps;
sl@0
    57
sl@0
    58
TInt PagedTrashCount=0; // Incremented by threads, is used to detect preemption.
sl@0
    59
TInt GlobError=KErrNone; // To communicate an error between threads.
sl@0
    60
TBool CtrlIOSupported=ETrue;
sl@0
    61
sl@0
    62
sl@0
    63
//const TInt KDiskSectorShift = 9;
sl@0
    64
const TInt KBufSizeInBytes = (32 * 1024);
sl@0
    65
sl@0
    66
LOCAL_D TBuf8<KBufSizeInBytes> Buffer;
sl@0
    67
sl@0
    68
sl@0
    69
sl@0
    70
// Three functions for the garbage test.
sl@0
    71
// CreateFile creates a file, and sets up the buffer for WriteNumber.
sl@0
    72
// After the code has finished writing numbers to the start,
sl@0
    73
// CloseAndDestroy cleans up.
sl@0
    74
sl@0
    75
void CreateFile(RFile &aFile,const TDesC& aFileName)
sl@0
    76
	{
sl@0
    77
	TBuf<256> fileName;	
sl@0
    78
	fileName.Append((TChar)('A'+DriveNumber));
sl@0
    79
	fileName+=_L(":\\f32-tst\\");
sl@0
    80
	TInt r=TheFs.MkDirAll(fileName);
sl@0
    81
	test(r==KErrNone || r== KErrAlreadyExists);
sl@0
    82
sl@0
    83
	fileName += aFileName;	
sl@0
    84
sl@0
    85
	r=aFile.Replace(TheFs,fileName,EFileWrite);
sl@0
    86
	if (r!=KErrNone)
sl@0
    87
		test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
sl@0
    88
	test(r==KErrNone);	
sl@0
    89
	Buffer.SetLength(4);
sl@0
    90
	}
sl@0
    91
	
sl@0
    92
void CloseAndDestroy(RFile &aFile)
sl@0
    93
	{
sl@0
    94
	TBuf<256> fileName;	
sl@0
    95
	aFile.FullName(fileName);
sl@0
    96
	aFile.Close();
sl@0
    97
	TheFs.Delete(fileName);
sl@0
    98
	}
sl@0
    99
sl@0
   100
TInt WriteNumber(RFile &aFile)
sl@0
   101
	{
sl@0
   102
	TInt r;
sl@0
   103
	Buffer[0]++;
sl@0
   104
	r = aFile.Write(0,Buffer);
sl@0
   105
	if (r==KErrNone)
sl@0
   106
		return aFile.Flush();
sl@0
   107
	else
sl@0
   108
		return r; 
sl@0
   109
	}
sl@0
   110
sl@0
   111
sl@0
   112
sl@0
   113
// Finds the 1st MMC drive, or checks the specified one fits requirements  
sl@0
   114
sl@0
   115
static TInt FindFsMMCDrive()
sl@0
   116
	{
sl@0
   117
	TDriveList driveList;
sl@0
   118
	TDriveInfo driveInfo;
sl@0
   119
	TInt r=TheFs.DriveList(driveList);
sl@0
   120
    test(r == KErrNone);
sl@0
   121
sl@0
   122
	TInt drvNum = DriveNumber;
sl@0
   123
	if (drvNum<0)
sl@0
   124
		drvNum = 0;
sl@0
   125
	do
sl@0
   126
		{
sl@0
   127
	    if(!driveList[drvNum])
sl@0
   128
	        continue;   //-- skip unexisting drive
sl@0
   129
sl@0
   130
	    test(TheFs.Drive(driveInfo, drvNum) == KErrNone);
sl@0
   131
sl@0
   132
		if(driveInfo.iMediaAtt&KMediaAttPageable)
sl@0
   133
			{
sl@0
   134
			// Internal MMC ?
sl@0
   135
			if (driveInfo.iType == EMediaHardDisk && 
sl@0
   136
				(driveInfo.iDriveAtt & KDriveAttInternal) &&
sl@0
   137
				(!(driveInfo.iDriveAtt & KDriveAttRemovable)))
sl@0
   138
				return (drvNum);
sl@0
   139
			}
sl@0
   140
		}
sl@0
   141
	while(DriveNumber<0 && ++drvNum<KMaxDrives);
sl@0
   142
sl@0
   143
	return (-1);
sl@0
   144
	}
sl@0
   145
sl@0
   146
sl@0
   147
//
sl@0
   148
// Writes to main area for the entire disk and reads back to verify.
sl@0
   149
// The function is called from TestMmcAccuratcy, which will have also
sl@0
   150
// started the background RepeatedPagingThread
sl@0
   151
//
sl@0
   152
void testWriteMain()
sl@0
   153
	{
sl@0
   154
	TInt i;
sl@0
   155
	TInt r;
sl@0
   156
	TInt changeCount=0;
sl@0
   157
	TInt totChangeCount=0;
sl@0
   158
	TInt cCount=0;
sl@0
   159
	TInt fullcCount=0;
sl@0
   160
	TInt oldPagedTrashCount=0;
sl@0
   161
	TInt delta=0;
sl@0
   162
	TInt high=0;
sl@0
   163
	TInt tot=0;
sl@0
   164
	TInt fullTot=0;
sl@0
   165
	TInt blockNo;
sl@0
   166
	
sl@0
   167
	SMmcStats stats;
sl@0
   168
	TInt reqPageCount=0;	
sl@0
   169
	TInt reqNormalCount=0;
sl@0
   170
sl@0
   171
	
sl@0
   172
	TInt readSize = KBufSizeInBytes/2;
sl@0
   173
	TInt writeSize = KBufSizeInBytes/2;
sl@0
   174
sl@0
   175
	Buffer.SetLength(2*readSize);
sl@0
   176
sl@0
   177
	TPtr8 subBuf1(&Buffer[0],readSize);
sl@0
   178
	TPtrC8 subBuf2(&Buffer[readSize], readSize);
sl@0
   179
	
sl@0
   180
	test.Printf(_L("writeSize = %d\n"), writeSize);
sl@0
   181
sl@0
   182
//	TInt64 size = DriveCaps.iSize - (DriveCaps.iSize % readSize);
sl@0
   183
	
sl@0
   184
	for(i = 0; i<readSize; i++)
sl@0
   185
		Buffer[readSize+i] = (char)(i%100);
sl@0
   186
sl@0
   187
	// Zero Stats
sl@0
   188
	if(CtrlIOSupported)
sl@0
   189
		{
sl@0
   190
		TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
sl@0
   191
	 	test(Drive.ControlIO(KMmcGetStats,statsBuf,0) == KErrNone);
sl@0
   192
		}
sl@0
   193
sl@0
   194
sl@0
   195
	TFileName fileName = _L("?:\\f32-tst\\mmcpage.txt");
sl@0
   196
	fileName[0] = (TText) ('A'+DriveNumber);
sl@0
   197
sl@0
   198
sl@0
   199
	r = TheFs.MkDirAll(fileName);
sl@0
   200
	test(r==KErrNone || r== KErrAlreadyExists);
sl@0
   201
//	fileName += KTempFileName;	
sl@0
   202
	RFile tempFile;
sl@0
   203
	r=tempFile.Replace(TheFs,fileName,EFileWrite);
sl@0
   204
	if (r!=KErrNone)
sl@0
   205
		test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
sl@0
   206
	test(r==KErrNone);	
sl@0
   207
sl@0
   208
	TVolumeInfo volInfo;
sl@0
   209
	r = TheFs.Volume(volInfo, DriveNumber);
sl@0
   210
	test (r == KErrNone);
sl@0
   211
sl@0
   212
	
sl@0
   213
	TInt64 size = volInfo.iFree - (volInfo.iFree % readSize);
sl@0
   214
	TInt maxFileSize = (size > KMaxTInt) ? KMaxTInt : (TInt) size;
sl@0
   215
	
sl@0
   216
	test.Printf(_L("Volume size %ld, free %ld maxFileSize %d file '%S'\n"), volInfo.iSize, volInfo.iFree, maxFileSize, &fileName);
sl@0
   217
	
sl@0
   218
	while (((totChangeCount<Maxloops) || Forever) && (GlobError==KErrNone))
sl@0
   219
		{
sl@0
   220
		
sl@0
   221
		for(TInt pos=0;
sl@0
   222
			((pos+writeSize) < maxFileSize) && ((totChangeCount<Maxloops) || Forever) && (GlobError==KErrNone);
sl@0
   223
			pos+=(TUint)(readSize))
sl@0
   224
			{
sl@0
   225
			blockNo=I64LOW(pos / writeSize);
sl@0
   226
			if (pos % (writeSize) == 0)
sl@0
   227
				test.Printf(_L("Block %d at %u \r"), blockNo, I64LOW(pos));
sl@0
   228
sl@0
   229
			//write the pattern
sl@0
   230
			r = tempFile.Write(pos,subBuf2);
sl@0
   231
			if (r != KErrNone)
sl@0
   232
				test.Printf(_L("Write failed %d"), r);
sl@0
   233
			test(r==KErrNone);
sl@0
   234
sl@0
   235
			//read back and verify
sl@0
   236
			r = tempFile.Read(pos,subBuf1,readSize);
sl@0
   237
			test(r==KErrNone);
sl@0
   238
sl@0
   239
			for(i=0;i<readSize;i++)
sl@0
   240
				if(Buffer[i]!=Buffer[readSize+i])
sl@0
   241
					{
sl@0
   242
					r = KErrCorrupt;
sl@0
   243
					break;
sl@0
   244
					}
sl@0
   245
			delta = PagedTrashCount-oldPagedTrashCount;
sl@0
   246
			cCount++;
sl@0
   247
			if (delta)
sl@0
   248
				{	
sl@0
   249
				if (delta>high)
sl@0
   250
					high=delta;
sl@0
   251
				tot+=delta;
sl@0
   252
				
sl@0
   253
				oldPagedTrashCount=PagedTrashCount;
sl@0
   254
				changeCount++;
sl@0
   255
				}
sl@0
   256
			if (pos % (writeSize) == 0)
sl@0
   257
				{				
sl@0
   258
sl@0
   259
				if ((blockNo%80==0) && (blockNo!=0))
sl@0
   260
					{
sl@0
   261
					totChangeCount+=changeCount;
sl@0
   262
					if(CtrlIOSupported)
sl@0
   263
						{
sl@0
   264
						test.Printf(_L("High%4d Avg%2d %d%% CC=%4d \n"), high, (TInt) (tot/cCount), (TInt)(changeCount*100)/cCount, totChangeCount);
sl@0
   265
						
sl@0
   266
						TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
sl@0
   267
						Drive.ControlIO(KMmcGetStats,statsBuf,0);
sl@0
   268
						test.Printf(_L("PR %d(%d%%) NR %d\n"), stats.iReqPage, (TInt) ((stats.iReqPage*100)/cCount), stats.iReqNormal);
sl@0
   269
sl@0
   270
						test(stats.iReqPage>0);
sl@0
   271
				 		reqPageCount+=stats.iReqPage;			 	
sl@0
   272
				 		reqNormalCount+=stats.iReqNormal;			 	
sl@0
   273
						}
sl@0
   274
sl@0
   275
					high=0;
sl@0
   276
					
sl@0
   277
					fullTot+=tot;
sl@0
   278
					tot=0;
sl@0
   279
					
sl@0
   280
					fullcCount+=cCount;
sl@0
   281
					cCount=0;
sl@0
   282
					changeCount=0;
sl@0
   283
					}
sl@0
   284
						
sl@0
   285
				}
sl@0
   286
			test(r==KErrNone);
sl@0
   287
			}
sl@0
   288
		if(CtrlIOSupported)
sl@0
   289
			{
sl@0
   290
			test.Printf(_L("Totals: Avg %2d %d%% CC=%4d \n"), fullTot/fullcCount, (TInt)(totChangeCount*100)/fullcCount, totChangeCount);
sl@0
   291
			test.Printf(_L("PR %d(%d%%) NR %d\n"), reqPageCount,(TInt) (reqPageCount*100/fullcCount), reqNormalCount );
sl@0
   292
			}
sl@0
   293
sl@0
   294
		// If totChangeCount does not change, mmc maybe busy waiting.
sl@0
   295
		test(totChangeCount>0);
sl@0
   296
		}
sl@0
   297
sl@0
   298
sl@0
   299
	tempFile.Close();
sl@0
   300
	r = TheFs.Delete(fileName);
sl@0
   301
	test (r == KErrNone);
sl@0
   302
	
sl@0
   303
	if (GlobError!=KErrNone)
sl@0
   304
		{
sl@0
   305
		test.Printf(_L("\nPageing failed with %x\n"), GlobError);
sl@0
   306
		test(0);
sl@0
   307
		}
sl@0
   308
	else
sl@0
   309
		test.Printf(_L("\ndone\n"));
sl@0
   310
	}
sl@0
   311
sl@0
   312
sl@0
   313
TUint8 ReadByte(volatile TUint8* aPtr)
sl@0
   314
	{
sl@0
   315
	return *aPtr;
sl@0
   316
	}
sl@0
   317
sl@0
   318
#define READ(a) ReadByte((volatile TUint8*)(a))
sl@0
   319
sl@0
   320
TUint32 RandomNo =0;
sl@0
   321
sl@0
   322
TUint32 Random()
sl@0
   323
	{
sl@0
   324
	RandomNo = RandomNo*69069+1;
sl@0
   325
	return RandomNo;
sl@0
   326
	}
sl@0
   327
sl@0
   328
sl@0
   329
// Many instances of this run while testWriteMain runs,
sl@0
   330
// to cause random background paging.
sl@0
   331
sl@0
   332
LOCAL_C TInt RepeatedPagingThread(TAny* aUseTb)
sl@0
   333
	{
sl@0
   334
//	RTest test(_L("RepeatedPagingThread"));
sl@0
   335
	TBool trashBurst = EFalse;
sl@0
   336
	// This makes the paging system continually page stuff.
sl@0
   337
	// get info about a paged ROM...
sl@0
   338
	
sl@0
   339
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
   340
	TUint8* start = (TUint8*)romHeader+romHeader->iPageableRomStart;
sl@0
   341
	TUint size = romHeader->iPageableRomSize;
sl@0
   342
	TInt pageSize = 0;
sl@0
   343
	PagedTrashCount=1;
sl@0
   344
sl@0
   345
	UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0);
sl@0
   346
	RandomNo=123;
sl@0
   347
	PagedTrashCount++;
sl@0
   348
sl@0
   349
	while (Testing)
sl@0
   350
		{
sl@0
   351
		TInt r=UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
sl@0
   352
		if (Random() & 1)
sl@0
   353
			User::AfterHighRes(500+Random() & 2047);
sl@0
   354
sl@0
   355
		if (r<0)
sl@0
   356
			{
sl@0
   357
			GlobError=r;
sl@0
   358
			PagedTrashCount=99;
sl@0
   359
			return (KErrNone);
sl@0
   360
			}
sl@0
   361
		if (trashBurst)
sl@0
   362
			{
sl@0
   363
			if ((Random() & 0xf) == 0xf)
sl@0
   364
				trashBurst=EFalse;
sl@0
   365
			PagedTrashCount++;
sl@0
   366
			}
sl@0
   367
		else 
sl@0
   368
			{
sl@0
   369
			
sl@0
   370
			for(TInt i=size/(pageSize); (i>0) && !trashBurst; --i)
sl@0
   371
				{
sl@0
   372
				READ(start+((TInt64(Random())*TInt64(size))>>32));
sl@0
   373
				if ((RandomNo & 0x3f) == 0x3f)
sl@0
   374
					{
sl@0
   375
					trashBurst= (TBool) aUseTb;
sl@0
   376
					}
sl@0
   377
				PagedTrashCount++;
sl@0
   378
				if (RandomNo & 1)
sl@0
   379
					User::AfterHighRes(500+Random() & 2047);
sl@0
   380
				}
sl@0
   381
			}
sl@0
   382
	
sl@0
   383
		}
sl@0
   384
	return(KErrNone);
sl@0
   385
	}
sl@0
   386
	
sl@0
   387
sl@0
   388
// This starts up multiple instances of repeatedPagingThread, and runs testWriteMain.
sl@0
   389
// After its done, it calls format, to clean up the drive.
sl@0
   390
sl@0
   391
void TestMmcAccuratcy()
sl@0
   392
	{
sl@0
   393
	RThread thisThread;
sl@0
   394
	const TInt KNoThreads=10;
sl@0
   395
	TInt i;
sl@0
   396
	test.Printf(_L("Reset stats\n"));
sl@0
   397
sl@0
   398
	i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalResetConcurrencyInfo,(TAny*)locDriveNumber,(TAny*)EMediaPagingStatsRom);
sl@0
   399
	test(i==KErrNone || i==KErrNotSupported);
sl@0
   400
	if(i==KErrNotSupported)
sl@0
   401
		test.Printf(_L("Concurrency stats not supported on this build\n"));
sl@0
   402
	i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalResetPagingBenchmark,(TAny*)locDriveNumber,(TAny*)EMediaPagingStatsRom);
sl@0
   403
	test(i==KErrNone || i==KErrNotSupported);
sl@0
   404
	if(i==KErrNotSupported)
sl@0
   405
		test.Printf(_L("Benchmark stats not supported on this build\n"));
sl@0
   406
sl@0
   407
	if (Maxloops>0)
sl@0
   408
		{
sl@0
   409
		TRequestStatus stat[KNoThreads];
sl@0
   410
		// Start Read Test
sl@0
   411
		RThread repeatedPagingThread[KNoThreads];
sl@0
   412
		
sl@0
   413
		test.Next(_L("Read/Write and Page test"));
sl@0
   414
sl@0
   415
		for (i=0; i<KNoThreads; i++)
sl@0
   416
			{
sl@0
   417
			test(repeatedPagingThread[i].Create(_L(""),RepeatedPagingThread,KDefaultStackSize,NULL,(TAny*) ETrue)==KErrNone);
sl@0
   418
			repeatedPagingThread[i].Logon(stat[i]);
sl@0
   419
			test(stat[i]==KRequestPending);	
sl@0
   420
			repeatedPagingThread[i].Resume();
sl@0
   421
			}
sl@0
   422
		// Start repeated paging.
sl@0
   423
		thisThread.SetPriority(EPriorityMore);
sl@0
   424
		Testing=ETrue;
sl@0
   425
		testWriteMain();
sl@0
   426
		Testing = 0;
sl@0
   427
		thisThread.SetPriority(EPriorityNormal);
sl@0
   428
		for (i=0; i<KNoThreads; i++)
sl@0
   429
	 		User::WaitForRequest(stat[i]);
sl@0
   430
	 		
sl@0
   431
		test.Printf(_L("Collect concurrency stats\n"));
sl@0
   432
		SMediaROMPagingConcurrencyInfo info;
sl@0
   433
		SPagingBenchmarkInfo infoBench;
sl@0
   434
		i=UserSvr::HalFunction(EHalGroupMedia,EMediaHalGetROMConcurrencyInfo,(TAny*)locDriveNumber,&info);
sl@0
   435
		test(i==KErrNone || i==KErrNotSupported);
sl@0
   436
		TInt r=UserSvr::HalFunction(EHalGroupMedia,EMediaHalGetROMPagingBenchmark,(TAny*)locDriveNumber,&infoBench);
sl@0
   437
		test(r==KErrNone || r==KErrNotSupported);
sl@0
   438
		if(i==KErrNone)
sl@0
   439
			{
sl@0
   440
			test.Printf(_L("Media concurrency stats:\n\n"));
sl@0
   441
			test.Printf(_L("The total number of page in requests issued whilst processing other page in requests: %d\n"),info.iTotalConcurrentReqs);
sl@0
   442
			test.Printf(_L("The total number of page in requests issued with at least one queue not empty: %d\n"),info.iTotalReqIssuedNonEmptyQ);
sl@0
   443
			test.Printf(_L("The maximum number of pending page in requests in the main queue any time during this session: %d\n"),info.iMaxReqsInPending);
sl@0
   444
			test.Printf(_L("The maximum number of pending page in requests in the deferred queue any time during this session: %d\n"),info.iMaxReqsInDeferred);
sl@0
   445
			test.Printf(_L("The total number of page in requests first-time deferred during this session: %d\n"),info.iTotalFirstTimeDeferrals);
sl@0
   446
			test.Printf(_L("The total number of page in requests re-deferred during this session: %d\n"),info.iTotalReDeferrals);
sl@0
   447
			test.Printf(_L("The maximum number of deferrals of any single page in request during this session: %d\n"),info.iMaxDeferrals);
sl@0
   448
			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);
sl@0
   449
			test.Printf(_L("The total number of page in requests serviced from main queue when completing an asynchronous request: %d\n"),info.iTotalSynchServicedFromMainQ);
sl@0
   450
			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);
sl@0
   451
			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);
sl@0
   452
			test.Printf(_L("The total number of dry runs of paging DFC avoided during this session: %d\n"),info.iTotalDryRunsAvoided);
sl@0
   453
			}
sl@0
   454
sl@0
   455
		if(r==KErrNone)
sl@0
   456
			{
sl@0
   457
			TInt freq = 0;
sl@0
   458
			r = HAL::Get(HAL::EFastCounterFrequency, freq);
sl@0
   459
			if (r==KErrNone)
sl@0
   460
				{
sl@0
   461
				TReal mult = 1000000.0 / freq;
sl@0
   462
				TReal min = 0.0;
sl@0
   463
				TReal max = 0.0;
sl@0
   464
				TReal avg = 0.0;
sl@0
   465
				if (infoBench.iCount != 0)
sl@0
   466
					{
sl@0
   467
					min = infoBench.iMinTime * mult;
sl@0
   468
					max = infoBench.iMaxTime * mult;
sl@0
   469
					avg = (infoBench.iTotalTime * mult) / infoBench.iCount;
sl@0
   470
					}
sl@0
   471
				test.Printf(_L("Media benchmarks:\n\n"));
sl@0
   472
				test.Printf(_L("The total number of page in requests issued: %d\n"),infoBench.iCount);
sl@0
   473
				test.Printf(_L("The average latency of any page in request in the Media subsystem: %9.1f(us)\n"),avg);
sl@0
   474
				test.Printf(_L("The maximum latency of any page in request in the Media subsystem: %9.1f(us)\n"),max);
sl@0
   475
				test.Printf(_L("The minimum latency of any page in request in the Media subsystem: %9.1f(us)\n"),min);
sl@0
   476
				}
sl@0
   477
			}
sl@0
   478
		}
sl@0
   479
		else
sl@0
   480
			test.Next(_L("Read/Write test - Skipped!"));
sl@0
   481
sl@0
   482
	}
sl@0
   483
	
sl@0
   484
sl@0
   485
// ************************************************************************************
sl@0
   486
	
sl@0
   487
	
sl@0
   488
/*
sl@0
   489
// This code causes a flush
sl@0
   490
// It is done in a second thread to see if you really do get just
sl@0
   491
// one deferral, with the other page requests just waiting in line.
sl@0
   492
// (Paging is not re-entrant)
sl@0
   493
sl@0
   494
TInt PagesBeingPaged=0;
sl@0
   495
RMutex PageMutex;
sl@0
   496
RSemaphore PageSemaphore;
sl@0
   497
RSemaphore PageDoneSemaphore;
sl@0
   498
 
sl@0
   499
LOCAL_C TInt CausePage(TAny*)
sl@0
   500
	{	
sl@0
   501
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
   502
	TUint8* start = (TUint8*)romHeader+romHeader->iPageableRomStart;
sl@0
   503
	TUint size = romHeader->iPageableRomSize;
sl@0
   504
	TUint8* addr=NULL;
sl@0
   505
	TBool flush;
sl@0
   506
	while (Testing)
sl@0
   507
		{
sl@0
   508
		// Wait on semaphore
sl@0
   509
		PageSemaphore.Wait();
sl@0
   510
		flush = (PagesBeingPaged==0);
sl@0
   511
		PagesBeingPaged++;
sl@0
   512
		addr=start+((TInt64(Random())*TInt64(size))>>32);	
sl@0
   513
		PageDoneSemaphore.Signal();
sl@0
   514
		if (flush)
sl@0
   515
			UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
sl@0
   516
		READ(addr);
sl@0
   517
		PageMutex.Wait();
sl@0
   518
		PagesBeingPaged--;
sl@0
   519
		PageMutex.Signal();
sl@0
   520
		}
sl@0
   521
	return 0;
sl@0
   522
	}
sl@0
   523
*/
sl@0
   524
sl@0
   525
// ************************************************************************************
sl@0
   526
sl@0
   527
//
sl@0
   528
// The gubbins that starts all the tests
sl@0
   529
//
sl@0
   530
// ParseCommandLine reads the arguments and sets globals accordingly.
sl@0
   531
//
sl@0
   532
sl@0
   533
void ParseCommandLine()
sl@0
   534
	{
sl@0
   535
	TBuf<32> args;
sl@0
   536
	User::CommandLine(args);
sl@0
   537
	TLex lex(args);
sl@0
   538
	
sl@0
   539
	FOREVER
sl@0
   540
		{
sl@0
   541
		
sl@0
   542
		TPtrC token=lex.NextToken();
sl@0
   543
		if(token.Length()!=0)
sl@0
   544
			{
sl@0
   545
			if ((token.Length()==2) && (token[1]==':'))
sl@0
   546
				DriveNumber=User::UpperCase(token[0])-'A';
sl@0
   547
			else if (token.Length()==1)
sl@0
   548
				{
sl@0
   549
				TChar driveLetter = User::UpperCase(token[0]); 
sl@0
   550
				if ((driveLetter>='A') && (driveLetter<='Z'))
sl@0
   551
					DriveNumber=driveLetter - (TChar) 'A';
sl@0
   552
				else 
sl@0
   553
					test.Printf(_L("Unknown argument '%S' was ignored.\n"), &token);
sl@0
   554
				}
sl@0
   555
			else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?")))
sl@0
   556
				{
sl@0
   557
				test.Printf(_L("\nUsage:  t_mmcpaging <driveletter> [rwsoak <cc>] [defer <c>]\n'-' indicated infinity.\n\n"));
sl@0
   558
				test.Getch();
sl@0
   559
				Maxloops=0;
sl@0
   560
				}
sl@0
   561
			else if (token==_L("rwsoak"))
sl@0
   562
				{
sl@0
   563
				TPtrC val=lex.NextToken();
sl@0
   564
				TLex lexv(val);
sl@0
   565
				TInt v;
sl@0
   566
sl@0
   567
				if (val==_L("-"))
sl@0
   568
					Forever=ETrue;
sl@0
   569
				else
sl@0
   570
					if (lexv.Val(v)==KErrNone)
sl@0
   571
						Maxloops=v;
sl@0
   572
					else
sl@0
   573
						test.Printf(_L("Bad value for rwsoak '%S' was ignored.\n"), &val);
sl@0
   574
				}
sl@0
   575
			else if (token==_L("defer"))
sl@0
   576
				{
sl@0
   577
				TPtrC val=lex.NextToken();
sl@0
   578
				TLex lexv(val);
sl@0
   579
				TInt v;
sl@0
   580
sl@0
   581
				if (val==_L("-"))
sl@0
   582
					MaxDeferLoops=KMaxTInt;
sl@0
   583
				else
sl@0
   584
					if (lexv.Val(v)==KErrNone)
sl@0
   585
						MaxDeferLoops=v;
sl@0
   586
					else
sl@0
   587
						test.Printf(_L("Bad value for defer '%S' was ignored.\n"), &val);
sl@0
   588
				}	
sl@0
   589
			else
sl@0
   590
				test.Printf(_L("Unknown argument '%S' was ignored.\n"), &token);
sl@0
   591
			}
sl@0
   592
		else
sl@0
   593
			break;
sl@0
   594
		
sl@0
   595
		}
sl@0
   596
	}
sl@0
   597
sl@0
   598
//
sl@0
   599
// E32Main
sl@0
   600
//
sl@0
   601
sl@0
   602
TInt E32Main()
sl@0
   603
	{
sl@0
   604
	TInt r;
sl@0
   605
	test.Title();
sl@0
   606
sl@0
   607
	test.Printf(_L("key\n---\n"));	
sl@0
   608
	test.Printf(_L("PR: Paging requests\n"));
sl@0
   609
	test.Printf(_L("NR: Normal requests\n\n"));
sl@0
   610
sl@0
   611
	
sl@0
   612
	test.Start(_L("Check that the rom is paged"));
sl@0
   613
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
   614
	if (romHeader->iPageableRomStart==NULL)
sl@0
   615
		test.Printf(_L("Test ROM is not paged - test skipped!\r\n"));
sl@0
   616
	else
sl@0
   617
		{
sl@0
   618
		ParseCommandLine();	
sl@0
   619
		test(TheFs.Connect()==KErrNone);
sl@0
   620
sl@0
   621
		r=UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0);
sl@0
   622
		if(r<0)
sl@0
   623
			{
sl@0
   624
			test.Printf(_L("DemandPagingFlushPages Error = %d\n"),r);
sl@0
   625
			test(0);
sl@0
   626
			}
sl@0
   627
			
sl@0
   628
		DriveNumber = FindFsMMCDrive();	
sl@0
   629
		
sl@0
   630
		if(DriveNumber<0)
sl@0
   631
			test.Printf(_L("MMC Flash not found - test skipped!\r\n"));
sl@0
   632
		else
sl@0
   633
			{
sl@0
   634
			RFile file;
sl@0
   635
			TBuf<256> fileName;	
sl@0
   636
			fileName.Append((TChar)('A'+DriveNumber));
sl@0
   637
			fileName+=_L(":\\f32-tst\\");
sl@0
   638
			TInt r=TheFs.MkDirAll(fileName);
sl@0
   639
			test(r==KErrNone || r== KErrAlreadyExists);
sl@0
   640
			fileName += _L("redglare.txt");
sl@0
   641
			r=file.Replace(TheFs,fileName,EFileWrite);
sl@0
   642
			if (r!=KErrNone)
sl@0
   643
				test.Printf(_L("Error %d: file '%S' could not be created\n"),r,&fileName);
sl@0
   644
			test(r==KErrNone);
sl@0
   645
			r=file.Write(_L8("The red glare of an ancient sun reflecting on the leaden surface of a primeval soup of decomposing matter"));
sl@0
   646
			if (r!=KErrNone)
sl@0
   647
				test.Printf(_L("Error %d: could not write to file\n"),r);
sl@0
   648
			test(r==KErrNone);
sl@0
   649
sl@0
   650
			test(file.Flush() == KErrNone);
sl@0
   651
sl@0
   652
			SBlockMapInfo info;
sl@0
   653
			TInt64 start=0;
sl@0
   654
			r=file.BlockMap(info,start, -1,ETestDebug);
sl@0
   655
			if (r!=KErrNone && r!=KErrCompletion)
sl@0
   656
				test.Printf(_L("Error %d: could not obtain block map\n"),r);
sl@0
   657
			test(r==KErrNone || r==KErrCompletion);
sl@0
   658
			locDriveNumber=info.iLocalDriveNumber;
sl@0
   659
			test.Printf(_L("Found drive: %c (MMC drive %d)\r\n"), DriveNumber+'A',locDriveNumber);
sl@0
   660
			file.Close();
sl@0
   661
			
sl@0
   662
			TDriveInfo driveInfo;
sl@0
   663
			test(TheFs.Drive(driveInfo, DriveNumber) == KErrNone);
sl@0
   664
sl@0
   665
			// Connect to device driver
sl@0
   666
			TBool changeFlag = EFalse;
sl@0
   667
			r = Drive.Connect(locDriveNumber,changeFlag);
sl@0
   668
			TPckg<TLocalDriveCapsV4>	capsPack(DriveCaps);
sl@0
   669
			Drive.Caps(capsPack);
sl@0
   670
			test(r == KErrNone);
sl@0
   671
sl@0
   672
			SMmcStats stats;
sl@0
   673
			TPtr8 statsBuf((TUint8*) &stats, sizeof(stats));
sl@0
   674
			r = Drive.ControlIO(KMmcGetStats,statsBuf,0);
sl@0
   675
sl@0
   676
sl@0
   677
			if (r!=KErrNone)
sl@0
   678
				{
sl@0
   679
				test.Printf(_L("LocalDrive does not support testing IO Requests\n"));
sl@0
   680
				CtrlIOSupported=EFalse;
sl@0
   681
				}
sl@0
   682
			test.Printf(_L("LocalDrive Connected\n"));
sl@0
   683
			//
sl@0
   684
			// Run tests	
sl@0
   685
			//
sl@0
   686
			TestMmcAccuratcy();
sl@0
   687
			// 
sl@0
   688
			// Free device and end test program
sl@0
   689
			//
sl@0
   690
			Drive.Disconnect();
sl@0
   691
			}	
sl@0
   692
		}
sl@0
   693
		
sl@0
   694
	test.End();
sl@0
   695
	return 0;
sl@0
   696
	}
sl@0
   697