os/kernelhwsrv/kerneltest/e32test/mmu/t_demandpaging.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/mmu/t_demandpaging.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1367 @@
     1.4 +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test\mmu\t_demandpaging.cpp
    1.18 +// Functional tests for demand paging. The test suite covers simple
    1.19 +// paging operations as well as HAL configuration and tuning functions.
    1.20 +// 001.01 DPTest::Attributes
    1.21 +// 001.02 DPTest::FlushCache
    1.22 +// 001.03 DPTest::CacheSize
    1.23 +// 001.04 DPTest::SetCacheSize
    1.24 +// 001.04.01 Changing size of flushed VM cache
    1.25 +// 001.04.02 Changing size of full VM cache
    1.26 +// 002 Loading test drivers
    1.27 +// 003 Test thread realtime state
    1.28 +// 003.01 Enable KREALTIME tracing
    1.29 +// 003.02 Test ERealtimeStateOff
    1.30 +// 003.03 Test ERealtimeStateOn
    1.31 +// 003.04 Test ERealtimeStateWarn
    1.32 +// 003.05 Test server with ERealtimeStateOff
    1.33 +// 003.06 Test server with ERealtimeStateOn
    1.34 +// 003.07 Test server with ERealtimeStateWarn
    1.35 +// 003.08 Disable KREALTIME tracing
    1.36 +// 004 Lock Test
    1.37 +// 005 Lock Test again
    1.38 +// 006 Test writing to paged ROM
    1.39 +// 007 Test IPC read from paged memory
    1.40 +// 007.01 Create server
    1.41 +// 007.02 IPC read from ROM
    1.42 +// 007.03 Stop server
    1.43 +// 008 Test contiguous RAM allocation reclaims paged memory
    1.44 +// 008.01 Start...
    1.45 +// 008.02 Contiguous RAM test: alloc size = 128K align = 16
    1.46 +// 008.03 Contiguous RAM test: alloc size = 128K align = 0
    1.47 +// 008.04 Contiguous RAM test: alloc size = 64K align = 15
    1.48 +// 008.05 Contiguous RAM test: alloc size = 64K align = 14
    1.49 +// 008.06 Contiguous RAM test: alloc size = 64K align = 13
    1.50 +// 008.07 Contiguous RAM test: alloc size = 64K align = 12
    1.51 +// 008.08 Contiguous RAM test: alloc size = 64K align = 0
    1.52 +// 008.09 Contiguous RAM test: alloc size = 8K align = 13
    1.53 +// 008.10 Contiguous RAM test: alloc size = 8K align = 12
    1.54 +// 008.11 Contiguous RAM test: alloc size = 8K align = 0
    1.55 +// 008.12 Contiguous RAM test: alloc size = 4K align = 13
    1.56 +// 008.13 Contiguous RAM test: alloc size = 4K align = 12
    1.57 +// 008.14 Contiguous RAM test: alloc size = 4K align = 0
    1.58 +// 009 Test no kernel faults when copying data from unpaged rom with mutex held
    1.59 +// 010 Close test driver
    1.60 +// 011 Test setting publish and subscribe properties from paged area
    1.61 +// 012 Rom Paging Benchmark
    1.62 +// 012.01 Benchmark ROM paging...
    1.63 +// 
    1.64 +//
    1.65 +
    1.66 +//! @SYMTestCaseID			KBASE-T_DEMANDPAGING-0334
    1.67 +//! @SYMTestType			UT
    1.68 +//! @SYMPREQ				PREQ1110
    1.69 +//! @SYMTestCaseDesc		Demand Paging functional tests.
    1.70 +//! @SYMTestActions			001 Test HAL interface
    1.71 +//! @SYMTestExpectedResults All tests should pass.
    1.72 +//! @SYMTestPriority        High
    1.73 +//! @SYMTestStatus          Implemented
    1.74 +
    1.75 +#define __E32TEST_EXTENSION__
    1.76 +#include <e32test.h>
    1.77 +#include <dptest.h>
    1.78 +#include <e32kpan.h>
    1.79 +#include <e32property.h>
    1.80 +#include <e32rom.h>
    1.81 +#include "d_memorytest.h"
    1.82 +#include "d_demandpaging.h"
    1.83 +#include "d_gobble.h"
    1.84 +#include "mmudetect.h"
    1.85 +#include "t_codepaging_dll.h"
    1.86 +#include "freeram.h"
    1.87 +
    1.88 +RTest test(_L("T_DEMANDPAGING"));
    1.89 +
    1.90 +_LIT(KTCodePagingDll4, "t_codepaging_dll4.dll");
    1.91 +const TInt KMinBufferSize = 16384;
    1.92 +const TInt KMaxIPCSize = 256*1024;
    1.93 +
    1.94 +TInt PageSize = 0;
    1.95 +RDemandPagingTestLdd Ldd;
    1.96 +RLibrary PagedLibrary;
    1.97 +
    1.98 +// A buffer containing paged memory, contents may or may not be paged in
    1.99 +const TUint8* LargeBuffer = NULL;
   1.100 +TInt LargeBufferSize = 0;
   1.101 +
   1.102 +// A buffer containing paged memeory, contents always paged out before access
   1.103 +const TUint8* SmallBuffer = NULL;
   1.104 +TInt SmallBufferSize = 0;
   1.105 +
   1.106 +// A shared buffer mapped to the global address range
   1.107 +TInt SharedBufferSize = KMaxIPCSize+4096;
   1.108 +TLinAddr SharedBufferAddr = 0;
   1.109 +TUint8* SharedBuffer = NULL;
   1.110 +
   1.111 +// A descriptor whose header is in paged memory (actually just a pointer to a zero word)
   1.112 +TDesC8* PagedHeaderDes = NULL;
   1.113 +
   1.114 +// A data paged chunk used as a buffer, if data paging is supported
   1.115 +_LIT(KChunkName, "t_demandpaging chunk");
   1.116 +RChunk DataPagedChunk;
   1.117 +TBool DataPagingSupported = EFalse;
   1.118 +TUint8* DataPagedBuffer = NULL;
   1.119 +
   1.120 +TUint8 ReadByte(volatile TUint8* aPtr)
   1.121 +	{
   1.122 +	return *aPtr;
   1.123 +	}
   1.124 +
   1.125 +#define READ(a) ReadByte((volatile TUint8*)(a))
   1.126 +
   1.127 +void ThrashPaging(TUint aMaxBytes=KMaxTUint)
   1.128 +	{
   1.129 +	TUint size = LargeBufferSize;
   1.130 +	if(size>aMaxBytes)
   1.131 +		size = aMaxBytes;
   1.132 +
   1.133 +	// read all ROM pages about 10 times each in a random order...
   1.134 +	TUint32 random=1;
   1.135 +	for(TInt i=size/(PageSize/10); i>0; --i)
   1.136 +		{
   1.137 +		READ(LargeBuffer+((TInt64(random)*TInt64(size))>>32));
   1.138 +		random = random*69069+1;
   1.139 +		}
   1.140 +	}
   1.141 +
   1.142 +void FragmentPagingCache(TUint aMaxBytes)
   1.143 +	{
   1.144 +	DPTest::FlushCache();
   1.145 +
   1.146 +	TUint size = Min(LargeBufferSize, aMaxBytes);
   1.147 +	if(size<aMaxBytes)
   1.148 +		test.Printf(_L("WARNING: LargeBuffer not large enough!  Have you built a full test ROM?\n"));
   1.149 +
   1.150 +	RChunk chunk;
   1.151 +	test(KErrNone==chunk.CreateDisconnectedLocal(0,0,size));
   1.152 +
   1.153 +	TUint32 random = 0;
   1.154 +	for(TUint i=0; i<size; i += PageSize)
   1.155 +		{
   1.156 +		random = random*69069+1;
   1.157 +		if(random<0x40000000)
   1.158 +			chunk.Commit(i,PageSize); // to make paging cache fragmented
   1.159 +		READ(LargeBuffer + i);
   1.160 +		}
   1.161 +
   1.162 +	CLOSE_AND_WAIT(chunk);
   1.163 +
   1.164 +	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
   1.165 +	}
   1.166 +
   1.167 +
   1.168 +void RomPagingBenchmark()
   1.169 +	{
   1.170 +	TInt r=DPTest::FlushCache();
   1.171 +	if(r!=KErrNone)
   1.172 +		return;
   1.173 +
   1.174 +	test.Start(_L("Benchmark ROM paging..."));
   1.175 +
   1.176 +	// change live list to be a small as possible
   1.177 +	test(KErrNone==DPTest::SetCacheSize(1,1));
   1.178 +
   1.179 +	RTimer timer;
   1.180 +	test(KErrNone==timer.CreateLocal());
   1.181 +	TRequestStatus status;
   1.182 +	timer.After(status,1);
   1.183 +	User::WaitForRequest(status);
   1.184 +
   1.185 +	TPckgBuf<DPTest::TEventInfo> events0;
   1.186 +	DPTest::EventInfo(events0);
   1.187 +
   1.188 +	TInt KRunTime = 10*1000*1000;
   1.189 +	timer.After(status,KRunTime);
   1.190 +	while(status==KRequestPending)
   1.191 +		for(const TUint8* ptr=LargeBuffer; ptr<(LargeBuffer+LargeBufferSize); ptr+=PageSize)
   1.192 +			{
   1.193 +			READ(ptr);
   1.194 +			if(status!=KRequestPending)
   1.195 +				break;
   1.196 +			}
   1.197 +
   1.198 +	TPckgBuf<DPTest::TEventInfo> events1;
   1.199 +	DPTest::EventInfo(events1);
   1.200 +
   1.201 +	User::WaitForRequest(status);
   1.202 +
   1.203 +	TUint pages = events1().iPageInReadCount-events0().iPageInReadCount;
   1.204 +	test.Printf(_L("%d pages in %d seconds = %d us/page\n"),pages,KRunTime/1000/1000,KRunTime/pages);
   1.205 +
   1.206 +	// restore live list to default size...
   1.207 +	test(KErrNone==DPTest::SetCacheSize(0,0));
   1.208 +
   1.209 +	test.End();
   1.210 +	}
   1.211 +
   1.212 +
   1.213 +void TestResizeVMCache()
   1.214 +	{
   1.215 +	TInt r = DPTest::SetCacheSize(0,0); // restore cache size to defaults
   1.216 +	test(r==KErrNone);
   1.217 +	TUint sizeMin = 0;
   1.218 +	TUint sizeMax = 0;
   1.219 +	TUint currentSize = 0;
   1.220 +	DPTest::CacheSize(sizeMin,sizeMax,currentSize);
   1.221 +	TUint originalMin = sizeMin;
   1.222 +	TUint originalMax = sizeMax;
   1.223 +	test.Printf(_L("original min=%u, original max=%u, current=%u\n"),originalMin/PageSize,originalMax/PageSize,currentSize/PageSize);
   1.224 +
   1.225 +	int K = currentSize/PageSize+4;
   1.226 +
   1.227 +	struct
   1.228 +		{
   1.229 +		TUint iMinPages;
   1.230 +		TUint iMaxPages;
   1.231 +		TInt iResult;
   1.232 +		}
   1.233 +	testArgs[] =
   1.234 +		{
   1.235 +			{	K,		K,		KErrNone},
   1.236 +			{	K-4,	K,		KErrNone},
   1.237 +			{	K,		K,		KErrNone},
   1.238 +			{	K,		K*2,	KErrNone},
   1.239 +			{	K,		K,		KErrNone},
   1.240 +			{	K-1,	K,		KErrNone},
   1.241 +			{	K,		K,		KErrNone},
   1.242 +			{	K,		K+1,	KErrNone},
   1.243 +			{	K,		K,		KErrNone},
   1.244 +			{	K+1,	K,		KErrArgument},
   1.245 +			{	K,		K-1,	KErrArgument},
   1.246 +			{	KMaxTInt,	KMaxTInt,	KErrNoMemory},
   1.247 +			{	K,		K,		KErrNone},
   1.248 +
   1.249 +			{	0,		0,		KErrNone}, // restore defaults
   1.250 +			{	0,		0,		KMaxTInt} // list end marker
   1.251 +		};
   1.252 +
   1.253 +	for(TInt j=0; j<2; ++j)
   1.254 +		{
   1.255 +		if(!j)
   1.256 +			{
   1.257 +			test.Start(_L("Changing size of flushed VM cache"));
   1.258 +			test.Printf(_L("Original cache size min == %u, max == %u\n"),originalMin/PageSize,originalMax/PageSize);
   1.259 +			}
   1.260 +		else
   1.261 +			test.Next(_L("Changing size of full VM cache"));
   1.262 +		TInt i=0;
   1.263 +		while(testArgs[i].iResult!=KMaxTInt)
   1.264 +			{
   1.265 +			TUint min=testArgs[i].iMinPages*PageSize;
   1.266 +			TUint max=testArgs[i].iMaxPages*PageSize;
   1.267 +			TInt result=testArgs[i].iResult;
   1.268 +
   1.269 +			ThrashPaging(max*2);
   1.270 +			if(!j)
   1.271 +				DPTest::FlushCache();
   1.272 +
   1.273 +			test.Printf(_L("DPTest::SetCacheSize min=%u, max=%u, expected result=%d\n"),min/PageSize,max/PageSize,result);
   1.274 +			TInt r=DPTest::SetCacheSize(min,max);
   1.275 +			if(r!=result)
   1.276 +				{
   1.277 +				test.Printf(_L("result=%d\n"),r);
   1.278 +				test(0);
   1.279 +				}
   1.280 +			if(r==KErrNone)
   1.281 +				{
   1.282 +				// we've successfully changed the cache size...
   1.283 +				if(max)
   1.284 +					{
   1.285 +					sizeMin = min;
   1.286 +					sizeMax = max;
   1.287 +					}
   1.288 +				else
   1.289 +					{
   1.290 +					sizeMin = originalMin;
   1.291 +					sizeMax = originalMax;
   1.292 +					}
   1.293 +				}
   1.294 +			if(r==KErrNoMemory)
   1.295 +				{
   1.296 +				// cache size after OOM is unpredictable, so reset our values
   1.297 +				DPTest::SetCacheSize(sizeMin,sizeMax);
   1.298 +				}
   1.299 +			else
   1.300 +				{
   1.301 +				// test 'get' function returns expected cache size
   1.302 +				r=DPTest::CacheSize(min,max,currentSize);
   1.303 +				test.Printf(_L("DPTest::CacheSize result=%d min=%u max=%u current=%u\n"),r,min/PageSize,max/PageSize,currentSize/PageSize);
   1.304 +				if(r!=KErrNone || min!=sizeMin || max!=sizeMax)
   1.305 +					test(0);
   1.306 +				test(currentSize >= min && currentSize <= max);
   1.307 +				}
   1.308 +			++i;
   1.309 +			}
   1.310 +		}
   1.311 +
   1.312 +	test.End();
   1.313 +	}
   1.314 +
   1.315 +
   1.316 +
   1.317 +void TestResizeVMCache2()
   1.318 +	{
   1.319 +	TUint originalMin = 0;
   1.320 +	TUint originalMax = 0;
   1.321 +	TUint currentSize = 0;
   1.322 +	test_KErrNone(DPTest::CacheSize(originalMax, originalMax, currentSize));
   1.323 +	test_KErrNone(DPTest::SetCacheSize(1, originalMax));
   1.324 +	TUint sizeMin = 0;
   1.325 +	TUint sizeMax = 0;
   1.326 +	test_KErrNone(DPTest::CacheSize(sizeMin, sizeMax, currentSize));
   1.327 +	test(sizeMin > 1);
   1.328 +	test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax));
   1.329 +	}
   1.330 +
   1.331 +
   1.332 +void TestHAL()
   1.333 +	{
   1.334 +	test.Start(_L("DPTest::Attributes"));
   1.335 +	TUint32 attr=DPTest::Attributes();
   1.336 +	test.Printf(_L("Attributes = %08x\n"),attr);
   1.337 +
   1.338 +	test.Next(_L("DPTest::FlushCache"));
   1.339 +	TInt r=DPTest::FlushCache();
   1.340 +	if(r==KErrNotSupported)
   1.341 +		test.Printf(_L("Not Supported\n"));
   1.342 +	else if(r<0)
   1.343 +		{
   1.344 +		test.Printf(_L("Error = %d\n"),r);
   1.345 +		test(0);
   1.346 +		}
   1.347 +
   1.348 +	test.Next(_L("DPTest::CacheSize"));
   1.349 +	TUint oldMin = 0;
   1.350 +	TUint oldMax = 0;
   1.351 +	TUint currentSize = 0;
   1.352 +	r=DPTest::CacheSize(oldMin,oldMax,currentSize);
   1.353 +	if(r==KErrNotSupported)
   1.354 +		test.Printf(_L("Not Supported\n"));
   1.355 +	else if(r<0)
   1.356 +		{
   1.357 +		test.Printf(_L("Error = %d\n"),r);
   1.358 +		test(0);
   1.359 +		}
   1.360 +	else
   1.361 +		{
   1.362 +		test.Printf(_L("Size = %dk,%dk,%dk\n"),oldMin>>10,oldMax>>10,currentSize>>10);
   1.363 +		}
   1.364 +
   1.365 +	test.Next(_L("DPTest::SetCacheSize"));
   1.366 +	r=DPTest::SetCacheSize(oldMin,oldMax);
   1.367 +	if(r==KErrNotSupported)
   1.368 +		test.Printf(_L("Not Supported\n"));
   1.369 +	else if(r<0)
   1.370 +		{
   1.371 +		test.Printf(_L("Error = %d\n"),r);
   1.372 +		test(0);
   1.373 +		}
   1.374 +	if(r==KErrNone)
   1.375 +		{
   1.376 +		TestResizeVMCache();
   1.377 +		TestResizeVMCache2();
   1.378 +		}
   1.379 +
   1.380 +	test.End();
   1.381 +	}
   1.382 +
   1.383 +// Test IPC and realtime state
   1.384 +
   1.385 +enum TIpcDir
   1.386 +	{
   1.387 +	EServerRead,
   1.388 +	EServerWrite
   1.389 +	};
   1.390 +
   1.391 +enum TIpcObjectPaged
   1.392 +	{
   1.393 +	ENothingPaged,
   1.394 +	EDesHeaderPaged,
   1.395 +	EDesContentPaged
   1.396 +	};
   1.397 +
   1.398 +enum TRealtimeOutcome
   1.399 +	{
   1.400 +	ENoError,
   1.401 +	EBadDescriptor,
   1.402 +	EServerTerminated,
   1.403 +	ERealtimePanic
   1.404 +	};
   1.405 +
   1.406 +class RTestSession : public RSessionBase
   1.407 +	{
   1.408 +public:
   1.409 +	TInt Create(RServer2 aServer)
   1.410 +		{
   1.411 +		return CreateSession(aServer,TVersion(),-1);
   1.412 +		}
   1.413 +	inline TInt Send(const TIpcArgs& aArgs)
   1.414 +		{
   1.415 +		return RSessionBase::SendReceive(0,aArgs);
   1.416 +		}
   1.417 +	};
   1.418 +
   1.419 +RServer2 TestServer;
   1.420 +
   1.421 +TInt IpcTestServerFunc(TAny* aArg)
   1.422 +	{
   1.423 +	TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff);
   1.424 +	TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff);
   1.425 +	User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff);
   1.426 +	User::TRealtimeState clientRealtime = (User::TRealtimeState)((((TInt)aArg) >> 24) & 0xff);
   1.427 +
   1.428 +	TInt r;
   1.429 +	// We want the server to fault the client when it is realtime 
   1.430 +	// and accessing paged out memory.
   1.431 +	r = TestServer.CreateGlobal(KNullDesC, EIpcSession_Sharable, EServerRole_Default, EServerOpt_PinClientDescriptorsDisable);
   1.432 +	if (r != KErrNone)
   1.433 +		return r;
   1.434 +	RThread::Rendezvous(KErrNone);
   1.435 +	
   1.436 +	RMessage2 message;
   1.437 +	TestServer.Receive(message);
   1.438 +	if ((clientRealtime == User::ERealtimeStateOn) != message.ClientIsRealtime())
   1.439 +		return KErrGeneral;
   1.440 +	message.Complete(KErrNone); // complete connection request
   1.441 +
   1.442 +	TRequestStatus s;
   1.443 +	TestServer.Receive(message,s);
   1.444 +	User::WaitForRequest(s);
   1.445 +	if (s != KErrNone)
   1.446 +		return s.Int();
   1.447 +
   1.448 +	TInt32 unpagedContent;
   1.449 +	TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4);
   1.450 +	TPtrC8 pagedContentBuf(SmallBuffer,sizeof(TInt));
   1.451 +
   1.452 +	TPtr8* dataPagedHeaderDes = (TPtr8*)DataPagedBuffer;
   1.453 +	if (DataPagingSupported)
   1.454 +		new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4);
   1.455 +	
   1.456 +	TPtr8 dataPagedContentDes(DataPagedBuffer + PageSize, 4);
   1.457 +				
   1.458 +	r = DPTest::FlushCache();
   1.459 +	if(r != KErrNone)
   1.460 +		return r;
   1.461 +	
   1.462 +	User::SetRealtimeState(realtime);
   1.463 +	if (dir == EServerRead)
   1.464 +		{
   1.465 +		switch (paged)
   1.466 +			{
   1.467 +			case ENothingPaged:
   1.468 +				r = message.Read(0,unpagedDes);
   1.469 +				break;
   1.470 +				
   1.471 +			case EDesHeaderPaged:
   1.472 +				r = DataPagingSupported ? message.Read(0,*dataPagedHeaderDes) : KErrNotSupported;
   1.473 +				break;
   1.474 +				
   1.475 +			case EDesContentPaged:
   1.476 +				r = DataPagingSupported ? message.Read(0,dataPagedContentDes) : KErrNotSupported;
   1.477 +				break;
   1.478 +
   1.479 +			default:
   1.480 +				r = KErrArgument;
   1.481 +				break;
   1.482 +			}
   1.483 +		}
   1.484 +	else if (dir == EServerWrite)
   1.485 +		{
   1.486 +		switch (paged)
   1.487 +			{
   1.488 +			case ENothingPaged:
   1.489 +				r = message.Write(0,unpagedDes);
   1.490 +				break;
   1.491 +				
   1.492 +			case EDesHeaderPaged:
   1.493 +				r = message.Write(0,*PagedHeaderDes);
   1.494 +				break;
   1.495 +				
   1.496 +			case EDesContentPaged:
   1.497 +				r = message.Write(0,pagedContentBuf);
   1.498 +				break;
   1.499 +
   1.500 +			default:
   1.501 +				r = KErrArgument;
   1.502 +				break;
   1.503 +			}
   1.504 +		}
   1.505 +	else
   1.506 +		r = KErrArgument;
   1.507 +	User::SetRealtimeState(User::ERealtimeStateOff);
   1.508 +
   1.509 +	message.Complete(KErrNone);
   1.510 +	return r;
   1.511 +	}
   1.512 +
   1.513 +TInt IpcTestClientFunc(TAny* aArg)
   1.514 +	{
   1.515 +	TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff);
   1.516 +	TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff);
   1.517 +	User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff);
   1.518 +
   1.519 +	RTestSession session;
   1.520 +	TInt r = session.Create(TestServer);
   1.521 +	if(r != KErrNone)
   1.522 +		return r;
   1.523 +
   1.524 +	TInt32 unpagedContent;
   1.525 +	TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4);
   1.526 +	TPtrC8 pagedContentBuf(SmallBuffer + PageSize, sizeof(TInt));
   1.527 +
   1.528 +	TPtr8* dataPagedHeaderDes = (TPtr8*)(DataPagedBuffer + (2 * PageSize));
   1.529 +	if (DataPagingSupported)
   1.530 +		new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4);
   1.531 +	
   1.532 +	TPtr8 dataPagedContentDes(DataPagedBuffer + (3 * PageSize), 4);
   1.533 +
   1.534 +	r = DPTest::FlushCache();
   1.535 +	if(r != KErrNone)
   1.536 +		return r;
   1.537 +	
   1.538 +	User::SetRealtimeState(realtime);
   1.539 +	if (dir == EServerRead)
   1.540 +		{
   1.541 +		switch (paged)
   1.542 +			{
   1.543 +			case ENothingPaged:
   1.544 +				r = session.Send(TIpcArgs(&unpagedDes));
   1.545 +				break;
   1.546 +				
   1.547 +			case EDesHeaderPaged:
   1.548 +				r = session.Send(TIpcArgs(PagedHeaderDes));
   1.549 +				break;
   1.550 +				
   1.551 +			case EDesContentPaged:
   1.552 +				r = session.Send(TIpcArgs(&pagedContentBuf));
   1.553 +				break;
   1.554 +
   1.555 +			default:
   1.556 +				r = KErrArgument;
   1.557 +				break;
   1.558 +			}
   1.559 +		}
   1.560 +	else if (dir == EServerWrite)
   1.561 +		{
   1.562 +		switch (paged)
   1.563 +			{
   1.564 +			case ENothingPaged:
   1.565 +				r = session.Send(TIpcArgs(&unpagedDes));
   1.566 +				break;
   1.567 +				
   1.568 +			case EDesHeaderPaged:
   1.569 +				r = DataPagingSupported ? session.Send(TIpcArgs(dataPagedHeaderDes)) : KErrNotSupported;
   1.570 +				break;
   1.571 +				
   1.572 +			case EDesContentPaged:
   1.573 +				r = DataPagingSupported ? session.Send(TIpcArgs(&dataPagedContentDes)) : KErrNotSupported;
   1.574 +				break;
   1.575 +
   1.576 +			default:
   1.577 +				r = KErrArgument;
   1.578 +				break;
   1.579 +			}
   1.580 +		}
   1.581 +	else
   1.582 +		r = KErrArgument;
   1.583 +	User::SetRealtimeState(User::ERealtimeStateOff);
   1.584 +
   1.585 +	session.Close();
   1.586 +	return r;
   1.587 +	}
   1.588 +
   1.589 +void TestRealtimeOutcome(RThread aThread, TRealtimeOutcome aOutcome)
   1.590 +	{
   1.591 +	switch(aOutcome)
   1.592 +		{
   1.593 +		case ENoError:
   1.594 +			test_Equal(EExitKill, aThread.ExitType());
   1.595 +			test_KErrNone(aThread.ExitReason());
   1.596 +			break;
   1.597 +			
   1.598 +		case EBadDescriptor:
   1.599 +			test_Equal(EExitKill, aThread.ExitType());
   1.600 +			test_Equal(KErrBadDescriptor, aThread.ExitReason());
   1.601 +			break;
   1.602 +
   1.603 +		case EServerTerminated:
   1.604 +			test_Equal(EExitKill, aThread.ExitType());
   1.605 +			test_Equal(KErrServerTerminated, aThread.ExitReason());
   1.606 +			break;
   1.607 +
   1.608 +		case ERealtimePanic:
   1.609 +			test_Equal(EExitPanic, aThread.ExitType());
   1.610 +			test(aThread.ExitCategory()==_L("KERN-EXEC"));
   1.611 +			test_Equal(EIllegalFunctionForRealtimeThread, aThread.ExitReason());
   1.612 +			break;
   1.613 +
   1.614 +		default:
   1.615 +			test(EFalse);
   1.616 +		}
   1.617 +	}
   1.618 +
   1.619 +void TestPagedIpc(TIpcDir aIpcDir,
   1.620 +				  TIpcObjectPaged aClientPaged,
   1.621 +				  TIpcObjectPaged aServerPaged,
   1.622 +				  User::TRealtimeState aClientState,
   1.623 +				  User::TRealtimeState aServerState,
   1.624 +				  TRealtimeOutcome aClientOutcome,
   1.625 +				  TRealtimeOutcome aServerOutcome)
   1.626 +	{
   1.627 +	test.Printf(_L("TestPagedIpc %d %d %d %d %d %d %d\n"), aIpcDir, aClientPaged, aServerPaged,
   1.628 +				aClientState, aServerState, aClientOutcome, aServerOutcome);
   1.629 +	
   1.630 +	RThread serverThread;
   1.631 +	RThread clientThread;
   1.632 +	TRequestStatus serverStatus;
   1.633 +	TRequestStatus clientStatus;
   1.634 +
   1.635 +	TInt serverArg = aIpcDir | (aServerPaged << 8) | (aServerState << 16) | (aClientState << 24);
   1.636 +	test_KErrNone(serverThread.Create(KNullDesC, &IpcTestServerFunc, 0x1000, NULL, (TAny*)serverArg));
   1.637 +	TName name;
   1.638 +	name = serverThread.Name();
   1.639 +	test.Printf(_L("  server: %S\n"), &name);
   1.640 +	serverThread.Rendezvous(serverStatus);
   1.641 +	serverThread.Resume();
   1.642 +	User::WaitForRequest(serverStatus);
   1.643 +	test_KErrNone(serverStatus.Int());
   1.644 +	serverThread.Logon(serverStatus);
   1.645 +	
   1.646 +	TInt clientArg = aIpcDir | (aClientPaged << 8) | (aClientState << 16);
   1.647 +	test_KErrNone(clientThread.Create(KNullDesC, &IpcTestClientFunc, 0x1000, NULL, (TAny*)clientArg));
   1.648 +	name = clientThread.Name();
   1.649 +	test.Printf(_L("  client: %S\n"), &name);
   1.650 +	clientThread.Logon(clientStatus);
   1.651 +	clientThread.Resume();
   1.652 +
   1.653 +	User::WaitForRequest(serverStatus);
   1.654 +	test.Printf(_L("  server exit type is %d %d\n"), serverThread.ExitType(), serverThread.ExitReason());
   1.655 +	TestServer.Close();  // because handle is process-relative, it's not closed if the server dies
   1.656 +
   1.657 +	User::WaitForRequest(clientStatus);
   1.658 +	test.Printf(_L("  client exit type is %d %d\n"), clientThread.ExitType(), clientThread.ExitReason());
   1.659 +
   1.660 +	TestRealtimeOutcome(serverThread, aServerOutcome);
   1.661 +	TestRealtimeOutcome(clientThread, aClientOutcome);
   1.662 +	
   1.663 +	CLOSE_AND_WAIT(serverThread);
   1.664 +	CLOSE_AND_WAIT(clientThread);
   1.665 +	}
   1.666 +
   1.667 +TInt TestThreadFunction(TAny* aType)
   1.668 +	{
   1.669 +	// Ensure that pageable memory is paged out
   1.670 +	TInt r=DPTest::FlushCache();
   1.671 +	if(r!=KErrNone)
   1.672 +		return r;
   1.673 +
   1.674 +	// Access pageable data whilst thread is in specified realttime state.
   1.675 +	User::SetRealtimeState((User::TRealtimeState)(TInt)aType);
   1.676 +	READ(SmallBuffer);
   1.677 +	return KErrNone;
   1.678 +	}
   1.679 +
   1.680 +TInt RunTestThread(User::TRealtimeState aType, TRealtimeOutcome aOutcome)
   1.681 +	{
   1.682 +	RThread thread;
   1.683 +	TInt r=thread.Create(KNullDesC, &TestThreadFunction, 0x1000, NULL, (TAny*)aType);
   1.684 +	if(r!=KErrNone)
   1.685 +		return r;
   1.686 +	TRequestStatus s;
   1.687 +	thread.Logon(s);
   1.688 +	if(s.Int()!=KRequestPending)
   1.689 +		return s.Int();
   1.690 +	thread.Resume();
   1.691 +	User::WaitForRequest(s);
   1.692 +	TestRealtimeOutcome(thread, aOutcome);
   1.693 +	CLOSE_AND_WAIT(thread);
   1.694 +	return KErrNone;
   1.695 +	}
   1.696 +
   1.697 +void TestRealtimeState()
   1.698 +	{
   1.699 +	// make sure live list is big enough
   1.700 +	test(KErrNone==DPTest::SetCacheSize(256*PageSize,256*PageSize));
   1.701 +
   1.702 +	test.Start(_L("Enable KREALTIME tracing"));
   1.703 +	Ldd.SetRealtimeTrace(ETrue);
   1.704 +
   1.705 +	test.Next(_L("Test ERealtimeStateOff"));
   1.706 +	RunTestThread(User::ERealtimeStateOff, ENoError);
   1.707 +
   1.708 +	test.Next(_L("Test ERealtimeStateOn"));
   1.709 +	RunTestThread(User::ERealtimeStateOn, ERealtimePanic);
   1.710 +
   1.711 +	test.Next(_L("Test ERealtimeStateWarn"));
   1.712 +	RunTestThread(User::ERealtimeStateWarn, ENoError);
   1.713 +
   1.714 +	test.Next(_L("Test combinations of IPC with realtime state"));
   1.715 +
   1.716 +	//           ipc dir:      client paged:     server paged:     client state:             server state:             client outcome:    server outcome:
   1.717 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.718 +	TestPagedIpc(EServerRead,  EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.719 +	TestPagedIpc(EServerRead,  EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.720 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.721 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.722 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.723 +
   1.724 +	if (DataPagingSupported)
   1.725 +		{
   1.726 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.727 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.728 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.729 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.730 +	TestPagedIpc(EServerWrite, EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.731 +	TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOff,  ENoError,          ENoError);
   1.732 +		}
   1.733 +
   1.734 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.735 +	TestPagedIpc(EServerRead,  EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.736 +	TestPagedIpc(EServerRead,  EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.737 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.738 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.739 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.740 +
   1.741 +	if (DataPagingSupported)
   1.742 +		{
   1.743 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.744 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.745 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.746 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.747 +	TestPagedIpc(EServerWrite, EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.748 +	TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateWarn, ENoError,          ENoError);
   1.749 +		}
   1.750 +
   1.751 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.752 +	TestPagedIpc(EServerRead,  EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.753 +	TestPagedIpc(EServerRead,  EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ERealtimePanic,    EBadDescriptor);
   1.754 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.755 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateOn,   EServerTerminated, ERealtimePanic);
   1.756 +	TestPagedIpc(EServerWrite, ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateOn,   EServerTerminated, ERealtimePanic);
   1.757 +
   1.758 +	if (DataPagingSupported)
   1.759 +		{
   1.760 +	TestPagedIpc(EServerRead,  ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.761 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesHeaderPaged,  User::ERealtimeStateOff,  User::ERealtimeStateOn,   EServerTerminated, ERealtimePanic);
   1.762 +	TestPagedIpc(EServerRead,  ENothingPaged,    EDesContentPaged, User::ERealtimeStateOff,  User::ERealtimeStateOn,   EServerTerminated, ERealtimePanic);
   1.763 +	TestPagedIpc(EServerWrite, ENothingPaged,    ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.764 +	TestPagedIpc(EServerWrite, EDesHeaderPaged,  ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ENoError,          ENoError);
   1.765 +	TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged,    User::ERealtimeStateOff,  User::ERealtimeStateOn,   ERealtimePanic,    EBadDescriptor);
   1.766 +		}
   1.767 +	
   1.768 +	test.End();
   1.769 +
   1.770 +	// retore size of live list
   1.771 +	test(KErrNone==DPTest::SetCacheSize(0,0));
   1.772 +	}
   1.773 +
   1.774 +void TestLock()
   1.775 +	{
   1.776 +	// make sure live list is big enough
   1.777 +	test(KErrNone==DPTest::SetCacheSize(128 * PageSize, 256 * PageSize));
   1.778 +
   1.779 +	TInt r = Ldd.LockTest(SmallBuffer,SmallBufferSize);
   1.780 +	if(r==KErrNone)
   1.781 +		{
   1.782 +		test.Next(_L("Lock Test again"));
   1.783 +		r = Ldd.LockTest(SmallBuffer,SmallBufferSize);
   1.784 +		}
   1.785 +	if(r)
   1.786 +		{
   1.787 +		test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r);
   1.788 +		test(0);
   1.789 +		}
   1.790 +		
   1.791 +	// restore live list to default size...
   1.792 +	test(KErrNone==DPTest::SetCacheSize(0,0));
   1.793 +	}
   1.794 +
   1.795 +const TInt KSmallPropertySize = 512;
   1.796 +const TInt KLargePropertySize = 16384;
   1.797 +	
   1.798 +struct SSetPropertyInfo
   1.799 +	{
   1.800 +	TUid iCategory;
   1.801 +	TInt iKey;
   1.802 +	TUint8* iData;
   1.803 +	TInt iLength;
   1.804 +	};
   1.805 +
   1.806 +TInt SetPropertyThreadFunction(TAny* aArg)
   1.807 +	{
   1.808 +	SSetPropertyInfo* info = (SSetPropertyInfo*)aArg;
   1.809 +	TInt r;
   1.810 +	r = DPTest::FlushCache();
   1.811 +	if (r != KErrNone)
   1.812 +		return r;
   1.813 +	TPtrC8 data(info->iData, info->iLength);
   1.814 +	r = RProperty::Set(info->iCategory, info->iKey, data);
   1.815 +	if (r != KErrNone)
   1.816 +		return r;
   1.817 +	RBuf8 buffer;
   1.818 +	r = buffer.Create(KLargePropertySize);
   1.819 +	if (r != KErrNone)
   1.820 +		return r;
   1.821 +	r = RProperty::Get(info->iCategory, info->iKey, buffer);
   1.822 +	if (r == KErrNone && buffer != data)
   1.823 +		r = KErrGeneral;
   1.824 +	buffer.Close();
   1.825 +	return r;
   1.826 +	}
   1.827 +
   1.828 +void TestPublishAndSubscribe()
   1.829 +	{
   1.830 +	RProcess thisProcess;
   1.831 +	TUid category = thisProcess.SecureId();
   1.832 +
   1.833 +	TSecurityPolicy alwaysPass(TSecurityPolicy::EAlwaysPass);
   1.834 +	test(RProperty::Define(category, 0, RProperty::EByteArray, alwaysPass, alwaysPass) == KErrNone);
   1.835 +	test(RProperty::Define(category, 1, RProperty::ELargeByteArray, alwaysPass, alwaysPass) == KErrNone);
   1.836 +	
   1.837 +	TPtrC8 smallData(SmallBuffer, KSmallPropertySize);
   1.838 +	TPtrC8 largeData(SmallBuffer, KLargePropertySize);
   1.839 +	
   1.840 +	RBuf8 buffer;
   1.841 +	test(buffer.Create(KLargePropertySize) == KErrNone);
   1.842 +
   1.843 +	// Set small property from paged data, method 1
   1.844 +	test(DPTest::FlushCache() == KErrNone);
   1.845 +	test(RProperty::Set(category, 0, smallData) == KErrNone);
   1.846 +	test(RProperty::Get(category, 0, buffer) == KErrNone);
   1.847 +	test(buffer == smallData);
   1.848 +	
   1.849 +	// Set small property from paged data, method 2
   1.850 +	RProperty smallProp;
   1.851 +	test(smallProp.Attach(category, 0) == KErrNone);
   1.852 +	test(DPTest::FlushCache() == KErrNone);
   1.853 +	test(smallProp.Set(smallData) == KErrNone);
   1.854 +	test(smallProp.Get(buffer) == KErrNone);
   1.855 +	test(buffer == smallData);
   1.856 +
   1.857 +	// Set large property from paged data, method 1
   1.858 +	test(DPTest::FlushCache() == KErrNone);
   1.859 +	test(RProperty::Set(category, 1, largeData) == KErrNone);
   1.860 +	test(RProperty::Get(category, 1, buffer) == KErrNone);
   1.861 +	test(buffer == largeData);
   1.862 +	
   1.863 +	// Set large property from paged data, method 2
   1.864 +	RProperty largeProp;
   1.865 +	test(largeProp.Attach(category, 1) == KErrNone);
   1.866 +	test(DPTest::FlushCache() == KErrNone);
   1.867 +	test(largeProp.Set(largeData) == KErrNone);
   1.868 +	test(largeProp.Get(buffer) == KErrNone);
   1.869 +	test(buffer == largeData);
   1.870 +
   1.871 +	// Set small property from unmapped address
   1.872 +	RThread thread;
   1.873 +#if !defined( __VC32__)
   1.874 +	SSetPropertyInfo info = { category, 0, 0, KSmallPropertySize };
   1.875 +#else
   1.876 +	SSetPropertyInfo info = { category.iUid, 0, 0, KSmallPropertySize };
   1.877 +#endif
   1.878 +	test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone);
   1.879 +	thread.Resume();
   1.880 +	TRequestStatus status;
   1.881 +	thread.Logon(status);
   1.882 +	User::WaitForRequest(status);
   1.883 +	test(thread.ExitType()==EExitPanic);
   1.884 +	test(thread.ExitCategory()==_L("KERN-EXEC"));
   1.885 +	test(thread.ExitReason()==ECausedException);
   1.886 +	thread.Close();
   1.887 +
   1.888 +	// Set large property from unmapped address
   1.889 +	info.iKey = 1;
   1.890 +	info.iLength = KLargePropertySize;
   1.891 +	test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone);
   1.892 +	thread.Resume();
   1.893 +	thread.Logon(status);
   1.894 +	User::WaitForRequest(status);
   1.895 +	test(thread.ExitType()==EExitPanic);
   1.896 +	test(thread.ExitCategory()==_L("KERN-EXEC"));
   1.897 +	test(thread.ExitReason()==ECausedException);
   1.898 +	thread.Close();
   1.899 +	
   1.900 +	test(RProperty::Delete(category, 0) == KErrNone);
   1.901 +	test(RProperty::Delete(category, 1) == KErrNone);
   1.902 +	}
   1.903 +
   1.904 +void TestWriteToPagedArea()
   1.905 +	{
   1.906 +	RMemoryTestLdd memoryTest;
   1.907 +	test(KErrNone==memoryTest.Open());
   1.908 +
   1.909 +	TModuleMemoryInfo exeInfo;
   1.910 +	test(KErrNone==RProcess().GetMemoryInfo(exeInfo));
   1.911 +	test.Printf(_L("test program code is %x+%x"),exeInfo.iCodeBase,exeInfo.iCodeSize);
   1.912 +
   1.913 +	TUint8* ptr = const_cast<TUint8*>(LargeBuffer);
   1.914 +	TUint8* end = ptr + LargeBufferSize;
   1.915 +	while(ptr<end)
   1.916 +		{
   1.917 +		if(ptr>=(TUint8*)_ALIGN_DOWN(exeInfo.iCodeBase,PageSize) && ptr<(TUint8*)_ALIGN_UP(exeInfo.iCodeBase+exeInfo.iCodeSize,PageSize))
   1.918 +			{
   1.919 +			// avoid testing the ROM which contains this test program
   1.920 +			ptr += PageSize;
   1.921 +			continue;
   1.922 +			}
   1.923 +	
   1.924 +		DPTest::FlushCache();
   1.925 +
   1.926 +		TInt stateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0);
   1.927 +		test(stateBits>=0);
   1.928 +		// write to paged out memory should cause exception...
   1.929 +		test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,0));
   1.930 +		// page state should be unchanged...
   1.931 +		TInt newStateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0);
   1.932 +		if(stateBits!=newStateBits)
   1.933 +			{
   1.934 +			test.Printf(_L("ptr=%x stateBits=%x newStateBits=%x"),ptr,stateBits,newStateBits);
   1.935 +			test(0);
   1.936 +			}
   1.937 +		// page-in in memory...
   1.938 +		TUint32 value = *(TUint32*)ptr;
   1.939 +		// write to paged out memory should still cause exception...
   1.940 +		test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,~value));
   1.941 +		// memory should be unchanged...
   1.942 +		test(value==*(TUint32*)ptr);
   1.943 +		ptr += PageSize;
   1.944 +		}
   1.945 +
   1.946 +	memoryTest.Close();
   1.947 +	}
   1.948 +
   1.949 +void TestContiguousRamAlloc()
   1.950 +	{
   1.951 +	test.Start(_L("Start..."));
   1.952 +
   1.953 +	const TInt KCacheSize = 1024*1024;
   1.954 +
   1.955 +	DPTest::SetCacheSize(0, KCacheSize); // make sure paging cache is a reasonable size
   1.956 +
   1.957 +	TInt testData[][2] = /* array of page size (in units of 'half pages')  and align values */
   1.958 +		{
   1.959 +			{64,5},
   1.960 +			{64,0},
   1.961 +			{32,4},
   1.962 +			{32,3},
   1.963 +			{32,2},
   1.964 +			{32,1},
   1.965 +			{32,0},
   1.966 +			{4,2},
   1.967 +			{4,1},
   1.968 +			{4,0},
   1.969 +			{2,2},
   1.970 +			{2,1},
   1.971 +			{2,0},
   1.972 +			{1,0},
   1.973 +			{0,0}
   1.974 +		};
   1.975 +	TInt pageShift = 1;
   1.976 +	while((1<<pageShift)<PageSize)
   1.977 +		++pageShift;
   1.978 +
   1.979 +	TInt* params = (TInt*)&testData;
   1.980 +	while(*params)
   1.981 +		{
   1.982 +		TInt size =  *params++<<(pageShift-1);	//Size is units of half pages, so one less shift to get required memory size
   1.983 +		TInt align = *params++;
   1.984 +		if(align)
   1.985 +			align += pageShift - 1;
   1.986 +		TBuf<256> title;
   1.987 +		title.AppendFormat(_L("Contiguous RAM test: alloc size = %dK align = %d"),size>>10, align);
   1.988 +		test.Next(title);
   1.989 +		FragmentPagingCache(KCacheSize);
   1.990 +		TInt r = Ldd.DoConsumeContiguousRamTest(align, size);
   1.991 +		if(r)
   1.992 +			{
   1.993 +			test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r);
   1.994 +			test(0);
   1.995 +			}
   1.996 +		}
   1.997 +
   1.998 +	DPTest::SetCacheSize(0,0); // back to defaults
   1.999 +	test.End();
  1.1000 +	}
  1.1001 +
  1.1002 +void TestReadHoldingMutex()
  1.1003 +	{
  1.1004 +	TUint8 localBuf[16];
  1.1005 +	TUint8* localPtr = localBuf;
  1.1006 +	if(DPTest::Attributes() & DPTest::EDataPaging) // if data paging supported...
  1.1007 +		localPtr = 0; // use zero to make driver use kernel memory as data destination
  1.1008 +	test(Ldd.ReadHoldingMutexTest(localPtr) == KErrNone);
  1.1009 +	}
  1.1010 +
  1.1011 +#if 0 // rom dump code...
  1.1012 +#include <f32file.h>
  1.1013 +	RFs fs;
  1.1014 +	RFile file;
  1.1015 +	test(KErrNone==fs.Connect());
  1.1016 +	test(KErrNone==file.Replace(fs, _L("d:\\ROMDUMP"),EFileWrite));
  1.1017 +	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  1.1018 +	TPtrC8 rom((TUint8*)romHeader,romHeader->iRomSize);
  1.1019 +	test(KErrNone==file.Write(rom));
  1.1020 +	file.Close();
  1.1021 +	fs.Close();
  1.1022 +	return 0;
  1.1023 +#endif
  1.1024 +
  1.1025 +
  1.1026 +class RMySession : public RSessionBase
  1.1027 +	{
  1.1028 +public:
  1.1029 +	TInt Connect(RServer2 aSrv,TRequestStatus& aStat)
  1.1030 +		{
  1.1031 +		TInt r=CreateSession(aSrv,TVersion(),-1,EIpcSession_Sharable,NULL,&aStat);
  1.1032 +		if(!r) ShareAuto(); return r;
  1.1033 +		}
  1.1034 +	TInt Send(TInt function,const TIpcArgs& args)
  1.1035 +		{return SendReceive(function,args);}
  1.1036 +	};
  1.1037 +
  1.1038 +
  1.1039 +TUint8* TestBuffer = 0;
  1.1040 +RMySession MySession;
  1.1041 +
  1.1042 +LOCAL_C TInt TestServerThread(TAny* aSize)
  1.1043 +	{
  1.1044 +	TInt r = TestServer.CreateGlobal(KNullDesC, EIpcSession_GlobalSharable);
  1.1045 +	if(r==KErrNone)
  1.1046 +		{
  1.1047 +		TestBuffer = (TUint8*)User::Alloc(KMaxIPCSize);
  1.1048 +		if(!TestBuffer)
  1.1049 +			r = KErrNoMemory;
  1.1050 +		}
  1.1051 +	TPtr8 buffer(TestBuffer,KMaxIPCSize);
  1.1052 +	RThread::Rendezvous(r);
  1.1053 +	if (r != KErrNone)
  1.1054 +		return r;
  1.1055 +
  1.1056 +	RMessage2 m;
  1.1057 +	TestServer.Receive(m);
  1.1058 +	m.Complete(KErrNone);	// connect message
  1.1059 +
  1.1060 +	TBool running = ETrue;
  1.1061 +	while (running)
  1.1062 +		{
  1.1063 +		TestServer.Receive(m);
  1.1064 +		RDebug::Printf("Server received: %d", m.Function());
  1.1065 +
  1.1066 +		TInt r = KErrNone;
  1.1067 +		switch(m.Function())
  1.1068 +			{
  1.1069 +			case 0:
  1.1070 +				// Kill server
  1.1071 +				running = EFalse;
  1.1072 +				break;
  1.1073 +
  1.1074 +			case 2:
  1.1075 +				buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize);
  1.1076 +				// fall through...
  1.1077 +			case 1:
  1.1078 +				// Perform CRC of data passed
  1.1079 +				{
  1.1080 +				DPTest::FlushCache();
  1.1081 +				r=m.Read(0,buffer);
  1.1082 +				if (r!=KErrNone)
  1.1083 +					break;
  1.1084 +				TUint32 crc=0;
  1.1085 +				Mem::Crc32(crc,buffer.Ptr(),buffer.Size());
  1.1086 +				r = crc;
  1.1087 +				}
  1.1088 +				break;
  1.1089 +
  1.1090 +			case 4:
  1.1091 +				buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize);
  1.1092 +				// fall through...
  1.1093 +			case 3:
  1.1094 +				// Write data to client descriptor
  1.1095 +				{
  1.1096 +				DPTest::FlushCache();
  1.1097 +				RDebug::Printf("Server writing %08x+%x", m.Int1(), m.Int2());
  1.1098 +				TPtrC8 ptr((TUint8*)m.Int1(),m.Int2());
  1.1099 +				r=m.Write(0,ptr);
  1.1100 +				}
  1.1101 +				break;
  1.1102 +			
  1.1103 +			default:
  1.1104 +				// Just complete anything else
  1.1105 +				break;
  1.1106 +			}
  1.1107 +		m.Complete(r);
  1.1108 +		}
  1.1109 +
  1.1110 +	RDebug::Printf("Server exiting");
  1.1111 +	User::Free(TestBuffer);
  1.1112 +	TestBuffer = NULL;
  1.1113 +	TestServer.Close();
  1.1114 +	return KErrNone;
  1.1115 +	}
  1.1116 +
  1.1117 +void TestIPC()
  1.1118 +	{
  1.1119 +	__KHEAP_MARK;
  1.1120 +		
  1.1121 +	const TUint8* start = LargeBuffer + 0x3df; // make range not page aligned
  1.1122 +	const TUint8* end = start + Min(LargeBufferSize, KMaxIPCSize * 10) - 0x130; // make range not page aligned
  1.1123 +	const TUint8* pos;
  1.1124 +	
  1.1125 +	test.Start(_L("Create server"));
  1.1126 +	RThread t;
  1.1127 +	TInt r=t.Create(KNullDesC,TestServerThread,0x1000,KMaxIPCSize+0x1000,KMaxIPCSize+0x1000,(void*)0);
  1.1128 +	test(r==KErrNone);
  1.1129 +	t.SetPriority(EPriorityMore);
  1.1130 +	TRequestStatus s;
  1.1131 +	t.Rendezvous(s);
  1.1132 +	t.Resume();
  1.1133 +	User::WaitForRequest(s);
  1.1134 +	test(TestServer.Handle() != KNullHandle);
  1.1135 +
  1.1136 +	test(MySession.Connect(TestServer,s) == KErrNone);
  1.1137 +	User::WaitForRequest(s);	// connected
  1.1138 +
  1.1139 +	TInt bufferType; // 0=server uses heap, 1=server uses SharedBuffer
  1.1140 +	for(bufferType=0; bufferType<=1; ++bufferType)
  1.1141 +		{
  1.1142 +		test.Next(_L("IPC read from ROM"));
  1.1143 +		pos = start;
  1.1144 +		while(pos<end)
  1.1145 +			{
  1.1146 +			TInt size = end-pos;
  1.1147 +			if(size>KMaxIPCSize)
  1.1148 +				size = KMaxIPCSize;
  1.1149 +			RDebug::Printf("read %x+%x",pos,size);
  1.1150 +			TPtrC8 ptr(pos,size);
  1.1151 +			TInt r = MySession.Send(1+bufferType,TIpcArgs(&ptr));
  1.1152 +			DPTest::FlushCache();
  1.1153 +			TUint32 crc=0;
  1.1154 +			Mem::Crc32(crc,pos,size);
  1.1155 +			RDebug::Printf("crc %08x %08x",r,crc);
  1.1156 +			if((TUint32)r!=crc)
  1.1157 +				{
  1.1158 +				RDebug::Printf("FAIL");
  1.1159 +				DPTest::FlushCache();
  1.1160 +				TInt count = 0;
  1.1161 +				for(TInt i=0; i<size; i+=4)
  1.1162 +					{
  1.1163 +					TUint32 a = pos[i];
  1.1164 +					TUint32 b = TestBuffer[i];
  1.1165 +					if(a!=b)
  1.1166 +						RDebug::Printf("%08x %02x!=%02x",pos+i,a,b);
  1.1167 +					if (++count > 100)
  1.1168 +						break;
  1.1169 +					}
  1.1170 +				}
  1.1171 +			test((TUint32)r==crc);
  1.1172 +			pos+=size;
  1.1173 +			}
  1.1174 +
  1.1175 +		test.Next(_L("IPC write from ROM"));
  1.1176 +		pos = start;
  1.1177 +		while(pos<end)
  1.1178 +			{
  1.1179 +			TInt size = end-pos;
  1.1180 +			if(size>KMaxIPCSize)
  1.1181 +				size = KMaxIPCSize;
  1.1182 +			RDebug::Printf("write %x+%x",pos,size);
  1.1183 +			memclr(TestBuffer, KMaxIPCSize);
  1.1184 +			TPtr8 ptr(TestBuffer,KMaxIPCSize);	// reuse the server's buffer
  1.1185 +			TInt r = MySession.Send(3+bufferType,TIpcArgs(&ptr,pos,size));
  1.1186 +			test_KErrNone(r);
  1.1187 +			DPTest::FlushCache();
  1.1188 +			TUint32 crc=0;
  1.1189 +			Mem::Crc32(crc,pos,size);
  1.1190 +			TUint32 crc2=0;
  1.1191 +			Mem::Crc32(crc2,TestBuffer,size);
  1.1192 +			RDebug::Printf("crc %08x %08x",crc,crc2);
  1.1193 +			if((TUint32)crc!=crc2)
  1.1194 +				{
  1.1195 +				RDebug::Printf("FAIL");
  1.1196 +				DPTest::FlushCache();
  1.1197 +				TInt count = 0;
  1.1198 +				for(TInt i=0; i<size; i+=4)
  1.1199 +					{
  1.1200 +					TUint32 a = pos[i];
  1.1201 +					TUint32 b = TestBuffer[i];
  1.1202 +					if(a!=b)
  1.1203 +						RDebug::Printf("%08x %02x!=%02x",pos+i,a,b);
  1.1204 +					if (++count > 100)
  1.1205 +						break;
  1.1206 +					}
  1.1207 +				}
  1.1208 +			test((TUint32)crc==crc2);
  1.1209 +			pos+=size;
  1.1210 +			}
  1.1211 +		}
  1.1212 +
  1.1213 +	if (DPTest::Attributes() & DPTest::ERomPaging)
  1.1214 +		{
  1.1215 +		test.Next(_L("Test passing descriptor headers in paged-out memory"));
  1.1216 +		__KHEAP_MARK;
  1.1217 +
  1.1218 +		DPTest::FlushCache();
  1.1219 +		TInt r = MySession.Send(5,TIpcArgs(PagedHeaderDes));
  1.1220 +		test_Equal(KErrNone, r);
  1.1221 +		
  1.1222 +		UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
  1.1223 +		__KHEAP_MARKEND;
  1.1224 +		}
  1.1225 +	
  1.1226 +	test.Next(_L("Stop server"));
  1.1227 +	MySession.Send(0,TIpcArgs(0));
  1.1228 +	MySession.Close();
  1.1229 +	t.Logon(s);
  1.1230 +	User::WaitForRequest(s);
  1.1231 +	test_Equal(EExitKill, t.ExitType());
  1.1232 +	test_Equal(KErrNone, t.ExitReason());
  1.1233 +	CLOSE_AND_WAIT(t);	
  1.1234 +	test.End();
  1.1235 +	
  1.1236 +	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
  1.1237 +	__KHEAP_MARKEND;
  1.1238 +	}
  1.1239 +
  1.1240 +
  1.1241 +TInt E32Main()
  1.1242 +	{
  1.1243 +	test.Title();
  1.1244 +	
  1.1245 +	test_KErrNone(UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&PageSize,0));
  1.1246 +	
  1.1247 +	if (DPTest::Attributes() & DPTest::ERomPaging)
  1.1248 +		test.Printf(_L("Rom paging supported\n"));
  1.1249 +	if (DPTest::Attributes() & DPTest::ECodePaging)
  1.1250 +		test.Printf(_L("Code paging supported\n"));
  1.1251 +	if (DPTest::Attributes() & DPTest::EDataPaging)
  1.1252 +		{
  1.1253 +		test.Printf(_L("Data paging supported\n"));
  1.1254 +		DataPagingSupported = ETrue;
  1.1255 +		TChunkCreateInfo createInfo;
  1.1256 +		createInfo.SetNormal(KMinBufferSize, KMinBufferSize);
  1.1257 +		createInfo.SetPaging(TChunkCreateInfo::EPaged);
  1.1258 +		createInfo.SetOwner(EOwnerProcess);
  1.1259 +		createInfo.SetGlobal(KChunkName);
  1.1260 +		test_KErrNone(DataPagedChunk.Create(createInfo));
  1.1261 +		test(DataPagedChunk.IsPaged()); // this is only ever called if data paging is supported
  1.1262 +		DataPagedBuffer = (TUint8*)DataPagedChunk.Base();
  1.1263 +		}
  1.1264 +		
  1.1265 +	test.Start(_L("Test HAL interface"));
  1.1266 +	TestHAL();
  1.1267 +
  1.1268 +	if (DPTest::Attributes() & DPTest::ERomPaging)
  1.1269 +		{
  1.1270 +		// Use paged part of rom for testing
  1.1271 +		TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  1.1272 +		test(romHeader->iPageableRomStart);
  1.1273 +		// todo: for some reason the first part of page of paged rom doesn't seem to get paged out
  1.1274 +		// when we flush the paging cache, hence LargeBuffer starts some way into this
  1.1275 +		LargeBuffer = (TUint8*)romHeader + romHeader->iPageableRomStart + 64 * PageSize; 
  1.1276 +		LargeBufferSize = romHeader->iPageableRomSize - 64 * PageSize;
  1.1277 +		test(LargeBufferSize > 0);
  1.1278 +		// Find a zero word in rom to set PagedHeaderDes to
  1.1279 +		TUint* ptr = (TUint*)LargeBuffer;
  1.1280 +		TUint* end = (TUint*)(LargeBuffer + LargeBufferSize);
  1.1281 +		while (*ptr && ptr < end)
  1.1282 +			++ptr;
  1.1283 +		test(*ptr == 0);
  1.1284 +		test.Printf(_L("Found zero word at %08x\n"), ptr);
  1.1285 +		PagedHeaderDes = (TDesC8*)ptr;
  1.1286 +		}
  1.1287 +	else if (DPTest::Attributes() & DPTest::ECodePaging)
  1.1288 +		{
  1.1289 +		// Use code paged DLL for testing
  1.1290 +		test_KErrNone(PagedLibrary.Load(KTCodePagingDll4));		
  1.1291 +		TGetAddressOfDataFunction func = (TGetAddressOfDataFunction)PagedLibrary.Lookup(KGetAddressOfDataFunctionOrdinal);
  1.1292 +		LargeBuffer = (TUint8*)func(LargeBufferSize);
  1.1293 +		test_NotNull(LargeBuffer);
  1.1294 +		PagedHeaderDes = (TDesC8*)LargeBuffer + 4;
  1.1295 +		}
  1.1296 +	else if (DPTest::Attributes() & DPTest::EDataPaging)
  1.1297 +		{
  1.1298 +		// Use data paged chunk for testing
  1.1299 +		LargeBuffer = DataPagedBuffer;
  1.1300 +		LargeBufferSize = KMinBufferSize;
  1.1301 +		}
  1.1302 +	else
  1.1303 +		{
  1.1304 +		test.Printf(_L("Demand Paging not supported\n"));
  1.1305 +		test.End();
  1.1306 +		return 0;
  1.1307 +		}
  1.1308 +	
  1.1309 +	test(LargeBufferSize >= KMinBufferSize);
  1.1310 +	SmallBuffer = LargeBuffer;
  1.1311 +	SmallBufferSize = KMinBufferSize;
  1.1312 +
  1.1313 +	test.Next(_L("Loading test drivers"));
  1.1314 +	TInt r = User::LoadLogicalDevice(KDemandPagingTestLddName);
  1.1315 +	test(r==KErrNone || r==KErrAlreadyExists);
  1.1316 +	test(Ldd.Open()==KErrNone);
  1.1317 +
  1.1318 +	test_KErrNone(Ldd.CreatePlatHwChunk(SharedBufferSize, SharedBufferAddr));
  1.1319 +	SharedBuffer = (TUint8*)SharedBufferAddr;
  1.1320 +
  1.1321 +	RDebug::Printf("SmallBuffer=%x, LargeBuffer=%x, SharedBuffer=%x\n",
  1.1322 +		SmallBuffer, LargeBuffer, SharedBuffer);
  1.1323 +
  1.1324 +	test.Next(_L("Gobble RAM"));
  1.1325 +	r = User::LoadLogicalDevice(KGobblerLddFileName);
  1.1326 +	test(r==KErrNone || r==KErrAlreadyExists);
  1.1327 +	RGobbler gobbler;
  1.1328 +	r = gobbler.Open();
  1.1329 +	test(r==KErrNone);
  1.1330 +	TUint32 taken = gobbler.GobbleRAM(64*1024*1024); // leave 64MB of free RAM
  1.1331 +	test.Printf(_L("Gobbled: %dK\n"), taken/1024);
  1.1332 +	test.Printf(_L("Free RAM 0x%08X bytes\n"),FreeRam());
  1.1333 +
  1.1334 +	test.Next(_L("Test contiguous RAM allocation reclaims paged memory"));
  1.1335 +	TestContiguousRamAlloc();
  1.1336 +
  1.1337 +	test.Next(_L("Test thread realtime state"));
  1.1338 +	TestRealtimeState();
  1.1339 +
  1.1340 +	test.Next(_L("Lock Test"));
  1.1341 +	TestLock();
  1.1342 +
  1.1343 +	test.Next(_L("Test writing to paged area"));
  1.1344 +	TestWriteToPagedArea();
  1.1345 +
  1.1346 +	test.Next(_L("Test IPC read from paged memory"));
  1.1347 +	TestIPC();
  1.1348 +
  1.1349 +	test.Next(_L("Test no kernel faults when copying data from unpaged rom with mutex held"));
  1.1350 +	TestReadHoldingMutex();
  1.1351 +
  1.1352 +	test.Next(_L("Close test driver"));
  1.1353 +	Ldd.DestroyPlatHwChunk();
  1.1354 +	Ldd.Close();
  1.1355 +
  1.1356 +	test.Next(_L("Test setting publish and subscribe properties from paged area"));
  1.1357 +	TestPublishAndSubscribe();
  1.1358 +
  1.1359 +	if (DPTest::Attributes() & DPTest::ERomPaging)
  1.1360 +		{
  1.1361 +		test.Next(_L("Rom Paging Benchmark"));
  1.1362 +		RomPagingBenchmark();
  1.1363 +		}
  1.1364 +
  1.1365 +	PagedLibrary.Close();
  1.1366 +	gobbler.Close();
  1.1367 +	test.End();
  1.1368 +
  1.1369 +	return 0;
  1.1370 +	}