|
1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // os/kernelhwsrv/kerneltest/e32test/dmav2/dma2_sim.cpp |
|
15 // Partial simulation of DMA2 PSL |
|
16 // |
|
17 // |
|
18 |
|
19 |
|
20 #include <kernel/kern_priv.h> |
|
21 |
|
22 #include <drivers/dma.h> |
|
23 #include <drivers/dma_hai.h> |
|
24 |
|
25 #include "d_dma2.h" |
|
26 |
|
27 // Debug support |
|
28 static const char KDmaPanicCat[] = "DMA PSL - " __FILE__; |
|
29 |
|
30 static const TInt KMaxTransferLen = 0x1000; // max transfer length for this DMAC |
|
31 static const TInt KMemAlignMask = 0; // memory addresses passed to DMAC must be multiple of 8 |
|
32 static const TInt KDesCount = 160; // Initial DMA descriptor count |
|
33 |
|
34 class TDmaDesc |
|
35 // |
|
36 // Hardware DMA descriptor |
|
37 // |
|
38 { |
|
39 public: |
|
40 enum {KStopBitMask = 1}; |
|
41 public: |
|
42 TPhysAddr iDescAddr; |
|
43 TPhysAddr iSrcAddr; |
|
44 TPhysAddr iDestAddr; |
|
45 TUint32 iCmd; |
|
46 }; |
|
47 |
|
48 |
|
49 ////////////////////////////////////////////////////////////////////////////// |
|
50 // Test Support |
|
51 ////////////////////////////////////////////////////////////////////////////// |
|
52 |
|
53 /** |
|
54 TO DO: Fill in to provide information to the V1 test harness (t_dma.exe) |
|
55 */ |
|
56 TDmaTestInfo TestInfo = |
|
57 { |
|
58 0, |
|
59 0, |
|
60 0, |
|
61 0, |
|
62 NULL, |
|
63 0, |
|
64 NULL, |
|
65 0, |
|
66 NULL |
|
67 }; |
|
68 |
|
69 |
|
70 EXPORT_C const TDmaTestInfo& DmaTestInfo() |
|
71 // |
|
72 // |
|
73 // |
|
74 { |
|
75 return TestInfo; |
|
76 } |
|
77 |
|
78 /** |
|
79 TO DO: Fill in to provide information to the V2 test harness (t_dma2.exe) |
|
80 */ |
|
81 TDmaV2TestInfo TestInfov2 = |
|
82 { |
|
83 0, |
|
84 0, |
|
85 0, |
|
86 0, |
|
87 {0}, |
|
88 0, |
|
89 {0}, |
|
90 1, |
|
91 {0} |
|
92 }; |
|
93 |
|
94 EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() |
|
95 { |
|
96 return TestInfov2; |
|
97 } |
|
98 |
|
99 |
|
100 ////////////////////////////////////////////////////////////////////////////// |
|
101 // Simulated channel |
|
102 ////////////////////////////////////////////////////////////////////////////// |
|
103 |
|
104 class MSimChannel |
|
105 { |
|
106 public: |
|
107 virtual void PreOpen() {} |
|
108 }; |
|
109 |
|
110 ////////////////////////////////////////////////////////////////////////////// |
|
111 // Derived Channel (Scatter/Gather) |
|
112 ////////////////////////////////////////////////////////////////////////////// |
|
113 |
|
114 const SDmacCaps KSimSgChanCaps = |
|
115 {0, // TInt iChannelPriorities; |
|
116 EFalse, // TBool iChannelPauseAndResume; |
|
117 EFalse, // TBool iAddrAlignedToElementSize; |
|
118 EFalse, // TBool i1DIndexAddressing; |
|
119 EFalse, // TBool i2DIndexAddressing; |
|
120 KDmaSyncAuto, // TUint iSynchronizationTypes; |
|
121 KDmaBurstSizeAny, // TUint iBurstTransactions; |
|
122 EFalse, // TBool iDescriptorInterrupt; |
|
123 EFalse, // TBool iFrameInterrupt; |
|
124 EFalse, // TBool iLinkedListPausedInterrupt; |
|
125 EFalse, // TBool iEndiannessConversion; |
|
126 KDmaGraphicsOpNone, // TUint iGraphicsOps; |
|
127 EFalse, // TBool iRepeatingTransfers; |
|
128 EFalse, // TBool iChannelLinking; |
|
129 ETrue, // TBool iHwDescriptors; |
|
130 EFalse, // TBool iSrcDstAsymmetry; |
|
131 EFalse, // TBool iAsymHwDescriptors; |
|
132 EFalse, // TBool iBalancedAsymSegments; |
|
133 EFalse, // TBool iAsymCompletionInterrupt; |
|
134 EFalse, // TBool iAsymDescriptorInterrupt; |
|
135 EFalse, // TBool iAsymFrameInterrupt; |
|
136 {0, 0, 0, 0, 0} // TUint32 iReserved[5]; |
|
137 }; |
|
138 |
|
139 const SDmacCaps KSimSwChanCaps = |
|
140 {0, // TInt iChannelPriorities; |
|
141 EFalse, // TBool iChannelPauseAndResume; |
|
142 EFalse, // TBool iAddrAlignedToElementSize; |
|
143 EFalse, // TBool i1DIndexAddressing; |
|
144 EFalse, // TBool i2DIndexAddressing; |
|
145 KDmaSyncAuto, // TUint iSynchronizationTypes; |
|
146 KDmaBurstSizeAny, // TUint iBurstTransactions; |
|
147 EFalse, // TBool iDescriptorInterrupt; |
|
148 EFalse, // TBool iFrameInterrupt; |
|
149 EFalse, // TBool iLinkedListPausedInterrupt; |
|
150 EFalse, // TBool iEndiannessConversion; |
|
151 KDmaGraphicsOpNone, // TUint iGraphicsOps; |
|
152 EFalse, // TBool iRepeatingTransfers; |
|
153 EFalse, // TBool iChannelLinking; |
|
154 EFalse, // TBool iHwDescriptors; |
|
155 EFalse, // TBool iSrcDstAsymmetry; |
|
156 EFalse, // TBool iAsymHwDescriptors; |
|
157 EFalse, // TBool iBalancedAsymSegments; |
|
158 EFalse, // TBool iAsymCompletionInterrupt; |
|
159 EFalse, // TBool iAsymDescriptorInterrupt; |
|
160 EFalse, // TBool iAsymFrameInterrupt; |
|
161 {0, 0, 0, 0, 0} // TUint32 iReserved[5]; |
|
162 }; |
|
163 |
|
164 class TEmptyChannel : public TDmaChannel, public MSimChannel |
|
165 { |
|
166 public: |
|
167 // Virtual from TDmaChannel |
|
168 void DoCancelAll(); |
|
169 |
|
170 void CallDefaultVirtuals(); |
|
171 |
|
172 // From MSimChannel |
|
173 void PreOpen(); |
|
174 }; |
|
175 |
|
176 void TEmptyChannel::DoCancelAll() |
|
177 { |
|
178 __DMA_CANT_HAPPEN(); |
|
179 } |
|
180 |
|
181 void TEmptyChannel::CallDefaultVirtuals() |
|
182 { |
|
183 DMA_PSL_TRACE("Calling default virtual TDmaChannel functions"); |
|
184 |
|
185 const DDmaRequest* req = NULL; |
|
186 SDmaDesHdr* hdr = NULL; |
|
187 |
|
188 DoQueue(*req); |
|
189 DoDfc(*req, hdr); |
|
190 DoDfc(*req, hdr, hdr); |
|
191 |
|
192 QueuedRequestCountChanged(); |
|
193 } |
|
194 |
|
195 void TEmptyChannel::PreOpen() |
|
196 { |
|
197 CallDefaultVirtuals(); |
|
198 } |
|
199 |
|
200 ////////////////////////////////////////////////////////////////////////////// |
|
201 // Derived SkelControllerSw Class |
|
202 ////////////////////////////////////////////////////////////////////////////// |
|
203 |
|
204 class TSkelDmac : public TDmac |
|
205 { |
|
206 public: |
|
207 TSkelDmac(const SCreateInfo& aInfo); |
|
208 TInt Create(const SCreateInfo& aInfo); |
|
209 private: |
|
210 // from TDmac (PIL pure virtual) |
|
211 virtual void StopTransfer(const TDmaChannel& aChannel); |
|
212 virtual TBool IsIdle(const TDmaChannel& aChannel); |
|
213 virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, |
|
214 TUint aDstFlags, TUint32 aPslInfo); |
|
215 virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, |
|
216 TUint aDstFlags, TUint32 aPslInfo); |
|
217 |
|
218 inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); |
|
219 |
|
220 void CallDefaultVirtuals(); |
|
221 TInt TestPool(); |
|
222 |
|
223 public: |
|
224 static const SCreateInfo KDmacInfoHw; |
|
225 static const SCreateInfo KDmacInfoSw; |
|
226 |
|
227 TEmptyChannel iChannel; |
|
228 }; |
|
229 |
|
230 |
|
231 const TDmac::SCreateInfo TSkelDmac::KDmacInfoHw = |
|
232 { |
|
233 ETrue, // iCapsHwDes |
|
234 KDesCount, // iDesCount |
|
235 sizeof(TDmaDesc), // iDesSize |
|
236 #ifndef __WINS__ |
|
237 EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs |
|
238 #endif |
|
239 }; |
|
240 |
|
241 const TDmac::SCreateInfo TSkelDmac::KDmacInfoSw = |
|
242 { |
|
243 EFalse, // iCapsHwDes |
|
244 KDesCount, // iDesCount |
|
245 sizeof(TDmaTransferArgs), // iDesSize |
|
246 #ifndef __WINS__ |
|
247 EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs |
|
248 #endif |
|
249 }; |
|
250 |
|
251 static TSkelDmac SkelControllerSw(TSkelDmac::KDmacInfoSw); |
|
252 static TSkelDmac SkelControllerHw(TSkelDmac::KDmacInfoHw); |
|
253 |
|
254 |
|
255 TSkelDmac::TSkelDmac(const SCreateInfo& aInfo) |
|
256 // |
|
257 // Constructor. |
|
258 // |
|
259 : TDmac(aInfo) |
|
260 { |
|
261 // TODO remove this once DMAC can be created and destroyed from test LDD entry |
|
262 // point |
|
263 TInt r = Create(aInfo); |
|
264 __NK_ASSERT_ALWAYS(r == KErrNone); |
|
265 |
|
266 CallDefaultVirtuals(); |
|
267 r = TestPool(); |
|
268 __NK_ASSERT_ALWAYS(r == KErrNone); |
|
269 } |
|
270 |
|
271 |
|
272 TInt TSkelDmac::Create(const SCreateInfo& aInfo) |
|
273 // |
|
274 // Second phase construction. |
|
275 // |
|
276 { |
|
277 TInt r = TDmac::Create(aInfo); // Base class Create() |
|
278 if (r == KErrNone) |
|
279 { |
|
280 __DMA_ASSERTA(ReserveSetOfDes(1) == KErrNone); |
|
281 } |
|
282 return r; |
|
283 } |
|
284 |
|
285 |
|
286 void TSkelDmac::StopTransfer(const TDmaChannel& aChannel) |
|
287 // |
|
288 // Stops a running channel. |
|
289 // |
|
290 { |
|
291 const TUint8 i = static_cast<TUint8>(aChannel.PslId()); |
|
292 |
|
293 __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::StopTransfer channel=%d (unsupported)", i)); |
|
294 |
|
295 (void) i; |
|
296 |
|
297 } |
|
298 |
|
299 |
|
300 TBool TSkelDmac::IsIdle(const TDmaChannel& aChannel) |
|
301 // |
|
302 // Returns the state of a given channel. |
|
303 // |
|
304 { |
|
305 const TUint8 i = static_cast<TUint8>(aChannel.PslId()); |
|
306 |
|
307 __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::IsIdle channel=%d (unsupported)", i)); |
|
308 |
|
309 // TO DO (for instance): Return the state of the RUN bit of the channel. |
|
310 // The return value should reflect the actual state. |
|
311 (void) i; |
|
312 |
|
313 return ETrue; |
|
314 } |
|
315 |
|
316 |
|
317 TUint TSkelDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, |
|
318 TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) |
|
319 // |
|
320 // Returns the maximum transfer length in bytes for a given transfer. |
|
321 // |
|
322 { |
|
323 // TO DO: Determine the proper return value, based on the arguments. |
|
324 |
|
325 // For instance: |
|
326 return KMaxTransferLen; |
|
327 } |
|
328 |
|
329 |
|
330 TUint TSkelDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, |
|
331 TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) |
|
332 // |
|
333 // Returns the memory buffer alignment restrictions mask for a given transfer. |
|
334 // |
|
335 { |
|
336 // TO DO: Determine the proper return value, based on the arguments. |
|
337 |
|
338 // For instance: |
|
339 return KMemAlignMask; |
|
340 } |
|
341 |
|
342 |
|
343 inline TDmaDesc* TSkelDmac::HdrToHwDes(const SDmaDesHdr& aHdr) |
|
344 // |
|
345 // Changes return type of base class call. |
|
346 // |
|
347 { |
|
348 return static_cast<TDmaDesc*>(TDmac::HdrToHwDes(aHdr)); |
|
349 } |
|
350 |
|
351 /** |
|
352 Call the default virtual functions on the TDmac, |
|
353 that would never otherwise be called |
|
354 |
|
355 */ |
|
356 void TSkelDmac::CallDefaultVirtuals() |
|
357 { |
|
358 DMA_PSL_TRACE("Calling default virtual TDmac functions"); |
|
359 |
|
360 TDmaChannel* channel = NULL; |
|
361 SDmaDesHdr* hdr = NULL; |
|
362 |
|
363 Transfer(*channel, *hdr); |
|
364 Transfer(*channel, *hdr, *hdr); |
|
365 |
|
366 const TDmaTransferArgs args; |
|
367 TInt r = KErrNone; |
|
368 |
|
369 r = InitHwDes(*hdr, args); |
|
370 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
371 |
|
372 r = InitSrcHwDes(*hdr, args); |
|
373 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
374 |
|
375 r = InitDstHwDes(*hdr, args); |
|
376 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
377 |
|
378 r = UpdateHwDes(*hdr, KPhysAddrInvalid, KPhysAddrInvalid, 0, 0); |
|
379 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
380 |
|
381 r = UpdateSrcHwDes(*hdr, KPhysAddrInvalid, 0, 0); |
|
382 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
383 |
|
384 r = UpdateDstHwDes(*hdr, KPhysAddrInvalid, 0, 0); |
|
385 __NK_ASSERT_ALWAYS(r == KErrGeneral); |
|
386 |
|
387 ChainHwDes(*hdr, *hdr); |
|
388 AppendHwDes(*channel, *hdr, *hdr); |
|
389 AppendHwDes(*channel, *hdr, *hdr, *hdr, *hdr); |
|
390 UnlinkHwDes(*channel, *hdr); |
|
391 |
|
392 TUint32 count = 0; |
|
393 |
|
394 count = HwDesNumDstElementsTransferred(*hdr); |
|
395 __NK_ASSERT_ALWAYS(count == 0); |
|
396 |
|
397 count = HwDesNumSrcElementsTransferred(*hdr); |
|
398 __NK_ASSERT_ALWAYS(count == 0); |
|
399 } |
|
400 |
|
401 TInt TSkelDmac::TestPool() |
|
402 { |
|
403 DMA_PSL_TRACE("TSkelDmac::TestPool()"); |
|
404 TInt count = 0; |
|
405 SDmaDesHdr* hdr = iFreeHdr; |
|
406 TAny* des = iDesPool; |
|
407 |
|
408 TInt r = KErrNone; |
|
409 while(hdr->iNext) |
|
410 { |
|
411 TAny* receivedDes = NULL; |
|
412 if(iCapsHwDes) |
|
413 { |
|
414 receivedDes = HdrToHwDes(*hdr); |
|
415 } |
|
416 else |
|
417 { |
|
418 TDmaTransferArgs& args = HdrToDes(*hdr); |
|
419 receivedDes = &args; |
|
420 } |
|
421 |
|
422 if(receivedDes != des) |
|
423 { |
|
424 DMA_PSL_TRACE1("TSkelDmac::TestPool() failure: count=%d", count); |
|
425 r = KErrGeneral; |
|
426 break; |
|
427 } |
|
428 |
|
429 hdr = hdr->iNext; |
|
430 des = (TAny*)((TUint)des + iDesSize); |
|
431 count++; |
|
432 } |
|
433 |
|
434 if(count != (KDesCount - 1)) |
|
435 { |
|
436 DMA_PSL_TRACE2("TSkelDmac::TestPool() failure: count = %d != (iMaxDesCount -1) = %d", count, KDesCount-1); |
|
437 r = KErrUnknown; |
|
438 } |
|
439 return r; |
|
440 } |
|
441 |
|
442 ////////////////////////////////////////////////////////////////////////////// |
|
443 // Simulated Fragmentation Dmac |
|
444 ////////////////////////////////////////////////////////////////////////////// |
|
445 |
|
446 |
|
447 const SDmacCaps KSimAsymmChanCaps = |
|
448 {0, // TInt iChannelPriorities; |
|
449 EFalse, // TBool iChannelPauseAndResume; |
|
450 EFalse, // TBool iAddrAlignedToElementSize; |
|
451 EFalse, // TBool i1DIndexAddressing; |
|
452 EFalse, // TBool i2DIndexAddressing; |
|
453 KDmaSyncAuto, // TUint iSynchronizationTypes; |
|
454 KDmaBurstSizeAny, // TUint iBurstTransactions; |
|
455 EFalse, // TBool iDescriptorInterrupt; |
|
456 EFalse, // TBool iFrameInterrupt; |
|
457 EFalse, // TBool iLinkedListPausedInterrupt; |
|
458 EFalse, // TBool iEndiannessConversion; |
|
459 KDmaGraphicsOpNone, // TUint iGraphicsOps; |
|
460 EFalse, // TBool iRepeatingTransfers; |
|
461 EFalse, // TBool iChannelLinking; |
|
462 ETrue, // TBool iHwDescriptors; |
|
463 EFalse, // TBool iSrcDstAsymmetry; |
|
464 ETrue, // TBool iAsymHwDescriptors; |
|
465 EFalse, // TBool iBalancedAsymSegments; |
|
466 EFalse, // TBool iAsymCompletionInterrupt; |
|
467 EFalse, // TBool iAsymDescriptorInterrupt; |
|
468 EFalse, // TBool iAsymFrameInterrupt; |
|
469 {0, 0, 0, 0, 0} // TUint32 iReserved[5]; |
|
470 }; |
|
471 |
|
472 const SDmacCaps KSimAsymmBalancedChanCaps = |
|
473 {0, // TInt iChannelPriorities; |
|
474 EFalse, // TBool iChannelPauseAndResume; |
|
475 EFalse, // TBool iAddrAlignedToElementSize; |
|
476 EFalse, // TBool i1DIndexAddressing; |
|
477 EFalse, // TBool i2DIndexAddressing; |
|
478 KDmaSyncAuto, // TUint iSynchronizationTypes; |
|
479 KDmaBurstSizeAny, // TUint iBurstTransactions; |
|
480 EFalse, // TBool iDescriptorInterrupt; |
|
481 EFalse, // TBool iFrameInterrupt; |
|
482 EFalse, // TBool iLinkedListPausedInterrupt; |
|
483 EFalse, // TBool iEndiannessConversion; |
|
484 KDmaGraphicsOpNone, // TUint iGraphicsOps; |
|
485 EFalse, // TBool iRepeatingTransfers; |
|
486 EFalse, // TBool iChannelLinking; |
|
487 ETrue, // TBool iHwDescriptors; |
|
488 EFalse, // TBool iSrcDstAsymmetry; |
|
489 ETrue, // TBool iAsymHwDescriptors; |
|
490 ETrue, // TBool iBalancedAsymSegments; |
|
491 EFalse, // TBool iAsymCompletionInterrupt; |
|
492 EFalse, // TBool iAsymDescriptorInterrupt; |
|
493 EFalse, // TBool iAsymFrameInterrupt; |
|
494 {0, 0, 0, 0, 0} // TUint32 iReserved[5]; |
|
495 }; |
|
496 |
|
497 |
|
498 class TAsymmDmac : public TDmac |
|
499 { |
|
500 struct THwDes |
|
501 { |
|
502 TUint iAddr; |
|
503 TUint iLength; |
|
504 TUint iCookie; |
|
505 }; |
|
506 public: |
|
507 TAsymmDmac(); |
|
508 TInt Create(); |
|
509 private: |
|
510 // Work around for compiler which forbids this |
|
511 // class from accessing the protected, nested TDmac::SCreateInfo |
|
512 using TDmac::SCreateInfo; |
|
513 |
|
514 // from TDmac (PIL pure virtual) |
|
515 virtual void StopTransfer(const TDmaChannel& aChannel); |
|
516 virtual TBool IsIdle(const TDmaChannel& aChannel); |
|
517 virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, |
|
518 TUint aDstFlags, TUint32 aPslInfo); |
|
519 virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, |
|
520 TUint aDstFlags, TUint32 aPslInfo); |
|
521 // from TDmac (PIL virtual) |
|
522 TInt InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); |
|
523 TInt InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/); |
|
524 |
|
525 void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); |
|
526 void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); |
|
527 |
|
528 inline THwDes* HdrToHwDes(const SDmaDesHdr& aHdr); |
|
529 |
|
530 private: |
|
531 static const SCreateInfo KInfo; |
|
532 public: |
|
533 static const TInt iChannelCount; |
|
534 TEmptyChannel iChannel; |
|
535 }; |
|
536 |
|
537 const TAsymmDmac::SCreateInfo TAsymmDmac::KInfo = |
|
538 { |
|
539 ETrue, // iCapsHwDes |
|
540 KDesCount, // iDesCount |
|
541 sizeof(THwDes), // iDesSize |
|
542 #ifndef __WINS__ |
|
543 EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs |
|
544 #endif |
|
545 }; |
|
546 |
|
547 const TInt TAsymmDmac::iChannelCount = 1; |
|
548 |
|
549 static TAsymmDmac AsymController; |
|
550 |
|
551 TAsymmDmac::TAsymmDmac() |
|
552 // |
|
553 // Constructor. |
|
554 // |
|
555 : TDmac(KInfo) |
|
556 { |
|
557 // TODO remove this once DMAC can be created and destroyed from test LDD entry |
|
558 // point |
|
559 TInt r = Create(); |
|
560 __NK_ASSERT_ALWAYS(r == KErrNone); |
|
561 } |
|
562 |
|
563 |
|
564 TInt TAsymmDmac::Create() |
|
565 // |
|
566 // Second phase construction. |
|
567 // |
|
568 { |
|
569 TInt r = TDmac::Create(KInfo); // Base class Create() |
|
570 if (r == KErrNone) |
|
571 { |
|
572 __DMA_ASSERTA(ReserveSetOfDes(iChannelCount) == KErrNone); |
|
573 } |
|
574 return r; |
|
575 } |
|
576 |
|
577 |
|
578 void TAsymmDmac::StopTransfer(const TDmaChannel& /*aChannel*/) |
|
579 // |
|
580 // Stops a running channel. |
|
581 // |
|
582 { |
|
583 __DMA_CANT_HAPPEN(); |
|
584 } |
|
585 |
|
586 |
|
587 TBool TAsymmDmac::IsIdle(const TDmaChannel& /*aChannel*/) |
|
588 // |
|
589 // Returns the state of a given channel. |
|
590 // |
|
591 { |
|
592 __DMA_CANT_HAPPEN(); |
|
593 return ETrue; |
|
594 } |
|
595 |
|
596 |
|
597 TUint TAsymmDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, |
|
598 TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) |
|
599 // |
|
600 // Returns the maximum transfer length in bytes for a given transfer. |
|
601 // |
|
602 { |
|
603 // TO DO: Determine the proper return value, based on the arguments. |
|
604 |
|
605 // For instance: |
|
606 return KMaxTransferLen; |
|
607 } |
|
608 |
|
609 |
|
610 TUint TAsymmDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, |
|
611 TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) |
|
612 // |
|
613 // Returns the memory buffer alignment restrictions mask for a given transfer. |
|
614 // |
|
615 { |
|
616 // TO DO: Determine the proper return value, based on the arguments. |
|
617 |
|
618 // For instance: |
|
619 return KMemAlignMask; |
|
620 } |
|
621 |
|
622 |
|
623 inline TAsymmDmac::THwDes* TAsymmDmac::HdrToHwDes(const SDmaDesHdr& aHdr) |
|
624 // |
|
625 // Changes return type of base class call. |
|
626 // |
|
627 { |
|
628 return static_cast<THwDes*>(TDmac::HdrToHwDes(aHdr)); |
|
629 } |
|
630 |
|
631 TInt TAsymmDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
|
632 { |
|
633 return KErrNone; |
|
634 } |
|
635 |
|
636 TInt TAsymmDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
|
637 { |
|
638 return KErrNone; |
|
639 } |
|
640 |
|
641 void TAsymmDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) |
|
642 { |
|
643 } |
|
644 |
|
645 void TAsymmDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) |
|
646 { |
|
647 } |
|
648 |
|
649 |
|
650 |
|
651 ////////////////////////////////////////////////////////////////////////////// |
|
652 // Channel Opening/Closing (Channel Allocator) |
|
653 ////////////////////////////////////////////////////////////////////////////// |
|
654 |
|
655 struct TChanEntry |
|
656 { |
|
657 TChanEntry(TDmac& aController, TDmaChannel& aChannel, const SDmacCaps& aCaps) |
|
658 : |
|
659 iController(aController), |
|
660 iChannel(aChannel), |
|
661 iCaps(aCaps) |
|
662 {} |
|
663 |
|
664 TDmac& iController; |
|
665 TDmaChannel& iChannel; |
|
666 const SDmacCaps& iCaps; |
|
667 }; |
|
668 |
|
669 const TChanEntry ChannelTable[] = |
|
670 { |
|
671 TChanEntry(SkelControllerSw, SkelControllerSw.iChannel, KSimSwChanCaps), |
|
672 TChanEntry(SkelControllerHw, SkelControllerHw.iChannel, KSimSgChanCaps), |
|
673 TChanEntry(AsymController, AsymController.iChannel, KSimAsymmChanCaps), |
|
674 TChanEntry(AsymController, AsymController.iChannel, KSimAsymmBalancedChanCaps) |
|
675 }; |
|
676 |
|
677 static const TInt KChannelCount = ARRAY_LENGTH(ChannelTable); |
|
678 |
|
679 TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/) |
|
680 // |
|
681 // |
|
682 // |
|
683 { |
|
684 __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId)); |
|
685 |
|
686 __DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount)); |
|
687 |
|
688 const TChanEntry& entry = ChannelTable[aOpenId]; |
|
689 TDmaChannel* pC = &entry.iChannel; |
|
690 if (pC->IsOpened()) |
|
691 { |
|
692 pC = NULL; |
|
693 } |
|
694 else |
|
695 { |
|
696 pC->iController = &entry.iController; |
|
697 pC->iPslId = aOpenId; |
|
698 pC->iDmacCaps = &entry.iCaps; |
|
699 |
|
700 // It is safe to signal here, |
|
701 // setting iController marks the channel |
|
702 // as taken |
|
703 Signal(); |
|
704 |
|
705 static_cast<TEmptyChannel*>(pC)->PreOpen(); |
|
706 |
|
707 Wait(); |
|
708 } |
|
709 return pC; |
|
710 } |
|
711 |
|
712 |
|
713 void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/) |
|
714 // |
|
715 // |
|
716 // |
|
717 { |
|
718 // NOP |
|
719 } |
|
720 |
|
721 |
|
722 TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/) |
|
723 // |
|
724 // |
|
725 // |
|
726 { |
|
727 return KErrNotSupported; |
|
728 } |