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