diff -r c1f20ce4abcf -r 3e88ff8f41d5 kerneltest/e32test/dmav2/dma2_sim.cpp --- a/kerneltest/e32test/dmav2/dma2_sim.cpp Tue Aug 31 16:34:26 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,760 +0,0 @@ -// Copyright (c) 2010 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: -// os/kernelhwsrv/kerneltest/e32test/dmav2/dma2_sim.cpp -// Partial simulation of DMA2 PSL -// -// - - -#include - -#include -#include - -#include "d_dma2.h" - -// Debug support -static const char KDmaPanicCat[] = "DMA PSL - " __FILE__; - -static const TInt KMaxTransferLen = 0x1000; // max transfer length for this DMAC -static const TInt KMemAlignMask = 0; // memory addresses passed to DMAC must be multiple of 8 -static const TInt KDesCount = 160; // Initial DMA descriptor count - -#define TEST_RETURN(X) if (!(X))\ - {\ - __KTRACE_OPT(KPANIC, Kern::Printf("Simulated Dma test failure: " __FILE__ " line %d", __LINE__));\ - return KErrAbort;\ - } - -class TDmaDesc -// -// Hardware DMA descriptor -// - { -public: - enum {KStopBitMask = 1}; -public: - TPhysAddr iDescAddr; - TPhysAddr iSrcAddr; - TPhysAddr iDestAddr; - TUint32 iCmd; - }; - - -////////////////////////////////////////////////////////////////////////////// -// Test Support -////////////////////////////////////////////////////////////////////////////// - -/** -TO DO: Fill in to provide information to the V1 test harness (t_dma.exe) -*/ -TDmaTestInfo TestInfo = - { - 0, - 0, - 0, - 0, - NULL, - 0, - NULL, - 0, - NULL - }; - - -EXPORT_C const TDmaTestInfo& DmaTestInfo() -// -// -// - { - return TestInfo; - } - -/** -TO DO: Fill in to provide information to the V2 test harness (t_dma2.exe) -*/ -TDmaV2TestInfo TestInfov2 = - { - 0, - 0, - 0, - 0, - {0}, - 0, - {0}, - 1, - {0} - }; - -EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() - { - return TestInfov2; - } - - -////////////////////////////////////////////////////////////////////////////// -// Simulated channel -////////////////////////////////////////////////////////////////////////////// - -/** -An interface class to add simulation specific functionallity to any DMA channel -*/ -class MSimChannel - { -public: - virtual TInt PreOpen() =0; - virtual TDmaChannel& Channel() =0; - }; - -////////////////////////////////////////////////////////////////////////////// -// Derived Channel (Scatter/Gather) -////////////////////////////////////////////////////////////////////////////// - -const SDmacCaps KSimSgChanCaps = - {0, // TInt iChannelPriorities; - EFalse, // TBool iChannelPauseAndResume; - EFalse, // TBool iAddrAlignedToElementSize; - EFalse, // TBool i1DIndexAddressing; - EFalse, // TBool i2DIndexAddressing; - KDmaSyncAuto, // TUint iSynchronizationTypes; - KDmaBurstSizeAny, // TUint iBurstTransactions; - EFalse, // TBool iDescriptorInterrupt; - EFalse, // TBool iFrameInterrupt; - EFalse, // TBool iLinkedListPausedInterrupt; - EFalse, // TBool iEndiannessConversion; - KDmaGraphicsOpNone, // TUint iGraphicsOps; - EFalse, // TBool iRepeatingTransfers; - EFalse, // TBool iChannelLinking; - ETrue, // TBool iHwDescriptors; - EFalse, // TBool iSrcDstAsymmetry; - EFalse, // TBool iAsymHwDescriptors; - EFalse, // TBool iBalancedAsymSegments; - EFalse, // TBool iAsymCompletionInterrupt; - EFalse, // TBool iAsymDescriptorInterrupt; - EFalse, // TBool iAsymFrameInterrupt; - {0, 0, 0, 0, 0} // TUint32 iReserved[5]; - }; - -const SDmacCaps KSimSwChanCaps = - {0, // TInt iChannelPriorities; - EFalse, // TBool iChannelPauseAndResume; - EFalse, // TBool iAddrAlignedToElementSize; - EFalse, // TBool i1DIndexAddressing; - EFalse, // TBool i2DIndexAddressing; - KDmaSyncAuto, // TUint iSynchronizationTypes; - KDmaBurstSizeAny, // TUint iBurstTransactions; - EFalse, // TBool iDescriptorInterrupt; - EFalse, // TBool iFrameInterrupt; - EFalse, // TBool iLinkedListPausedInterrupt; - EFalse, // TBool iEndiannessConversion; - KDmaGraphicsOpNone, // TUint iGraphicsOps; - EFalse, // TBool iRepeatingTransfers; - EFalse, // TBool iChannelLinking; - EFalse, // TBool iHwDescriptors; - EFalse, // TBool iSrcDstAsymmetry; - EFalse, // TBool iAsymHwDescriptors; - EFalse, // TBool iBalancedAsymSegments; - EFalse, // TBool iAsymCompletionInterrupt; - EFalse, // TBool iAsymDescriptorInterrupt; - EFalse, // TBool iAsymFrameInterrupt; - {0, 0, 0, 0, 0} // TUint32 iReserved[5]; - }; - -class TEmptyChannel : public TDmaChannel, public MSimChannel - { -public: - // Virtual from TDmaChannel - void DoCancelAll(); - - void CallDefaultVirtuals(); - TInt CheckExtensionStubs(); - - // From MSimChannel - TInt PreOpen(); - TDmaChannel& Channel() {return *this;} - }; - -void TEmptyChannel::DoCancelAll() - { - __DMA_CANT_HAPPEN(); - } - -void TEmptyChannel::CallDefaultVirtuals() - { - DMA_PSL_TRACE("Calling default virtual TDmaChannel functions"); - - const DDmaRequest* req = NULL; - SDmaDesHdr* hdr = NULL; - - DoQueue(*req); - DoDfc(*req, hdr); - DoDfc(*req, hdr, hdr); - - QueuedRequestCountChanged(); - } - -TInt TEmptyChannel::CheckExtensionStubs() - { - DMA_PSL_TRACE("Calling extension stubs"); - - TInt r = Extension(0, NULL); - TEST_RETURN(r == KErrNotSupported) - - r = StaticExtension(0, NULL); - TEST_RETURN(r == KErrNotSupported) - - return KErrNone; - } - -TInt TEmptyChannel::PreOpen() - { - CallDefaultVirtuals(); - return CheckExtensionStubs(); - } - -////////////////////////////////////////////////////////////////////////////// -// Derived SkelControllerSw Class -////////////////////////////////////////////////////////////////////////////// - -class TSkelDmac : public TDmac - { -public: - TSkelDmac(const SCreateInfo& aInfo); - TInt Create(const SCreateInfo& aInfo); -private: - // from TDmac (PIL pure virtual) - virtual void StopTransfer(const TDmaChannel& aChannel); - virtual TBool IsIdle(const TDmaChannel& aChannel); - virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, - TUint aDstFlags, TUint32 aPslInfo); - virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, - TUint aDstFlags, TUint32 aPslInfo); - - inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); - - void CallDefaultVirtuals(); - TInt TestPool(); - -public: - static const SCreateInfo KDmacInfoHw; - static const SCreateInfo KDmacInfoSw; - - TEmptyChannel iChannel; - }; - - -const TDmac::SCreateInfo TSkelDmac::KDmacInfoHw = - { - ETrue, // iCapsHwDes - KDesCount, // iDesCount - sizeof(TDmaDesc), // iDesSize -#ifndef __WINS__ - EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs -#endif - }; - -const TDmac::SCreateInfo TSkelDmac::KDmacInfoSw = - { - EFalse, // iCapsHwDes - KDesCount, // iDesCount - sizeof(TDmaTransferArgs), // iDesSize -#ifndef __WINS__ - EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs -#endif - }; - -static TSkelDmac SkelControllerSw(TSkelDmac::KDmacInfoSw); -static TSkelDmac SkelControllerHw(TSkelDmac::KDmacInfoHw); - - -TSkelDmac::TSkelDmac(const SCreateInfo& aInfo) -// -// Constructor. -// - : TDmac(aInfo) - { - TInt r = Create(aInfo); - __NK_ASSERT_ALWAYS(r == KErrNone); - - CallDefaultVirtuals(); - r = TestPool(); - __NK_ASSERT_ALWAYS(r == KErrNone); - } - - -TInt TSkelDmac::Create(const SCreateInfo& aInfo) -// -// Second phase construction. -// - { - TInt r = TDmac::Create(aInfo); // Base class Create() - if (r == KErrNone) - { - __DMA_ASSERTA(ReserveSetOfDes(1) == KErrNone); - } - return r; - } - - -void TSkelDmac::StopTransfer(const TDmaChannel& aChannel) -// -// Stops a running channel. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - - __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::StopTransfer channel=%d (unsupported)", i)); - - (void) i; - - } - - -TBool TSkelDmac::IsIdle(const TDmaChannel& aChannel) -// -// Returns the state of a given channel. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - - __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::IsIdle channel=%d (unsupported)", i)); - - // TO DO (for instance): Return the state of the RUN bit of the channel. - // The return value should reflect the actual state. - (void) i; - - return ETrue; - } - - -TUint TSkelDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, - TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) -// -// Returns the maximum transfer length in bytes for a given transfer. -// - { - // TO DO: Determine the proper return value, based on the arguments. - - // For instance: - return KMaxTransferLen; - } - - -TUint TSkelDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, - TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) -// -// Returns the memory buffer alignment restrictions mask for a given transfer. -// - { - // TO DO: Determine the proper return value, based on the arguments. - - // For instance: - return KMemAlignMask; - } - - -inline TDmaDesc* TSkelDmac::HdrToHwDes(const SDmaDesHdr& aHdr) -// -// Changes return type of base class call. -// - { - return static_cast(TDmac::HdrToHwDes(aHdr)); - } - -/** -Call the default virtual functions on the TDmac, -that would never otherwise be called - -*/ -void TSkelDmac::CallDefaultVirtuals() - { - DMA_PSL_TRACE("Calling default virtual TDmac functions"); - - TDmaChannel* channel = NULL; - SDmaDesHdr* hdr = NULL; - - Transfer(*channel, *hdr); - Transfer(*channel, *hdr, *hdr); - - const TDmaTransferArgs args; - TInt r = KErrNone; - - r = InitHwDes(*hdr, args); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - r = InitSrcHwDes(*hdr, args); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - r = InitDstHwDes(*hdr, args); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - r = UpdateHwDes(*hdr, KPhysAddrInvalid, KPhysAddrInvalid, 0, 0); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - r = UpdateSrcHwDes(*hdr, KPhysAddrInvalid, 0, 0); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - r = UpdateDstHwDes(*hdr, KPhysAddrInvalid, 0, 0); - __NK_ASSERT_ALWAYS(r == KErrGeneral); - - ChainHwDes(*hdr, *hdr); - AppendHwDes(*channel, *hdr, *hdr); - AppendHwDes(*channel, *hdr, *hdr, *hdr, *hdr); - UnlinkHwDes(*channel, *hdr); - - TUint32 count = 0; - - count = HwDesNumDstElementsTransferred(*hdr); - __NK_ASSERT_ALWAYS(count == 0); - - count = HwDesNumSrcElementsTransferred(*hdr); - __NK_ASSERT_ALWAYS(count == 0); - } - -TInt TSkelDmac::TestPool() - { - DMA_PSL_TRACE("TSkelDmac::TestPool()"); - TInt count = 0; - SDmaDesHdr* hdr = iFreeHdr; - TAny* des = iDesPool; - - TInt r = KErrNone; - while(hdr->iNext) - { - TAny* receivedDes = NULL; - if(iCapsHwDes) - { - receivedDes = HdrToHwDes(*hdr); - } - else - { - TDmaTransferArgs& args = HdrToDes(*hdr); - receivedDes = &args; - } - - if(receivedDes != des) - { - DMA_PSL_TRACE1("TSkelDmac::TestPool() failure: count=%d", count); - r = KErrGeneral; - break; - } - - hdr = hdr->iNext; - des = (TAny*)((TUint)des + iDesSize); - count++; - } - - if(count != (KDesCount - 1)) - { - DMA_PSL_TRACE2("TSkelDmac::TestPool() failure: count = %d != (iMaxDesCount -1) = %d", count, KDesCount-1); - r = KErrUnknown; - } - return r; - } - -////////////////////////////////////////////////////////////////////////////// -// Simulated Fragmentation Dmac -////////////////////////////////////////////////////////////////////////////// - - -const SDmacCaps KSimAsymmChanCaps = - {0, // TInt iChannelPriorities; - EFalse, // TBool iChannelPauseAndResume; - EFalse, // TBool iAddrAlignedToElementSize; - EFalse, // TBool i1DIndexAddressing; - EFalse, // TBool i2DIndexAddressing; - KDmaSyncAuto, // TUint iSynchronizationTypes; - KDmaBurstSizeAny, // TUint iBurstTransactions; - EFalse, // TBool iDescriptorInterrupt; - EFalse, // TBool iFrameInterrupt; - EFalse, // TBool iLinkedListPausedInterrupt; - EFalse, // TBool iEndiannessConversion; - KDmaGraphicsOpNone, // TUint iGraphicsOps; - EFalse, // TBool iRepeatingTransfers; - EFalse, // TBool iChannelLinking; - ETrue, // TBool iHwDescriptors; - EFalse, // TBool iSrcDstAsymmetry; - ETrue, // TBool iAsymHwDescriptors; - EFalse, // TBool iBalancedAsymSegments; - EFalse, // TBool iAsymCompletionInterrupt; - EFalse, // TBool iAsymDescriptorInterrupt; - EFalse, // TBool iAsymFrameInterrupt; - {0, 0, 0, 0, 0} // TUint32 iReserved[5]; - }; - -const SDmacCaps KSimAsymmBalancedChanCaps = - {0, // TInt iChannelPriorities; - EFalse, // TBool iChannelPauseAndResume; - EFalse, // TBool iAddrAlignedToElementSize; - EFalse, // TBool i1DIndexAddressing; - EFalse, // TBool i2DIndexAddressing; - KDmaSyncAuto, // TUint iSynchronizationTypes; - KDmaBurstSizeAny, // TUint iBurstTransactions; - EFalse, // TBool iDescriptorInterrupt; - EFalse, // TBool iFrameInterrupt; - EFalse, // TBool iLinkedListPausedInterrupt; - EFalse, // TBool iEndiannessConversion; - KDmaGraphicsOpNone, // TUint iGraphicsOps; - EFalse, // TBool iRepeatingTransfers; - EFalse, // TBool iChannelLinking; - ETrue, // TBool iHwDescriptors; - EFalse, // TBool iSrcDstAsymmetry; - ETrue, // TBool iAsymHwDescriptors; - ETrue, // TBool iBalancedAsymSegments; - EFalse, // TBool iAsymCompletionInterrupt; - EFalse, // TBool iAsymDescriptorInterrupt; - EFalse, // TBool iAsymFrameInterrupt; - {0, 0, 0, 0, 0} // TUint32 iReserved[5]; - }; - - -class TAsymmDmac : public TDmac - { - struct THwDes - { - TUint iAddr; - TUint iLength; - TUint iCookie; - }; -public: - TAsymmDmac(); - TInt Create(); -private: - // Work around for compiler which forbids this - // class from accessing the protected, nested TDmac::SCreateInfo - using TDmac::SCreateInfo; - - // from TDmac (PIL pure virtual) - virtual void StopTransfer(const TDmaChannel& aChannel); - virtual TBool IsIdle(const TDmaChannel& aChannel); - virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, - TUint aDstFlags, TUint32 aPslInfo); - virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, - TUint aDstFlags, TUint32 aPslInfo); - // from TDmac (PIL virtual) - TInt InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); - TInt InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); - - void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); - void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); - - inline THwDes* HdrToHwDes(const SDmaDesHdr& aHdr); - -private: - static const SCreateInfo KInfo; -public: - static const TInt iChannelCount; - TEmptyChannel iChannel; - }; - -const TAsymmDmac::SCreateInfo TAsymmDmac::KInfo = - { - ETrue, // iCapsHwDes - KDesCount, // iDesCount - sizeof(THwDes), // iDesSize -#ifndef __WINS__ - EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs -#endif - }; - -const TInt TAsymmDmac::iChannelCount = 1; - -static TAsymmDmac AsymController; - -TAsymmDmac::TAsymmDmac() -// -// Constructor. -// - : TDmac(KInfo) - { - TInt r = Create(); - __NK_ASSERT_ALWAYS(r == KErrNone); - } - - -TInt TAsymmDmac::Create() -// -// Second phase construction. -// - { - TInt r = TDmac::Create(KInfo); // Base class Create() - if (r == KErrNone) - { - __DMA_ASSERTA(ReserveSetOfDes(iChannelCount) == KErrNone); - } - return r; - } - - -void TAsymmDmac::StopTransfer(const TDmaChannel& /*aChannel*/) -// -// Stops a running channel. -// - { - __DMA_CANT_HAPPEN(); - } - - -TBool TAsymmDmac::IsIdle(const TDmaChannel& /*aChannel*/) -// -// Returns the state of a given channel. -// - { - __DMA_CANT_HAPPEN(); - return ETrue; - } - - -TUint TAsymmDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, - TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) -// -// Returns the maximum transfer length in bytes for a given transfer. -// - { - // TO DO: Determine the proper return value, based on the arguments. - - // For instance: - return KMaxTransferLen; - } - - -TUint TAsymmDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, - TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) -// -// Returns the memory buffer alignment restrictions mask for a given transfer. -// - { - // TO DO: Determine the proper return value, based on the arguments. - - // For instance: - return KMemAlignMask; - } - - -inline TAsymmDmac::THwDes* TAsymmDmac::HdrToHwDes(const SDmaDesHdr& aHdr) -// -// Changes return type of base class call. -// - { - return static_cast(TDmac::HdrToHwDes(aHdr)); - } - -TInt TAsymmDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) - { - return KErrNone; - } - -TInt TAsymmDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) - { - return KErrNone; - } - -void TAsymmDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) - { - } - -void TAsymmDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) - { - } - - - -////////////////////////////////////////////////////////////////////////////// -// Channel Opening/Closing (Channel Allocator) -////////////////////////////////////////////////////////////////////////////// - -struct TChanEntry - { - TChanEntry(TDmac& aController, MSimChannel& aChannel, const SDmacCaps& aCaps) - : - iController(aController), - iSimChannel(aChannel), - iCaps(aCaps) - {} - - TDmac& iController; - MSimChannel& iSimChannel; - const SDmacCaps& iCaps; - }; - -const TChanEntry ChannelTable[] = - { - TChanEntry(SkelControllerSw, SkelControllerSw.iChannel, KSimSwChanCaps), - TChanEntry(SkelControllerHw, SkelControllerHw.iChannel, KSimSgChanCaps), - TChanEntry(AsymController, AsymController.iChannel, KSimAsymmChanCaps), - TChanEntry(AsymController, AsymController.iChannel, KSimAsymmBalancedChanCaps) - }; - -static const TInt KChannelCount = ARRAY_LENGTH(ChannelTable); - -TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/) -// -// -// - { - __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId)); - - __DMA_ASSERTA(aOpenId < static_cast(KChannelCount)); - - const TChanEntry& entry = ChannelTable[aOpenId]; - TDmaChannel* pC = &entry.iSimChannel.Channel(); - if (pC->IsOpened()) - { - pC = NULL; - } - else - { - pC->iController = &entry.iController; - pC->iPslId = aOpenId; - pC->iDmacCaps = &entry.iCaps; - - // It is safe to signal here, - // setting iController marks the channel - // as taken - Signal(); - - TInt r = entry.iSimChannel.PreOpen(); - - Wait(); - - // If there was an error - // Close channel after retaking mutex - if(r != KErrNone) - { - pC->iController = NULL; - pC = NULL; - } - - - } - return pC; - } - - -void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/) -// -// -// - { - // NOP - } - - -TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/) -// -// -// - { - return KErrNotSupported; - }