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