haltDSP.h (1501B)
1 #pragma once 2 3 #include <cstdint> 4 #include <functional> 5 #include <unordered_map> 6 #include <atomic> 7 8 #include "dsp56kEmu/semaphore.h" 9 10 namespace dsp56k 11 { 12 class DSP; 13 } 14 15 namespace hwLib 16 { 17 class HaltDSP 18 { 19 public: 20 explicit HaltDSP(dsp56k::DSP& _dsp); 21 22 void haltDSP(bool _wait = false); 23 bool resumeDSP(); 24 25 // only returns true if the last halt request has been serviced 26 bool isHalting() const { return m_halting && m_irqRequestCount == m_irqServedCount; } 27 28 dsp56k::DSP& getDSP() const { return m_dsp; } 29 30 void wakeUp(std::function<void()>&& _func); 31 32 private: 33 void onInterrupt(); 34 35 dsp56k::DSP& m_dsp; 36 37 uint32_t m_halted = 0; 38 uint32_t m_irq; 39 dsp56k::SpscSemaphore m_blockSem; 40 41 std::mutex m_mutex; 42 dsp56k::ConditionVariable m_cvHalted; 43 44 std::atomic<uint32_t> m_irqServedCount = 0; 45 uint32_t m_irqRequestCount = 0; 46 47 uint32_t m_wakeUpId = 0; 48 uint32_t m_wakeUpCount = 0; 49 50 std::unordered_map<uint32_t, std::function<void()>> m_wakeUps; 51 52 std::atomic<bool> m_halting = false; 53 }; 54 55 class ScopedResumeDSP 56 { 57 public: 58 explicit ScopedResumeDSP(HaltDSP& _haltDSP) : m_haltDSP(_haltDSP), m_resumed(_haltDSP.resumeDSP()) 59 { 60 } 61 62 ~ScopedResumeDSP() 63 { 64 if(m_resumed) 65 m_haltDSP.haltDSP(); 66 } 67 private: 68 HaltDSP& m_haltDSP; 69 bool m_resumed; 70 }; 71 72 class ScopedHaltDSP 73 { 74 public: 75 explicit ScopedHaltDSP(HaltDSP& _haltDSP) : m_haltDSP(_haltDSP) 76 { 77 _haltDSP.haltDSP(); 78 } 79 80 ~ScopedHaltDSP() 81 { 82 m_haltDSP.resumeDSP(); 83 } 84 private: 85 HaltDSP& m_haltDSP; 86 }; 87 }