diff -r c1f20ce4abcf -r 3e88ff8f41d5 bsptemplate/asspandvariant/template_assp/dmapsl_v2.cpp --- a/bsptemplate/asspandvariant/template_assp/dmapsl_v2.cpp Tue Aug 31 16:34:26 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,480 +0,0 @@ -// Copyright (c) 2004-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: -// bsptemplate/asspvariant/template_assp/dmapsl_v2.cpp -// Template DMA Platform Specific Layer (PSL). -// -// - - -#include -#include // /assp/template_assp/ - -#include -#include - - -// Debug support -static const char KDmaPanicCat[] = "DMA PSL - " __FILE__; - -static const TInt KMaxTransferLen = 0x1FE0; // max transfer length for this DMAC -static const TInt KMemAlignMask = 7; // memory addresses passed to DMAC must be multiple of 8 -static const TInt KChannelCount = 16; // we got 16 channels -static const TInt KDesCount = 160; // Initial DMA descriptor count - - -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}, - 0, - {0} - }; - -EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() - { - return TestInfov2; - } - -////////////////////////////////////////////////////////////////////////////// -// Helper Functions -////////////////////////////////////////////////////////////////////////////// - -inline TBool IsHwDesAligned(TAny* aDes) -// -// Checks whether given hardware descriptor is 16-bytes aligned. -// - { - return ((TLinAddr)aDes & 0xF) == 0; - } - - -static TUint32 DmaCmdReg(TUint aCount, TUint aFlags, TUint32 aSrcPslInfo, TUint32 aDstPslInfo) -// -// Returns value to set in DMA command register or in descriptor command field. -// - { - // TO DO: Construct CMD word from input values. - // The return value should reflect the actual control word. - return (aCount | aFlags | aSrcPslInfo | aDstPslInfo); - } - - -////////////////////////////////////////////////////////////////////////////// -// Derived Channel (Scatter/Gather) -////////////////////////////////////////////////////////////////////////////// - -class TTemplateSgChannel : public TDmaSgChannel - { -public: - TDmaDesc* iTmpDes; - TPhysAddr iTmpDesPhysAddr; - }; - - -////////////////////////////////////////////////////////////////////////////// -// Derived Controller Class -////////////////////////////////////////////////////////////////////////////// - -class TTemplateDmac : public TDmac - { -public: - TTemplateDmac(); - TInt Create(); -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); - // from TDmac (PIL virtual) - virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr); - virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs); - virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); - virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, - const SDmaDesHdr& aNewHdr); - virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); - // other - static void Isr(TAny* aThis); - inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); -private: - static const SCreateInfo KInfo; -public: - TTemplateSgChannel iChannels[KChannelCount]; - }; - - -static TTemplateDmac Controller; - - -const TDmac::SCreateInfo TTemplateDmac::KInfo = - { - ETrue, // iCapsHwDes - KDesCount, // iDesCount - sizeof(TDmaDesc), // iDesSize - EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs - }; - - -TTemplateDmac::TTemplateDmac() -// -// Constructor. -// - : TDmac(KInfo) - {} - - -TInt TTemplateDmac::Create() -// -// Second phase construction. -// - { - TInt r = TDmac::Create(KInfo); // Base class Create() - if (r == KErrNone) - { - __DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone); - for (TInt i=0; i < KChannelCount; ++i) - { - TDmaDesc* pD = HdrToHwDes(*iFreeHdr); - iChannels[i].iTmpDes = pD; - iChannels[i].iTmpDesPhysAddr = HwDesLinToPhys(pD); - iFreeHdr = iFreeHdr->iNext; - } - r = Interrupt::Bind(EAsspIntIdDma, Isr, this); - if (r == KErrNone) - { - // TO DO: Map DMA clients (requests) to DMA channels here. - - r = Interrupt::Enable(EAsspIntIdDma); - } - } - return r; - } - - -void TTemplateDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) -// -// Initiates a (previously constructed) request on a specific channel. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - TDmaDesc* pD = HdrToHwDes(aHdr); - - __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::Transfer channel=%d des=0x%08X", i, pD)); - - // TO DO (for instance): Load the first descriptor address into the DMAC and start it - // by setting the RUN bit. - (void) *pD, (void) i; - - } - - -void TTemplateDmac::StopTransfer(const TDmaChannel& aChannel) -// -// Stops a running channel. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - - __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::StopTransfer channel=%d", i)); - - // TO DO (for instance): Clear the RUN bit of the channel. - (void) i; - - } - - -TBool TTemplateDmac::IsIdle(const TDmaChannel& aChannel) -// -// Returns the state of a given channel. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - - __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::IsIdle channel=%d", 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 TTemplateDmac::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 TTemplateDmac::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; - } - - -TInt TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs) -// -// Sets up (from a passed in request) the descriptor with that fragment's -// source and destination address, the fragment size, and the (driver/DMA -// controller) specific transfer parameters (mem/peripheral, burst size, -// transfer width). -// - { - TDmaDesc* pD = HdrToHwDes(aHdr); - - __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD)); - - // Unaligned descriptor? Bug in generic layer! - __DMA_ASSERTD(IsHwDesAligned(pD)); - - const TDmaTransferConfig& src = aTransferArgs.iSrcConfig; - const TDmaTransferConfig& dst = aTransferArgs.iDstConfig; - pD->iSrcAddr = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr); - __DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid); - pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr); - __DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid); - pD->iCmd = DmaCmdReg(aTransferArgs.iTransferCount, aTransferArgs.iFlags, - src.iPslTargetInfo, dst.iPslTargetInfo); - pD->iDescAddr = TDmaDesc::KStopBitMask; - - return KErrNone; - } - - -void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr) -// -// Chains hardware descriptors together by setting the next pointer of the original descriptor -// to the physical address of the descriptor to be chained. -// - { - TDmaDesc* pD = HdrToHwDes(aHdr); - TDmaDesc* pN = HdrToHwDes(aNextHdr); - - __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::ChainHwDes des=0x%08X next des=0x%08X", pD, pN)); - - // Unaligned descriptor? Bug in generic layer! - __DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN)); - - // TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer. - - pD->iDescAddr = HwDesLinToPhys(pN); - } - - -void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, - const SDmaDesHdr& aNewHdr) -// -// Appends a descriptor to the chain while the channel is running. -// - { - const TUint8 i = static_cast(aChannel.PslId()); - - TDmaDesc* pL = HdrToHwDes(aLastHdr); - TDmaDesc* pN = HdrToHwDes(aNewHdr); - - __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X", - i, pL, pN)); - // Unaligned descriptor? Bug in generic layer! - __DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN)); - - TPhysAddr newPhys = HwDesLinToPhys(pN); - - const TInt irq = NKern::DisableAllInterrupts(); - StopTransfer(aChannel); - - pL->iDescAddr = newPhys; - const TTemplateSgChannel& channel = static_cast(aChannel); - TDmaDesc* pD = channel.iTmpDes; - - // TO DO: Implement the appropriate algorithm for appending a descriptor here. - (void) *pD, (void) i; - - NKern::RestoreInterrupts(irq); - - __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::UnlinkHwDes")); - TDmaDesc* pD = HdrToHwDes(aHdr); - pD->iDescAddr = TDmaDesc::KStopBitMask; - - // TO DO: Modify pD->iCmd so that an end-of-transfer interrupt will get raised. - - } - - -void TTemplateDmac::Isr(TAny* aThis) -// -// This ISR reads the interrupt identification and calls back into the base class -// interrupt service handler with the channel identifier and an indication whether the -// transfer completed correctly or with an error. -// - { - TTemplateDmac& me = *static_cast(aThis); - - // TO DO: Implement the behaviour described above, call HandleIsr(). - - HandleIsr(me.iChannels[5], EDmaCallbackRequestCompletion, ETrue); // Example - - } - - -inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr) -// -// Changes return type of base class call. -// - { - return static_cast(TDmac::HdrToHwDes(aHdr)); - } - - -////////////////////////////////////////////////////////////////////////////// -// Channel Opening/Closing (Channel Allocator) -////////////////////////////////////////////////////////////////////////////// - -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)); - - TDmaChannel* pC = Controller.iChannels + aOpenId; - if (pC->IsOpened()) - { - pC = NULL; - } - else - { - pC->iController = &Controller; - pC->iPslId = aOpenId; - } - - return pC; - } - - -void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/) -// -// -// - { - // NOP - } - - -TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/) -// -// -// - { - return KErrNotSupported; - } - - -////////////////////////////////////////////////////////////////////////////// -// DLL Exported Function -////////////////////////////////////////////////////////////////////////////// - -DECLARE_STANDARD_EXTENSION() -// -// Creates and initializes a new DMA controller object on the kernel heap. -// - { - __KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension")); - - const TInt r = DmaChannelMgr::Initialise(); - if (r != KErrNone) - { - return r; - } - return Controller.Create(); - }