|
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 } |