use bit_field::BitField;
use bitflags::bitflags;
use crate::msr::{Msr, MsrReadWrite};
bitflags! {
pub struct VmCrFlags: u64 {
const DPD = 1 << 0;
const R_INIT = 1 << 1;
const DIS_A20M = 1 << 2;
const LOCK = 1 << 3;
const SVMDIS = 1 << 4;
}
}
pub struct VmCr;
impl MsrReadWrite for VmCr {
const MSR: Msr = Msr::VM_CR;
}
impl VmCr {
pub fn read() -> VmCrFlags {
VmCrFlags::from_bits_truncate(Self::read_raw())
}
}
bitflags! {
pub struct VmcbCleanBits: u32 {
const I = 1 << 0;
const IOPM = 1 << 1;
const ASID = 1 << 2;
const TPR = 1 << 3;
const NP = 1 << 4;
const CR_X = 1 << 5;
const DR_X = 1 << 6;
const DT = 1 << 7;
const SEG = 1 << 8;
const CR2 = 1 << 9;
const LBR = 1 << 10;
const AVIC = 1 << 11;
const CET = 1 << 12;
const UNMODIFIED = 0xffff_ffff;
}
}
bitflags! {
pub struct VmcbIntInfo: u32 {
const ERROR_CODE = 1 << 11;
const VALID = 1 << 31;
}
}
#[repr(u32)]
#[derive(Debug)]
pub enum InterruptType {
External = 0,
Nmi = 2,
Exception = 3,
SoftIntr = 4,
}
impl VmcbIntInfo {
fn has_error_code(vector: u8) -> bool {
matches!(vector, 8 | 10 | 11 | 12 | 13 | 14 | 17)
}
pub fn from(int_type: InterruptType, vector: u8) -> Self {
let mut bits = vector as u32;
bits.set_bits(8..11, int_type as u32);
let mut info = Self::from_bits_retain(bits) | Self::VALID;
if Self::has_error_code(vector) {
info |= Self::ERROR_CODE;
}
info
}
}
#[repr(u8)]
#[derive(Debug)]
pub enum VmcbTlbControl {
DoNotFlush = 0,
FlushAll = 0x01,
FlushAsid = 0x03,
FlushAsidNonGlobal = 0x07,
}