deprecate sync/dirty and emplace the writepage syscall

This commit is contained in:
bunnie 2025-05-18 04:25:18 +08:00
parent dfd82c94b8
commit 289028fa48

View file

@ -7,7 +7,6 @@ use xous_kernel::arch::PAGE_SIZE;
use xous_kernel::*;
use crate::arch;
use crate::arch::mem::MMUFlags;
use crate::arch::process::Process as ArchProcess;
use crate::irq::{interrupt_claim, interrupt_free};
use crate::mem::MemoryManager;
@ -1115,92 +1114,19 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
Err(xous_kernel::Error::AccessDenied)
}
}
SwapAbi::MarkDirty => {
// Any process can request a page to be marked as dirty. Note that simply
// writing to a page does *not* mark it as dirty. The updating process *must*
// manually mark pages as dirty.
let vaddr_start = a1;
let len_to_mark = a2;
MemoryManager::with_mut(|mm| {
let page_start = vaddr_start & !(PAGE_SIZE - 1);
let page_end = ((vaddr_start + len_to_mark) + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1);
for page in (page_start..page_end).step_by(PAGE_SIZE) {
let pte = crate::arch::mem::pagetable_entry(page)
.expect("couldn't retrieve PTE for dirty mark");
unsafe {
pte.write_volatile(pte.read_volatile() | MMUFlags::D.bits());
}
// figure out the paddr corresponding to the vaddr above, and mark it dirty in the
// RPT
match crate::arch::mem::virt_to_phys(page) {
Ok(paddr) => {
mm.mark_rpt_dirty(paddr).expect("couldn't mark swap page as dirty")
}
_ => {
// if it happens to be swapped out, don't error on this
println!("MarkDirty: page does not exist in memory {:x}(v)", page);
()
}
}
}
Ok(xous_kernel::Result::Ok)
})
}
SwapAbi::Sync => {
SwapAbi::WritePage => {
if pid.get() != xous_kernel::SWAPPER_PID {
return Err(xous_kernel::Error::AccessDenied);
}
// This will only affect the current PID's mapped pages; it also does not de-allocate
// the pages from RAM, it merely syncs to disk and clears the dirty bit.
let vaddr_start = a1;
let len_to_sync = a2;
let target_pid_usize = a3;
let target_tid = crate::arch::process::current_tid();
use crate::services::SystemServices;
SystemServices::with(|system_services| {
let target_pid = PID::new(target_pid_usize as u8).unwrap();
// get a handle to the target memory space
let target_map = system_services.get_process(target_pid).unwrap().mapping;
let swapper_pid = PID::new(xous_kernel::SWAPPER_PID).unwrap();
let swapper_map = system_services.get_process(swapper_pid).unwrap().mapping;
// Any process can request a sync of dirty pages to FLASH
MemoryManager::with_mut(|mm| {
let vaddr_start_aligned = vaddr_start & !(PAGE_SIZE - 1);
let vaddr_end_aligned =
((vaddr_start_aligned + (vaddr_start - vaddr_start_aligned) + len_to_sync)
+ (PAGE_SIZE - 1))
& !(PAGE_SIZE - 1);
for vpage in (vaddr_start_aligned..vaddr_end_aligned).step_by(PAGE_SIZE) {
// swap to target memory space
target_map.activate().unwrap();
let paddr = match crate::arch::mem::virt_to_phys(vpage) {
Ok(paddr) => paddr,
_ => {
// keep this hint around because this may be indicative
// of an error.
println!("*********** Sync encountered unmapped page: {:x}v", vpage);
continue;
}
};
swapper_map.activate().unwrap();
if mm.rpt_is_dirty(paddr) {
#[cfg(feature = "debug-swap-verbose")]
println!("*********** Flushing dirty page: {:x}v {:x}p", vpage, paddr);
Swap::with_mut(|swap| {
swap.flush_page_syscall(vpage, paddr, target_pid, target_tid)
})
} else {
#[cfg(feature = "debug-swap-verbose")]
println!("********** {:x}v is clean", vpage);
}
}
});
Ok(xous_kernel::Result::Ok)
})
let src_pid = PID::new(a1 as u8).unwrap();
// strip off the virtual addres prefix: by definition this region is 1:1 mapped in the
// LSBs
let flash_offset = a2 & 0x0FFF_FFFF;
let page_vaddr_in_swapper = a3;
Swap::with_mut(|swap| {
swap.write_page_syscall(src_pid, flash_offset, page_vaddr_in_swapper);
});
Ok(xous_kernel::Result::Ok)
}
SwapAbi::Invalid => {
println!(