1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/dmav2/d_dma2_cmn.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,328 @@
1.4 +/*
1.5 +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description: Implmentation of DMAv2 test code, common
1.18 +* to both user and kernel side
1.19 +*
1.20 +*/
1.21 +#ifdef __KERNEL_MODE__
1.22 +#include <platform.h>
1.23 +#endif
1.24 +
1.25 +#include "d_dma2.h"
1.26 +
1.27 +TInt Log2(TInt aNum)
1.28 + {
1.29 + TInt res = -1;
1.30 + while(aNum)
1.31 + {
1.32 + res++;
1.33 + aNum >>= 1;
1.34 + }
1.35 + return res;
1.36 + }
1.37 +
1.38 +TCallbackRecord::TCallbackRecord(
1.39 + TCbContext aContext,
1.40 + TInt aReq,
1.41 + TInt aReqSrc,
1.42 + TInt aReqDst,
1.43 + TInt aDes,
1.44 + TInt aDesSrc,
1.45 + TInt aDesDst,
1.46 + TInt aFrame,
1.47 + TInt aFrameSrc,
1.48 + TInt aFrameDst,
1.49 + TInt aPause,
1.50 + TInt aPauseSrc,
1.51 + TInt aPauseDst,
1.52 + TDmaResult aResult
1.53 + )
1.54 + //Default iIsrRedoRequestResult is 1 as this is an invalid error code
1.55 + :iResult(aResult), iContext(aContext), iIsrRedoRequestResult(1)
1.56 + {
1.57 + SetCount(EDmaCallbackRequestCompletion, aReq);
1.58 + SetCount(EDmaCallbackRequestCompletion_Src, aReqSrc);
1.59 + SetCount(EDmaCallbackRequestCompletion_Dst, aReqDst);
1.60 + SetCount(EDmaCallbackDescriptorCompletion, aDes);
1.61 + SetCount(EDmaCallbackDescriptorCompletion_Src, aDesSrc);
1.62 + SetCount(EDmaCallbackDescriptorCompletion_Dst, aDesDst);
1.63 + SetCount(EDmaCallbackFrameCompletion, aFrame);
1.64 + SetCount(EDmaCallbackFrameCompletion_Src, aFrameSrc);
1.65 + SetCount(EDmaCallbackFrameCompletion_Dst, aFrameDst);
1.66 + SetCount(EDmaCallbackLinkedListPaused, aPause);
1.67 + SetCount(EDmaCallbackLinkedListPaused_Src, aPauseSrc);
1.68 + SetCount(EDmaCallbackLinkedListPaused_Dst, aPauseDst);
1.69 + }
1.70 +
1.71 +TCallbackRecord TCallbackRecord::Empty()
1.72 + {
1.73 + return TCallbackRecord(EInvalid,0,0,0,0,0,0,0,0,0,0,0,0,EDmaResultError);
1.74 + }
1.75 +
1.76 +void TCallbackRecord::Reset()
1.77 + {
1.78 + new (this) TCallbackRecord();
1.79 + }
1.80 +
1.81 +TBool TCallbackRecord::operator == (const TCallbackRecord aOther) const
1.82 + {
1.83 + return (memcompare((TUint8*)this, sizeof(*this), (TUint8*)&aOther, sizeof(aOther)) == 0);
1.84 + }
1.85 +
1.86 +TInt TCallbackRecord::GetCount(TDmaCallbackType aCbType) const
1.87 + {
1.88 + const TInt index = BitToIndex(aCbType);
1.89 + return iCallbackLog[index];
1.90 + }
1.91 +
1.92 +void TCallbackRecord::SetCount(TDmaCallbackType aCbType, TInt aCount)
1.93 + {
1.94 + const TInt index = BitToIndex(aCbType);
1.95 + iCallbackLog[index] = aCount;
1.96 + }
1.97 +
1.98 +TInt TCallbackRecord::BitToIndex(TDmaCallbackType aCbType) const
1.99 + {
1.100 + const TInt index = Log2(aCbType);
1.101 + TEST_ASSERT(index >=0 && index < KNumberOfCallbacks);
1.102 +
1.103 + return index;
1.104 + }
1.105 +
1.106 +void TCallbackRecord::ProcessCallback(TUint aCallbackMask, TDmaResult aResult)
1.107 + {
1.108 + // This function may be called several
1.109 + // times and will accumulate the number of each callback
1.110 + // received. However, it will only ever remember the last
1.111 + // result and context value,
1.112 + iResult = aResult;
1.113 + iContext = CurrentContext();
1.114 + TEST_ASSERT(iContext != EInvalid);
1.115 +
1.116 + for(TInt i=0; i < KNumberOfCallbacks; i++)
1.117 + {
1.118 + if(aCallbackMask & 1)
1.119 + {
1.120 + iCallbackLog[i]++;
1.121 + }
1.122 + aCallbackMask >>= 1;
1.123 + }
1.124 + // Assert that we have handled all bits
1.125 + // if not then maybe KNumberOfCallbacks is too small
1.126 + // or there is a spurious bit in aCallbackMask
1.127 + TEST_ASSERT(aCallbackMask == 0);
1.128 + }
1.129 +
1.130 +TCallbackRecord::TCbContext TCallbackRecord::CurrentContext() const
1.131 + {
1.132 +#ifdef __KERNEL_MODE__
1.133 + switch(NKern::CurrentContext())
1.134 + {
1.135 + case NKern::EThread:
1.136 + return EThread;
1.137 + case NKern::EInterrupt:
1.138 + return EIsr;
1.139 + case NKern::EIDFC: //fall-through
1.140 + case NKern::EEscaped:
1.141 + default:
1.142 + return EInvalid;
1.143 + }
1.144 +#else
1.145 + //for the benefit of user-mode testing
1.146 + return EThread;
1.147 +#endif
1.148 + }
1.149 +
1.150 +void TCallbackRecord::Print() const
1.151 + {
1.152 + PRINT(GetCount(EDmaCallbackRequestCompletion));
1.153 + PRINT(GetCount(EDmaCallbackRequestCompletion_Src));
1.154 + PRINT(GetCount(EDmaCallbackRequestCompletion_Dst));
1.155 + PRINT(GetCount(EDmaCallbackDescriptorCompletion));
1.156 + PRINT(GetCount(EDmaCallbackDescriptorCompletion_Src));
1.157 + PRINT(GetCount(EDmaCallbackDescriptorCompletion_Dst));
1.158 + PRINT(GetCount(EDmaCallbackFrameCompletion));
1.159 + PRINT(GetCount(EDmaCallbackFrameCompletion_Src));
1.160 + PRINT(GetCount(EDmaCallbackFrameCompletion_Dst));
1.161 + PRINT(GetCount(EDmaCallbackLinkedListPaused));
1.162 + PRINT(GetCount(EDmaCallbackLinkedListPaused_Src));
1.163 + PRINT(GetCount(EDmaCallbackLinkedListPaused_Dst));
1.164 + PRINT(iResult);
1.165 + PRINT(iContext);
1.166 + PRINT(iIsrRedoRequestResult);
1.167 + }
1.168 +
1.169 +TDmacTestCaps::TDmacTestCaps()
1.170 + :iPILVersion(1)
1.171 + {
1.172 + }
1.173 +
1.174 +TDmacTestCaps::TDmacTestCaps(const SDmacCaps& aDmacCaps, TInt aVersion)
1.175 + :SDmacCaps(aDmacCaps), iPILVersion(aVersion)
1.176 + {}
1.177 +
1.178 +TAddrRange::TAddrRange(TUint aStart, TUint aLength)
1.179 + :iStart(aStart), iLength(aLength)
1.180 + {
1.181 + TEST_ASSERT(iLength > 0);
1.182 + }
1.183 +
1.184 +TBool TAddrRange::Contains(TAddrRange aRange) const
1.185 + {
1.186 + return Contains(aRange.Start()) && Contains(aRange.End());
1.187 + }
1.188 +
1.189 +TBool TAddrRange::Overlaps(const TAddrRange& aRange) const
1.190 + {
1.191 + return (aRange.Contains(iStart) || aRange.Contains(End()) ||
1.192 + Contains(aRange.Start()) || Contains(aRange.End()));
1.193 + }
1.194 +/**
1.195 +If addresses have been left as KPhysAddrInvalid or the count as 0
1.196 +(ie. the default values used for IsrRedoRequest)
1.197 +then substitute the values from aTransferArgs.
1.198 +*/
1.199 +void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs)
1.200 + {
1.201 + if(iSrcAddr == KPhysAddrInvalidUser)
1.202 + iSrcAddr = aTransferArgs.iSrcConfig.iAddr;
1.203 +
1.204 + if(iDstAddr == KPhysAddrInvalidUser)
1.205 + iDstAddr = aTransferArgs.iDstConfig.iAddr;
1.206 +
1.207 + if(iTransferCount == 0)
1.208 + iTransferCount = aTransferArgs.iTransferCount;
1.209 + }
1.210 +
1.211 +/**
1.212 +Addresses are converted into absolute,
1.213 +addresses (virtual in user mode, physical in kernel)
1.214 +unless they are KPhysAddrInvalid
1.215 +*/
1.216 +void TAddressParms::Fixup(TLinAddr aChunkBase)
1.217 + {
1.218 + if(iSrcAddr != KPhysAddrInvalidUser)
1.219 + {
1.220 + iSrcAddr += aChunkBase;
1.221 +
1.222 +#ifdef __KERNEL_MODE__
1.223 + iSrcAddr = Epoc::LinearToPhysical(iSrcAddr);
1.224 + TEST_ASSERT(iSrcAddr != KPhysAddrInvalid);
1.225 +#endif
1.226 + }
1.227 +#ifndef __KERNEL_MODE__
1.228 + else
1.229 + {
1.230 + // Substitute must be called before
1.231 + // Fixup on user side
1.232 + TEST_FAULT;
1.233 + }
1.234 +#endif
1.235 +
1.236 + if(iDstAddr != KPhysAddrInvalidUser)
1.237 + {
1.238 + iDstAddr += aChunkBase;
1.239 +
1.240 +#ifdef __KERNEL_MODE__
1.241 + iDstAddr = Epoc::LinearToPhysical(iDstAddr);
1.242 + TEST_ASSERT(iDstAddr != KPhysAddrInvalid);
1.243 +#endif
1.244 + }
1.245 +#ifndef __KERNEL_MODE__
1.246 + else
1.247 + {
1.248 + // Substitute must be called before
1.249 + // Fixup on user side
1.250 + TEST_FAULT;
1.251 + }
1.252 +#endif
1.253 + }
1.254 +
1.255 +TBool TAddressParms::CheckRange(TLinAddr aStart, TUint aSize)
1.256 + {
1.257 + TAddrRange chunk(aStart, aSize);
1.258 + return chunk.Contains(SourceRange()) && chunk.Contains(DestRange());
1.259 + }
1.260 +
1.261 +/**
1.262 +@return ETrue if the source or destination range of this object
1.263 +overlaps with aRange
1.264 +*/
1.265 +TBool TAddressParms::Overlaps(const TAddrRange aRange) const
1.266 + {
1.267 + return SourceRange().Overlaps(aRange) || DestRange().Overlaps(aRange);
1.268 + }
1.269 +
1.270 +/**
1.271 +@return ETrue if either the source or dest range of this
1.272 +overlap with either of those of aParm
1.273 +*/
1.274 +TBool TAddressParms::Overlaps(const TAddressParms aParm) const
1.275 + {
1.276 + return Overlaps(aParm.SourceRange()) || Overlaps(aParm.DestRange());
1.277 + }
1.278 +
1.279 +TBool TAddressParms::operator==(const TAddressParms& aOther) const
1.280 + {
1.281 + return iSrcAddr == aOther.iSrcAddr &&
1.282 + iDstAddr == aOther.iDstAddr &&
1.283 + iTransferCount == aOther.iTransferCount;
1.284 + }
1.285 +
1.286 +TAddressParms GetAddrParms(const TDmaTransferArgs& aArgs)
1.287 + {
1.288 + return TAddressParms(aArgs);
1.289 + }
1.290 +
1.291 +TAddrRange TAddressParms::SourceRange() const
1.292 + {
1.293 + return TAddrRange(iSrcAddr, iTransferCount);
1.294 + }
1.295 +
1.296 +TAddrRange TAddressParms::DestRange() const
1.297 + {
1.298 + return TAddrRange(iDstAddr, iTransferCount);
1.299 + }
1.300 +
1.301 +void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams)
1.302 + {
1.303 + aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr;
1.304 + aTransferArgs.iDstConfig.iAddr = aAddrParams.iDstAddr;
1.305 + aTransferArgs.iTransferCount = aAddrParams.iTransferCount;
1.306 + }
1.307 +
1.308 +TIsrRequeArgs TIsrRequeArgsSet::GetArgs()
1.309 + {
1.310 + TEST_ASSERT(!IsEmpty());
1.311 + const TIsrRequeArgs args(iRequeArgs[iIndex]);
1.312 + iIndex++;
1.313 + iCount--;
1.314 + return args;
1.315 + }
1.316 +
1.317 +
1.318 +void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs)
1.319 + {
1.320 + for(TInt i=0; i<iCount; i++)
1.321 + {
1.322 + iRequeArgs[i].Substitute(aTransferArgs);
1.323 + }
1.324 + }
1.325 +void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
1.326 + {
1.327 + for(TInt i=0; i<iCount; i++)
1.328 + {
1.329 + iRequeArgs[i].Fixup(aChunkBase);
1.330 + }
1.331 + }