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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use alloc::{string::String, vec::Vec};
use core::{
marker::PhantomData,
ops::{Deref, DerefMut},
};
use crate::{
constant::PAGE_SIZE,
mem::{address::PageRange, page_table::PageTable, PageNumber, VirtualAddress},
};
#[repr(C)]
#[derive(Clone, Copy)]
pub struct UserPtr<T> {
satp: usize,
ptr: *mut T,
phantom: PhantomData<T>,
}
unsafe impl<T: Clone + Copy + 'static> Send for UserPtr<T> {}
unsafe impl<T: Clone + Copy + 'static> Sync for UserPtr<T> {}
impl<T> UserPtr<T> {
pub fn new(satp: usize, ptr: usize) -> Self {
Self {
satp,
ptr: ptr as *mut T,
phantom: PhantomData,
}
}
pub fn as_string(&self) -> String {
let page_table = PageTable::from_satp(self.satp);
let mut virtual_address = VirtualAddress::from(self.ptr as usize);
let mut string = String::new();
loop {
let char_pointer = page_table.translate(virtual_address).unwrap().as_ptr() as *const u8;
let char = unsafe { *char_pointer as char };
if char == '\0' {
break;
}
string.push(char);
virtual_address += 1;
}
string
}
pub fn as_buffer(&self, length: usize) -> Vec<&'static [u8]> {
let page_table = PageTable::from_satp(self.satp);
let mut translated_buffer = Vec::new();
let buffer_address_start = VirtualAddress::from(self.ptr as usize);
let buffer_address_end = buffer_address_start + length;
let page_range = PageRange::new(
PageNumber::from(buffer_address_start),
PageNumber::from(buffer_address_end).offset(1),
);
for (index, page_number) in page_range.iter().enumerate() {
let frame_number = page_table
.translate_page(page_number)
.unwrap()
.frame_number();
let lower_bound = {
if index == 0 {
buffer_address_start.page_offset()
} else {
0
}
};
let upper_bound = {
if index == page_range.len() - 1 {
buffer_address_end.page_offset()
} else {
PAGE_SIZE
}
};
translated_buffer.push(&frame_number.as_bytes()[lower_bound..upper_bound]);
}
translated_buffer
}
}
impl<T: 'static> Deref for UserPtr<T> {
type Target = T;
fn deref(&self) -> &T {
let page_table = PageTable::from_satp(self.satp);
let virtual_address = VirtualAddress::from(self.ptr as usize);
page_table.translate(virtual_address).unwrap().as_ref()
}
}
impl<T: 'static> DerefMut for UserPtr<T> {
fn deref_mut(&mut self) -> &mut T {
let page_table = PageTable::from_satp(self.satp);
let virtual_address = VirtualAddress::from(self.ptr as usize);
page_table.translate(virtual_address).unwrap().as_mut()
}
}