diff options
author | Richard Braun <rbraun@sceen.net> | 2013-07-04 14:20:24 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-07-06 19:02:10 +0200 |
commit | 1c389aca56725700cf9e99805eb90feb0b94072b (patch) | |
tree | 22ca929244a33c5d2c699d1a8b16399b2f707de8 /vm/vm_map.c | |
parent | b6e66e8290ca33102714f34f66d2ed2062ba33f3 (diff) |
page fault handling works !
Diffstat (limited to 'vm/vm_map.c')
-rw-r--r-- | vm/vm_map.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/vm/vm_map.c b/vm/vm_map.c index 559beb2b..50e9c361 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -917,8 +917,10 @@ int vm_map_fault(struct vm_map *map, unsigned long addr, int access) { struct vm_map_entry *entry; + struct vm_object *object; struct vm_page *page; - int error; + uint64_t offset; + int error, prot; addr = vm_page_trunc(addr); @@ -938,18 +940,27 @@ vm_map_fault(struct vm_map *map, unsigned long addr, int access) /* Null mappings are reserved for the kernel and always wired */ assert(entry->object != NULL); - - page = vm_object_get(entry->object, entry->offset + (addr - entry->start)); + object = entry->object; + offset = entry->offset + (addr - entry->start); + page = vm_object_get(object, offset); if (page == NULL) { - /* TODO Get page from pager */ - error = ERROR_FAULT; - goto out; + /* TODO Get neighbor pages */ + error = object->pager->get(object, offset, &page); + + if (error) + goto out; } - /* TODO Map the page */ + prot = VM_MAP_PROT(entry->flags); + error = pmap_enter(map->pmap, addr, vm_page_to_pa(page), prot); + + /* TODO Properly handle errors */ + if (error) + panic("vm_map: unable to create physical mapping"); - error = ERROR_INVAL; + pmap_update(map->pmap, addr, addr + PAGE_SIZE); + error = 0; out: mutex_unlock(&map->lock); |