First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\mmu\d_sharedio.cpp
15 // LDD for testing SharedIoBuffers
19 #include <kernel/kern_priv.h>
20 #include "d_sharedio.h"
26 class DSharedIoTestFactory : public DLogicalDevice
29 DSharedIoTestFactory();
30 ~DSharedIoTestFactory();
31 virtual TInt Install();
32 virtual void GetCaps(TDes8& aDes) const;
33 virtual TInt Create(DLogicalChannelBase*& aChannel);
35 DSharedIoBuffer* iGlobalBuffer;
42 class DSharedIoTest : public DLogicalChannelBase
45 virtual ~DSharedIoTest();
47 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
48 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
50 DSharedIoBuffer* iIoBuffer;
51 DSharedIoBuffer* iGlobalBuffer;
52 DSharedIoTestFactory* iFactory;
54 TPhysAddr iPhysAddress;
62 DSharedIoTestFactory::DSharedIoTestFactory()
67 DSharedIoTestFactory::~DSharedIoTestFactory()
71 TInt DSharedIoTestFactory::Create(DLogicalChannelBase*& aChannel)
73 __KTRACE_OPT(KMMU,Kern::Printf(">DSharedIoTestFactory::Create iGlobalBuffer=%x",iGlobalBuffer));
79 TUint aAttribs=EMapAttrSupRw | EMapAttrFullyBlocking;
81 TInt r=DSharedIoBuffer::New(iGlobalBuffer,KSizeGlobalBuffer,aAttribs);
85 aChannel=new DSharedIoTest;
88 ((DSharedIoTest*)aChannel)->iGlobalBuffer=iGlobalBuffer;
89 ((DSharedIoTest*)aChannel)->iFactory=this;
90 __KTRACE_OPT(KMMU,Kern::Printf("<DSharedIoTestFactory::Create iGlobalBuffer=%x",iGlobalBuffer));
94 TInt DSharedIoTestFactory::Install()
96 return SetName(&KSharedIoTestLddName);
99 void DSharedIoTestFactory::GetCaps(TDes8& /* aDes */) const
101 //aDes.FillZ(aDes.MaxLength());
104 DECLARE_STANDARD_LDD()
106 return new DSharedIoTestFactory;
113 TInt DSharedIoTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
118 DSharedIoTest::~DSharedIoTest()
123 TInt checkBuffer(TAny* buffer, TUint32 aSize, TUint32 key)
126 TUint8* m=(TUint8*)buffer;
127 for(TUint32 size=0;size<aSize;size++,key+=5,m++)
129 if(*m!=(TUint8)(key%256))
138 TInt fillBuffer(TAny* buffer, TUint32 aSize, TUint32 key)
140 TUint8* m=(TUint8*)buffer;
141 for(TUint32 size=0;size<aSize;size++,key+=5,m++)
143 *m=(TUint8)(key%256);
148 static void AppendNumToBuf(TDes8& aDes, const TDesC& aNum, TInt width, char fill)
150 TInt l = aNum.Length();
151 for (; l < width; ++l)
152 aDes.Append(TChar(fill));
156 static void DumpMemory(TUint8* aStart, TInt aSize)
162 TInt i = (TInt)aStart & 0xF; // first byte in this line to dump
163 TInt n = 16; // end byte in this line
170 val.Num((TUint32)aStart & ~0xF, EHex);
171 AppendNumToBuf(line, val, 8, '0');
177 for (j = 0; j < i; ++j)
183 if (j == 7) line.Append(space);
188 val.Num(aStart[j-i], EHex);
190 AppendNumToBuf(line, val, 2, '0');
192 if (j == 7) line.Append(space);
201 if (j == 7) line.Append(space);
207 for (j = 0; j < i; ++j)
212 char c = aStart[j-i];
213 if (c < ' ' || c > 126) c = '.';
214 line.Append(TChar(c));
217 Kern::Printf("%S", &line);
228 TBool CheckMemCleared(TLinAddr aAddress, TInt aSize)
230 TUint8* aPtr = (TUint8*)aAddress;
231 for(TInt i = 0; i<aSize; i++)
235 Kern::Printf("CheckMemCleared(0x%x, %d) failed at i = 0x%x", aAddress, aSize, i);
236 // Start on current line & ~0xF, run for 16 lines x 16 bytes
237 TUint8 *p = (TUint8*)((aAddress + i) & ~0x0F);
240 if (p < aPtr) p = aPtr;
241 if (p - aPtr > aSize - n) // if (p + n > aPtr + aSize) rearranged (to avoid overflow)
242 n = aPtr + aSize - p;
251 TInt DSharedIoTest::Request(TInt aFunction, TAny* a1, TAny* a2)
256 case RTestLdd::ECreateBuffer:
258 TUint32 size = (TUint32)a1;
265 TUint aAttribs1=EMapAttrSupRw | EMapAttrBufferedNC;
266 TUint aAttribs2=EMapAttrSupRw | EMapAttrFullyBlocking;
267 TUint aAttribs3=EMapAttrSupRw | EMapAttrCachedMax;
269 NKern::ThreadEnterCS();
270 r=DSharedIoBuffer::New(iIoBuffer,size,aAttribs1);
273 Kern::Printf("Error creating buffer r=%d\n",r);
274 NKern::ThreadLeaveCS();
278 //Check the buffer is properly initialized (the previous content
279 //deleted by inserting all 0x03s)
280 if (!CheckMemCleared(iIoBuffer->iAddress, iIoBuffer->iSize))
282 Kern::Printf("Error memory zeroing test for shared io buffers");
283 NKern::ThreadLeaveCS();
287 //just test that we can construct a second shared buffer
288 DSharedIoBuffer* ptr;
289 r=DSharedIoBuffer::New(ptr,size,aAttribs2);
292 Kern::Printf("Error creating the 2nd buffer r=%d\n",r);
295 NKern::ThreadLeaveCS();
298 delete ptr; //creation successfull, simply delete the object
300 // and the third one, this time fully cached.
301 r=DSharedIoBuffer::New(ptr,size,aAttribs3);
304 Kern::Printf("Error creating the 3rd buffer r=%d\n",r);
307 NKern::ThreadLeaveCS();
310 delete ptr; //creation successfull, simply delete the object
312 NKern::ThreadLeaveCS();
313 if(iIoBuffer->iSize!=size) // test
315 Kern::Printf("Error checking size iIoBuffer->iSize=%d size=%d\n",iIoBuffer->iSize,size);
318 memset((void*)iIoBuffer->iAddress,0,size);
322 case RTestLdd::EMapInGlobalBuffer:
328 kumemget32(&id,a1,sizeof(TUint));
330 NKern::ThreadEnterCS();
331 Kern::Containers()[EProcess]->Wait();
332 DProcess* process=Kern::ProcessFromId(id);
335 Kern::Containers()[EProcess]->Signal();
338 r=iGlobalBuffer->UserMap(process);
343 NKern::ThreadLeaveCS();
348 if(iGlobalBuffer->UserToKernel(iGlobalBuffer->iUserAddress,iGlobalBuffer->iSize)!=iGlobalBuffer->iAddress)
351 if(iGlobalBuffer->UserToKernel(iGlobalBuffer->iUserAddress,iGlobalBuffer->iSize+1)!=NULL)
354 if(iGlobalBuffer->KernelToUser(iGlobalBuffer->iAddress)!=iGlobalBuffer->iUserAddress)
357 kumemput32(a1,&iGlobalBuffer->iUserAddress,sizeof(TAny*));
358 kumemput32(a2,&iGlobalBuffer->iSize,sizeof(TInt));
363 case RTestLdd::EMapOutGlobalBuffer:
367 r=iGlobalBuffer->UserUnmap();
369 if(iGlobalBuffer->iUserProcess)
374 case RTestLdd::EDestroyGlobalBuffer:
376 NKern::ThreadEnterCS();
377 delete iGlobalBuffer;
378 iGlobalBuffer = NULL;
379 iFactory->iGlobalBuffer=NULL;
380 NKern::ThreadLeaveCS();
384 case RTestLdd::ECreateBufferPhysAddr:
387 return KErrNotSupported;
389 TUint32 size=Kern::RoundToPageSize(1);
390 NKern::ThreadEnterCS();
391 r=Epoc::AllocPhysicalRam(size,iPhysAddress);
392 Kern::Printf("phys addr = %X!\n",iPhysAddress);
395 NKern::ThreadLeaveCS();
400 //test that we can construct a fully cached sharedio
401 DSharedIoBuffer* ptr;
402 r=DSharedIoBuffer::New(ptr,iPhysAddress,size,EMapAttrSupRw|EMapAttrCachedMax);
405 Kern::Printf("Error creating the physical cached buffer r=%d\n",r);
406 Epoc::FreePhysicalRam(iPhysAddress,size);
408 NKern::ThreadLeaveCS();
411 delete ptr; //creation successfull, simply delete the object
414 r=DSharedIoBuffer::New(iIoBuffer,iPhysAddress,size,EMapAttrSupRw|EMapAttrFullyBlocking);
417 Epoc::FreePhysicalRam(iPhysAddress,size);
419 NKern::ThreadLeaveCS();
423 if(iIoBuffer->iSize!=size) // test
427 Epoc::FreePhysicalRam(iPhysAddress,size);
429 NKern::ThreadLeaveCS();
433 fillBuffer((TAny*)iIoBuffer->iAddress,size,180);
435 DPlatChunkHw* hwChunk;
436 r=DPlatChunkHw::New(hwChunk, iPhysAddress, size, EMapAttrSupRw|EMapAttrFullyBlocking);
441 Epoc::FreePhysicalRam(iPhysAddress,size);
443 NKern::ThreadLeaveCS();
447 r=checkBuffer((TAny*)hwChunk->LinearAddress(),size,180);
452 hwChunk->Close(NULL);
453 Epoc::FreePhysicalRam(iPhysAddress,size);
455 NKern::ThreadLeaveCS();
459 hwChunk->Close(NULL);
460 NKern::ThreadLeaveCS();
465 case RTestLdd::EDestroyBufferPhysAddr:
468 return KErrNotSupported;
470 TUint32 size=Kern::RoundToPageSize(1);
471 NKern::ThreadEnterCS();
474 r=Epoc::FreePhysicalRam(iPhysAddress,size);
476 NKern::ThreadLeaveCS();
482 case RTestLdd::EMapInBuffer:
484 r=iIoBuffer->UserMap(&Kern::CurrentProcess());
488 TAny** p = (TAny**)iIoBuffer->iAddress;
489 TAny* ua = (TAny*)iIoBuffer->iUserAddress;
490 TAny** end = (TAny**)((TInt)p+iIoBuffer->iSize);
494 ua = (TAny*)((TInt)ua+sizeof(TAny*));
496 if(iIoBuffer->UserToKernel(iIoBuffer->iUserAddress,iIoBuffer->iSize)!=iIoBuffer->iAddress)
499 if(iIoBuffer->UserToKernel(iIoBuffer->iUserAddress,iIoBuffer->iSize+1)!=NULL)
502 if(iIoBuffer->KernelToUser(iIoBuffer->iAddress)!=iIoBuffer->iUserAddress)
504 kumemput32(a1,&iIoBuffer->iUserAddress,sizeof(TAny*));
505 kumemput32(a2,&iIoBuffer->iSize,sizeof(TInt));
509 case RTestLdd::EMapOutBuffer:
511 r=iIoBuffer->UserUnmap();
513 if(iIoBuffer->iUserProcess)
518 case RTestLdd::EDestroyBuffer:
519 NKern::ThreadEnterCS();
522 NKern::ThreadLeaveCS();
525 case RTestLdd::ECheckBuffer:
526 if(!iIoBuffer->iAddress || !iIoBuffer->iUserAddress || !iIoBuffer->iUserProcess)
528 return checkBuffer((TAny*)iIoBuffer->iAddress,iIoBuffer->iSize,(TUint32)a1);
530 case RTestLdd::EFillBuffer:
531 if(!iIoBuffer->iAddress || !iIoBuffer->iUserAddress || !iIoBuffer->iUserProcess)
533 return fillBuffer((TAny*)iIoBuffer->iAddress,iIoBuffer->iSize,(TUint32)a1);
535 case RTestLdd::EThreadRW:
538 TPckg<TInt> a(dummy);
542 pT=&Kern::CurrentThread();
546 NKern::ThreadEnterCS();
547 DObjectCon* pC=Kern::Containers()[EThread];
549 pT=Kern::ThreadFromId((TInt)a2);
553 NKern::ThreadLeaveCS();
555 r=Kern::ThreadDesRead(pT,a1,a,0,KChunkShiftBy0);
561 r=Kern::ThreadDesWrite(pT,a1,a,0,KChunkShiftBy0,&Kern::CurrentThread());