diff options
-rw-r--r-- | Makefrag.am | 1 | ||||
-rw-r--r-- | kern/error.h | 11 | ||||
-rw-r--r-- | vm/vm_map.c | 37 | ||||
-rw-r--r-- | vm/vm_object.c | 31 | ||||
-rw-r--r-- | vm/vm_object.h | 8 |
5 files changed, 76 insertions, 12 deletions
diff --git a/Makefrag.am b/Makefrag.am index 8740ac6e..3bd12fbc 100644 --- a/Makefrag.am +++ b/Makefrag.am @@ -62,6 +62,7 @@ x15_SOURCES += \ vm/vm_kmem.h \ vm/vm_map.c \ vm/vm_map.h \ + vm/vm_object.c \ vm/vm_object.h \ vm/vm_page.h \ vm/vm_phys.c \ diff --git a/kern/error.h b/kern/error.h index f80e5a94..a376d379 100644 --- a/kern/error.h +++ b/kern/error.h @@ -18,10 +18,11 @@ #ifndef _KERN_ERROR_H #define _KERN_ERROR_H -#define ERROR_NOMEM 1 -#define ERROR_AGAIN 2 -#define ERROR_INVAL 3 -#define ERROR_BUSY 4 -#define ERROR_FAULT 5 +#define ERROR_NOMEM 1 +#define ERROR_AGAIN 2 +#define ERROR_INVAL 3 +#define ERROR_BUSY 4 +#define ERROR_FAULT 5 +#define ERROR_ACCES 6 #endif /* _KERN_ERROR_H */ diff --git a/vm/vm_map.c b/vm/vm_map.c index f65ce5e5..559beb2b 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -917,16 +917,43 @@ int vm_map_fault(struct vm_map *map, unsigned long addr, int access) { struct vm_map_entry *entry; + struct vm_page *page; + int error; + + addr = vm_page_trunc(addr); - (void)access; + mutex_lock(&map->lock); entry = vm_map_fault_lookup(map, addr); - if (entry == NULL) - return ERROR_FAULT; + if (entry == NULL) { + error = ERROR_FAULT; + goto out; + } + + if ((access & VM_MAP_PROT(entry->flags)) != access) { + error = ERROR_ACCES; + goto out; + } - printk("vm_map: fault on entry %p\n", entry); - return ERROR_AGAIN; + /* 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)); + + if (page == NULL) { + /* TODO Get page from pager */ + error = ERROR_FAULT; + goto out; + } + + /* TODO Map the page */ + + error = ERROR_INVAL; + +out: + mutex_unlock(&map->lock); + return error; } static void diff --git a/vm/vm_object.c b/vm/vm_object.c new file mode 100644 index 00000000..d3cd9493 --- /dev/null +++ b/vm/vm_object.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 Richard Braun. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <kern/rdxtree.h> +#include <kern/rdxtree.h> +#include <kern/stddef.h> +#include <kern/stdint.h> +#include <vm/vm_object.h> +#include <vm/vm_page.h> + +struct vm_page * +vm_object_get(const struct vm_object *object, uint64_t offset) +{ + /* TODO Bump radix tree key size to 64-bits */ + + return NULL; +} diff --git a/vm/vm_object.h b/vm/vm_object.h index 86bd12f5..b8b34aa9 100644 --- a/vm/vm_object.h +++ b/vm/vm_object.h @@ -27,12 +27,11 @@ #ifndef _VM_VM_OBJECT_H #define _VM_VM_OBJECT_H -#include <kern/list.h> #include <kern/mutex.h> #include <kern/rdxtree.h> #include <kern/stdint.h> -#include <vm/vm_page.h> +struct vm_page; struct vm_object_pager; /* @@ -64,4 +63,9 @@ vm_object_init(struct vm_object *object, struct vm_object_pager *pager) object->pager = pager; } +/* + * Get the page at offset inside an object, or NULL if none is found. + */ +struct vm_page * vm_object_get(const struct vm_object *object, uint64_t offset); + #endif /* _VM_VM_OBJECT_H */ |