bsptemplate/asspandvariant/template_assp/dmapsl_v2.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
child 258 880ff05ad710
child 263 9e2d4f7f5028
--- 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 <kernel/kern_priv.h>
-#include <template_assp.h>									// /assp/template_assp/
-
-#include <drivers/dma.h>
-#include <drivers/dma_hai.h>
-
-
-// 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<TUint8>(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<TUint8>(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<TUint8>(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<TUint8>(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<const TTemplateSgChannel&>(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::AppendHwDes"));
-	}
-
-
-void TTemplateDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& aHdr)
-//
-// Unlink the last item in the h/w descriptor chain from a subsequent chain that it was
-// possibly linked to.
-//
-	{
- 	__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<TTemplateDmac*>(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<TDmaDesc*>(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<TUint32>(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();
-	}