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