diff -r a990138eda40 -r c30940f6d922 kerneltest/e32test/dmav2/d_dma2.cpp --- a/kerneltest/e32test/dmav2/d_dma2.cpp Thu Apr 29 11:08:53 2010 +0100 +++ b/kerneltest/e32test/dmav2/d_dma2.cpp Tue May 04 09:44:26 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies). // All rights reserved. // This component and the accompanying materials are made available // under the terms of "Eclipse Public License v1.0" @@ -55,7 +55,7 @@ } return FastCountToMicroSecs(diff); #else - //TODO On SMP it is possible for the value returned from + //On SMP it is possible for the value returned from //NKern::FastCounter to depend on the current CPU (ie. //NaviEngine) // @@ -100,6 +100,7 @@ TInt DoGetInfo(TAny* aInfo); TInt OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie); + TInt OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo); TInt CloseDmaChannelByCookie(TUint aDriverCookie); TInt PauseDmaChannelByCookie(TUint aDriverCookie); TInt ResumeDmaChannelByCookie(TUint aDriverCookie); @@ -127,9 +128,6 @@ */ TInt CreateDmaRequest(TUint aChannelCookie, TUint& aRequestCookie, TBool aNewCallback = EFalse, TInt aMaxFragmentSizeBytes=0); - //TODO what happens if a client closes a channel that - //it still has dma requests associated with? - /** Destroys a previously created dma request object */ @@ -141,7 +139,7 @@ TInt CookieToChannelIndex(TUint aDriverCookie) const; TInt CookieToRequestIndex(TUint aRequestCookie) const; - void FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const; + void MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const; TInt FragmentRequest(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TBool aLegacy=ETrue); TInt QueueRequest(TUint aRequestCookie, TRequestStatus* aStatus, TCallbackRecord* aRecord, TUint64* aDurationMicroSecs); @@ -177,6 +175,19 @@ TUint64 GetDuration() {return iStopwatch.ReadMicroSecs();} + /** + Store a copy of the TDmaTransferArgs which was used for fragmentation + for argument checking + */ + void SetAddressParms(const TDmaTransferArgs& aAddressParms) + {iFragmentedTransfer = aAddressParms;} + + /** + Retrieve stored TDmaTransferArgs + */ + const TDmaTransferArgs& GetAddressParms() const + {return iFragmentedTransfer;} + protected: TInt Create(); /** Construct with old style callback */ @@ -202,6 +213,13 @@ TStopwatch iStopwatch; TIsrRequeArgsSet iIsrRequeArgSet; + + /** + This will be updated each time fragment is called. + It is required so that, at queue time, if ISR re-queue + arguments are added, they can be checked for sanity + */ + TDmaTransferArgs iFragmentedTransfer; }; DClientDmaRequest* DClientDmaRequest::Construct(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TBool aNewStyle, TInt aMaxTransferSize) @@ -341,38 +359,7 @@ #endif } -/** -Check that both source and destination of ISR reque args will -lie within the range specified by aStart and aSize. - -@param aStart The linear base address of the region -@param aSize The size of the region -*/ -TBool TIsrRequeArgs::CheckRange(TLinAddr aStart, TUint aSize) const - { - TUint physStart = Epoc::LinearToPhysical(aStart); - TEST_ASSERT(physStart != KPhysAddrInvalid); - - TAddrRange chunk(physStart, aSize); - TBool sourceOk = (iSrcAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(SourceRange()); - - TBool destOk = (iDstAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(DestRange()); - - return sourceOk && destOk; - } - -TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize) const - { - for(TInt i=0; i openArgsBuf; + Kern::KUDesGet(openArgsBuf, *reinterpret_cast(a2)); + + SCreateInfoTest& openTestInfo = openArgsBuf(); + openInfo.iCookie = openTestInfo.iCookie; + openInfo.iDesCount = openTestInfo.iDesCount; + openInfo.iDfcQ = iDfcQ; + openInfo.iDfcPriority = openTestInfo.iDfcPriority; + + #ifdef DMA_APIV2 + openInfo.iPriority = openTestInfo.iPriority; + openInfo.iDynChannel = openTestInfo.iDynChannel; + #endif + + TInt r = OpenDmaChannel(driverCookie, openInfo); + umemput32(a1, &driverCookie, sizeof(TAny*)); + Kern::KUDesPut(*reinterpret_cast(a2), openArgsBuf); + return r; + } case RDmaSession::ECloseChannel: { TUint driverCookie = reinterpret_cast(a1); @@ -660,11 +673,15 @@ TDmaTransferArgs& transferArgs = const_cast(argsBuff().iTransferArgs); //convert address offsets in to kernel virtual addresses - FixupTransferArgs(transferArgs); - - TEST_ASSERT((TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size()))); + MakeAddressesAbsoulute(transferArgs); TInt r = KErrGeneral; + if (!TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size())) + { + // Return error code for invalid src and destination arguments used in tranferArgs + r=KErrArgument; + return r; + } TStopwatch clock; clock.Start(); @@ -708,7 +725,6 @@ } case RDmaSession::EQueueRequestWithReque: { - //TODO can common code with EQueueRequest be extracted? TPckgBuf argsBuff; Kern::KUDesGet(argsBuff, *reinterpret_cast(a1)); @@ -723,13 +739,11 @@ DClientDmaRequest* const request = RequestFromCookie(requestCookie); if(request != NULL) { - argsBuff().iRequeSet.Fixup(iChunkBase); - //TODO reque args must be substituted in order to - //check the range. The original transfer args are not - //available when queue is called, they could - //however be stored within DClientDmaRequest - //TEST_ASSERT((argsBuff().iRequeSet.CheckRange(iChunkBase, iChunk->Size()))); - request->AddRequeArgs(argsBuff().iRequeSet); + TIsrRequeArgsSet& requeArgs = argsBuff().iRequeSet; + requeArgs.Fixup(iChunkBase); + + TEST_ASSERT(requeArgs.CheckRange(iChunkBase, iChunk->Size(), request->GetAddressParms() )); + request->AddRequeArgs(requeArgs); r = QueueRequest(requestCookie, requestStatus, callbackRec, duration); } @@ -740,21 +754,6 @@ } return r; } - case RDmaSession::EIsrRedoRequest: - { - TPckgBuf argsBuff; - Kern::KUDesGet(argsBuff, *reinterpret_cast(a1)); - - const TUint driverCookie = argsBuff().iDriverCookie; - const TUint32 srcAddr = argsBuff().iSrcAddr; - const TUint32 dstAddr = argsBuff().iDstAddr; - const TInt transferCount = argsBuff().iTransferCount; - const TUint32 pslRequestInfo = argsBuff().iPslRequestInfo; - const TBool isrCb = argsBuff().iIsrCb; - - TInt r = IsrRedoRequestByCookie(driverCookie,srcAddr,dstAddr,transferCount,pslRequestInfo,isrCb); - return r; - } case RDmaSession::EIsOpened: { TUint driverCookie = (TUint)a1; @@ -797,29 +796,21 @@ } } -TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie ) +TInt DDmaTestSession::OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo) { - TDmaChannel::SCreateInfo info; - info.iCookie = aPslCookie; - info.iDfcQ = iDfcQ; - info.iDfcPriority = 3; - info.iDesCount = 128; - - TDmaChannel* channel = NULL; - //cs so thread can't be killed between //opening channel and adding to array NKern::ThreadEnterCS(); - TInt r = TDmaChannel::Open(info, channel); + TDmaChannel* channel = NULL; + TInt r = TDmaChannel::Open(aInfo, channel); if(KErrNone == r) { __NK_ASSERT_ALWAYS(channel); - - __KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel)); + + __KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel)); - - TInt err = iChannels.Append(channel); - if(KErrNone == err) + r = iChannels.Append(channel); + if(KErrNone == r) { aDriverCookie = reinterpret_cast(channel); } @@ -834,6 +825,20 @@ return r; } +/** +Open a DMA channel with arbitrary default parameters +*/ +TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie ) + { + TDmaChannel::SCreateInfo info; + info.iCookie = aPslCookie; + info.iDfcQ = iDfcQ; + info.iDfcPriority = 3; + info.iDesCount = 128; + + return OpenDmaChannel(aDriverCookie, info); + } + TInt DDmaTestSession::CookieToChannelIndex(TUint aDriverCookie) const { const TInt r = iChannels.Find(reinterpret_cast(aDriverCookie)); @@ -906,8 +911,7 @@ __KTRACE_OPT(KDMA, Kern::Printf("CancelAllByIndex: %d", aIndex)); __NK_ASSERT_DEBUG(aIndex < iChannels.Count()); - TDmaChannel* channel = iChannels[aIndex]; - iChannels.Remove(aIndex); + TDmaChannel* channel = iChannels[aIndex]; channel->CancelAll(); } @@ -1188,7 +1192,11 @@ return r; } -void DDmaTestSession::FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const +/** +Replace addresses specified as an offset from the chunk base with absolute +virtual addresses. +*/ +void DDmaTestSession::MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const { aTransferArgs.iSrcConfig.iAddr += iChunkBase; aTransferArgs.iDstConfig.iAddr += iChunkBase; @@ -1225,23 +1233,29 @@ if(requestIndex < 0) return requestIndex; + DClientDmaRequest& request = *iClientDmaReqs[requestIndex]; + request.SetAddressParms(aTransferArgs); + TInt r = KErrNotSupported; + + if (aTransferArgs.iTransferCount < 1) + { + // Return error code for invalid transfer size used in tranferArgs + r=KErrArgument; + return r; + } + if(aLegacy) { - // TODO we can extract the required info from the struct to - // set flags TUint flags = KDmaMemSrc | KDmaIncSrc | KDmaMemDest | KDmaIncDest; - const TUint src = aTransferArgs.iSrcConfig.iAddr; const TUint dst = aTransferArgs.iDstConfig.iAddr; - r = iClientDmaReqs[requestIndex]->Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL); + r = request.Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL); } else { #ifdef DMA_APIV2 - r = iClientDmaReqs[requestIndex]->Fragment(aTransferArgs); -#else - r = KErrNotSupported; + r = request.Fragment(aTransferArgs); #endif } return r; @@ -1296,9 +1310,6 @@ for(TInt i=0; i