diff --git a/modules/axfs-ng/src/fs/ext4/mod.rs b/modules/axfs-ng/src/fs/ext4/mod.rs index 7e5fa2d0a9..fd8c6e6b2b 100644 --- a/modules/axfs-ng/src/fs/ext4/mod.rs +++ b/modules/axfs-ng/src/fs/ext4/mod.rs @@ -12,24 +12,16 @@ pub(crate) struct Ext4Disk(AxBlockDevice); impl BlockDevice for Ext4Disk { fn read_blocks(&mut self, block_id: u64, buf: &mut [u8]) -> Ext4Result { - let mut block_buf = [0u8; EXT4_DEV_BSIZE]; - for (i, block) in buf.chunks_mut(EXT4_DEV_BSIZE).enumerate() { - self.0 - .read_block(block_id + i as u64, &mut block_buf) - .map_err(|_| Ext4Error::new(EIO as _, None))?; - block.copy_from_slice(&block_buf); - } + self.0 + .read_block(block_id, buf) + .map_err(|_| Ext4Error::new(EIO as _, None))?; Ok(buf.len()) } fn write_blocks(&mut self, block_id: u64, buf: &[u8]) -> Ext4Result { - let mut block_buf = [0u8; EXT4_DEV_BSIZE]; - for (i, block) in buf.chunks(EXT4_DEV_BSIZE).enumerate() { - block_buf.copy_from_slice(block); - self.0 - .write_block(block_id + i as u64, &block_buf) - .map_err(|_| Ext4Error::new(EIO as _, None))?; - } + self.0 + .write_block(block_id, buf) + .map_err(|_| Ext4Error::new(EIO as _, None))?; Ok(buf.len()) } diff --git a/modules/axhal/src/percpu.rs b/modules/axhal/src/percpu.rs index d6f1c88771..09f738dcd5 100644 --- a/modules/axhal/src/percpu.rs +++ b/modules/axhal/src/percpu.rs @@ -80,6 +80,10 @@ pub(crate) fn init_primary(cpu_id: usize) { CPU_ID.write_current_raw(cpu_id); IS_BSP.write_current_raw(true); } + #[cfg(all(feature = "irq", target_arch = "riscv64"))] + { + axplat_riscv64_qemu_virt::register_this_cpu_id(this_cpu_id); + } } #[allow(dead_code)] @@ -89,4 +93,8 @@ pub(crate) fn init_secondary(cpu_id: usize) { CPU_ID.write_current_raw(cpu_id); IS_BSP.write_current_raw(false); } + #[cfg(all(feature = "irq", target_arch = "riscv64"))] + { + axplat_riscv64_qemu_virt::register_this_cpu_id(this_cpu_id); + } } diff --git a/modules/axmm/src/aspace.rs b/modules/axmm/src/aspace.rs index 4288a20195..e2271ed190 100644 --- a/modules/axmm/src/aspace.rs +++ b/modules/axmm/src/aspace.rs @@ -172,7 +172,7 @@ impl AddrSpace { while let Some(area) = self.areas.find(start) { let range = VirtAddrRange::new(start, area.end().min(end)); area.backend() - .populate(range, area.flags(), access_flags, &mut modify)?; + .populate(area, range, area.flags(), access_flags, &mut modify)?; start = area.end(); assert!(start.is_aligned_4k()); if start >= end { @@ -325,6 +325,7 @@ impl AddrSpace { if flags.contains(access_flags) { let page_size = area.backend().page_size(); let populate_result = area.backend().populate( + area, VirtAddrRange::from_start_size(vaddr.align_down(page_size), page_size as _), flags, access_flags, diff --git a/modules/axmm/src/backend/cow.rs b/modules/axmm/src/backend/cow.rs index 57baa8ae58..530c41d897 100644 --- a/modules/axmm/src/backend/cow.rs +++ b/modules/axmm/src/backend/cow.rs @@ -10,6 +10,7 @@ use axhal::{ use axsync::Mutex; use kspin::SpinNoIrq; use memory_addr::{PhysAddr, VirtAddr, VirtAddrRange}; +use memory_set::MemoryArea; use crate::{ AddrSpace, @@ -142,11 +143,13 @@ impl BackendOps for CowBackend { fn populate( &self, + area: &MemoryArea, range: VirtAddrRange, flags: MappingFlags, access_flags: MappingFlags, pt: &mut PageTableMut, ) -> AxResult<(usize, Option>)> { + const PREFETCH_PAGES: usize = 3; let mut pages = 0; for addr in pages_in(range, self.size)? { match pt.query(addr) { @@ -163,6 +166,29 @@ impl BackendOps for CowBackend { Err(PagingError::NotMapped) => { self.alloc_new_at(addr, flags, pt)?; pages += 1; + // prefetch at most PREFETCH_PAGES pages ahead + let va_range = area.va_range(); + for addr in pages_in( + VirtAddrRange::from_start_size( + addr + self.size as usize, + PREFETCH_PAGES * self.size as usize, + ), + self.size, + )? { + if !va_range.contains(addr) { + break; + } + match pt.query(addr) { + Ok(_) => { + // Already mapped. + } + Err(PagingError::NotMapped) => { + self.alloc_new_at(addr, flags, pt)?; + pages += 1; + } + Err(_) => break, + } + } } Err(_) => return Err(AxError::BadAddress), } diff --git a/modules/axmm/src/backend/file.rs b/modules/axmm/src/backend/file.rs index 123f44e3dd..9033220243 100644 --- a/modules/axmm/src/backend/file.rs +++ b/modules/axmm/src/backend/file.rs @@ -10,6 +10,7 @@ use axfs_ng::{CachedFile, FileFlags}; use axhal::paging::{MappingFlags, PageSize, PageTableMut, PagingError}; use axsync::Mutex; use memory_addr::{PAGE_SIZE_4K, VirtAddr, VirtAddrRange}; +use memory_set::MemoryArea; use crate::{ AddrSpace, @@ -138,6 +139,7 @@ impl BackendOps for FileBackend { fn populate( &self, + _area: &MemoryArea, range: VirtAddrRange, flags: MappingFlags, access_flags: MappingFlags, diff --git a/modules/axmm/src/backend/mod.rs b/modules/axmm/src/backend/mod.rs index 35da4493af..f1c71522c5 100644 --- a/modules/axmm/src/backend/mod.rs +++ b/modules/axmm/src/backend/mod.rs @@ -10,7 +10,7 @@ use axhal::{ use axsync::Mutex; use enum_dispatch::enum_dispatch; use memory_addr::{PAGE_SIZE_4K, PhysAddr, VirtAddr, VirtAddrRange}; -use memory_set::MappingBackend; +use memory_set::{MappingBackend, MemoryArea}; pub mod cow; pub mod file; @@ -74,6 +74,7 @@ pub trait BackendOps { /// Populate a memory region. Returns number of pages populated. fn populate( &self, + _area: &MemoryArea, _range: VirtAddrRange, _flags: MappingFlags, _access_flags: MappingFlags, diff --git a/modules/axruntime/Cargo.toml b/modules/axruntime/Cargo.toml index 25216be460..c74d8e65c6 100644 --- a/modules/axruntime/Cargo.toml +++ b/modules/axruntime/Cargo.toml @@ -48,3 +48,6 @@ chrono = { workspace = true, optional = true } crate_interface = { workspace = true } indoc = "2" percpu = { workspace = true, optional = true } + +[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] +riscv = "0.14" \ No newline at end of file diff --git a/modules/axruntime/src/lib.rs b/modules/axruntime/src/lib.rs index 8609d09e2b..2dfdc5d932 100644 --- a/modules/axruntime/src/lib.rs +++ b/modules/axruntime/src/lib.rs @@ -246,6 +246,11 @@ pub fn rust_main(cpu_id: usize, arg: usize) -> ! { core::hint::spin_loop(); } + #[cfg(target_arch = "riscv64")] + unsafe { + use riscv::register::sstatus; + sstatus::set_sum(); + } unsafe { main() }; #[cfg(feature = "multitask")] diff --git a/modules/axruntime/src/mp.rs b/modules/axruntime/src/mp.rs index 464cfd7326..50a6fd4091 100644 --- a/modules/axruntime/src/mp.rs +++ b/modules/axruntime/src/mp.rs @@ -51,6 +51,14 @@ pub fn rust_main_secondary(cpu_id: usize) -> ! { #[cfg(feature = "ipi")] axipi::init(); + #[cfg(target_arch = "riscv64")] + { + use riscv::register::sstatus; + unsafe { + sstatus::set_sum(); + } + } + info!("Secondary CPU {:x} init OK.", cpu_id); super::INITED_CPUS.fetch_add(1, Ordering::Release);