use crate::{error::Result, exit::VmExit};
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum Regs {
X86_64 {
rip: u64,
rsp: u64,
gprs: [u64; 16],
},
Aarch64 {
pc: u64,
sp_el1: u64,
gprs: [u64; 31],
pstate: u64,
},
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
pub struct Irq {
pub id: u32,
pub level: bool,
}
impl Irq {
pub const fn edge(id: u32) -> Self {
Self { id, level: false }
}
pub const fn level(id: u32) -> Self {
Self { id, level: true }
}
}
pub trait Vcpu: Send {
fn run(&mut self) -> Result<VmExit>;
fn cancel(&self);
fn get_regs(&self) -> Result<Regs>;
fn set_regs(&mut self, regs: &Regs) -> Result<()>;
fn inject_irq(&mut self, irq: Irq) -> Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn irq_constructors_set_level() {
assert!(!Irq::edge(33).level);
assert!(Irq::level(33).level);
}
#[test]
fn aarch64_regs_have_31_gprs() {
let r = Regs::Aarch64 {
pc: 0,
sp_el1: 0,
gprs: [0; 31],
pstate: 0,
};
match r {
Regs::Aarch64 { gprs, .. } => assert_eq!(gprs.len(), 31),
Regs::X86_64 { .. } => unreachable!(),
}
}
}