use std::os::fd::{AsFd, BorrowedFd};
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64};
use std::sync::mpsc::Sender;
use rstest::fixture;
use crate::hv::IoeventFd;
use crate::mem::mapped::{ArcMemPages, RamBus};
use crate::virtio::queue::{QUEUE_SIZE_MAX, QueueReg};
use crate::virtio::{IrqSender, Result};
pub const QUEUE_SIZE: u16 = QUEUE_SIZE_MAX;
const MEM_SIZE: usize = 2 << 20;
pub const DATA_ADDR: u64 = 0x0;
const QUEUE_START: u64 = 1 << 20;
#[fixture]
pub fn fixture_ram_bus() -> RamBus {
let host_pages = ArcMemPages::from_anonymous(MEM_SIZE, None, None).unwrap();
let ram_bus = RamBus::new();
ram_bus.add(0, host_pages).unwrap();
ram_bus
}
#[fixture]
pub fn fixture_queues(#[default(1)] count: u16) -> Box<[QueueReg]> {
(0..count)
.map(|i| {
let base = QUEUE_START + i as u64 * 0x2000;
QueueReg {
size: AtomicU16::new(QUEUE_SIZE),
desc: AtomicU64::new(base),
driver: AtomicU64::new(base + 0x1000),
device: AtomicU64::new(base + 0x1400),
enabled: AtomicBool::new(true),
}
})
.collect()
}
#[derive(Debug)]
pub struct FakeIrqSender {
pub q_tx: Sender<u16>,
}
impl IrqSender for FakeIrqSender {
fn queue_irq(&self, idx: u16) {
self.q_tx.send(idx).unwrap();
}
fn config_irq(&self) {
unimplemented!()
}
fn queue_irqfd<F, T>(&self, _idx: u16, _f: F) -> Result<T>
where
F: FnOnce(BorrowedFd) -> Result<T>,
{
unimplemented!()
}
fn config_irqfd<F, T>(&self, _f: F) -> Result<T>
where
F: FnOnce(BorrowedFd) -> Result<T>,
{
unimplemented!()
}
}
#[derive(Debug, Default)]
pub struct FakeIoeventFd;
impl AsFd for FakeIoeventFd {
fn as_fd(&self) -> BorrowedFd<'_> {
unreachable!()
}
}
impl IoeventFd for FakeIoeventFd {}