Nothing to see here, move along
at main 69 lines 2.3 kB view raw
1use x86_64::PhysAddr; 2use x86_64::VirtAddr; 3use x86_64::structures::paging::{ 4 Mapper, OffsetPageTable, Page, PageTableFlags, PhysFrame, Size4KiB, 5}; 6 7use super::phys::BitmapFrameAllocator; 8 9pub fn map_mmio( 10 mapper: &mut OffsetPageTable, 11 allocator: &mut BitmapFrameAllocator, 12 phys: u64, 13 hhdm_offset: u64, 14) -> Result<(), crate::error::KernelError> { 15 let virt = VirtAddr::new(phys + hhdm_offset); 16 let page: Page<Size4KiB> = Page::containing_address(virt); 17 let frame = PhysFrame::containing_address(PhysAddr::new(phys)); 18 let flags = PageTableFlags::PRESENT 19 | PageTableFlags::WRITABLE 20 | PageTableFlags::NO_CACHE 21 | PageTableFlags::WRITE_THROUGH 22 | PageTableFlags::NO_EXECUTE; 23 24 match unsafe { mapper.map_to(page, frame, flags, allocator) } { 25 Ok(flush) => { 26 flush.flush(); 27 Ok(()) 28 } 29 Err(x86_64::structures::paging::mapper::MapToError::PageAlreadyMapped(existing)) => { 30 if existing == frame { 31 Ok(()) 32 } else { 33 Err(crate::error::KernelError::InvalidAddress) 34 } 35 } 36 Err(_) => Err(crate::error::KernelError::ResourceExhausted), 37 } 38} 39 40pub fn test_mapping(mapper: &mut OffsetPageTable, allocator: &mut BitmapFrameAllocator) { 41 let test_addr = VirtAddr::new(0xFFFF_FFFF_F000_0000); 42 let test_page: Page<Size4KiB> = Page::containing_address(test_addr); 43 44 let frame = allocator.allocate().expect("Failed to allocate test frame"); 45 46 let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; 47 let phys_frame = frame.inner(); 48 49 unsafe { 50 mapper 51 .map_to(test_page, phys_frame, flags, allocator) 52 .expect("Failed to map test page") 53 .flush(); 54 } 55 56 let ptr: *mut u64 = test_addr.as_mut_ptr(); 57 unsafe { ptr.write_volatile(0xDEAD_BEEF_CAFE_BABE) }; 58 let readback = unsafe { ptr.read_volatile() }; 59 assert_eq!( 60 readback, 0xDEAD_BEEF_CAFE_BABE, 61 "Virtual memory test failed" 62 ); 63 64 let (returned_frame, flush) = mapper.unmap(test_page).expect("Failed to unmap test page"); 65 flush.flush(); 66 allocator.deallocate_frame(returned_frame); 67 68 crate::kprintln!(" Virtual memory mapping test passed"); 69}