use super::hypercalls::{cpuid_signature, hyp_io_read, hyp_io_write};
use crate::{
hal::PhysAddr,
transport::pci::bus::{Cam, ConfigurationAccess, DeviceFunction},
};
const PKVM_SIGNATURE: &[u8] = b"PKVM";
pub struct HypCam {
phys_base: PhysAddr,
cam: Cam,
}
impl HypCam {
pub fn new(phys_base: PhysAddr, cam: Cam) -> Self {
Self { phys_base, cam }
}
pub fn is_pkvm() -> bool {
cpuid_signature() == PKVM_SIGNATURE
}
}
impl ConfigurationAccess for HypCam {
fn read_word(&self, device_function: DeviceFunction, register_offset: u8) -> u32 {
let address = self.cam.cam_offset(device_function, register_offset);
hyp_io_read(self.phys_base + u64::from(address), 4) as u32
}
fn write_word(&mut self, device_function: DeviceFunction, register_offset: u8, data: u32) {
let address = self.cam.cam_offset(device_function, register_offset);
hyp_io_write(self.phys_base + u64::from(address), 4, data.into());
}
unsafe fn unsafe_clone(&self) -> Self {
Self {
phys_base: self.phys_base,
cam: self.cam,
}
}
}