os/kernelhwsrv/kerneltest/e32test/mmu/d_memorytest.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) 2004-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\d_memorytest.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <kernel/kern_priv.h>
sl@0
    19
#include <kernel/cache.h>
sl@0
    20
#include "d_memorytest.h"
sl@0
    21
sl@0
    22
//
sl@0
    23
// Class definitions
sl@0
    24
//
sl@0
    25
sl@0
    26
class DMemoryTestFactory : public DLogicalDevice
sl@0
    27
	{
sl@0
    28
public:
sl@0
    29
	~DMemoryTestFactory();
sl@0
    30
	virtual TInt Install();
sl@0
    31
	virtual void GetCaps(TDes8& aDes) const;
sl@0
    32
	virtual TInt Create(DLogicalChannelBase*& aChannel);
sl@0
    33
	};
sl@0
    34
sl@0
    35
class DMemoryTestChannel : public DLogicalChannelBase
sl@0
    36
	{
sl@0
    37
public:
sl@0
    38
	DMemoryTestChannel();
sl@0
    39
	~DMemoryTestChannel();
sl@0
    40
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    41
	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
sl@0
    42
private:
sl@0
    43
	TInt TestAllocZerosMemory();
sl@0
    44
	TInt TestReAllocZerosMemory();
sl@0
    45
	TInt AllocTest1();
sl@0
    46
	TInt ReAllocTest1();
sl@0
    47
	TInt ReAllocTest2(TUint8*& mem1, TUint8*& mem2, TUint8*& mem3);
sl@0
    48
	TInt AllocPhysTest(TUint32 aIters, TUint32 aSize); 
sl@0
    49
	TInt AllocPhysTest1(TUint32 aIters, TUint32 aSize); 
sl@0
    50
public:
sl@0
    51
	DMemoryTestFactory*	iFactory;
sl@0
    52
	TVirtualPinObject* iVirtualPinObject;
sl@0
    53
	
sl@0
    54
	struct{
sl@0
    55
		TPhysicalPinObject* iObject;
sl@0
    56
		TPhysAddr iPhysAddr;
sl@0
    57
		TPhysAddr iPhysPageList[KUCPageCount];
sl@0
    58
		TUint 	iColour;
sl@0
    59
		TUint32 iActualMapAttr;
sl@0
    60
		}iPhysicalPinning;
sl@0
    61
sl@0
    62
	struct{
sl@0
    63
		TKernelMapObject* iObject;
sl@0
    64
		TPhysAddr iPhysPageList[KUCPageCount];
sl@0
    65
		TLinAddr iLinAddr;
sl@0
    66
		}iKernelMapping;
sl@0
    67
sl@0
    68
	TUint32 iPageSize;
sl@0
    69
	};
sl@0
    70
sl@0
    71
//
sl@0
    72
// DMemoryTestFactory
sl@0
    73
//
sl@0
    74
sl@0
    75
TInt DMemoryTestFactory::Install()
sl@0
    76
	{
sl@0
    77
	return SetName(&KMemoryTestLddName);
sl@0
    78
	}
sl@0
    79
sl@0
    80
DMemoryTestFactory::~DMemoryTestFactory()
sl@0
    81
	{
sl@0
    82
	}
sl@0
    83
sl@0
    84
void DMemoryTestFactory::GetCaps(TDes8& /*aDes*/) const
sl@0
    85
	{
sl@0
    86
	// Not used but required as DLogicalDevice::GetCaps is pure virtual
sl@0
    87
	}
sl@0
    88
sl@0
    89
TInt DMemoryTestFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
    90
	{
sl@0
    91
	aChannel = NULL;
sl@0
    92
	DMemoryTestChannel* channel=new DMemoryTestChannel;
sl@0
    93
	if(!channel)
sl@0
    94
		return KErrNoMemory;
sl@0
    95
	channel->iFactory = this;
sl@0
    96
	aChannel = channel;
sl@0
    97
	return KErrNone;
sl@0
    98
	}
sl@0
    99
sl@0
   100
DECLARE_STANDARD_LDD()
sl@0
   101
	{
sl@0
   102
	return new DMemoryTestFactory;
sl@0
   103
	}
sl@0
   104
sl@0
   105
//
sl@0
   106
// DMemoryTestChannel
sl@0
   107
//
sl@0
   108
sl@0
   109
TInt DMemoryTestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
sl@0
   110
	{
sl@0
   111
	return KErrNone;
sl@0
   112
	}
sl@0
   113
sl@0
   114
DMemoryTestChannel::DMemoryTestChannel()
sl@0
   115
	{
sl@0
   116
	iPageSize = Kern::RoundToPageSize(1);
sl@0
   117
	}
sl@0
   118
sl@0
   119
DMemoryTestChannel::~DMemoryTestChannel()
sl@0
   120
	{
sl@0
   121
	Kern::DestroyVirtualPinObject(iVirtualPinObject);
sl@0
   122
	}
sl@0
   123
sl@0
   124
sl@0
   125
TInt DMemoryTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   126
	{
sl@0
   127
	TInt r=KErrNotSupported;
sl@0
   128
sl@0
   129
	switch(aFunction)
sl@0
   130
		{
sl@0
   131
	case RMemoryTestLdd::EReadWriteMemory:
sl@0
   132
	case RMemoryTestLdd::EReadMemory:
sl@0
   133
	case RMemoryTestLdd::EWriteMemory:
sl@0
   134
		{
sl@0
   135
		TUint32 value=(TUint32)a2;
sl@0
   136
#ifdef _DEBUG
sl@0
   137
		TInt debugMask = Kern::CurrentThread().iDebugMask;
sl@0
   138
		Kern::CurrentThread().iDebugMask = debugMask&~(1<<KPANIC);
sl@0
   139
#endif
sl@0
   140
		XTRAP(r, XT_DEFAULT,
sl@0
   141
			if(aFunction==RMemoryTestLdd::EReadWriteMemory)
sl@0
   142
				{
sl@0
   143
				kumemget32(&value,a1,4);
sl@0
   144
				kumemput32(a1,&value,4);
sl@0
   145
				}
sl@0
   146
			else if(aFunction==RMemoryTestLdd::EReadMemory)
sl@0
   147
				kumemget32(&value,a1,4);
sl@0
   148
			else if(aFunction==RMemoryTestLdd::EWriteMemory)
sl@0
   149
				kumemput32(a1,&value,4);
sl@0
   150
			);
sl@0
   151
#ifdef _DEBUG
sl@0
   152
		Kern::CurrentThread().iDebugMask = debugMask;
sl@0
   153
#endif
sl@0
   154
		if(aFunction==RMemoryTestLdd::EReadMemory)
sl@0
   155
			kumemput32(a2,&value,sizeof(value));
sl@0
   156
sl@0
   157
		return r;
sl@0
   158
		}
sl@0
   159
sl@0
   160
	case RMemoryTestLdd::ETestAllocZerosMemory:
sl@0
   161
	case RMemoryTestLdd::ETestReAllocZerosMemory:
sl@0
   162
		{
sl@0
   163
		NKern::ThreadEnterCS();		
sl@0
   164
		TInt r;
sl@0
   165
		if (aFunction==RMemoryTestLdd::ETestAllocZerosMemory)
sl@0
   166
			r=TestAllocZerosMemory();
sl@0
   167
		else
sl@0
   168
			r=TestReAllocZerosMemory();
sl@0
   169
		NKern::ThreadLeaveCS();
sl@0
   170
		return r;
sl@0
   171
		}
sl@0
   172
sl@0
   173
	case RMemoryTestLdd::ETestAllocPhysTest:
sl@0
   174
		{
sl@0
   175
		NKern::ThreadEnterCS();
sl@0
   176
		r=AllocPhysTest((TUint32)a1,(TUint32)a2);
sl@0
   177
		NKern::ThreadLeaveCS();
sl@0
   178
		return r;
sl@0
   179
		}
sl@0
   180
sl@0
   181
	case RMemoryTestLdd::ETestAllocPhysTest1:
sl@0
   182
		{
sl@0
   183
		NKern::ThreadEnterCS();
sl@0
   184
		r=AllocPhysTest1((TUint32)a1,(TUint32)a2);
sl@0
   185
		NKern::ThreadLeaveCS();
sl@0
   186
		return r;
sl@0
   187
		}
sl@0
   188
sl@0
   189
	case RMemoryTestLdd::ECreateVirtualPinObject:
sl@0
   190
		{
sl@0
   191
		NKern::ThreadEnterCS();
sl@0
   192
		r=Kern::CreateVirtualPinObject(iVirtualPinObject);
sl@0
   193
		NKern::ThreadLeaveCS();
sl@0
   194
		return r;
sl@0
   195
		}
sl@0
   196
		
sl@0
   197
	case RMemoryTestLdd::EPinVirtualMemory:
sl@0
   198
		return Kern::PinVirtualMemory(iVirtualPinObject, (TLinAddr)a1, (TUint)a2);
sl@0
   199
sl@0
   200
	case RMemoryTestLdd::EUnpinVirtualMemory:
sl@0
   201
		Kern::UnpinVirtualMemory(iVirtualPinObject);
sl@0
   202
		return KErrNone;
sl@0
   203
sl@0
   204
	case RMemoryTestLdd::EDestroyVirtualPinObject:
sl@0
   205
		{
sl@0
   206
		NKern::ThreadEnterCS();
sl@0
   207
		Kern::DestroyVirtualPinObject(iVirtualPinObject);
sl@0
   208
		NKern::ThreadLeaveCS();
sl@0
   209
		return KErrNone;
sl@0
   210
		}
sl@0
   211
sl@0
   212
	case RMemoryTestLdd::ESetPanicTrace:
sl@0
   213
		{
sl@0
   214
		TBool old = false;
sl@0
   215
#ifdef _DEBUG
sl@0
   216
		DThread& thread = Kern::CurrentThread();
sl@0
   217
		TInt debugMask = thread.iDebugMask;
sl@0
   218
		if(debugMask&(1<<KPANIC))
sl@0
   219
			old = true;
sl@0
   220
		if(a1)
sl@0
   221
			debugMask |= (1<<KPANIC);
sl@0
   222
		else
sl@0
   223
			debugMask &= ~(1<<KPANIC);
sl@0
   224
		thread.iDebugMask = debugMask;
sl@0
   225
#endif
sl@0
   226
		return old;
sl@0
   227
		}
sl@0
   228
sl@0
   229
	case RMemoryTestLdd::EIsMemoryPresent:
sl@0
   230
#ifndef __WINS__
sl@0
   231
		return Epoc::LinearToPhysical((TLinAddr)a1) != KPhysAddrInvalid;
sl@0
   232
#else
sl@0
   233
		Kern::PanicCurrentThread(_L("IsMemoryPresent should not be used on the emulator"), KErrNotSupported);
sl@0
   234
		return KErrNotSupported;
sl@0
   235
#endif
sl@0
   236
sl@0
   237
	case RMemoryTestLdd::ECreatePhysicalPinObject:
sl@0
   238
		{
sl@0
   239
		NKern::ThreadEnterCS();
sl@0
   240
		r=Kern::CreatePhysicalPinObject(iPhysicalPinning.iObject);
sl@0
   241
		NKern::ThreadLeaveCS();
sl@0
   242
		return r;
sl@0
   243
		}
sl@0
   244
sl@0
   245
	case RMemoryTestLdd::EPinPhysicalMemory:
sl@0
   246
		return Kern::PinPhysicalMemory(iPhysicalPinning.iObject, (TLinAddr)a1, (TUint)a2, EFalse, iPhysicalPinning.iPhysAddr,
sl@0
   247
							iPhysicalPinning.iPhysPageList, iPhysicalPinning.iActualMapAttr, iPhysicalPinning.iColour, NULL);
sl@0
   248
sl@0
   249
	case RMemoryTestLdd::EPinPhysicalMemoryRO:
sl@0
   250
		return Kern::PinPhysicalMemory(iPhysicalPinning.iObject, (TLinAddr)a1, (TUint)a2, ETrue, iPhysicalPinning.iPhysAddr,
sl@0
   251
							iPhysicalPinning.iPhysPageList, iPhysicalPinning.iActualMapAttr, iPhysicalPinning.iColour, NULL);
sl@0
   252
sl@0
   253
	case RMemoryTestLdd::ECheckPageList:
sl@0
   254
		{
sl@0
   255
#ifdef __WINS__
sl@0
   256
		return KErrNotSupported;
sl@0
   257
#else
sl@0
   258
		TInt i;
sl@0
   259
		for (i=0;i<KUCPageCount; i++)
sl@0
   260
			{
sl@0
   261
			TPhysAddr addr = Epoc::LinearToPhysical((TLinAddr)a1 + i*iPageSize);
sl@0
   262
			if (addr==KPhysAddrInvalid) 				 return KErrGeneral;
sl@0
   263
			if (addr!=iPhysicalPinning.iPhysPageList[i]) return KErrNotFound;
sl@0
   264
			}
sl@0
   265
		return KErrNone;
sl@0
   266
#endif		
sl@0
   267
		}
sl@0
   268
sl@0
   269
	case RMemoryTestLdd::ESyncPinnedPhysicalMemory:
sl@0
   270
		return Cache::SyncPhysicalMemoryBeforeDmaWrite(iPhysicalPinning.iPhysPageList,
sl@0
   271
									iPhysicalPinning.iColour, (TUint)a1, (TUint)a2, iPhysicalPinning.iActualMapAttr);
sl@0
   272
sl@0
   273
	case RMemoryTestLdd::EMovePinnedPhysicalMemory:
sl@0
   274
		{
sl@0
   275
#ifdef __WINS__
sl@0
   276
		return KErrNotSupported;
sl@0
   277
#else
sl@0
   278
		TPhysAddr newPage;
sl@0
   279
		NKern::ThreadEnterCS();
sl@0
   280
		r = Epoc::MovePhysicalPage(iPhysicalPinning.iPhysPageList[(TUint)a1], newPage);		
sl@0
   281
		NKern::ThreadLeaveCS();
sl@0
   282
		return r;
sl@0
   283
#endif
sl@0
   284
		}
sl@0
   285
sl@0
   286
	case RMemoryTestLdd::EInvalidatePinnedPhysicalMemory:
sl@0
   287
		{
sl@0
   288
		r = Cache::SyncPhysicalMemoryBeforeDmaRead(iPhysicalPinning.iPhysPageList,
sl@0
   289
									iPhysicalPinning.iColour, (TUint)a1, (TUint)a2, iPhysicalPinning.iActualMapAttr);
sl@0
   290
		if (r==KErrNone)
sl@0
   291
			r = Cache::SyncPhysicalMemoryAfterDmaRead(iPhysicalPinning.iPhysPageList,
sl@0
   292
										iPhysicalPinning.iColour, (TUint)a1, (TUint)a2, iPhysicalPinning.iActualMapAttr);
sl@0
   293
		return r;	
sl@0
   294
		}
sl@0
   295
		
sl@0
   296
	case RMemoryTestLdd::EUnpinPhysicalMemory:
sl@0
   297
		return Kern::UnpinPhysicalMemory(iPhysicalPinning.iObject);
sl@0
   298
sl@0
   299
	case RMemoryTestLdd::EDestroyPhysicalPinObject:
sl@0
   300
		{
sl@0
   301
		NKern::ThreadEnterCS();
sl@0
   302
		r=Kern::DestroyPhysicalPinObject(iPhysicalPinning.iObject);
sl@0
   303
		NKern::ThreadLeaveCS();
sl@0
   304
		return r;
sl@0
   305
		}
sl@0
   306
sl@0
   307
	case RMemoryTestLdd::EPinKernelPhysicalMemory:
sl@0
   308
		{
sl@0
   309
		TPhysicalPinObject* pinObject;
sl@0
   310
		TPhysAddr aAddress;
sl@0
   311
		TPhysAddr aPages[2];
sl@0
   312
		TUint aColour=0;
sl@0
   313
		TUint32 actualMemAttr;
sl@0
   314
		NKern::ThreadEnterCS();
sl@0
   315
		Kern::CreatePhysicalPinObject(pinObject);
sl@0
   316
		r = Kern::PinPhysicalMemory(pinObject, (TLinAddr)&aAddress, 4, EFalse, aAddress, aPages, actualMemAttr, aColour, NULL);
sl@0
   317
		Cache::SyncPhysicalMemoryBeforeDmaWrite(aPages, aColour, 10, 30, actualMemAttr);
sl@0
   318
		Kern::UnpinPhysicalMemory(pinObject);
sl@0
   319
		Kern::DestroyPhysicalPinObject(pinObject);
sl@0
   320
		NKern::ThreadLeaveCS();
sl@0
   321
		return r;
sl@0
   322
		}
sl@0
   323
sl@0
   324
	case RMemoryTestLdd::ECreateKernelMapObject:
sl@0
   325
		{
sl@0
   326
		NKern::ThreadEnterCS();
sl@0
   327
		r=Kern::CreateKernelMapObject(iKernelMapping.iObject, (TUint)a1);
sl@0
   328
		NKern::ThreadLeaveCS();
sl@0
   329
		return r;
sl@0
   330
		}
sl@0
   331
sl@0
   332
	case RMemoryTestLdd::EKernelMapMemory:
sl@0
   333
		return Kern::MapAndPinMemory(	iKernelMapping.iObject, NULL, (TLinAddr)a1, (TUint)a2, 0,
sl@0
   334
										iKernelMapping.iLinAddr, iKernelMapping.iPhysPageList);
sl@0
   335
sl@0
   336
	case RMemoryTestLdd::EKernelMapMemoryRO:
sl@0
   337
		return Kern::MapAndPinMemory(	iKernelMapping.iObject, NULL, (TLinAddr)a1, (TUint)a2, Kern::EKernelMap_ReadOnly,
sl@0
   338
										iKernelMapping.iLinAddr, iKernelMapping.iPhysPageList);
sl@0
   339
sl@0
   340
	case RMemoryTestLdd::EKernelMapMemoryInvalid:
sl@0
   341
		return Kern::MapAndPinMemory(	iKernelMapping.iObject, NULL, (TLinAddr)a1, (TUint)a2, (TUint)~Kern::EKernelMap_ReadOnly,
sl@0
   342
										iKernelMapping.iLinAddr, iKernelMapping.iPhysPageList);
sl@0
   343
sl@0
   344
	case RMemoryTestLdd::EKernelMapCheckPageList:
sl@0
   345
		{
sl@0
   346
#ifdef __WINS__
sl@0
   347
		return KErrNotSupported;
sl@0
   348
#else
sl@0
   349
		TUint i = 0;
sl@0
   350
		for (; i < (TUint)KUCPageCount; i++)
sl@0
   351
			{
sl@0
   352
			// Compare the user side address to physical addresses
sl@0
   353
			TPhysAddr addr = Epoc::LinearToPhysical((TLinAddr)a1 + i*iPageSize);
sl@0
   354
			if (addr == KPhysAddrInvalid) 				 
sl@0
   355
				return KErrGeneral;
sl@0
   356
			if (addr != iKernelMapping.iPhysPageList[i]) 
sl@0
   357
				return KErrNotFound;
sl@0
   358
			// Compare the kernel side address to physical addresses
sl@0
   359
			addr = Epoc::LinearToPhysical(iKernelMapping.iLinAddr + i*iPageSize);
sl@0
   360
			if (addr == KPhysAddrInvalid) 				 
sl@0
   361
				return KErrGeneral;
sl@0
   362
			if (addr != iKernelMapping.iPhysPageList[i])
sl@0
   363
				return KErrNotFound;
sl@0
   364
			}
sl@0
   365
		return KErrNone;
sl@0
   366
#endif		
sl@0
   367
		}
sl@0
   368
sl@0
   369
	case RMemoryTestLdd::EKernelMapSyncMemory:
sl@0
   370
		Cache::SyncMemoryBeforeDmaWrite(iKernelMapping.iLinAddr, KUCPageCount*iPageSize);
sl@0
   371
		return KErrNone;
sl@0
   372
sl@0
   373
	case RMemoryTestLdd::EKernelMapInvalidateMemory:
sl@0
   374
		{
sl@0
   375
		Cache::SyncMemoryBeforeDmaRead(iKernelMapping.iLinAddr, KUCPageCount*iPageSize);
sl@0
   376
		Cache::SyncMemoryAfterDmaRead(iKernelMapping.iLinAddr, KUCPageCount*iPageSize);
sl@0
   377
		return KErrNone;
sl@0
   378
		}
sl@0
   379
sl@0
   380
	case RMemoryTestLdd::EKernelMapMoveMemory:
sl@0
   381
		{
sl@0
   382
#ifdef __WINS__
sl@0
   383
		return KErrNotSupported;
sl@0
   384
#else
sl@0
   385
		TPhysAddr newPage;
sl@0
   386
		NKern::ThreadEnterCS();
sl@0
   387
		r = Epoc::MovePhysicalPage(iKernelMapping.iPhysPageList[(TUint)a1], newPage);		
sl@0
   388
		NKern::ThreadLeaveCS();
sl@0
   389
		return r;
sl@0
   390
#endif
sl@0
   391
		}
sl@0
   392
sl@0
   393
	case RMemoryTestLdd::EKernelMapReadModifyMemory:
sl@0
   394
		{
sl@0
   395
		TUint8* p = (TUint8*)iKernelMapping.iLinAddr;
sl@0
   396
		// Verify the contents of the data when accessed via the kernel mapping.
sl@0
   397
		TUint i = 0;
sl@0
   398
		for (i = 0; i < KUCPageCount*iPageSize; i++)
sl@0
   399
			{
sl@0
   400
			if (*p++ != (TUint8)i)
sl@0
   401
				return KErrCorrupt;
sl@0
   402
			}
sl@0
   403
		// Modify the data via the kernel mapping.
sl@0
   404
		p = (TUint8*)iKernelMapping.iLinAddr;
sl@0
   405
		for (i = 0; i < KUCPageCount*iPageSize; i++)
sl@0
   406
			{
sl@0
   407
			*p++ = (TUint8)(i + 1);
sl@0
   408
			}
sl@0
   409
		return KErrNone;
sl@0
   410
		}
sl@0
   411
		
sl@0
   412
	case RMemoryTestLdd::EKernelUnmapMemory:
sl@0
   413
		Kern::UnmapAndUnpinMemory(iKernelMapping.iObject);
sl@0
   414
		return KErrNone;
sl@0
   415
sl@0
   416
	case RMemoryTestLdd::EDestroyKernelMapObject:
sl@0
   417
		{
sl@0
   418
		NKern::ThreadEnterCS();
sl@0
   419
		Kern::DestroyKernelMapObject(iKernelMapping.iObject);
sl@0
   420
		NKern::ThreadLeaveCS();
sl@0
   421
		return KErrNone;
sl@0
   422
		}
sl@0
   423
		
sl@0
   424
	default:
sl@0
   425
		return KErrNotSupported;
sl@0
   426
		}
sl@0
   427
	}
sl@0
   428
sl@0
   429
// Fail a test by returning an error code indicating the problem
sl@0
   430
#define FAIL_ALLOC_TEST(testIndex, byteOffset, unexepectedValue) \
sl@0
   431
	err = ((testIndex) << 16) | ((byteOffset) << 8) | (unexepectedValue)
sl@0
   432
sl@0
   433
TInt DMemoryTestChannel::TestAllocZerosMemory()
sl@0
   434
	{
sl@0
   435
	TInt count = 100;
sl@0
   436
	TInt r = KErrNotSupported;
sl@0
   437
sl@0
   438
	do	{	//re-try up to 100 times if memory conditions are not correct
sl@0
   439
		r=AllocTest1();
sl@0
   440
		} while(((r == KErrNoMemory)||(r == KErrUnknown)) && --count);
sl@0
   441
sl@0
   442
	return r;
sl@0
   443
	}
sl@0
   444
sl@0
   445
TInt DMemoryTestChannel::AllocTest1()
sl@0
   446
	{
sl@0
   447
	const TInt KSize = 256;
sl@0
   448
	TInt err = KErrNone;
sl@0
   449
	TUint8* mem1 = (TUint8*)Kern::Alloc(KSize);
sl@0
   450
	if (!mem1)
sl@0
   451
		return KErrNoMemory;
sl@0
   452
	memset(mem1, KSize, 0xff);
sl@0
   453
	Kern::Free(mem1);
sl@0
   454
	TUint8* mem2 = (TUint8*)Kern::Alloc(KSize);
sl@0
   455
	if (!mem2)
sl@0
   456
		return KErrNoMemory;
sl@0
   457
	if (mem1 != mem2)
sl@0
   458
		err = KErrUnknown;	// Test inconclusive, can retry
sl@0
   459
	for (TInt i = 0 ; i<KSize && err==KErrNone; ++i)
sl@0
   460
		{
sl@0
   461
		if (mem2[i] != 0)
sl@0
   462
			FAIL_ALLOC_TEST(1, i, mem2[i]);
sl@0
   463
		}
sl@0
   464
	Kern::Free(mem2);
sl@0
   465
sl@0
   466
	return err;
sl@0
   467
	}
sl@0
   468
sl@0
   469
TInt DMemoryTestChannel::TestReAllocZerosMemory()
sl@0
   470
	{
sl@0
   471
	TInt count = 100;
sl@0
   472
	TInt r = KErrNotSupported;
sl@0
   473
sl@0
   474
	do	{	//re-try up to 100 times if memory conditions are not correct
sl@0
   475
		r=ReAllocTest1();
sl@0
   476
		} while(((r == KErrNoMemory)||(r == KErrUnknown)) && --count);
sl@0
   477
sl@0
   478
	if (r!=KErrNone)	
sl@0
   479
		return r;
sl@0
   480
sl@0
   481
	count = 100;
sl@0
   482
	do	{	//	re-try up to 100 times if memory conditions are not correct
sl@0
   483
		TUint8* mem1 = NULL;
sl@0
   484
		TUint8* mem2 = NULL;
sl@0
   485
		TUint8* mem3 = NULL;
sl@0
   486
		r=ReAllocTest2(mem1, mem2, mem3);
sl@0
   487
		if (mem1)
sl@0
   488
			Kern::Free(mem1);
sl@0
   489
		if (mem2)
sl@0
   490
			Kern::Free(mem2);
sl@0
   491
		if (mem3)
sl@0
   492
			Kern::Free(mem3);
sl@0
   493
		} while(((r == KErrNoMemory)||(r == KErrUnknown)) && --count);
sl@0
   494
	
sl@0
   495
	return r;
sl@0
   496
	}
sl@0
   497
sl@0
   498
// The actual size of the block allocated given the size requested.
sl@0
   499
#define ALIGNED_SIZE(aReqSize) (_ALIGN_UP(aReqSize + RHeap::EAllocCellSize, RHeap::ECellAlignment) - RHeap::EAllocCellSize)
sl@0
   500
sl@0
   501
// We only acllocate blocks where the size we get is the size we ask for - this
sl@0
   502
// just makes testing easier.
sl@0
   503
const TInt KSize = ALIGNED_SIZE(200), KHalfSize = ALIGNED_SIZE(100), KSmallSize = ALIGNED_SIZE(50);
sl@0
   504
sl@0
   505
TInt DMemoryTestChannel::ReAllocTest1()
sl@0
   506
	{
sl@0
   507
	// Test case where cell grows
sl@0
   508
	// 
sl@0
   509
	// Expected heap layout:
sl@0
   510
	//   1: [-mem1-------]
sl@0
   511
	//   2: [-mem1-]
sl@0
   512
	//   3: [-mem1-------]
sl@0
   513
sl@0
   514
	TInt err = KErrNone;
sl@0
   515
	TUint8* mem1 = (TUint8*)Kern::Alloc(KSize); // 1
sl@0
   516
	if (!mem1)
sl@0
   517
		return KErrNoMemory;
sl@0
   518
	memset(mem1, 0xff, KSize);
sl@0
   519
	TUint8* mem2 = (TUint8*)Kern::ReAlloc(mem1, KHalfSize); // 2
sl@0
   520
	if (mem1 != mem2)
sl@0
   521
		{
sl@0
   522
		mem1 = 0;
sl@0
   523
		Kern::Free(mem2);
sl@0
   524
		return KErrUnknown; // Don't expect move on shrink
sl@0
   525
		}
sl@0
   526
	mem2 = (TUint8*)Kern::ReAlloc(mem1, KSize); // 3
sl@0
   527
	if (mem1 != mem2)
sl@0
   528
		{
sl@0
   529
		mem1 = 0;
sl@0
   530
		Kern::Free(mem2);
sl@0
   531
		return KErrUnknown; // Expect growth into original area
sl@0
   532
		}
sl@0
   533
	
sl@0
   534
	TInt i;
sl@0
   535
	for (i = 0 ; i<KHalfSize && err==KErrNone; ++i)
sl@0
   536
		{
sl@0
   537
		if (mem1[i] != 0xff)
sl@0
   538
			FAIL_ALLOC_TEST(2, i, mem1[i]);
sl@0
   539
		}
sl@0
   540
	for (i = KHalfSize ; i<KSize && err==KErrNone; ++i)
sl@0
   541
		{
sl@0
   542
		if (mem1[i] != 0)
sl@0
   543
			FAIL_ALLOC_TEST(3, i, mem1[i]);
sl@0
   544
		}
sl@0
   545
sl@0
   546
	Kern::Free(mem1);
sl@0
   547
	return err;
sl@0
   548
	}
sl@0
   549
sl@0
   550
TInt DMemoryTestChannel::ReAllocTest2(TUint8*& mem1, TUint8*& mem2, TUint8*& mem3)
sl@0
   551
	{	
sl@0
   552
	// Test case where cell is moved
sl@0
   553
	// 
sl@0
   554
	// Expected heap layout:
sl@0
   555
	//   1: [ mem1 ]
sl@0
   556
	//   2: [ mem1 ] [ mem2 ]
sl@0
   557
	//   3: [ mem1 ] [ mem2 ] [ mem3       ]
sl@0
   558
	//   4:          [ mem2 ] [ mem1       ] 
sl@0
   559
sl@0
   560
	mem1 = (TUint8*)Kern::Alloc(KSmallSize); // 1
sl@0
   561
	if (!mem1)
sl@0
   562
		return KErrNoMemory;
sl@0
   563
	memset(mem1, 0xff, KSmallSize);	
sl@0
   564
	mem2 = (TUint8*)Kern::Alloc(KSmallSize); // 2
sl@0
   565
	if (!mem2)
sl@0
   566
		return KErrNoMemory;
sl@0
   567
	if (mem2 <= (mem1 + KSmallSize))
sl@0
   568
		return KErrUnknown;	// Expect mem2 higher than mem1
sl@0
   569
	memset(mem2, 0xee, KSmallSize);		
sl@0
   570
	mem3 = (TUint8*)Kern::Alloc(KSize); // 3
sl@0
   571
	if (!mem3)
sl@0
   572
		return KErrNoMemory;
sl@0
   573
	if (mem3 <= (mem2 + KSmallSize))
sl@0
   574
		return KErrUnknown;	// Expect mem3 higher than mem2
sl@0
   575
	memset(mem3, 0xdd, KSize);
sl@0
   576
	Kern::Free(mem3);
sl@0
   577
	TUint8* m3 = mem3;
sl@0
   578
	mem3 = NULL;
sl@0
   579
	TUint8* mem4 = (TUint8*)Kern::ReAlloc(mem1, KSize); // 4
sl@0
   580
	if (!mem4)
sl@0
   581
		return KErrNoMemory;	
sl@0
   582
	if (mem4 == mem1)
sl@0
   583
		return KErrUnknown; // Expect move on grow
sl@0
   584
	mem1=mem4;
sl@0
   585
	if (mem4 != m3)
sl@0
   586
		return KErrUnknown; // Expect to realloc to use old mem3 space
sl@0
   587
	
sl@0
   588
	TInt i;
sl@0
   589
	TInt err = KErrNone;
sl@0
   590
	for (i = 0 ; i<KSmallSize && err==KErrNone; ++i)
sl@0
   591
		{
sl@0
   592
		if (mem1[i] != 0xff)
sl@0
   593
			FAIL_ALLOC_TEST(4, i, mem1[i]);
sl@0
   594
		}
sl@0
   595
	for (i = KSmallSize; i<KSize && err==KErrNone; ++i)
sl@0
   596
		{
sl@0
   597
		if (mem1[i] != 0)
sl@0
   598
			FAIL_ALLOC_TEST(5, i, mem1[i]);
sl@0
   599
		}
sl@0
   600
sl@0
   601
	return err;
sl@0
   602
	}
sl@0
   603
sl@0
   604
#ifdef __EPOC32__
sl@0
   605
#define CHECK(c) { if(!(c)) { Kern::Printf("Fail  %d", __LINE__); ; ret = __LINE__;} }
sl@0
   606
sl@0
   607
TInt DMemoryTestChannel::AllocPhysTest(TUint32 aIters, TUint32 aSize)
sl@0
   608
	{
sl@0
   609
	TInt	ret = KErrNone;
sl@0
   610
	TUint32	index;
sl@0
   611
sl@0
   612
	TUint32  pageSize = 0;
sl@0
   613
	CHECK(Kern::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0)==KErrNone);
sl@0
   614
	TUint32  numPages = aSize / pageSize;
sl@0
   615
	TUint32  pageIndex;
sl@0
   616
	TPhysAddr*	 addrArray = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * numPages);
sl@0
   617
	CHECK(addrArray);
sl@0
   618
	if(!addrArray)
sl@0
   619
		{
sl@0
   620
		return KErrNoMemory;
sl@0
   621
		}
sl@0
   622
sl@0
   623
	for (index = 0; index < aIters; index ++)
sl@0
   624
		{
sl@0
   625
		for (pageIndex = 0; pageIndex < numPages; pageIndex ++)
sl@0
   626
			{
sl@0
   627
			ret = Epoc::AllocPhysicalRam(pageSize, addrArray[pageIndex], 0);
sl@0
   628
			if (ret != KErrNone)
sl@0
   629
				{
sl@0
   630
				break;
sl@0
   631
				}
sl@0
   632
			}
sl@0
   633
		for (pageIndex = 0; pageIndex < numPages; pageIndex ++)
sl@0
   634
			{
sl@0
   635
			if (addrArray[pageIndex])
sl@0
   636
				{
sl@0
   637
				Epoc::FreePhysicalRam(addrArray[pageIndex], pageSize);
sl@0
   638
				addrArray[pageIndex] = NULL;
sl@0
   639
				}
sl@0
   640
			}
sl@0
   641
		if (ret != KErrNone)
sl@0
   642
			{
sl@0
   643
			break;
sl@0
   644
			}
sl@0
   645
		}
sl@0
   646
sl@0
   647
	Kern::Free(addrArray);
sl@0
   648
	return ret;
sl@0
   649
	}
sl@0
   650
sl@0
   651
#else
sl@0
   652
sl@0
   653
TInt DMemoryTestChannel::AllocPhysTest(TUint32 , TUint32 )
sl@0
   654
	{
sl@0
   655
	return KErrNone;
sl@0
   656
	}
sl@0
   657
sl@0
   658
#endif
sl@0
   659
sl@0
   660
#ifdef __EPOC32__
sl@0
   661
sl@0
   662
TInt DMemoryTestChannel::AllocPhysTest1(TUint32 aIters, TUint32 aSize)
sl@0
   663
	{
sl@0
   664
	TInt	ret = KErrNone;
sl@0
   665
	TUint32	index;
sl@0
   666
sl@0
   667
	TUint32  pageSize = 0;
sl@0
   668
	CHECK(Kern::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&pageSize,0)==KErrNone);
sl@0
   669
	TUint32 numPages = aSize / pageSize;
sl@0
   670
	TPhysAddr*	 addrArray = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * numPages);
sl@0
   671
	for (index = 0; index < aIters; index ++)
sl@0
   672
		{
sl@0
   673
		ret = Epoc::AllocPhysicalRam(numPages, addrArray);
sl@0
   674
		if (ret != KErrNone)
sl@0
   675
			{
sl@0
   676
			break;
sl@0
   677
			}
sl@0
   678
		Epoc::FreePhysicalRam(numPages, addrArray);
sl@0
   679
		}
sl@0
   680
	Kern::Free(addrArray);
sl@0
   681
	return ret;
sl@0
   682
	}
sl@0
   683
#else
sl@0
   684
sl@0
   685
TInt DMemoryTestChannel::AllocPhysTest1(TUint32 , TUint32 )
sl@0
   686
	{
sl@0
   687
	return KErrNone;
sl@0
   688
	}
sl@0
   689
sl@0
   690
#endif