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