353 */ |
353 */ |
354 { |
354 { |
355 public: |
355 public: |
356 static void StartEmulation(); |
356 static void StartEmulation(); |
357 static void StopEmulation(); |
357 static void StopEmulation(); |
|
358 static TBool InISR(); |
|
359 static void Synchronize(); |
358 private: |
360 private: |
359 enum { KPeriod = 1 }; // in ms |
361 enum { KPeriod = 1 }; // in ms |
|
362 enum { EDmaSimIdle=0u, EDmaSimStarted=1u, EDmaSimInISR=2u, EDmaSimStopping=0x80000000u }; |
360 static void TickCB(TAny* aThis); |
363 static void TickCB(TAny* aThis); |
361 static NTimer Timer; |
364 static NTimer Timer; |
|
365 static volatile TInt StartStop; |
362 }; |
366 }; |
363 |
367 |
364 NTimer DmacSim::Timer; |
368 NTimer DmacSim::Timer; |
|
369 volatile TInt DmacSim::StartStop; |
365 |
370 |
366 void DmacSim::StartEmulation() |
371 void DmacSim::StartEmulation() |
367 { |
372 { |
|
373 __DMA_ASSERTA(StartStop==EDmaSimIdle); |
368 new (&Timer) NTimer(&TickCB, 0); |
374 new (&Timer) NTimer(&TickCB, 0); |
|
375 __e32_atomic_store_ord32(&StartStop, EDmaSimStarted); |
369 __DMA_ASSERTA(Timer.OneShot(KPeriod, EFalse) == KErrNone); |
376 __DMA_ASSERTA(Timer.OneShot(KPeriod, EFalse) == KErrNone); |
370 } |
377 } |
371 |
378 |
372 void DmacSim::StopEmulation() |
379 void DmacSim::StopEmulation() |
373 { |
380 { |
374 Timer.Cancel(); |
381 TInt orig = __e32_atomic_tas_ord32(&StartStop, (TInt)EDmaSimStarted, (TInt)EDmaSimStopping, 0); |
|
382 if (orig == EDmaSimIdle) |
|
383 return; // wasn't running |
|
384 // loop until we succeed in cancelling the timer or the timer callback |
|
385 // notices that we are shutting down |
|
386 while (!Timer.Cancel() && __e32_atomic_load_acq32(&StartStop)!=EDmaSimIdle) |
|
387 {} |
|
388 __e32_atomic_store_ord32(&StartStop, EDmaSimIdle); |
375 } |
389 } |
376 |
390 |
377 void DmacSim::TickCB(TAny*) |
391 void DmacSim::TickCB(TAny*) |
378 { |
392 { |
379 DmacSb::DoTransfer(); |
393 TInt orig = (TInt)__e32_atomic_ior_acq32(&StartStop, EDmaSimInISR); |
380 DmacDb::DoTransfer(); |
394 if (orig >= 0) |
381 DmacSg::DoTransfer(); |
395 { |
382 __DMA_ASSERTA(Timer.Again(KPeriod) == KErrNone); |
396 DmacSb::DoTransfer(); |
|
397 DmacDb::DoTransfer(); |
|
398 DmacSg::DoTransfer(); |
|
399 } |
|
400 orig = (TInt)__e32_atomic_and_rel32(&StartStop, (TUint32)~EDmaSimInISR); |
|
401 if (orig < 0) |
|
402 { |
|
403 __e32_atomic_store_rel32(&StartStop, EDmaSimIdle); |
|
404 return; |
|
405 } |
|
406 TInt r = Timer.Again(KPeriod); |
|
407 if (r == KErrArgument) |
|
408 r = Timer.OneShot(KPeriod); |
|
409 __DMA_ASSERTA(r == KErrNone); |
|
410 } |
|
411 |
|
412 TBool DmacSim::InISR() |
|
413 { |
|
414 return __e32_atomic_load_acq32(&StartStop) & EDmaSimInISR; |
|
415 } |
|
416 |
|
417 void DmacSim::Synchronize() |
|
418 { |
|
419 while (InISR()) |
|
420 {} |
383 } |
421 } |
384 |
422 |
385 ////////////////////////////////////////////////////////////////////////////// |
423 ////////////////////////////////////////////////////////////////////////////// |
386 // PSL FOR DMA SIMULATION |
424 // PSL FOR DMA SIMULATION |
387 ////////////////////////////////////////////////////////////////////////////// |
425 ////////////////////////////////////////////////////////////////////////////// |
664 |
704 |
665 |
705 |
666 void DSimSgController::StopTransfer(const TDmaChannel& aChannel) |
706 void DSimSgController::StopTransfer(const TDmaChannel& aChannel) |
667 { |
707 { |
668 __e32_atomic_and_ord32(&DmacSg::ChannelControl[aChannel.PslId()], (TUint32)~DmacSg::EChannelBitRun); |
708 __e32_atomic_and_ord32(&DmacSg::ChannelControl[aChannel.PslId()], (TUint32)~DmacSg::EChannelBitRun); |
|
709 DmacSim::Synchronize(); |
669 } |
710 } |
670 |
711 |
671 |
712 |
672 void DSimSgController::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, |
713 void DSimSgController::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, |
673 TUint /*aFlags*/, TUint32 /*aPslInfo*/, TUint32 /*aCookie*/) |
714 TUint /*aFlags*/, TUint32 /*aPslInfo*/, TUint32 /*aCookie*/) |