kernel_api/memory/
physical.rs

1#![unstable(feature = "kernel_internals", issue = "none")]
2
3use core::fmt::{Debug, Formatter};
4use core::mem::ManuallyDrop;
5use core::num::NonZero;
6use crate::memory::allocator::{PhysicalAllocator, Location, SpecificLocation};
7use crate::memory::{AllocError, Frame};
8use crate::sync::RwSpinlock;
9
10#[unstable(feature = "kernel_internals", issue = "none")]
11pub struct GlobalAllocator {
12	#[unstable(feature = "kernel_internals", issue = "none")]
13	pub rwlock: RwSpinlock<Option<&'static dyn PhysicalAllocator>>
14}
15
16// todo: can this be a macro?
17#[unstable(feature = "kernel_internals", issue = "none")]
18unsafe impl PhysicalAllocator for GlobalAllocator {
19	fn allocate_contiguous(&self, frame_count: usize) -> Result<Frame, AllocError> {
20		self.rwlock.read()
21				.expect("No global allocator set")
22				.allocate_contiguous(frame_count)
23	}
24
25	unsafe fn deallocate_contiguous(&self, base: Frame, frame_count: NonZero<usize>) {
26		self.rwlock.read()
27		    .expect("No global allocator set")
28		    .deallocate_contiguous(base, frame_count)
29	}
30
31	fn allocate_at(&self, frame_count: usize, location: SpecificLocation) -> Result<Frame, AllocError> {
32		self.rwlock.read()
33		    .expect("No global allocator set")
34		    .allocate_at(frame_count, location)
35	}
36}
37
38#[unstable(feature = "kernel_internals", issue = "none")]
39#[inline]
40#[track_caller]
41pub fn highmem() -> &'static GlobalAllocator {
42	unsafe { &crate::bridge::memory::GLOBAL_HIGHMEM }
43}
44
45#[unstable(feature = "kernel_internals", issue = "none")]
46#[inline]
47#[track_caller]
48pub fn dmamem() -> &'static GlobalAllocator {
49	unsafe { &crate::bridge::memory::GLOBAL_DMA }
50}
51
52/// Conceptually the same as a hypothetical `Arc<[Frame]>`
53///
54/// # Invariants
55///
56/// Internal implementation assumes that two `OwnedFrames` cannot overlap unless they came from the same original `OwnedFrames`
57/// object
58pub struct OwnedFrames<'allocator> {
59	pub(super) base: Frame,
60	pub(super) len: NonZero<usize>,
61	allocator: &'allocator dyn PhysicalAllocator
62}
63
64impl Debug for OwnedFrames<'_> {
65	fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
66		f.debug_struct("OwnedFrames")
67				.field("base", &self.base)
68				.field("len", &self.len)
69				.field("allocator", &"<physical allocator>")
70				.finish()
71	}
72}
73
74impl OwnedFrames<'static> {
75	pub fn new(count: NonZero<usize>) -> Result<Self, AllocError> {
76		Self::new_with(count, highmem())
77	}
78}
79
80impl<'a> OwnedFrames<'a> {
81	pub fn new_with(count: NonZero<usize>, allocator: &'a dyn PhysicalAllocator) -> Result<Self, AllocError> {
82		let base = allocator.allocate_contiguous(count.get())?;
83		Ok(OwnedFrames {
84			base,
85			len: count,
86			allocator
87		})
88	}
89
90	pub fn xnew(count: NonZero<usize>, allocator: &'a dyn PhysicalAllocator, location: Location) -> Result<Self, AllocError> {
91		match location {
92			Location::Any => Self::new_with(count, allocator),
93			Location::Specific(loc) => {
94				let base = allocator.allocate_at(count.get(), loc)?;
95				Ok(OwnedFrames {
96					base,
97					len: count,
98					allocator
99				})
100			},
101		}
102	}
103
104	fn split_at(self, n: NonZero<usize>) -> (Self, Self) {
105		assert!(n <= self.len);
106
107		/*let second_base = self.base + n.get();
108		let lens = (n, self.len - n);*/
109
110		todo!("Insert new RC node")
111
112		//(Self { base: self.base, len: lens.0 }, Self { base: second_base, len: lens.1 })
113	}
114
115	pub fn into_raw_parts(self) -> (Frame, NonZero<usize>, &'a dyn PhysicalAllocator) {
116		let this = ManuallyDrop::new(self);
117		(this.base, this.len, this.allocator)
118	}
119
120	pub unsafe fn from_raw_parts(base: Frame, len: NonZero<usize>, allocator: &'a dyn PhysicalAllocator) -> Self {
121		Self {
122			base, len, allocator
123		}
124	}
125}
126
127impl Clone for OwnedFrames<'_> {
128	fn clone(&self) -> Self {
129		todo!("Update RC nodes");
130		Self { .. *self }
131	}
132}
133
134impl Drop for OwnedFrames<'_> {
135	fn drop(&mut self) {
136		unsafe {
137			self.allocator.deallocate_contiguous(self.base, self.len);
138		}
139	}
140}