os/kernelhwsrv/kerneltest/e32test/lffs/tf_erase.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2003-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 // Tests erasing of Flash. Does not test suspending (see TF_SUSPEND)
    15 // 
    16 //
    17 
    18 #include <e32std.h>
    19 #include <e32std_private.h>
    20 #include <e32svr.h>
    21 #include <e32test.h>
    22 #include "randgen.h"
    23 #include "user_config.h"
    24 
    25 RTest test( _L("TF_ERASE") );
    26 
    27 
    28 class CEraseTest : public CBase
    29 	{
    30 	public:
    31 		~CEraseTest();
    32 
    33 		void CreateL();
    34 
    35 		void DoTest();
    36 
    37 	private:
    38 		void DoSimpleTest();
    39 		void DoSimpleTest2();
    40 		void DoPseudoRandomTest();
    41 		void DoRangeTest();
    42 
    43 		TInt EraseOneBlock( TInt aBlockNumber );
    44 		TInt ZeroFillBlock( TInt aBlockNumber );
    45 		TBool ValidateBlock( TInt aBlockNumber, TUint32 aFillWord );
    46 
    47 
    48 	private:
    49 		TBusLocalDrive	iDrive;
    50 		TBool			iDriveOpened;
    51 
    52 		TInt			iFlashSize;
    53 		TInt			iBlockSize;
    54 		TInt			iBlockCount;
    55 
    56 		TBuf8<512>		iReadBuffer;
    57 
    58 	};
    59 
    60 
    61 CEraseTest::~CEraseTest()
    62 	{
    63 	if( iDriveOpened )
    64 		{
    65 		iDrive.Disconnect();
    66 		}
    67 	}
    68 
    69 
    70 
    71 void CEraseTest::CreateL()
    72 	{
    73 	//
    74 	// Load the device drivers
    75 	//
    76 #ifndef SKIP_PDD_LOAD
    77 	test.Printf( _L("Loading %S\n"), &KLfsDriverName );
    78 	r = User::LoadPhysicalDevice( KLfsDriverName );
    79 	test( KErrNone == r || KErrAlreadyExists == r );
    80 #endif
    81 
    82 #ifdef UNMOUNT_DRIVE
    83 	RFs fs;
    84 	test( KErrNone == fs.Connect() );
    85 #if 0
    86 	// XXX - not eka2
    87 	test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
    88 #endif
    89 	TFullName name;
    90 	fs.FileSystemName( name, KLffsLogicalDriveNumber );
    91 	if( name.Length() > 0 )
    92 		{
    93 		test.Printf( _L("Unmounting drive") );
    94 		test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
    95 		User::After( 2000000 );
    96 		test.Printf( _L("Drive unmounted") );
    97 		}
    98 	fs.Close();
    99 #endif
   100 
   101 	//
   102 	// Open a TBusLogicalDevice to drive
   103 	//
   104 	test.Printf( _L("Opening media channel\n") );
   105 	static TBool changedFlag = EFalse;
   106 	User::LeaveIfError( iDrive.Connect( KDriveNumber, changedFlag ) );
   107 	iDriveOpened = ETrue;
   108 
   109 	//
   110 	// Get size of Flash drive, block size, block count
   111 	//
   112 	TLocalDriveCapsV2Buf info;
   113     iDrive.Caps(info);
   114 	iFlashSize = I64LOW(info().iSize);
   115 	iBlockSize = info().iEraseBlockSize;
   116 	iBlockCount = iFlashSize / iBlockSize;
   117 
   118 	test.Printf( _L("Flash size is 0x%x bytes\n"), iFlashSize );
   119 	test.Printf( _L("Block size is 0x%x bytes\n"), iBlockSize );
   120 	test.Printf( _L("Block count is %d\n"), iBlockCount );
   121 
   122 	test.Printf( _L("CreateL complete\n") );
   123 	}
   124 
   125 
   126 void CEraseTest::DoTest()
   127 	//
   128 	// Main test dispatcher
   129 	//
   130 	{
   131 	test.Next( _L("Starting tests...") );
   132 	DoSimpleTest();
   133 	DoSimpleTest2();
   134 	DoPseudoRandomTest();
   135 	DoRangeTest();
   136 	}
   137 
   138 
   139 TInt CEraseTest::EraseOneBlock( TInt aBlockNumber )
   140 	//
   141 	// Erases block aBlockNumber on Flash
   142 	//
   143 	{
   144 	TInt blockBaseOffset = aBlockNumber * iBlockSize;
   145 
   146 	test.Printf( _L("Erasing block %d (offs=0x%x)\n"), aBlockNumber, blockBaseOffset );
   147 	
   148 	TInt r = iDrive.Format( blockBaseOffset, iBlockSize );
   149 
   150 	test.Printf( _L("... Format returned %d\n"), r );
   151 	return r;
   152 	}
   153 
   154 
   155 TBool CEraseTest::ValidateBlock( TInt aBlockNumber, TUint32 aFillWord )
   156 	//
   157 	// Checks that every word in block aBlockNumber has the value aFillWord
   158 	//
   159 	{
   160 	TUint offset = aBlockNumber * iBlockSize;
   161 	test.Printf( _L("Validating block %d (offs=0x%x)\n"), aBlockNumber, offset );
   162 	
   163 	TBool failed = EFalse;
   164 	const TInt readBufLen = iReadBuffer.MaxLength();
   165 
   166 	for( TInt len = iBlockSize; len > 0 && !failed ;)
   167 		{
   168 		TInt r = iDrive.Read( offset, readBufLen, iReadBuffer );
   169 		if( r != KErrNone )
   170 			{
   171 			test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset );
   172 			test( KErrNone == r );
   173 			}
   174 		test( iReadBuffer.Length() == readBufLen );
   175 
   176 		TUint32* p = (TUint32*)iReadBuffer.Ptr();
   177 		for( TInt i = 0; i < readBufLen; i += 4 )
   178 			{
   179 			if( aFillWord != *p )
   180 				{
   181 				failed = ETrue;
   182 				test.Printf( _L("... FAILED: word @ offs=0x%x, read=0x%x, expected=0x%x\n"), 
   183 								offset+i, p[0], aFillWord );
   184 				break;
   185 				}
   186 			++p;
   187 			}
   188 		offset += readBufLen;
   189 		len -= readBufLen;
   190 		}
   191 	
   192 	return !failed;
   193 	}
   194 
   195 
   196 TInt CEraseTest::ZeroFillBlock( TInt aBlockNumber )
   197 	//
   198 	// Zero-fills an entire block
   199 	// The requires that writing works (so as a side-effect performs a
   200 	// very basic test of writing)
   201 	//
   202 	{
   203 	test.Printf( _L("Zero-filling block %d\n"), aBlockNumber );
   204 
   205 	//
   206 	// Create a buffer full of zeros
   207 	//
   208 	const TInt KZeroBufSize = 512;
   209 
   210 	TBuf8<KZeroBufSize> buf;
   211 	buf.FillZ( buf.MaxLength() );
   212 
   213 	//
   214 	// Write the data out to the Flash
   215 	//
   216 	TInt writeCount = iBlockSize / KZeroBufSize;
   217 	TInt r = KErrNone;
   218 	TInt blockBaseOffset = aBlockNumber * iBlockSize;
   219 	for( ; (writeCount > 0) && (KErrNone == r); writeCount-- )
   220 		{
   221 		r = iDrive.Write( blockBaseOffset, buf );
   222 		if( r != KErrNone )
   223 			{
   224 			test.Printf( _L("... FAIL: write failed (%d) at offset 0x%x\n"), r, blockBaseOffset );
   225 			}
   226 		blockBaseOffset += KZeroBufSize;
   227 		}
   228 
   229 	return r;
   230 	}
   231 
   232 
   233 void CEraseTest::DoSimpleTest()
   234 	//
   235 	// Simple erase test. This just zero-fills and then erases each block in turn
   236 	//
   237 	{
   238 	test.Next( _L("Simple test: erases each block in turn\n") );
   239 
   240 	for( TInt block = 0; block < iBlockCount; block++ )
   241 		{
   242 		test( KErrNone == ZeroFillBlock( block ) );
   243 		test( ValidateBlock( block, 0 ) );
   244 		test( KErrNone == EraseOneBlock( block ) );
   245 		test( ValidateBlock( block, 0xFFFFFFFF ) );
   246 		}
   247 	}
   248 
   249 void CEraseTest::DoSimpleTest2()
   250 	//
   251 	// Another simple erase test.
   252 	// This time we zero-fill all blocks first, then erase them all
   253 	//
   254 	{
   255 	test.Next( _L("Simple test2 : zero-fills whole Flash, then erases all blocks\n") );
   256 
   257 	for( TInt block = 0; block < iBlockCount; block++ )
   258 		{
   259 		test( KErrNone == ZeroFillBlock( block ) );
   260 		test( ValidateBlock( block, 0 ) );
   261 		}
   262 
   263 	for( TInt block = 0; block < iBlockCount; block++ )
   264 		{
   265 		test( KErrNone == EraseOneBlock( block ) );
   266 		test( ValidateBlock( block, 0xFFFFFFFF ) );
   267 		}
   268 	}
   269 
   270 
   271 
   272 void CEraseTest::DoPseudoRandomTest()
   273 	//
   274 	// Erases the blocks in pseudo-random order, zero-filling first
   275 	//
   276 	{
   277 	test.Next( _L("Test random erase order\n") );
   278 
   279 	TRandomGenerator random;
   280 #if 0
   281 	random.SetSeed( TInt64(0x1020466E, 0x3F9C0C00) );
   282 #else
   283 	random.SetSeed( 0x1020466E );
   284 #endif
   285 
   286 	for( TInt count = 0; count < 50; count++ )
   287 		{
   288 		TUint block = random.Next() % iBlockCount;
   289 		test( KErrNone == ZeroFillBlock( block ) );
   290 
   291 		test( ValidateBlock( block, 0 ) );
   292 
   293 		test( KErrNone == EraseOneBlock( block ) );
   294 
   295 		test( ValidateBlock( block, 0xFFFFFFFF ) );
   296 		}
   297 	}
   298 
   299 void CEraseTest::DoRangeTest()
   300 	//
   301 	// Simple erase test. This just zero-fills and then erases each block in turn
   302 	//
   303 	{
   304 	test.Next( _L("Range test: check that erase only affects erased block\n") );
   305 
   306 	//
   307 	// Pre-fill all blocks with zero
   308 	//
   309 	test.Printf( _L("Pre-zeroing blocks\n") );
   310 	for( TInt block = 0; block < iBlockCount; block++ )
   311 		{
   312 		test( KErrNone == ZeroFillBlock( block ) );
   313 		test( ValidateBlock( block, 0 ) );
   314 		}
   315 
   316 	//
   317 	// The test is to erase a block. Check it is erased and all
   318 	// other blocks are still zeros. Then we re-zero the block just
   319 	// erased and repeat test with next block
   320 	//
   321 	test.Printf( _L("Now testing erase...\n") );
   322 	for( TInt eraseBlock = 0; eraseBlock < iBlockCount; eraseBlock++ )
   323 		{
   324 		test( KErrNone == EraseOneBlock( eraseBlock ) );
   325 		test( ValidateBlock( eraseBlock, 0xFFFFFFFF ) );
   326 		
   327 		// check all other blocks are still zero
   328 		for( TInt j = 0; j < iBlockCount; j++ )
   329 			{
   330 			if( j != eraseBlock )
   331 				{
   332 				// test if not the one we just erased
   333 				test( ValidateBlock( j, 0 ) );
   334 				}
   335 			}
   336 
   337 		// Now zero-fill the block we just erased and move to next block
   338 		test( KErrNone == ZeroFillBlock( eraseBlock ) );
   339 		test( ValidateBlock( eraseBlock, 0 ) );
   340 		}
   341 
   342 	}
   343 
   344 
   345 TInt E32Main()
   346 	{
   347 	test.Title();
   348 	test.Start(_L("Testing media erase operations"));
   349 
   350 	CEraseTest eraseTest;
   351 	TRAPD( ret, eraseTest.CreateL() );
   352 	if( KErrNone == ret )
   353 		{
   354 		eraseTest.DoTest();
   355 		}
   356 
   357 	test.End();
   358 	return KErrNone;
   359 	}