--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/d_shbuf.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1795 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test/mmu/d_shbuf.cpp
+//
+
+#include "d_shbuf.h"
+#include <kernel/kernel.h>
+#include <kernel/cache.h>
+#include "plat_priv.h"
+#include <kernel/sshbuf.h>
+
+
+#define TEST_EXP(a) CheckPoint(a, __LINE__)
+#define TEST_KERRNONE(a) CheckPointError(a, __LINE__)
+
+#ifdef TEST_CLIENT_THREAD
+#define TEST_ENTERCS() NKern::ThreadEnterCS()
+#define TEST_LEAVECS() NKern::ThreadLeaveCS()
+#else
+#define TEST_ENTERCS()
+#define TEST_LEAVECS()
+#endif // TEST_CLIENT_THREAD
+
+const TInt KMaxPhysicalMemoryBlockSize = 512 << 10; // 512KB;
+
+// ----------------------------------------------------------------------------
+
+class DShBufTestDrvFactory : public DLogicalDevice
+ {
+public:
+ DShBufTestDrvFactory();
+ ~DShBufTestDrvFactory();
+ virtual TInt Install();
+ virtual void GetCaps(TDes8& aDes) const;
+ virtual TInt Create(DLogicalChannelBase*& aChannel);
+public:
+#ifndef TEST_CLIENT_THREAD
+ TDynamicDfcQue* iDfcQ;
+#endif
+ };
+
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_CLIENT_THREAD
+class DShBufTestDrvChannel : public DLogicalChannelBase
+#else
+class DShBufTestDrvChannel : public DLogicalChannel
+#endif
+ {
+public:
+ DShBufTestDrvChannel();
+ ~DShBufTestDrvChannel();
+ // Inherited from DLogicalChannel
+ virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+#ifdef TEST_CLIENT_THREAD
+ // Inherited from DLogicalChannelBase: process all DoControl in the user's context
+ virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+#else
+ TInt DoControl(TInt aReqNo, TAny* a1, TAny* a2);
+ virtual void HandleMsg(TMessageBase* aMsg);
+ virtual TInt SendMsg(TMessageBase* aMsg);
+#endif
+public:
+ TShPoolCreateInfo* iCreateinfo;
+ TShPoolInfo iUserpoolinfo;
+ TShPool* iPools[2];
+ TShBuf* iAdopted;
+ TUint8 iDriverTxBuffer[8192];
+ TUint8 iDriverRxBuffer[8192];
+#ifndef TEST_CLIENT_THREAD
+ DThread* iClient;
+ TVirtualPinObject* iPin;
+#endif
+ };
+
+// ----------------------------------------------------------------------------
+
+void CheckPoint(TInt aCondition, TInt aLine)
+ {
+ if (!aCondition)
+ {
+ Kern::Printf("Device driver test failed (line %d)", aLine);
+ }
+ }
+
+void CheckPointError(TInt aErrorCode, TInt aLine)
+ {
+ if (aErrorCode != KErrNone)
+ {
+ Kern::Printf("Device driver error %d (line %d)", aErrorCode, aLine);
+ }
+ }
+
+TInt Log2(TInt aNum)
+ {
+ TInt res = -1;
+ while(aNum)
+ {
+ res++;
+ aNum >>= 1;
+ }
+ return res;
+ }
+
+TInt RoundUp(TInt aNum, TInt aAlignmentLog2)
+ {
+ if (aNum % (1 << aAlignmentLog2) == 0)
+ {
+ return aNum;
+ }
+ return (aNum & ~((1 << aAlignmentLog2) - 1)) + (1 << aAlignmentLog2);
+ }
+
+#ifdef __WINS__
+#define SHBUF_NOT_WINS(x)
+#else
+#define SHBUF_NOT_WINS(x) x
+#endif
+TBool IsBufferContiguous(TShBuf* SHBUF_NOT_WINS(aBuf))
+ {
+ TInt pagesize;
+ TInt r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
+ TEST_KERRNONE(r);
+
+#ifdef __WINS__
+ return ETrue;
+#else
+ TUint8* ptr = Kern::ShBufPtr(aBuf);
+ TUint size = Kern::ShBufSize(aBuf);
+
+ TBool iscontiguous = ETrue;
+
+ TPhysAddr startphys = Epoc::LinearToPhysical((TLinAddr) ptr);
+ TUint i;
+
+ for (i = 0; i < size; i += pagesize)
+ {
+ TPhysAddr current = Epoc::LinearToPhysical((TLinAddr) ptr + i);
+ if (current != startphys + i)
+ {
+ Kern::Printf("Page %d: 0x%08x (started@0x%08x expected 0x%08x)", i, current, startphys, startphys + i);
+ iscontiguous = EFalse;
+ break;
+ }
+ }
+
+ return iscontiguous;
+#endif // __WINS__
+ }
+
+DECLARE_STANDARD_LDD()
+ {
+ return new DShBufTestDrvFactory;
+ }
+
+DShBufTestDrvFactory::DShBufTestDrvFactory()
+ {
+ iParseMask=0; //no units, no info, no pdd
+ iUnitsMask=0;
+ iVersion=TVersion(1,0,KE32BuildVersionNumber);
+ }
+
+DShBufTestDrvFactory::~DShBufTestDrvFactory()
+ {
+#ifndef TEST_CLIENT_THREAD
+ if (iDfcQ)
+ iDfcQ->Destroy();
+#endif
+ }
+
+#ifndef TEST_CLIENT_THREAD
+const TInt KShBufTestThreadPriority = 1;
+_LIT(KShBufTestThread,"ShBufTestThread");
+#endif
+
+TInt DShBufTestDrvFactory::Install()
+ {
+#ifndef TEST_CLIENT_THREAD
+ TInt r = Kern::DynamicDfcQCreate(iDfcQ, KShBufTestThreadPriority, KShBufTestThread);
+
+ if (r != KErrNone)
+ return r;
+ return(SetName(&KTestShBufOwn));
+#else
+ return(SetName(&KTestShBufClient));
+#endif
+ }
+
+
+void DShBufTestDrvFactory::GetCaps(TDes8& /*aDes*/) const
+ {
+ // Get capabilities - overriding pure virtual
+ }
+
+TInt DShBufTestDrvFactory::Create(DLogicalChannelBase*& aChannel)
+ {
+ aChannel=new DShBufTestDrvChannel;
+ return aChannel?KErrNone:KErrNoMemory;
+ }
+
+// ----------------------------------------------------------------------------
+
+DShBufTestDrvChannel::DShBufTestDrvChannel()
+ {
+#ifndef TEST_CLIENT_THREAD
+ iClient=&Kern::CurrentThread();
+ iClient->Open();
+#endif
+
+ TPtr8 bufp(iDriverRxBuffer,0,sizeof(iDriverRxBuffer));
+
+ for(TInt pos = 0; pos < bufp.Length(); pos++)
+ {
+ bufp[pos] = (TUint8)(pos & 31);
+ }
+ }
+
+DShBufTestDrvChannel::~DShBufTestDrvChannel()
+ {
+ NKern::ThreadEnterCS();
+#ifndef TEST_CLIENT_THREAD
+ Kern::SafeClose((DObject*&)iClient, NULL);
+ if(iPin)
+ {
+ Kern::DestroyVirtualPinObject(iPin);
+ }
+#endif
+ delete iCreateinfo;
+ NKern::ThreadLeaveCS();
+ }
+
+TInt DShBufTestDrvChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
+ {
+#ifndef TEST_CLIENT_THREAD
+ SetDfcQ(((DShBufTestDrvFactory*)iDevice)->iDfcQ);
+ iMsgQ.Receive();
+#endif
+
+ return KErrNone;
+ }
+
+#ifndef TEST_CLIENT_THREAD
+void DShBufTestDrvChannel::HandleMsg(TMessageBase* aMsg)
+ {
+ TInt r=KErrNone;
+ TThreadMessage& m=*(TThreadMessage*)aMsg;
+ TInt id=m.iValue;
+ if (id==(TInt)ECloseMsg)
+ {
+ m.Complete(KErrNone,EFalse);
+ return;
+ }
+ else
+ {
+ r=DoControl(id,m.Ptr0(),m.Ptr1());
+ }
+ m.Complete(r,ETrue);
+ }
+
+TInt DShBufTestDrvChannel::SendMsg(TMessageBase* aMsg)
+ {
+ // We can only handle one request at a time.
+ TEST_EXP(!iCreateinfo && !iPin);
+ if(iCreateinfo || iPin)
+ {
+ return KErrInUse;
+ }
+
+ TThreadMessage& m = *(TThreadMessage*)aMsg;
+ TAny* a1 = m.Ptr0();
+ TAny* a2 = m.Ptr1();
+ TInt r = KErrNone;
+
+ // Make a copy of the parameters in the asynchronous read case so that we don't
+ // risk a page fault by reading user-mode memory from the msg DFC.
+ //
+ // Manage writes using a TClientBufferRequest.
+ switch(aMsg->iValue)
+ {
+ // Reads
+ case RShBufTestChannel::ETestOpenUserPool:
+ kumemget(&iUserpoolinfo, a2, sizeof(iUserpoolinfo));
+ break;
+ case RShBufTestChannel::ETestCreatePoolContiguousPool:
+ NKern::ThreadEnterCS();
+ iCreateinfo = new TShPoolCreateInfo;
+ NKern::ThreadLeaveCS();
+ TEST_EXP(iCreateinfo != NULL);
+ if(!iCreateinfo)
+ {
+ r = KErrNoMemory;
+ break;
+ }
+
+ kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
+ break;
+ case RShBufTestChannel::EFromTPtr8ProcessAndRelease:
+ {
+ TPtr8 dest(iDriverTxBuffer, sizeof(iDriverTxBuffer));
+ Kern::ThreadDesRead(iClient, a1, dest, 0, KChunkShiftBy0);
+ }
+ break;
+
+ // Writes
+ case RShBufTestChannel::ETestOpenKernelPool:
+ NKern::ThreadEnterCS();
+ iCreateinfo = new TShPoolCreateInfo;
+ NKern::ThreadLeaveCS();
+ TEST_EXP(iCreateinfo != NULL);
+ if(!iCreateinfo)
+ {
+ r = KErrNoMemory;
+ break;
+ }
+
+ kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
+
+ // Fallthrough...
+ case RShBufTestChannel::ETestAllocateMax:
+ case RShBufTestChannel::ETestAllocateKernelBuffer:
+ {
+ NKern::ThreadEnterCS();
+ r = Kern::CreateAndPinVirtualMemory(iPin, (TLinAddr)a2, sizeof(TInt));
+ NKern::ThreadLeaveCS();
+ }
+ break;
+
+ // Descriptor writes
+ case RShBufTestChannel::EFromTPtr8ProcessAndReturn:
+ {
+ TUint size = ((const TDes8*)a1)->Size();
+
+ if(size <= sizeof(iDriverRxBuffer))
+ {
+ NKern::ThreadEnterCS();
+ r = Kern::CreateAndPinVirtualMemory(iPin, (TLinAddr)((const TDes8*)a1)->Ptr(), size);
+ NKern::ThreadLeaveCS();
+ }
+ else
+ {
+ r = KErrNoMemory;
+ }
+ }
+ break;
+ }
+
+ if(r == KErrNone)
+ {
+ r = DLogicalChannel::SendMsg(aMsg);
+ }
+
+ return r;
+ }
+#endif
+
+#ifdef TEST_CLIENT_THREAD
+TInt DShBufTestDrvChannel::Request(TInt aReqNo, TAny* a1, TAny* a2)
+#else
+TInt DShBufTestDrvChannel::DoControl(TInt aReqNo, TAny* a1, TAny* a2)
+#endif
+ {
+ TInt r=KErrNotSupported;
+
+ switch (aReqNo)
+ {
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::OpenUserPool(TInt aHandle, TShPoolInfo& aPoolInfo)
+ case RShBufTestChannel::ETestOpenUserPool:
+ {
+ DThread* tP=NULL;
+
+#ifdef TEST_CLIENT_THREAD
+ kumemget(&iUserpoolinfo, a2, sizeof(iUserpoolinfo));
+ tP=&Kern::CurrentThread();
+#else
+ tP=iClient;
+#endif
+
+ TEST_EXP(!iPools[0]);
+ if(iPools[0])
+ {
+ r = KErrAlreadyExists;
+ break;
+ }
+
+ NKern::ThreadEnterCS();
+ r = Kern::ShPoolOpen(iPools[0], tP, (TInt) a1, ETrue, KDefaultPoolHandleFlags);
+ NKern::ThreadLeaveCS();
+
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+
+ TInt n;
+ n = reinterpret_cast<DShPool*>(iPools[0])->AccessCount();
+ TEST_EXP(n == 2);
+ if (n != 2)
+ {
+ r = KErrUnknown;
+ break;
+ }
+
+ TShPoolInfo poolinfo;
+ Kern::ShPoolGetInfo(iPools[0], poolinfo);
+ if (!((poolinfo.iBufSize == iUserpoolinfo.iBufSize) &&
+ ((TUint)Kern::ShPoolBufSize(iPools[0]) == iUserpoolinfo.iBufSize) &&
+ (poolinfo.iInitialBufs == iUserpoolinfo.iInitialBufs) &&
+ (poolinfo.iMaxBufs == iUserpoolinfo.iMaxBufs) &&
+ (poolinfo.iGrowTriggerRatio == iUserpoolinfo.iGrowTriggerRatio) &&
+ (poolinfo.iGrowByRatio == iUserpoolinfo.iGrowByRatio) &&
+ (poolinfo.iShrinkHysteresisRatio == iUserpoolinfo.iShrinkHysteresisRatio) &&
+ (poolinfo.iAlignment == iUserpoolinfo.iAlignment) &&
+ ((poolinfo.iFlags & EShPoolNonPageAlignedBuffer) == (iUserpoolinfo.iFlags & EShPoolNonPageAlignedBuffer)) &&
+ ((poolinfo.iFlags & EShPoolPageAlignedBuffer) == (iUserpoolinfo.iFlags & EShPoolPageAlignedBuffer))))
+ {
+ TEST_EXP(EFalse);
+ Kern::Printf("poolinfo.iBufSize == %d (expected %d)", poolinfo.iBufSize, iUserpoolinfo.iBufSize);
+ Kern::Printf("BufSize() == %d", Kern::ShPoolBufSize(iPools[0]));
+ Kern::Printf("poolinfo.iInitialBufs == %d (expected %d)", poolinfo.iInitialBufs, iUserpoolinfo.iInitialBufs);
+ Kern::Printf("poolinfo.iMaxBufs == %d (expected %d)", poolinfo.iMaxBufs, iUserpoolinfo.iMaxBufs);
+ Kern::Printf("poolinfo.iGrowTriggerRatio == %d (expected %d)", poolinfo.iGrowTriggerRatio, iUserpoolinfo.iGrowTriggerRatio);
+ Kern::Printf("poolinfo.iGrowByRatio == %d (expected %d)", poolinfo.iGrowByRatio, iUserpoolinfo.iGrowByRatio);
+ Kern::Printf("poolinfo.iShrinkHysteresisRatio == %d (expected %d)", poolinfo.iShrinkHysteresisRatio, iUserpoolinfo.iShrinkHysteresisRatio);
+ Kern::Printf("poolinfo.iAlignment == %d (expected %d)", poolinfo.iAlignment, iUserpoolinfo.iAlignment);
+ Kern::Printf("poolinfo.iFlags == 0x%08x (user=0x%08x)", poolinfo.iFlags, iUserpoolinfo.iFlags);
+
+ r = KErrUnknown;
+ break;
+ }
+
+ if(poolinfo.iFlags & EShPoolPageAlignedBuffer)
+ {
+ NKern::ThreadEnterCS();
+ r = Kern::ShPoolSetBufferWindow(iPools[0],-1);
+ NKern::ThreadLeaveCS();
+ TEST_KERRNONE(r);
+ if(r!=KErrNone)
+ break;
+ }
+
+ r = KErrNone;
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::OpenKernelPool(TShPoolCreateInfo& aInfo, TInt& aHandle)
+ case RShBufTestChannel::ETestOpenKernelPool:
+ {
+ TInt handle;
+#ifdef TEST_CLIENT_THREAD
+ // We can only handle one request at a time.
+ TEST_EXP(!iCreateinfo);
+ if(iCreateinfo)
+ {
+ r = KErrInUse;
+ break;
+ }
+
+ NKern::ThreadEnterCS();
+ iCreateinfo = new TShPoolCreateInfo;
+ NKern::ThreadLeaveCS();
+ TEST_EXP(iCreateinfo != NULL);
+ if(!iCreateinfo)
+ {
+ r = KErrNoMemory;
+ break;
+ }
+
+ kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
+#endif
+
+ TEST_EXP(!iPools[1]);
+ if(iPools[1])
+ {
+ r = KErrAlreadyExists;
+ break;
+ }
+
+ NKern::ThreadEnterCS();
+ r = Kern::ShPoolCreate(iPools[1], *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
+ delete iCreateinfo;
+ iCreateinfo = NULL;
+ NKern::ThreadLeaveCS();
+
+ TEST_KERRNONE(r);
+ if (r)
+ {
+#ifndef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+ break;
+ }
+
+ TInt n;
+ n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
+ TEST_EXP(n == 1);
+ if (n != 1)
+ {
+#ifndef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+
+ r = KErrUnknown;
+ break;
+ }
+
+ TShPoolInfo poolinfo;
+ Kern::ShPoolGetInfo(iPools[1], poolinfo);
+ if(poolinfo.iFlags & EShPoolPageAlignedBuffer)
+ {
+ NKern::ThreadEnterCS();
+ r = Kern::ShPoolSetBufferWindow(iPools[1],-1);
+ NKern::ThreadLeaveCS();
+ TEST_KERRNONE(r);
+ if(r!=KErrNone)
+ {
+#ifndef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+
+ break;
+ }
+ }
+
+#ifdef TEST_CLIENT_THREAD
+ // Now create a handle for the client
+ NKern::ThreadEnterCS();
+ handle = Kern::ShPoolMakeHandleAndOpen(iPools[1], NULL, KDefaultPoolHandleFlags);
+ NKern::ThreadLeaveCS();
+#else
+ handle = Kern::ShPoolMakeHandleAndOpen(iPools[1], iClient, KDefaultPoolHandleFlags);
+#endif
+ TEST_EXP(handle > 0);
+ if (handle < 0)
+ {
+#ifndef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+
+ r = handle;
+ break;
+ }
+
+ n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
+
+ TEST_EXP(n == 2);
+ if (n != 2)
+ {
+#ifndef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+
+ r = KErrUnknown;
+ break;
+ }
+
+#ifdef TEST_CLIENT_THREAD
+ kumemput(a2, &handle, sizeof(handle));
+#else
+ Kern::ThreadRawWrite(iClient, a2, &handle, sizeof(handle), iClient);
+
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::CloseUserPool()
+ case RShBufTestChannel::ETestCloseUserPool:
+ {
+ TInt n;
+ n = reinterpret_cast<DShPool*>(iPools[0])->AccessCount();
+
+ TEST_EXP(n == 1);
+ if (n != 1)
+ {
+ r = KErrUnknown;
+ break;
+ }
+ TEST_ENTERCS();
+ r = Kern::ShPoolClose(iPools[0]);
+ iPools[0] = 0;
+ TEST_LEAVECS();
+ if (r>0)
+ {
+ r = KErrNone;
+ }
+
+ TEST_KERRNONE(r);
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::CloseKernelPool()
+ case RShBufTestChannel::ETestCloseKernelPool:
+ {
+#if 0
+ TInt n;
+ n = reinterpret_cast<DShPool*>(iPools[1])->AccessCount();
+ TEST_EXP(n == 2);
+ if (n != 2)
+ {
+ r = KErrUnknown;
+ break;
+ }
+#endif
+ TEST_ENTERCS();
+ r = Kern::ShPoolClose(iPools[1]);
+ iPools[1] = 0;
+ TEST_LEAVECS();
+ if (r>0)
+ {
+ r = KErrNone;
+ }
+
+ TEST_KERRNONE(r);
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::ManipulateUserBuffer(TInt aHandle)
+ case RShBufTestChannel::ETestManipulateUserBuffer:
+ {
+ TShBuf* ubuf = NULL;
+ DThread* tP;
+
+#ifdef TEST_CLIENT_THREAD
+ tP=&Kern::CurrentThread();
+#else
+ tP=iClient;
+#endif
+ NKern::ThreadEnterCS();
+
+ r = Kern::ShBufOpen(ubuf, tP, (TInt) a1);
+
+ TEST_KERRNONE(r);
+ if (r!=KErrNone)
+ {
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ TInt n;
+ n = reinterpret_cast<DShBuf*>(ubuf)->AccessCount();
+
+ TEST_EXP(n == 2);
+ if (n != 2)
+ {
+ r = KErrUnknown;
+ Kern::ShBufClose(ubuf);
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ TInt i;
+
+ TInt blocks = Kern::ShBufSize(ubuf) / KTestData1().Length();
+
+ for (i = 0; i < blocks; i++)
+ {
+
+ TPtr8 ptr(Kern::ShBufPtr(ubuf) + (i * KTestData1().Length()), KTestData1().Length(), KTestData1().Length());
+ r = KTestData1().Compare(ptr);
+
+ if (r)
+ {
+ break;
+ }
+ ptr.Fill(i);
+ }
+
+ TEST_EXP(r == KErrNone);
+ if (r)
+ {
+ r = KErrUnknown;
+ }
+ Kern::ShBufClose(ubuf);
+ NKern::ThreadLeaveCS();
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::AllocateKernelBuffer(TInt aPoolIndex, TInt& aHandle)
+ case RShBufTestChannel::ETestAllocateKernelBuffer:
+ {
+ TInt poolindex = (TInt) a1;
+ if ((poolindex != 0) && (poolindex != 1))
+ {
+ r = KErrArgument;
+ break;
+ }
+
+ NKern::ThreadEnterCS();
+
+ // Allocate kernel-side buffer
+ TShBuf* kbuf;
+ r = Kern::ShPoolAlloc(iPools[poolindex], kbuf, 0);
+
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ // Fill it with test data
+ TUint i;
+ for (i = 0; i < Kern::ShPoolBufSize(iPools[poolindex]) / KTestData2().Length(); i++)
+ {
+ TPtr8 ptr(Kern::ShBufPtr(kbuf) + (i * KTestData2().Length()), KTestData2().Length(), KTestData2().Length());
+ ptr.Copy(KTestData2());
+ }
+
+ // Now create a handle for the client
+ TInt handle;
+#ifdef TEST_CLIENT_THREAD
+ handle = Kern::ShBufMakeHandleAndOpen(kbuf, NULL);
+#else
+ handle = Kern::ShBufMakeHandleAndOpen(kbuf, iClient);
+#endif
+
+ TEST_EXP(handle > 0);
+ if (handle < 0)
+ {
+ r = handle;
+ Kern::ShBufClose(kbuf);
+ NKern::ThreadLeaveCS();
+
+ break;
+ }
+ TInt n;
+ n = reinterpret_cast<DShBuf*>(kbuf)->AccessCount();
+
+ TEST_EXP(n == 2);
+ if (n != 2)
+ {
+ r = KErrUnknown;
+ Kern::ShBufClose(kbuf);
+ NKern::ThreadLeaveCS();
+
+ break;
+ }
+#ifdef TEST_CLIENT_THREAD
+ NKern::ThreadLeaveCS();
+
+ kumemput(a2, &handle, sizeof(handle));
+
+ NKern::ThreadEnterCS();
+ Kern::ShBufClose(kbuf);
+ NKern::ThreadLeaveCS();
+#else
+ NKern::ThreadLeaveCS();
+
+ Kern::ThreadRawWrite(iClient, a2, &handle, sizeof(handle), iClient);
+
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+
+ // Close buffer - but it is still referenced by client handle
+ Kern::ShBufClose(kbuf);
+ NKern::ThreadLeaveCS();
+#endif
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt ContiguousPoolKernel(TShPoolCreateInfo& aInfo)
+ case RShBufTestChannel::ETestCreatePoolContiguousPool:
+ {
+#ifdef TEST_CLIENT_THREAD
+ NKern::ThreadEnterCS();
+ iCreateinfo = new TShPoolCreateInfo;
+ NKern::ThreadLeaveCS();
+ TEST_EXP(iCreateinfo != NULL);
+ if(!iCreateinfo)
+ {
+ r = KErrNoMemory;
+ break;
+ }
+
+ kumemget(iCreateinfo, a1, sizeof(TShPoolInfo));
+#endif
+
+ TShPool* mainpool;
+ TShPool* otherpool;
+
+ NKern::ThreadEnterCS();
+
+ r = Kern::ShPoolCreate(otherpool, *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
+ TEST_KERRNONE(r);
+
+ r = Kern::ShPoolSetBufferWindow(otherpool,-1);
+ TEST_KERRNONE(r);
+
+ iCreateinfo->SetContiguous();
+ TEST_KERRNONE(r);
+
+ r = Kern::ShPoolCreate(mainpool, *iCreateinfo, ETrue, KDefaultPoolHandleFlags);
+ NKern::ThreadEnterCS();
+ delete iCreateinfo;
+ iCreateinfo = NULL;
+ NKern::ThreadLeaveCS();
+ TEST_KERRNONE(r);
+
+ r = Kern::ShPoolSetBufferWindow(mainpool,-1);
+ TEST_KERRNONE(r);
+
+ TInt i;
+ TShBuf* mainbuf[KTestPoolSizeInBufs];
+ TShBuf* otherbuf[KTestPoolSizeInBufs];
+ for (i = 0; i < KTestPoolSizeInBufs; i++)
+ {
+ r = Kern::ShPoolAlloc(mainpool, mainbuf[i], 0);
+ if (r)
+ {
+ Kern::Printf("i=%d r=%d\n", i, r);
+ TEST_KERRNONE(r);
+ }
+ r = Kern::ShPoolAlloc(otherpool, otherbuf[i], 0);
+ if (r)
+ {
+ Kern::Printf("i=%d r=%d\n", i, r);
+ TEST_KERRNONE(r);
+ }
+ TBool iscontiguous;
+ iscontiguous = IsBufferContiguous(mainbuf[i]);
+ if (!iscontiguous)
+ {
+ Kern::Printf("i=%d\n", i, r);
+ TEST_EXP(iscontiguous);
+ }
+ // delay?
+ }
+
+ // Free every other buffer
+ for (i = 0; i < KTestPoolSizeInBufs; i += 2)
+ {
+ Kern::ShBufClose(mainbuf[i]);
+ Kern::ShBufClose(otherbuf[i]);
+ }
+
+ // Re-allocate buffers
+ for (i = 0; i < KTestPoolSizeInBufs; i += 2)
+ {
+ r = Kern::ShPoolAlloc(otherpool, otherbuf[i], 0);
+ if (r)
+ {
+ Kern::Printf("i=%d r=%d\n", i, r);
+ TEST_KERRNONE(r);
+ }
+ r = Kern::ShPoolAlloc(mainpool, mainbuf[i], 0);
+ if (r)
+ {
+ Kern::Printf("i=%d r=%d\n", i, r);
+ TEST_KERRNONE(r);
+ }
+ TBool iscontiguous;
+ iscontiguous = IsBufferContiguous(mainbuf[i]);
+ if (!iscontiguous)
+ {
+ Kern::Printf("i=%d\n", i, r);
+ TEST_EXP(iscontiguous);
+ // bang
+ }
+ }
+ for (i = 0; i < KTestPoolSizeInBufs; i++)
+ {
+ Kern::ShBufClose(mainbuf[i]);
+ Kern::ShBufClose(otherbuf[i]);
+ }
+
+ Kern::ShPoolClose(mainpool);
+ Kern::ShPoolClose(otherpool);
+ NKern::ThreadLeaveCS();
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt CreatePoolPhysAddrCont(TInt aBufSize)
+// TInt CreatePoolPhysAddrNonCont(TInt aBufSize)
+ case RShBufTestChannel::ETestCreatePoolPhysAddrCont:
+ case RShBufTestChannel::ETestCreatePoolPhysAddrNonCont:
+ {
+ r = KErrNone;
+#ifndef __WINS__
+ TInt bufsize = (TInt) a1;
+ TInt minimumAlignmentLog2 = __e32_find_ms1_32(Cache::DmaBufferAlignment());
+ if (minimumAlignmentLog2 < 5)
+ minimumAlignmentLog2 = 5;
+ TInt pagesize;
+ r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+
+ if (bufsize > KMaxPhysicalMemoryBlockSize)
+ {
+ // Buffer too large
+ return KErrNone;
+ }
+ TInt physicalblocksize = RoundUp(128 * RoundUp(bufsize, Log2(minimumAlignmentLog2)), Log2(pagesize) + 1);
+ if (physicalblocksize > KMaxPhysicalMemoryBlockSize)
+ {
+ physicalblocksize = KMaxPhysicalMemoryBlockSize;
+ }
+ if (physicalblocksize < pagesize * 4)
+ {
+ physicalblocksize = pagesize * 4;
+ }
+
+ NKern::ThreadEnterCS();
+
+ // Allocate an array of physical addresses
+ TPhysAddr* addrtable = NULL;
+
+ // Allocate physical memory
+ TPhysAddr physaddr;
+ if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
+ {
+ r = Epoc::AllocPhysicalRam(physicalblocksize, physaddr, 0);
+ }
+ else
+ {
+ addrtable = (TPhysAddr*) Kern::Alloc((physicalblocksize / pagesize) * sizeof(TPhysAddr));
+ TEST_EXP(addrtable != NULL);
+ if (addrtable == NULL)
+ {
+ r = KErrNoMemory;
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ TPhysAddr* addrtabletmp;
+ addrtabletmp = (TPhysAddr*) Kern::Alloc((physicalblocksize / pagesize / 2) * sizeof(TPhysAddr));
+ TEST_EXP(addrtabletmp != NULL);
+ if (addrtabletmp == NULL)
+ {
+ r = KErrNoMemory;
+ }
+ else
+ {
+ // Allocate discontiguous memory
+ r = Epoc::AllocPhysicalRam(1, addrtable);
+ TEST_KERRNONE(r);
+ if (r == KErrNone)
+ {
+ r = Epoc::AllocPhysicalRam(1, addrtabletmp); // 1 page gap
+ TEST_KERRNONE(r);
+ if (r == KErrNone)
+ {
+ r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtable + 1);
+ TEST_KERRNONE(r);
+ if (r == KErrNone)
+ {
+ r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtabletmp + 1); // big gap
+ TEST_KERRNONE(r);
+ if (r == KErrNone)
+ {
+ r = Epoc::AllocPhysicalRam(physicalblocksize / pagesize / 2, addrtable + physicalblocksize / pagesize / 2);
+ TEST_KERRNONE(r);
+ r = Epoc::FreePhysicalRam(physicalblocksize / pagesize / 2 - 1, addrtabletmp + 1);
+ TEST_KERRNONE(r);
+ }
+ }
+ r = Epoc::FreePhysicalRam(1, addrtabletmp);
+ TEST_KERRNONE(r);
+ }
+ }
+ Kern::Free(addrtabletmp);
+ }
+ }
+
+ if (r)
+ {
+ Kern::Free(addrtable);
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ // Create pool
+ TInt poolsizeinbufs;
+ poolsizeinbufs = physicalblocksize / RoundUp(bufsize, minimumAlignmentLog2);
+
+ TShPool* pool = NULL;
+ if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
+ {
+ TShPoolCreateInfo inf(TShPoolCreateInfo::EDevice, bufsize,
+ poolsizeinbufs, 0, physicalblocksize / pagesize, physaddr);
+ r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
+ }
+ else
+ {
+ TShPoolCreateInfo inf(TShPoolCreateInfo::EDevice, bufsize,
+ poolsizeinbufs, 0, physicalblocksize / pagesize, addrtable);
+ r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
+ }
+ TEST_KERRNONE(r);
+ if (r == KErrNone)
+ {
+ // Do some buffer allocation with the pool
+ TInt freecount1 = Kern::ShPoolFreeCount(pool);
+ RPointerArray<TShBuf> bufarray;
+ TInt allocated = 0;
+ do
+ {
+ TShBuf* buf;
+ r = Kern::ShPoolAlloc(pool, buf, 0);
+ if (r == KErrNone)
+ {
+ TPtr8 ptr(Kern::ShBufPtr(buf), Kern::ShBufSize(buf), Kern::ShBufSize(buf));
+ ptr.Fill('$');
+ bufarray.Append(buf);
+ allocated++;
+ }
+ }
+ while (r == KErrNone);
+ TInt freecount2 = Kern::ShPoolFreeCount(pool);
+
+ if (r != KErrNoMemory)
+ {
+ TEST_KERRNONE(r);
+ }
+ while (bufarray.Count())
+ {
+ if (bufarray[0])
+ {
+ Kern::ShBufClose(bufarray[0]);
+ }
+ bufarray.Remove(0);
+ }
+ TInt freecount3 = Kern::ShPoolFreeCount(pool);
+ bufarray.Close();
+ //
+ r = Kern::ShPoolClose(pool);
+ if (r>0)
+ {
+ r = KErrNone;
+ }
+
+ TEST_KERRNONE(r);
+
+ if ((freecount1 != freecount3) || (freecount1 != allocated) || (freecount1 != poolsizeinbufs) || (freecount2))
+ {
+ r = KErrUnknown;
+ Kern::Printf("fc1=%d fc2=%d fc3=%d alloc=%d", freecount1, freecount2, freecount3, allocated);
+ TEST_EXP(EFalse);
+ }
+ }
+ NKern::Sleep(5000);
+ TInt r2;
+ if (aReqNo == RShBufTestChannel::ETestCreatePoolPhysAddrCont)
+ {
+ r2 = Epoc::FreePhysicalRam(physaddr, physicalblocksize);
+ }
+ else
+ {
+ r2 = Epoc::FreePhysicalRam(physicalblocksize / pagesize, addrtable);
+ Kern::Free(addrtable);
+ }
+ TEST_KERRNONE(r2);
+ if (!r && r2)
+ {
+ r = r2; // if an error occurred whilst freeing physical memory, report it
+ }
+ NKern::ThreadLeaveCS();
+#endif // __WINS__
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt AllocateMax(TInt aPoolIndex, TInt& aAllocated)
+ case RShBufTestChannel::ETestAllocateMax:
+ {
+ TInt r2;
+ TInt poolindex = (TInt) a1;
+ if ((poolindex != 0) && (poolindex != 1))
+ {
+ r2 = KErrArgument;
+ break;
+ }
+ TShPoolInfo poolinfo;
+ Kern::ShPoolGetInfo(iPools[poolindex], poolinfo);
+
+ NKern::ThreadEnterCS();
+
+ RPointerArray<TShBuf> bufarray;
+ do
+ {
+ TShBuf* buf;
+ r2 = Kern::ShPoolAlloc(iPools[poolindex], buf, 0);
+ if(r2==KErrNoMemory && (TUint)bufarray.Count()<poolinfo.iMaxBufs)
+ {
+ NKern::Sleep(1000);
+ r2 = Kern::ShPoolAlloc(iPools[poolindex], buf, 0);
+ }
+ if (r2 == KErrNone)
+ {
+ r2 = bufarray.Append(buf);
+ TEST_KERRNONE(r2);
+ if (r2!=KErrNone)
+ {
+ Kern::ShBufClose(buf);
+ r2 = KErrGeneral;
+ }
+ }
+ }
+ while (r2 == KErrNone);
+
+ // close all buffers...
+ TInt n = bufarray.Count();
+ while (n)
+ Kern::ShBufClose(bufarray[--n]);
+
+ if (r2 != KErrNoMemory)
+ {
+ TEST_KERRNONE(r2);
+ }
+ else
+ {
+ // Do it once more
+ n = 0;
+ while (n<bufarray.Count())
+ {
+ r2 = Kern::ShPoolAlloc(iPools[poolindex], bufarray[n], 0);
+ if(r2==KErrNoMemory)
+ {
+ NKern::Sleep(1000);
+ r2 = Kern::ShPoolAlloc(iPools[poolindex], bufarray[n], 0);
+ }
+ if (r2)
+ {
+ Kern::Printf("Line %d: n=%d r2=%d", __LINE__, n, r2);
+ break;
+ }
+ ++n;
+ }
+
+ if (r2 == KErrNone)
+ {
+ TShBuf* extrabuf;
+ r2 = Kern::ShPoolAlloc(iPools[poolindex], extrabuf, 0);
+
+ TEST_EXP(r2 == KErrNoMemory);
+ }
+
+ while (n)
+ Kern::ShBufClose(bufarray[--n]);
+ }
+
+ TInt allocated = bufarray.Count();
+
+ bufarray.Close();
+ if (r2 == KErrNoMemory)
+ {
+ r = KErrNone;
+ }
+ else
+ {
+ r = r2;
+ }
+
+#ifdef TEST_CLIENT_THREAD
+ NKern::ThreadLeaveCS();
+ kumemput(a2, &allocated, sizeof(allocated));
+#else
+ NKern::ThreadLeaveCS();
+
+ Kern::ThreadRawWrite(iClient, a2, &allocated, sizeof(allocated), iClient);
+
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt BufferAlignmentKernel(TInt aBufSize)
+ case RShBufTestChannel::ETestBufferAlignmentKernel:
+ {
+ TInt bufsize = (TInt) a1;
+ TInt alignment = (TInt) a2;
+
+ TInt pagesize;
+ r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+
+ NKern::ThreadEnterCS();
+
+ const TInt KNumBuffers = 20;
+
+ {
+ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, bufsize, KNumBuffers, alignment); // TODO: Change minbufs back to 8 when the pool growing code works
+ TShPool* pool;
+ r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ TInt j;
+ TShBuf* buf[KNumBuffers];
+ memclr(buf,sizeof(buf));
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ r = Kern::ShPoolAlloc(pool, buf[j], 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ Kern::Printf("i=%d j=%d", alignment, j);
+ break;
+ }
+ }
+ if (r == KErrNone)
+ {
+ if (alignment < KTestMinimumAlignmentLog2)
+ {
+ alignment = KTestMinimumAlignmentLog2;
+ }
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ if (((TUint32) Kern::ShBufPtr(buf[j]) & ((1 << alignment) - 1)))
+ {
+ Kern::Printf("Pool%d buf[%d]->Base() == 0x%08x", alignment, j, Kern::ShBufPtr(buf[j]));
+ r = KErrUnknown;
+ break;
+ }
+ }
+ }
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ if (buf[j])
+ {
+ Kern::ShBufClose(buf[j]);
+ }
+ }
+ TInt r2;
+ r2 = Kern::ShPoolClose(pool);
+
+ if (r2>0)
+ {
+ r2 = KErrNone;
+ }
+
+ TEST_KERRNONE(r2);
+ if (r == KErrNone)
+ {
+ r = r2;
+ }
+ if (r)
+ {
+ NKern::ThreadLeaveCS();
+ break;
+ }
+ }
+ // Page aligned buffers
+ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, bufsize, KNumBuffers); // TODO: Change minbufs back to 8 when the pool growing code works
+ TShPool* pool;
+ r = Kern::ShPoolCreate(pool, inf, ETrue, KDefaultPoolHandleFlags);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ r = Kern::ShPoolSetBufferWindow(pool,-1);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ Kern::ShPoolClose(pool);
+ NKern::ThreadLeaveCS();
+ break;
+ }
+
+ TInt j;
+ TShBuf* buf[KNumBuffers];
+ memclr(buf,sizeof(buf));
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ r = Kern::ShPoolAlloc(pool, buf[j], 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ Kern::Printf("j=%d", j);
+ break;
+ }
+ }
+ if (r == KErrNone)
+ {
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ if ((TUint32) Kern::ShBufPtr(buf[j]) & (pagesize - 1))
+ {
+ Kern::Printf("buf[%d]->Base() == 0x%08x", j, Kern::ShBufPtr(buf[j]));
+ r = KErrUnknown;
+ break;
+ }
+ }
+ }
+ for (j = 0; j < KNumBuffers; j++)
+ {
+ if (buf[j])
+ {
+ Kern::ShBufClose(buf[j]);
+ }
+ }
+ TInt r2;
+ r2 = Kern::ShPoolClose(pool);
+ if (r2>0)
+ {
+ r2 = KErrNone;
+ }
+
+ TEST_KERRNONE(r2);
+ if (!r)
+ {
+ r = r2;
+ }
+
+ NKern::ThreadLeaveCS();
+ }
+ break;
+// ----------------------------------------------------------------------------
+// TInt NegativeTestsKernel()
+ case RShBufTestChannel::ETestNegativeTestsKernel:
+ {
+ TInt pagesize;
+ r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+
+ #define TEST_POOLCREATE_FAIL(i, p, e, r) \
+ { \
+ TInt r2; \
+ TEST_ENTERCS(); \
+ r2 = Kern::ShPoolCreate(p, i, ETrue, KDefaultPoolHandleFlags); \
+ TEST_LEAVECS(); \
+ if (r2 != e) \
+ { \
+ Kern::Printf("Device drive (line %d) r=%d", __LINE__, r2); \
+ TEST_EXP(EFalse); \
+ r = KErrUnknown; \
+ break; \
+ } \
+ }
+
+ TShPool* pool;
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 100, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 100); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, 10); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 65537, 65536); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, 1 + (1 << (32 - Log2(pagesize)))); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+#ifndef __WINS__
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 128 * pagesize, (Kern::FreeRamInBytes() / (128 * pagesize)) + 1); TEST_POOLCREATE_FAIL(inf, pool, KErrNoMemory, r); }
+#endif
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 100, 0, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 100, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, 10, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, KMaxTUint, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, KMaxTUint, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 65537, 65536, 0); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, KMaxTUint); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, 33); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 300, 24); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 65537, 16); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, Log2(pagesize) + 1); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ { TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 128, 10, 0); inf.SetGuardPages(); TEST_POOLCREATE_FAIL(inf, pool, KErrArgument, r); }
+ }
+ break;
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// TInt RShBufTestChannel::PinBuffer(TInt aPoolHandle, TInt aBufferHandle)
+#ifndef __WINS__
+ case RShBufTestChannel::ETestPinBuffer:
+ {
+ TInt rignore;
+ TInt pagesize;
+ r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pagesize, 0);
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+ TShPool* upool = NULL;
+ TShBuf* ubufu = NULL; // User buffer unmapped
+ TShBuf* ubufm = NULL; // User buffer mapped
+ DThread* tP;
+#ifdef TEST_CLIENT_THREAD
+ tP=&Kern::CurrentThread();
+#else
+ tP=iClient;
+#endif
+
+ // Create pin object
+ TPhysicalPinObject* pinobj;
+ TEST_ENTERCS();
+ r = Kern::CreatePhysicalPinObject(pinobj);
+ TEST_LEAVECS();
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ break;
+ }
+
+ // Open user pool
+ TEST_ENTERCS();
+ r = Kern::ShPoolOpen(upool, tP, (TInt) a1, ETrue, KDefaultPoolHandleFlags);
+ TEST_LEAVECS();
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ TEST_ENTERCS();
+ rignore = Kern::DestroyPhysicalPinObject(pinobj);
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+ break;
+ }
+ TShPoolInfo poolinfo;
+ Kern::ShPoolGetInfo(upool, poolinfo);
+
+ // Open user buffer but do not map it
+ TEST_ENTERCS();
+ r = Kern::ShBufOpen(ubufu, tP, (TInt) a2);
+ TEST_LEAVECS();
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ TEST_ENTERCS();
+ rignore = Kern::DestroyPhysicalPinObject(pinobj);
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+
+ TEST_ENTERCS();
+ rignore = Kern::ShPoolClose(upool);
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+
+ break;
+ }
+
+ // Allocate an array of physical addresses
+ TPhysAddr* addrtable;
+ TUint size = Kern::ShBufSize(ubufu);
+ TEST_ENTERCS();
+ addrtable = (TPhysAddr*) Kern::Alloc((RoundUp(size, Log2(pagesize)) / pagesize) * sizeof(TPhysAddr));
+ TEST_LEAVECS();
+ TEST_EXP(addrtable != NULL);
+ if (!addrtable)
+ {
+ TEST_ENTERCS();
+ rignore = Kern::DestroyPhysicalPinObject(pinobj);
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+ TEST_ENTERCS();
+ rignore = Kern::ShBufClose(ubufu);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+ TEST_ENTERCS();
+ rignore = Kern::ShPoolClose(upool);
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+ r = KErrNoMemory;
+
+ break;
+ }
+
+ // Pin buffer
+ TPhysAddr addr;
+ TUint32 mapattr;
+ TUint color;
+ NKern::ThreadEnterCS();
+ r = Kern::ShBufPin(ubufu, pinobj, ETrue, addr, addrtable, mapattr, color);
+ NKern::ThreadLeaveCS();
+ TEST_KERRNONE(r);
+ if (addr != addrtable[0])
+ {
+ TEST_EXP(addr == KPhysAddrInvalid);
+ if (poolinfo.iFlags & EShPoolContiguous)
+ {
+ TEST_EXP(EFalse); // Shouldn't happen with contiguous pools
+ Kern::Printf("addr=0x%08x addrtable[0]=0x%08x", addr, addrtable[0]);
+ r = KErrUnknown;
+ }
+ else
+ {
+ if (addr != KPhysAddrInvalid)
+ {
+ TEST_EXP(EFalse); // if buffer is not contiguous addr must be KPhysAddrInvalid
+ Kern::Printf("addr=0x%08x addrtable[0]=0x%08x", addr, addrtable[0]);
+ r = KErrUnknown;
+ }
+ }
+ }
+ // Leave later if this fails
+
+ // Destroy pin object
+ TEST_ENTERCS();
+ TInt r2 = Kern::DestroyPhysicalPinObject(pinobj);
+ TEST_LEAVECS();
+ TEST_KERRNONE(r2);
+
+ // Close unmapped buffer
+ TEST_ENTERCS();
+ rignore = Kern::ShBufClose(ubufu);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+
+ // Leave test now if previous call to Kern::ShBufPin failed
+ if (r)
+ {
+ TEST_ENTERCS();
+ Kern::Free(addrtable);
+ rignore = Kern::ShPoolClose(upool);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+
+ break;
+ }
+
+ // Open window if pool is buffer-aligned
+ if (poolinfo.iFlags & EShPoolPageAlignedBuffer)
+ {
+ NKern::ThreadEnterCS();
+ r = Kern::ShPoolSetBufferWindow(upool, -1);
+ NKern::ThreadLeaveCS();
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ TEST_ENTERCS();
+ Kern::Free(addrtable);
+ rignore = Kern::ShPoolClose(upool);
+
+ TEST_LEAVECS();
+ TEST_KERRNONE(rignore);
+
+ break;
+ }
+ }
+
+ // Open user buffer and map it this time
+ TEST_ENTERCS();
+ r = Kern::ShBufOpen(ubufm, tP, (TInt) a2);
+ TEST_LEAVECS();
+ TEST_KERRNONE(r);
+ if (r)
+ {
+ TEST_ENTERCS();
+ Kern::Free(addrtable);
+ rignore = Kern::ShPoolClose(upool);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+
+ break;
+ }
+
+ // Ensure that physical addresses match
+ TUint8* ptr = Kern::ShBufPtr(ubufm);
+ TEST_EXP(ptr != NULL);
+ TBool isok = ETrue;
+ TInt i;
+ for (i = 0; i < RoundUp(size, Log2(pagesize)) / pagesize; i++)
+ {
+ TPhysAddr current = Epoc::LinearToPhysical((TLinAddr) ptr + i * pagesize);
+ if (current != addrtable[i])
+ {
+ Kern::Printf("Page %d: Current=0x%08x addrtable=0x%08x (linaddr=0x%08x)", i, current, addrtable[i], ptr + i * pagesize);
+ isok = EFalse;
+ break;
+ }
+ }
+ if (!isok)
+ {
+ r = KErrUnknown;
+ }
+ TEST_KERRNONE(r);
+
+ // Close mapped buffer
+ TEST_ENTERCS();
+ rignore = Kern::ShBufClose(ubufm);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+
+ // Close pool
+ TEST_ENTERCS();
+ rignore = Kern::ShPoolClose(upool);
+ TEST_LEAVECS();
+
+ TEST_KERRNONE(rignore);
+
+ // Free address table
+ TEST_ENTERCS();
+ Kern::Free(addrtable);
+ TEST_LEAVECS();
+
+ if (!r && r2)
+ {
+ r = r2;
+ }
+ }
+ break;
+#endif // __WINS__
+// ----------------------------------------------------------------------------
+ case RShBufTestChannel::EFromRShBufProcessAndReturn:
+ {
+ // inline TInt FromRShBufProcessAndReturn(TInt aHandle);
+ TInt bufsize = (TInt) a1;
+
+ TEST_ENTERCS();
+ // Allocate kernel-side buffer
+ TShBuf* kbuf;
+ r = Kern::ShPoolAlloc(iPools[0], kbuf, 0);
+
+ if (r)
+ {
+ TEST_LEAVECS();
+ break;
+ }
+
+ TUint8* ptr = Kern::ShBufPtr(kbuf);
+ TInt* lengthPtr = (TInt*)ptr;
+ *lengthPtr = bufsize - 2;
+
+#if 0 // do not cache
+ for(TInt pos = 4; pos < bufsize; pos++)
+ {
+ ptr[pos] = (TUint8)(pos & 31);
+ }
+#endif
+
+ // Now create a handle for the client
+ TInt handle;
+#ifdef TEST_CLIENT_THREAD
+ handle = Kern::ShBufMakeHandleAndOpen(kbuf, NULL);
+#else
+ handle = Kern::ShBufMakeHandleAndOpen(kbuf, iClient);
+#endif
+
+ if (handle < 0)
+ {
+ r = handle;
+ Kern::ShBufClose(kbuf);
+ TEST_LEAVECS();
+ break;
+ }
+
+ // Close buffer - but it is still referenced by client handle
+ Kern::ShBufClose(kbuf);
+ TEST_LEAVECS();
+
+ r=handle;
+ }
+ break;
+ case RShBufTestChannel::EFromRShBufProcessAndRelease:
+ {
+ // inline TInt FromRShBufProcessAndRelease(TInt aHandle);
+ TShBuf* ubuf = NULL;
+ DThread* tP;
+
+#ifdef TEST_CLIENT_THREAD
+ tP=&Kern::CurrentThread();
+#else
+ tP=iClient;
+#endif
+
+ TEST_ENTERCS();
+ r = Kern::ShBufOpen(ubuf, tP, (TInt) a1);
+ // close handle on behalf of user side application
+ Kern::CloseHandle(tP, (TInt) a1);
+ TEST_LEAVECS();
+
+ if(r!=KErrNone)
+ {
+ Kern::Printf("Buf not found");
+ break;
+ }
+
+#ifdef _DEBUG
+ TUint8* dataPtr = Kern::ShBufPtr(ubuf);
+
+ TInt* lengthPtr = (TInt*)(&dataPtr[0]);
+
+ for(TInt pos = 4; pos < *lengthPtr; pos++)
+ {
+ if (dataPtr[pos] != (TUint8)(pos & 31))
+ {
+ r=KErrCorrupt;
+ Kern::Printf("Buf corrupt");
+ break;
+ }
+ }
+#endif
+
+ TEST_ENTERCS();
+ Kern::ShBufClose(ubuf);
+ TEST_LEAVECS();
+
+ r=KErrNone;
+ }
+ break;
+ case RShBufTestChannel::EFromTPtr8ProcessAndReturn:
+ {
+ TInt bufsize = (TInt) a2;
+ TPtr8 rxBuf(iDriverRxBuffer,sizeof(iDriverRxBuffer),sizeof(iDriverRxBuffer));
+
+#if 0
+ for(TInt pos = 0; pos < bufsize; pos++)
+ {
+ rxBuf[pos] = (TUint8)(pos & 31);
+ }
+#endif
+ rxBuf.SetLength(bufsize-2);
+
+#ifdef TEST_CLIENT_THREAD
+ Kern::KUDesPut(*(TDes8*)a1, rxBuf); // put content from test app
+ r=KErrNone;
+#else
+ r = Kern::ThreadDesWrite(iClient, a1, rxBuf, 0, iClient);
+
+ NKern::ThreadEnterCS();
+ Kern::DestroyVirtualPinObject(iPin);
+ NKern::ThreadLeaveCS();
+#endif
+ }
+ break;
+ case RShBufTestChannel::EFromTPtr8ProcessAndRelease:
+ {
+ // inline TInt FromTPtr8ProcessAndRelease(TDes8& aBuf);
+#if defined _DEBUG || defined TEST_CLIENT_THREAD
+ TPtr8 bufp(iDriverTxBuffer, sizeof(iDriverTxBuffer), sizeof(iDriverTxBuffer));
+#endif
+#ifdef TEST_CLIENT_THREAD
+ Kern::KUDesGet(bufp,*(const TDesC8*)a1); // get content from test app
+#endif
+
+#ifdef _DEBUG
+ TUint8* bufptr = const_cast<TUint8*>(bufp.Ptr());
+ for(TInt pos = 0; pos < bufp.Length(); pos++)
+ {
+ if (bufptr[pos] != (TUint8)(pos & 31))
+ {
+ r=KErrCorrupt;
+ Kern::Printf("Buf corrupt");
+ break;
+ }
+ }
+#endif
+
+ // Nothing to release here!
+
+ r=KErrNone;
+ }
+ break;
+ }
+
+ return r;
+ }