Nothing to see here, move along
at main 62 lines 2.2 kB view raw
1#![allow(dead_code)] 2 3use lancer_core::error::KernelError; 4use lancer_core::header::KernelObjectHeader; 5use lancer_core::object_layout::KernelObject; 6use x86_64::PhysAddr; 7 8use crate::mem::addr::phys_to_virt; 9 10unsafe fn read_tag_and_generation(phys: PhysAddr) -> (u8, u32) { 11 let ptr = phys_to_virt(phys).as_ptr::<KernelObjectHeader>(); 12 let tag = unsafe { core::ptr::addr_of!((*ptr).tag).read() }; 13 let generation = unsafe { core::ptr::addr_of!((*ptr).generation).read() }; 14 (tag, generation) 15} 16 17fn validate_tag_and_generation<T: KernelObject>(tag: u8, generation: u32, expected_generation: u32) -> Result<(), KernelError> { 18 match tag == T::TAG as u8 { 19 true => {} 20 false => return Err(KernelError::InvalidType), 21 } 22 match generation != expected_generation { 23 true => Err(KernelError::StaleGeneration), 24 false => Ok(()), 25 } 26} 27 28pub unsafe fn read_header(phys: PhysAddr) -> Result<&'static KernelObjectHeader, KernelError> { 29 match phys.as_u64().is_multiple_of(core::mem::align_of::<KernelObjectHeader>() as u64) { 30 false => Err(KernelError::InvalidAddress), 31 true => { 32 let virt = phys_to_virt(phys); 33 Ok(unsafe { &*(virt.as_ptr::<KernelObjectHeader>()) }) 34 } 35 } 36} 37 38pub unsafe fn read_object<T: KernelObject>( 39 phys: PhysAddr, 40 expected_generation: u32, 41) -> Result<&'static T, KernelError> { 42 match phys.as_u64().is_multiple_of(T::METADATA_ALIGN as u64) { 43 false => return Err(KernelError::InvalidAddress), 44 true => {} 45 } 46 let (tag, generation) = unsafe { read_tag_and_generation(phys) }; 47 validate_tag_and_generation::<T>(tag, generation, expected_generation)?; 48 Ok(unsafe { &*(phys_to_virt(phys).as_ptr::<T>()) }) 49} 50 51pub unsafe fn write_object<T: KernelObject>( 52 phys: PhysAddr, 53 expected_generation: u32, 54) -> Result<*mut T, KernelError> { 55 match phys.as_u64().is_multiple_of(T::METADATA_ALIGN as u64) { 56 false => return Err(KernelError::InvalidAddress), 57 true => {} 58 } 59 let (tag, generation) = unsafe { read_tag_and_generation(phys) }; 60 validate_tag_and_generation::<T>(tag, generation, expected_generation)?; 61 Ok(phys_to_virt(phys).as_mut_ptr::<T>()) 62}