kerneltest/e32test/dmav2/d_dma2_cmn.cpp
changeset 45 329ab0095843
child 130 c30940f6d922
equal deleted inserted replaced
44:36bfc973b146 45:329ab0095843
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implmentation of DMAv2 test code, common
       
    15 * to both user and kernel side
       
    16 *
       
    17 */
       
    18 #ifdef __KERNEL_MODE__
       
    19 #include <platform.h>
       
    20 #endif
       
    21 
       
    22 #include "d_dma2.h"
       
    23 
       
    24 TInt Log2(TInt aNum)
       
    25 	{
       
    26 	TInt res = -1;
       
    27 	while(aNum)
       
    28 		{
       
    29 		res++;
       
    30 		aNum >>= 1;
       
    31 		}
       
    32 	return res;
       
    33 	}
       
    34 
       
    35 TCallbackRecord::TCallbackRecord(
       
    36 		TCbContext aContext,
       
    37 		TInt aReq,
       
    38 		TInt aReqSrc,
       
    39 		TInt aReqDst,
       
    40 		TInt aDes,
       
    41 		TInt aDesSrc,
       
    42 		TInt aDesDst,
       
    43 		TInt aFrame,
       
    44 		TInt aFrameSrc,
       
    45 		TInt aFrameDst,
       
    46 		TInt aPause,
       
    47 		TInt aPauseSrc,
       
    48 		TInt aPauseDst,
       
    49 		TDmaResult aResult
       
    50 	)
       
    51 	//Default iIsrRedoRequestResult is 1 as this is an invalid error code
       
    52 	:iResult(aResult), iContext(aContext), iIsrRedoRequestResult(1)
       
    53 	{
       
    54 	SetCount(EDmaCallbackRequestCompletion, aReq);
       
    55 	SetCount(EDmaCallbackRequestCompletion_Src, aReqSrc);
       
    56 	SetCount(EDmaCallbackRequestCompletion_Dst, aReqDst);
       
    57 	SetCount(EDmaCallbackDescriptorCompletion, aDes);
       
    58 	SetCount(EDmaCallbackDescriptorCompletion_Src, aDesSrc);
       
    59 	SetCount(EDmaCallbackDescriptorCompletion_Dst, aDesDst);
       
    60 	SetCount(EDmaCallbackFrameCompletion, aFrame);
       
    61 	SetCount(EDmaCallbackFrameCompletion_Src, aFrameSrc);
       
    62 	SetCount(EDmaCallbackFrameCompletion_Dst, aFrameDst);
       
    63 	SetCount(EDmaCallbackLinkedListPaused, aPause);
       
    64 	SetCount(EDmaCallbackLinkedListPaused_Src, aPauseSrc);
       
    65 	SetCount(EDmaCallbackLinkedListPaused_Dst, aPauseDst);
       
    66 	}
       
    67 
       
    68 TCallbackRecord TCallbackRecord::Empty()
       
    69 	{
       
    70 	return TCallbackRecord(EInvalid,0,0,0,0,0,0,0,0,0,0,0,0,EDmaResultError);
       
    71 	}
       
    72 
       
    73 void TCallbackRecord::Reset()
       
    74 	{
       
    75 	new (this) TCallbackRecord();
       
    76 	}
       
    77 
       
    78 TBool TCallbackRecord::operator == (const TCallbackRecord aOther) const
       
    79 	{
       
    80 	return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0);
       
    81 	}
       
    82 
       
    83 TInt TCallbackRecord::GetCount(TDmaCallbackType aCbType) const
       
    84 	{
       
    85 	const TInt index = BitToIndex(aCbType);
       
    86 	return iCallbackLog[index];
       
    87 	}
       
    88 
       
    89 void TCallbackRecord::SetCount(TDmaCallbackType aCbType, TInt aCount)
       
    90 	{
       
    91 	const TInt index = BitToIndex(aCbType);
       
    92 	iCallbackLog[index] = aCount;
       
    93 	}
       
    94 
       
    95 TInt TCallbackRecord::BitToIndex(TDmaCallbackType aCbType) const
       
    96 	{
       
    97 	const TInt index = Log2(aCbType);
       
    98 	TEST_ASSERT(index >=0 && index < KNumberOfCallbacks);
       
    99 
       
   100 	return index;
       
   101 	}
       
   102 
       
   103 void TCallbackRecord::ProcessCallback(TUint aCallbackMask, TDmaResult aResult)
       
   104 	{
       
   105 	// This function may be called several
       
   106 	// times and will accumulate the number of each callback
       
   107 	// received. However, it will only ever remember the last
       
   108 	// result and context value,
       
   109 	iResult = aResult;
       
   110 	iContext = CurrentContext();
       
   111 	TEST_ASSERT(iContext != EInvalid);
       
   112 
       
   113 	for(TInt i=0; i < KNumberOfCallbacks; i++)
       
   114 		{
       
   115 		if(aCallbackMask & 1)
       
   116 			{
       
   117 			iCallbackLog[i]++;
       
   118 			}
       
   119 		aCallbackMask >>= 1;
       
   120 		}
       
   121 	// Assert that we have handled all bits
       
   122 	// if not then maybe KNumberOfCallbacks is too small
       
   123 	// or there is a spurious bit in aCallbackMask
       
   124 	TEST_ASSERT(aCallbackMask == 0);
       
   125 	}
       
   126 
       
   127 TCallbackRecord::TCbContext TCallbackRecord::CurrentContext() const
       
   128 	{
       
   129 #ifdef __KERNEL_MODE__
       
   130 	switch(NKern::CurrentContext())
       
   131 		{
       
   132 	case NKern::EThread:
       
   133 		return EThread;
       
   134 	case NKern::EInterrupt:
       
   135 		return EIsr;
       
   136 	case NKern::EIDFC: //fall-through
       
   137 	case NKern::EEscaped:
       
   138 	default:
       
   139 		return EInvalid;
       
   140 		}
       
   141 #else
       
   142 	//for the benefit of user-mode testing
       
   143 	return EThread;
       
   144 #endif
       
   145 	}
       
   146 
       
   147 void TCallbackRecord::Print() const
       
   148 	{
       
   149 	PRINT(GetCount(EDmaCallbackRequestCompletion));
       
   150 	PRINT(GetCount(EDmaCallbackRequestCompletion_Src));
       
   151 	PRINT(GetCount(EDmaCallbackRequestCompletion_Dst));
       
   152 	PRINT(GetCount(EDmaCallbackDescriptorCompletion));
       
   153 	PRINT(GetCount(EDmaCallbackDescriptorCompletion_Src));
       
   154 	PRINT(GetCount(EDmaCallbackDescriptorCompletion_Dst));
       
   155 	PRINT(GetCount(EDmaCallbackFrameCompletion));
       
   156 	PRINT(GetCount(EDmaCallbackFrameCompletion_Src));
       
   157 	PRINT(GetCount(EDmaCallbackFrameCompletion_Dst));
       
   158 	PRINT(GetCount(EDmaCallbackLinkedListPaused));
       
   159 	PRINT(GetCount(EDmaCallbackLinkedListPaused_Src));
       
   160 	PRINT(GetCount(EDmaCallbackLinkedListPaused_Dst));
       
   161 	PRINT(iResult);
       
   162 	PRINT(iContext);
       
   163 	PRINT(iIsrRedoRequestResult);
       
   164 	}
       
   165 
       
   166 TDmacTestCaps::TDmacTestCaps()
       
   167 	:iPILVersion(1)
       
   168 	{
       
   169 	}
       
   170 
       
   171 TDmacTestCaps::TDmacTestCaps(const SDmacCaps& aDmacCaps, TInt aVersion)
       
   172 	:SDmacCaps(aDmacCaps), iPILVersion(aVersion)
       
   173 	{}
       
   174 
       
   175 TAddrRange::TAddrRange(TUint aStart, TUint aLength)
       
   176 	:iStart(aStart), iLength(aLength)
       
   177 	{
       
   178 	TEST_ASSERT(iLength > 0);
       
   179 	}
       
   180 
       
   181 TBool TAddrRange::Contains(TAddrRange aRange) const
       
   182 	{
       
   183 	return Contains(aRange.Start()) && Contains(aRange.End());
       
   184 	}
       
   185 
       
   186 TBool TAddrRange::Overlaps(const TAddrRange& aRange) const
       
   187 	{
       
   188 	return (aRange.Contains(iStart) || aRange.Contains(End()) ||
       
   189 			Contains(aRange.Start()) || Contains(aRange.End()));
       
   190 	}
       
   191 /**
       
   192 If addresses have been left as KPhysAddrInvalid or the count as 0
       
   193 (ie. the default values used for IsrRedoRequest)
       
   194 then substitute the values from aTransferArgs.
       
   195 */
       
   196 void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs)
       
   197 	{
       
   198 	if(iSrcAddr == KPhysAddrInvalidUser)
       
   199 		iSrcAddr = aTransferArgs.iSrcConfig.iAddr;
       
   200 
       
   201 	if(iDstAddr == KPhysAddrInvalidUser)
       
   202 		iDstAddr = aTransferArgs.iDstConfig.iAddr;
       
   203 
       
   204 	if(iTransferCount == 0)
       
   205 		iTransferCount = aTransferArgs.iTransferCount;
       
   206 	}
       
   207 
       
   208 /**
       
   209 Addresses are converted into absolute,
       
   210 addresses (virtual in user mode, physical in kernel)
       
   211 unless they are KPhysAddrInvalid
       
   212 */
       
   213 void TAddressParms::Fixup(TLinAddr aChunkBase)
       
   214 	{
       
   215 	if(iSrcAddr != KPhysAddrInvalidUser)
       
   216 		{
       
   217 		iSrcAddr += aChunkBase;
       
   218 
       
   219 #ifdef __KERNEL_MODE__
       
   220 		iSrcAddr = Epoc::LinearToPhysical(iSrcAddr);
       
   221 		TEST_ASSERT(iSrcAddr != KPhysAddrInvalid);
       
   222 #endif
       
   223 		}
       
   224 #ifndef __KERNEL_MODE__
       
   225 	else
       
   226 		{
       
   227 		// Substitute must be called before
       
   228 		// Fixup on user side
       
   229 		TEST_FAULT;
       
   230 		}
       
   231 #endif
       
   232 
       
   233 	if(iDstAddr != KPhysAddrInvalidUser)
       
   234 		{
       
   235 		iDstAddr += aChunkBase;
       
   236 
       
   237 #ifdef __KERNEL_MODE__
       
   238 		iDstAddr = Epoc::LinearToPhysical(iDstAddr);
       
   239 		TEST_ASSERT(iDstAddr != KPhysAddrInvalid);
       
   240 #endif
       
   241 		}
       
   242 #ifndef __KERNEL_MODE__
       
   243 	else
       
   244 		{
       
   245 		// Substitute must be called before
       
   246 		// Fixup on user side
       
   247 		TEST_FAULT;
       
   248 		}
       
   249 #endif
       
   250 	}
       
   251 
       
   252 TBool TAddressParms::CheckRange(TLinAddr aStart, TUint aSize)
       
   253 	{
       
   254 	TAddrRange chunk(aStart, aSize);
       
   255 	return chunk.Contains(SourceRange()) && chunk.Contains(DestRange());
       
   256 	}
       
   257 
       
   258 /**
       
   259 @return ETrue if the source or destination range of this object
       
   260 overlaps with aRange
       
   261 */
       
   262 TBool TAddressParms::Overlaps(const TAddrRange aRange) const
       
   263 	{
       
   264 	return SourceRange().Overlaps(aRange) || DestRange().Overlaps(aRange);
       
   265 	}
       
   266 
       
   267 /**
       
   268 @return ETrue if either the source or dest range of this
       
   269 overlap with either of those of aParm
       
   270 */
       
   271 TBool TAddressParms::Overlaps(const TAddressParms aParm) const
       
   272 	{
       
   273 	return Overlaps(aParm.SourceRange()) || Overlaps(aParm.DestRange());
       
   274 	}
       
   275 
       
   276 TBool TAddressParms::operator==(const TAddressParms& aOther) const
       
   277 	{
       
   278 	return iSrcAddr == aOther.iSrcAddr &&
       
   279 		iDstAddr == aOther.iDstAddr &&
       
   280 		iTransferCount == aOther.iTransferCount;
       
   281 	}
       
   282 
       
   283 TAddressParms GetAddrParms(const TDmaTransferArgs& aArgs)
       
   284 	{
       
   285 	return TAddressParms(aArgs);
       
   286 	}
       
   287 
       
   288 TAddrRange TAddressParms::SourceRange() const
       
   289 	{
       
   290 	return TAddrRange(iSrcAddr, iTransferCount);
       
   291 	}
       
   292 
       
   293 TAddrRange TAddressParms::DestRange() const
       
   294 	{
       
   295 	return TAddrRange(iDstAddr, iTransferCount);
       
   296 	}
       
   297 
       
   298 void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams)
       
   299 	{
       
   300 	aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr;
       
   301 	aTransferArgs.iDstConfig.iAddr = aAddrParams.iDstAddr;
       
   302 	aTransferArgs.iTransferCount = aAddrParams.iTransferCount;
       
   303 	}
       
   304 
       
   305 TIsrRequeArgs TIsrRequeArgsSet::GetArgs()
       
   306 	{
       
   307 	TEST_ASSERT(!IsEmpty());
       
   308 	const TIsrRequeArgs args(iRequeArgs[iIndex]);
       
   309 	iIndex++;
       
   310 	iCount--;
       
   311 	return args;
       
   312 	}
       
   313 
       
   314 
       
   315 void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs)
       
   316 	{
       
   317 	for(TInt i=0; i<iCount; i++)
       
   318 		{
       
   319 		iRequeArgs[i].Substitute(aTransferArgs);
       
   320 		}
       
   321 	}
       
   322 void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
       
   323 	{
       
   324 	for(TInt i=0; i<iCount; i++)
       
   325 		{
       
   326 		iRequeArgs[i].Fixup(aChunkBase);
       
   327 		}
       
   328 	}