| 0 |      1 | // Copyright (c) 2003-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_sharedio.cpp
 | 
|  |     15 | // Overview:
 | 
|  |     16 | // Verifies the correct implementation of Shared IO Buffers
 | 
|  |     17 | // API information:
 | 
|  |     18 | // DSharedIoBuffer
 | 
|  |     19 | // Details:
 | 
|  |     20 | // 1. Loading the shared IO buffer test device driver
 | 
|  |     21 | // 2. Create buffer of a specified size
 | 
|  |     22 | // - it passes a request to the device driver to create a buffer
 | 
|  |     23 | // - the driver creates a shared io buffer and it zero fills it
 | 
|  |     24 | // - it checks the size is as specified
 | 
|  |     25 | // 3. Map in buffer
 | 
|  |     26 | // - it passes a request to the device driver to map the buffer created at
 | 
|  |     27 | // step 1 into this user process
 | 
|  |     28 | // - the driver maps the buffer into this user process
 | 
|  |     29 | // - checks if UserToKernel and KernelToUser methods work as expected
 | 
|  |     30 | // - fills a buffer
 | 
|  |     31 | // - returns the user address and size to the user process
 | 
|  |     32 | // - using the address and size returned by the driver, the user process
 | 
|  |     33 | // checks the buffer is filled as expected
 | 
|  |     34 | // 4. Fill and check shared buffer
 | 
|  |     35 | // - user process fills the buffer and driver checks it
 | 
|  |     36 | // - driver fills the buffer and user process checks it
 | 
|  |     37 | // 5. Map Out Buffer
 | 
|  |     38 | // - requests to the driver that the buffer should be unmapped from this
 | 
|  |     39 | // process' address space
 | 
|  |     40 | // - the driver checks that iUserAddress becomes NULL after unmapping
 | 
|  |     41 | // 6. Destroy Buffer
 | 
|  |     42 | // - requests to the driver to destroy the buffer
 | 
|  |     43 | // 7. Create a buffer with a physical address
 | 
|  |     44 | // (not performed on WINS)
 | 
|  |     45 | // - requests to the driver to create a buffer by specifying a physical address
 | 
|  |     46 | // - the driver allocates a physical address
 | 
|  |     47 | // - creates a shared IO buffer over that physical address
 | 
|  |     48 | // - fills the buffer with a pattern
 | 
|  |     49 | // - destroys the buffer
 | 
|  |     50 | // - creates a hardware chunk over the same physical address
 | 
|  |     51 | // - checks the buffer contains the pattern
 | 
|  |     52 | // - closes the chunk
 | 
|  |     53 | // 8. Check using the same buffer by 2 different user processes
 | 
|  |     54 | // (not performed on WINS)
 | 
|  |     55 | // - process 1 maps a global buffer (the global buffer will be
 | 
|  |     56 | // created in the context of process 1)
 | 
|  |     57 | // - fills it
 | 
|  |     58 | // - unmaps it
 | 
|  |     59 | // - process 2 maps the global buffer
 | 
|  |     60 | // - checks if it's filled accordingly
 | 
|  |     61 | // - unmaps it
 | 
|  |     62 | // - destroys the global buffer
 | 
|  |     63 | // 9. Checking buffers are protected at context switching
 | 
|  |     64 | // (not relevant on WINS)
 | 
|  |     65 | // - creates a shared buffer and map it into this process
 | 
|  |     66 | // - creates a new process
 | 
|  |     67 | // - the new process tries to access the buffer mapped into the first process
 | 
|  |     68 | // by zeroing the raw buffer passed from the first process. This relies on the
 | 
|  |     69 | // fact that each shared buffer is created in the Home Section, so they will be
 | 
|  |     70 | // available at the same address
 | 
|  |     71 | // - tests if the new process was panicked due to access violation
 | 
|  |     72 | // - tests if the contents of the buffer haven't been changed
 | 
|  |     73 | // 10.Checking writing to unmapped buffer
 | 
|  |     74 | // (not performed on WINS)
 | 
|  |     75 | // - creates a new process
 | 
|  |     76 | // - the new process creates a buffer, maps it and unmaps it
 | 
|  |     77 | // - the new process tries to use the buffer after unmapping
 | 
|  |     78 | // - the parent process logs the exit type and reason and checks
 | 
|  |     79 | // these are EExitPanic and 3 (Kern 3 - access violation)
 | 
|  |     80 | // 11.Checking address lookup is implemented
 | 
|  |     81 | // (not relevant on WINS)
 | 
|  |     82 | // - creates a new process
 | 
|  |     83 | // - the new process will ask the device driver to read and write a descriptor
 | 
|  |     84 | // in the old process, the kernel will perform an address lookup before
 | 
|  |     85 | // reading or writing the descriptor, to make sure the address location does
 | 
|  |     86 | // belong to the old process. The descriptor is a TPtr pointing to a buffer
 | 
|  |     87 | // located in a shared io buffer.
 | 
|  |     88 | // - device driver will return an error in case address lookup fails or ThreadRead
 | 
|  |     89 | // or ThreadWrite fail
 | 
|  |     90 | // - the new process returns the error code returned by the device driver
 | 
|  |     91 | // - the old process tests for the exit code for the new process being KErrNone and
 | 
|  |     92 | // that the thread is not panicked, and also that the values written and read
 | 
|  |     93 | // are those expected.
 | 
|  |     94 | // 12.Closing test driver
 | 
|  |     95 | // - Trivial, but it will test if a created & mapped shared io buffer gets released
 | 
|  |     96 | // successfully when the logical channel is closed (which in turn will delete the
 | 
|  |     97 | // shared io buffer associated with the channel)
 | 
|  |     98 | // The test comes in 4 flavours, in order to test memory protection when context switching
 | 
|  |     99 | // between different types of processes.
 | 
|  |    100 | // T_SHAREDIO:
 | 
|  |    101 | // Main process is a moving process which creates another moving process.
 | 
|  |    102 | // T_SHAREDIO2:
 | 
|  |    103 | // Main process is a fixed process which creates a moving process.
 | 
|  |    104 | // T_SHAREDIO3:
 | 
|  |    105 | // Main process is a fixed process which creates another fixed process.
 | 
|  |    106 | // T_SHAREDIO4:
 | 
|  |    107 | // Main process is a moving process which creates a fixed process.
 | 
|  |    108 | // Platforms/Drives/Compatibility:
 | 
|  |    109 | // All (some steps will not be performed on emulator)
 | 
|  |    110 | // Assumptions/Requirement/Pre-requisites:
 | 
|  |    111 | // The test needs D_SHAREDIO.LDD, the device driver that actually operates the API. 
 | 
|  |    112 | // Failures and causes:
 | 
|  |    113 | // Failures of this test will indicate defects in the implementation of Shared Io Buffers.
 | 
|  |    114 | // Base Port information:
 | 
|  |    115 | // No?
 | 
|  |    116 | // 
 | 
|  |    117 | //
 | 
|  |    118 | 
 | 
|  |    119 | #define __E32TEST_EXTENSION__
 | 
|  |    120 | 
 | 
|  |    121 | #include <e32test.h>
 | 
|  |    122 | #include <e32math.h>
 | 
|  |    123 | #include "d_sharedio.h"
 | 
|  |    124 | #include <e32hal.h>
 | 
|  |    125 | #include "u32std.h"
 | 
|  |    126 | #include <u32hal.h>
 | 
|  |    127 | #include <e32svr.h>
 | 
|  |    128 | #include <f32dbg.h>
 | 
|  |    129 | #include <e32def.h>
 | 
|  |    130 | #include <e32def_private.h>
 | 
|  |    131 | #include "freeram.h"
 | 
|  |    132 | 
 | 
|  |    133 | LOCAL_D RTest test(_L("T_SHAREDIO"));
 | 
|  |    134 | 
 | 
|  |    135 | const TInt KTestBufferSize = 0x100000;
 | 
|  |    136 | 
 | 
|  |    137 | TUint MemModelAttributes;
 | 
|  |    138 | TBool PhysicalCommitSupported;
 | 
|  |    139 | 
 | 
|  |    140 | RTestLdd ldd;
 | 
|  |    141 | 
 | 
|  |    142 | TUint32 TestBufferSizes[]={0x1000, 0x10453, 0x100000, 0x100001, 0x203000, 0};
 | 
|  |    143 | 
 | 
|  |    144 | TInt checkBuffer(TAny* buffer, TUint32 aSize, TUint32 key)
 | 
|  |    145 | 	{
 | 
|  |    146 | 	TInt r=KErrNone;
 | 
|  |    147 | 	TUint8* m=(TUint8*)buffer;
 | 
|  |    148 | 	for(TUint32 size=0;size<aSize;size++,key+=5,m++)
 | 
|  |    149 | 		{
 | 
|  |    150 | 		if(*m!=(TUint8)(key%256))
 | 
|  |    151 | 			{
 | 
|  |    152 | 			r=KErrCorrupt;
 | 
|  |    153 | 			break;
 | 
|  |    154 | 			}
 | 
|  |    155 | 		}
 | 
|  |    156 | 	return r;
 | 
|  |    157 | 	}
 | 
|  |    158 | 
 | 
|  |    159 | TInt fillBuffer(TAny* buffer, TUint32 aSize, TUint32 key)
 | 
|  |    160 | 	{
 | 
|  |    161 | 	TUint8* m=(TUint8*)buffer;
 | 
|  |    162 | 	for(TUint32 size=0;size<aSize;size++,key+=5,m++)
 | 
|  |    163 | 		{
 | 
|  |    164 | 		*m=(TUint8)(key%256);
 | 
|  |    165 | 		}
 | 
|  |    166 | 	return KErrNone;
 | 
|  |    167 | 	}
 | 
|  |    168 | 
 | 
|  |    169 | TBool CheckBuffer(TAny* aBuffer,TInt aSize)
 | 
|  |    170 | 	{
 | 
|  |    171 | 	TAny** p = (TAny**)aBuffer;
 | 
|  |    172 | 	TAny** end = (TAny**)((TInt)p+aSize);
 | 
|  |    173 | 	while(p<end)
 | 
|  |    174 | 		{
 | 
|  |    175 | 		if(*p!=p)
 | 
|  |    176 | 			return EFalse;
 | 
|  |    177 | 		++p;
 | 
|  |    178 | 		}
 | 
|  |    179 | 	return ETrue;
 | 
|  |    180 | 	}
 | 
|  |    181 | 
 | 
|  |    182 | enum TTestProcessFunctions
 | 
|  |    183 | 	{
 | 
|  |    184 | 	ETestProcess1,
 | 
|  |    185 | 	ETestProcess2,
 | 
|  |    186 | 	ETestProcess3,
 | 
|  |    187 | 	};
 | 
|  |    188 | 
 | 
|  |    189 | class RTestProcess : public RProcess
 | 
|  |    190 | 	{
 | 
|  |    191 | public:
 | 
|  |    192 | 	void Create(TTestProcessFunctions aFunction,TInt aArg1=-1,TInt aArg2=-1);
 | 
|  |    193 | 	};
 | 
|  |    194 | 
 | 
|  |    195 | void RTestProcess::Create(TTestProcessFunctions aFunction,TInt aArg1,TInt aArg2)
 | 
|  |    196 | 	{
 | 
|  |    197 | 	if(aArg1==-1)
 | 
|  |    198 | 		aArg1 = RProcess().Id();
 | 
|  |    199 | 	TBuf<512> commandLine;
 | 
|  |    200 | 	commandLine.Num((TInt)aFunction);
 | 
|  |    201 | 	commandLine.Append(_L(" "));
 | 
|  |    202 | 	commandLine.AppendNum(aArg1);
 | 
|  |    203 | 	commandLine.Append(_L(" "));
 | 
|  |    204 | 	commandLine.AppendNum(aArg2);
 | 
|  |    205 | #ifdef __FIXED__
 | 
|  |    206 | 	//fixed process creating a moving process
 | 
|  |    207 | 	TFileName filename(RProcess().FileName());
 | 
|  |    208 | 	TInt pos=filename.LocateReverse(TChar('\\'));
 | 
|  |    209 | 	filename.SetLength(pos+1);
 | 
|  |    210 | 	filename+=_L("T_SHAREDIO.EXE");
 | 
|  |    211 | 	TInt r = RProcess::Create(filename,commandLine);
 | 
|  |    212 | #else
 | 
|  |    213 | #ifdef __SECOND_FIXED__
 | 
|  |    214 | 	//fixed process creating another fixed process
 | 
|  |    215 | 	TFileName filename(RProcess().FileName());
 | 
|  |    216 | 	TInt pos=filename.LocateReverse(TChar('\\'));
 | 
|  |    217 | 	filename.SetLength(pos+1);
 | 
|  |    218 | 	filename+=_L("T_SHAREDIO2.EXE");
 | 
|  |    219 | 	TInt r = RProcess::Create(filename,commandLine);
 | 
|  |    220 | #else
 | 
|  |    221 | #ifdef __MOVING_FIXED__
 | 
|  |    222 | 	//moving process creating a fixed process
 | 
|  |    223 | 	TFileName filename(RProcess().FileName());
 | 
|  |    224 | 	TInt pos=filename.LocateReverse(TChar('\\'));
 | 
|  |    225 | 	filename.SetLength(pos+1);
 | 
|  |    226 | 	filename+=_L("T_SHAREDIO2.EXE");
 | 
|  |    227 | 	TInt r = RProcess::Create(filename,commandLine);
 | 
|  |    228 | #else
 | 
|  |    229 | 	//moving process creating a moving process
 | 
|  |    230 | 	TInt r = RProcess::Create(RProcess().FileName(),commandLine);
 | 
|  |    231 | #endif
 | 
|  |    232 | #endif
 | 
|  |    233 | #endif
 | 
|  |    234 | 	test(r==KErrNone);
 | 
|  |    235 | 	SetJustInTime(EFalse);
 | 
|  |    236 | 	}
 | 
|  |    237 | 
 | 
|  |    238 | const TInt KProcessRendezvous = KRequestPending+1;
 | 
|  |    239 | 
 | 
|  |    240 | TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
 | 
|  |    241 | 	{
 | 
|  |    242 | 	(void)aArg1;
 | 
|  |    243 | 	(void)aArg2;
 | 
|  |    244 | 
 | 
|  |    245 | 	RTestLdd ldd;
 | 
|  |    246 | 	TInt r;
 | 
|  |    247 | 	r=User::LoadLogicalDevice(KSharedIoTestLddName);
 | 
|  |    248 | 	if(r!=KErrNone && r!=KErrAlreadyExists)
 | 
|  |    249 | 		return KErrGeneral;
 | 
|  |    250 | 	r=ldd.Open();
 | 
|  |    251 | 	if(r!=KErrNone)
 | 
|  |    252 | 		return r;
 | 
|  |    253 | 
 | 
|  |    254 | 	switch(aTestNum)
 | 
|  |    255 | 		{
 | 
|  |    256 | 	case ETestProcess1:
 | 
|  |    257 | 		{
 | 
|  |    258 | 		TAny* gbuffer;
 | 
|  |    259 | 		TUint32 gsize;
 | 
|  |    260 | 		r=User::GetTIntParameter(1,(TInt&)gbuffer);
 | 
|  |    261 | 		if(r!=KErrNone)
 | 
|  |    262 | 			return r;
 | 
|  |    263 | 		r=User::GetTIntParameter(2,(TInt&)gsize);
 | 
|  |    264 | 		if(r!=KErrNone)
 | 
|  |    265 | 			return r;
 | 
|  |    266 | 
 | 
|  |    267 | 		r=checkBuffer(gbuffer,gsize,23454);
 | 
|  |    268 | 		if(r!=KErrNone)
 | 
|  |    269 | 			return r;
 | 
|  |    270 | 		r=ldd.MapOutGlobalBuffer();
 | 
|  |    271 | 		if(r!=KErrNone)
 | 
|  |    272 | 			return r;
 | 
|  |    273 | 
 | 
|  |    274 | 		r=ldd.CreateBuffer(KTestBufferSize);
 | 
|  |    275 | 		if(r!=KErrNone)
 | 
|  |    276 | 			return r;
 | 
|  |    277 | 
 | 
|  |    278 | 		TAny* buffer;
 | 
|  |    279 | 		TUint32 size;
 | 
|  |    280 | 		r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    281 | 		if(r!=KErrNone)
 | 
|  |    282 | 			return r;
 | 
|  |    283 | 
 | 
|  |    284 | 		if(!CheckBuffer(buffer,size))
 | 
|  |    285 | 			return KErrGeneral;
 | 
|  |    286 | 
 | 
|  |    287 | 		r=ldd.MapOutBuffer();
 | 
|  |    288 | 		if(r!=KErrNone)
 | 
|  |    289 | 			return r;
 | 
|  |    290 | 
 | 
|  |    291 | 		RProcess::Rendezvous(KProcessRendezvous);
 | 
|  |    292 | 
 | 
|  |    293 | 		*(TInt*)buffer = 0;   // Should cause exception
 | 
|  |    294 | 		break;
 | 
|  |    295 | 		}
 | 
|  |    296 | 	case ETestProcess2:
 | 
|  |    297 | 		{
 | 
|  |    298 | 		TInt size=aArg2;
 | 
|  |    299 | 		TUint8* p=(TUint8*)aArg1;
 | 
|  |    300 | 
 | 
|  |    301 | 		RProcess::Rendezvous(KProcessRendezvous);
 | 
|  |    302 | 		for(TInt i=0;i<size;i++)
 | 
|  |    303 | 			p[i]=0; // Should cause exception
 | 
|  |    304 | 		break;
 | 
|  |    305 | 		}
 | 
|  |    306 | 	case ETestProcess3:
 | 
|  |    307 | 		{
 | 
|  |    308 | 		TAny* buffer;
 | 
|  |    309 | 		TUint32 size;
 | 
|  |    310 | 
 | 
|  |    311 | 		r=ldd.CreateBuffer(KTestBufferSize);
 | 
|  |    312 | 		if(r!=KErrNone)
 | 
|  |    313 | 			return r;
 | 
|  |    314 | 
 | 
|  |    315 | 		r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    316 | 		if(r!=KErrNone)
 | 
|  |    317 | 			return r;
 | 
|  |    318 | 
 | 
|  |    319 | 		if(!CheckBuffer(buffer,size))
 | 
|  |    320 | 			return KErrGeneral;
 | 
|  |    321 | 
 | 
|  |    322 | 		*(TInt*)buffer=KMagic1;
 | 
|  |    323 | 		TPckg<TInt> buf(*(TInt*)buffer);
 | 
|  |    324 | 		r=ldd.ThreadRW(buf);
 | 
|  |    325 | 		if(r!=KErrNone)
 | 
|  |    326 | 			return r;
 | 
|  |    327 | 
 | 
|  |    328 | 		if(*(TInt*)buffer!=KMagic2)
 | 
|  |    329 | 			return KErrCorrupt;
 | 
|  |    330 | 
 | 
|  |    331 | 		r=ldd.ThreadRW(*(TDes8*)aArg1,aArg2);
 | 
|  |    332 | 		if(r!=KErrNone)
 | 
|  |    333 | 			return r;
 | 
|  |    334 | 		
 | 
|  |    335 | 		r=ldd.MapOutBuffer();
 | 
|  |    336 | 		if(r!=KErrNone)
 | 
|  |    337 | 			return r;
 | 
|  |    338 | 
 | 
|  |    339 | 		break;
 | 
|  |    340 | 		}
 | 
|  |    341 | 	default:
 | 
|  |    342 | 		User::Panic(_L("T_SHAREDIO"),1);
 | 
|  |    343 | 		}
 | 
|  |    344 | 
 | 
|  |    345 | 	ldd.Close();	
 | 
|  |    346 | 	return KErrNone;
 | 
|  |    347 | 	}
 | 
|  |    348 | 
 | 
|  |    349 | void CreateWithOOMCheck(TInt aSize, TBool aPhysicalAddress)
 | 
|  |    350 | 	{
 | 
|  |    351 | 	TInt failResult=KErrGeneral;
 | 
|  |    352 | 
 | 
|  |    353 | 	TInt freeRam = FreeRam(); //This will also add a delay
 | 
|  |    354 | 
 | 
|  |    355 | 	for(TInt failCount=1; failCount<1000; failCount++)
 | 
|  |    356 | 		{
 | 
|  |    357 | 		test.Printf(_L("alloc fail count = %d\n"),failCount);
 | 
|  |    358 | 
 | 
|  |    359 | 		User::__DbgSetAllocFail(ETrue,RAllocator::EFailNext,failCount);
 | 
|  |    360 | 		__KHEAP_MARK;
 | 
|  |    361 | 		
 | 
|  |    362 | 		if (aPhysicalAddress)
 | 
|  |    363 | 			failResult=ldd.CreateBufferPhysAddr(aSize);
 | 
|  |    364 | 		else
 | 
|  |    365 | 			failResult=ldd.CreateBuffer(aSize);
 | 
|  |    366 | 
 | 
|  |    367 | 		if(failResult==KErrNone)
 | 
|  |    368 | 			break;
 | 
|  |    369 | 
 | 
|  |    370 | 		test(failResult==KErrNoMemory);
 | 
|  |    371 | 		__KHEAP_MARKEND;
 | 
|  |    372 | 
 | 
|  |    373 | 		test(freeRam == FreeRam());  //This will also add a delay
 | 
|  |    374 | 		}
 | 
|  |    375 | 	User::__DbgSetAllocFail(ETrue,RAllocator::ENone,0);
 | 
|  |    376 | 	__KHEAP_RESET;
 | 
|  |    377 | 
 | 
|  |    378 | 	test.Next(_L("Destroy buffer"));
 | 
|  |    379 | 	if (aPhysicalAddress)
 | 
|  |    380 | 		ldd.DestroyBufferPhysAddr();
 | 
|  |    381 | 	else
 | 
|  |    382 | 		ldd.DestroyBuffer();
 | 
|  |    383 | 	
 | 
|  |    384 | 	test(freeRam == FreeRam());  //This will also add a delay
 | 
|  |    385 | 	}
 | 
|  |    386 | 
 | 
|  |    387 | GLDEF_C TInt E32Main()
 | 
|  |    388 |     {
 | 
|  |    389 | 	TBuf16<512> cmd;
 | 
|  |    390 | 	User::CommandLine(cmd);
 | 
|  |    391 | 	if(cmd.Length() && TChar(cmd[0]).IsDigit())
 | 
|  |    392 | 		{
 | 
|  |    393 | 		TInt function = -1;
 | 
|  |    394 | 		TInt arg1 = -1;
 | 
|  |    395 | 		TInt arg2 = -1;
 | 
|  |    396 | 		TLex lex(cmd);
 | 
|  |    397 | 		lex.Val(function);
 | 
|  |    398 | 		lex.SkipSpace();
 | 
|  |    399 | 		lex.Val(arg1);
 | 
|  |    400 | 		lex.SkipSpace();
 | 
|  |    401 | 		lex.Val(arg2);
 | 
|  |    402 | 		return DoTestProcess(function,arg1,arg2);
 | 
|  |    403 | 		}
 | 
|  |    404 | 
 | 
|  |    405 | 	MemModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
 | 
|  |    406 | 	TUint mm=MemModelAttributes&EMemModelTypeMask;
 | 
|  |    407 | 	PhysicalCommitSupported = mm!=EMemModelTypeDirect && mm!=EMemModelTypeEmul;
 | 
|  |    408 | 
 | 
|  |    409 | // Turn off lazy dll unloading
 | 
|  |    410 | 	RLoader l;
 | 
|  |    411 | 	test(l.Connect()==KErrNone);
 | 
|  |    412 | 	test(l.CancelLazyDllUnload()==KErrNone);
 | 
|  |    413 | 	l.Close();
 | 
|  |    414 | 
 | 
|  |    415 | 	test.Title();
 | 
|  |    416 | 
 | 
|  |    417 | #if defined(__FIXED__) || defined(__SECOND_FIXED__) || defined(__MOVING_FIXED__)
 | 
|  |    418 | 	if(mm!=EMemModelTypeMoving)
 | 
|  |    419 | 		{
 | 
|  |    420 | 		test.Printf(_L("TESTS NOT RUN - Only applicable to moving memory model\r\n"));
 | 
|  |    421 | 		return 0;
 | 
|  |    422 | 		}
 | 
|  |    423 | #endif
 | 
|  |    424 | 
 | 
|  |    425 | 	test.Start(_L("Loading test driver..."));
 | 
|  |    426 | 
 | 
|  |    427 | 	TInt r;
 | 
|  |    428 | 	r=User::LoadLogicalDevice(KSharedIoTestLddName);
 | 
|  |    429 | 	test(r==KErrNone || r==KErrAlreadyExists);
 | 
|  |    430 | 	r=User::LoadLogicalDevice(KSharedIoTestLddName);
 | 
|  |    431 | 	test(r==KErrAlreadyExists);
 | 
|  |    432 | 	r=ldd.Open();
 | 
|  |    433 | 	test(r==KErrNone);
 | 
|  |    434 | 
 | 
|  |    435 | 	TAny* buffer;
 | 
|  |    436 | 	TUint32 size;
 | 
|  |    437 | 	TUint32 key;
 | 
|  |    438 | 
 | 
|  |    439 | 	TInt testBufferSize=0;
 | 
|  |    440 | 	for(; TestBufferSizes[testBufferSize]!=0; ++testBufferSize)
 | 
|  |    441 | 		{
 | 
|  |    442 | 		test.Printf(_L("Test buffer size = %08x\n"),TestBufferSizes[testBufferSize]);
 | 
|  |    443 | 
 | 
|  |    444 | 		test.Next(_L("Create buffer"));
 | 
|  |    445 | 		r=ldd.CreateBuffer(TestBufferSizes[testBufferSize]);
 | 
|  |    446 | 		if(r!=KErrNone)
 | 
|  |    447 | 			test.Printf(_L("Creating buffer failed client r=%d"), r);
 | 
|  |    448 | 		test(r==KErrNone);
 | 
|  |    449 | 
 | 
|  |    450 | 		test.Next(_L("Map In Buffer"));
 | 
|  |    451 | 		r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    452 | 		
 | 
|  |    453 | 		test.Next(_L("CheckBuffer"));
 | 
|  |    454 | 		test(CheckBuffer(buffer,size));
 | 
|  |    455 | 		test(r==KErrNone);
 | 
|  |    456 | 		test.Next(_L("Fill and check shared buffer"));
 | 
|  |    457 | 		key=Math::Random();
 | 
|  |    458 | 		fillBuffer(buffer,size,key);
 | 
|  |    459 | 		test(ldd.CheckBuffer(key)==KErrNone);
 | 
|  |    460 | 
 | 
|  |    461 | 		key=Math::Random();
 | 
|  |    462 | 		test(ldd.FillBuffer(key)==KErrNone);
 | 
|  |    463 | 		test(checkBuffer(buffer,size,key)==KErrNone);
 | 
|  |    464 | 
 | 
|  |    465 | 		test.Next(_L("Map Out Buffer"));
 | 
|  |    466 | 		r=ldd.MapOutBuffer();
 | 
|  |    467 | 		test(r==KErrNone);
 | 
|  |    468 | 
 | 
|  |    469 | 		test.Next(_L("Destroy Buffer"));
 | 
|  |    470 | 		r=ldd.DestroyBuffer();
 | 
|  |    471 | 		test(r==KErrNone);
 | 
|  |    472 | 
 | 
|  |    473 | 		test.Next(_L("Create a buffer under OOM conditions"));
 | 
|  |    474 | 		CreateWithOOMCheck(TestBufferSizes[testBufferSize], EFalse);
 | 
|  |    475 | 
 | 
|  |    476 | 		if(PhysicalCommitSupported)
 | 
|  |    477 | 			{
 | 
|  |    478 | 			test.Next(_L("Create a buffer with a physical address under OOM conditions"));
 | 
|  |    479 | 			CreateWithOOMCheck(TestBufferSizes[testBufferSize], ETrue);
 | 
|  |    480 | 
 | 
|  |    481 | 			test.Next(_L("Create a buffer with a physical address"));
 | 
|  |    482 | 			r=ldd.CreateBufferPhysAddr(0x1000);
 | 
|  |    483 | 			test(r==KErrNone);
 | 
|  |    484 | 
 | 
|  |    485 | 			test.Next(_L("Map In physical address Buffer"));
 | 
|  |    486 | 			r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    487 | 			test(r==KErrNone);
 | 
|  |    488 | 
 | 
|  |    489 | 			test.Next(_L("Fill and check physical address shared buffer"));
 | 
|  |    490 | 			key=Math::Random();
 | 
|  |    491 | 			fillBuffer(buffer,size,key);
 | 
|  |    492 | 			test(ldd.CheckBuffer(key)==KErrNone);
 | 
|  |    493 | 
 | 
|  |    494 | 			key=Math::Random();
 | 
|  |    495 | 			test(ldd.FillBuffer(key)==KErrNone);
 | 
|  |    496 | 			test(checkBuffer(buffer,size,key)==KErrNone);
 | 
|  |    497 | 
 | 
|  |    498 | 			test.Next(_L("Map Out physical address Buffer"));
 | 
|  |    499 | 			r=ldd.MapOutBuffer();
 | 
|  |    500 | 			test(r==KErrNone);
 | 
|  |    501 | 
 | 
|  |    502 | 			test.Next(_L("Destroy a buffer with a physical address"));
 | 
|  |    503 | 			r=ldd.DestroyBufferPhysAddr();
 | 
|  |    504 | 			test(r==KErrNone);
 | 
|  |    505 | 		}
 | 
|  |    506 | 
 | 
|  |    507 | 		test.Next(_L("Check using the same buffer by 2 different user processes"));
 | 
|  |    508 | 		TAny* gbuffer;
 | 
|  |    509 | 		TUint32 gsize;
 | 
|  |    510 | 		r=ldd.MapInGlobalBuffer(RProcess().Id(),gbuffer,gsize);
 | 
|  |    511 | 		test(r==KErrNone);
 | 
|  |    512 | 
 | 
|  |    513 | 		fillBuffer(gbuffer,gsize,23454);
 | 
|  |    514 | 
 | 
|  |    515 | 		r=ldd.MapOutGlobalBuffer();
 | 
|  |    516 | 		test(r==KErrNone);
 | 
|  |    517 | 
 | 
|  |    518 | 		r=ldd.CreateBuffer(TestBufferSizes[testBufferSize]);
 | 
|  |    519 | 		test(r==KErrNone);
 | 
|  |    520 | 
 | 
|  |    521 | 		r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    522 | 		test(r==KErrNone);
 | 
|  |    523 | 
 | 
|  |    524 | 		test(CheckBuffer(buffer,size));
 | 
|  |    525 | 
 | 
|  |    526 | 		key=Math::Random();
 | 
|  |    527 | 		fillBuffer(buffer,size,key);
 | 
|  |    528 | 		test(ldd.CheckBuffer(key)==KErrNone);
 | 
|  |    529 | 
 | 
|  |    530 | 		RTestProcess rogueP;
 | 
|  |    531 | 		TRequestStatus rendezvous;
 | 
|  |    532 | 		TRequestStatus logon;
 | 
|  |    533 | 
 | 
|  |    534 | 		if(MemModelAttributes&EMemModelAttrProcessProt)
 | 
|  |    535 | 			{
 | 
|  |    536 | 			test.Next(_L("Checking buffers are protected at context switching"));
 | 
|  |    537 | 			rogueP.Create(ETestProcess2,(TInt)buffer,(TInt)size);
 | 
|  |    538 | 			rogueP.Logon(logon);
 | 
|  |    539 | 			rogueP.Rendezvous(rendezvous);
 | 
|  |    540 | 			rogueP.Resume();
 | 
|  |    541 | 			User::WaitForRequest(rendezvous);
 | 
|  |    542 | 			test(rendezvous==KProcessRendezvous);
 | 
|  |    543 | 			User::WaitForRequest(logon);
 | 
|  |    544 | 			test(rogueP.ExitType()==EExitPanic);
 | 
|  |    545 | 			test(logon==3);
 | 
|  |    546 | 			test(ldd.CheckBuffer(key)==KErrNone);
 | 
|  |    547 | 			}
 | 
|  |    548 | 
 | 
|  |    549 | 		r=ldd.MapOutBuffer();
 | 
|  |    550 | 		test(r==KErrNone);
 | 
|  |    551 | 
 | 
|  |    552 | 		r=ldd.DestroyBuffer();
 | 
|  |    553 | 		test(r==KErrNone);
 | 
|  |    554 | 
 | 
|  |    555 | 		RTestProcess process;
 | 
|  |    556 | 
 | 
|  |    557 | 		if((MemModelAttributes&EMemModelAttrKernProt) && (MemModelAttributes&EMemModelTypeMask)!=EMemModelTypeDirect)
 | 
|  |    558 | 			{
 | 
|  |    559 | 			test.Next(_L("Checking writing to unmapped buffer"));
 | 
|  |    560 | 			process.Create(ETestProcess1);
 | 
|  |    561 | 			process.Logon(logon);
 | 
|  |    562 | 			process.Rendezvous(rendezvous);
 | 
|  |    563 | 			test(ldd.MapInGlobalBuffer(process.Id(),gbuffer,gsize)==KErrNone);
 | 
|  |    564 | 			test(process.SetParameter(1,(TInt)gbuffer)==KErrNone);
 | 
|  |    565 | 			test(process.SetParameter(2,(TInt)gsize)==KErrNone);
 | 
|  |    566 | 			process.Resume();
 | 
|  |    567 | 			User::WaitForRequest(rendezvous);
 | 
|  |    568 | 			test(rendezvous==KProcessRendezvous);
 | 
|  |    569 | 			User::WaitForRequest(logon);
 | 
|  |    570 | 			test(process.ExitType()==EExitPanic);
 | 
|  |    571 | 			test(logon==3);
 | 
|  |    572 | 			process.Close();
 | 
|  |    573 | 			}
 | 
|  |    574 | 
 | 
|  |    575 | 		r=ldd.CreateBuffer(TestBufferSizes[testBufferSize]);
 | 
|  |    576 | 		if(r!=KErrNone)
 | 
|  |    577 | 			return r;
 | 
|  |    578 | 
 | 
|  |    579 | 		r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    580 | 		if(r!=KErrNone)
 | 
|  |    581 | 			return r;
 | 
|  |    582 | 
 | 
|  |    583 | 		if(!CheckBuffer(buffer,size))
 | 
|  |    584 | 			return KErrGeneral;
 | 
|  |    585 | 
 | 
|  |    586 | 		*(TInt*)buffer=KMagic1;
 | 
|  |    587 | 		TPckg<TInt> buf(*(TInt*)buffer);
 | 
|  |    588 | 
 | 
|  |    589 | 		RTestProcess proc;
 | 
|  |    590 | 		test.Next(_L("Checking address lookup is implemented"));
 | 
|  |    591 | 		proc.Create(ETestProcess3,(TInt)&buf,RThread().Id());
 | 
|  |    592 | 		proc.Logon(logon);
 | 
|  |    593 | 		proc.Resume();
 | 
|  |    594 | 		User::WaitForRequest(logon);
 | 
|  |    595 | 
 | 
|  |    596 | 		test(proc.ExitType()==EExitKill);
 | 
|  |    597 | 		test(logon==0);
 | 
|  |    598 | 		test(*(TInt*)buffer==KMagic2);
 | 
|  |    599 | 
 | 
|  |    600 | 		ldd.DestroyBuffer();
 | 
|  |    601 | 
 | 
|  |    602 | 		// Check process death whilst buffer is mapped in
 | 
|  |    603 | 		// Test case for defect DEF051851 - Shared IO Buffer fault when process dies
 | 
|  |    604 | 		test.Next(_L("Checking process death whilst buffer is mapped in"));
 | 
|  |    605 | 			process.Create(ETestProcess1);
 | 
|  |    606 | 			process.Logon(logon);
 | 
|  |    607 | 			test.Start(_L("Map buffer into another process"));
 | 
|  |    608 | 			test(ldd.MapInGlobalBuffer(process.Id(),gbuffer,gsize)==KErrNone);
 | 
|  |    609 | 			test.Next(_L("Kill other process"));
 | 
|  |    610 | 			process.Kill(99);
 | 
|  |    611 | 			User::WaitForRequest(logon);
 | 
|  |    612 | 			test(process.ExitType()==EExitKill);
 | 
|  |    613 | 			test(logon==99);
 | 
|  |    614 | 			process.Close();
 | 
|  |    615 | 			test.Next(_L("Map out buffer"));
 | 
|  |    616 | 			r=ldd.MapOutGlobalBuffer();
 | 
|  |    617 | 			test.Printf(_L("result = %d\n"),r);
 | 
|  |    618 | 			test(r==KErrNone);
 | 
|  |    619 | 
 | 
|  |    620 | 			test.Next(_L("Map buffer into this process"));
 | 
|  |    621 | 			test(ldd.MapInGlobalBuffer(RProcess().Id(),gbuffer,gsize)==KErrNone);
 | 
|  |    622 | 			test.Next(_L("Map out buffer from this process"));
 | 
|  |    623 | 			r=ldd.MapOutGlobalBuffer();
 | 
|  |    624 | 			test.Printf(_L("result = %d\n"),r);
 | 
|  |    625 | 			test(r==KErrNone);
 | 
|  |    626 | 
 | 
|  |    627 | 			process.Create(ETestProcess1);
 | 
|  |    628 | 			process.Logon(logon);
 | 
|  |    629 | 			test.Next(_L("Map buffer into another process"));
 | 
|  |    630 | 			test(ldd.MapInGlobalBuffer(process.Id(),gbuffer,gsize)==KErrNone);
 | 
|  |    631 | 			test.Next(_L("Kill other process"));
 | 
|  |    632 | 			process.Kill(99);
 | 
|  |    633 | 			User::WaitForRequest(logon);
 | 
|  |    634 | 			test(process.ExitType()==EExitKill);
 | 
|  |    635 | 			test(logon==99);
 | 
|  |    636 | 			process.Close();
 | 
|  |    637 | 			test.Next(_L("Map out buffer"));
 | 
|  |    638 | 			r=ldd.MapOutGlobalBuffer();
 | 
|  |    639 | 			test.Printf(_L("result = %d\n"),r);
 | 
|  |    640 | 			test(r==KErrNone);
 | 
|  |    641 | 			test.End();
 | 
|  |    642 | 	} // loop for next buffer size
 | 
|  |    643 | 
 | 
|  |    644 | 	test.Next(_L("Create and map in buffer"));
 | 
|  |    645 | 	r=ldd.CreateBuffer(KTestBufferSize);
 | 
|  |    646 | 	test(r==KErrNone);
 | 
|  |    647 | 	r=ldd.MapInBuffer(&buffer,&size);
 | 
|  |    648 | 	test(r==KErrNone);
 | 
|  |    649 | 
 | 
|  |    650 | //  Test for DEF053512 - Can't delete SharedIo buffers in DLogicalDevice destructor 
 | 
|  |    651 | 
 | 
|  |    652 | 	test.Next(_L("Map in global buffer"));
 | 
|  |    653 | 	TAny* gbuffer;
 | 
|  |    654 | 	TUint32 gsize;
 | 
|  |    655 | 	test(ldd.MapInGlobalBuffer(RProcess().Id(),gbuffer,gsize)==KErrNone);
 | 
|  |    656 | 
 | 
|  |    657 | 	test.Next(_L("Closing channel (with a buffer still mapped in)"));
 | 
|  |    658 | 	ldd.Close();
 | 
|  |    659 | 
 | 
|  |    660 | //  Test for DEF053512 - Can't delete SharedIo buffers in DLogicalDevice destructor 
 | 
|  |    661 | 
 | 
|  |    662 | 	test.Next(_L("Unload driver (whilst global buffer still mapped in)"));
 | 
|  |    663 | 	r=User::FreeLogicalDevice(KSharedIoTestLddName);
 | 
|  |    664 | 	test(r==KErrNone);
 | 
|  |    665 | 
 | 
|  |    666 | 	test.End();
 | 
|  |    667 | 
 | 
|  |    668 | 
 | 
|  |    669 | 
 | 
|  |    670 | 	return(0);
 | 
|  |    671 |     }
 | 
|  |    672 | 
 | 
|  |    673 | 
 |