summaryrefslogtreecommitdiff
path: root/vm/vm_map.c
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-07-04 14:20:24 +0200
committerRichard Braun <rbraun@sceen.net>2013-07-06 19:02:10 +0200
commit1c389aca56725700cf9e99805eb90feb0b94072b (patch)
tree22ca929244a33c5d2c699d1a8b16399b2f707de8 /vm/vm_map.c
parentb6e66e8290ca33102714f34f66d2ed2062ba33f3 (diff)
page fault handling works !
Diffstat (limited to 'vm/vm_map.c')
-rw-r--r--vm/vm_map.c27
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);