Update contrib.
1 // Copyright (c) 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_shbuf.cpp
18 #include <kernel/kernel.h>
19 #include <kernel/cache.h>
20 #include "plat_priv.h"
21 #include <kernel/sshbuf.h>
24 #define TEST_EXP(a) CheckPoint(a, __LINE__)
25 #define TEST_KERRNONE(a) CheckPointError(a, __LINE__)
27 #ifdef TEST_CLIENT_THREAD
28 #define TEST_ENTERCS() NKern::ThreadEnterCS()
29 #define TEST_LEAVECS() NKern::ThreadLeaveCS()
31 #define TEST_ENTERCS()
32 #define TEST_LEAVECS()
33 #endif // TEST_CLIENT_THREAD
35 const TInt KMaxPhysicalMemoryBlockSize = 512 << 10; // 512KB;
37 // ----------------------------------------------------------------------------
39 class DShBufTestDrvFactory : public DLogicalDevice
42 DShBufTestDrvFactory();
43 ~DShBufTestDrvFactory();
44 virtual TInt Install();
45 virtual void GetCaps(TDes8& aDes) const;
46 virtual TInt Create(DLogicalChannelBase*& aChannel);
48 #ifndef TEST_CLIENT_THREAD
49 TDynamicDfcQue* iDfcQ;
53 // ----------------------------------------------------------------------------
55 #ifdef TEST_CLIENT_THREAD
56 class DShBufTestDrvChannel : public DLogicalChannelBase
58 class DShBufTestDrvChannel : public DLogicalChannel
62 DShBufTestDrvChannel();
63 ~DShBufTestDrvChannel();
64 // Inherited from DLogicalChannel
65 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
66 #ifdef TEST_CLIENT_THREAD
67 // Inherited from DLogicalChannelBase: process all DoControl in the user's context
68 virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
70 TInt DoControl(TInt aReqNo, TAny* a1, TAny* a2);
71 virtual void HandleMsg(TMessageBase* aMsg);
72 virtual TInt SendMsg(TMessageBase* aMsg);
75 TShPoolCreateInfo* iCreateinfo;
76 TShPoolInfo iUserpoolinfo;
79 TUint8 iDriverTxBuffer[8192];
80 TUint8 iDriverRxBuffer[8192];
81 #ifndef TEST_CLIENT_THREAD
83 TVirtualPinObject* iPin;
87 // ----------------------------------------------------------------------------
89 void CheckPoint(TInt aCondition, TInt aLine)
93 Kern::Printf("Device driver test failed (line %d)", aLine);
97 void CheckPointError(TInt aErrorCode, TInt aLine)
99 if (aErrorCode != KErrNone)
101 Kern::Printf("Device driver error %d (line %d)", aErrorCode, aLine);
116 TInt RoundUp(TInt aNum, TInt aAlignmentLog2)
118 if (aNum % (1 << aAlignmentLog2) == 0)
122 return (aNum & ~((1 << aAlignmentLog2) - 1)) + (1 << aAlignmentLog2);
126 #define SHBUF_NOT_WINS(x)
128 #define SHBUF_NOT_WINS(x) x
130 TBool IsBufferContiguous(TShBuf* SHBUF_NOT_WINS(aBuf))
133 TInt r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
139 TUint8* ptr = Kern::ShBufPtr(aBuf);
140 TUint size = Kern::ShBufSize(aBuf);
142 TBool iscontiguous = ETrue;
144 TPhysAddr startphys = Epoc::LinearToPhysical((TLinAddr) ptr);
147 for (i = 0; i < size; i += pagesize)
149 TPhysAddr current = Epoc::LinearToPhysical((TLinAddr) ptr + i);
150 if (current != startphys + i)
152 Kern::Printf("Page %d: 0x%08x (started@0x%08x expected 0x%08x)", i, current, startphys, startphys + i);
153 iscontiguous = EFalse;
162 DECLARE_STANDARD_LDD()
164 return new DShBufTestDrvFactory;
167 DShBufTestDrvFactory::DShBufTestDrvFactory()
169 iParseMask=0; //no units, no info, no pdd
171 iVersion=TVersion(1,0,KE32BuildVersionNumber);
174 DShBufTestDrvFactory::~DShBufTestDrvFactory()
176 #ifndef TEST_CLIENT_THREAD
182 #ifndef TEST_CLIENT_THREAD
183 const TInt KShBufTestThreadPriority = 1;
184 _LIT(KShBufTestThread,"ShBufTestThread");
187 TInt DShBufTestDrvFactory::Install()
189 #ifndef TEST_CLIENT_THREAD
190 TInt r = Kern::DynamicDfcQCreate(iDfcQ, KShBufTestThreadPriority, KShBufTestThread);
194 return(SetName(&KTestShBufOwn));
196 return(SetName(&KTestShBufClient));
201 void DShBufTestDrvFactory::GetCaps(TDes8& /*aDes*/) const
203 // Get capabilities - overriding pure virtual
206 TInt DShBufTestDrvFactory::Create(DLogicalChannelBase*& aChannel)
208 aChannel=new DShBufTestDrvChannel;
209 return aChannel?KErrNone:KErrNoMemory;
212 // ----------------------------------------------------------------------------
214 DShBufTestDrvChannel::DShBufTestDrvChannel()
216 #ifndef TEST_CLIENT_THREAD
217 iClient=&Kern::CurrentThread();
221 TPtr8 bufp(iDriverRxBuffer,0,sizeof(iDriverRxBuffer));
223 for(TInt pos = 0; pos < bufp.Length(); pos++)
225 bufp[pos] = (TUint8)(pos & 31);
229 DShBufTestDrvChannel::~DShBufTestDrvChannel()
231 NKern::ThreadEnterCS();
232 #ifndef TEST_CLIENT_THREAD
233 Kern::SafeClose((DObject*&)iClient, NULL);
236 Kern::DestroyVirtualPinObject(iPin);
240 NKern::ThreadLeaveCS();
243 TInt DShBufTestDrvChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
245 #ifndef TEST_CLIENT_THREAD
246 SetDfcQ(((DShBufTestDrvFactory*)iDevice)->iDfcQ);
253 #ifndef TEST_CLIENT_THREAD
254 void DShBufTestDrvChannel::HandleMsg(TMessageBase* aMsg)
257 TThreadMessage& m=*(TThreadMessage*)aMsg;
259 if (id==(TInt)ECloseMsg)
261 m.Complete(KErrNone,EFalse);
266 r=DoControl(id,m.Ptr0(),m.Ptr1());
271 TInt DShBufTestDrvChannel::SendMsg(TMessageBase* aMsg)
273 // We can only handle one request at a time.
274 TEST_EXP(!iCreateinfo && !iPin);
275 if(iCreateinfo || iPin)
280 TThreadMessage& m = *(TThreadMessage*)aMsg;
285 // Make a copy of the parameters in the asynchronous read case so that we don't
286 // risk a page fault by reading user-mode memory from the msg DFC.
288 // Manage writes using a TClientBufferRequest.
292 case RShBufTestChannel::ETestOpenUserPool:
293 kumemget(&iUserpoolinfo, a2, sizeof(iUserpoolinfo));
295 case RShBufTestChannel::ETestCreatePoolContiguousPool:
296 NKern::ThreadEnterCS();
297 iCreateinfo = new TShPoolCreateInfo;
298 NKern::ThreadLeaveCS();
299 TEST_EXP(iCreateinfo != NULL);
306 kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
308 case RShBufTestChannel::EFromTPtr8ProcessAndRelease:
310 TPtr8 dest(iDriverTxBuffer, sizeof(iDriverTxBuffer));
311 Kern::ThreadDesRead(iClient, a1, dest, 0, KChunkShiftBy0);
316 case RShBufTestChannel::ETestOpenKernelPool:
317 NKern::ThreadEnterCS();
318 iCreateinfo = new TShPoolCreateInfo;
319 NKern::ThreadLeaveCS();
320 TEST_EXP(iCreateinfo != NULL);
327 kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
330 case RShBufTestChannel::ETestAllocateMax:
331 case RShBufTestChannel::ETestAllocateKernelBuffer:
333 NKern::ThreadEnterCS();
334 r = Kern::CreateAndPinVirtualMemory(iPin, (TLinAddr)a2, sizeof(TInt));
335 NKern::ThreadLeaveCS();
340 case RShBufTestChannel::EFromTPtr8ProcessAndReturn:
342 TPtr8 tempPtr(0, 0, 0);
343 kumemget(&tempPtr, a1, sizeof(tempPtr));
345 TUint size = tempPtr.Size();
347 if(size <= sizeof(iDriverRxBuffer))
349 NKern::ThreadEnterCS();
350 r = Kern::CreateAndPinVirtualMemory(iPin, (TLinAddr)tempPtr.Ptr(), size);
351 NKern::ThreadLeaveCS();
363 r = DLogicalChannel::SendMsg(aMsg);
370 #ifdef TEST_CLIENT_THREAD
371 TInt DShBufTestDrvChannel::Request(TInt aReqNo, TAny* a1, TAny* a2)
373 TInt DShBufTestDrvChannel::DoControl(TInt aReqNo, TAny* a1, TAny* a2)
376 TInt r=KErrNotSupported;
380 // ----------------------------------------------------------------------------
381 // TInt RShBufTestChannel::OpenUserPool(TInt aHandle, TShPoolInfo& aPoolInfo)
382 case RShBufTestChannel::ETestOpenUserPool:
386 #ifdef TEST_CLIENT_THREAD
387 kumemget(&iUserpoolinfo, a2, sizeof(iUserpoolinfo));
388 tP=&Kern::CurrentThread();
393 TEST_EXP(!iPools[0]);
396 r = KErrAlreadyExists;
400 NKern::ThreadEnterCS();
401 r = Kern::ShPoolOpen(iPools[0], tP, (TInt) a1, ETrue, KDefaultPoolHandleFlags);
402 NKern::ThreadLeaveCS();
411 n = reinterpret_cast<DShPool*>(iPools[0])->AccessCount();
419 TShPoolInfo poolinfo;
420 Kern::ShPoolGetInfo(iPools[0], poolinfo);
421 if (!((poolinfo.iBufSize == iUserpoolinfo.iBufSize) &&
422 ((TUint)Kern::ShPoolBufSize(iPools[0]) == iUserpoolinfo.iBufSize) &&
423 (poolinfo.iInitialBufs == iUserpoolinfo.iInitialBufs) &&
424 (poolinfo.iMaxBufs == iUserpoolinfo.iMaxBufs) &&
425 (poolinfo.iGrowTriggerRatio == iUserpoolinfo.iGrowTriggerRatio) &&
426 (poolinfo.iGrowByRatio == iUserpoolinfo.iGrowByRatio) &&
427 (poolinfo.iShrinkHysteresisRatio == iUserpoolinfo.iShrinkHysteresisRatio) &&
428 (poolinfo.iAlignment == iUserpoolinfo.iAlignment) &&
429 ((poolinfo.iFlags & EShPoolNonPageAlignedBuffer) == (iUserpoolinfo.iFlags & EShPoolNonPageAlignedBuffer)) &&
430 ((poolinfo.iFlags & EShPoolPageAlignedBuffer) == (iUserpoolinfo.iFlags & EShPoolPageAlignedBuffer))))
433 Kern::Printf("poolinfo.iBufSize == %d (expected %d)", poolinfo.iBufSize, iUserpoolinfo.iBufSize);
434 Kern::Printf("BufSize() == %d", Kern::ShPoolBufSize(iPools[0]));
435 Kern::Printf("poolinfo.iInitialBufs == %d (expected %d)", poolinfo.iInitialBufs, iUserpoolinfo.iInitialBufs);
436 Kern::Printf("poolinfo.iMaxBufs == %d (expected %d)", poolinfo.iMaxBufs, iUserpoolinfo.iMaxBufs);
437 Kern::Printf("poolinfo.iGrowTriggerRatio == %d (expected %d)", poolinfo.iGrowTriggerRatio, iUserpoolinfo.iGrowTriggerRatio);
438 Kern::Printf("poolinfo.iGrowByRatio == %d (expected %d)", poolinfo.iGrowByRatio, iUserpoolinfo.iGrowByRatio);
439 Kern::Printf("poolinfo.iShrinkHysteresisRatio == %d (expected %d)", poolinfo.iShrinkHysteresisRatio, iUserpoolinfo.iShrinkHysteresisRatio);
440 Kern::Printf("poolinfo.iAlignment == %d (expected %d)", poolinfo.iAlignment, iUserpoolinfo.iAlignment);
441 Kern::Printf("poolinfo.iFlags == 0x%08x (user=0x%08x)", poolinfo.iFlags, iUserpoolinfo.iFlags);
447 if(poolinfo.iFlags & EShPoolPageAlignedBuffer)
449 NKern::ThreadEnterCS();
450 r = Kern::ShPoolSetBufferWindow(iPools[0],-1);
451 NKern::ThreadLeaveCS();
460 // ----------------------------------------------------------------------------
461 // TInt RShBufTestChannel::OpenKernelPool(TShPoolCreateInfo& aInfo, TInt& aHandle)
462 case RShBufTestChannel::ETestOpenKernelPool:
465 #ifdef TEST_CLIENT_THREAD
466 // We can only handle one request at a time.
467 TEST_EXP(!iCreateinfo);
474 NKern::ThreadEnterCS();
475 iCreateinfo = new TShPoolCreateInfo;
476 NKern::ThreadLeaveCS();
477 TEST_EXP(iCreateinfo != NULL);
484 kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
487 TEST_EXP(!iPools[1]);
490 r = KErrAlreadyExists;
494 NKern::ThreadEnterCS();
495 r = Kern::ShPoolCreate(iPools[1], *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
498 NKern::ThreadLeaveCS();
503 #ifndef TEST_CLIENT_THREAD
504 NKern::ThreadEnterCS();
505 Kern::DestroyVirtualPinObject(iPin);
506 NKern::ThreadLeaveCS();
512 n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
516 #ifndef TEST_CLIENT_THREAD
517 NKern::ThreadEnterCS();
518 Kern::DestroyVirtualPinObject(iPin);
519 NKern::ThreadLeaveCS();
526 TShPoolInfo poolinfo;
527 Kern::ShPoolGetInfo(iPools[1], poolinfo);
528 if(poolinfo.iFlags & EShPoolPageAlignedBuffer)
530 NKern::ThreadEnterCS();
531 r = Kern::ShPoolSetBufferWindow(iPools[1],-1);
532 NKern::ThreadLeaveCS();
536 #ifndef TEST_CLIENT_THREAD
537 NKern::ThreadEnterCS();
538 Kern::DestroyVirtualPinObject(iPin);
539 NKern::ThreadLeaveCS();
546 #ifdef TEST_CLIENT_THREAD
547 // Now create a handle for the client
548 NKern::ThreadEnterCS();
549 handle = Kern::ShPoolMakeHandleAndOpen(iPools[1], NULL, KDefaultPoolHandleFlags);
550 NKern::ThreadLeaveCS();
552 handle = Kern::ShPoolMakeHandleAndOpen(iPools[1], iClient, KDefaultPoolHandleFlags);
554 TEST_EXP(handle > 0);
557 #ifndef TEST_CLIENT_THREAD
558 NKern::ThreadEnterCS();
559 Kern::DestroyVirtualPinObject(iPin);
560 NKern::ThreadLeaveCS();
567 n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
572 #ifndef TEST_CLIENT_THREAD
573 NKern::ThreadEnterCS();
574 Kern::DestroyVirtualPinObject(iPin);
575 NKern::ThreadLeaveCS();
582 #ifdef TEST_CLIENT_THREAD
583 kumemput(a2, &handle, sizeof(handle));
585 Kern::ThreadRawWrite(iClient, a2, &handle, sizeof(handle), iClient);
587 NKern::ThreadEnterCS();
588 Kern::DestroyVirtualPinObject(iPin);
589 NKern::ThreadLeaveCS();
593 // ----------------------------------------------------------------------------
594 // TInt RShBufTestChannel::CloseUserPool()
595 case RShBufTestChannel::ETestCloseUserPool:
598 n = reinterpret_cast<DShPool*>(iPools[0])->AccessCount();
607 r = Kern::ShPoolClose(iPools[0]);
618 // ----------------------------------------------------------------------------
619 // TInt RShBufTestChannel::CloseKernelPool()
620 case RShBufTestChannel::ETestCloseKernelPool:
624 n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
633 r = Kern::ShPoolClose(iPools[1]);
644 // ----------------------------------------------------------------------------
645 // TInt RShBufTestChannel::ManipulateUserBuffer(TInt aHandle)
646 case RShBufTestChannel::ETestManipulateUserBuffer:
651 #ifdef TEST_CLIENT_THREAD
652 tP=&Kern::CurrentThread();
656 NKern::ThreadEnterCS();
658 r = Kern::ShBufOpen(ubuf, tP, (TInt) a1);
663 NKern::ThreadLeaveCS();
668 n = reinterpret_cast<DShBuf*>(ubuf)->AccessCount();
674 Kern::ShBufClose(ubuf);
675 NKern::ThreadLeaveCS();
681 TInt blocks = Kern::ShBufSize(ubuf) / KTestData1().Length();
683 for (i = 0; i < blocks; i++)
686 TPtr8 ptr(Kern::ShBufPtr(ubuf) + (i * KTestData1().Length()), KTestData1().Length(), KTestData1().Length());
687 r = KTestData1().Compare(ptr);
696 TEST_EXP(r == KErrNone);
701 Kern::ShBufClose(ubuf);
702 NKern::ThreadLeaveCS();
705 // ----------------------------------------------------------------------------
706 // TInt RShBufTestChannel::AllocateKernelBuffer(TInt aPoolIndex, TInt& aHandle)
707 case RShBufTestChannel::ETestAllocateKernelBuffer:
709 TInt poolindex = (TInt) a1;
710 if ((poolindex != 0) && (poolindex != 1))
716 NKern::ThreadEnterCS();
718 // Allocate kernel-side buffer
720 r = Kern::ShPoolAlloc(iPools[poolindex], kbuf, 0);
725 NKern::ThreadLeaveCS();
729 // Fill it with test data
731 for (i = 0; i < Kern::ShPoolBufSize(iPools[poolindex]) / KTestData2().Length(); i++)
733 TPtr8 ptr(Kern::ShBufPtr(kbuf) + (i * KTestData2().Length()), KTestData2().Length(), KTestData2().Length());
734 ptr.Copy(KTestData2());
737 // Now create a handle for the client
739 #ifdef TEST_CLIENT_THREAD
740 handle = Kern::ShBufMakeHandleAndOpen(kbuf, NULL);
742 handle = Kern::ShBufMakeHandleAndOpen(kbuf, iClient);
745 TEST_EXP(handle > 0);
749 Kern::ShBufClose(kbuf);
750 NKern::ThreadLeaveCS();
755 n = reinterpret_cast<DShBuf*>(kbuf)->AccessCount();
761 Kern::ShBufClose(kbuf);
762 NKern::ThreadLeaveCS();
766 #ifdef TEST_CLIENT_THREAD
767 NKern::ThreadLeaveCS();
769 kumemput(a2, &handle, sizeof(handle));
771 NKern::ThreadEnterCS();
772 Kern::ShBufClose(kbuf);
773 NKern::ThreadLeaveCS();
775 NKern::ThreadLeaveCS();
777 Kern::ThreadRawWrite(iClient, a2, &handle, sizeof(handle), iClient);
779 NKern::ThreadEnterCS();
780 Kern::DestroyVirtualPinObject(iPin);
782 // Close buffer - but it is still referenced by client handle
783 Kern::ShBufClose(kbuf);
784 NKern::ThreadLeaveCS();
788 // ----------------------------------------------------------------------------
789 // TInt ContiguousPoolKernel(TShPoolCreateInfo& aInfo)
790 case RShBufTestChannel::ETestCreatePoolContiguousPool:
792 #ifdef TEST_CLIENT_THREAD
793 NKern::ThreadEnterCS();
794 iCreateinfo = new TShPoolCreateInfo;
795 NKern::ThreadLeaveCS();
796 TEST_EXP(iCreateinfo != NULL);
803 kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
809 NKern::ThreadEnterCS();
811 r = Kern::ShPoolCreate(otherpool, *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
814 r = Kern::ShPoolSetBufferWindow(otherpool,-1);
817 iCreateinfo->SetContiguous();
820 r = Kern::ShPoolCreate(mainpool, *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
821 NKern::ThreadEnterCS();
824 NKern::ThreadLeaveCS();
827 r = Kern::ShPoolSetBufferWindow(mainpool,-1);
831 TShBuf* mainbuf[KTestPoolSizeInBufs];
832 TShBuf* otherbuf[KTestPoolSizeInBufs];
833 for (i = 0; i < KTestPoolSizeInBufs; i++)
835 r = Kern::ShPoolAlloc(mainpool, mainbuf[i], 0);
838 Kern::Printf("i=%d r=%d\n", i, r);
841 r = Kern::ShPoolAlloc(otherpool, otherbuf[i], 0);
844 Kern::Printf("i=%d r=%d\n", i, r);
848 iscontiguous = IsBufferContiguous(mainbuf[i]);
851 Kern::Printf("i=%d\n", i, r);
852 TEST_EXP(iscontiguous);
857 // Free every other buffer
858 for (i = 0; i < KTestPoolSizeInBufs; i += 2)
860 Kern::ShBufClose(mainbuf[i]);
861 Kern::ShBufClose(otherbuf[i]);
864 // Re-allocate buffers
865 for (i = 0; i < KTestPoolSizeInBufs; i += 2)
867 r = Kern::ShPoolAlloc(otherpool, otherbuf[i], 0);
870 Kern::Printf("i=%d r=%d\n", i, r);
873 r = Kern::ShPoolAlloc(mainpool, mainbuf[i], 0);
876 Kern::Printf("i=%d r=%d\n", i, r);
880 iscontiguous = IsBufferContiguous(mainbuf[i]);
883 Kern::Printf("i=%d\n", i, r);
884 TEST_EXP(iscontiguous);
888 for (i = 0; i < KTestPoolSizeInBufs; i++)
890 Kern::ShBufClose(mainbuf[i]);
891 Kern::ShBufClose(otherbuf[i]);
894 Kern::ShPoolClose(mainpool);
895 Kern::ShPoolClose(otherpool);
896 NKern::ThreadLeaveCS();
899 // ----------------------------------------------------------------------------
900 // TInt CreatePoolPhysAddrCont(TInt aBufSize)
901 // TInt CreatePoolPhysAddrNonCont(TInt aBufSize)
902 case RShBufTestChannel::ETestCreatePoolPhysAddrCont:
903 case RShBufTestChannel::ETestCreatePoolPhysAddrNonCont:
907 TInt bufsize = (TInt) a1;
908 TInt minimumAlignmentLog2 = __e32_find_ms1_32(Cache::DmaBufferAlignment());
909 if (minimumAlignmentLog2 < 5)
910 minimumAlignmentLog2 = 5;
912 r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
919 if (bufsize > KMaxPhysicalMemoryBlockSize)
924 TInt physicalblocksize = RoundUp(128 * RoundUp(bufsize, Log2(minimumAlignmentLog2)), Log2(pagesize) + 1);
925 if (physicalblocksize > KMaxPhysicalMemoryBlockSize)
927 physicalblocksize = KMaxPhysicalMemoryBlockSize;
929 if (physicalblocksize < pagesize * 4)
931 physicalblocksize = pagesize * 4;
934 NKern::ThreadEnterCS();
936 // Allocate an array of physical addresses
937 TPhysAddr* addrtable = NULL;
939 // Allocate physical memory
941 if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
943 r = Epoc::AllocPhysicalRam(physicalblocksize, physaddr, 0);
947 addrtable = (TPhysAddr*) Kern::Alloc((physicalblocksize / pagesize) * sizeof(TPhysAddr));
948 TEST_EXP(addrtable != NULL);
949 if (addrtable == NULL)
952 NKern::ThreadLeaveCS();
956 TPhysAddr* addrtabletmp;
957 addrtabletmp = (TPhysAddr*) Kern::Alloc((physicalblocksize / pagesize / 2) * sizeof(TPhysAddr));
958 TEST_EXP(addrtabletmp != NULL);
959 if (addrtabletmp == NULL)
965 // Allocate discontiguous memory
966 r = Epoc::AllocPhysicalRam(1, addrtable);
970 r = Epoc::AllocPhysicalRam(1, addrtabletmp); // 1 page gap
974 r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtable + 1);
978 r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtabletmp + 1); // big gap
982 r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2, addrtable + physicalblocksize / pagesize / 2);
984 r = Epoc::FreePhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtabletmp + 1);
988 r = Epoc::FreePhysicalRam(1, addrtabletmp);
992 Kern::Free(addrtabletmp);
998 Kern::Free(addrtable);
999 NKern::ThreadLeaveCS();
1004 TInt poolsizeinbufs;
1005 poolsizeinbufs = physicalblocksize / RoundUp(bufsize, minimumAlignmentLog2);
1007 TShPool* pool = NULL;
1008 if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
1010 TShPoolCreateInfo inf(TShPoolCreateInfo::EDevice, bufsize,
1011 poolsizeinbufs, 0, physicalblocksize / pagesize, physaddr);
1012 r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
1016 TShPoolCreateInfo inf(TShPoolCreateInfo::EDevice, bufsize,
1017 poolsizeinbufs, 0, physicalblocksize / pagesize, addrtable);
1018 r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
1023 // Do some buffer allocation with the pool
1024 TInt freecount1 = Kern::ShPoolFreeCount(pool);
1025 RPointerArray<TShBuf> bufarray;
1030 r = Kern::ShPoolAlloc(pool, buf, 0);
1033 TPtr8 ptr(Kern::ShBufPtr(buf), Kern::ShBufSize(buf), Kern::ShBufSize(buf));
1035 bufarray.Append(buf);
1039 while (r == KErrNone);
1040 TInt freecount2 = Kern::ShPoolFreeCount(pool);
1042 if (r != KErrNoMemory)
1046 while (bufarray.Count())
1050 Kern::ShBufClose(bufarray[0]);
1054 TInt freecount3 = Kern::ShPoolFreeCount(pool);
1057 r = Kern::ShPoolClose(pool);
1065 if ((freecount1 != freecount3) || (freecount1 != allocated) || (freecount1 != poolsizeinbufs) || (freecount2))
1068 Kern::Printf("fc1=%d fc2=%d fc3=%d alloc=%d", freecount1, freecount2, freecount3, allocated);
1074 if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
1076 r2 = Epoc::FreePhysicalRam(physaddr, physicalblocksize);
1080 r2 = Epoc::FreePhysicalRam(physicalblocksize / pagesize, addrtable);
1081 Kern::Free(addrtable);
1086 r = r2; // if an error occurred whilst freeing physical memory, report it
1088 NKern::ThreadLeaveCS();
1092 // ----------------------------------------------------------------------------
1093 // TInt AllocateMax(TInt aPoolIndex, TInt& aAllocated)
1094 case RShBufTestChannel::ETestAllocateMax:
1097 TInt poolindex = (TInt) a1;
1098 if ((poolindex != 0) && (poolindex != 1))
1103 TShPoolInfo poolinfo;
1104 Kern::ShPoolGetInfo(iPools[poolindex], poolinfo);
1106 NKern::ThreadEnterCS();
1108 RPointerArray<TShBuf> bufarray;
1112 r2 = Kern::ShPoolAlloc(iPools[poolindex], buf, 0);
1113 if(r2==KErrNoMemory && (TUint)bufarray.Count()<poolinfo.iMaxBufs)
1116 r2 = Kern::ShPoolAlloc(iPools[poolindex], buf, 0);
1120 r2 = bufarray.Append(buf);
1124 Kern::ShBufClose(buf);
1129 while (r2 == KErrNone);
1131 // close all buffers...
1132 TInt n = bufarray.Count();
1134 Kern::ShBufClose(bufarray[--n]);
1136 if (r2 != KErrNoMemory)
1144 while (n<bufarray.Count())
1146 r2 = Kern::ShPoolAlloc(iPools[poolindex], bufarray[n], 0);
1147 if(r2==KErrNoMemory)
1150 r2 = Kern::ShPoolAlloc(iPools[poolindex], bufarray[n], 0);
1154 Kern::Printf("Line %d: n=%d r2=%d", __LINE__, n, r2);
1163 r2 = Kern::ShPoolAlloc(iPools[poolindex], extrabuf, 0);
1165 TEST_EXP(r2 == KErrNoMemory);
1169 Kern::ShBufClose(bufarray[--n]);
1172 TInt allocated = bufarray.Count();
1175 if (r2 == KErrNoMemory)
1184 #ifdef TEST_CLIENT_THREAD
1185 NKern::ThreadLeaveCS();
1186 kumemput(a2, &allocated, sizeof(allocated));
1188 NKern::ThreadLeaveCS();
1190 Kern::ThreadRawWrite(iClient, a2, &allocated, sizeof(allocated), iClient);
1192 NKern::ThreadEnterCS();
1193 Kern::DestroyVirtualPinObject(iPin);
1194 NKern::ThreadLeaveCS();
1199 // ----------------------------------------------------------------------------
1200 // TInt BufferAlignmentKernel(TInt aBufSize)
1201 case RShBufTestChannel::ETestBufferAlignmentKernel:
1203 TInt bufsize = (TInt) a1;
1204 TInt alignment = (TInt) a2;
1207 r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
1214 NKern::ThreadEnterCS();
1216 const TInt KNumBuffers = 20;
1219 TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, bufsize, KNumBuffers, alignment); // TODO: Change minbufs back to 8 when the pool growing code works
1221 r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
1225 NKern::ThreadLeaveCS();
1230 TShBuf* buf[KNumBuffers];
1231 memclr(buf,sizeof(buf));
1232 for (j = 0; j < KNumBuffers; j++)
1234 r = Kern::ShPoolAlloc(pool, buf[j], 0);
1238 Kern::Printf("i=%d j=%d", alignment, j);
1244 if (alignment < KTestMinimumAlignmentLog2)
1246 alignment = KTestMinimumAlignmentLog2;
1248 for (j = 0; j < KNumBuffers; j++)
1250 if (((TUint32) Kern::ShBufPtr(buf[j]) & ((1 << alignment) - 1)))
1252 Kern::Printf("Pool%d buf[%d]->Base() == 0x%08x", alignment, j, Kern::ShBufPtr(buf[j]));
1258 for (j = 0; j < KNumBuffers; j++)
1262 Kern::ShBufClose(buf[j]);
1266 r2 = Kern::ShPoolClose(pool);
1280 NKern::ThreadLeaveCS();
1284 // Page aligned buffers
1285 TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, bufsize, KNumBuffers); // TODO: Change minbufs back to 8 when the pool growing code works
1287 r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
1291 NKern::ThreadLeaveCS();
1295 r = Kern::ShPoolSetBufferWindow(pool,-1);
1299 Kern::ShPoolClose(pool);
1300 NKern::ThreadLeaveCS();
1305 TShBuf* buf[KNumBuffers];
1306 memclr(buf,sizeof(buf));
1307 for (j = 0; j < KNumBuffers; j++)
1309 r = Kern::ShPoolAlloc(pool, buf[j], 0);
1313 Kern::Printf("j=%d", j);
1319 for (j = 0; j < KNumBuffers; j++)
1321 if ((TUint32) Kern::ShBufPtr(buf[j]) & (pagesize - 1))
1323 Kern::Printf("buf[%d]->Base() == 0x%08x", j, Kern::ShBufPtr(buf[j]));
1329 for (j = 0; j < KNumBuffers; j++)
1333 Kern::ShBufClose(buf[j]);
1337 r2 = Kern::ShPoolClose(pool);
1349 NKern::ThreadLeaveCS();
1352 // ----------------------------------------------------------------------------
1353 // TInt NegativeTestsKernel()
1354 case RShBufTestChannel::ETestNegativeTestsKernel:
1357 r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
1364 #define TEST_POOLCREATE_FAIL(i, p, e, r) \
1368 r2 = Kern::ShPoolCreate(p, i, ETrue, KDefaultPoolHandleFlags); \
1372 Kern::Printf("Device drive (line %d) r=%d", __LINE__, r2); \
1380 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1381 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 100, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1382 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 100); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1383 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, 10); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1384 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1385 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1386 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 65537, 65536); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1387 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, 1 + (1 << (32 - Log2(pagesize)))); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1389 { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 128 * pagesize, (Kern::FreeRamInBytes() / (128 * pagesize)) + 1); TEST_POOLCREATE_FAIL(inf, pool, KErrNoMemory, r); }
1391 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1392 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 100, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1393 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 100, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1394 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, 10, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1395 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, KMaxTUint, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1396 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, KMaxTUint, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1397 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 65537, 65536, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1398 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1399 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, 33); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1400 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 300, 24); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1401 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 65537, 16); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1402 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, Log2(pagesize) + 1); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1403 { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 128, 10, 0); inf.SetGuardPages(); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
1406 // ----------------------------------------------------------------------------
1408 // ----------------------------------------------------------------------------
1409 // TInt RShBufTestChannel::PinBuffer(TInt aPoolHandle, TInt aBufferHandle)
1411 case RShBufTestChannel::ETestPinBuffer:
1415 r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
1421 TShPool* upool = NULL;
1422 TShBuf* ubufu = NULL; // User buffer unmapped
1423 TShBuf* ubufm = NULL; // User buffer mapped
1425 #ifdef TEST_CLIENT_THREAD
1426 tP=&Kern::CurrentThread();
1431 // Create pin object
1432 TPhysicalPinObject* pinobj;
1434 r = Kern::CreatePhysicalPinObject(pinobj);
1444 r = Kern::ShPoolOpen(upool, tP, (TInt) a1, ETrue, KDefaultPoolHandleFlags);
1450 rignore = Kern::DestroyPhysicalPinObject(pinobj);
1452 TEST_KERRNONE(rignore);
1455 TShPoolInfo poolinfo;
1456 Kern::ShPoolGetInfo(upool, poolinfo);
1458 // Open user buffer but do not map it
1460 r = Kern::ShBufOpen(ubufu, tP, (TInt) a2);
1466 rignore = Kern::DestroyPhysicalPinObject(pinobj);
1468 TEST_KERRNONE(rignore);
1471 rignore = Kern::ShPoolClose(upool);
1473 TEST_KERRNONE(rignore);
1478 // Allocate an array of physical addresses
1479 TPhysAddr* addrtable;
1480 TUint size = Kern::ShBufSize(ubufu);
1482 addrtable = (TPhysAddr*) Kern::Alloc((RoundUp(size, Log2(pagesize)) / pagesize) * sizeof(TPhysAddr));
1484 TEST_EXP(addrtable != NULL);
1488 rignore = Kern::DestroyPhysicalPinObject(pinobj);
1490 TEST_KERRNONE(rignore);
1492 rignore = Kern::ShBufClose(ubufu);
1495 TEST_KERRNONE(rignore);
1497 rignore = Kern::ShPoolClose(upool);
1499 TEST_KERRNONE(rignore);
1509 NKern::ThreadEnterCS();
1510 r = Kern::ShBufPin(ubufu, pinobj, ETrue, addr, addrtable, mapattr, color);
1511 NKern::ThreadLeaveCS();
1513 if (addr != addrtable[0])
1515 TEST_EXP(addr == KPhysAddrInvalid);
1516 if (poolinfo.iFlags & EShPoolContiguous)
1518 TEST_EXP(EFalse); // Shouldn't happen with contiguous pools
1519 Kern::Printf("addr=0x%08x addrtable[0]=0x%08x", addr, addrtable[0]);
1524 if (addr != KPhysAddrInvalid)
1526 TEST_EXP(EFalse); // if buffer is not contiguous addr must be KPhysAddrInvalid
1527 Kern::Printf("addr=0x%08x addrtable[0]=0x%08x", addr, addrtable[0]);
1532 // Leave later if this fails
1534 // Destroy pin object
1536 TInt r2 = Kern::DestroyPhysicalPinObject(pinobj);
1540 // Close unmapped buffer
1542 rignore = Kern::ShBufClose(ubufu);
1545 TEST_KERRNONE(rignore);
1547 // Leave test now if previous call to Kern::ShBufPin failed
1551 Kern::Free(addrtable);
1552 rignore = Kern::ShPoolClose(upool);
1555 TEST_KERRNONE(rignore);
1560 // Open window if pool is buffer-aligned
1561 if (poolinfo.iFlags & EShPoolPageAlignedBuffer)
1563 NKern::ThreadEnterCS();
1564 r = Kern::ShPoolSetBufferWindow(upool, -1);
1565 NKern::ThreadLeaveCS();
1570 Kern::Free(addrtable);
1571 rignore = Kern::ShPoolClose(upool);
1574 TEST_KERRNONE(rignore);
1580 // Open user buffer and map it this time
1582 r = Kern::ShBufOpen(ubufm, tP, (TInt) a2);
1588 Kern::Free(addrtable);
1589 rignore = Kern::ShPoolClose(upool);
1592 TEST_KERRNONE(rignore);
1597 // Ensure that physical addresses match
1598 TUint8* ptr = Kern::ShBufPtr(ubufm);
1599 TEST_EXP(ptr != NULL);
1602 for (i = 0; i < RoundUp(size, Log2(pagesize)) / pagesize; i++)
1604 TPhysAddr current = Epoc::LinearToPhysical((TLinAddr) ptr + i * pagesize);
1605 if (current != addrtable[i])
1607 Kern::Printf("Page %d: Current=0x%08x addrtable=0x%08x (linaddr=0x%08x)", i, current, addrtable[i], ptr + i * pagesize);
1618 // Close mapped buffer
1620 rignore = Kern::ShBufClose(ubufm);
1623 TEST_KERRNONE(rignore);
1627 rignore = Kern::ShPoolClose(upool);
1630 TEST_KERRNONE(rignore);
1632 // Free address table
1634 Kern::Free(addrtable);
1644 // ----------------------------------------------------------------------------
1645 case RShBufTestChannel::EFromRShBufProcessAndReturn:
1647 // inline TInt FromRShBufProcessAndReturn(TInt aHandle);
1648 TInt bufsize = (TInt) a1;
1651 // Allocate kernel-side buffer
1653 r = Kern::ShPoolAlloc(iPools[0], kbuf, 0);
1661 TUint8* ptr = Kern::ShBufPtr(kbuf);
1662 TInt* lengthPtr = (TInt*)ptr;
1663 *lengthPtr = bufsize - 2;
1665 #if 0 // do not cache
1666 for(TInt pos = 4; pos < bufsize; pos++)
1668 ptr[pos] = (TUint8)(pos & 31);
1672 // Now create a handle for the client
1674 #ifdef TEST_CLIENT_THREAD
1675 handle = Kern::ShBufMakeHandleAndOpen(kbuf, NULL);
1677 handle = Kern::ShBufMakeHandleAndOpen(kbuf, iClient);
1683 Kern::ShBufClose(kbuf);
1688 // Close buffer - but it is still referenced by client handle
1689 Kern::ShBufClose(kbuf);
1695 case RShBufTestChannel::EFromRShBufProcessAndRelease:
1697 // inline TInt FromRShBufProcessAndRelease(TInt aHandle);
1698 TShBuf* ubuf = NULL;
1701 #ifdef TEST_CLIENT_THREAD
1702 tP=&Kern::CurrentThread();
1708 r = Kern::ShBufOpen(ubuf, tP, (TInt) a1);
1709 // close handle on behalf of user side application
1710 Kern::CloseHandle(tP, (TInt) a1);
1715 Kern::Printf("Buf not found");
1720 TUint8* dataPtr = Kern::ShBufPtr(ubuf);
1722 TInt* lengthPtr = (TInt*)(&dataPtr[0]);
1724 for(TInt pos = 4; pos < *lengthPtr; pos++)
1726 if (dataPtr[pos] != (TUint8)(pos & 31))
1729 Kern::Printf("Buf corrupt");
1736 Kern::ShBufClose(ubuf);
1742 case RShBufTestChannel::EFromTPtr8ProcessAndReturn:
1744 TInt bufsize = (TInt) a2;
1745 TPtr8 rxBuf(iDriverRxBuffer,sizeof(iDriverRxBuffer),sizeof(iDriverRxBuffer));
1748 for(TInt pos = 0; pos < bufsize; pos++)
1750 rxBuf[pos] = (TUint8)(pos & 31);
1753 rxBuf.SetLength(bufsize-2);
1755 #ifdef TEST_CLIENT_THREAD
1756 Kern::KUDesPut(*(TDes8*)a1, rxBuf); // put content from test app
1759 r = Kern::ThreadDesWrite(iClient, a1, rxBuf, 0, iClient);
1761 NKern::ThreadEnterCS();
1762 Kern::DestroyVirtualPinObject(iPin);
1763 NKern::ThreadLeaveCS();
1767 case RShBufTestChannel::EFromTPtr8ProcessAndRelease:
1769 // inline TInt FromTPtr8ProcessAndRelease(TDes8& aBuf);
1770 #if defined _DEBUG || defined TEST_CLIENT_THREAD
1771 TPtr8 bufp(iDriverTxBuffer, sizeof(iDriverTxBuffer), sizeof(iDriverTxBuffer));
1773 #ifdef TEST_CLIENT_THREAD
1774 Kern::KUDesGet(bufp,*(const TDesC8*)a1); // get content from test app
1778 TUint8* bufptr = const_cast<TUint8*>(bufp.Ptr());
1779 for(TInt pos = 0; pos < bufp.Length(); pos++)
1781 if (bufptr[pos] != (TUint8)(pos & 31))
1784 Kern::Printf("Buf corrupt");
1790 // Nothing to release here!