*/
void vmm_unmap_page(uint64_t virt);
+/*
+ * Find a contiguous free (unmapped) virtual address region.
+ * Scans page tables from 'start' up to 'end' for 'length' bytes of
+ * contiguous unmapped pages. Returns the base VA, or 0 on failure.
+ */
+uintptr_t vmm_find_free_area(uintptr_t start, uintptr_t end, uint32_t length);
+
#endif
return 1;
}
+uintptr_t vmm_find_free_area(uintptr_t start, uintptr_t end, uint32_t length) {
+ if (length == 0) return 0;
+ uint32_t pages_needed = (length + 0xFFFU) >> 12;
+
+ uintptr_t irqf = spin_lock_irqsave(&vmm_lock);
+
+ uintptr_t run_start = start & ~(uintptr_t)0xFFF;
+ uint32_t run_len = 0;
+
+ for (uintptr_t va = run_start; va < end; va += 0x1000U) {
+ uint32_t pi = pae_pdpt_index((uint64_t)va);
+ uint32_t di = pae_pd_index((uint64_t)va);
+ uint32_t ti = pae_pt_index((uint64_t)va);
+
+ int mapped = 0;
+ volatile uint64_t* pd = pae_pd_recursive(pi);
+ if (pd[di] & X86_PTE_PRESENT) {
+ volatile uint64_t* pt = pae_pt_recursive(pi, di);
+ if (pt[ti] & X86_PTE_PRESENT)
+ mapped = 1;
+ }
+
+ if (!mapped) {
+ if (run_len == 0) run_start = va;
+ run_len++;
+ if (run_len >= pages_needed) {
+ spin_unlock_irqrestore(&vmm_lock, irqf);
+ return run_start;
+ }
+ } else {
+ run_len = 0;
+ }
+ }
+
+ spin_unlock_irqrestore(&vmm_lock, irqf);
+ return 0;
+}
+
void vmm_init(void) {
kprintf("[VMM] PAE paging active.\n");
const uintptr_t MMAP_BASE = 0x40000000U;
const uintptr_t MMAP_END = 0x7FF00000U;
- for (uintptr_t candidate = MMAP_BASE; candidate + length <= MMAP_END; candidate += 0x1000U) {
- int overlap = 0;
- for (int i = 0; i < PROCESS_MAX_MMAPS; i++) {
- if (current_process->mmaps[i].length == 0) continue;
- uintptr_t mb = current_process->mmaps[i].base;
- uint32_t ml = current_process->mmaps[i].length;
- if (candidate < mb + ml && candidate + length > mb) {
- overlap = 1;
- candidate = ((mb + ml + 0xFFFU) & ~(uintptr_t)0xFFFU) - 0x1000U;
- break;
- }
- }
- if (!overlap) return candidate;
- }
- return 0;
+ return vmm_find_free_area(MMAP_BASE, MMAP_END, length);
}
__attribute__((noinline))