mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
vmm: distinguish virtio interrupts
VirtIO device models can assert interrupts to notify about buffer and configuration changes. By now, we could only assert buffer notification interrupts, but no configuration changes. The latter is needed, e.g. to notify about GPU mode changes. Ref genodelabs/genode#4783
This commit is contained in:
parent
441186468c
commit
cb3b6c4b88
@ -279,7 +279,7 @@ class Vmm::Virtio_block_device
|
||||
void completed(Job &job, bool)
|
||||
{
|
||||
job.done(*_queue[REQUEST]);
|
||||
_assert_irq();
|
||||
_buffer_notification();
|
||||
destroy(_heap, &job);
|
||||
}
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ class Vmm::Virtio_console : public Virtio_device<Virtio_split_queue, 2>
|
||||
if (!_terminal.avail() || !_queue[RX].constructed()) return;
|
||||
|
||||
_queue[RX]->notify(read);
|
||||
_assert_irq();
|
||||
_buffer_notification();
|
||||
}
|
||||
|
||||
void _notify(unsigned idx) override
|
||||
@ -59,7 +59,7 @@ class Vmm::Virtio_console : public Virtio_device<Virtio_split_queue, 2>
|
||||
};
|
||||
|
||||
if (_queue[TX]->notify(write))
|
||||
_assert_irq();
|
||||
_buffer_notification();
|
||||
}
|
||||
|
||||
enum Device_id { CONSOLE = 0x3 };
|
||||
|
@ -341,18 +341,35 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, private Virtio_device_base
|
||||
return ((uint64_t)_device_high.value()<<32) | _device_low.value();
|
||||
}
|
||||
|
||||
void _assert_irq()
|
||||
enum Irq : uint64_t {
|
||||
NONE = 0UL,
|
||||
BUFFER = 1UL << 0,
|
||||
CONFIG = 1UL << 1,
|
||||
};
|
||||
|
||||
void _assert_irq(uint64_t irq)
|
||||
{
|
||||
_irq_status.set(0x1);
|
||||
_irq_status.set(_irq_status.value() | irq);
|
||||
_irq.assert();
|
||||
}
|
||||
|
||||
void _deassert_irq()
|
||||
void _deassert_irq(uint64_t irq)
|
||||
{
|
||||
_irq_status.set(0);
|
||||
_irq_status.set(_irq_status.value() & ~irq);
|
||||
_irq.deassert();
|
||||
}
|
||||
|
||||
void _buffer_notification()
|
||||
{
|
||||
_assert_irq(BUFFER);
|
||||
}
|
||||
|
||||
void _config_notification()
|
||||
{
|
||||
_config_gen.set(_config_gen.value() + 1);
|
||||
_assert_irq(CONFIG);
|
||||
}
|
||||
|
||||
void _construct_queue()
|
||||
{
|
||||
Genode::Mutex::Guard guard(mutex());
|
||||
@ -403,10 +420,10 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, private Virtio_device_base
|
||||
|
||||
struct Interrupt_ack : Reg
|
||||
{
|
||||
void write(Address_range&, Cpu&, Register) override
|
||||
void write(Address_range&, Cpu&, Register v) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(Reg::device().mutex());
|
||||
Reg::device()._deassert_irq();
|
||||
Reg::device()._deassert_irq(v);
|
||||
}
|
||||
|
||||
Interrupt_ack(Virtio_device &device)
|
||||
@ -442,7 +459,6 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, private Virtio_device_base
|
||||
}
|
||||
|
||||
Genode::Mutex & mutex() { return _mutex; }
|
||||
void config_has_changed() { _config_gen.set(_config_gen.get() + 1); }
|
||||
};
|
||||
|
||||
#endif /* _VIRTIO_DEVICE_H_ */
|
||||
|
@ -37,7 +37,7 @@ void Vmm::Virtio_gpu_queue::notify(Virtio_gpu_device & dev)
|
||||
|
||||
_used.write<Used_queue::Idx>((uint16_t)_cur_idx.idx());
|
||||
memory_barrier();
|
||||
if (_avail.inject_irq()) dev.assert_irq();
|
||||
if (_avail.inject_irq()) dev.buffer_notification();
|
||||
}
|
||||
|
||||
|
||||
|
@ -469,7 +469,10 @@ class Vmm::Virtio_gpu_device : public Virtio_device<Virtio_gpu_queue, 2>
|
||||
_mode_change();
|
||||
}
|
||||
|
||||
void assert_irq() { _assert_irq(); }
|
||||
void buffer_notification()
|
||||
{
|
||||
_buffer_notification();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _VIRTIO_GPU_H_ */
|
||||
|
@ -272,7 +272,7 @@ class Vmm::Virtio_input_device : public Virtio_device<Virtio_split_queue, 2>
|
||||
return size;
|
||||
});
|
||||
|
||||
if (irq) _assert_irq();
|
||||
if (irq) _buffer_notification();
|
||||
}
|
||||
|
||||
void _notify(unsigned idx) override
|
||||
|
@ -74,7 +74,7 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
|
||||
|
||||
bool irq = _queue[RX]->notify(recv);
|
||||
|
||||
if (irq) _assert_irq();
|
||||
if (irq) _buffer_notification();
|
||||
}
|
||||
|
||||
void _tx()
|
||||
@ -99,7 +99,7 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
|
||||
|
||||
if (!_queue[TX].constructed()) return;
|
||||
|
||||
if (_queue[TX]->notify(send)) _assert_irq();
|
||||
if (_queue[TX]->notify(send)) _buffer_notification();
|
||||
_free_packets();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user