39        void free()
 override {  }
 
 
   43    std::shared_ptr<qemu::Timer> m_deadline_timer;
 
   49    sc_core::sc_event_or_list m_external_ev;
 
   50    sc_core::sc_process_handle m_sc_thread; 
 
   52    std::atomic<bool> m_signaled;
 
   53    std::mutex m_signaled_lock;
 
   54    std::condition_variable m_signaled_cond;
 
   56    std::shared_ptr<gs::tlm_quantumkeeper_extended> m_qk;
 
   57    std::atomic<bool> m_finished = 
false;
 
   58    std::atomic<bool> m_started = 
false;
 
   59    enum { none, start_reset, hold_reset, finish_reset } m_resetting = none;
 
   62    std::mutex m_can_delete;
 
   70    void create_quantum_keeper()
 
   75            SCP_FATAL(()) << 
"qbox : Sync policy unknown";
 
   85    void set_coroutine_mode()
 
   87        switch (m_qk->get_thread_type()) {
 
   88        case gs::SyncPolicy::SYSTEMC_THREAD:
 
   92        case gs::SyncPolicy::OS_THREAD:
 
  116        if (m_inst.
get_tcg_mode() != QemuInstance::TCG_SINGLE) {
 
  117            std::lock_guard<std::mutex> 
lock(m_signaled_lock);
 
  119            m_signaled_cond.notify_all();
 
  121            std::lock_guard<std::mutex> 
lock(m_inst.g_signaled_lock);
 
  122            m_inst.g_signaled = 
true;
 
  123            m_inst.g_signaled_cond.notify_all();
 
  131    void watch_external_ev()
 
  145        SCP_TRACE(())(
"QEMU deadline KICK callback");
 
  147            if (!m_finished) m_qemu_kick_ev.async_notify();
 
  159    void deadline_timer_cb()
 
  161        SCP_TRACE(())(
"QEMU deadline timer callback");
 
  166            rearm_deadline_timer();
 
  170            sc_core::sc_time 
sc_t = sc_core::sc_time_stamp();
 
  171            if (sc_core::sc_time(
now, sc_core::SC_NS) > 
sc_t) {
 
  172                m_qk->set(sc_core::sc_time(
now, sc_core::SC_NS) - 
sc_t);
 
  190        if (m_finished) 
return;
 
  193            m_on_sysc.
run_on_sysc([
this]() { wait(m_external_ev); });
 
  195            if (m_inst.
get_tcg_mode() != QemuInstance::TCG_SINGLE) {
 
  196                std::unique_lock<std::mutex> 
lock(m_signaled_lock);
 
  197                m_signaled_cond.wait(
lock, [
this] { 
return m_signaled || m_finished; });
 
  200                std::unique_lock<std::mutex> 
lock(m_inst.g_signaled_lock);
 
  201                m_inst.g_signaled_cond.wait(
lock, [
this] { 
return m_inst.g_signaled || m_finished; });
 
  202                m_inst.g_signaled = 
false;
 
  205        if (m_finished) 
return;
 
  213    void rearm_deadline_timer()
 
  217        m_deadline_timer->mod(m_inst.
get().get_virtual_clock() + m_quantum_ns);
 
  224    void prepare_run_cpu()
 
  233        if (m_inst.
get_tcg_mode() == QemuInstance::TCG_SINGLE) {
 
  234            while (!m_inst.can_run() && !m_finished) {
 
  238            while (!m_cpu.can_run() && !m_finished) {
 
  250            m_cpu.set_soft_stopped(
false);
 
  257        m_inst.
get().lock_iothread();
 
  271        for (
int i = 0; 
i < m_inst.number_devices(); 
i++) {
 
  272            if ((m_inst.
get().get_virtual_clock() == 
last_vclock) && (m_cpu.can_run())) {
 
  282    void sync_with_kernel()
 
  286        m_cpu.set_soft_stopped(
true);
 
  288        m_inst.
get().unlock_iothread();
 
  292        sc_core::sc_time 
sc_t = sc_core::sc_time_stamp();
 
  293        if (sc_core::sc_time(
now, sc_core::SC_NS) > 
sc_t) {
 
  294            m_qk->set(sc_core::sc_time(
now, sc_core::SC_NS) - 
sc_t);
 
  305    void end_of_loop_cb()
 
  308        if (m_finished) 
return;
 
  310            m_inst.
get().coroutine_yield();
 
  312            std::lock_guard<std::mutex> 
lock(m_can_delete);
 
  321    void mainloop_thread_coroutine()
 
  323        m_cpu.register_thread();
 
  325        for (; !m_finished;) {
 
  333    cci::cci_param<unsigned int> p_gdb_port;
 
  345        , m_qemu_kick_ev(
false)
 
  347        , p_gdb_port(
"gdb_port", 0, 
"Wait for gdb connection on TCP port <gdb_port>")
 
  348        , socket(
"mem", *
this, inst)
 
  350        using namespace std::placeholders;
 
  352        m_external_ev |= m_qemu_kick_ev;
 
  354        auto haltcb = std::bind(&QemuCpu::halt_cb, 
this, 
_1);
 
  355        halt.register_value_changed_cb(
haltcb);
 
  356        auto resetcb = std::bind(&QemuCpu::reset_cb, 
this, 
_1);
 
  357        reset.register_value_changed_cb(
resetcb);
 
  359        create_quantum_keeper();
 
  360        set_coroutine_mode();
 
  366        m_inst.add_dev(
this);
 
  368        m_start_reset_done_ev.async_detach_suspending();
 
  374        while (!m_can_delete.try_lock()) {
 
  377        m_inst.del_dev(
this);
 
  382    void end_of_simulation()
 override 
  384        if (m_finished) 
return;
 
  387        if (!m_cpu.valid()) {
 
  396        m_inst.
get().lock_iothread();
 
  398        m_cpu.clear_callbacks();
 
  402            m_inst.
get().unlock_iothread();
 
  421        m_cpu.set_unplug(
true);
 
  424        m_inst.
get().unlock_iothread();
 
  431    bool can_run()
 override { 
return m_cpu.can_run(); }
 
  433    void before_end_of_elaboration()
 override 
  435        QemuDevice::before_end_of_elaboration();
 
  440            m_sc_thread = sc_core::sc_spawn(std::bind(&QemuCpu::mainloop_thread_coroutine, 
this));
 
  443        socket.init(m_dev, 
"memory");
 
  445        m_cpu.set_soft_stopped(
true);
 
  447        m_cpu.set_end_of_loop_callback(std::bind(&QemuCpu::end_of_loop_cb, 
this));
 
  448        m_cpu.set_kick_callback(std::bind(&QemuCpu::kick_cb, 
this));
 
  450        m_deadline_timer = m_inst.
get().timer_new();
 
  451        m_deadline_timer->set_callback(std::bind(&QemuCpu::deadline_timer_cb, 
this));
 
  453        m_cpu_hint_ext.set_cpu(m_cpu);
 
  456    void halt_cb(
const bool& 
val)
 
  461                m_deadline_timer->del();
 
  465                rearm_deadline_timer();
 
  467            m_inst.
get().lock_iothread();
 
  469            m_inst.
get().unlock_iothread();
 
  470            m_qemu_kick_ev.async_notify(); 
 
  475    void reset_cb(
const bool& 
val)
 
  478        if (m_finished) 
return;
 
  481            if (m_resetting != none) 
return; 
 
  483            m_resetting = start_reset;
 
  484            m_cpu.async_safe_run([&] {
 
  486                m_resetting = hold_reset;
 
  487                m_start_reset_done_ev.async_notify();
 
  490            if (m_resetting == none) 
return; 
 
  491            while (m_resetting == start_reset) {
 
  493                sc_core::wait(m_start_reset_done_ev);
 
  499            m_qemu_kick_ev.async_notify(); 
 
  503        m_qemu_kick_ev.async_notify(); 
 
  505    virtual void end_of_elaboration()
 override 
  507        QemuDevice::end_of_elaboration();
 
  509        if (!p_gdb_port.is_default_value()) {
 
  510            std::stringstream 
ss;
 
  511            SCP_INFO(()) << 
"Starting gdb server on TCP port " << p_gdb_port;
 
  512            ss << 
"tcp::" << p_gdb_port;
 
  513            m_inst.
get().start_gdb_server(
ss.str());
 
  517    virtual void start_of_simulation()
 override 
  519        m_quantum_ns = 
int64_t(tlm_utils::tlm_quantumkeeper::get_global_quantum().
to_seconds() * 1
e9);
 
  521        QemuDevice::start_of_simulation();
 
  522        if (m_inst.
get_tcg_mode() == QemuInstance::TCG_SINGLE) {
 
  523            if (m_inst.can_run()) {
 
  529            m_cpu.set_soft_stopped(
false);
 
  530            rearm_deadline_timer();
 
  538        m_cpu.set_vcpu_dirty(
true);
 
  544    virtual void initiator_customize_tlm_payload(TlmPayload& 
payload)
 override 
  547        payload.set_extension(&m_cpu_hint_ext);
 
  550    virtual void initiator_tidy_tlm_payload(TlmPayload& 
payload)
 override { 
payload.clear_extension(&m_cpu_hint_ext); }
 
  556    virtual sc_core::sc_time initiator_get_local_time()
 override 
  558        using sc_core::sc_time;
 
  559        using sc_core::SC_NS;
 
  564        sc_core::sc_time 
sc_t = sc_core::sc_time_stamp();
 
  567            return m_qk->get_local_time();
 
  569            return sc_core::SC_ZERO_TIME;
 
  577    virtual void initiator_set_local_time(
const sc_core::sc_time& 
t)
 override 
  581        if (m_qk->need_sync()) {
 
  591    virtual void initiator_async_run(qemu::Cpu::AsyncJobFn 
job)
 override 
  593        if (!m_finished) m_cpu.async_run(
job);