--- nono/vm/virtio_base.cpp 2026/04/29 17:05:29 1.1.1.2 +++ nono/vm/virtio_base.cpp 2026/04/29 17:05:33 1.1.1.3 @@ -229,8 +229,7 @@ VirtIODevice::WritePort(uint32 offset, u case VirtIO::QUEUE_READY: putlog(2, "QUEUE_READY(%u) <- $%08x", queue_sel, data); if (vq) { - vq->ready = data; - QueueReady(); + vq->SetReady(data); } break; @@ -382,7 +381,7 @@ VirtIODevice::MonitorUpdateVirtQueue(Tex y++; screen.Puts(1, y, "Ring:"); - if (__predict_true(q.ready)) { + if (__predict_true(q.GetReady())) { uint16 aidx = PeekLE16(q.driver + 2); uint16 head = PeekLE16(q.driver + 4 + q.Mod(aidx) * 2); uint16 uidx = PeekLE16(q.device + 2); @@ -458,7 +457,7 @@ VirtIODevice::MonitorUpdateVirtQDesc(Tex screen.Print(x0, y++, TA::Disable, "%02x", i); } - if (__predict_true(q.ready)) { + if (__predict_true(q.GetReady())) { uint avail_idx = PeekLE16(q.driver + 2); uint used_idx = PeekLE16(q.device + 2); screen.Puts(x1 - 3, ytop + q.Mod(avail_idx), "G>"); @@ -489,7 +488,7 @@ VirtIODevice::Reset() q.driver = 0xcccccccc; q.device = 0xcccccccc; q.num = 0; - q.ready = 0; + q.SetReady(0); q.last_avail_idx = 0; } vq = NULL; @@ -533,7 +532,7 @@ VirtIODevice::GetReg(uint32 addr) const case VirtIO::QUEUE_READY: if (vq) { - return vq->ready; + return vq->GetReady(); } else { return 0; } @@ -549,11 +548,11 @@ VirtIODevice::GetReg(uint32 addr) const } } -// QUEUE_READY 時の処理。 +// QUEUE_READY が更新された時に呼ばれる。必要ならオーバーライドする。 +// q->ready が 0 なら Not ready(初期状態)、1 なら Ready。 void -VirtIODevice::QueueReady() +VirtIODevice::QueueReadyChanged(VirtQueue *q) { - // 必要ならオーバーライドする。 } // QUEUE_NOTIFY の処理。(これは裏スレッドで実行される) @@ -1098,9 +1097,21 @@ VirtIOThread::ThreadRun() // // コンストラクタ -VirtQueue::VirtQueue(int idx_, const std::string& name_, int num_max_) +VirtQueue::VirtQueue(VirtIODevice *parent_, int idx_, const std::string& name_, + int num_max_) { + parent = parent_; idx = idx_; name = name_; num_max = num_max_; } + +// QUEUE_READY の代入。 +void +VirtQueue::SetReady(uint32 val) +{ + if (val != ready) { + ready = val; + parent->QueueReadyChanged(this); + } +}