Fetch buffer in user space as a Vec.

This commit is contained in:
Yifan Wu 2020-12-07 18:07:19 +08:00
parent 064f1cb5cb
commit f54573ae15
6 changed files with 49 additions and 15 deletions

View file

@ -1,4 +1,4 @@
use super::{frame_alloc, PhysPageNum, FrameTracker, VirtPageNum};
use super::{frame_alloc, PhysPageNum, FrameTracker, VirtPageNum, VirtAddr, StepByOne};
use alloc::vec::Vec;
use alloc::vec;
use bitflags::*;
@ -69,9 +69,9 @@ impl PageTable {
}
}
/// Temporarily used to get arguments from user space.
pub fn from_root_ppn(root_ppn: PhysPageNum) -> Self {
pub fn from_token(satp: usize) -> Self {
Self {
root_ppn,
root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
frames: Vec::new(),
}
}
@ -95,6 +95,8 @@ impl PageTable {
result
}
fn find_pte(&self, vpn: VirtPageNum) -> Option<&PageTableEntry> {
//println!("into find_pte");
//println!("root_ppn = {:?}", self.root_ppn);
let idxs = vpn.indexes();
let mut ppn = self.root_ppn;
let mut result: Option<&PageTableEntry> = None;
@ -123,10 +125,37 @@ impl PageTable {
*pte = PageTableEntry::empty();
}
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
//println!("into PageTable::translate");
self.find_pte(vpn)
.map(|pte| {pte.clone()})
}
pub fn token(&self) -> usize {
8usize << 60 | self.root_ppn.0
}
}
pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static [u8]> {
//println!("into translated_byte_buffer!");
let page_table = PageTable::from_token(token);
let mut start = ptr as usize;
let end = start + len;
//println!("start={:#x},end={:#x}", start, end);
let mut v = Vec::new();
while start < end {
//println!("start={:#x}", start);
let start_va = VirtAddr::from(start);
let mut vpn = start_va.floor();
//println!("vpn={:?}", vpn);
let ppn = page_table
.translate(vpn)
.unwrap()
.ppn();
//println!("ppn={:?}", ppn);
vpn.step();
let mut end_va: VirtAddr = vpn.into();
end_va = end_va.min(VirtAddr::from(end));
v.push(&ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
start = end_va.into();
}
v
}