diff --git a/Cargo.lock b/Cargo.lock index ff1b4baf42..6e51ce15ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1288,7 +1288,7 @@ checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "page_table_entry" version = "0.5.3" -source = "git+https://github.com/Mivik/page_table_multiarch.git?rev=19ededd#19ededdb806ab3b22efb4880661790524fa421a5" +source = "git+https://github.com/OrangeQi-CQ/page_table_multiarch?rev=8bbd18a#8bbd18a15770c74734d2b2f69b69243ee53d6739" dependencies = [ "aarch64-cpu 10.0.0", "bitflags 2.9.1", @@ -1299,7 +1299,7 @@ dependencies = [ [[package]] name = "page_table_multiarch" version = "0.5.3" -source = "git+https://github.com/Mivik/page_table_multiarch.git?rev=19ededd#19ededdb806ab3b22efb4880661790524fa421a5" +source = "git+https://github.com/OrangeQi-CQ/page_table_multiarch?rev=8bbd18a#8bbd18a15770c74734d2b2f69b69243ee53d6739" dependencies = [ "log", "memory_addr", diff --git a/Cargo.toml b/Cargo.toml index 7214779f1a..667ea51df5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,5 +69,5 @@ axdma = { path = "modules/axdma" } lto = true [patch.crates-io] -page_table_multiarch = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" } -page_table_entry = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" } +page_table_multiarch = { git = "https://github.com/OrangeQi-CQ/page_table_multiarch", rev = "8bbd18a" } +page_table_entry = { git = "https://github.com/OrangeQi-CQ/page_table_multiarch", rev = "8bbd18a" } diff --git a/modules/axfs/src/fops.rs b/modules/axfs/src/fops.rs index 9cd1827a5e..cff40a8925 100644 --- a/modules/axfs/src/fops.rs +++ b/modules/axfs/src/fops.rs @@ -46,6 +46,7 @@ pub struct OpenOptions { create: bool, create_new: bool, directory: bool, + direct: bool, // system-specific _custom_flags: i32, _mode: u32, @@ -64,6 +65,7 @@ impl OpenOptions { create: false, create_new: false, directory: false, + direct: false, // system-specific _custom_flags: 0, _mode: 0o666, @@ -101,11 +103,20 @@ impl OpenOptions { pub fn directory(&mut self, directory: bool) { self.directory = directory; } + /// Sets the option to use page cache + pub fn direct(&mut self, direct: bool) { + self.direct = direct; + } + /// check whether contains directory. pub fn has_directory(&self) -> bool { self.directory } + pub fn has_direct(&self) -> bool { + self.direct + } + /// Sets the create flags. pub fn set_create(mut self, create: bool, create_new: bool) -> Self { self.create = create; @@ -125,6 +136,11 @@ impl OpenOptions { self } + pub fn set_direct(mut self, direct: bool) -> Self { + self.direct = direct; + self + } + const fn is_valid(&self) -> bool { if !self.read && !self.write && !self.append && !self.directory { return false; diff --git a/modules/axhal/src/mem.rs b/modules/axhal/src/mem.rs index e4e15747d3..23de880d45 100644 --- a/modules/axhal/src/mem.rs +++ b/modules/axhal/src/mem.rs @@ -54,6 +54,10 @@ pub struct MemRegion { /// `paddr = vaddr - PHYS_VIRT_OFFSET`. #[inline] pub const fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr { + assert!( + vaddr.as_usize() >= PHYS_VIRT_OFFSET, + "Converted address is invalid, check if the virtual address is in kernel space" + ); pa!(vaddr.as_usize() - PHYS_VIRT_OFFSET) } diff --git a/modules/axmm/src/aspace.rs b/modules/axmm/src/aspace.rs index f9691ec10f..1f87cbb71c 100644 --- a/modules/axmm/src/aspace.rs +++ b/modules/axmm/src/aspace.rs @@ -2,12 +2,12 @@ use core::fmt; use axerrno::{AxError, AxResult, ax_err}; use axhal::mem::phys_to_virt; -use axhal::paging::{MappingFlags, PageTable, PagingError}; +use axhal::paging::{MappingFlags, PageTable, PagingError, PageSize}; use memory_addr::{ MemoryAddr, PAGE_SIZE_4K, PageIter4K, PhysAddr, VirtAddr, VirtAddrRange, is_aligned_4k, }; use memory_set::{MemoryArea, MemorySet}; - +use axhal::arch::flush_tlb; use crate::backend::Backend; use crate::mapping_err_to_ax_err; @@ -39,6 +39,26 @@ impl AddrSpace { &self.pt } + pub fn check_page_dirty(&mut self, vaddr: VirtAddr) -> bool { + // 必须要刷新 tlb,否则会导致标志位不同步! + flush_tlb(Some(vaddr)); + self.pt.is_dirty(vaddr).unwrap() + } + + pub fn set_page_dirty(&mut self, vaddr: VirtAddr, dirty: bool) { + self.pt.set_dirty(vaddr, dirty).unwrap(); + } + + pub fn check_page_access(&mut self, vaddr: VirtAddr) -> bool { + // 必须要刷新 tlb,否则会导致标志位不同步! + flush_tlb(Some(vaddr)); + self.pt.is_accessed(vaddr).unwrap() + } + + pub fn set_page_access(&mut self, vaddr: VirtAddr, access: bool) { + self.pt.set_accessed(vaddr, access).unwrap(); + } + /// Returns the root physical address of the inner page table. pub const fn page_table_root(&self) -> PhysAddr { self.pt.root_paddr() @@ -161,6 +181,46 @@ impl AddrSpace { Ok(()) } + /// Forcely set the page table + pub fn force_map_page( + &mut self, + vaddr: VirtAddr, + paddr: PhysAddr, + access_flags: MappingFlags + ) -> bool { + match self.areas.find(vaddr) { + Some(area) => { + if !area.flags().contains(access_flags) { + panic!("FORCE MAP PAGE FAILED(ACCESS MOD): {:#x} => {:#x}!", vaddr, paddr); + } + match self.pt.map(vaddr, paddr, PageSize::Size4K, area.flags()) { + Ok(_) => { + return true; + }, + Err(e) => { + panic!("FORCE MAP PAGE FAILED(PAGE TABLE FAILED {:?}): {:#x} => {:#x}", e, vaddr, paddr); + } + } + }, + _ => { + panic!("FORCE MAP PAGE FAILED(NOT FOUND AREA): {:#x} => {:#x}!", vaddr, paddr); + }, + }; + } + + + pub fn force_unmap_page(&mut self, vaddr: VirtAddr) { + match self.areas.find(vaddr) { + Some(_) => { + self.pt.unmap(vaddr) + .map(|_| true) + .unwrap_or_else(|_| panic!("FORCE FORCE PAGE FAILED(PAGE TABLE FAILEDA): {:#x}!", vaddr)); + }, + _ => panic!("FORCE UNMAP PAGE FAILED(NOT FOUND AREA): {:#x}!", vaddr), + }; + } + + /// Populates the area with physical frames, returning false if the area /// contains unmapped area. pub fn populate_area(&mut self, mut start: VirtAddr, size: usize) -> AxResult {