use crate::addr::SHIM_VIRT_OFFSET;
use crate::snp::get_cbit_mask;
use spinning::{Lazy, RwLock};
use x86_64::registers::control::Cr3;
use x86_64::structures::paging::mapper::PageTableFrameMapping;
use x86_64::structures::paging::{MappedPageTable, PageTable, PhysFrame};
use x86_64::VirtAddr;
#[derive(Debug)]
pub struct EncPhysOffset {
pub offset: VirtAddr,
pub c_bit_mask: u64,
}
impl Default for EncPhysOffset {
fn default() -> Self {
EncPhysOffset {
offset: VirtAddr::new(SHIM_VIRT_OFFSET as u64),
c_bit_mask: get_cbit_mask(),
}
}
}
unsafe impl PageTableFrameMapping for EncPhysOffset {
fn frame_to_pointer(&self, frame: PhysFrame) -> *mut PageTable {
let phys_start_address = frame.start_address().as_u64();
assert_eq!(phys_start_address & self.c_bit_mask, self.c_bit_mask);
let virt = self.offset + (phys_start_address & !self.c_bit_mask);
virt.as_mut_ptr()
}
}
pub static SHIM_PAGETABLE: Lazy<RwLock<MappedPageTable<'static, EncPhysOffset>>> =
Lazy::new(|| {
let enc_phys_offset = EncPhysOffset::default();
let enc_offset_page_table = unsafe {
let level_4_table_ptr = enc_phys_offset.frame_to_pointer(Cr3::read().0);
MappedPageTable::new(&mut *level_4_table_ptr, enc_phys_offset)
};
RwLock::<MappedPageTable<'static, EncPhysOffset>>::const_new(
spinning::RawRwLock::const_new(),
enc_offset_page_table,
)
});