use virtio_bindings::virtio_ids::VIRTIO_ID_NET;
use virtio_bindings::virtio_mmio::{
VIRTIO_MMIO_CONFIG_GENERATION, VIRTIO_MMIO_DEVICE_FEATURES, VIRTIO_MMIO_DEVICE_FEATURES_SEL,
VIRTIO_MMIO_DEVICE_ID, VIRTIO_MMIO_DRIVER_FEATURES, VIRTIO_MMIO_DRIVER_FEATURES_SEL,
VIRTIO_MMIO_INTERRUPT_ACK, VIRTIO_MMIO_INTERRUPT_STATUS, VIRTIO_MMIO_MAGIC_VALUE,
VIRTIO_MMIO_QUEUE_AVAIL_HIGH, VIRTIO_MMIO_QUEUE_AVAIL_LOW, VIRTIO_MMIO_QUEUE_DESC_HIGH,
VIRTIO_MMIO_QUEUE_DESC_LOW, VIRTIO_MMIO_QUEUE_NOTIFY, VIRTIO_MMIO_QUEUE_NUM,
VIRTIO_MMIO_QUEUE_NUM_MAX, VIRTIO_MMIO_QUEUE_READY, VIRTIO_MMIO_QUEUE_SEL,
VIRTIO_MMIO_QUEUE_USED_HIGH, VIRTIO_MMIO_QUEUE_USED_LOW, VIRTIO_MMIO_STATUS,
VIRTIO_MMIO_VENDOR_ID, VIRTIO_MMIO_VERSION,
};
use super::device::{MMIO_MAGIC, MMIO_VERSION, VENDOR_ID, VirtioNet};
impl VirtioNet {
pub fn mmio_read(&self, offset: u64, data: &mut [u8]) {
if offset >= 0x100 {
self.config_bytes((offset - 0x100) as usize, data);
return;
}
if data.len() != 4 {
for b in data.iter_mut() {
*b = 0xff;
}
return;
}
let val: u32 = match offset as u32 {
VIRTIO_MMIO_MAGIC_VALUE => MMIO_MAGIC,
VIRTIO_MMIO_VERSION => MMIO_VERSION,
VIRTIO_MMIO_DEVICE_ID => VIRTIO_ID_NET,
VIRTIO_MMIO_VENDOR_ID => VENDOR_ID,
VIRTIO_MMIO_DEVICE_FEATURES => self.device_features_window(),
VIRTIO_MMIO_QUEUE_NUM_MAX => self.queue_max_size(),
VIRTIO_MMIO_QUEUE_READY => self.queue_ready(),
VIRTIO_MMIO_INTERRUPT_STATUS => self.interrupt_status(),
VIRTIO_MMIO_STATUS => self.device_status(),
VIRTIO_MMIO_CONFIG_GENERATION => self.config_generation(),
_ => 0,
};
tracing::debug!(offset, val, "virtio-net mmio_read");
data.copy_from_slice(&val.to_le_bytes());
}
pub fn mmio_write(&mut self, offset: u64, data: &[u8]) {
if offset >= 0x100 {
tracing::debug!(
offset,
len = data.len(),
"virtio-net config-space write ignored"
);
return;
}
if data.len() != 4 {
return;
}
let val = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
tracing::debug!(offset, val, "virtio-net mmio_write");
match offset as u32 {
VIRTIO_MMIO_DEVICE_FEATURES_SEL => self.set_device_features_sel(val),
VIRTIO_MMIO_DRIVER_FEATURES_SEL => self.set_driver_features_sel(val),
VIRTIO_MMIO_DRIVER_FEATURES => self.set_driver_features_window(val),
VIRTIO_MMIO_QUEUE_SEL => self.set_queue_select(val),
VIRTIO_MMIO_QUEUE_NUM => self.set_queue_size(val as u16),
VIRTIO_MMIO_QUEUE_READY => self.set_queue_ready(val == 1),
VIRTIO_MMIO_QUEUE_NOTIFY => self.notify_queue(val),
VIRTIO_MMIO_INTERRUPT_ACK => self.ack_interrupt(val),
VIRTIO_MMIO_STATUS => self.write_status(val),
VIRTIO_MMIO_QUEUE_DESC_LOW => self.set_queue_desc_addr(Some(val), None),
VIRTIO_MMIO_QUEUE_DESC_HIGH => self.set_queue_desc_addr(None, Some(val)),
VIRTIO_MMIO_QUEUE_AVAIL_LOW => self.set_queue_avail_addr(Some(val), None),
VIRTIO_MMIO_QUEUE_AVAIL_HIGH => self.set_queue_avail_addr(None, Some(val)),
VIRTIO_MMIO_QUEUE_USED_LOW => self.set_queue_used_addr(Some(val), None),
VIRTIO_MMIO_QUEUE_USED_HIGH => self.set_queue_used_addr(None, Some(val)),
_ => {}
}
}
}