1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use alloc::vec::Vec;
use crate::{PhysAddr, KHANDLER, PAGE_SIZE};
#[derive(Debug)]
pub struct PhysFrame {
paddr: PhysAddr,
allocated: bool,
}
impl PhysFrame {
pub fn new() -> Option<Self> {
KHANDLER.frame_alloc().map(|paddr| Self {
paddr,
allocated: true,
})
}
pub fn new_zero() -> Option<Self> {
Self::new().map(|mut f| {
f.zero();
f
})
}
fn alloc_contiguous_base(frame_count: usize, align_log2: usize) -> Option<PhysAddr> {
KHANDLER.frame_alloc_contiguous(frame_count, align_log2)
}
pub fn new_contiguous(frame_count: usize, align_log2: usize) -> Vec<Self> {
Self::alloc_contiguous_base(frame_count, align_log2).map_or(Vec::new(), |base| {
(0..frame_count)
.map(|i| Self {
paddr: base + i * PAGE_SIZE,
allocated: true,
})
.collect()
})
}
pub unsafe fn from_paddr(paddr: PhysAddr) -> Self {
assert!(crate::addr::is_aligned(paddr));
Self {
paddr,
allocated: false,
}
}
pub fn paddr(&self) -> PhysAddr {
self.paddr
}
pub fn as_ptr(&self) -> *const u8 {
crate::mem::phys_to_virt(self.paddr) as *const u8
}
pub fn as_mut_ptr(&self) -> *mut u8 {
crate::mem::phys_to_virt(self.paddr) as *mut u8
}
pub fn zero(&mut self) {
crate::mem::pmem_zero(self.paddr, PAGE_SIZE);
}
}
impl Drop for PhysFrame {
fn drop(&mut self) {
if self.allocated {
KHANDLER.frame_dealloc(self.paddr)
}
}
}
lazy_static! {
pub static ref ZERO_FRAME: PhysFrame = PhysFrame::new_zero().expect("failed to alloc zero frame");
}