sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\mmu\t_demandpaging.cpp sl@0: // Functional tests for demand paging. The test suite covers simple sl@0: // paging operations as well as HAL configuration and tuning functions. sl@0: // 001.01 DPTest::Attributes sl@0: // 001.02 DPTest::FlushCache sl@0: // 001.03 DPTest::CacheSize sl@0: // 001.04 DPTest::SetCacheSize sl@0: // 001.04.01 Changing size of flushed VM cache sl@0: // 001.04.02 Changing size of full VM cache sl@0: // 002 Loading test drivers sl@0: // 003 Test thread realtime state sl@0: // 003.01 Enable KREALTIME tracing sl@0: // 003.02 Test ERealtimeStateOff sl@0: // 003.03 Test ERealtimeStateOn sl@0: // 003.04 Test ERealtimeStateWarn sl@0: // 003.05 Test server with ERealtimeStateOff sl@0: // 003.06 Test server with ERealtimeStateOn sl@0: // 003.07 Test server with ERealtimeStateWarn sl@0: // 003.08 Disable KREALTIME tracing sl@0: // 004 Lock Test sl@0: // 005 Lock Test again sl@0: // 006 Test writing to paged ROM sl@0: // 007 Test IPC read from paged memory sl@0: // 007.01 Create server sl@0: // 007.02 IPC read from ROM sl@0: // 007.03 Stop server sl@0: // 008 Test contiguous RAM allocation reclaims paged memory sl@0: // 008.01 Start... sl@0: // 008.02 Contiguous RAM test: alloc size = 128K align = 16 sl@0: // 008.03 Contiguous RAM test: alloc size = 128K align = 0 sl@0: // 008.04 Contiguous RAM test: alloc size = 64K align = 15 sl@0: // 008.05 Contiguous RAM test: alloc size = 64K align = 14 sl@0: // 008.06 Contiguous RAM test: alloc size = 64K align = 13 sl@0: // 008.07 Contiguous RAM test: alloc size = 64K align = 12 sl@0: // 008.08 Contiguous RAM test: alloc size = 64K align = 0 sl@0: // 008.09 Contiguous RAM test: alloc size = 8K align = 13 sl@0: // 008.10 Contiguous RAM test: alloc size = 8K align = 12 sl@0: // 008.11 Contiguous RAM test: alloc size = 8K align = 0 sl@0: // 008.12 Contiguous RAM test: alloc size = 4K align = 13 sl@0: // 008.13 Contiguous RAM test: alloc size = 4K align = 12 sl@0: // 008.14 Contiguous RAM test: alloc size = 4K align = 0 sl@0: // 009 Test no kernel faults when copying data from unpaged rom with mutex held sl@0: // 010 Close test driver sl@0: // 011 Test setting publish and subscribe properties from paged area sl@0: // 012 Rom Paging Benchmark sl@0: // 012.01 Benchmark ROM paging... sl@0: // sl@0: // sl@0: sl@0: //! @SYMTestCaseID KBASE-T_DEMANDPAGING-0334 sl@0: //! @SYMTestType UT sl@0: //! @SYMPREQ PREQ1110 sl@0: //! @SYMTestCaseDesc Demand Paging functional tests. sl@0: //! @SYMTestActions 001 Test HAL interface sl@0: //! @SYMTestExpectedResults All tests should pass. sl@0: //! @SYMTestPriority High sl@0: //! @SYMTestStatus Implemented sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "d_memorytest.h" sl@0: #include "d_demandpaging.h" sl@0: #include "d_gobble.h" sl@0: #include "mmudetect.h" sl@0: #include "t_codepaging_dll.h" sl@0: #include "freeram.h" sl@0: sl@0: RTest test(_L("T_DEMANDPAGING")); sl@0: sl@0: _LIT(KTCodePagingDll4, "t_codepaging_dll4.dll"); sl@0: const TInt KMinBufferSize = 16384; sl@0: const TInt KMaxIPCSize = 256*1024; sl@0: sl@0: TInt PageSize = 0; sl@0: RDemandPagingTestLdd Ldd; sl@0: RLibrary PagedLibrary; sl@0: sl@0: // A buffer containing paged memory, contents may or may not be paged in sl@0: const TUint8* LargeBuffer = NULL; sl@0: TInt LargeBufferSize = 0; sl@0: sl@0: // A buffer containing paged memeory, contents always paged out before access sl@0: const TUint8* SmallBuffer = NULL; sl@0: TInt SmallBufferSize = 0; sl@0: sl@0: // A shared buffer mapped to the global address range sl@0: TInt SharedBufferSize = KMaxIPCSize+4096; sl@0: TLinAddr SharedBufferAddr = 0; sl@0: TUint8* SharedBuffer = NULL; sl@0: sl@0: // A descriptor whose header is in paged memory (actually just a pointer to a zero word) sl@0: TDesC8* PagedHeaderDes = NULL; sl@0: sl@0: // A data paged chunk used as a buffer, if data paging is supported sl@0: _LIT(KChunkName, "t_demandpaging chunk"); sl@0: RChunk DataPagedChunk; sl@0: TBool DataPagingSupported = EFalse; sl@0: TUint8* DataPagedBuffer = NULL; sl@0: sl@0: TUint8 ReadByte(volatile TUint8* aPtr) sl@0: { sl@0: return *aPtr; sl@0: } sl@0: sl@0: #define READ(a) ReadByte((volatile TUint8*)(a)) sl@0: sl@0: void ThrashPaging(TUint aMaxBytes=KMaxTUint) sl@0: { sl@0: TUint size = LargeBufferSize; sl@0: if(size>aMaxBytes) sl@0: size = aMaxBytes; sl@0: sl@0: // read all ROM pages about 10 times each in a random order... sl@0: TUint32 random=1; sl@0: for(TInt i=size/(PageSize/10); i>0; --i) sl@0: { sl@0: READ(LargeBuffer+((TInt64(random)*TInt64(size))>>32)); sl@0: random = random*69069+1; sl@0: } sl@0: } sl@0: sl@0: void FragmentPagingCache(TUint aMaxBytes) sl@0: { sl@0: DPTest::FlushCache(); sl@0: sl@0: TUint size = Min(LargeBufferSize, aMaxBytes); sl@0: if(size events0; sl@0: DPTest::EventInfo(events0); sl@0: sl@0: TInt KRunTime = 10*1000*1000; sl@0: timer.After(status,KRunTime); sl@0: while(status==KRequestPending) sl@0: for(const TUint8* ptr=LargeBuffer; ptr<(LargeBuffer+LargeBufferSize); ptr+=PageSize) sl@0: { sl@0: READ(ptr); sl@0: if(status!=KRequestPending) sl@0: break; sl@0: } sl@0: sl@0: TPckgBuf events1; sl@0: DPTest::EventInfo(events1); sl@0: sl@0: User::WaitForRequest(status); sl@0: sl@0: TUint pages = events1().iPageInReadCount-events0().iPageInReadCount; sl@0: test.Printf(_L("%d pages in %d seconds = %d us/page\n"),pages,KRunTime/1000/1000,KRunTime/pages); sl@0: sl@0: // restore live list to default size... sl@0: test(KErrNone==DPTest::SetCacheSize(0,0)); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: void TestResizeVMCache() sl@0: { sl@0: TInt r = DPTest::SetCacheSize(0,0); // restore cache size to defaults sl@0: test(r==KErrNone); sl@0: TUint sizeMin = 0; sl@0: TUint sizeMax = 0; sl@0: TUint currentSize = 0; sl@0: DPTest::CacheSize(sizeMin,sizeMax,currentSize); sl@0: TUint originalMin = sizeMin; sl@0: TUint originalMax = sizeMax; sl@0: test.Printf(_L("original min=%u, original max=%u, current=%u\n"),originalMin/PageSize,originalMax/PageSize,currentSize/PageSize); sl@0: sl@0: int K = currentSize/PageSize+4; sl@0: sl@0: struct sl@0: { sl@0: TUint iMinPages; sl@0: TUint iMaxPages; sl@0: TInt iResult; sl@0: } sl@0: testArgs[] = sl@0: { sl@0: { K, K, KErrNone}, sl@0: { K-4, K, KErrNone}, sl@0: { K, K, KErrNone}, sl@0: { K, K*2, KErrNone}, sl@0: { K, K, KErrNone}, sl@0: { K-1, K, KErrNone}, sl@0: { K, K, KErrNone}, sl@0: { K, K+1, KErrNone}, sl@0: { K, K, KErrNone}, sl@0: { K+1, K, KErrArgument}, sl@0: { K, K-1, KErrArgument}, sl@0: { KMaxTInt, KMaxTInt, KErrNoMemory}, sl@0: { K, K, KErrNone}, sl@0: sl@0: { 0, 0, KErrNone}, // restore defaults sl@0: { 0, 0, KMaxTInt} // list end marker sl@0: }; sl@0: sl@0: for(TInt j=0; j<2; ++j) sl@0: { sl@0: if(!j) sl@0: { sl@0: test.Start(_L("Changing size of flushed VM cache")); sl@0: test.Printf(_L("Original cache size min == %u, max == %u\n"),originalMin/PageSize,originalMax/PageSize); sl@0: } sl@0: else sl@0: test.Next(_L("Changing size of full VM cache")); sl@0: TInt i=0; sl@0: while(testArgs[i].iResult!=KMaxTInt) sl@0: { sl@0: TUint min=testArgs[i].iMinPages*PageSize; sl@0: TUint max=testArgs[i].iMaxPages*PageSize; sl@0: TInt result=testArgs[i].iResult; sl@0: sl@0: ThrashPaging(max*2); sl@0: if(!j) sl@0: DPTest::FlushCache(); sl@0: sl@0: test.Printf(_L("DPTest::SetCacheSize min=%u, max=%u, expected result=%d\n"),min/PageSize,max/PageSize,result); sl@0: TInt r=DPTest::SetCacheSize(min,max); sl@0: if(r!=result) sl@0: { sl@0: test.Printf(_L("result=%d\n"),r); sl@0: test(0); sl@0: } sl@0: if(r==KErrNone) sl@0: { sl@0: // we've successfully changed the cache size... sl@0: if(max) sl@0: { sl@0: sizeMin = min; sl@0: sizeMax = max; sl@0: } sl@0: else sl@0: { sl@0: sizeMin = originalMin; sl@0: sizeMax = originalMax; sl@0: } sl@0: } sl@0: if(r==KErrNoMemory) sl@0: { sl@0: // cache size after OOM is unpredictable, so reset our values sl@0: DPTest::SetCacheSize(sizeMin,sizeMax); sl@0: } sl@0: else sl@0: { sl@0: // test 'get' function returns expected cache size sl@0: r=DPTest::CacheSize(min,max,currentSize); sl@0: test.Printf(_L("DPTest::CacheSize result=%d min=%u max=%u current=%u\n"),r,min/PageSize,max/PageSize,currentSize/PageSize); sl@0: if(r!=KErrNone || min!=sizeMin || max!=sizeMax) sl@0: test(0); sl@0: test(currentSize >= min && currentSize <= max); sl@0: } sl@0: ++i; sl@0: } sl@0: } sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: sl@0: void TestResizeVMCache2() sl@0: { sl@0: TUint originalMin = 0; sl@0: TUint originalMax = 0; sl@0: TUint currentSize = 0; sl@0: test_KErrNone(DPTest::CacheSize(originalMax, originalMax, currentSize)); sl@0: test_KErrNone(DPTest::SetCacheSize(1, originalMax)); sl@0: TUint sizeMin = 0; sl@0: TUint sizeMax = 0; sl@0: test_KErrNone(DPTest::CacheSize(sizeMin, sizeMax, currentSize)); sl@0: test(sizeMin > 1); sl@0: test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax)); sl@0: } sl@0: sl@0: sl@0: void TestHAL() sl@0: { sl@0: test.Start(_L("DPTest::Attributes")); sl@0: TUint32 attr=DPTest::Attributes(); sl@0: test.Printf(_L("Attributes = %08x\n"),attr); sl@0: sl@0: test.Next(_L("DPTest::FlushCache")); sl@0: TInt r=DPTest::FlushCache(); sl@0: if(r==KErrNotSupported) sl@0: test.Printf(_L("Not Supported\n")); sl@0: else if(r<0) sl@0: { sl@0: test.Printf(_L("Error = %d\n"),r); sl@0: test(0); sl@0: } sl@0: sl@0: test.Next(_L("DPTest::CacheSize")); sl@0: TUint oldMin = 0; sl@0: TUint oldMax = 0; sl@0: TUint currentSize = 0; sl@0: r=DPTest::CacheSize(oldMin,oldMax,currentSize); sl@0: if(r==KErrNotSupported) sl@0: test.Printf(_L("Not Supported\n")); sl@0: else if(r<0) sl@0: { sl@0: test.Printf(_L("Error = %d\n"),r); sl@0: test(0); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L("Size = %dk,%dk,%dk\n"),oldMin>>10,oldMax>>10,currentSize>>10); sl@0: } sl@0: sl@0: test.Next(_L("DPTest::SetCacheSize")); sl@0: r=DPTest::SetCacheSize(oldMin,oldMax); sl@0: if(r==KErrNotSupported) sl@0: test.Printf(_L("Not Supported\n")); sl@0: else if(r<0) sl@0: { sl@0: test.Printf(_L("Error = %d\n"),r); sl@0: test(0); sl@0: } sl@0: if(r==KErrNone) sl@0: { sl@0: TestResizeVMCache(); sl@0: TestResizeVMCache2(); sl@0: } sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: // Test IPC and realtime state sl@0: sl@0: enum TIpcDir sl@0: { sl@0: EServerRead, sl@0: EServerWrite sl@0: }; sl@0: sl@0: enum TIpcObjectPaged sl@0: { sl@0: ENothingPaged, sl@0: EDesHeaderPaged, sl@0: EDesContentPaged sl@0: }; sl@0: sl@0: enum TRealtimeOutcome sl@0: { sl@0: ENoError, sl@0: EBadDescriptor, sl@0: EServerTerminated, sl@0: ERealtimePanic sl@0: }; sl@0: sl@0: class RTestSession : public RSessionBase sl@0: { sl@0: public: sl@0: TInt Create(RServer2 aServer) sl@0: { sl@0: return CreateSession(aServer,TVersion(),-1); sl@0: } sl@0: inline TInt Send(const TIpcArgs& aArgs) sl@0: { sl@0: return RSessionBase::SendReceive(0,aArgs); sl@0: } sl@0: }; sl@0: sl@0: RServer2 TestServer; sl@0: sl@0: TInt IpcTestServerFunc(TAny* aArg) sl@0: { sl@0: TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff); sl@0: TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff); sl@0: User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff); sl@0: User::TRealtimeState clientRealtime = (User::TRealtimeState)((((TInt)aArg) >> 24) & 0xff); sl@0: sl@0: TInt r; sl@0: // We want the server to fault the client when it is realtime sl@0: // and accessing paged out memory. sl@0: r = TestServer.CreateGlobal(KNullDesC, EIpcSession_Sharable, EServerRole_Default, EServerOpt_PinClientDescriptorsDisable); sl@0: if (r != KErrNone) sl@0: return r; sl@0: RThread::Rendezvous(KErrNone); sl@0: sl@0: RMessage2 message; sl@0: TestServer.Receive(message); sl@0: if ((clientRealtime == User::ERealtimeStateOn) != message.ClientIsRealtime()) sl@0: return KErrGeneral; sl@0: message.Complete(KErrNone); // complete connection request sl@0: sl@0: TRequestStatus s; sl@0: TestServer.Receive(message,s); sl@0: User::WaitForRequest(s); sl@0: if (s != KErrNone) sl@0: return s.Int(); sl@0: sl@0: TInt32 unpagedContent; sl@0: TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4); sl@0: TPtrC8 pagedContentBuf(SmallBuffer,sizeof(TInt)); sl@0: sl@0: TPtr8* dataPagedHeaderDes = (TPtr8*)DataPagedBuffer; sl@0: if (DataPagingSupported) sl@0: new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4); sl@0: sl@0: TPtr8 dataPagedContentDes(DataPagedBuffer + PageSize, 4); sl@0: sl@0: r = DPTest::FlushCache(); sl@0: if(r != KErrNone) sl@0: return r; sl@0: sl@0: User::SetRealtimeState(realtime); sl@0: if (dir == EServerRead) sl@0: { sl@0: switch (paged) sl@0: { sl@0: case ENothingPaged: sl@0: r = message.Read(0,unpagedDes); sl@0: break; sl@0: sl@0: case EDesHeaderPaged: sl@0: r = DataPagingSupported ? message.Read(0,*dataPagedHeaderDes) : KErrNotSupported; sl@0: break; sl@0: sl@0: case EDesContentPaged: sl@0: r = DataPagingSupported ? message.Read(0,dataPagedContentDes) : KErrNotSupported; sl@0: break; sl@0: sl@0: default: sl@0: r = KErrArgument; sl@0: break; sl@0: } sl@0: } sl@0: else if (dir == EServerWrite) sl@0: { sl@0: switch (paged) sl@0: { sl@0: case ENothingPaged: sl@0: r = message.Write(0,unpagedDes); sl@0: break; sl@0: sl@0: case EDesHeaderPaged: sl@0: r = message.Write(0,*PagedHeaderDes); sl@0: break; sl@0: sl@0: case EDesContentPaged: sl@0: r = message.Write(0,pagedContentBuf); sl@0: break; sl@0: sl@0: default: sl@0: r = KErrArgument; sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: r = KErrArgument; sl@0: User::SetRealtimeState(User::ERealtimeStateOff); sl@0: sl@0: message.Complete(KErrNone); sl@0: return r; sl@0: } sl@0: sl@0: TInt IpcTestClientFunc(TAny* aArg) sl@0: { sl@0: TIpcDir dir = (TIpcDir)(((TInt)aArg) & 0xff); sl@0: TIpcObjectPaged paged = (TIpcObjectPaged)((((TInt)aArg) >> 8) & 0xff); sl@0: User::TRealtimeState realtime = (User::TRealtimeState)((((TInt)aArg) >> 16) & 0xff); sl@0: sl@0: RTestSession session; sl@0: TInt r = session.Create(TestServer); sl@0: if(r != KErrNone) sl@0: return r; sl@0: sl@0: TInt32 unpagedContent; sl@0: TPtr8 unpagedDes((TUint8*)&unpagedContent, 4, 4); sl@0: TPtrC8 pagedContentBuf(SmallBuffer + PageSize, sizeof(TInt)); sl@0: sl@0: TPtr8* dataPagedHeaderDes = (TPtr8*)(DataPagedBuffer + (2 * PageSize)); sl@0: if (DataPagingSupported) sl@0: new (dataPagedHeaderDes) TPtr8((TUint8*)&unpagedContent, 4); sl@0: sl@0: TPtr8 dataPagedContentDes(DataPagedBuffer + (3 * PageSize), 4); sl@0: sl@0: r = DPTest::FlushCache(); sl@0: if(r != KErrNone) sl@0: return r; sl@0: sl@0: User::SetRealtimeState(realtime); sl@0: if (dir == EServerRead) sl@0: { sl@0: switch (paged) sl@0: { sl@0: case ENothingPaged: sl@0: r = session.Send(TIpcArgs(&unpagedDes)); sl@0: break; sl@0: sl@0: case EDesHeaderPaged: sl@0: r = session.Send(TIpcArgs(PagedHeaderDes)); sl@0: break; sl@0: sl@0: case EDesContentPaged: sl@0: r = session.Send(TIpcArgs(&pagedContentBuf)); sl@0: break; sl@0: sl@0: default: sl@0: r = KErrArgument; sl@0: break; sl@0: } sl@0: } sl@0: else if (dir == EServerWrite) sl@0: { sl@0: switch (paged) sl@0: { sl@0: case ENothingPaged: sl@0: r = session.Send(TIpcArgs(&unpagedDes)); sl@0: break; sl@0: sl@0: case EDesHeaderPaged: sl@0: r = DataPagingSupported ? session.Send(TIpcArgs(dataPagedHeaderDes)) : KErrNotSupported; sl@0: break; sl@0: sl@0: case EDesContentPaged: sl@0: r = DataPagingSupported ? session.Send(TIpcArgs(&dataPagedContentDes)) : KErrNotSupported; sl@0: break; sl@0: sl@0: default: sl@0: r = KErrArgument; sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: r = KErrArgument; sl@0: User::SetRealtimeState(User::ERealtimeStateOff); sl@0: sl@0: session.Close(); sl@0: return r; sl@0: } sl@0: sl@0: void TestRealtimeOutcome(RThread aThread, TRealtimeOutcome aOutcome) sl@0: { sl@0: switch(aOutcome) sl@0: { sl@0: case ENoError: sl@0: test_Equal(EExitKill, aThread.ExitType()); sl@0: test_KErrNone(aThread.ExitReason()); sl@0: break; sl@0: sl@0: case EBadDescriptor: sl@0: test_Equal(EExitKill, aThread.ExitType()); sl@0: test_Equal(KErrBadDescriptor, aThread.ExitReason()); sl@0: break; sl@0: sl@0: case EServerTerminated: sl@0: test_Equal(EExitKill, aThread.ExitType()); sl@0: test_Equal(KErrServerTerminated, aThread.ExitReason()); sl@0: break; sl@0: sl@0: case ERealtimePanic: sl@0: test_Equal(EExitPanic, aThread.ExitType()); sl@0: test(aThread.ExitCategory()==_L("KERN-EXEC")); sl@0: test_Equal(EIllegalFunctionForRealtimeThread, aThread.ExitReason()); sl@0: break; sl@0: sl@0: default: sl@0: test(EFalse); sl@0: } sl@0: } sl@0: sl@0: void TestPagedIpc(TIpcDir aIpcDir, sl@0: TIpcObjectPaged aClientPaged, sl@0: TIpcObjectPaged aServerPaged, sl@0: User::TRealtimeState aClientState, sl@0: User::TRealtimeState aServerState, sl@0: TRealtimeOutcome aClientOutcome, sl@0: TRealtimeOutcome aServerOutcome) sl@0: { sl@0: test.Printf(_L("TestPagedIpc %d %d %d %d %d %d %d\n"), aIpcDir, aClientPaged, aServerPaged, sl@0: aClientState, aServerState, aClientOutcome, aServerOutcome); sl@0: sl@0: RThread serverThread; sl@0: RThread clientThread; sl@0: TRequestStatus serverStatus; sl@0: TRequestStatus clientStatus; sl@0: sl@0: TInt serverArg = aIpcDir | (aServerPaged << 8) | (aServerState << 16) | (aClientState << 24); sl@0: test_KErrNone(serverThread.Create(KNullDesC, &IpcTestServerFunc, 0x1000, NULL, (TAny*)serverArg)); sl@0: TName name; sl@0: name = serverThread.Name(); sl@0: test.Printf(_L(" server: %S\n"), &name); sl@0: serverThread.Rendezvous(serverStatus); sl@0: serverThread.Resume(); sl@0: User::WaitForRequest(serverStatus); sl@0: test_KErrNone(serverStatus.Int()); sl@0: serverThread.Logon(serverStatus); sl@0: sl@0: TInt clientArg = aIpcDir | (aClientPaged << 8) | (aClientState << 16); sl@0: test_KErrNone(clientThread.Create(KNullDesC, &IpcTestClientFunc, 0x1000, NULL, (TAny*)clientArg)); sl@0: name = clientThread.Name(); sl@0: test.Printf(_L(" client: %S\n"), &name); sl@0: clientThread.Logon(clientStatus); sl@0: clientThread.Resume(); sl@0: sl@0: User::WaitForRequest(serverStatus); sl@0: test.Printf(_L(" server exit type is %d %d\n"), serverThread.ExitType(), serverThread.ExitReason()); sl@0: TestServer.Close(); // because handle is process-relative, it's not closed if the server dies sl@0: sl@0: User::WaitForRequest(clientStatus); sl@0: test.Printf(_L(" client exit type is %d %d\n"), clientThread.ExitType(), clientThread.ExitReason()); sl@0: sl@0: TestRealtimeOutcome(serverThread, aServerOutcome); sl@0: TestRealtimeOutcome(clientThread, aClientOutcome); sl@0: sl@0: CLOSE_AND_WAIT(serverThread); sl@0: CLOSE_AND_WAIT(clientThread); sl@0: } sl@0: sl@0: TInt TestThreadFunction(TAny* aType) sl@0: { sl@0: // Ensure that pageable memory is paged out sl@0: TInt r=DPTest::FlushCache(); sl@0: if(r!=KErrNone) sl@0: return r; sl@0: sl@0: // Access pageable data whilst thread is in specified realttime state. sl@0: User::SetRealtimeState((User::TRealtimeState)(TInt)aType); sl@0: READ(SmallBuffer); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt RunTestThread(User::TRealtimeState aType, TRealtimeOutcome aOutcome) sl@0: { sl@0: RThread thread; sl@0: TInt r=thread.Create(KNullDesC, &TestThreadFunction, 0x1000, NULL, (TAny*)aType); sl@0: if(r!=KErrNone) sl@0: return r; sl@0: TRequestStatus s; sl@0: thread.Logon(s); sl@0: if(s.Int()!=KRequestPending) sl@0: return s.Int(); sl@0: thread.Resume(); sl@0: User::WaitForRequest(s); sl@0: TestRealtimeOutcome(thread, aOutcome); sl@0: CLOSE_AND_WAIT(thread); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void TestRealtimeState() sl@0: { sl@0: // make sure live list is big enough sl@0: test(KErrNone==DPTest::SetCacheSize(256*PageSize,256*PageSize)); sl@0: sl@0: test.Start(_L("Enable KREALTIME tracing")); sl@0: Ldd.SetRealtimeTrace(ETrue); sl@0: sl@0: test.Next(_L("Test ERealtimeStateOff")); sl@0: RunTestThread(User::ERealtimeStateOff, ENoError); sl@0: sl@0: test.Next(_L("Test ERealtimeStateOn")); sl@0: RunTestThread(User::ERealtimeStateOn, ERealtimePanic); sl@0: sl@0: test.Next(_L("Test ERealtimeStateWarn")); sl@0: RunTestThread(User::ERealtimeStateWarn, ENoError); sl@0: sl@0: test.Next(_L("Test combinations of IPC with realtime state")); sl@0: sl@0: // ipc dir: client paged: server paged: client state: server state: client outcome: server outcome: sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: sl@0: if (DataPagingSupported) sl@0: { sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOff, ENoError, ENoError); sl@0: } sl@0: sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: sl@0: if (DataPagingSupported) sl@0: { sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateWarn, ENoError, ENoError); sl@0: } sl@0: sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ERealtimePanic, EBadDescriptor); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic); sl@0: sl@0: if (DataPagingSupported) sl@0: { sl@0: TestPagedIpc(EServerRead, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesHeaderPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic); sl@0: TestPagedIpc(EServerRead, ENothingPaged, EDesContentPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, EServerTerminated, ERealtimePanic); sl@0: TestPagedIpc(EServerWrite, ENothingPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesHeaderPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ENoError, ENoError); sl@0: TestPagedIpc(EServerWrite, EDesContentPaged, ENothingPaged, User::ERealtimeStateOff, User::ERealtimeStateOn, ERealtimePanic, EBadDescriptor); sl@0: } sl@0: sl@0: test.End(); sl@0: sl@0: // retore size of live list sl@0: test(KErrNone==DPTest::SetCacheSize(0,0)); sl@0: } sl@0: sl@0: void TestLock() sl@0: { sl@0: // make sure live list is big enough sl@0: test(KErrNone==DPTest::SetCacheSize(128 * PageSize, 256 * PageSize)); sl@0: sl@0: TInt r = Ldd.LockTest(SmallBuffer,SmallBufferSize); sl@0: if(r==KErrNone) sl@0: { sl@0: test.Next(_L("Lock Test again")); sl@0: r = Ldd.LockTest(SmallBuffer,SmallBufferSize); sl@0: } sl@0: if(r) sl@0: { sl@0: test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r); sl@0: test(0); sl@0: } sl@0: sl@0: // restore live list to default size... sl@0: test(KErrNone==DPTest::SetCacheSize(0,0)); sl@0: } sl@0: sl@0: const TInt KSmallPropertySize = 512; sl@0: const TInt KLargePropertySize = 16384; sl@0: sl@0: struct SSetPropertyInfo sl@0: { sl@0: TUid iCategory; sl@0: TInt iKey; sl@0: TUint8* iData; sl@0: TInt iLength; sl@0: }; sl@0: sl@0: TInt SetPropertyThreadFunction(TAny* aArg) sl@0: { sl@0: SSetPropertyInfo* info = (SSetPropertyInfo*)aArg; sl@0: TInt r; sl@0: r = DPTest::FlushCache(); sl@0: if (r != KErrNone) sl@0: return r; sl@0: TPtrC8 data(info->iData, info->iLength); sl@0: r = RProperty::Set(info->iCategory, info->iKey, data); sl@0: if (r != KErrNone) sl@0: return r; sl@0: RBuf8 buffer; sl@0: r = buffer.Create(KLargePropertySize); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = RProperty::Get(info->iCategory, info->iKey, buffer); sl@0: if (r == KErrNone && buffer != data) sl@0: r = KErrGeneral; sl@0: buffer.Close(); sl@0: return r; sl@0: } sl@0: sl@0: void TestPublishAndSubscribe() sl@0: { sl@0: RProcess thisProcess; sl@0: TUid category = thisProcess.SecureId(); sl@0: sl@0: TSecurityPolicy alwaysPass(TSecurityPolicy::EAlwaysPass); sl@0: test(RProperty::Define(category, 0, RProperty::EByteArray, alwaysPass, alwaysPass) == KErrNone); sl@0: test(RProperty::Define(category, 1, RProperty::ELargeByteArray, alwaysPass, alwaysPass) == KErrNone); sl@0: sl@0: TPtrC8 smallData(SmallBuffer, KSmallPropertySize); sl@0: TPtrC8 largeData(SmallBuffer, KLargePropertySize); sl@0: sl@0: RBuf8 buffer; sl@0: test(buffer.Create(KLargePropertySize) == KErrNone); sl@0: sl@0: // Set small property from paged data, method 1 sl@0: test(DPTest::FlushCache() == KErrNone); sl@0: test(RProperty::Set(category, 0, smallData) == KErrNone); sl@0: test(RProperty::Get(category, 0, buffer) == KErrNone); sl@0: test(buffer == smallData); sl@0: sl@0: // Set small property from paged data, method 2 sl@0: RProperty smallProp; sl@0: test(smallProp.Attach(category, 0) == KErrNone); sl@0: test(DPTest::FlushCache() == KErrNone); sl@0: test(smallProp.Set(smallData) == KErrNone); sl@0: test(smallProp.Get(buffer) == KErrNone); sl@0: test(buffer == smallData); sl@0: sl@0: // Set large property from paged data, method 1 sl@0: test(DPTest::FlushCache() == KErrNone); sl@0: test(RProperty::Set(category, 1, largeData) == KErrNone); sl@0: test(RProperty::Get(category, 1, buffer) == KErrNone); sl@0: test(buffer == largeData); sl@0: sl@0: // Set large property from paged data, method 2 sl@0: RProperty largeProp; sl@0: test(largeProp.Attach(category, 1) == KErrNone); sl@0: test(DPTest::FlushCache() == KErrNone); sl@0: test(largeProp.Set(largeData) == KErrNone); sl@0: test(largeProp.Get(buffer) == KErrNone); sl@0: test(buffer == largeData); sl@0: sl@0: // Set small property from unmapped address sl@0: RThread thread; sl@0: #if !defined( __VC32__) sl@0: SSetPropertyInfo info = { category, 0, 0, KSmallPropertySize }; sl@0: #else sl@0: SSetPropertyInfo info = { category.iUid, 0, 0, KSmallPropertySize }; sl@0: #endif sl@0: test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone); sl@0: thread.Resume(); sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(thread.ExitType()==EExitPanic); sl@0: test(thread.ExitCategory()==_L("KERN-EXEC")); sl@0: test(thread.ExitReason()==ECausedException); sl@0: thread.Close(); sl@0: sl@0: // Set large property from unmapped address sl@0: info.iKey = 1; sl@0: info.iLength = KLargePropertySize; sl@0: test(thread.Create(_L("SetPropertyThread"), SetPropertyThreadFunction, 4096, NULL, &info) == KErrNone); sl@0: thread.Resume(); sl@0: thread.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(thread.ExitType()==EExitPanic); sl@0: test(thread.ExitCategory()==_L("KERN-EXEC")); sl@0: test(thread.ExitReason()==ECausedException); sl@0: thread.Close(); sl@0: sl@0: test(RProperty::Delete(category, 0) == KErrNone); sl@0: test(RProperty::Delete(category, 1) == KErrNone); sl@0: } sl@0: sl@0: void TestWriteToPagedArea() sl@0: { sl@0: RMemoryTestLdd memoryTest; sl@0: test(KErrNone==memoryTest.Open()); sl@0: sl@0: TModuleMemoryInfo exeInfo; sl@0: test(KErrNone==RProcess().GetMemoryInfo(exeInfo)); sl@0: test.Printf(_L("test program code is %x+%x"),exeInfo.iCodeBase,exeInfo.iCodeSize); sl@0: sl@0: TUint8* ptr = const_cast(LargeBuffer); sl@0: TUint8* end = ptr + LargeBufferSize; sl@0: while(ptr=(TUint8*)_ALIGN_DOWN(exeInfo.iCodeBase,PageSize) && ptr<(TUint8*)_ALIGN_UP(exeInfo.iCodeBase+exeInfo.iCodeSize,PageSize)) sl@0: { sl@0: // avoid testing the ROM which contains this test program sl@0: ptr += PageSize; sl@0: continue; sl@0: } sl@0: sl@0: DPTest::FlushCache(); sl@0: sl@0: TInt stateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0); sl@0: test(stateBits>=0); sl@0: // write to paged out memory should cause exception... sl@0: test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,0)); sl@0: // page state should be unchanged... sl@0: TInt newStateBits = UserSvr::HalFunction(EHalGroupVM, EVMPageState, ptr, 0); sl@0: if(stateBits!=newStateBits) sl@0: { sl@0: test.Printf(_L("ptr=%x stateBits=%x newStateBits=%x"),ptr,stateBits,newStateBits); sl@0: test(0); sl@0: } sl@0: // page-in in memory... sl@0: TUint32 value = *(TUint32*)ptr; sl@0: // write to paged out memory should still cause exception... sl@0: test(KErrBadDescriptor==memoryTest.WriteMemory(ptr,~value)); sl@0: // memory should be unchanged... sl@0: test(value==*(TUint32*)ptr); sl@0: ptr += PageSize; sl@0: } sl@0: sl@0: memoryTest.Close(); sl@0: } sl@0: sl@0: void TestContiguousRamAlloc() sl@0: { sl@0: test.Start(_L("Start...")); sl@0: sl@0: const TInt KCacheSize = 1024*1024; sl@0: sl@0: DPTest::SetCacheSize(0, KCacheSize); // make sure paging cache is a reasonable size sl@0: sl@0: TInt testData[][2] = /* array of page size (in units of 'half pages') and align values */ sl@0: { sl@0: {64,5}, sl@0: {64,0}, sl@0: {32,4}, sl@0: {32,3}, sl@0: {32,2}, sl@0: {32,1}, sl@0: {32,0}, sl@0: {4,2}, sl@0: {4,1}, sl@0: {4,0}, sl@0: {2,2}, sl@0: {2,1}, sl@0: {2,0}, sl@0: {1,0}, sl@0: {0,0} sl@0: }; sl@0: TInt pageShift = 1; sl@0: while((1< title; sl@0: title.AppendFormat(_L("Contiguous RAM test: alloc size = %dK align = %d"),size>>10, align); sl@0: test.Next(title); sl@0: FragmentPagingCache(KCacheSize); sl@0: TInt r = Ldd.DoConsumeContiguousRamTest(align, size); sl@0: if(r) sl@0: { sl@0: test.Printf(_L("failed at D_DEMANPAGING.CPP line %d\n"),r); sl@0: test(0); sl@0: } sl@0: } sl@0: sl@0: DPTest::SetCacheSize(0,0); // back to defaults sl@0: test.End(); sl@0: } sl@0: sl@0: void TestReadHoldingMutex() sl@0: { sl@0: TUint8 localBuf[16]; sl@0: TUint8* localPtr = localBuf; sl@0: if(DPTest::Attributes() & DPTest::EDataPaging) // if data paging supported... sl@0: localPtr = 0; // use zero to make driver use kernel memory as data destination sl@0: test(Ldd.ReadHoldingMutexTest(localPtr) == KErrNone); sl@0: } sl@0: sl@0: #if 0 // rom dump code... sl@0: #include sl@0: RFs fs; sl@0: RFile file; sl@0: test(KErrNone==fs.Connect()); sl@0: test(KErrNone==file.Replace(fs, _L("d:\\ROMDUMP"),EFileWrite)); sl@0: TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); sl@0: TPtrC8 rom((TUint8*)romHeader,romHeader->iRomSize); sl@0: test(KErrNone==file.Write(rom)); sl@0: file.Close(); sl@0: fs.Close(); sl@0: return 0; sl@0: #endif sl@0: sl@0: sl@0: class RMySession : public RSessionBase sl@0: { sl@0: public: sl@0: TInt Connect(RServer2 aSrv,TRequestStatus& aStat) sl@0: { sl@0: TInt r=CreateSession(aSrv,TVersion(),-1,EIpcSession_Sharable,NULL,&aStat); sl@0: if(!r) ShareAuto(); return r; sl@0: } sl@0: TInt Send(TInt function,const TIpcArgs& args) sl@0: {return SendReceive(function,args);} sl@0: }; sl@0: sl@0: sl@0: TUint8* TestBuffer = 0; sl@0: RMySession MySession; sl@0: sl@0: LOCAL_C TInt TestServerThread(TAny* aSize) sl@0: { sl@0: TInt r = TestServer.CreateGlobal(KNullDesC, EIpcSession_GlobalSharable); sl@0: if(r==KErrNone) sl@0: { sl@0: TestBuffer = (TUint8*)User::Alloc(KMaxIPCSize); sl@0: if(!TestBuffer) sl@0: r = KErrNoMemory; sl@0: } sl@0: TPtr8 buffer(TestBuffer,KMaxIPCSize); sl@0: RThread::Rendezvous(r); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: RMessage2 m; sl@0: TestServer.Receive(m); sl@0: m.Complete(KErrNone); // connect message sl@0: sl@0: TBool running = ETrue; sl@0: while (running) sl@0: { sl@0: TestServer.Receive(m); sl@0: RDebug::Printf("Server received: %d", m.Function()); sl@0: sl@0: TInt r = KErrNone; sl@0: switch(m.Function()) sl@0: { sl@0: case 0: sl@0: // Kill server sl@0: running = EFalse; sl@0: break; sl@0: sl@0: case 2: sl@0: buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize); sl@0: // fall through... sl@0: case 1: sl@0: // Perform CRC of data passed sl@0: { sl@0: DPTest::FlushCache(); sl@0: r=m.Read(0,buffer); sl@0: if (r!=KErrNone) sl@0: break; sl@0: TUint32 crc=0; sl@0: Mem::Crc32(crc,buffer.Ptr(),buffer.Size()); sl@0: r = crc; sl@0: } sl@0: break; sl@0: sl@0: case 4: sl@0: buffer.Set(SharedBuffer,KMaxIPCSize,KMaxIPCSize); sl@0: // fall through... sl@0: case 3: sl@0: // Write data to client descriptor sl@0: { sl@0: DPTest::FlushCache(); sl@0: RDebug::Printf("Server writing %08x+%x", m.Int1(), m.Int2()); sl@0: TPtrC8 ptr((TUint8*)m.Int1(),m.Int2()); sl@0: r=m.Write(0,ptr); sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: // Just complete anything else sl@0: break; sl@0: } sl@0: m.Complete(r); sl@0: } sl@0: sl@0: RDebug::Printf("Server exiting"); sl@0: User::Free(TestBuffer); sl@0: TestBuffer = NULL; sl@0: TestServer.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void TestIPC() sl@0: { sl@0: __KHEAP_MARK; sl@0: sl@0: const TUint8* start = LargeBuffer + 0x3df; // make range not page aligned sl@0: const TUint8* end = start + Min(LargeBufferSize, KMaxIPCSize * 10) - 0x130; // make range not page aligned sl@0: const TUint8* pos; sl@0: sl@0: test.Start(_L("Create server")); sl@0: RThread t; sl@0: TInt r=t.Create(KNullDesC,TestServerThread,0x1000,KMaxIPCSize+0x1000,KMaxIPCSize+0x1000,(void*)0); sl@0: test(r==KErrNone); sl@0: t.SetPriority(EPriorityMore); sl@0: TRequestStatus s; sl@0: t.Rendezvous(s); sl@0: t.Resume(); sl@0: User::WaitForRequest(s); sl@0: test(TestServer.Handle() != KNullHandle); sl@0: sl@0: test(MySession.Connect(TestServer,s) == KErrNone); sl@0: User::WaitForRequest(s); // connected sl@0: sl@0: TInt bufferType; // 0=server uses heap, 1=server uses SharedBuffer sl@0: for(bufferType=0; bufferType<=1; ++bufferType) sl@0: { sl@0: test.Next(_L("IPC read from ROM")); sl@0: pos = start; sl@0: while(posKMaxIPCSize) sl@0: size = KMaxIPCSize; sl@0: RDebug::Printf("read %x+%x",pos,size); sl@0: TPtrC8 ptr(pos,size); sl@0: TInt r = MySession.Send(1+bufferType,TIpcArgs(&ptr)); sl@0: DPTest::FlushCache(); sl@0: TUint32 crc=0; sl@0: Mem::Crc32(crc,pos,size); sl@0: RDebug::Printf("crc %08x %08x",r,crc); sl@0: if((TUint32)r!=crc) sl@0: { sl@0: RDebug::Printf("FAIL"); sl@0: DPTest::FlushCache(); sl@0: TInt count = 0; sl@0: for(TInt i=0; i 100) sl@0: break; sl@0: } sl@0: } sl@0: test((TUint32)r==crc); sl@0: pos+=size; sl@0: } sl@0: sl@0: test.Next(_L("IPC write from ROM")); sl@0: pos = start; sl@0: while(posKMaxIPCSize) sl@0: size = KMaxIPCSize; sl@0: RDebug::Printf("write %x+%x",pos,size); sl@0: memclr(TestBuffer, KMaxIPCSize); sl@0: TPtr8 ptr(TestBuffer,KMaxIPCSize); // reuse the server's buffer sl@0: TInt r = MySession.Send(3+bufferType,TIpcArgs(&ptr,pos,size)); sl@0: test_KErrNone(r); sl@0: DPTest::FlushCache(); sl@0: TUint32 crc=0; sl@0: Mem::Crc32(crc,pos,size); sl@0: TUint32 crc2=0; sl@0: Mem::Crc32(crc2,TestBuffer,size); sl@0: RDebug::Printf("crc %08x %08x",crc,crc2); sl@0: if((TUint32)crc!=crc2) sl@0: { sl@0: RDebug::Printf("FAIL"); sl@0: DPTest::FlushCache(); sl@0: TInt count = 0; sl@0: for(TInt i=0; i 100) sl@0: break; sl@0: } sl@0: } sl@0: test((TUint32)crc==crc2); sl@0: pos+=size; sl@0: } sl@0: } sl@0: sl@0: if (DPTest::Attributes() & DPTest::ERomPaging) sl@0: { sl@0: test.Next(_L("Test passing descriptor headers in paged-out memory")); sl@0: __KHEAP_MARK; sl@0: sl@0: DPTest::FlushCache(); sl@0: TInt r = MySession.Send(5,TIpcArgs(PagedHeaderDes)); sl@0: test_Equal(KErrNone, r); sl@0: sl@0: UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); sl@0: __KHEAP_MARKEND; sl@0: } sl@0: sl@0: test.Next(_L("Stop server")); sl@0: MySession.Send(0,TIpcArgs(0)); sl@0: MySession.Close(); sl@0: t.Logon(s); sl@0: User::WaitForRequest(s); sl@0: test_Equal(EExitKill, t.ExitType()); sl@0: test_Equal(KErrNone, t.ExitReason()); sl@0: CLOSE_AND_WAIT(t); sl@0: test.End(); sl@0: sl@0: UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); sl@0: __KHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: TInt E32Main() sl@0: { sl@0: test.Title(); sl@0: sl@0: test_KErrNone(UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&PageSize,0)); sl@0: sl@0: if (DPTest::Attributes() & DPTest::ERomPaging) sl@0: test.Printf(_L("Rom paging supported\n")); sl@0: if (DPTest::Attributes() & DPTest::ECodePaging) sl@0: test.Printf(_L("Code paging supported\n")); sl@0: if (DPTest::Attributes() & DPTest::EDataPaging) sl@0: { sl@0: test.Printf(_L("Data paging supported\n")); sl@0: DataPagingSupported = ETrue; sl@0: TChunkCreateInfo createInfo; sl@0: createInfo.SetNormal(KMinBufferSize, KMinBufferSize); sl@0: createInfo.SetPaging(TChunkCreateInfo::EPaged); sl@0: createInfo.SetOwner(EOwnerProcess); sl@0: createInfo.SetGlobal(KChunkName); sl@0: test_KErrNone(DataPagedChunk.Create(createInfo)); sl@0: test(DataPagedChunk.IsPaged()); // this is only ever called if data paging is supported sl@0: DataPagedBuffer = (TUint8*)DataPagedChunk.Base(); sl@0: } sl@0: sl@0: test.Start(_L("Test HAL interface")); sl@0: TestHAL(); sl@0: sl@0: if (DPTest::Attributes() & DPTest::ERomPaging) sl@0: { sl@0: // Use paged part of rom for testing sl@0: TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress(); sl@0: test(romHeader->iPageableRomStart); sl@0: // todo: for some reason the first part of page of paged rom doesn't seem to get paged out sl@0: // when we flush the paging cache, hence LargeBuffer starts some way into this sl@0: LargeBuffer = (TUint8*)romHeader + romHeader->iPageableRomStart + 64 * PageSize; sl@0: LargeBufferSize = romHeader->iPageableRomSize - 64 * PageSize; sl@0: test(LargeBufferSize > 0); sl@0: // Find a zero word in rom to set PagedHeaderDes to sl@0: TUint* ptr = (TUint*)LargeBuffer; sl@0: TUint* end = (TUint*)(LargeBuffer + LargeBufferSize); sl@0: while (*ptr && ptr < end) sl@0: ++ptr; sl@0: test(*ptr == 0); sl@0: test.Printf(_L("Found zero word at %08x\n"), ptr); sl@0: PagedHeaderDes = (TDesC8*)ptr; sl@0: } sl@0: else if (DPTest::Attributes() & DPTest::ECodePaging) sl@0: { sl@0: // Use code paged DLL for testing sl@0: test_KErrNone(PagedLibrary.Load(KTCodePagingDll4)); sl@0: TGetAddressOfDataFunction func = (TGetAddressOfDataFunction)PagedLibrary.Lookup(KGetAddressOfDataFunctionOrdinal); sl@0: LargeBuffer = (TUint8*)func(LargeBufferSize); sl@0: test_NotNull(LargeBuffer); sl@0: PagedHeaderDes = (TDesC8*)LargeBuffer + 4; sl@0: } sl@0: else if (DPTest::Attributes() & DPTest::EDataPaging) sl@0: { sl@0: // Use data paged chunk for testing sl@0: LargeBuffer = DataPagedBuffer; sl@0: LargeBufferSize = KMinBufferSize; sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L("Demand Paging not supported\n")); sl@0: test.End(); sl@0: return 0; sl@0: } sl@0: sl@0: test(LargeBufferSize >= KMinBufferSize); sl@0: SmallBuffer = LargeBuffer; sl@0: SmallBufferSize = KMinBufferSize; sl@0: sl@0: test.Next(_L("Loading test drivers")); sl@0: TInt r = User::LoadLogicalDevice(KDemandPagingTestLddName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: test(Ldd.Open()==KErrNone); sl@0: sl@0: test_KErrNone(Ldd.CreatePlatHwChunk(SharedBufferSize, SharedBufferAddr)); sl@0: SharedBuffer = (TUint8*)SharedBufferAddr; sl@0: sl@0: RDebug::Printf("SmallBuffer=%x, LargeBuffer=%x, SharedBuffer=%x\n", sl@0: SmallBuffer, LargeBuffer, SharedBuffer); sl@0: sl@0: test.Next(_L("Gobble RAM")); sl@0: r = User::LoadLogicalDevice(KGobblerLddFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: RGobbler gobbler; sl@0: r = gobbler.Open(); sl@0: test(r==KErrNone); sl@0: TUint32 taken = gobbler.GobbleRAM(64*1024*1024); // leave 64MB of free RAM sl@0: test.Printf(_L("Gobbled: %dK\n"), taken/1024); sl@0: test.Printf(_L("Free RAM 0x%08X bytes\n"),FreeRam()); sl@0: sl@0: test.Next(_L("Test contiguous RAM allocation reclaims paged memory")); sl@0: TestContiguousRamAlloc(); sl@0: sl@0: test.Next(_L("Test thread realtime state")); sl@0: TestRealtimeState(); sl@0: sl@0: test.Next(_L("Lock Test")); sl@0: TestLock(); sl@0: sl@0: test.Next(_L("Test writing to paged area")); sl@0: TestWriteToPagedArea(); sl@0: sl@0: test.Next(_L("Test IPC read from paged memory")); sl@0: TestIPC(); sl@0: sl@0: test.Next(_L("Test no kernel faults when copying data from unpaged rom with mutex held")); sl@0: TestReadHoldingMutex(); sl@0: sl@0: test.Next(_L("Close test driver")); sl@0: Ldd.DestroyPlatHwChunk(); sl@0: Ldd.Close(); sl@0: sl@0: test.Next(_L("Test setting publish and subscribe properties from paged area")); sl@0: TestPublishAndSubscribe(); sl@0: sl@0: if (DPTest::Attributes() & DPTest::ERomPaging) sl@0: { sl@0: test.Next(_L("Rom Paging Benchmark")); sl@0: RomPagingBenchmark(); sl@0: } sl@0: sl@0: PagedLibrary.Close(); sl@0: gobbler.Close(); sl@0: test.End(); sl@0: sl@0: return 0; sl@0: }