Finds an available page chunk entry, stores the physical address in the page table and returns the virtual address.
(
level_4_physaddr: u64,
physaddr: PhysAddr
)
| 601 | /// Finds an available page chunk entry, stores the physical address |
| 602 | /// in the page table and returns the virtual address. |
| 603 | pub fn put_page_chunk( |
| 604 | level_4_physaddr: u64, |
| 605 | physaddr: PhysAddr |
| 606 | ) -> Result<VirtAddr, usize> { |
| 607 | let memory_info = unsafe {MEMORY_INFO.as_mut().unwrap()}; |
| 608 | |
| 609 | let l4_table: &mut PageTable = unsafe { |
| 610 | &mut *(memory_info.physical_memory_offset |
| 611 | + level_4_physaddr).as_mut_ptr()}; |
| 612 | let l4_entry = &mut l4_table[MEMORY_CHUNK_L4_ENTRY]; |
| 613 | |
| 614 | if l4_entry.is_unused() { |
| 615 | // L3 table not allocated -> Create |
| 616 | let (_new_table_ptr, new_table_physaddr) = create_empty_pagetable(); |
| 617 | l4_entry.set_addr(PhysAddr::new(new_table_physaddr), |
| 618 | PageTableFlags::PRESENT | |
| 619 | PageTableFlags::WRITABLE | |
| 620 | PageTableFlags::USER_ACCESSIBLE); |
| 621 | } |
| 622 | let l3_table: &mut PageTable = unsafe { |
| 623 | &mut *(memory_info.physical_memory_offset |
| 624 | + l4_entry.addr().as_u64()).as_mut_ptr()}; |
| 625 | |
| 626 | // Each entry in l3_table from FIRST to LAST inclusive |
| 627 | // is a separate chunk |
| 628 | for ind in MEMORY_CHUNK_L3_FIRST..=MEMORY_CHUNK_L3_LAST { |
| 629 | let entry = &mut l3_table[ind]; |
| 630 | if entry.is_unused() { |
| 631 | // Found an empty chunk |
| 632 | entry.set_addr(physaddr, |
| 633 | PageTableFlags::PRESENT | |
| 634 | PageTableFlags::WRITABLE | |
| 635 | PageTableFlags::USER_ACCESSIBLE); |
| 636 | |
| 637 | // Convert L4 and L3 index into virtual address |
| 638 | return Ok(VirtAddr::new(((MEMORY_CHUNK_L4_ENTRY as u64) << 39) | |
| 639 | (ind << 30) as u64)); |
| 640 | } |
| 641 | } |
| 642 | Err(syscalls::SYSCALL_ERROR_NOMEMSLOTS) |
| 643 | } |
| 644 | |
| 645 | /////////////////////////////////////////////////////////////////////// |
| 646 |
no test coverage detected