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