#![allow(dead_code)] use lancer_core::error::KernelError; use lancer_core::header::KernelObjectHeader; use lancer_core::object_layout::KernelObject; use x86_64::PhysAddr; use crate::mem::addr::phys_to_virt; unsafe fn read_tag_and_generation(phys: PhysAddr) -> (u8, u32) { let ptr = phys_to_virt(phys).as_ptr::(); let tag = unsafe { core::ptr::addr_of!((*ptr).tag).read() }; let generation = unsafe { core::ptr::addr_of!((*ptr).generation).read() }; (tag, generation) } fn validate_tag_and_generation(tag: u8, generation: u32, expected_generation: u32) -> Result<(), KernelError> { match tag == T::TAG as u8 { true => {} false => return Err(KernelError::InvalidType), } match generation != expected_generation { true => Err(KernelError::StaleGeneration), false => Ok(()), } } pub unsafe fn read_header(phys: PhysAddr) -> Result<&'static KernelObjectHeader, KernelError> { match phys.as_u64().is_multiple_of(core::mem::align_of::() as u64) { false => Err(KernelError::InvalidAddress), true => { let virt = phys_to_virt(phys); Ok(unsafe { &*(virt.as_ptr::()) }) } } } pub unsafe fn read_object( phys: PhysAddr, expected_generation: u32, ) -> Result<&'static T, KernelError> { match phys.as_u64().is_multiple_of(T::METADATA_ALIGN as u64) { false => return Err(KernelError::InvalidAddress), true => {} } let (tag, generation) = unsafe { read_tag_and_generation(phys) }; validate_tag_and_generation::(tag, generation, expected_generation)?; Ok(unsafe { &*(phys_to_virt(phys).as_ptr::()) }) } pub unsafe fn write_object( phys: PhysAddr, expected_generation: u32, ) -> Result<*mut T, KernelError> { match phys.as_u64().is_multiple_of(T::METADATA_ALIGN as u64) { false => return Err(KernelError::InvalidAddress), true => {} } let (tag, generation) = unsafe { read_tag_and_generation(phys) }; validate_tag_and_generation::(tag, generation, expected_generation)?; Ok(phys_to_virt(phys).as_mut_ptr::()) }