| author | Pat Downey <patd@symbian.org> | 
| Wed, 01 Sep 2010 12:34:56 +0100 | |
| branch | RCL_3 | 
| changeset 44 | 3e88ff8f41d5 | 
| parent 43 | c1f20ce4abcf | 
| permissions | -rw-r--r-- | 
| 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> | |
| 44 | 131 | #include "freeram.h" | 
| 0 | 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 | ||
| 44 | 353 | TInt freeRam = FreeRam(); //This will also add a delay | 
| 354 | ||
| 0 | 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; | |
| 44 | 372 | |
| 373 | test(freeRam == FreeRam()); //This will also add a delay | |
| 43 
c1f20ce4abcf
Revision: 201035
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: 
0diff
changeset | 374 | } | 
| 44 | 375 | User::__DbgSetAllocFail(ETrue,RAllocator::ENone,0); | 
| 0 | 376 | __KHEAP_RESET; | 
| 377 | ||
| 378 | 	test.Next(_L("Destroy buffer"));
 | |
| 379 | if (aPhysicalAddress) | |
| 380 | ldd.DestroyBufferPhysAddr(); | |
| 381 | else | |
| 382 | ldd.DestroyBuffer(); | |
| 383 | ||
| 44 | 384 | test(freeRam == FreeRam()); //This will also add a delay | 
| 0 | 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 |