use ahrightos_memory::{
MemoryManager, Page, PageTable, PageTableEntry, PageTableFlags, PhysAddr, SimpleFrameAllocator,
VirtAddr, VmPermissions, VmRegion, VmRegionKind, VmRegionTable, PAGE_SIZE,
};
#[test]
fn memory_crate_exposes_kernel_ready_contract() {
let mut manager = MemoryManager::new(0x8020_0123, 0x8030_0000);
let first = manager.frame_allocator.allocate().expect("first frame");
assert_eq!(first.start_address().as_usize() % PAGE_SIZE, 0);
let page = Page::containing_address(VirtAddr::new(0x4000_0123));
assert_eq!(page.start_address(), VirtAddr::new(0x4000_0000));
let mut table = PageTable::new();
let entry = table.get_entry_mut(1);
entry.set(
PhysAddr::new(0x8020_0000).as_usize() >> 12,
PageTableFlags::Valid as usize | PageTableFlags::Read as usize,
);
assert_ne!(*table.get_entry(1), PageTableEntry::new());
table.zero();
assert_eq!(*table.get_entry(1), PageTableEntry::new());
}
#[test]
fn frame_allocator_ignores_double_free_and_kernel_range_free() {
let mut allocator = SimpleFrameAllocator::new(0x8020_0000, 0x8020_5000);
let first = allocator.allocate().expect("first frame");
let first_addr = first.start_address();
allocator.deallocate(first);
allocator.deallocate(first);
let reused = allocator.allocate().expect("reused frame");
let next = allocator.allocate().expect("next frame");
assert_eq!(reused.start_address(), first_addr);
assert_ne!(next.start_address(), first_addr);
let before = allocator.next_frame();
let kernel_frame = ahrightos_memory::PhysFrame::containing_address(PhysAddr::new(0x8010_0000));
allocator.deallocate(kernel_frame);
assert_eq!(allocator.next_frame(), before);
}
#[test]
fn vm_region_table_exposes_mmap_stack_and_swap_contracts() {
let user_rw = VmPermissions::READ
.union(VmPermissions::WRITE)
.union(VmPermissions::USER);
let mut table = VmRegionTable::new();
table
.insert(
VmRegion::new(
VirtAddr::new(0x4000_0000),
PAGE_SIZE * 2,
VmRegionKind::FileBacked,
user_rw,
)
.unwrap(),
)
.unwrap();
table
.insert(
VmRegion::new(
VirtAddr::new(0x5000_0000),
PAGE_SIZE,
VmRegionKind::SwapBacked,
user_rw,
)
.unwrap(),
)
.unwrap();
assert_eq!(table.len(), 2);
assert_eq!(
table.find(VirtAddr::new(0x4000_0100)).unwrap().kind(),
VmRegionKind::FileBacked
);
assert!(table.commit_page(VirtAddr::new(0x5000_0000)).unwrap());
assert_eq!(
table
.find(VirtAddr::new(0x5000_0000))
.unwrap()
.committed_page_count(),
1
);
}