os/kernelhwsrv/kerneltest/f32test/demandpaging/integtest/src/t_dpattr.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // @SYMTestCaseID				KBASE-DP_FUNC_ATTRIBUTES-0303
    15 // @SYMTestCaseDesc			Symbian OS Toolchain's Paging Override and the
    16 // Paging Policy settings
    17 // @SYMREQ						REQ6808
    18 // @SYMPREQ					PREQ1110
    19 // @SYMTestPriority			High
    20 // @SYMTestActions
    21 // 1.	Load executables with the RProcess API and run them. Each executable has a
    22 // different set of attributes:
    23 // "	Paging attribute: paged, unpaged or no paging attribute in MMP and/or
    24 // OBY files
    25 // "	Compression mode: specified or not
    26 // "	Executable built in ROM as 'data' or 'file'
    27 // "	Solid binaries or aliases
    28 // Retrieve and analyse the demand paging activity trace caused by the preceding
    29 // action, in order to determine whether this binary is paged on demand or not.
    30 // 2.	Repeat the preceding action by loading DLLs with the RLibrary API and
    31 // making calls to them.
    32 // @SYMTestExpectedResults
    33 // 1.	Process complete without error. If, according to the trace data gathered,
    34 // the main thread newly created process causes the executable to be paged in,
    35 // then it is a proof that the executable is paged. Depending on the Paging
    36 // Override setting and the Loader Paging Policy specified at the time the ROM was
    37 // built, the Loader makes a decision as to whether page the binary or not,
    38 // according to the rules listed in the Design Sketch. This is how we determine
    39 // this, in this order:
    40 // a.	If ROM paging is disabled: not paged
    41 // b.	If executable was built in ROM as 'data': not paged
    42 // c.	If the a file compression scheme was specified at ROM build time: not paged
    43 // d.	If the Loader Paging policy is 'NOT PAGED': not paged
    44 // e.	If the Loader Paging policy is 'ALWAYS PAGE': paged
    45 // f.	If the Paging Override is 'NOT PAGED': not paged
    46 // g.	If the Paging Override is 'ALWAYS PAGE': paged
    47 // h.	If the OBY paging keyword for this executable is 'PAGED': paged
    48 // i.	If the OBY paging keyword for this executable is 'NOT PAGED': unpaged
    49 // j.	If the MMP paging keyword for this executable is 'PAGED': paged
    50 // k.	If the MMP paging keyword for this executable is 'NOT PAGED': not paged
    51 // l.	If the Paging Override is 'DEFAULT UNPAGED': not paged
    52 // m.	If the Paging Override is 'DEFAULT PAGED': paged
    53 // n.	If the Paging Policy is 'DEFAULT UNPAGED': not paged
    54 // o.	The executable must be paged
    55 // 2.	DLL is loaded. Functions are called and complete without errors. The rules
    56 // to determine whether the binary should be paged or not are the same as in the
    57 // preceding action.
    58 // 
    59 //
    60 
    61 #include <e32test.h>
    62 #include <e32ldr.h>
    63 #include <d32btrace.h>
    64 #include "u32std.h"
    65 #include <f32file.h>
    66 #include <dptest.h>
    67 
    68 #define TEST_EQ(a,b) { if (a != b) { test.Printf(_L("%d != %d\n"), a, b); test(EFalse); } }
    69 #define TEST_CONDITION(a) { if (!a) { test.Printf(_L("TEST FAILED at line %d\n"), __LINE__); pass = EFalse; } }
    70 #define LE4(a) ((TUint) (*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a))
    71 
    72 RTest test(_L("T_DPATTR"));
    73 RBTrace btrace;
    74 RFs fs;
    75 
    76 // ROM paging settings
    77 TBool gIsRomDemangPagingEnabled;
    78 TInt gPagingOverride;
    79 TInt gPagingPolicy;
    80 
    81 // This process
    82 TUint32 gNThreadId = 0;
    83 
    84 // Test executables attributes flags
    85 enum
    86 	{
    87 	ENone					= 0,
    88 	EMMPPaged				= 1 << 0,		// "PAGED" keyword in MMP file
    89 	EMMPUnpaged				= 1 << 1,		// "UNPAGED" keyword in MMP file
    90 	EMMPCompressTarget		= 1 << 2,		// "COMPRESSTARGET" keyword in MMP file
    91 	EMMPNoCompressTarget	= 1 << 3,		// "UNCOMPRESSTARGET" keyword in MMP file
    92 	EIBYData				= 1 << 4,		// File included as "data" in IBY file
    93 	EIBYFile				= 1 << 5,		// File included as "file" in IBY file
    94 	EIBYFileCompress		= 1 << 6,		// File included as "file_x_" in IBY file (_x_=compression scheme)
    95 	EIBYPaged				= 1 << 7,		// File declared "paged" in IBY file
    96 	EIBYUnpaged				= 1 << 8,		// File declared "unpaged in IBY file
    97 	EIBYAlias				= 1 << 9,		// File name is an alias
    98 	EDLLWritableStaticData	= 1 << 10		// DLL contains writable static data
    99 	};
   100 
   101 // Test executables attributes
   102 const TUint testExeAttr[] =
   103 	{
   104 	/* 000 - does not exist */ ENone,
   105 	/* 001 */ EIBYFile,
   106 	/* 002 */ EMMPPaged | EIBYFile,
   107 	/* 003 */ EMMPUnpaged | EIBYFile,
   108 	/* 004 */ EIBYFileCompress,
   109 	/* 005 */ EMMPPaged | EIBYFileCompress,
   110 	/* 006 */ EMMPUnpaged | EIBYFileCompress,
   111 	/* 007 */ EIBYFileCompress,
   112 	/* 008 */ EMMPPaged | EIBYFileCompress,
   113 	/* 009 */ EMMPUnpaged | EIBYFileCompress,
   114 	/* 010 */ EIBYFileCompress,
   115 	/* 011 */ EMMPPaged | EIBYFileCompress,
   116 	/* 012 */ EMMPUnpaged | EIBYFileCompress,
   117 	/* 013 */ EIBYFile | EMMPCompressTarget,
   118 	/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
   119 	/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
   120 	/* 016 */ EIBYData,
   121 	/* 017 */ EMMPPaged | EIBYData,
   122 	/* 018 */ EMMPUnpaged | EIBYData,
   123 	/* 019 */ EIBYFile | EIBYPaged,
   124 	/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
   125 	/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
   126 	/* 022 */ EIBYFile | EIBYUnpaged,
   127 	/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
   128 	/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
   129 	/* 025 */ EIBYData | EIBYPaged,
   130 	/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
   131 	/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
   132 	/* 028 */ EIBYData | EIBYUnpaged,
   133 	/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
   134 	/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
   135 	/* 031 */ EIBYAlias | EIBYFile,
   136 	/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
   137 	/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
   138 	/* 034 */ EIBYAlias | EIBYFileCompress,
   139 	/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
   140 	/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
   141 	/* 037 */ EIBYAlias | EIBYFileCompress,
   142 	/* 038 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
   143 	/* 039 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
   144 	/* 040 */ EIBYAlias | EIBYFileCompress,
   145 	/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
   146 	/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
   147 	/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
   148 	/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
   149 	/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
   150 	/* 046 */ EIBYAlias | EIBYData,
   151 	/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
   152 	/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
   153 	/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
   154 	/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
   155 	/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
   156 	/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
   157 	/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
   158 	/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
   159 	/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
   160 	/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
   161 	/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
   162 	/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
   163 	/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
   164 	/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
   165 	};
   166 const TUint testDllAttr[] =
   167 	{
   168 	/* 000 - does not exist */ ENone,
   169 	/* 001 */ EIBYFile,
   170 	/* 002 */ EMMPPaged | EIBYFile,
   171 	/* 003 */ EMMPUnpaged | EIBYFile,
   172 	/* 004 */ EIBYFileCompress,
   173 	/* 005 */ EMMPPaged | EIBYFileCompress,
   174 	/* 006 */ EMMPUnpaged | EIBYFileCompress,
   175 	/* 007 */ EDLLWritableStaticData,
   176 	/* 008 */ EMMPPaged | EDLLWritableStaticData,
   177 	/* 009 */ EMMPUnpaged | EDLLWritableStaticData,
   178 	/* 010 */ EIBYFileCompress,
   179 	/* 011 */ EMMPPaged | EIBYFileCompress,
   180 	/* 012 */ EMMPUnpaged | EIBYFileCompress,
   181 	/* 013 */ EIBYFile | EMMPCompressTarget,
   182 	/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
   183 	/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
   184 	/* 016 */ EIBYData,
   185 	/* 017 */ EMMPPaged | EIBYData,
   186 	/* 018 */ EMMPUnpaged | EIBYData,
   187 	/* 019 */ EIBYFile | EIBYPaged,
   188 	/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
   189 	/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
   190 	/* 022 */ EIBYFile | EIBYUnpaged,
   191 	/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
   192 	/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
   193 	/* 025 */ EIBYData | EIBYPaged,
   194 	/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
   195 	/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
   196 	/* 028 */ EIBYData | EIBYUnpaged,
   197 	/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
   198 	/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
   199 	/* 031 */ EIBYAlias | EIBYFile,
   200 	/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
   201 	/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
   202 	/* 034 */ EIBYAlias | EIBYFileCompress,
   203 	/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
   204 	/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
   205 	/* 037 */ EIBYAlias | EDLLWritableStaticData,
   206 	/* 038 */ EIBYAlias | EMMPPaged | EDLLWritableStaticData,
   207 	/* 039 */ EIBYAlias | EMMPUnpaged | EDLLWritableStaticData,
   208 	/* 040 */ EIBYAlias | EIBYFileCompress,
   209 	/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
   210 	/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
   211 	/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
   212 	/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
   213 	/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
   214 	/* 046 */ EIBYAlias | EIBYData,
   215 	/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
   216 	/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
   217 	/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
   218 	/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
   219 	/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
   220 	/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
   221 	/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
   222 	/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
   223 	/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
   224 	/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
   225 	/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
   226 	/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
   227 	/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
   228 	/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
   229 	};
   230 
   231 void InitNThreadID()
   232 	{
   233 	_LIT(KThreadName, "ARandomThreadName");
   234 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
   235 	btrace.Empty();
   236 	btrace.SetMode(RBTrace::EEnable);
   237 	// rename the current thread to force a ThreadID trace
   238 	User::RenameThread(KThreadName);
   239 	btrace.SetMode(0);
   240 	TInt size;
   241 	TUint8* pDataStart;
   242 	TUint8* pCurrentRecord;
   243 	// extract the nano-kernel thread ID from the trace
   244 	while ((size = btrace.GetData(pDataStart)) != 0)
   245 		{
   246 		pCurrentRecord = pDataStart;
   247 		while (pCurrentRecord - pDataStart < size)
   248 			{
   249 			TInt extensionCount = 4 * (
   250 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
   251 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
   252 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
   253 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
   254 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
   255 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
   256 			//
   257 			if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EThreadName))
   258 				{
   259 				TBuf<255> threadName;
   260 				threadName.Format(_L(""));
   261 				for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
   262 					{
   263 					threadName.AppendFormat(_L("%c"), *j);
   264 					}
   265 				if (threadName == KThreadName)
   266 					{
   267 					test.Printf(_L("This thread's NThread ID: %08x\n"), LE4(pCurrentRecord + 4 + extensionCount));
   268 					gNThreadId = LE4(pCurrentRecord + 4 + extensionCount);
   269 					}
   270 				}
   271 			pCurrentRecord = BTrace::NextRecord(pCurrentRecord);
   272 			}
   273 		btrace.DataUsed();
   274 		}
   275 	}
   276 	
   277 void LoadExesRom()
   278 	{
   279 	TInt r;
   280 	TBool pass = ETrue;
   281 	r = btrace.ResizeBuffer(32768); // 32k should be large enough
   282 	TEST_EQ(r, KErrNone);
   283 	btrace.SetFilter(BTrace::EPaging, ETrue);
   284 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
   285 	btrace.SetMode(0);
   286 	
   287 	for (TInt i = 1; i <= 60; i++)
   288 		{
   289 		TBuf<255> filename;
   290 		filename.Format(_L("Z:\\SYS\\BIN\\DPEXE%03d.EXE"), i);
   291 	
   292 		test.Printf(_L("Loading %S... "), &filename);
   293 		
   294 		TBool paged = EFalse;
   295 		TBool inRom = EFalse;
   296 		
   297 		TUint32 nthreadAddr = 0;
   298 		TBuf<255> processName;
   299 		
   300 		if (fs.IsFileInRom(filename) != NULL)
   301 			{
   302 			inRom = ETrue;
   303 			}
   304 		else
   305 			{
   306 			inRom = EFalse;
   307 			}
   308 		
   309 		// Ensure that the paging live list is empty
   310 		r = DPTest::FlushCache();
   311 		if (gIsRomDemangPagingEnabled)
   312 			{
   313 			TEST_EQ(r, KErrNone);
   314 			}
   315 		else
   316 			{
   317 			TEST_EQ(r, KErrNotSupported);
   318 			}
   319 		
   320 		btrace.Empty(); // empty the BTrace buffer
   321 		btrace.SetMode(RBTrace::EEnable);
   322 		RProcess proc;
   323 		r = proc.Create(filename, _L(""));
   324 			
   325 		if ((testExeAttr[i] & EIBYAlias) && (testExeAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
   326 		// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
   327 			{
   328 			TEST_EQ(r, KErrNotFound);
   329 			continue;
   330 			}
   331 		else
   332 			{
   333 			TEST_EQ(r, KErrNone);
   334 			}
   335 		
   336 		// Resume the process and wait until it completes
   337 		TRequestStatus ps;
   338 		proc.Logon(ps);
   339 		proc.Resume();
   340 		proc.Close();
   341 		User::WaitForRequest(ps);
   342 		
   343 		// Disable trace
   344 		btrace.SetMode(0);
   345 		
   346 		TInt size;
   347 		TUint8* pDataStart;
   348 		TUint8* pCurrentRecord;
   349 		
   350 		// We have a while loop here, in the unlikely case that our trace is fragmented	
   351 		while ((size = btrace.GetData(pDataStart)) != 0)
   352 			{
   353 			pCurrentRecord = pDataStart;
   354 			while (pCurrentRecord - pDataStart < size)
   355 				{
   356 				// Number of bytes used by the BTrace extensions
   357 				TInt extensionCount = 4 * (
   358 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
   359 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
   360 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
   361 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
   362 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
   363 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
   364 				
   365 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EProcessName))
   366 				// Process renamed
   367 					{
   368 					processName.Format(_L(""));
   369 					for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
   370 						{
   371 						processName.AppendFormat(_L("%c"), *j);
   372 						}
   373 					TBuf<255> expected;
   374 					expected.Format(_L("dpexe%03d.exe[%08x]%04x"), i, 0, 1);
   375 					
   376 					if (processName == expected)
   377 						{
   378 						nthreadAddr = LE4(pCurrentRecord + 4 + extensionCount);
   379 						}					
   380 					}
   381 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging) && (LE4(pCurrentRecord + 8) == nthreadAddr))
   382 				/* The main thread of the test process tries to page in the test executable	*/
   383 					{
   384 					paged = ETrue;
   385 					}
   386 				pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
   387 				}
   388 			btrace.DataUsed();
   389 			}
   390 		
   391 		if (paged)
   392 			test.Printf(_L("paged!\n"));
   393 		else
   394 			test.Printf(_L("not paged!\n"));
   395 		
   396 		if (!gIsRomDemangPagingEnabled)
   397 		// ROM paging disabled. All files are in ROM and unpaged
   398 			{
   399 			test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
   400 			TEST_CONDITION(inRom);
   401 			TEST_CONDITION(!paged);
   402 			}
   403 		else if (testExeAttr[i] & EIBYData)
   404 			// data - if ROM paged, then these executables will be moved to ROFS
   405 			// these are always expected to be RAM loaded
   406 			{
   407 			test.Printf(_L("EXE is DATA in ROFS\n"));
   408 			TEST_CONDITION(!inRom);
   409 			}
   410 		else if (testExeAttr[i] & EIBYFileCompress)
   411 			// Compression format specified in the IBY file
   412 			// These are expected to be stay in ROM, but will be RAM-loaded
   413 			{
   414 			test.Printf(_L("EXE has own compression method: shouldn't be paged\n"));
   415 			TEST_CONDITION(inRom);
   416 			TEST_CONDITION(!paged);
   417 			}
   418 		// from this point onwards, all executables can potentially be paged - paging policy takes precedence
   419 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
   420 			{
   421 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
   422 			TEST_CONDITION(inRom);
   423 			TEST_CONDITION(!paged);
   424 			}
   425 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
   426 			{
   427 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
   428 			TEST_CONDITION(inRom);
   429 			TEST_CONDITION(paged);
   430 			}
   431 		// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
   432 		else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
   433 			{
   434 			test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
   435 			TEST_CONDITION(inRom);
   436 			TEST_CONDITION(!paged);
   437 			}
   438 		else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
   439 			{
   440 			test.Printf(_L("Paging override is Always Page: should be paged\n"));
   441 			TEST_CONDITION(inRom);
   442 			TEST_CONDITION(paged);
   443 			}
   444 		// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
   445 		else if (testExeAttr[i] & EIBYPaged)
   446 			{
   447 			test.Printf(_L("Paged keyword in OBY: should be paged\n"));
   448 			TEST_CONDITION(inRom);
   449 			TEST_CONDITION(paged);
   450 			}
   451 		else if (testExeAttr[i] & EIBYUnpaged)
   452 			{
   453 			test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
   454 			TEST_CONDITION(inRom);
   455 			TEST_CONDITION(!paged);
   456 			}
   457 		// Next, MMP setting takes precedence
   458 		else if (testExeAttr[i] & EMMPPaged)
   459 			{
   460 			test.Printf(_L("Paged keyword in MMP: should be paged\n"));
   461 			TEST_CONDITION(inRom);
   462 			TEST_CONDITION(paged);
   463 			}
   464 		else if (testExeAttr[i] & EMMPUnpaged)
   465 			{
   466 			test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
   467 			TEST_CONDITION(inRom);
   468 			TEST_CONDITION(!paged);
   469 			}
   470 		// The test exe has no attribute. Paging overright default paging mode takes precedence
   471 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
   472 			{
   473 			test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
   474 			TEST_CONDITION(inRom);
   475 			TEST_CONDITION(!paged);
   476 			}
   477 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
   478 			{
   479 			test.Printf(_L("Paging override is Default Paged: should be paged\n"));
   480 			TEST_CONDITION(inRom);
   481 			TEST_CONDITION(paged);
   482 			}
   483 		// Paging policy default paging mode takes precedence
   484 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
   485 			{
   486 			test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
   487 			TEST_CONDITION(inRom);
   488 			TEST_CONDITION(!paged);
   489 			}
   490 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
   491 			{
   492 			test.Printf(_L("Paging policy is Default paged: should be paged\n"));
   493 			TEST_CONDITION(inRom);
   494 			TEST_CONDITION(paged);
   495 			}
   496 		// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
   497 		else
   498 			{
   499 			test.Printf(_L("No paging policy!\n"));
   500 			test(EFalse);
   501 			}
   502 		}
   503 	test(pass);
   504 	}
   505 	
   506 
   507 void LoadDllsRom()
   508 	{
   509 	TInt r;
   510 	TBool pass = ETrue;
   511 	r = btrace.ResizeBuffer(32768); // 32k should be large enough
   512 	TEST_EQ(r, KErrNone);
   513 	btrace.SetFilter(BTrace::EPaging, ETrue);
   514 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
   515 	btrace.SetMode(0);
   516 	
   517 	for (TInt i = 1; i <= 60; i++)
   518 		{
   519 		TBuf<255> filename;
   520 		filename.Format(_L("Z:\\SYS\\BIN\\DPDLL%03d.DLL"), i);
   521 	
   522 		test.Printf(_L("Loading %S... "), &filename);
   523 		
   524 		TBool paged = EFalse;
   525 		TBool inRom = EFalse;
   526 		
   527 		TUint libLoadEnd;
   528 		TInt filesize;
   529 		
   530 		TUint8* addr;
   531 		if ((addr = fs.IsFileInRom(filename)) != NULL)
   532 			{
   533 			inRom = ETrue;
   534 			}
   535 		else
   536 			{
   537 			inRom = EFalse;
   538 			}
   539 		
   540 		RFile file;
   541 		r = file.Open(fs, filename, EFileRead);
   542 		if ((testDllAttr[i] & EIBYAlias) && (testDllAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
   543 		// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
   544 			{
   545 			TEST_EQ(r, KErrNotFound);
   546 			continue;
   547 			}
   548 		else
   549 			{
   550 			TEST_EQ(r, KErrNone);
   551 			}
   552 		r = file.Size(filesize);
   553 		TEST_EQ(r, KErrNone);
   554 		file.Close();
   555 		
   556 		// Ensure that the paging live list is empty
   557 		r = DPTest::FlushCache();
   558 		if (gIsRomDemangPagingEnabled)
   559 			{
   560 			TEST_EQ(r, KErrNone);
   561 			}
   562 		else
   563 			{
   564 			TEST_EQ(r, KErrNotSupported);
   565 			}
   566 		
   567 		btrace.Empty(); // empty the BTrace buffer
   568 		btrace.SetMode(RBTrace::EEnable);
   569 		RLibrary lib;
   570 		r = lib.Load(filename);
   571 		libLoadEnd = User::FastCounter();
   572 		
   573 		TEST_EQ(r, KErrNone);
   574 		
   575 		TLibraryFunction function1;
   576 		TLibraryFunction function2;
   577 		TLibraryFunction function3;
   578 		TLibraryFunction function4;
   579 		
   580 		function1 = lib.Lookup(1);
   581 		function2 = lib.Lookup(2);
   582 		function3 = lib.Lookup(3);
   583 		function4 = lib.Lookup(4);
   584 		
   585 		test(function1 != NULL);
   586 		test(function2 != NULL);
   587 		test(function3 != NULL);
   588 		test(function4 == NULL);
   589 		
   590 		// Resume the process and wait until it completes
   591 	
   592 		function1();
   593 		function2();
   594 		function3();
   595 		
   596 		lib.Close();
   597 		
   598 		//processResumeStart = User::FastCounter();
   599 		//processResumeEnd = User::FastCounter();
   600 		
   601 		// Disable trace
   602 		btrace.SetMode(0);
   603 		
   604 		TInt size;
   605 		TUint8* pDataStart;
   606 		TUint8* pCurrentRecord;
   607 		
   608 		// We have a while loop here, in the unlikely case that our trace is fragmented	
   609 		while ((size = btrace.GetData(pDataStart)) != 0)
   610 			{
   611 			pCurrentRecord = pDataStart;
   612 			while (pCurrentRecord - pDataStart < size)
   613 				{
   614 				// Number of bytes used by the BTrace extensions
   615 				TInt extensionCount = 4 * (
   616 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
   617 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
   618 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
   619 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
   620 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
   621 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
   622 
   623 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging)
   624 					&& (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EPagingPageInBegin)
   625 					&& (LE4(pCurrentRecord + 4) > libLoadEnd)
   626 					&& (LE4(pCurrentRecord + extensionCount) == gNThreadId)
   627 					&& (LE4(pCurrentRecord + 4 + extensionCount) >= (TUint32) addr)
   628 					&& (LE4(pCurrentRecord + 4 + extensionCount) < ((TUint32) addr) + filesize))
   629 				// If the DLL is paged in under this thread after it's been RLibrary::Load'ed, then we assume the DLL is paged
   630 					{
   631 					paged = ETrue;
   632 					}
   633 				pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
   634 				}
   635 			btrace.DataUsed();
   636 			}
   637 
   638 		if (paged)
   639 			test.Printf(_L("paged!\n"));
   640 		else
   641 			test.Printf(_L("not paged!\n"));
   642 
   643 		if (!gIsRomDemangPagingEnabled)
   644 		// ROM paging disabled. All files are in ROM and unpaged
   645 			{
   646 			test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
   647 			test(inRom);
   648 			TEST_CONDITION(!paged);
   649 			}
   650 		else if (testDllAttr[i] & EIBYData)
   651 			// data - if ROM paged, then these executables will be moved to ROFS
   652 			// these are always expected to be RAM loaded
   653 			{
   654 			test.Printf(_L("DLL is DATA in ROFS: shouldn't be paged\n"));
   655 			TEST_CONDITION(!inRom);
   656 			TEST_CONDITION(!paged);
   657 			}
   658 		else if (testDllAttr[i] & EIBYFileCompress)
   659 			// Compression format specified in the IBY file
   660 			// These are expected to be stay in ROM, but will be RAM-loaded
   661 			{
   662 			test.Printf(_L("DLL has own compression method: shouldn't be paged\n"));
   663 			TEST_CONDITION(inRom);
   664 			TEST_CONDITION(!paged);
   665 			}
   666 		// from this point onwards, all executables can potentially be paged - paging policy takes precedence
   667 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
   668 			{
   669 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
   670 			TEST_CONDITION(inRom);
   671 			TEST_CONDITION(!paged);
   672 			}
   673 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
   674 			{
   675 			test.Printf(_L("Paging policy is Always Page: should be paged\n"));
   676 			TEST_CONDITION(inRom);
   677 			TEST_CONDITION(paged);
   678 			}
   679 		// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
   680 		else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
   681 			{
   682 			test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
   683 			TEST_CONDITION(inRom);
   684 			TEST_CONDITION(!paged);
   685 			}
   686 		else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
   687 			{
   688 			test.Printf(_L("Paging override is Always Page: should be paged\n"));
   689 			TEST_CONDITION(inRom);
   690 			TEST_CONDITION(paged);
   691 			}
   692 		// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
   693 		else if (testDllAttr[i] & EIBYPaged)
   694 			{
   695 			test.Printf(_L("Paged keyword in OBY: should be paged\n"));
   696 			TEST_CONDITION(inRom);
   697 			TEST_CONDITION(paged);
   698 			}
   699 		else if (testDllAttr[i] & EIBYUnpaged)
   700 			{
   701 			test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
   702 			TEST_CONDITION(inRom);
   703 			TEST_CONDITION(!paged);
   704 			}
   705 		// Next, MMP setting takes precedence
   706 		else if (testDllAttr[i] & EMMPPaged)
   707 			{
   708 			test.Printf(_L("Paged keyword in MMP: should be paged\n"));
   709 			TEST_CONDITION(inRom);
   710 			TEST_CONDITION(paged);
   711 			}
   712 		else if (testDllAttr[i] & EMMPUnpaged)
   713 			{
   714 			test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
   715 			TEST_CONDITION(inRom);
   716 			TEST_CONDITION(!paged);
   717 			}
   718 		// The test exe has no attribute. Paging overright default paging mode takes precedence
   719 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
   720 			{
   721 			test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
   722 			TEST_CONDITION(inRom);
   723 			TEST_CONDITION(!paged);
   724 			}
   725 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
   726 			{
   727 			test.Printf(_L("Paging override is Default Paged: should be paged\n"));
   728 			TEST_CONDITION(inRom);
   729 			TEST_CONDITION(paged);
   730 			}
   731 		// Paging policy default paging mode takes precedence
   732 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
   733 			{
   734 			test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
   735 			TEST_CONDITION(inRom);
   736 			TEST_CONDITION(!paged);
   737 			}
   738 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
   739 			{
   740 			test.Printf(_L("Paging policy is Default paged: should be paged\n"));
   741 			TEST_CONDITION(inRom);
   742 			TEST_CONDITION(paged);
   743 			}
   744 		// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
   745 		else
   746 			{
   747 			test.Printf(_L("No paging policy!\n"));
   748 			test(EFalse);
   749 			}
   750 		}
   751 	test(pass);
   752 	}
   753 
   754 GLDEF_C TInt E32Main()
   755 	{
   756 	TInt r;
   757 	test.Title();
   758 	test.Start(_L("Check environment"));
   759 	
   760 	// Open the BTrace handler
   761 	r = btrace.Open();
   762 	TEST_EQ(r, KErrNone);
   763 	
   764 	// capture the NThread ID of the main thread of the current process
   765 	InitNThreadID();
   766 	test(gNThreadId != 0);
   767 	
   768 	gPagingPolicy = E32Loader::PagingPolicy();
   769 	gPagingOverride = -1;
   770 	
   771 	r = fs.Connect();
   772 	TEST_EQ(r, KErrNone);
   773 	
   774 	if (fs.IsFileInRom(_L("\\ovr_nopaging")) != NULL)
   775 		{
   776 		gPagingOverride = EKernelConfigCodePagingPolicyNoPaging;
   777 		}
   778 	if (fs.IsFileInRom(_L("\\ovr_alwayspage")) != NULL)
   779 		{
   780 		gPagingOverride = EKernelConfigCodePagingPolicyAlwaysPage;
   781 		}
   782 	if (fs.IsFileInRom(_L("\\ovr_defaultunpaged")) != NULL)
   783 		{
   784 		gPagingOverride = EKernelConfigCodePagingPolicyDefaultUnpaged;
   785 		}
   786 	if (fs.IsFileInRom(_L("\\ovr_defaultpaged")) != NULL)
   787 		{
   788 		gPagingOverride = EKernelConfigCodePagingPolicyDefaultPaged;
   789 		}
   790 	if (fs.IsFileInRom(_L("\\pcy_nopaging")) != NULL)
   791 		{
   792 		gPagingPolicy = EKernelConfigCodePagingPolicyNoPaging;
   793 		}
   794 	if (fs.IsFileInRom(_L("\\pcy_alwayspage")) != NULL)
   795 		{
   796 		gPagingPolicy = EKernelConfigCodePagingPolicyAlwaysPage;
   797 		}
   798 	if (fs.IsFileInRom(_L("\\pcy_defaultunpaged")) != NULL)
   799 		{
   800 		gPagingPolicy = EKernelConfigCodePagingPolicyDefaultUnpaged;
   801 		}
   802 	if (fs.IsFileInRom(_L("\\pcy_defaultpaged")) != NULL)
   803 		{
   804 		gPagingPolicy = EKernelConfigCodePagingPolicyDefaultPaged;
   805 		}
   806 		
   807 	gIsRomDemangPagingEnabled = (fs.IsFileInRom(_L("Z:\\SYS\\BIN\\DPEXE046.EXE")) == NULL);
   808 		
   809 	test.Printf(_L("Demand Paging Enabled? %d\n"), gIsRomDemangPagingEnabled);
   810 	test.Printf(_L("PagingOverride %d\n"), gPagingOverride);
   811 	test.Printf(_L("PagingPolicy %d\n"), gPagingPolicy);
   812 	
   813 	test.Next(_L("Load ROM EXEs"));
   814 	LoadExesRom();
   815 	test.Next(_L("Load ROM DLLs"));
   816 	LoadDllsRom();
   817 	
   818 	btrace.Close();
   819 	fs.Close();
   820 	test.End();
   821 	test.Close();
   822 	return KErrNone;
   823 	}