1use ax_memory_addr::{PhysAddr, VirtAddr};
2
3use crate::{AllocResult, PAGE_SIZE, UsageKind, global_allocator};
4
5#[derive(Debug)]
9pub struct GlobalPage {
10 start_vaddr: VirtAddr,
11 num_pages: usize,
12}
13
14impl GlobalPage {
15 pub fn alloc() -> AllocResult<Self> {
17 let vaddr = global_allocator().alloc_pages(1, PAGE_SIZE, UsageKind::Global)?;
18 Ok(Self {
19 start_vaddr: vaddr.into(),
20 num_pages: 1,
21 })
22 }
23
24 pub fn alloc_zero() -> AllocResult<Self> {
26 let mut p = Self::alloc()?;
27 p.zero();
28 Ok(p)
29 }
30
31 pub fn alloc_contiguous(num_pages: usize, alignment: usize) -> AllocResult<Self> {
33 let vaddr = global_allocator().alloc_pages(num_pages, alignment, UsageKind::Global)?;
34 Ok(Self {
35 start_vaddr: vaddr.into(),
36 num_pages,
37 })
38 }
39
40 pub fn start_vaddr(&self) -> VirtAddr {
42 self.start_vaddr
43 }
44
45 pub fn start_paddr<F>(&self, virt_to_phys: F) -> PhysAddr
47 where
48 F: FnOnce(VirtAddr) -> PhysAddr,
49 {
50 virt_to_phys(self.start_vaddr)
51 }
52
53 pub fn size(&self) -> usize {
55 self.num_pages * PAGE_SIZE
56 }
57
58 pub fn as_ptr(&self) -> *const u8 {
60 self.start_vaddr.as_ptr()
61 }
62
63 pub fn as_mut_ptr(&mut self) -> *mut u8 {
65 self.start_vaddr.as_mut_ptr()
66 }
67
68 pub fn fill(&mut self, byte: u8) {
70 unsafe { core::ptr::write_bytes(self.as_mut_ptr(), byte, self.size()) }
71 }
72
73 pub fn zero(&mut self) {
75 self.fill(0)
76 }
77
78 pub fn as_slice(&self) -> &[u8] {
80 unsafe { core::slice::from_raw_parts(self.as_ptr(), self.size()) }
81 }
82
83 pub fn as_slice_mut(&mut self) -> &mut [u8] {
85 unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr(), self.size()) }
86 }
87}
88
89impl Drop for GlobalPage {
90 fn drop(&mut self) {
91 global_allocator().dealloc_pages(
92 self.start_vaddr.into(),
93 self.num_pages,
94 UsageKind::Global,
95 );
96 }
97}