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