1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of "Eclipse Public License v1.0" |
4 // under the terms of "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
28 #ifdef __KERNEL_MODE__ |
28 #ifdef __KERNEL_MODE__ |
29 #include <nkern.h> |
29 #include <nkern.h> |
30 #include <kernel.h> |
30 #include <kernel.h> |
31 #define TEST_FAULT FAULT(); |
31 #define TEST_FAULT FAULT(); |
32 #define PRINT(N) Kern::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
32 #define PRINT(N) Kern::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
|
33 #define PRINTF(X) Kern::Printf X ; |
33 #else |
34 #else |
34 #include <e32std.h> |
35 #include <e32std.h> |
35 #include <e32debug.h> |
36 #include <e32debug.h> |
36 #define TEST_FAULT RDebug::Printf("Assertion failure in %s, %d", __FILE__, __LINE__); User::Invariant() |
37 #define TEST_FAULT {RDebug::Printf("Assertion failure in %s, %d", __FILE__, __LINE__); User::Invariant();} |
37 #define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
38 #define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
|
39 #define PRINTF(X) RDebug::Printf X ; |
38 #endif |
40 #endif |
39 |
41 |
40 #define TEST_ASSERT(C) if(!(C)) {TEST_FAULT;} |
42 #define TEST_ASSERT(C) if(!(C)) {TEST_FAULT;} |
41 |
43 |
42 const TUint KPhysAddrInvalidUser=0xFFFFFFFFu; // KPhysAddrInvalid is not defined on the user side |
44 const TUint KPhysAddrInvalidUser=0xFFFFFFFFu; // KPhysAddrInvalid is not defined on the user side |
43 #ifdef __KERNEL_MODE__ |
45 #ifdef __KERNEL_MODE__ |
44 //if this fails then KPhysAddrInvalidUser must be updated to match |
46 //if this fails then KPhysAddrInvalidUser must be updated to match |
45 //KPhysAddrInvalid |
47 //KPhysAddrInvalid |
46 __ASSERT_COMPILE(KPhysAddrInvalidUser == KPhysAddrInvalid); |
48 __ASSERT_COMPILE(KPhysAddrInvalidUser == KPhysAddrInvalid); |
|
49 #else |
|
50 const TUint KPhysAddrInvalid = KPhysAddrInvalidUser; |
47 #endif |
51 #endif |
48 |
52 |
|
53 #ifdef __KERNEL_MODE__ |
|
54 //Function to format the output. |
|
55 inline void DmaAppendFormat(TDes8& aBuf, const char* aFmt, ...) |
|
56 { |
|
57 if(!(&aBuf)) |
|
58 return; |
|
59 VA_LIST list; |
|
60 VA_START(list,aFmt); |
|
61 Kern::AppendFormat(aBuf,aFmt,list); |
|
62 } |
|
63 #endif |
49 |
64 |
50 _LIT(KTestDmaLddName, "TestDmaV2"); |
65 _LIT(KTestDmaLddName, "TestDmaV2"); |
51 |
66 |
52 inline TVersion TestDmaLddVersion() { return TVersion(1, 0, 1); } |
67 inline TVersion TestDmaLddVersion() { return TVersion(1, 0, 1); } |
53 |
68 |
155 |
170 |
156 TInt iPILVersion; |
171 TInt iPILVersion; |
157 }; |
172 }; |
158 |
173 |
159 |
174 |
|
175 /** SCreateInfo for opening DMA - Reused for testing */ |
|
176 struct SCreateInfoTest |
|
177 { |
|
178 /** Default constructor. Initializes all fields with meaningful default |
|
179 values. |
|
180 |
|
181 Must be inline (for now) because exporting it would break existing |
|
182 custom DMA libs as their clients would need the export which would |
|
183 be missing from the custom .def files. |
|
184 */ |
|
185 SCreateInfoTest() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {}; |
|
186 |
|
187 /** Identifier used by PSL to select channel to open */ |
|
188 TUint32 iCookie; |
|
189 /** Number of descriptors this channel can use. |
|
190 |
|
191 This number is not used in the upgraded version of the DMA |
|
192 framework and is kept there only for source compatibility. If the |
|
193 client is certain that it will only ever use that version, then the |
|
194 value passed here doesn't matter - the framework will ignore it. |
|
195 |
|
196 @deprecated |
|
197 */ |
|
198 TInt iDesCount; |
|
199 /** DFC queue used to service DMA interrupts. |
|
200 |
|
201 The DFC thread priority must be higher than any client thread |
|
202 priority to avoid a situation where a transfer completes while |
|
203 being cancelled and another transfer is started before the DFC |
|
204 thread gets a chance to run. This would lead to a stray DFC. |
|
205 */ |
|
206 //TDfcQue* iDfcQ; |
|
207 |
|
208 TAny* iDfcQ; |
|
209 |
|
210 /** DFC priority */ |
|
211 TUint8 iDfcPriority; |
|
212 /** Used by PSL to configure a channel priority (if possible). |
|
213 |
|
214 The default is KDmaPriorityNone (the don't care value). |
|
215 |
|
216 @see TDmaPriority |
|
217 */ |
|
218 TUint iPriority; |
|
219 /** Request a dynamic DMA channel. |
|
220 |
|
221 If this is set to ETrue then the Open call is for a 'dynamic' as |
|
222 opposed to a static and solely owned DMA channel. A number of |
|
223 properties of the opened TDmaChannel object will be different in |
|
224 that case. |
|
225 |
|
226 The default value is EFalse. |
|
227 */ |
|
228 TBool iDynChannel; |
|
229 }; |
|
230 |
|
231 |
160 class TDmaChannel; |
232 class TDmaChannel; |
161 |
233 |
162 struct TAddrRange |
234 struct TAddrRange |
163 { |
235 { |
164 TAddrRange(TUint aStart, TUint aLength); |
236 TAddrRange(TUint aStart, TUint aLength); |
167 |
239 |
168 inline TBool Contains(TUint aValue) const {return Rng(iStart, aValue, End());} |
240 inline TBool Contains(TUint aValue) const {return Rng(iStart, aValue, End());} |
169 TBool Contains(TAddrRange aRange) const; |
241 TBool Contains(TAddrRange aRange) const; |
170 |
242 |
171 TBool Overlaps(const TAddrRange& aRange) const; |
243 TBool Overlaps(const TAddrRange& aRange) const; |
|
244 TBool IsFilled(TUint8 aValue) const; |
|
245 |
172 static void SelfTest(); |
246 static void SelfTest(); |
173 |
247 |
174 private: |
248 private: |
175 TUint iStart; |
249 TUint iStart; |
176 TUint iLength; |
250 TUint iLength; |
188 iDstAddr(aArgs.iDstConfig.iAddr), |
262 iDstAddr(aArgs.iDstConfig.iAddr), |
189 iTransferCount(aArgs.iTransferCount) |
263 iTransferCount(aArgs.iTransferCount) |
190 {} |
264 {} |
191 |
265 |
192 /** |
266 /** |
193 If any src, dst, or transfer count are zero, substitute the values from |
267 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
194 aTransferArgs in their place |
268 the default values used for IsrRedoRequest) then substitute the values from |
|
269 aTransferArgs. |
195 */ |
270 */ |
196 void Substitute(const TDmaTransferArgs& aTransferArgs); |
271 void Substitute(const TDmaTransferArgs& aTransferArgs); |
197 |
272 |
198 /** |
273 /** |
199 When recieved by the test driver, src and dst |
274 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
|
275 the default values used for IsrRedoRequest) then substitute the values from |
|
276 aTransferArgs. |
|
277 */ |
|
278 void Substitute(const TAddressParms& aTransferArgs); |
|
279 |
|
280 /** |
|
281 When received by the test driver, src and dst |
200 addresses will be offsets from the dma test session's |
282 addresses will be offsets from the dma test session's |
201 chunk base. They must be converted to absolute, *physical* addresses |
283 chunk base. They must be converted to absolute, *physical* addresses |
202 */ |
284 */ |
203 void Fixup(TLinAddr aChunkBase); |
285 void Fixup(TLinAddr aChunkBase); |
204 |
286 |
213 |
295 |
214 TBool Overlaps(const TAddrRange aRange) const; |
296 TBool Overlaps(const TAddrRange aRange) const; |
215 TBool Overlaps(const TAddressParms aParm) const; |
297 TBool Overlaps(const TAddressParms aParm) const; |
216 |
298 |
217 TBool operator==(const TAddressParms& aOther) const; |
299 TBool operator==(const TAddressParms& aOther) const; |
|
300 |
|
301 |
|
302 /** |
|
303 Produce a printable representation |
|
304 */ |
|
305 void AppendString(TDes& aBuf) const |
|
306 { |
|
307 _LIT(KOutput, "TAddressParms: src=0x%08x (%d) dst=0x%08x (%d) count=0x%08x (%d)\0"); |
|
308 #ifdef __KERNEL_MODE__ |
|
309 DmaAppendFormat(aBuf, (const char*)KOutput().Ptr(), iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount); |
|
310 #else |
|
311 aBuf.AppendFormat(KOutput, iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount); |
|
312 #endif |
|
313 } |
|
314 |
|
315 void MakePhysical(); |
218 |
316 |
219 static void SelfTest(); |
317 static void SelfTest(); |
220 |
318 |
221 TUint32 iSrcAddr; |
319 TUint32 iSrcAddr; |
222 TUint32 iDstAddr; |
320 TUint32 iDstAddr; |
253 /** |
351 /** |
254 A collection of TIsrRequeArgs |
352 A collection of TIsrRequeArgs |
255 */ |
353 */ |
256 struct TIsrRequeArgsSet |
354 struct TIsrRequeArgsSet |
257 { |
355 { |
258 |
356 friend class CIsrRequeTest; |
259 friend class CIsrRequeTest; //TODO see line 394 t_dma2.cpp |
|
260 TIsrRequeArgsSet(TIsrRequeArgs* aRequeueArgs=NULL, TInt aCount =0) |
357 TIsrRequeArgsSet(TIsrRequeArgs* aRequeueArgs=NULL, TInt aCount =0) |
261 :iCount(aCount), iIndex(0) |
358 :iCount(aCount), iIndex(0) |
262 { |
359 { |
263 TEST_ASSERT(iCount <= MaxCount); |
360 TEST_ASSERT(iCount <= MaxCount); |
264 for(TInt i=0; i<iCount; i++) |
361 for(TInt i=0; i<iCount; i++) |
271 TBool IsEmpty() const |
368 TBool IsEmpty() const |
272 {return iCount == 0;} |
369 {return iCount == 0;} |
273 |
370 |
274 TIsrRequeArgs GetArgs(); |
371 TIsrRequeArgs GetArgs(); |
275 |
372 |
|
373 /** |
|
374 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
|
375 the default values used for IsrRedoRequest) then substitute the appropriate |
|
376 value from the previous argument struct. aTransferArgs is used to |
|
377 substitute values for the initial argument struct. |
|
378 */ |
276 void Substitute(const TDmaTransferArgs& aTransferArgs); |
379 void Substitute(const TDmaTransferArgs& aTransferArgs); |
277 void Fixup(TLinAddr aChunkBase); |
380 void Fixup(TLinAddr aChunkBase); |
278 TBool CheckRange(TLinAddr aAddr, TUint aSize) const; |
381 TBool CheckRange(TLinAddr aAddr, TUint aSize) const; |
279 |
382 |
|
383 /** |
|
384 Check that all re-queue parameters will remain within the region defined |
|
385 by aAddr and aSize. This overload assumes that the requeue parameters have |
|
386 not been substituted hence the data in aInitialParms is required. |
|
387 |
|
388 @param aInitialParms The original transfer that the re-queues in this set are based on |
|
389 */ |
|
390 TBool CheckRange(TLinAddr aAddr, TUint aSize, const TDmaTransferArgs& aInitialParms) const; |
|
391 |
|
392 static void SelfTest(); |
280 private: |
393 private: |
281 enum {MaxCount=6}; |
394 enum {MaxCount=6}; |
282 TInt iCount; |
395 TInt iCount; |
283 TInt iIndex; |
396 TInt iIndex; |
284 TIsrRequeArgs iRequeArgs[MaxCount]; |
397 TIsrRequeArgs iRequeArgs[MaxCount]; |
298 TInt ChannelIsOpened(TUint aDriverCookie,TBool &aChannelOpen) |
411 TInt ChannelIsOpened(TUint aDriverCookie,TBool &aChannelOpen) |
299 { |
412 { |
300 return DoControl(EIsOpened, reinterpret_cast<TAny*>(aDriverCookie), &aChannelOpen); |
413 return DoControl(EIsOpened, reinterpret_cast<TAny*>(aDriverCookie), &aChannelOpen); |
301 } |
414 } |
302 |
415 |
303 TInt ChannelIsrRedoRequest(TUint aDriverCookie,TUint32 aSrcAddr,TUint32 aDstAddr,TInt aTransferCount,TUint32 aPslRequestInfo,TBool aIsrCb) |
|
304 { |
|
305 TIsrRedoReqArgs args(aDriverCookie,aSrcAddr,aDstAddr,aTransferCount,aPslRequestInfo,aIsrCb); |
|
306 TPckgC<TIsrRedoReqArgs> package(args); |
|
307 return DoControl(EIsrRedoRequest,&package); |
|
308 } |
|
309 |
|
310 TInt ChannelCancelAll(TUint aDriverCookie) |
416 TInt ChannelCancelAll(TUint aDriverCookie) |
311 { |
417 { |
312 return DoControl(ECancelAllChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
418 return DoControl(ECancelAllChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
313 } |
419 } |
314 |
420 |
315 TInt ChannelOpen(TUint aPslCookie, TUint& aDriverCookie) |
421 TInt ChannelOpen(TUint aPslCookie, TUint& aDriverCookie) |
316 { |
422 { |
317 return DoControl(EOpenChannel, reinterpret_cast<TAny*>(aPslCookie), &aDriverCookie); |
423 return DoControl(EOpenChannel, reinterpret_cast<TAny*>(aPslCookie), &aDriverCookie); |
|
424 } |
|
425 |
|
426 TInt ChannelOpen(TUint& aDriverCookie, SCreateInfoTest& aInfo) |
|
427 { |
|
428 TPckg<SCreateInfoTest> package(aInfo); |
|
429 return DoControl(EOpenChannelExposed,&aDriverCookie, &package); |
318 } |
430 } |
319 |
431 |
320 TInt ChannelClose(TUint aDriverCookie) |
432 TInt ChannelClose(TUint aDriverCookie) |
321 { |
433 { |
322 return DoControl(ECloseChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
434 return DoControl(ECloseChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
345 TPckg<TDmacTestCaps> package(aChannelCaps); |
457 TPckg<TDmacTestCaps> package(aChannelCaps); |
346 return DoControl(EChannelCaps, reinterpret_cast<TAny*>(aDriverCookie), &package); |
458 return DoControl(EChannelCaps, reinterpret_cast<TAny*>(aDriverCookie), &package); |
347 } |
459 } |
348 |
460 |
349 TInt Open() |
461 TInt Open() |
350 {// TO DO: Add Info , this class is just to test the opening of channels |
462 { |
351 //TPckgBuf<TOpenInfo> infoBuf; |
|
352 //infoBuf().iWhat = TOpenInfo::EOpen; |
|
353 //infoBuf().U.iOpen.iId = aId; |
|
354 //infoBuf().U.iOpen.iDesCount = aDesCount; |
|
355 //infoBuf().U.iOpen.iMaxTransferSize = aMaxTransferSize; |
|
356 return DoCreate(KTestDmaLddName,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); |
463 return DoCreate(KTestDmaLddName,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); |
357 } |
464 } |
358 |
465 |
359 //TODO rename this (append "old") |
466 |
360 TInt RequestCreate(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
467 TInt RequestCreateOld(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
361 { |
468 { |
362 return DoRequestCreate(aChannelCookie, EFalse, aMaxTransferSize, aRequestCookie); |
469 return DoRequestCreate(aChannelCookie, EFalse, aMaxTransferSize, aRequestCookie); |
363 } |
470 } |
364 |
471 |
365 //TODO rename this (get rid of "new" |
472 |
366 TInt RequestCreateNew(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
473 TInt RequestCreate(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
367 { |
474 { |
368 return DoRequestCreate(aChannelCookie, ETrue, aMaxTransferSize, aRequestCookie); |
475 return DoRequestCreate(aChannelCookie, ETrue, aMaxTransferSize, aRequestCookie); |
369 } |
476 } |
370 |
477 |
371 TInt RequestDestroy(TUint aRequestCookie) |
478 TInt RequestDestroy(TUint aRequestCookie) |
405 //(TClientDataRequest can not be programmed with a NULL to |
512 //(TClientDataRequest can not be programmed with a NULL to |
406 //indicate that an argument is unwanted) |
513 //indicate that an argument is unwanted) |
407 TCallbackRecord dummyRec; |
514 TCallbackRecord dummyRec; |
408 TUint64 dummyTime=0; |
515 TUint64 dummyTime=0; |
409 |
516 |
|
517 aStatus = KRequestPending; |
|
518 |
410 TQueueArgs args(aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
519 TQueueArgs args(aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
411 TPckgC<TQueueArgs> package(args); |
520 TPckgC<TQueueArgs> package(args); |
412 return DoControl(EQueueRequest, &package); |
521 return DoControl(EQueueRequest, &package); |
413 } |
522 } |
414 |
523 |
436 //if the client does not want them. |
545 //if the client does not want them. |
437 //(TClientDataRequest can not be programmed with a NULL to |
546 //(TClientDataRequest can not be programmed with a NULL to |
438 //indicate that an argument is unwanted) |
547 //indicate that an argument is unwanted) |
439 TCallbackRecord dummyRec; |
548 TCallbackRecord dummyRec; |
440 TUint64 dummyTime=0; |
549 TUint64 dummyTime=0; |
|
550 |
|
551 aStatus = KRequestPending; |
441 |
552 |
442 TQueueArgsWithReque args(aRequeueArgs, aCount, aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
553 TQueueArgsWithReque args(aRequeueArgs, aCount, aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
443 TPckgC<TQueueArgsWithReque> package(args); |
554 TPckgC<TQueueArgsWithReque> package(args); |
444 return DoControl(EQueueRequestWithReque, &package); |
555 return DoControl(EQueueRequestWithReque, &package); |
445 } |
556 } |
516 TRequestStatus* iStatus; |
627 TRequestStatus* iStatus; |
517 TCallbackRecord* iCallbackRecord; |
628 TCallbackRecord* iCallbackRecord; |
518 TUint64* iDurationMicroSecs; |
629 TUint64* iDurationMicroSecs; |
519 }; |
630 }; |
520 |
631 |
521 struct TIsrRedoReqArgs |
|
522 { |
|
523 TIsrRedoReqArgs(TUint aDriverCookie=0,TUint32 aSrcAddr=0, TUint32 aDstAddr=0, TInt aTransferCount=0, TUint32 aPslRequestInfo=0,TBool aIsrCb=ETrue) |
|
524 :iDriverCookie(aDriverCookie),iSrcAddr(aSrcAddr),iDstAddr(aDstAddr),iTransferCount(aTransferCount),iPslRequestInfo(aPslRequestInfo),iIsrCb(aIsrCb) |
|
525 {} |
|
526 TUint iDriverCookie; |
|
527 TUint32 iSrcAddr; |
|
528 TUint32 iDstAddr; |
|
529 TInt iTransferCount; |
|
530 TUint32 iPslRequestInfo; |
|
531 TBool iIsrCb; |
|
532 }; |
|
533 |
|
534 /** |
632 /** |
535 This struct is used for queing and including a set of transfers |
633 This struct is used for queing and including a set of transfers |
536 to be setup from ISR context callback |
634 to be setup from ISR context callback |
537 */ |
635 */ |
538 struct TQueueArgsWithReque : public TQueueArgs |
636 struct TQueueArgsWithReque : public TQueueArgs |