mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Refactor the source structure in aster_frame::mm
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
e8595b95fe
commit
7095b37e7e
@ -56,7 +56,7 @@ use aster_frame::cpu::UserContext;
|
|||||||
use aster_frame::prelude::*;
|
use aster_frame::prelude::*;
|
||||||
use aster_frame::task::{Task, TaskOptions};
|
use aster_frame::task::{Task, TaskOptions};
|
||||||
use aster_frame::user::{ReturnReason, UserMode, UserSpace};
|
use aster_frame::user::{ReturnReason, UserMode, UserSpace};
|
||||||
use aster_frame::mm::{PageFlags, PAGE_SIZE, Vaddr, VmAllocOptions, VmIo, VmMapOptions, VmSpace};
|
use aster_frame::mm::{PageFlags, PAGE_SIZE, Vaddr, FrameAllocOptions, VmIo, VmMapOptions, VmSpace};
|
||||||
|
|
||||||
/// The kernel's boot and initialization process is managed by Asterinas Framework.
|
/// The kernel's boot and initialization process is managed by Asterinas Framework.
|
||||||
/// After the process is done, the kernel's execution environment
|
/// After the process is done, the kernel's execution environment
|
||||||
@ -73,7 +73,7 @@ pub fn main() {
|
|||||||
fn create_user_space(program: &[u8]) -> UserSpace {
|
fn create_user_space(program: &[u8]) -> UserSpace {
|
||||||
let user_pages = {
|
let user_pages = {
|
||||||
let nframes = program.len().align_up(PAGE_SIZE) / PAGE_SIZE;
|
let nframes = program.len().align_up(PAGE_SIZE) / PAGE_SIZE;
|
||||||
let vm_frames = VmAllocOptions::new(nframes).alloc().unwrap();
|
let vm_frames = FrameAllocOptions::new(nframes).alloc().unwrap();
|
||||||
// Phyiscal memory pages can be only accessed
|
// Phyiscal memory pages can be only accessed
|
||||||
// via the Frame abstraction.
|
// via the Frame abstraction.
|
||||||
vm_frames.write_bytes(0, program).unwrap();
|
vm_frames.write_bytes(0, program).unwrap();
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
dma::Daddr,
|
dma::Daddr,
|
||||||
page_prop::{CachePolicy, PageProperty, PrivilegedPageFlags as PrivFlags},
|
page_prop::{CachePolicy, PageProperty, PrivilegedPageFlags as PrivFlags},
|
||||||
page_table::PageTableError,
|
page_table::PageTableError,
|
||||||
Frame, Paddr, PageFlags, PageTable, VmAllocOptions, VmIo, PAGE_SIZE,
|
Frame, FrameAllocOptions, Paddr, PageFlags, PageTable, VmIo, PAGE_SIZE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ pub enum ContextTableError {
|
|||||||
impl RootTable {
|
impl RootTable {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
root_frame: VmAllocOptions::new(1).alloc_single().unwrap(),
|
root_frame: FrameAllocOptions::new(1).alloc_single().unwrap(),
|
||||||
context_tables: BTreeMap::new(),
|
context_tables: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ pub struct ContextTable {
|
|||||||
impl ContextTable {
|
impl ContextTable {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
entries_frame: VmAllocOptions::new(1).alloc_single().unwrap(),
|
entries_frame: FrameAllocOptions::new(1).alloc_single().unwrap(),
|
||||||
page_tables: BTreeMap::new(),
|
page_tables: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,14 @@ use tdx_guest::init_tdx;
|
|||||||
|
|
||||||
pub use self::{cpu::CpuLocal, error::Error, prelude::Result};
|
pub use self::{cpu::CpuLocal, error::Error, prelude::Result};
|
||||||
|
|
||||||
|
/// Initialize the framework.
|
||||||
|
///
|
||||||
|
/// This function represents the first phase booting up the system. It makes
|
||||||
|
/// all functionalities of the framework available after the call.
|
||||||
|
///
|
||||||
|
/// TODO: We need to refactor this function to make it more modular and
|
||||||
|
/// make inter-initialization-dependencies more clear and reduce usages of
|
||||||
|
/// boot stage only global variables.
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
arch::before_all_init();
|
arch::before_all_init();
|
||||||
logger::init();
|
logger::init();
|
||||||
|
@ -190,11 +190,11 @@ mod test {
|
|||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mm::VmAllocOptions;
|
use crate::mm::FrameAllocOptions;
|
||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn map_with_coherent_device() {
|
fn map_with_coherent_device() {
|
||||||
let vm_segment = VmAllocOptions::new(1)
|
let vm_segment = FrameAllocOptions::new(1)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -204,7 +204,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn map_with_incoherent_device() {
|
fn map_with_incoherent_device() {
|
||||||
let vm_segment = VmAllocOptions::new(1)
|
let vm_segment = FrameAllocOptions::new(1)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -217,7 +217,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn duplicate_map() {
|
fn duplicate_map() {
|
||||||
let vm_segment_parent = VmAllocOptions::new(2)
|
let vm_segment_parent = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -229,7 +229,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn read_and_write() {
|
fn read_and_write() {
|
||||||
let vm_segment = VmAllocOptions::new(2)
|
let vm_segment = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -244,7 +244,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn reader_and_wirter() {
|
fn reader_and_wirter() {
|
||||||
let vm_segment = VmAllocOptions::new(2)
|
let vm_segment = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -294,11 +294,11 @@ mod test {
|
|||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mm::VmAllocOptions;
|
use crate::mm::FrameAllocOptions;
|
||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn streaming_map() {
|
fn streaming_map() {
|
||||||
let vm_segment = VmAllocOptions::new(1)
|
let vm_segment = FrameAllocOptions::new(1)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -309,7 +309,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn duplicate_map() {
|
fn duplicate_map() {
|
||||||
let vm_segment_parent = VmAllocOptions::new(2)
|
let vm_segment_parent = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -322,7 +322,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn read_and_write() {
|
fn read_and_write() {
|
||||||
let vm_segment = VmAllocOptions::new(2)
|
let vm_segment = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -338,7 +338,7 @@ mod test {
|
|||||||
|
|
||||||
#[ktest]
|
#[ktest]
|
||||||
fn reader_and_wirter() {
|
fn reader_and_wirter() {
|
||||||
let vm_segment = VmAllocOptions::new(2)
|
let vm_segment = FrameAllocOptions::new(2)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -9,15 +9,15 @@ use crate::{
|
|||||||
|
|
||||||
/// A collection of base page frames (regular physical memory pages).
|
/// A collection of base page frames (regular physical memory pages).
|
||||||
///
|
///
|
||||||
/// For the most parts, `VmFrameVec` is like `Vec<Frame>`. But the
|
/// For the most parts, `FrameVec` is like `Vec<Frame>`. But the
|
||||||
/// implementation may or may not be based on `Vec`. Having a dedicated
|
/// implementation may or may not be based on `Vec`. Having a dedicated
|
||||||
/// type to represent a series of page frames is convenient because,
|
/// type to represent a series of page frames is convenient because,
|
||||||
/// more often than not, one needs to operate on a batch of frames rather
|
/// more often than not, one needs to operate on a batch of frames rather
|
||||||
/// a single frame.
|
/// a single frame.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VmFrameVec(pub(crate) Vec<Frame>);
|
pub struct FrameVec(pub(crate) Vec<Frame>);
|
||||||
|
|
||||||
impl VmFrameVec {
|
impl FrameVec {
|
||||||
pub fn get(&self, index: usize) -> Option<&Frame> {
|
pub fn get(&self, index: usize) -> Option<&Frame> {
|
||||||
self.0.get(index)
|
self.0.get(index)
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ impl VmFrameVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Append some frames.
|
/// Append some frames.
|
||||||
pub fn append(&mut self, more: &mut VmFrameVec) -> Result<()> {
|
pub fn append(&mut self, more: &mut FrameVec) -> Result<()> {
|
||||||
self.0.append(&mut more.0);
|
self.0.append(&mut more.0);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ impl VmFrameVec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for VmFrameVec {
|
impl IntoIterator for FrameVec {
|
||||||
type Item = Frame;
|
type Item = Frame;
|
||||||
|
|
||||||
type IntoIter = alloc::vec::IntoIter<Self::Item>;
|
type IntoIter = alloc::vec::IntoIter<Self::Item>;
|
||||||
@ -99,7 +99,7 @@ impl IntoIterator for VmFrameVec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VmIo for VmFrameVec {
|
impl VmIo for FrameVec {
|
||||||
fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
||||||
// Do bound check with potential integer overflow in mind
|
// Do bound check with potential integer overflow in mind
|
||||||
let max_offset = offset.checked_add(buf.len()).ok_or(Error::Overflow)?;
|
let max_offset = offset.checked_add(buf.len()).ok_or(Error::Overflow)?;
|
||||||
@ -143,12 +143,12 @@ impl VmIo for VmFrameVec {
|
|||||||
|
|
||||||
/// An iterator for frames.
|
/// An iterator for frames.
|
||||||
pub struct FrameVecIter<'a> {
|
pub struct FrameVecIter<'a> {
|
||||||
frames: &'a VmFrameVec,
|
frames: &'a FrameVec,
|
||||||
current: usize,
|
current: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FrameVecIter<'a> {
|
impl<'a> FrameVecIter<'a> {
|
||||||
pub fn new(frames: &'a VmFrameVec) -> Self {
|
pub fn new(frames: &'a FrameVec) -> Self {
|
||||||
Self { frames, current: 0 }
|
Self { frames, current: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,23 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//! Untyped physical memory management.
|
||||||
|
//!
|
||||||
|
//! A frame is a special page (defined in [`super::page`]) that is _untyped_
|
||||||
|
//! memory. It is used to store data irrelevant to the integrity of the kernel.
|
||||||
|
//! All pages mapped to the virtual address space of the users are backed by
|
||||||
|
//! frames. Frames, with all the properties of pages, can additionally be safely
|
||||||
|
//! read and written by the kernel or the user.
|
||||||
|
|
||||||
|
pub mod frame_vec;
|
||||||
|
pub mod options;
|
||||||
|
pub mod segment;
|
||||||
|
|
||||||
use core::mem::ManuallyDrop;
|
use core::mem::ManuallyDrop;
|
||||||
|
|
||||||
use super::{
|
pub use frame_vec::{FrameVec, FrameVecIter};
|
||||||
|
pub use segment::Segment;
|
||||||
|
|
||||||
|
use super::page::{
|
||||||
allocator,
|
allocator,
|
||||||
meta::{FrameMeta, MetaSlot, PageMeta, PageUsage},
|
meta::{FrameMeta, MetaSlot, PageMeta, PageUsage},
|
||||||
Page,
|
Page,
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::{page::allocator, Frame, Segment, VmFrameVec};
|
use super::{Frame, FrameVec, Segment};
|
||||||
use crate::{prelude::*, Error};
|
use crate::{mm::page::allocator, prelude::*, Error};
|
||||||
|
|
||||||
/// Options for allocating physical memory pages (or frames).
|
/// Options for allocating physical memory pages (or frames).
|
||||||
///
|
///
|
||||||
@ -10,13 +10,13 @@ use crate::{prelude::*, Error};
|
|||||||
/// may store Rust objects or affect Rust memory safety, e.g.,
|
/// may store Rust objects or affect Rust memory safety, e.g.,
|
||||||
/// the code and data segments of the OS kernel, the stack and heap
|
/// the code and data segments of the OS kernel, the stack and heap
|
||||||
/// allocated for the OS kernel.
|
/// allocated for the OS kernel.
|
||||||
pub struct VmAllocOptions {
|
pub struct FrameAllocOptions {
|
||||||
nframes: usize,
|
nframes: usize,
|
||||||
is_contiguous: bool,
|
is_contiguous: bool,
|
||||||
uninit: bool,
|
uninit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VmAllocOptions {
|
impl FrameAllocOptions {
|
||||||
/// Creates new options for allocating the specified number of frames.
|
/// Creates new options for allocating the specified number of frames.
|
||||||
pub fn new(nframes: usize) -> Self {
|
pub fn new(nframes: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -46,7 +46,7 @@ impl VmAllocOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a collection of page frames according to the given options.
|
/// Allocate a collection of page frames according to the given options.
|
||||||
pub fn alloc(&self) -> Result<VmFrameVec> {
|
pub fn alloc(&self) -> Result<FrameVec> {
|
||||||
let frames = if self.is_contiguous {
|
let frames = if self.is_contiguous {
|
||||||
allocator::alloc(self.nframes).ok_or(Error::NoMemory)?
|
allocator::alloc(self.nframes).ok_or(Error::NoMemory)?
|
||||||
} else {
|
} else {
|
||||||
@ -54,7 +54,7 @@ impl VmAllocOptions {
|
|||||||
for _ in 0..self.nframes {
|
for _ in 0..self.nframes {
|
||||||
frame_list.push(allocator::alloc_single().ok_or(Error::NoMemory)?);
|
frame_list.push(allocator::alloc_single().ok_or(Error::NoMemory)?);
|
||||||
}
|
}
|
||||||
VmFrameVec(frame_list)
|
FrameVec(frame_list)
|
||||||
};
|
};
|
||||||
if !self.uninit {
|
if !self.uninit {
|
||||||
for frame in frames.iter() {
|
for frame in frames.iter() {
|
||||||
@ -102,9 +102,9 @@ impl VmAllocOptions {
|
|||||||
fn test_alloc_dealloc() {
|
fn test_alloc_dealloc() {
|
||||||
// Here we allocate and deallocate frames in random orders to test the allocator.
|
// Here we allocate and deallocate frames in random orders to test the allocator.
|
||||||
// We expect the test to fail if the underlying implementation panics.
|
// We expect the test to fail if the underlying implementation panics.
|
||||||
let single_options = VmAllocOptions::new(1);
|
let single_options = FrameAllocOptions::new(1);
|
||||||
let multi_options = VmAllocOptions::new(10);
|
let multi_options = FrameAllocOptions::new(10);
|
||||||
let mut contiguous_options = VmAllocOptions::new(10);
|
let mut contiguous_options = FrameAllocOptions::new(10);
|
||||||
contiguous_options.is_contiguous(true);
|
contiguous_options.is_contiguous(true);
|
||||||
let mut remember_vec = Vec::new();
|
let mut remember_vec = Vec::new();
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
@ -2,19 +2,22 @@
|
|||||||
|
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
use super::{
|
use super::Frame;
|
||||||
allocator,
|
|
||||||
meta::{PageMeta, PageUsage, SegmentHeadMeta},
|
|
||||||
Frame, Page,
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mm::{HasPaddr, Paddr, VmIo, VmReader, VmWriter, PAGE_SIZE},
|
mm::{
|
||||||
|
page::{
|
||||||
|
allocator,
|
||||||
|
meta::{PageMeta, PageUsage, SegmentHeadMeta},
|
||||||
|
Page,
|
||||||
|
},
|
||||||
|
HasPaddr, Paddr, VmIo, VmReader, VmWriter, PAGE_SIZE,
|
||||||
|
},
|
||||||
Error, Result,
|
Error, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A handle to a contiguous range of page frames (physical memory pages).
|
/// A handle to a contiguous range of page frames (physical memory pages).
|
||||||
///
|
///
|
||||||
/// The biggest difference between `Segment` and `VmFrameVec` is that
|
/// The biggest difference between `Segment` and `FrameVec` is that
|
||||||
/// the page frames must be contiguous for `Segment`.
|
/// the page frames must be contiguous for `Segment`.
|
||||||
///
|
///
|
||||||
/// A cloned `Segment` refers to the same page frames as the original.
|
/// A cloned `Segment` refers to the same page frames as the original.
|
||||||
@ -24,7 +27,7 @@ use crate::{
|
|||||||
/// #Example
|
/// #Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let vm_segment = VmAllocOptions::new(2)
|
/// let vm_segment = FrameAllocOptions::new(2)
|
||||||
/// .is_contiguous(true)
|
/// .is_contiguous(true)
|
||||||
/// .alloc_contiguous()?;
|
/// .alloc_contiguous()?;
|
||||||
/// vm_segment.write_bytes(0, buf)?;
|
/// vm_segment.write_bytes(0, buf)?;
|
@ -9,7 +9,7 @@ use pod::Pod;
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// A trait that enables reading/writing data from/to a VM object,
|
/// A trait that enables reading/writing data from/to a VM object,
|
||||||
/// e.g., `VmSpace`, `VmFrameVec`, and `Frame`.
|
/// e.g., `VmSpace`, `FrameVec`, and `Frame`.
|
||||||
///
|
///
|
||||||
/// # Concurrency
|
/// # Concurrency
|
||||||
///
|
///
|
||||||
|
@ -9,11 +9,11 @@ pub type Vaddr = usize;
|
|||||||
pub type Paddr = usize;
|
pub type Paddr = usize;
|
||||||
|
|
||||||
pub(crate) mod dma;
|
pub(crate) mod dma;
|
||||||
|
pub mod frame;
|
||||||
pub(crate) mod heap_allocator;
|
pub(crate) mod heap_allocator;
|
||||||
mod io;
|
mod io;
|
||||||
pub(crate) mod kspace;
|
pub(crate) mod kspace;
|
||||||
mod offset;
|
mod offset;
|
||||||
mod options;
|
|
||||||
pub(crate) mod page;
|
pub(crate) mod page;
|
||||||
pub(crate) mod page_prop;
|
pub(crate) mod page_prop;
|
||||||
pub(crate) mod page_table;
|
pub(crate) mod page_table;
|
||||||
@ -26,9 +26,8 @@ use spin::Once;
|
|||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
dma::{Daddr, DmaCoherent, DmaDirection, DmaStream, DmaStreamSlice, HasDaddr},
|
dma::{Daddr, DmaCoherent, DmaDirection, DmaStream, DmaStreamSlice, HasDaddr},
|
||||||
|
frame::{options::FrameAllocOptions, Frame, FrameVec, FrameVecIter, Segment},
|
||||||
io::{VmIo, VmReader, VmWriter},
|
io::{VmIo, VmReader, VmWriter},
|
||||||
options::VmAllocOptions,
|
|
||||||
page::{Frame, FrameVecIter, Segment, VmFrameVec},
|
|
||||||
page_prop::{CachePolicy, PageFlags, PageProperty},
|
page_prop::{CachePolicy, PageFlags, PageProperty},
|
||||||
space::{VmMapOptions, VmSpace},
|
space::{VmMapOptions, VmSpace},
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//! The physical page memory allocator.
|
||||||
|
//!
|
||||||
|
//! TODO: Decouple it with the frame allocator in [`crate::mm::frame::options`] by
|
||||||
|
//! allocating pages rather untyped memory from this module.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use align_ext::AlignExt;
|
use align_ext::AlignExt;
|
||||||
@ -7,12 +12,16 @@ use buddy_system_allocator::FrameAllocator;
|
|||||||
use log::info;
|
use log::info;
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
use super::{meta::FrameMeta, Frame, Page, Segment, VmFrameVec};
|
use super::{meta::FrameMeta, Page};
|
||||||
use crate::{boot::memory_region::MemoryRegionType, mm::PAGE_SIZE, sync::SpinLock};
|
use crate::{
|
||||||
|
boot::memory_region::MemoryRegionType,
|
||||||
|
mm::{Frame, FrameVec, Segment, PAGE_SIZE},
|
||||||
|
sync::SpinLock,
|
||||||
|
};
|
||||||
|
|
||||||
pub(in crate::mm) static FRAME_ALLOCATOR: Once<SpinLock<FrameAllocator>> = Once::new();
|
pub(in crate::mm) static FRAME_ALLOCATOR: Once<SpinLock<FrameAllocator>> = Once::new();
|
||||||
|
|
||||||
pub(crate) fn alloc(nframes: usize) -> Option<VmFrameVec> {
|
pub(crate) fn alloc(nframes: usize) -> Option<FrameVec> {
|
||||||
FRAME_ALLOCATOR
|
FRAME_ALLOCATOR
|
||||||
.get()
|
.get()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -27,7 +36,7 @@ pub(crate) fn alloc(nframes: usize) -> Option<VmFrameVec> {
|
|||||||
};
|
};
|
||||||
vector.push(frame);
|
vector.push(frame);
|
||||||
}
|
}
|
||||||
VmFrameVec(vector)
|
FrameVec(vector)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ pub enum PageUsage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub(super) struct MetaSlot {
|
pub(in crate::mm) struct MetaSlot {
|
||||||
/// The metadata of the page.
|
/// The metadata of the page.
|
||||||
///
|
///
|
||||||
/// The implementation may cast a `*const MetaSlot` to a `*const PageMeta`.
|
/// The implementation may cast a `*const MetaSlot` to a `*const PageMeta`.
|
||||||
@ -139,7 +139,7 @@ impl Sealed for FrameMeta {}
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct SegmentHeadMeta {
|
pub struct SegmentHeadMeta {
|
||||||
/// Length of the segment in bytes.
|
/// Length of the segment in bytes.
|
||||||
pub(super) seg_len: u64,
|
pub(in crate::mm) seg_len: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sealed for SegmentHeadMeta {}
|
impl Sealed for SegmentHeadMeta {}
|
||||||
|
@ -1,33 +1,31 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
//! Managing pages or frames.
|
//! Physical memory page management.
|
||||||
//!
|
//!
|
||||||
//! A page is an aligned, contiguous range of bytes in physical memory. The sizes
|
//! A page is an aligned, contiguous range of bytes in physical memory. The sizes
|
||||||
//! of base pages and huge pages are architecture-dependent. A page can be mapped
|
//! of base pages and huge pages are architecture-dependent. A page can be mapped
|
||||||
//! to a virtual address using the page table.
|
//! to a virtual address using the page table.
|
||||||
//!
|
//!
|
||||||
//! A frame is a special page that is _untyped_ memory. It is used to store data
|
//! Pages can be accessed through page handles, namely, [`Page`]. A page handle
|
||||||
//! irrelevant to the integrity of the kernel. All pages mapped to the virtual
|
//! is a reference-counted handle to a page. When all handles to a page are dropped,
|
||||||
//! address space of the users are backed by frames.
|
//! the page is released and can be reused.
|
||||||
|
//!
|
||||||
|
//! Pages can have dedicated metadata, which is implemented in the [`meta`] module.
|
||||||
|
//! The reference count and usage of a page are stored in the metadata as well, leaving
|
||||||
|
//! the handle only a pointer to the metadata.
|
||||||
|
|
||||||
pub(crate) mod allocator;
|
pub(crate) mod allocator;
|
||||||
mod frame;
|
|
||||||
pub(in crate::mm) mod meta;
|
pub(in crate::mm) mod meta;
|
||||||
mod segment;
|
|
||||||
mod vm_frame_vec;
|
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
sync::atomic::{AtomicU32, AtomicUsize, Ordering},
|
sync::atomic::{AtomicU32, AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use frame::Frame;
|
|
||||||
use meta::{mapping, MetaSlot, PageMeta};
|
use meta::{mapping, MetaSlot, PageMeta};
|
||||||
pub use segment::Segment;
|
|
||||||
pub use vm_frame_vec::{FrameVecIter, VmFrameVec};
|
|
||||||
|
|
||||||
use super::PAGE_SIZE;
|
use super::PAGE_SIZE;
|
||||||
use crate::mm::{paddr_to_vaddr, Paddr, PagingConsts, Vaddr};
|
use crate::mm::{Paddr, PagingConsts, Vaddr};
|
||||||
|
|
||||||
static MAX_PADDR: AtomicUsize = AtomicUsize::new(0);
|
static MAX_PADDR: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
@ -35,8 +33,8 @@ static MAX_PADDR: AtomicUsize = AtomicUsize::new(0);
|
|||||||
/// whose metadata is represented by `M`.
|
/// whose metadata is represented by `M`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Page<M: PageMeta> {
|
pub struct Page<M: PageMeta> {
|
||||||
ptr: *const MetaSlot,
|
pub(super) ptr: *const MetaSlot,
|
||||||
_marker: PhantomData<M>,
|
pub(super) _marker: PhantomData<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<M: PageMeta> Send for Page<M> {}
|
unsafe impl<M: PageMeta> Send for Page<M> {}
|
||||||
|
@ -101,10 +101,10 @@ fn test_boot_pt() {
|
|||||||
use super::page_walk;
|
use super::page_walk;
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::mm::{PageTableEntry, PagingConsts},
|
arch::mm::{PageTableEntry, PagingConsts},
|
||||||
mm::{CachePolicy, PageFlags, VmAllocOptions},
|
mm::{CachePolicy, FrameAllocOptions, PageFlags},
|
||||||
};
|
};
|
||||||
|
|
||||||
let root_frame = VmAllocOptions::new(1).alloc_single().unwrap();
|
let root_frame = FrameAllocOptions::new(1).alloc_single().unwrap();
|
||||||
let root_paddr = root_frame.start_paddr();
|
let root_paddr = root_frame.start_paddr();
|
||||||
|
|
||||||
let mut boot_pt = BootPageTable::<PageTableEntry, PagingConsts> {
|
let mut boot_pt = BootPageTable::<PageTableEntry, PagingConsts> {
|
||||||
|
@ -122,7 +122,7 @@ where
|
|||||||
// Create a guard array that only hold the root node lock.
|
// Create a guard array that only hold the root node lock.
|
||||||
let guards = core::array::from_fn(|i| {
|
let guards = core::array::from_fn(|i| {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
Some(pt.root.copy_handle().lock())
|
Some(pt.root.clone_shallow().lock())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -313,7 +313,7 @@ where
|
|||||||
// Drop the lock on the guard level.
|
// Drop the lock on the guard level.
|
||||||
self.guards[C::NR_LEVELS - self.guard_level] = None;
|
self.guards[C::NR_LEVELS - self.guard_level] = None;
|
||||||
// Re-walk the page table to retreive the locks.
|
// Re-walk the page table to retreive the locks.
|
||||||
self.guards[0] = Some(self.pt.root.copy_handle().lock());
|
self.guards[0] = Some(self.pt.root.clone_shallow().lock());
|
||||||
self.level = C::NR_LEVELS;
|
self.level = C::NR_LEVELS;
|
||||||
let cur_pte = self.read_cur_pte();
|
let cur_pte = self.read_cur_pte();
|
||||||
let cur_child_is_pt = cur_pte.is_present() && !cur_pte.is_last(self.level);
|
let cur_child_is_pt = cur_pte.is_present() && !cur_pte.is_last(self.level);
|
||||||
|
@ -135,7 +135,7 @@ impl PageTable<KernelMode> {
|
|||||||
/// Then, one can use a user page table to call [`fork_copy_on_write`], creating
|
/// Then, one can use a user page table to call [`fork_copy_on_write`], creating
|
||||||
/// other child page tables.
|
/// other child page tables.
|
||||||
pub(crate) fn create_user_page_table(&self) -> PageTable<UserMode> {
|
pub(crate) fn create_user_page_table(&self) -> PageTable<UserMode> {
|
||||||
let root_frame = self.root.copy_handle().lock();
|
let root_frame = self.root.clone_shallow().lock();
|
||||||
const NR_PTES_PER_NODE: usize = nr_subpage_per_huge::<PagingConsts>();
|
const NR_PTES_PER_NODE: usize = nr_subpage_per_huge::<PagingConsts>();
|
||||||
let new_root_frame =
|
let new_root_frame =
|
||||||
unsafe { root_frame.make_copy(0..0, NR_PTES_PER_NODE / 2..NR_PTES_PER_NODE) };
|
unsafe { root_frame.make_copy(0..0, NR_PTES_PER_NODE / 2..NR_PTES_PER_NODE) };
|
||||||
@ -157,7 +157,7 @@ impl PageTable<KernelMode> {
|
|||||||
debug_assert!(start < NR_PTES_PER_NODE);
|
debug_assert!(start < NR_PTES_PER_NODE);
|
||||||
let end = root_index.end;
|
let end = root_index.end;
|
||||||
debug_assert!(end <= NR_PTES_PER_NODE);
|
debug_assert!(end <= NR_PTES_PER_NODE);
|
||||||
let mut root_frame = self.root.copy_handle().lock();
|
let mut root_frame = self.root.clone_shallow().lock();
|
||||||
for i in start..end {
|
for i in start..end {
|
||||||
if !root_frame.read_pte(i).is_present() {
|
if !root_frame.read_pte(i).is_present() {
|
||||||
let frame = PageTableNode::alloc(PagingConsts::NR_LEVELS - 1);
|
let frame = PageTableNode::alloc(PagingConsts::NR_LEVELS - 1);
|
||||||
@ -254,7 +254,7 @@ where
|
|||||||
/// This is only useful for IOMMU page tables. Think twice before using it in other cases.
|
/// This is only useful for IOMMU page tables. Think twice before using it in other cases.
|
||||||
pub(crate) unsafe fn shallow_copy(&self) -> Self {
|
pub(crate) unsafe fn shallow_copy(&self) -> Self {
|
||||||
PageTable {
|
PageTable {
|
||||||
root: self.root.copy_handle(),
|
root: self.root.clone_shallow(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of the handle.
|
/// Create a copy of the handle.
|
||||||
pub(super) fn copy_handle(&self) -> Self {
|
pub(super) fn clone_shallow(&self) -> Self {
|
||||||
self.inc_ref();
|
self.inc_ref();
|
||||||
Self {
|
Self {
|
||||||
raw: self.raw,
|
raw: self.raw,
|
||||||
@ -321,7 +321,7 @@ where
|
|||||||
for i in deep {
|
for i in deep {
|
||||||
match self.child(i, /*meaningless*/ true) {
|
match self.child(i, /*meaningless*/ true) {
|
||||||
Child::PageTable(pt) => {
|
Child::PageTable(pt) => {
|
||||||
let guard = pt.copy_handle().lock();
|
let guard = pt.clone_shallow().lock();
|
||||||
let new_child = guard.make_copy(0..nr_subpage_per_huge::<C>(), 0..0);
|
let new_child = guard.make_copy(0..nr_subpage_per_huge::<C>(), 0..0);
|
||||||
new_frame.set_child_pt(i, new_child.into_raw(), /*meaningless*/ true);
|
new_frame.set_child_pt(i, new_child.into_raw(), /*meaningless*/ true);
|
||||||
}
|
}
|
||||||
@ -339,7 +339,7 @@ where
|
|||||||
debug_assert_eq!(self.level(), C::NR_LEVELS);
|
debug_assert_eq!(self.level(), C::NR_LEVELS);
|
||||||
match self.child(i, /*meaningless*/ true) {
|
match self.child(i, /*meaningless*/ true) {
|
||||||
Child::PageTable(pt) => {
|
Child::PageTable(pt) => {
|
||||||
new_frame.set_child_pt(i, pt.copy_handle(), /*meaningless*/ true);
|
new_frame.set_child_pt(i, pt.clone_shallow(), /*meaningless*/ true);
|
||||||
}
|
}
|
||||||
Child::None => {}
|
Child::None => {}
|
||||||
Child::Frame(_) | Child::Untracked(_) => {
|
Child::Frame(_) | Child::Untracked(_) => {
|
||||||
|
@ -6,7 +6,7 @@ use super::*;
|
|||||||
use crate::mm::{
|
use crate::mm::{
|
||||||
kspace::LINEAR_MAPPING_BASE_VADDR,
|
kspace::LINEAR_MAPPING_BASE_VADDR,
|
||||||
page_prop::{CachePolicy, PageFlags},
|
page_prop::{CachePolicy, PageFlags},
|
||||||
VmAllocOptions,
|
FrameAllocOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
const PAGE_SIZE: usize = 4096;
|
||||||
@ -17,7 +17,7 @@ fn test_range_check() {
|
|||||||
let good_va = 0..PAGE_SIZE;
|
let good_va = 0..PAGE_SIZE;
|
||||||
let bad_va = 0..PAGE_SIZE + 1;
|
let bad_va = 0..PAGE_SIZE + 1;
|
||||||
let bad_va2 = LINEAR_MAPPING_BASE_VADDR..LINEAR_MAPPING_BASE_VADDR + PAGE_SIZE;
|
let bad_va2 = LINEAR_MAPPING_BASE_VADDR..LINEAR_MAPPING_BASE_VADDR + PAGE_SIZE;
|
||||||
let to = VmAllocOptions::new(1).alloc().unwrap();
|
let to = FrameAllocOptions::new(1).alloc().unwrap();
|
||||||
assert!(pt.cursor_mut(&good_va).is_ok());
|
assert!(pt.cursor_mut(&good_va).is_ok());
|
||||||
assert!(pt.cursor_mut(&bad_va).is_err());
|
assert!(pt.cursor_mut(&bad_va).is_err());
|
||||||
assert!(pt.cursor_mut(&bad_va2).is_err());
|
assert!(pt.cursor_mut(&bad_va2).is_err());
|
||||||
@ -31,7 +31,7 @@ fn test_tracked_map_unmap() {
|
|||||||
let pt = PageTable::<UserMode>::empty();
|
let pt = PageTable::<UserMode>::empty();
|
||||||
|
|
||||||
let from = PAGE_SIZE..PAGE_SIZE * 2;
|
let from = PAGE_SIZE..PAGE_SIZE * 2;
|
||||||
let frame = VmAllocOptions::new(1).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1).alloc_single().unwrap();
|
||||||
let start_paddr = frame.start_paddr();
|
let start_paddr = frame.start_paddr();
|
||||||
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
||||||
unsafe { pt.cursor_mut(&from).unwrap().map(frame.clone(), prop) };
|
unsafe { pt.cursor_mut(&from).unwrap().map(frame.clone(), prop) };
|
||||||
@ -75,7 +75,7 @@ fn test_untracked_map_unmap() {
|
|||||||
fn test_user_copy_on_write() {
|
fn test_user_copy_on_write() {
|
||||||
let pt = PageTable::<UserMode>::empty();
|
let pt = PageTable::<UserMode>::empty();
|
||||||
let from = PAGE_SIZE..PAGE_SIZE * 2;
|
let from = PAGE_SIZE..PAGE_SIZE * 2;
|
||||||
let frame = VmAllocOptions::new(1).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1).alloc_single().unwrap();
|
||||||
let start_paddr = frame.start_paddr();
|
let start_paddr = frame.start_paddr();
|
||||||
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
||||||
unsafe { pt.cursor_mut(&from).unwrap().map(frame.clone(), prop) };
|
unsafe { pt.cursor_mut(&from).unwrap().map(frame.clone(), prop) };
|
||||||
@ -131,7 +131,7 @@ fn test_base_protect_query() {
|
|||||||
|
|
||||||
let from_ppn = 1..1000;
|
let from_ppn = 1..1000;
|
||||||
let from = PAGE_SIZE * from_ppn.start..PAGE_SIZE * from_ppn.end;
|
let from = PAGE_SIZE * from_ppn.start..PAGE_SIZE * from_ppn.end;
|
||||||
let to = VmAllocOptions::new(999).alloc().unwrap();
|
let to = FrameAllocOptions::new(999).alloc().unwrap();
|
||||||
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
let prop = PageProperty::new(PageFlags::RW, CachePolicy::Writeback);
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut cursor = pt.cursor_mut(&from).unwrap();
|
let mut cursor = pt.cursor_mut(&from).unwrap();
|
||||||
|
@ -6,7 +6,7 @@ use super::{
|
|||||||
is_page_aligned,
|
is_page_aligned,
|
||||||
kspace::KERNEL_PAGE_TABLE,
|
kspace::KERNEL_PAGE_TABLE,
|
||||||
page_table::{PageTable, PageTableMode, UserMode},
|
page_table::{PageTable, PageTableMode, UserMode},
|
||||||
CachePolicy, PageFlags, PageProperty, PagingConstsTrait, PrivilegedPageFlags, VmFrameVec,
|
CachePolicy, FrameVec, PageFlags, PageProperty, PagingConstsTrait, PrivilegedPageFlags,
|
||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -65,7 +65,7 @@ impl VmSpace {
|
|||||||
/// The ownership of the frames will be transferred to the `VmSpace`.
|
/// The ownership of the frames will be transferred to the `VmSpace`.
|
||||||
///
|
///
|
||||||
/// For more information, see `VmMapOptions`.
|
/// For more information, see `VmMapOptions`.
|
||||||
pub fn map(&self, frames: VmFrameVec, options: &VmMapOptions) -> Result<Vaddr> {
|
pub fn map(&self, frames: FrameVec, options: &VmMapOptions) -> Result<Vaddr> {
|
||||||
if options.addr.is_none() {
|
if options.addr.is_none() {
|
||||||
return Err(Error::InvalidArgs);
|
return Err(Error::InvalidArgs);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use super::{
|
|||||||
pub(crate) use crate::arch::task::{context_switch, TaskContext};
|
pub(crate) use crate::arch::task::{context_switch, TaskContext};
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::CpuSet,
|
cpu::CpuSet,
|
||||||
mm::{kspace::KERNEL_PAGE_TABLE, PageFlags, Segment, VmAllocOptions, PAGE_SIZE},
|
mm::{kspace::KERNEL_PAGE_TABLE, FrameAllocOptions, PageFlags, Segment, PAGE_SIZE},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
sync::{SpinLock, SpinLockGuard},
|
sync::{SpinLock, SpinLockGuard},
|
||||||
user::UserSpace,
|
user::UserSpace,
|
||||||
@ -42,7 +42,7 @@ pub struct KernelStack {
|
|||||||
impl KernelStack {
|
impl KernelStack {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
segment: VmAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE).alloc_contiguous()?,
|
segment: FrameAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE).alloc_contiguous()?,
|
||||||
has_guard_page: false,
|
has_guard_page: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ impl KernelStack {
|
|||||||
/// An additional page is allocated and be regarded as a guard page, which should not be accessed.
|
/// An additional page is allocated and be regarded as a guard page, which should not be accessed.
|
||||||
pub fn new_with_guard_page() -> Result<Self> {
|
pub fn new_with_guard_page() -> Result<Self> {
|
||||||
let stack_segment =
|
let stack_segment =
|
||||||
VmAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE + 1).alloc_contiguous()?;
|
FrameAllocOptions::new(KERNEL_STACK_SIZE / PAGE_SIZE + 1).alloc_contiguous()?;
|
||||||
// FIXME: modifying the the linear mapping is bad.
|
// FIXME: modifying the the linear mapping is bad.
|
||||||
let page_table = KERNEL_PAGE_TABLE.get().unwrap();
|
let page_table = KERNEL_PAGE_TABLE.get().unwrap();
|
||||||
let guard_page_vaddr = {
|
let guard_page_vaddr = {
|
||||||
|
@ -9,7 +9,7 @@ use aster_block::{
|
|||||||
id::{Bid, BlockId},
|
id::{Bid, BlockId},
|
||||||
BLOCK_SIZE,
|
BLOCK_SIZE,
|
||||||
};
|
};
|
||||||
use aster_frame::mm::{Frame, VmAllocOptions, VmIo};
|
use aster_frame::mm::{Frame, FrameAllocOptions, VmIo};
|
||||||
use aster_rights::Full;
|
use aster_rights::Full;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -1242,7 +1242,10 @@ impl Inode for ExfatInode {
|
|||||||
.discard_range(read_off..read_off + read_len);
|
.discard_range(read_off..read_off + read_len);
|
||||||
|
|
||||||
let mut buf_offset = 0;
|
let mut buf_offset = 0;
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1)
|
||||||
|
.uninit(true)
|
||||||
|
.alloc_single()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let start_pos = inner.start_chain.walk_to_cluster_at_offset(read_off)?;
|
let start_pos = inner.start_chain.walk_to_cluster_at_offset(read_off)?;
|
||||||
let cluster_size = inner.fs().cluster_size();
|
let cluster_size = inner.fs().cluster_size();
|
||||||
@ -1355,7 +1358,10 @@ impl Inode for ExfatInode {
|
|||||||
let mut cur_offset = start_pos.1;
|
let mut cur_offset = start_pos.1;
|
||||||
for _ in Bid::from_offset(offset)..Bid::from_offset(end_offset) {
|
for _ in Bid::from_offset(offset)..Bid::from_offset(end_offset) {
|
||||||
let frame = {
|
let frame = {
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1)
|
||||||
|
.uninit(true)
|
||||||
|
.alloc_single()
|
||||||
|
.unwrap();
|
||||||
frame.write_bytes(0, &buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
frame.write_bytes(0, &buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
||||||
frame
|
frame
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,7 @@ mod test {
|
|||||||
bio::{BioEnqueueError, BioStatus, BioType, SubmittedBio},
|
bio::{BioEnqueueError, BioStatus, BioType, SubmittedBio},
|
||||||
BlockDevice,
|
BlockDevice,
|
||||||
};
|
};
|
||||||
use aster_frame::mm::{Segment, VmAllocOptions, VmIo};
|
use aster_frame::mm::{FrameAllocOptions, Segment, VmIo};
|
||||||
use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -102,7 +102,7 @@ mod test {
|
|||||||
/// Read exfat disk image
|
/// Read exfat disk image
|
||||||
fn new_vm_segment_from_image() -> Segment {
|
fn new_vm_segment_from_image() -> Segment {
|
||||||
let vm_segment = {
|
let vm_segment = {
|
||||||
VmAllocOptions::new(EXFAT_IMAGE.len() / PAGE_SIZE)
|
FrameAllocOptions::new(EXFAT_IMAGE.len() / PAGE_SIZE)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
|
@ -40,7 +40,7 @@ impl Ext2 {
|
|||||||
let npages = ((super_block.block_groups_count() as usize)
|
let npages = ((super_block.block_groups_count() as usize)
|
||||||
* core::mem::size_of::<RawGroupDescriptor>())
|
* core::mem::size_of::<RawGroupDescriptor>())
|
||||||
.div_ceil(BLOCK_SIZE);
|
.div_ceil(BLOCK_SIZE);
|
||||||
let segment = VmAllocOptions::new(npages)
|
let segment = FrameAllocOptions::new(npages)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()?;
|
.alloc_contiguous()?;
|
||||||
match block_device.read_blocks_sync(super_block.group_descriptors_bid(0), &segment)? {
|
match block_device.read_blocks_sync(super_block.group_descriptors_bid(0), &segment)? {
|
||||||
|
@ -132,7 +132,7 @@ impl IndirectBlock {
|
|||||||
/// Allocates an uninitialized block whose bytes are to be populated with
|
/// Allocates an uninitialized block whose bytes are to be populated with
|
||||||
/// data loaded from the disk.
|
/// data loaded from the disk.
|
||||||
fn alloc_uninit() -> Result<Self> {
|
fn alloc_uninit() -> Result<Self> {
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single()?;
|
let frame = FrameAllocOptions::new(1).uninit(true).alloc_single()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
frame,
|
frame,
|
||||||
state: State::Uninit,
|
state: State::Uninit,
|
||||||
@ -141,7 +141,7 @@ impl IndirectBlock {
|
|||||||
|
|
||||||
/// Allocates a new block with its bytes initialized to zero.
|
/// Allocates a new block with its bytes initialized to zero.
|
||||||
pub fn alloc() -> Result<Self> {
|
pub fn alloc() -> Result<Self> {
|
||||||
let frame = VmAllocOptions::new(1).alloc_single()?;
|
let frame = FrameAllocOptions::new(1).alloc_single()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
frame,
|
frame,
|
||||||
state: State::Dirty,
|
state: State::Dirty,
|
||||||
|
@ -653,7 +653,10 @@ impl Inner {
|
|||||||
|
|
||||||
let mut buf_offset = 0;
|
let mut buf_offset = 0;
|
||||||
for bid in Bid::from_offset(offset)..Bid::from_offset(offset + read_len) {
|
for bid in Bid::from_offset(offset)..Bid::from_offset(offset + read_len) {
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1)
|
||||||
|
.uninit(true)
|
||||||
|
.alloc_single()
|
||||||
|
.unwrap();
|
||||||
self.inode_impl
|
self.inode_impl
|
||||||
.read_block_sync(bid.to_raw() as Ext2Bid, &frame)?;
|
.read_block_sync(bid.to_raw() as Ext2Bid, &frame)?;
|
||||||
frame.read_bytes(0, &mut buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
frame.read_bytes(0, &mut buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
||||||
@ -691,7 +694,10 @@ impl Inner {
|
|||||||
let mut buf_offset = 0;
|
let mut buf_offset = 0;
|
||||||
for bid in Bid::from_offset(offset)..Bid::from_offset(end_offset) {
|
for bid in Bid::from_offset(offset)..Bid::from_offset(end_offset) {
|
||||||
let frame = {
|
let frame = {
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single().unwrap();
|
let frame = FrameAllocOptions::new(1)
|
||||||
|
.uninit(true)
|
||||||
|
.alloc_single()
|
||||||
|
.unwrap();
|
||||||
frame.write_bytes(0, &buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
frame.write_bytes(0, &buf[buf_offset..buf_offset + BLOCK_SIZE])?;
|
||||||
frame
|
frame
|
||||||
};
|
};
|
||||||
@ -1572,7 +1578,7 @@ impl InodeImpl {
|
|||||||
|
|
||||||
pub fn sync_data_holes(&self) -> Result<()> {
|
pub fn sync_data_holes(&self) -> Result<()> {
|
||||||
let inner = self.0.read();
|
let inner = self.0.read();
|
||||||
let zero_frame = VmAllocOptions::new(1).alloc_single().unwrap();
|
let zero_frame = FrameAllocOptions::new(1).alloc_single().unwrap();
|
||||||
for bid in 0..inner.desc.blocks_count() {
|
for bid in 0..inner.desc.blocks_count() {
|
||||||
let is_data_hole = inner.blocks_hole_desc.read().is_hole(bid as usize);
|
let is_data_hole = inner.blocks_hole_desc.read().is_hole(bid as usize);
|
||||||
if is_data_hole {
|
if is_data_hole {
|
||||||
|
@ -12,7 +12,7 @@ pub(super) use aster_block::{
|
|||||||
BlockDevice, BLOCK_SIZE,
|
BlockDevice, BLOCK_SIZE,
|
||||||
};
|
};
|
||||||
pub(super) use aster_frame::{
|
pub(super) use aster_frame::{
|
||||||
mm::{Frame, Segment, VmAllocOptions, VmIo},
|
mm::{Frame, FrameAllocOptions, Segment, VmIo},
|
||||||
sync::{RwMutex, RwMutexReadGuard, RwMutexWriteGuard},
|
sync::{RwMutex, RwMutexReadGuard, RwMutexWriteGuard},
|
||||||
};
|
};
|
||||||
pub(super) use aster_rights::Full;
|
pub(super) use aster_rights::Full;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
use aster_block::bio::{BioStatus, BioWaiter};
|
use aster_block::bio::{BioStatus, BioWaiter};
|
||||||
use aster_frame::mm::{Frame, VmAllocOptions};
|
use aster_frame::mm::{Frame, FrameAllocOptions};
|
||||||
use aster_rights::Full;
|
use aster_rights::Full;
|
||||||
use lru::LruCache;
|
use lru::LruCache;
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ struct Page {
|
|||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn alloc() -> Result<Self> {
|
pub fn alloc() -> Result<Self> {
|
||||||
let frame = VmAllocOptions::new(1).uninit(true).alloc_single()?;
|
let frame = FrameAllocOptions::new(1).uninit(true).alloc_single()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
frame,
|
frame,
|
||||||
state: PageState::Uninit,
|
state: PageState::Uninit,
|
||||||
@ -216,7 +216,7 @@ impl Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_zero() -> Result<Self> {
|
pub fn alloc_zero() -> Result<Self> {
|
||||||
let frame = VmAllocOptions::new(1).alloc_single()?;
|
let frame = FrameAllocOptions::new(1).alloc_single()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
frame,
|
frame,
|
||||||
state: PageState::Dirty,
|
state: PageState::Dirty,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
use aster_frame::mm::{Frame, PageFlags, VmFrameVec, VmIo, VmMapOptions, VmSpace};
|
use aster_frame::mm::{Frame, FrameVec, PageFlags, VmIo, VmMapOptions, VmSpace};
|
||||||
|
|
||||||
use super::{interval::Interval, is_intersected, Vmar, Vmar_};
|
use super::{interval::Interval, is_intersected, Vmar, Vmar_};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -484,7 +484,7 @@ impl VmMappingInner {
|
|||||||
vm_space.unmap(&(map_addr..(map_addr + PAGE_SIZE))).unwrap();
|
vm_space.unmap(&(map_addr..(map_addr + PAGE_SIZE))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_space.map(VmFrameVec::from_one_frame(frame), &vm_map_options)?;
|
vm_space.map(FrameVec::from_one_frame(frame), &vm_map_options)?;
|
||||||
self.mapped_pages.insert(page_idx);
|
self.mapped_pages.insert(page_idx);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use core::ops::Range;
|
|||||||
use align_ext::AlignExt;
|
use align_ext::AlignExt;
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
collections::xarray::{CursorMut, XArray, XMark},
|
collections::xarray::{CursorMut, XArray, XMark},
|
||||||
mm::{Frame, VmAllocOptions, VmReader, VmWriter},
|
mm::{Frame, FrameAllocOptions, VmReader, VmWriter},
|
||||||
};
|
};
|
||||||
use aster_rights::Rights;
|
use aster_rights::Rights;
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ pub(super) struct Vmo_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn clone_page(page: &Frame) -> Result<Frame> {
|
fn clone_page(page: &Frame) -> Result<Frame> {
|
||||||
let new_page = VmAllocOptions::new(1).alloc_single()?;
|
let new_page = FrameAllocOptions::new(1).alloc_single()?;
|
||||||
new_page.copy_from(page);
|
new_page.copy_from(page);
|
||||||
Ok(new_page)
|
Ok(new_page)
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ impl Vmo_ {
|
|||||||
None => {
|
None => {
|
||||||
// Condition 1. The new anonymous page only need to be marked as `ExclusivePage`
|
// Condition 1. The new anonymous page only need to be marked as `ExclusivePage`
|
||||||
// when current VMO is a cow VMO, otherwise this mark is meaningless.
|
// when current VMO is a cow VMO, otherwise this mark is meaningless.
|
||||||
(VmAllocOptions::new(1).alloc_single()?, is_cow_vmo)
|
(FrameAllocOptions::new(1).alloc_single()?, is_cow_vmo)
|
||||||
}
|
}
|
||||||
Some(pager) => {
|
Some(pager) => {
|
||||||
let page = pager.commit_page(page_idx)?;
|
let page = pager.commit_page(page_idx)?;
|
||||||
|
@ -7,7 +7,7 @@ use core::{marker::PhantomData, ops::Range};
|
|||||||
use align_ext::AlignExt;
|
use align_ext::AlignExt;
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
collections::xarray::XArray,
|
collections::xarray::XArray,
|
||||||
mm::{Frame, VmAllocOptions},
|
mm::{Frame, FrameAllocOptions},
|
||||||
};
|
};
|
||||||
use aster_rights::{Dup, Rights, TRightSet, TRights, Write};
|
use aster_rights::{Dup, Rights, TRightSet, TRights, Write};
|
||||||
use aster_rights_proc::require;
|
use aster_rights_proc::require;
|
||||||
@ -144,7 +144,7 @@ fn committed_pages_if_continuous(flags: VmoFlags, size: usize) -> Result<XArray<
|
|||||||
if flags.contains(VmoFlags::CONTIGUOUS) {
|
if flags.contains(VmoFlags::CONTIGUOUS) {
|
||||||
// if the vmo is continuous, we need to allocate frames for the vmo
|
// if the vmo is continuous, we need to allocate frames for the vmo
|
||||||
let frames_num = size / PAGE_SIZE;
|
let frames_num = size / PAGE_SIZE;
|
||||||
let frames = VmAllocOptions::new(frames_num)
|
let frames = FrameAllocOptions::new(frames_num)
|
||||||
.is_contiguous(true)
|
.is_contiguous(true)
|
||||||
.alloc()?;
|
.alloc()?;
|
||||||
let mut committed_pages = XArray::new();
|
let mut committed_pages = XArray::new();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use aster_frame::mm::{Frame, Segment, VmAllocOptions, VmIo};
|
use aster_frame::mm::{Frame, FrameAllocOptions, Segment, VmIo};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
bio::{Bio, BioEnqueueError, BioSegment, BioStatus, BioType, BioWaiter, SubmittedBio},
|
bio::{Bio, BioEnqueueError, BioSegment, BioStatus, BioType, BioWaiter, SubmittedBio},
|
||||||
@ -89,7 +89,7 @@ impl VmIo for dyn BlockDevice {
|
|||||||
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
||||||
last - first + 1
|
last - first + 1
|
||||||
};
|
};
|
||||||
let segment = VmAllocOptions::new(num_blocks as usize)
|
let segment = FrameAllocOptions::new(num_blocks as usize)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()?;
|
.alloc_contiguous()?;
|
||||||
let bio_segment = BioSegment::from_segment(segment, offset % BLOCK_SIZE, buf.len());
|
let bio_segment = BioSegment::from_segment(segment, offset % BLOCK_SIZE, buf.len());
|
||||||
@ -130,7 +130,7 @@ impl VmIo for dyn BlockDevice {
|
|||||||
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
||||||
last - first + 1
|
last - first + 1
|
||||||
};
|
};
|
||||||
let segment = VmAllocOptions::new(num_blocks as usize)
|
let segment = FrameAllocOptions::new(num_blocks as usize)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()?;
|
.alloc_contiguous()?;
|
||||||
segment.write_bytes(offset % BLOCK_SIZE, buf)?;
|
segment.write_bytes(offset % BLOCK_SIZE, buf)?;
|
||||||
@ -171,7 +171,7 @@ impl dyn BlockDevice {
|
|||||||
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
let last = Bid::from_offset(offset + buf.len() - 1).to_raw();
|
||||||
last - first + 1
|
last - first + 1
|
||||||
};
|
};
|
||||||
let segment = VmAllocOptions::new(num_blocks as usize)
|
let segment = FrameAllocOptions::new(num_blocks as usize)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()?;
|
.alloc_contiguous()?;
|
||||||
segment.write_bytes(offset % BLOCK_SIZE, buf)?;
|
segment.write_bytes(offset % BLOCK_SIZE, buf)?;
|
||||||
|
@ -4,7 +4,9 @@ use alloc::{collections::LinkedList, sync::Arc};
|
|||||||
|
|
||||||
use align_ext::AlignExt;
|
use align_ext::AlignExt;
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
mm::{Daddr, DmaDirection, DmaStream, HasDaddr, VmAllocOptions, VmReader, VmWriter, PAGE_SIZE},
|
mm::{
|
||||||
|
Daddr, DmaDirection, DmaStream, FrameAllocOptions, HasDaddr, VmReader, VmWriter, PAGE_SIZE,
|
||||||
|
},
|
||||||
sync::SpinLock,
|
sync::SpinLock,
|
||||||
};
|
};
|
||||||
use pod::Pod;
|
use pod::Pod;
|
||||||
@ -27,7 +29,7 @@ impl TxBuffer {
|
|||||||
} else {
|
} else {
|
||||||
let segment = {
|
let segment = {
|
||||||
let nframes = (nbytes.align_up(PAGE_SIZE)) / PAGE_SIZE;
|
let nframes = (nbytes.align_up(PAGE_SIZE)) / PAGE_SIZE;
|
||||||
VmAllocOptions::new(nframes).alloc_contiguous().unwrap()
|
FrameAllocOptions::new(nframes).alloc_contiguous().unwrap()
|
||||||
};
|
};
|
||||||
DmaStream::map(segment, DmaDirection::ToDevice, false).unwrap()
|
DmaStream::map(segment, DmaDirection::ToDevice, false).unwrap()
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,9 @@ use alloc::{
|
|||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
mm::{Daddr, DmaDirection, DmaStream, HasDaddr, VmAllocOptions, VmReader, VmWriter, PAGE_SIZE},
|
mm::{
|
||||||
|
Daddr, DmaDirection, DmaStream, FrameAllocOptions, HasDaddr, VmReader, VmWriter, PAGE_SIZE,
|
||||||
|
},
|
||||||
sync::{RwLock, SpinLock},
|
sync::{RwLock, SpinLock},
|
||||||
};
|
};
|
||||||
use bitvec::{array::BitArray, prelude::Lsb0};
|
use bitvec::{array::BitArray, prelude::Lsb0};
|
||||||
@ -145,7 +147,7 @@ impl DmaPage {
|
|||||||
pool: Weak<DmaPool>,
|
pool: Weak<DmaPool>,
|
||||||
) -> Result<Self, aster_frame::Error> {
|
) -> Result<Self, aster_frame::Error> {
|
||||||
let dma_stream = {
|
let dma_stream = {
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous()?;
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous()?;
|
||||||
|
|
||||||
DmaStream::map(vm_segment, direction, is_cache_coherent)
|
DmaStream::map(vm_segment, direction, is_cache_coherent)
|
||||||
.map_err(|_| aster_frame::Error::AccessDenied)?
|
.map_err(|_| aster_frame::Error::AccessDenied)?
|
||||||
|
@ -9,7 +9,7 @@ use aster_block::{
|
|||||||
};
|
};
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
io_mem::IoMem,
|
io_mem::IoMem,
|
||||||
mm::{DmaDirection, DmaStream, DmaStreamSlice, VmAllocOptions, VmIo},
|
mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmIo},
|
||||||
sync::SpinLock,
|
sync::SpinLock,
|
||||||
trap::TrapFrame,
|
trap::TrapFrame,
|
||||||
};
|
};
|
||||||
@ -100,12 +100,12 @@ impl DeviceInner {
|
|||||||
let queue = VirtQueue::new(0, Self::QUEUE_SIZE, transport.as_mut())
|
let queue = VirtQueue::new(0, Self::QUEUE_SIZE, transport.as_mut())
|
||||||
.expect("create virtqueue failed");
|
.expect("create virtqueue failed");
|
||||||
let block_requests = {
|
let block_requests = {
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous().unwrap();
|
||||||
DmaStream::map(vm_segment, DmaDirection::Bidirectional, false).unwrap()
|
DmaStream::map(vm_segment, DmaDirection::Bidirectional, false).unwrap()
|
||||||
};
|
};
|
||||||
assert!(Self::QUEUE_SIZE as usize * REQ_SIZE <= block_requests.nbytes());
|
assert!(Self::QUEUE_SIZE as usize * REQ_SIZE <= block_requests.nbytes());
|
||||||
let block_responses = {
|
let block_responses = {
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous().unwrap();
|
||||||
DmaStream::map(vm_segment, DmaDirection::Bidirectional, false).unwrap()
|
DmaStream::map(vm_segment, DmaDirection::Bidirectional, false).unwrap()
|
||||||
};
|
};
|
||||||
assert!(Self::QUEUE_SIZE as usize * RESP_SIZE <= block_responses.nbytes());
|
assert!(Self::QUEUE_SIZE as usize * RESP_SIZE <= block_responses.nbytes());
|
||||||
@ -216,7 +216,7 @@ impl DeviceInner {
|
|||||||
};
|
};
|
||||||
const MAX_ID_LENGTH: usize = 20;
|
const MAX_ID_LENGTH: usize = 20;
|
||||||
let device_id_stream = {
|
let device_id_stream = {
|
||||||
let segment = VmAllocOptions::new(1)
|
let segment = FrameAllocOptions::new(1)
|
||||||
.uninit(true)
|
.uninit(true)
|
||||||
.alloc_contiguous()
|
.alloc_contiguous()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -6,7 +6,7 @@ use core::hint::spin_loop;
|
|||||||
use aster_console::{AnyConsoleDevice, ConsoleCallback};
|
use aster_console::{AnyConsoleDevice, ConsoleCallback};
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
io_mem::IoMem,
|
io_mem::IoMem,
|
||||||
mm::{DmaDirection, DmaStream, DmaStreamSlice, VmAllocOptions, VmReader},
|
mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmReader},
|
||||||
sync::{RwLock, SpinLock},
|
sync::{RwLock, SpinLock},
|
||||||
trap::TrapFrame,
|
trap::TrapFrame,
|
||||||
};
|
};
|
||||||
@ -87,12 +87,12 @@ impl ConsoleDevice {
|
|||||||
SpinLock::new(VirtQueue::new(TRANSMIT0_QUEUE_INDEX, 2, transport.as_mut()).unwrap());
|
SpinLock::new(VirtQueue::new(TRANSMIT0_QUEUE_INDEX, 2, transport.as_mut()).unwrap());
|
||||||
|
|
||||||
let send_buffer = {
|
let send_buffer = {
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous().unwrap();
|
||||||
DmaStream::map(vm_segment, DmaDirection::ToDevice, false).unwrap()
|
DmaStream::map(vm_segment, DmaDirection::ToDevice, false).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let receive_buffer = {
|
let receive_buffer = {
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous().unwrap();
|
||||||
DmaStream::map(vm_segment, DmaDirection::FromDevice, false).unwrap()
|
DmaStream::map(vm_segment, DmaDirection::FromDevice, false).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use core::{fmt::Debug, iter, mem};
|
|||||||
|
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
io_mem::IoMem,
|
io_mem::IoMem,
|
||||||
mm::{DmaDirection, DmaStream, HasDaddr, VmAllocOptions, VmIo, PAGE_SIZE},
|
mm::{DmaDirection, DmaStream, FrameAllocOptions, HasDaddr, VmIo, PAGE_SIZE},
|
||||||
offset_of,
|
offset_of,
|
||||||
sync::{RwLock, SpinLock},
|
sync::{RwLock, SpinLock},
|
||||||
trap::TrapFrame,
|
trap::TrapFrame,
|
||||||
@ -239,7 +239,7 @@ impl EventTable {
|
|||||||
fn new(num_events: usize) -> Self {
|
fn new(num_events: usize) -> Self {
|
||||||
assert!(num_events * mem::size_of::<VirtioInputEvent>() <= PAGE_SIZE);
|
assert!(num_events * mem::size_of::<VirtioInputEvent>() <= PAGE_SIZE);
|
||||||
|
|
||||||
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
|
let vm_segment = FrameAllocOptions::new(1).alloc_contiguous().unwrap();
|
||||||
|
|
||||||
let default_event = VirtioInputEvent::default();
|
let default_event = VirtioInputEvent::default();
|
||||||
let iter = iter::repeat(&default_event).take(EVENT_SIZE);
|
let iter = iter::repeat(&default_event).take(EVENT_SIZE);
|
||||||
|
@ -10,7 +10,7 @@ use core::{
|
|||||||
|
|
||||||
use aster_frame::{
|
use aster_frame::{
|
||||||
io_mem::IoMem,
|
io_mem::IoMem,
|
||||||
mm::{DmaCoherent, VmAllocOptions},
|
mm::{DmaCoherent, FrameAllocOptions},
|
||||||
offset_of,
|
offset_of,
|
||||||
};
|
};
|
||||||
use aster_rights::{Dup, TRightSet, TRights, Write};
|
use aster_rights::{Dup, TRightSet, TRights, Write};
|
||||||
@ -82,7 +82,7 @@ impl VirtQueue {
|
|||||||
let desc_size = size_of::<Descriptor>() * size as usize;
|
let desc_size = size_of::<Descriptor>() * size as usize;
|
||||||
|
|
||||||
let (seg1, seg2) = {
|
let (seg1, seg2) = {
|
||||||
let continue_segment = VmAllocOptions::new(2).alloc_contiguous().unwrap();
|
let continue_segment = FrameAllocOptions::new(2).alloc_contiguous().unwrap();
|
||||||
let seg1 = continue_segment.range(0..1);
|
let seg1 = continue_segment.range(0..1);
|
||||||
let seg2 = continue_segment.range(1..2);
|
let seg2 = continue_segment.range(1..2);
|
||||||
(seg1, seg2)
|
(seg1, seg2)
|
||||||
@ -101,17 +101,17 @@ impl VirtQueue {
|
|||||||
}
|
}
|
||||||
(
|
(
|
||||||
SafePtr::new(
|
SafePtr::new(
|
||||||
DmaCoherent::map(VmAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
DmaCoherent::map(FrameAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
SafePtr::new(
|
SafePtr::new(
|
||||||
DmaCoherent::map(VmAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
DmaCoherent::map(FrameAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
SafePtr::new(
|
SafePtr::new(
|
||||||
DmaCoherent::map(VmAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
DmaCoherent::map(FrameAllocOptions::new(1).alloc_contiguous().unwrap(), true)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user