kernel_api/memory/
physical.rs1#![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#[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
52pub 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 todo!("Insert new RC node")
111
112 }
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}