Nothing to see here, move along
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}