From 8a38d940cc06a2608a0bf491b334687774bd32a0 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 15 Mar 2026 22:22:25 +0000 Subject: [PATCH] vm: address-space: add function to translate virtual addresses to physical --- include/kernel/address-space.h | 9 +++++++- vm/address-space.c | 40 ++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/kernel/address-space.h b/include/kernel/address-space.h index d84c0fd..076201e 100644 --- a/include/kernel/address-space.h +++ b/include/kernel/address-space.h @@ -5,7 +5,8 @@ #include #include -#define ADDRESS_SPACE_COPY_ALL ((size_t)-1) +#define ADDRESS_SPACE_COPY_ALL ((size_t) - 1) +#define ADDRESS_SPACE_F_ struct address_space; struct vm_object; @@ -158,6 +159,12 @@ extern kern_status_t address_space_memmove_v( size_t bytes_to_move, size_t *nr_bytes_moved); +extern kern_status_t address_space_translate( + struct address_space *space, + virt_addr_t in, + phys_addr_t *out, + unsigned long *irq_flags); + void address_space_dump(struct address_space *region); DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base) diff --git a/vm/address-space.c b/vm/address-space.c index f26421f..4dc16fc 100644 --- a/vm/address-space.c +++ b/vm/address-space.c @@ -110,9 +110,9 @@ static struct vm_area *get_entry( enum get_entry_flags flags) { /* `x` must be to the left of `y` */ -#define LEFT_DIFF(x, y) ((y) ? ((y)->vma_base - (x)) : ((size_t)-1)) +#define LEFT_DIFF(x, y) ((y) ? ((y)->vma_base - (x)) : ((size_t) - 1)) /* `x` must be to the right of `y` */ -#define RIGHT_DIFF(x, y) ((y) ? ((y)->vma_limit - (x)) : ((size_t)-1)) +#define RIGHT_DIFF(x, y) ((y) ? ((y)->vma_limit - (x)) : ((size_t) - 1)) struct btree_node *cur = region->s_mappings.b_root; if (!cur) { @@ -1413,6 +1413,42 @@ extern kern_status_t address_space_memmove_v( return KERN_OK; } +kern_status_t address_space_translate( + struct address_space *space, + virt_addr_t in, + phys_addr_t *out, + unsigned long *irq_flags) +{ + if (in >= VM_KERNEL_BASE) { + return vm_virt_to_phys((const void *)in); + } + + struct vm_area *area = get_entry(space, in, GET_ENTRY_EXACT); + if (!area || !area->vma_object) { + return KERN_NO_ENTRY; + } + + off_t offset = in - area->vma_base + area->vma_object_offset; + struct vm_object *vmo = area->vma_object; + vm_object_lock(vmo); + address_space_unlock(space); + struct vm_page *pg = vm_object_get_page( + vmo, + offset, + VMO_ALLOCATE_MISSING_PAGE | VMO_REQUEST_MISSING_PAGE, + irq_flags); + if (!pg) { + return KERN_NO_ENTRY; + } + + phys_addr_t paddr = vm_page_get_paddr(pg); + paddr += (in & VM_PAGE_MASK); + vm_object_unlock(vmo); + address_space_lock(space); + + return paddr; +} + #ifdef TRACE void address_space_dump(struct address_space *region) {