diff -r 000000000000 -r a41df078684a kerneltest/e32test/mmu/d_shbuf.cpp --- /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 +#include +#include "plat_priv.h" +#include + + +#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(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(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(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(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(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(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(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 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 bufarray; + do + { + TShBuf* buf; + r2 = Kern::ShPoolAlloc(iPools[poolindex], buf, 0); + if(r2==KErrNoMemory && (TUint)bufarray.Count()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(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; + }