use super::*;
impl VirtioBlk {
pub fn mmio_read(&self, offset: u64, data: &mut [u8]) {
if offset >= 0x100 {
self.read_blk_config(offset - 0x100, data);
return;
}
if data.len() != 4 {
data.fill(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_BLOCK,
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,
};
data.copy_from_slice(&val.to_le_bytes());
}
pub fn mmio_write(&mut self, offset: u64, data: &[u8]) {
if offset >= 0x100 {
return;
}
if data.len() != 4 {
return;
}
let val = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
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)),
_ => {}
}
}
}