kerneltest/e32test/mmu/t_shadow.cpp
changeset 0 a41df078684a
child 26 c734af59ce98
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1997-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 // e32test\mmu\t_shadow.cpp
       
    15 // Overview:
       
    16 // Test ROM shadowing
       
    17 // API Information:
       
    18 // RBusLogicalChannel
       
    19 // Details:
       
    20 // - Load and open the logical device driver ("D_SHADOW.LDD"). Verify
       
    21 // results.
       
    22 // - Allocate a shadow ROM page, verify data is copied into shadow page
       
    23 // without altering the following page.
       
    24 // - Move the shadow page and the original rom page.
       
    25 // - Write and verify data in the shadow page.
       
    26 // - Free the shadow page and verify original ROM data is restored.
       
    27 // - Test pinning of shadow pages.
       
    28 // Platforms/Drives/Compatibility:
       
    29 // All.
       
    30 // Assumptions/Requirement/Pre-requisites:
       
    31 // Failures and causes:
       
    32 // Base Port information:
       
    33 // 
       
    34 //
       
    35 
       
    36 #define __E32TEST_EXTENSION__
       
    37 
       
    38 #include <e32test.h>
       
    39 #include <e32uid.h>
       
    40 #include <e32hal.h>
       
    41 #include "d_shadow.h"
       
    42 #include "d_gobble.h"
       
    43 #include "..\defrag\d_pagemove.h"
       
    44 #include "d_memorytest.h"
       
    45 #include <dptest.h>
       
    46 #include "mmudetect.h"
       
    47 #include "freeram.h"
       
    48 
       
    49 enum TPaged
       
    50 	{
       
    51 	EUnpaged,
       
    52 	EPaged
       
    53 	};
       
    54 
       
    55 _LIT(KLddFileName, "D_SHADOW.LDD");
       
    56 _LIT(KMoveLddFileName, "D_PAGEMOVE.LDD");
       
    57 
       
    58 LOCAL_D RTest test(_L("T_SHADOW"));
       
    59 
       
    60 RPageMove PageMove;
       
    61 RShadow Shadow;
       
    62 RMemoryTestLdd MemoryTest;
       
    63 
       
    64 TInt PageSize;
       
    65 LOCAL_D TBool RomPagingSupported = EFalse;
       
    66 #ifndef __X86__
       
    67 LOCAL_D TBool PageMovingSupported = ETrue;
       
    68 #else
       
    69 LOCAL_D TBool PageMovingSupported = EFalse;
       
    70 #endif
       
    71 
       
    72 TLinAddr RomUnpagedStart = 0;
       
    73 TLinAddr RomUnpagedEnd = 0;
       
    74 TLinAddr RomPagedStart = 0;
       
    75 TLinAddr RomPagedEnd = 0;
       
    76 
       
    77 TUint8* PageBuffer1 = NULL;
       
    78 TUint8* PageBuffer2 = NULL;
       
    79 TUint8* PageBuffer3 = NULL;
       
    80 
       
    81 void TestShadowPage(TLinAddr aPageAddr, TPaged aPageType)
       
    82 	{
       
    83 	test.Start(_L("Test shadowing a page"));	
       
    84 	test.Printf(_L("  addr == 0x%08x, type == %d\n"), aPageAddr, aPageType);
       
    85 
       
    86 	test.Next(_L("Copy page to be shadowed and following page to local buffers"));
       
    87 	TLinAddr secondPage = aPageAddr + PageSize;
       
    88 	if (secondPage >= RomPagedEnd)
       
    89 		secondPage = RomUnpagedStart;
       
    90 	Mem::Move(PageBuffer1,(TAny*)aPageAddr,PageSize);
       
    91 	Mem::Move(PageBuffer3,(TAny*)(secondPage),PageSize);
       
    92 	
       
    93 	TUint origPhysAddr = 0xffffffff;	// The physical address of the rom page to be shadowed
       
    94 	
       
    95 	if (PageMovingSupported && aPageType == EPaged)
       
    96 		{
       
    97 		test.Next(_L("Test page can be moved"));
       
    98 		TUint dummy = *(volatile TUint32*)aPageAddr;  // ensure paged in
       
    99 		test_KErrNone(PageMove.TryMovingUserPage((TAny*)aPageAddr));
       
   100 		
       
   101 		test.Next(_L("Get page's physical address"));
       
   102 		dummy += *(volatile TUint32*)aPageAddr;  // ensure paged in
       
   103 		test_KErrNone(PageMove.GetPhysAddr((TAny*)aPageAddr, (TAny*)&origPhysAddr));
       
   104 		test.Printf(_L("  physical address: %08x\n"), origPhysAddr);
       
   105 		}
       
   106 
       
   107 	test.Next(_L("Allocate a shadow ROM page"));
       
   108 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   109 
       
   110 	test.Next(_L("Try to shadow the page again"));
       
   111 	test_Equal(KErrAlreadyExists, Shadow.Alloc(aPageAddr));
       
   112 
       
   113 	if (PageMovingSupported && aPageType == EPaged)
       
   114 		{
       
   115 		test.Next(_L("Check page's physical address has changed"));
       
   116 		TUint newPhysAddr;
       
   117 		test_KErrNone(PageMove.GetPhysAddr((TAny*)aPageAddr, (TAny*)&newPhysAddr));
       
   118 		test(newPhysAddr != origPhysAddr);
       
   119 		
       
   120 		test.Next(_L("Test moving a shadowed page is not allowed"));
       
   121 		test_Equal(KErrNotSupported, PageMove.TryMovingUserPage((TAny*)aPageAddr));
       
   122 	
       
   123 		test.Next(_L("Test moving the original page fails (it should be pinned)"));
       
   124 		test_Equal(KErrInUse, PageMove.TryMovingPhysAddr((TAny*)origPhysAddr, (TAny*)&newPhysAddr));
       
   125 		}
       
   126 
       
   127 	test.Next(_L("Check data copied into shadow page"));
       
   128 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer1,PageSize));
       
   129 
       
   130 	test.Next(_L("Check page following shadow page is unaltered"));
       
   131 	test_Equal(0, Mem::Compare((TUint8*)(secondPage),PageSize,PageBuffer3,PageSize));
       
   132 
       
   133 	test.Next(_L("Write data into shadow page"));
       
   134 	for(TInt i=0; i<PageSize; i++)
       
   135 		{
       
   136 		TInt i2=i*i;
       
   137 		PageBuffer2[i]=TUint8(i2^(i2>>8)^(i2>>16));
       
   138 		}
       
   139 	test_KErrNone(Shadow.Write(aPageAddr,PageBuffer2));
       
   140 
       
   141 	test.Next(_L("Check data written into shadow page"));
       
   142 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer2,PageSize));
       
   143 	
       
   144 	test.Next(_L("Check page following shadow page is unaltered"));
       
   145 	test_Equal(0, Mem::Compare((TUint8*)(secondPage),PageSize,PageBuffer3,PageSize));
       
   146 
       
   147 	test.Next(_L("Allocate another shadow ROM page"));
       
   148 	test_KErrNone(Shadow.Alloc(secondPage));
       
   149 
       
   150 	test.Next(_L("Free the original shadow page"));
       
   151 	test_KErrNone(Shadow.Free(aPageAddr));
       
   152 
       
   153 	test.Next(_L("Check original ROM data restored"));
       
   154 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer1,PageSize));
       
   155 
       
   156 	if (PageMovingSupported && aPageType == EPaged)
       
   157 		{
       
   158 		test.Next(_L("Test page can be moved again"));
       
   159 		test_KErrNone(PageMove.TryMovingUserPage((TAny*)aPageAddr));
       
   160 		}
       
   161 	
       
   162 	test.Next(_L("Free the second shadow page"));
       
   163 	test_KErrNone(Shadow.Free(secondPage));
       
   164 
       
   165 	test.Next(_L("Check original ROM data restored"));
       
   166 	test_Equal(0, Mem::Compare((TUint8*)(secondPage),PageSize,PageBuffer3,PageSize));
       
   167 	test.End();
       
   168 	}
       
   169 
       
   170 /*
       
   171     Reintroduce this when RTest can report whether the test is
       
   172     being run in automatic or manual mode
       
   173 */
       
   174 void TestFreeze(TLinAddr aPageAddr)
       
   175 	{
       
   176 	test.Start(_L("Test freezing a shadow page"));	
       
   177 	test.Printf(_L("Press 0 to test Freeze (causes kernel fault)\n"));
       
   178 	test.Printf(_L("Press any other key to skip this test\n"));
       
   179 	TKeyCode key=test.Getch();
       
   180 	if (key==TKeyCode('0'))
       
   181 		{
       
   182 		test.Next(_L("Freeze first shadow page"));
       
   183 		test_KErrNone(Shadow.Freeze(aPageAddr));
       
   184 
       
   185 		test.Printf(_L("Press a key to attempt write after freezing\n"));
       
   186 		test.Printf(_L("Should get Kernel Exception 9, Data Address 50000xxx\n"));
       
   187 		test.Getch();
       
   188 		Shadow.Write(aPageAddr,PageBuffer2);
       
   189 		test(0);
       
   190 		}
       
   191 	test.End();
       
   192 	}
       
   193 
       
   194 void TestNoFreeRAM(TLinAddr aPageAddr)
       
   195 	{
       
   196 	test.Start(_L("Test allocating a shadow page when all free RAM is in 'chunk caches'"));
       
   197 	
       
   198 	test.Next(_L("Load gobbler LDD"));
       
   199 	TInt r = User::LoadLogicalDevice(KGobblerLddFileName);
       
   200 	test_Value(r, r==KErrNone || r==KErrAlreadyExists);
       
   201 	RGobbler gobbler;
       
   202 	test_KErrNone(gobbler.Open());
       
   203 	TUint32 taken = gobbler.GobbleRAM(496*1024*1024);
       
   204 	test.Printf(_L("  Gobbled: %dK\n"), taken/1024);
       
   205 	test.Printf(_L("  Free RAM 0x%08X bytes\n"),FreeRam());
       
   206 
       
   207 	// Remove limit on max size of live list
       
   208 	TUint originalMin = 0;
       
   209 	TUint originalMax = 0;
       
   210 	TUint currentSize = 0;
       
   211 	r = DPTest::CacheSize(originalMin, originalMax, currentSize);
       
   212 	test_Value(r, r == KErrNone || r == KErrNotSupported);
       
   213 	TBool resizeCache = r == KErrNone;
       
   214 	if (resizeCache)
       
   215 		test_KErrNone(DPTest::SetCacheSize(originalMin, KMaxTUint));
       
   216 
       
   217 	// put all of free RAM in a chunk...
       
   218 	TChunkCreateInfo createInfo;
       
   219 	createInfo.SetCache(512*1024*1024);
       
   220 	RChunk testChunk;
       
   221 	test_KErrNone(testChunk.Create(createInfo));
       
   222 	TInt commitEnd = 0;
       
   223 	while(KErrNone==(r=testChunk.Commit(commitEnd,PageSize)))
       
   224 		commitEnd += PageSize;
       
   225 	test_Equal(KErrNoMemory,r);
       
   226 	
       
   227 	// no memory to allocate shadow page...
       
   228 	test_Equal(KErrNoMemory,Shadow.Alloc(aPageAddr));
       
   229 	// unlock all of RAM in chunk...
       
   230 	test_KErrNone(testChunk.Unlock(0,commitEnd));
       
   231 	// should have memory now...
       
   232 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   233 	// tidy up...
       
   234 	test_KErrNone(Shadow.Free(aPageAddr));
       
   235 	testChunk.Close();
       
   236 
       
   237 	// Restore original settings for live list size
       
   238 	if (resizeCache)
       
   239 		test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax));
       
   240 
       
   241 	gobbler.Close();
       
   242 	test.End();
       
   243 	}
       
   244 
       
   245 void TestShadowPageOOM(TLinAddr aPageAddr)
       
   246 	{
       
   247 	test.Start(_L("Test OOM while shadowing a page"));
       
   248 	test.Printf(_L("  addr == 0x%08x\n"), aPageAddr);
       
   249 
       
   250 	test.Next(_L("Copy page to be shadowed and following page to local buffers"));
       
   251 	Mem::Move(PageBuffer1,(TAny*)aPageAddr,PageSize);
       
   252 
       
   253 	__KHEAP_MARK;
       
   254 	
       
   255 	TInt r;
       
   256 	TInt failCount = 0;
       
   257 	test.Next(_L("Allocate a shadow ROM page"));
       
   258 	do
       
   259 		{
       
   260 		__KHEAP_FAILNEXT(failCount);
       
   261 		r = Shadow.Alloc(aPageAddr);
       
   262 		if (r == KErrNoMemory)
       
   263 			++failCount;
       
   264 		}
       
   265 	while (r == KErrNoMemory);
       
   266 	__KHEAP_RESET;
       
   267 	test.Printf(_L("  returned %d after %d allocations\n"), r, failCount);
       
   268 	test_KErrNone(r);
       
   269 
       
   270 	test.Next(_L("Try to shadow the page again"));
       
   271 	__KHEAP_FAILNEXT(0);
       
   272 	test_Equal(KErrAlreadyExists, Shadow.Alloc(aPageAddr));
       
   273 	__KHEAP_RESET;
       
   274 
       
   275 	test.Next(_L("Check data copied into shadow page"));
       
   276 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer1,PageSize));
       
   277 
       
   278 	test.Next(_L("Write data into shadow page"));
       
   279 	for(TInt i=0; i<PageSize; i++)
       
   280 		{
       
   281 		TInt i2=i*i;
       
   282 		PageBuffer2[i]=TUint8(i2^(i2>>8)^(i2>>16));
       
   283 		}
       
   284 	test_KErrNone(Shadow.Write(aPageAddr,PageBuffer2));
       
   285 
       
   286 	test.Next(_L("Check data written into shadow page"));
       
   287 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer2,PageSize));
       
   288 
       
   289 	test.Next(_L("Free the original shadow page"));
       
   290 	__KHEAP_FAILNEXT(0);
       
   291 	test_KErrNone(Shadow.Free(aPageAddr));
       
   292 	__KHEAP_RESET;
       
   293 	
       
   294 	test.Next(_L("Check original ROM data restored"));
       
   295 	test_Equal(0, Mem::Compare((TUint8*)aPageAddr,PageSize,PageBuffer1,PageSize));
       
   296 
       
   297 	test.Next(_L("Check kernel heap balance"));
       
   298 	__KHEAP_MARKEND;
       
   299 
       
   300 	test.End();
       
   301 	}
       
   302 
       
   303 void TestInteractionWithPinning(TLinAddr aPageAddr)
       
   304 	{
       
   305 	test.Start(_L("Test pinning of shadow pages"));
       
   306 	
       
   307 	// Create pin object to use for all pinnings
       
   308 	test_KErrNone(MemoryTest.CreateVirtualPinObject());
       
   309 
       
   310 	test.Next(_L("Test pin - shadow - unpin - unshadow"));
       
   311 	test_Equal(KErrNone, MemoryTest.PinVirtualMemory((TLinAddr)aPageAddr, PageSize));
       
   312 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   313 	test_Equal(KErrNone, MemoryTest.UnpinVirtualMemory());
       
   314 	test_KErrNone(Shadow.Free(aPageAddr));
       
   315 		
       
   316 	test.Next(_L("Test pin - shadow - unshadow - unpin"));
       
   317 	test_Equal(KErrNone, MemoryTest.PinVirtualMemory((TLinAddr)aPageAddr, PageSize));
       
   318 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   319 	test_KErrNone(Shadow.Free(aPageAddr));
       
   320 	test_Equal(KErrNone, MemoryTest.UnpinVirtualMemory());
       
   321 
       
   322 	test.Next(_L("Test shadow - pin - unpin - unshadow"));
       
   323 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   324 	test_Equal(KErrNone, MemoryTest.PinVirtualMemory((TLinAddr)aPageAddr, PageSize));
       
   325 	test_Equal(KErrNone, MemoryTest.UnpinVirtualMemory());
       
   326 	test_KErrNone(Shadow.Free(aPageAddr));
       
   327 
       
   328 	test.Next(_L("Test shadow - pin - unshadow - unpin"));
       
   329 	test_KErrNone(Shadow.Alloc(aPageAddr));
       
   330 	test_Equal(KErrNone, MemoryTest.PinVirtualMemory((TLinAddr)aPageAddr, PageSize));
       
   331 	test_KErrNone(Shadow.Free(aPageAddr));
       
   332 	test_Equal(KErrNone, MemoryTest.UnpinVirtualMemory());
       
   333 
       
   334 	test_KErrNone(MemoryTest.DestroyVirtualPinObject());
       
   335 	test.End();
       
   336 	}
       
   337 
       
   338 const TUint KChunkShift = 20;
       
   339 const TUint KChunkSize = 1 << KChunkShift;
       
   340 
       
   341 void TestRomIsSectionMapped()
       
   342 	{
       
   343 	test.Start(_L("Test ROM is section mapped"));
       
   344 	
       
   345 	TUint pdSize;
       
   346 	TUint pdBase;
       
   347 	TUint offset;
       
   348 
       
   349 #ifdef __MARM__
       
   350 	test_KErrNone(Shadow.GetPdInfo(KGlobalPageDirectory, pdSize, pdBase, offset));
       
   351 	test.Printf(_L("pd base == %08x, pd size == %08x, pd offset == %08x\n"), pdBase, pdSize, offset);
       
   352 
       
   353 	for (TLinAddr addr = RomUnpagedStart ; addr <= RomUnpagedEnd ; addr += KChunkSize)
       
   354 		{
       
   355 		TUint i = (addr >> KChunkShift) - offset;
       
   356 		TUint pde = Shadow.Read(pdBase + i*4);
       
   357 		test.Printf(_L("  %08x: PDE %08x\n"), addr, pde);
       
   358 
       
   359 		TUint expectedPdeType = (RomUnpagedEnd - addr) >= KChunkSize ? 2 : 1;
       
   360 		test_Equal(expectedPdeType, pde & 3);
       
   361 		}
       
   362 #else
       
   363 	test.Printf(_L("Test not supported on this architecture\n"));
       
   364 #endif
       
   365 
       
   366 	test.End();
       
   367 	}
       
   368 
       
   369 void Initialise()
       
   370 	{
       
   371 	test.Start(_L("Load test LDDs"));
       
   372 	
       
   373 	TInt r=User::LoadLogicalDevice(KLddFileName);
       
   374 	test_Value(r, r==KErrNone || r==KErrAlreadyExists);
       
   375 	if (PageMovingSupported)
       
   376 		{
       
   377 		r=User::LoadLogicalDevice(KMoveLddFileName);
       
   378 		test_Value(r, r==KErrNone || r==KErrAlreadyExists);
       
   379 		}
       
   380 
       
   381 	test_KErrNone(UserHal::PageSizeInBytes(PageSize));
       
   382 
       
   383 	test.Next(_L("Open test LDDs"));
       
   384 	test_KErrNone(Shadow.Open());
       
   385 	test_KErrNone(MemoryTest.Open());
       
   386 	if (PageMovingSupported)
       
   387 		test_KErrNone(PageMove.Open());
       
   388 
       
   389 	test.Next(_L("Allocate some RAM"));
       
   390 	PageBuffer1=(TUint8*)User::Alloc(PageSize);
       
   391 	test_NotNull(PageBuffer1);
       
   392 	PageBuffer2=(TUint8*)User::Alloc(PageSize);
       
   393 	test_NotNull(PageBuffer2);
       
   394 	PageBuffer3=(TUint8*)User::Alloc(PageSize);
       
   395 	test_NotNull(PageBuffer3);
       
   396 
       
   397 	test.Next(_L("Discover ROM addresses"));
       
   398 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
       
   399 	RomUnpagedStart = (TLinAddr)romHeader;
       
   400 	test_Equal(0, RomUnpagedStart & (PageSize - 1));
       
   401 
       
   402 	//Round up to page size (May already be rounded, but doesnt hurt)
       
   403 	TUint romSize = (romHeader->iUncompressedSize + PageSize - 1) & ~(PageSize - 1);
       
   404 	
       
   405 	if (DPTest::Attributes() & DPTest::ERomPaging)
       
   406 		{
       
   407 		// Use paged part of rom for testing
       
   408 		test_NotNull(romHeader->iPageableRomStart);
       
   409 		RomUnpagedEnd = RomUnpagedStart + romHeader->iPageableRomStart;
       
   410 		test_Equal(0, RomUnpagedEnd & (PageSize - 1));
       
   411 		RomPagedStart = RomUnpagedEnd;
       
   412 		RomPagedEnd = RomUnpagedStart + romSize;
       
   413 		RomPagingSupported = ETrue;
       
   414 		}
       
   415 	else
       
   416 		{
       
   417 		RomUnpagedEnd = RomUnpagedStart + romSize;
       
   418 		RomPagedStart = RomUnpagedEnd;
       
   419 		RomPagedEnd = RomPagedStart;
       
   420 		}
       
   421 
       
   422 	test.Printf(_L("Unpaged ROM: %08x -> %08x\n"), RomUnpagedStart, RomUnpagedEnd);
       
   423 	test.Printf(_L("Paged ROM:   %08x -> %08x\n"), RomPagedStart, RomPagedEnd);
       
   424 
       
   425 	test.End();
       
   426 	}
       
   427 
       
   428 void Finalise()
       
   429 	{
       
   430 	PageMove.Close();
       
   431 	MemoryTest.Close();
       
   432 
       
   433 	User::Free(PageBuffer1);
       
   434 	User::Free(PageBuffer2);
       
   435 	User::Free(PageBuffer3);
       
   436 	}
       
   437 
       
   438 GLDEF_C TInt E32Main()
       
   439 //
       
   440 // Test ROM shadowing
       
   441 //
       
   442     {
       
   443 	test.Title();
       
   444 	
       
   445 	if (!HaveMMU())
       
   446 		{
       
   447 		test.Printf(_L("This test requires an MMU\n"));
       
   448 		return KErrNone;
       
   449 		}
       
   450 #ifdef __WINS__
       
   451 	test.Printf(_L("Test not valid in WINS\n"));
       
   452 #else
       
   453 
       
   454 	test.Start(_L("Testing ROM shadowing"));
       
   455 	Initialise();
       
   456 
       
   457 	TestRomIsSectionMapped(); 
       
   458 
       
   459 	TestShadowPage(RomUnpagedStart, EUnpaged);
       
   460 	TestShadowPage(RomUnpagedStart + PageSize, EUnpaged);
       
   461 	TestShadowPage(RomUnpagedEnd - PageSize, EUnpaged);
       
   462 	TestNoFreeRAM(RomUnpagedStart);
       
   463 	TestShadowPageOOM(RomUnpagedStart);
       
   464 	
       
   465 	if (RomPagingSupported)
       
   466 		{
       
   467 		TestShadowPage(RomPagedStart, EPaged);
       
   468 		TestShadowPage(RomPagedStart + PageSize, EPaged);
       
   469 		TestShadowPage(RomPagedEnd - PageSize, EPaged);
       
   470 		TestNoFreeRAM(RomPagedEnd - PageSize);
       
   471 		TestShadowPageOOM(RomPagedStart);
       
   472 		TestInteractionWithPinning(RomPagedStart);
       
   473 		}
       
   474 
       
   475 	// todo: add test when reforming section mappings is implemented
       
   476 	// TestRomIsSectionMapped();
       
   477 	
       
   478 	Finalise();
       
   479 	test.End();
       
   480 	
       
   481 #endif
       
   482 	return(KErrNone);
       
   483     }
       
   484