Skip to content

Commit

Permalink
Merge pull request #178 from Azure-stars/arceos_main
Browse files Browse the repository at this point in the history
[mm] Add functions to read and write data in AddrSpace
  • Loading branch information
equation314 authored Sep 23, 2024
2 parents 76d8cfc + d9ea8ce commit 6cc3eb3
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }}
run: make clippy ARCH=aarch64
- name: Check code format
continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }}
run: cargo fmt --all -- --check

build:
Expand Down
67 changes: 65 additions & 2 deletions modules/axmm/src/aspace.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use core::fmt;

use axerrno::{ax_err, AxError, AxResult};
use axhal::paging::{MappingFlags, PageTable};
use memory_addr::{is_aligned_4k, pa, MemoryAddr, PhysAddr, VirtAddr, VirtAddrRange};
use axhal::{
mem::phys_to_virt,
paging::{MappingFlags, PageTable},
};
use memory_addr::{
is_aligned_4k, pa, MemoryAddr, PageIter4K, PhysAddr, VirtAddr, VirtAddrRange, PAGE_SIZE_4K,
};

use crate::paging_err_to_ax_err;

Expand Down Expand Up @@ -109,6 +114,64 @@ impl AddrSpace {
Ok(())
}

/// To process data in this area with the given function.
///
/// Now it supports reading and writing data in the given interval.
fn process_area_data<F>(&self, start: VirtAddr, size: usize, mut f: F) -> AxResult
where
F: FnMut(VirtAddr, usize, usize),
{
if !self.contains_range(start, size) {
return ax_err!(InvalidInput, "address out of range");
}
let mut cnt = 0;
// If start is aligned to 4K, start_align_down will be equal to start_align_up.
let end_align_up = (start + size).align_up_4k();
for vaddr in PageIter4K::new(start.align_down_4k(), end_align_up)
.expect("Failed to create page iterator")
{
let (mut paddr, _, _) = self.pt.query(vaddr).map_err(|_| AxError::BadAddress)?;

let mut copy_size = (size - cnt).min(PAGE_SIZE_4K);

if copy_size == 0 {
break;
}
if vaddr == start.align_down_4k() && start.align_offset_4k() != 0 {
let align_offset = start.align_offset_4k();
copy_size = copy_size.min(PAGE_SIZE_4K - align_offset);
paddr += align_offset;
}
f(phys_to_virt(paddr), cnt, copy_size);
cnt += copy_size;
}
Ok(())
}

/// To read data from the address space.
///
/// # Arguments
///
/// * `start` - The start virtual address to read.
/// * `buf` - The buffer to store the data.
pub fn read(&self, start: VirtAddr, buf: &mut [u8]) -> AxResult {
self.process_area_data(start, buf.len(), |src, offset, read_size| unsafe {
core::ptr::copy_nonoverlapping(src.as_ptr(), buf.as_mut_ptr().add(offset), read_size);
})
}

/// To write data to the address space.
///
/// # Arguments
///
/// * `start_vaddr` - The start virtual address to write.
/// * `buf` - The buffer to write to the address space.
pub fn write(&self, start: VirtAddr, buf: &[u8]) -> AxResult {
self.process_area_data(start, buf.len(), |dst, offset, write_size| unsafe {
core::ptr::copy_nonoverlapping(buf.as_ptr().add(offset), dst.as_mut_ptr(), write_size);
})
}

/// Updates mapping within the specified virtual address range.
///
/// Returns an error if the address range is out of the address space or not
Expand Down

0 comments on commit 6cc3eb3

Please sign in to comment.