kern
changeset 68:0a205396e1a0
- added a generic red-black tree data structure
- added a VM map as an red-black tree of vm_pages in the process structure
- constructed the vm map of the memory passed by the kernel initially to the first process.
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Mon, 10 Oct 2011 04:16:01 +0300 |
parents | ebca81749ef5 |
children | b45e2d5f0ae1 |
files | src/proc.c src/proc.h src/rbtree.c src/rbtree.h src/vm.c src/vm.h |
diffstat | 6 files changed, 596 insertions(+), 4 deletions(-) [+] |
line diff
1.1 --- a/src/proc.c Sun Oct 09 20:38:35 2011 +0300 1.2 +++ b/src/proc.c Mon Oct 10 04:16:01 2011 +0300 1.3 @@ -131,6 +131,9 @@ 1.4 /* make it current */ 1.5 set_current_pid(p->id); 1.6 1.7 + /* build the current vm map */ 1.8 + cons_vmmap(&p->vmmap); 1.9 + 1.10 /* execute a fake return from interrupt with the fake stack frame */ 1.11 intr_ret(ifrm); 1.12 }
2.1 --- a/src/proc.h Sun Oct 09 20:38:35 2011 +0300 2.2 +++ b/src/proc.h Mon Oct 10 04:16:01 2011 +0300 2.3 @@ -3,6 +3,7 @@ 2.4 2.5 #include <inttypes.h> 2.6 #include "asmops.h" 2.7 +#include "rbtree.h" 2.8 2.9 #define MAX_PROC 128 2.10 2.11 @@ -31,6 +32,9 @@ 2.12 2.13 int ticks_left; 2.14 2.15 + /* process vm map */ 2.16 + struct rbtree vmmap; 2.17 + 2.18 /* extends of the process heap, increased by sbrk */ 2.19 2.20 /* first page of the user stack, extends up to KMEM_START */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/rbtree.c Mon Oct 10 04:16:01 2011 +0300 3.3 @@ -0,0 +1,457 @@ 3.4 +#include <stdio.h> 3.5 +#include <stdlib.h> 3.6 +#include <string.h> 3.7 +#include "rbtree.h" 3.8 + 3.9 +#define INT2PTR(x) ((void*)(x)) 3.10 +#define PTR2INT(x) ((int)(x)) 3.11 + 3.12 +static int cmpaddr(void *ap, void *bp); 3.13 +static int cmpint(void *ap, void *bp); 3.14 + 3.15 +static int count_nodes(struct rbnode *node); 3.16 +static void del_tree(struct rbnode *node, void (*delfunc)(struct rbnode*, void*), void *cls); 3.17 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data); 3.18 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key); 3.19 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key);*/ 3.20 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls); 3.21 + 3.22 +struct rbtree *rb_create(rb_cmp_func_t cmp_func) 3.23 +{ 3.24 + struct rbtree *rb; 3.25 + 3.26 + if(!(rb = malloc(sizeof *rb))) { 3.27 + return 0; 3.28 + } 3.29 + if(rb_init(rb, cmp_func) == -1) { 3.30 + free(rb); 3.31 + return 0; 3.32 + } 3.33 + return rb; 3.34 +} 3.35 + 3.36 +void rb_free(struct rbtree *rb) 3.37 +{ 3.38 + rb_destroy(rb); 3.39 + free(rb); 3.40 +} 3.41 + 3.42 + 3.43 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func) 3.44 +{ 3.45 + memset(rb, 0, sizeof *rb); 3.46 + 3.47 + if(cmp_func == RB_KEY_INT) { 3.48 + rb->cmp = cmpint; 3.49 + } else if(cmp_func == RB_KEY_STRING) { 3.50 + rb->cmp = (rb_cmp_func_t)strcmp; 3.51 + } else { 3.52 + rb->cmp = cmpaddr; 3.53 + } 3.54 + 3.55 + rb->alloc = malloc; 3.56 + rb->free = free; 3.57 + return 0; 3.58 +} 3.59 + 3.60 +void rb_destroy(struct rbtree *rb) 3.61 +{ 3.62 + del_tree(rb->root, rb->del, rb->del_cls); 3.63 +} 3.64 + 3.65 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free) 3.66 +{ 3.67 + rb->alloc = alloc; 3.68 + rb->free = free; 3.69 +} 3.70 + 3.71 + 3.72 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func) 3.73 +{ 3.74 + rb->cmp = func; 3.75 +} 3.76 + 3.77 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls) 3.78 +{ 3.79 + rb->del = func; 3.80 + rb->del_cls = cls; 3.81 +} 3.82 + 3.83 +int rb_size(struct rbtree *rb) 3.84 +{ 3.85 + return count_nodes(rb->root); 3.86 +} 3.87 + 3.88 +int rb_insert(struct rbtree *rb, void *key, void *data) 3.89 +{ 3.90 + rb->root = insert(rb, rb->root, key, data); 3.91 + rb->root->red = 0; 3.92 + return 0; 3.93 +} 3.94 + 3.95 +int rb_inserti(struct rbtree *rb, int key, void *data) 3.96 +{ 3.97 + rb->root = insert(rb, rb->root, INT2PTR(key), data); 3.98 + rb->root->red = 0; 3.99 + return 0; 3.100 +} 3.101 + 3.102 + 3.103 +int rb_delete(struct rbtree *rb, void *key) 3.104 +{ 3.105 + rb->root = delete(rb, rb->root, key); 3.106 + rb->root->red = 0; 3.107 + return 0; 3.108 +} 3.109 + 3.110 +int rb_deletei(struct rbtree *rb, int key) 3.111 +{ 3.112 + rb->root = delete(rb, rb->root, INT2PTR(key)); 3.113 + rb->root->red = 0; 3.114 + return 0; 3.115 +} 3.116 + 3.117 + 3.118 +void *rb_find(struct rbtree *rb, void *key) 3.119 +{ 3.120 + struct rbnode *node = rb->root; 3.121 + 3.122 + while(node) { 3.123 + int cmp = rb->cmp(key, node->key); 3.124 + if(cmp == 0) { 3.125 + return node; 3.126 + } 3.127 + node = cmp < 0 ? node->left : node->right; 3.128 + } 3.129 + return 0; 3.130 +} 3.131 + 3.132 +void *rb_findi(struct rbtree *rb, int key) 3.133 +{ 3.134 + return rb_find(rb, INT2PTR(key)); 3.135 +} 3.136 + 3.137 + 3.138 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls) 3.139 +{ 3.140 + traverse(rb->root, func, cls); 3.141 +} 3.142 + 3.143 + 3.144 +struct rbnode *rb_root(struct rbtree *rb) 3.145 +{ 3.146 + return rb->root; 3.147 +} 3.148 + 3.149 +void rb_begin(struct rbtree *rb) 3.150 +{ 3.151 + rb->rstack = 0; 3.152 + rb->iter = rb->root; 3.153 +} 3.154 + 3.155 +#define push(sp, x) ((x)->next = (sp), (sp) = (x)) 3.156 +#define pop(sp) ((sp) = (sp)->next) 3.157 +#define top(sp) (sp) 3.158 + 3.159 +struct rbnode *rb_next(struct rbtree *rb) 3.160 +{ 3.161 + struct rbnode *res = 0; 3.162 + 3.163 + while(rb->rstack || rb->iter) { 3.164 + if(rb->iter) { 3.165 + push(rb->rstack, rb->iter); 3.166 + rb->iter = rb->iter->left; 3.167 + } else { 3.168 + rb->iter = top(rb->rstack); 3.169 + pop(rb->rstack); 3.170 + res = rb->iter; 3.171 + rb->iter = rb->iter->right; 3.172 + break; 3.173 + } 3.174 + } 3.175 + return res; 3.176 +} 3.177 + 3.178 +void *rb_node_key(struct rbnode *node) 3.179 +{ 3.180 + return node ? node->key : 0; 3.181 +} 3.182 + 3.183 +int rb_node_keyi(struct rbnode *node) 3.184 +{ 3.185 + return node ? PTR2INT(node->key) : 0; 3.186 +} 3.187 + 3.188 +void *rb_node_data(struct rbnode *node) 3.189 +{ 3.190 + return node ? node->data : 0; 3.191 +} 3.192 + 3.193 +static int cmpaddr(void *ap, void *bp) 3.194 +{ 3.195 + return ap < bp ? -1 : (ap > bp ? 1 : 0); 3.196 +} 3.197 + 3.198 +static int cmpint(void *ap, void *bp) 3.199 +{ 3.200 + return PTR2INT(ap) - PTR2INT(bp); 3.201 +} 3.202 + 3.203 + 3.204 +/* ---- left-leaning 2-3 red-black implementation ---- */ 3.205 + 3.206 +/* helper prototypes */ 3.207 +static int is_red(struct rbnode *tree); 3.208 +static void color_flip(struct rbnode *tree); 3.209 +static struct rbnode *rot_left(struct rbnode *a); 3.210 +static struct rbnode *rot_right(struct rbnode *a); 3.211 +static struct rbnode *find_min(struct rbnode *tree); 3.212 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree); 3.213 +/*static struct rbnode *move_red_right(struct rbnode *tree);*/ 3.214 +static struct rbnode *move_red_left(struct rbnode *tree); 3.215 +static struct rbnode *fix_up(struct rbnode *tree); 3.216 + 3.217 +static int count_nodes(struct rbnode *node) 3.218 +{ 3.219 + if(!node) 3.220 + return 0; 3.221 + 3.222 + return 1 + count_nodes(node->left) + count_nodes(node->right); 3.223 +} 3.224 + 3.225 +static void del_tree(struct rbnode *node, rb_del_func_t delfunc, void *cls) 3.226 +{ 3.227 + if(!node) 3.228 + return; 3.229 + 3.230 + del_tree(node->left, delfunc, cls); 3.231 + del_tree(node->right, delfunc, cls); 3.232 + 3.233 + delfunc(node, cls); 3.234 + free(node); 3.235 +} 3.236 + 3.237 +static struct rbnode *insert(struct rbtree *rb, struct rbnode *tree, void *key, void *data) 3.238 +{ 3.239 + int cmp; 3.240 + 3.241 + if(!tree) { 3.242 + struct rbnode *node = rb->alloc(sizeof *node); 3.243 + node->red = 1; 3.244 + node->key = key; 3.245 + node->data = data; 3.246 + node->left = node->right = 0; 3.247 + return node; 3.248 + } 3.249 + 3.250 + cmp = rb->cmp(key, tree->key); 3.251 + 3.252 + if(cmp < 0) { 3.253 + tree->left = insert(rb, tree->left, key, data); 3.254 + } else if(cmp > 0) { 3.255 + tree->right = insert(rb, tree->right, key, data); 3.256 + } else { 3.257 + tree->data = data; 3.258 + } 3.259 + 3.260 + /* fix right-leaning reds */ 3.261 + if(is_red(tree->right)) { 3.262 + tree = rot_left(tree); 3.263 + } 3.264 + /* fix two reds in a row */ 3.265 + if(is_red(tree->left) && is_red(tree->left->left)) { 3.266 + tree = rot_right(tree); 3.267 + } 3.268 + 3.269 + /* if 4-node, split it by color inversion */ 3.270 + if(is_red(tree->left) && is_red(tree->right)) { 3.271 + color_flip(tree); 3.272 + } 3.273 + 3.274 + return tree; 3.275 +} 3.276 + 3.277 +static struct rbnode *delete(struct rbtree *rb, struct rbnode *tree, void *key) 3.278 +{ 3.279 + int cmp; 3.280 + 3.281 + if(!tree) { 3.282 + return 0; 3.283 + } 3.284 + 3.285 + cmp = rb->cmp(key, tree->key); 3.286 + 3.287 + if(cmp < 0) { 3.288 + if(!is_red(tree->left) && !is_red(tree->left->left)) { 3.289 + tree = move_red_left(tree); 3.290 + } 3.291 + tree->left = delete(rb, tree->left, key); 3.292 + } else { 3.293 + /* need reds on the right */ 3.294 + if(is_red(tree->left)) { 3.295 + tree = rot_right(tree); 3.296 + } 3.297 + 3.298 + /* found it at the bottom (XXX what certifies left is null?) */ 3.299 + if(cmp == 0 && !tree->right) { 3.300 + if(rb->del) { 3.301 + rb->del(tree, rb->del_cls); 3.302 + } 3.303 + rb->free(tree); 3.304 + return 0; 3.305 + } 3.306 + 3.307 + if(!is_red(tree->right) && !is_red(tree->right->left)) { 3.308 + tree = move_red_left(tree); 3.309 + } 3.310 + 3.311 + if(key == tree->key) { 3.312 + struct rbnode *rmin = find_min(tree->right); 3.313 + tree->key = rmin->key; 3.314 + tree->data = rmin->data; 3.315 + tree->right = del_min(rb, tree->right); 3.316 + } else { 3.317 + tree->right = delete(rb, tree->right, key); 3.318 + } 3.319 + } 3.320 + 3.321 + return fix_up(tree); 3.322 +} 3.323 + 3.324 +/*static struct rbnode *find(struct rbtree *rb, struct rbnode *node, void *key) 3.325 +{ 3.326 + int cmp; 3.327 + 3.328 + if(!node) 3.329 + return 0; 3.330 + 3.331 + if((cmp = rb->cmp(key, node->key)) == 0) { 3.332 + return node; 3.333 + } 3.334 + return find(rb, cmp < 0 ? node->left : node->right, key); 3.335 +}*/ 3.336 + 3.337 +static void traverse(struct rbnode *node, void (*func)(struct rbnode*, void*), void *cls) 3.338 +{ 3.339 + if(!node) 3.340 + return; 3.341 + 3.342 + traverse(node->left, func, cls); 3.343 + func(node, cls); 3.344 + traverse(node->right, func, cls); 3.345 +} 3.346 + 3.347 +/* helpers */ 3.348 + 3.349 +static int is_red(struct rbnode *tree) 3.350 +{ 3.351 + return tree && tree->red; 3.352 +} 3.353 + 3.354 +static void color_flip(struct rbnode *tree) 3.355 +{ 3.356 + tree->red = !tree->red; 3.357 + tree->left->red = !tree->left->red; 3.358 + tree->right->red = !tree->right->red; 3.359 +} 3.360 + 3.361 +static struct rbnode *rot_left(struct rbnode *a) 3.362 +{ 3.363 + struct rbnode *b = a->right; 3.364 + a->right = b->left; 3.365 + b->left = a; 3.366 + b->red = a->red; 3.367 + a->red = 1; 3.368 + return b; 3.369 +} 3.370 + 3.371 +static struct rbnode *rot_right(struct rbnode *a) 3.372 +{ 3.373 + struct rbnode *b = a->left; 3.374 + a->left = b->right; 3.375 + b->right = a; 3.376 + b->red = a->red; 3.377 + a->red = 1; 3.378 + return b; 3.379 +} 3.380 + 3.381 +static struct rbnode *find_min(struct rbnode *tree) 3.382 +{ 3.383 + struct rbnode *node; 3.384 + 3.385 + if(!tree) 3.386 + return 0; 3.387 + 3.388 + while(node->left) { 3.389 + node = node->left; 3.390 + } 3.391 + return node; 3.392 +} 3.393 + 3.394 +static struct rbnode *del_min(struct rbtree *rb, struct rbnode *tree) 3.395 +{ 3.396 + if(!tree->left) { 3.397 + if(rb->del) { 3.398 + rb->del(tree->left, rb->del_cls); 3.399 + } 3.400 + rb->free(tree->left); 3.401 + return 0; 3.402 + } 3.403 + 3.404 + /* make sure we've got red (3/4-nodes) at the left side so we can delete at the bottom */ 3.405 + if(!is_red(tree->left) && !is_red(tree->left->left)) { 3.406 + tree = move_red_left(tree); 3.407 + } 3.408 + tree->left = del_min(rb, tree->left); 3.409 + 3.410 + /* fix right-reds, red-reds, and split 4-nodes on the way up */ 3.411 + return fix_up(tree); 3.412 +} 3.413 + 3.414 +#if 0 3.415 +/* push a red link on this node to the right */ 3.416 +static struct rbnode *move_red_right(struct rbnode *tree) 3.417 +{ 3.418 + /* flipping it makes both children go red, so we have a red to the right */ 3.419 + color_flip(tree); 3.420 + 3.421 + /* if after the flip we've got a red-red situation to the left, fix it */ 3.422 + if(is_red(tree->left->left)) { 3.423 + tree = rot_right(tree); 3.424 + color_flip(tree); 3.425 + } 3.426 + return tree; 3.427 +} 3.428 +#endif 3.429 + 3.430 +/* push a red link on this node to the left */ 3.431 +static struct rbnode *move_red_left(struct rbnode *tree) 3.432 +{ 3.433 + /* flipping it makes both children go red, so we have a red to the left */ 3.434 + color_flip(tree); 3.435 + 3.436 + /* if after the flip we've got a red-red on the right-left, fix it */ 3.437 + if(is_red(tree->right->left)) { 3.438 + tree->right = rot_right(tree->right); 3.439 + tree = rot_left(tree); 3.440 + color_flip(tree); 3.441 + } 3.442 + return tree; 3.443 +} 3.444 + 3.445 +static struct rbnode *fix_up(struct rbnode *tree) 3.446 +{ 3.447 + /* fix right-leaning */ 3.448 + if(is_red(tree->right)) { 3.449 + tree = rot_left(tree); 3.450 + } 3.451 + /* change invalid red-red pairs into a proper 4-node */ 3.452 + if(is_red(tree->left) && is_red(tree->left->left)) { 3.453 + tree = rot_right(tree); 3.454 + } 3.455 + /* split 4-nodes */ 3.456 + if(is_red(tree->left) && is_red(tree->right)) { 3.457 + color_flip(tree); 3.458 + } 3.459 + return tree; 3.460 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/rbtree.h Mon Oct 10 04:16:01 2011 +0300 4.3 @@ -0,0 +1,82 @@ 4.4 +#ifndef RBTREE_H_ 4.5 +#define RBTREE_H_ 4.6 + 4.7 +struct rbtree; 4.8 +struct rbnode; 4.9 + 4.10 + 4.11 +typedef void *(*rb_alloc_func_t)(size_t); 4.12 +typedef void (*rb_free_func_t)(void*); 4.13 + 4.14 +typedef int (*rb_cmp_func_t)(void*, void*); 4.15 +typedef void (*rb_del_func_t)(struct rbnode*, void*); 4.16 + 4.17 + 4.18 +struct rbtree { 4.19 + struct rbnode *root; 4.20 + 4.21 + rb_alloc_func_t alloc; 4.22 + rb_free_func_t free; 4.23 + 4.24 + rb_cmp_func_t cmp; 4.25 + rb_del_func_t del; 4.26 + void *del_cls; 4.27 + 4.28 + struct rbnode *rstack, *iter; 4.29 +}; 4.30 + 4.31 + 4.32 +struct rbnode { 4.33 + void *key, *data; 4.34 + int red; 4.35 + struct rbnode *left, *right; 4.36 + struct rbnode *next; /* for iterator stack */ 4.37 +}; 4.38 + 4.39 +#define RB_KEY_ADDR (rb_cmp_func_t)(0) 4.40 +#define RB_KEY_INT (rb_cmp_func_t)(1) 4.41 +#define RB_KEY_STRING (rb_cmp_func_t)(3) 4.42 + 4.43 + 4.44 +#ifdef __cplusplus 4.45 +extern "C" { 4.46 +#endif 4.47 + 4.48 +struct rbtree *rb_create(rb_cmp_func_t cmp_func); 4.49 +void rb_free(struct rbtree *rb); 4.50 + 4.51 +int rb_init(struct rbtree *rb, rb_cmp_func_t cmp_func); 4.52 +void rb_destroy(struct rbtree *rb); 4.53 + 4.54 +void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free); 4.55 +void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func); 4.56 +void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls); 4.57 + 4.58 +int rb_size(struct rbtree *rb); 4.59 + 4.60 +int rb_insert(struct rbtree *rb, void *key, void *data); 4.61 +int rb_inserti(struct rbtree *rb, int key, void *data); 4.62 + 4.63 +int rb_delete(struct rbtree *rb, void *key); 4.64 +int rb_deletei(struct rbtree *rb, int key); 4.65 + 4.66 +void *rb_find(struct rbtree *rb, void *key); 4.67 +void *rb_findi(struct rbtree *rb, int key); 4.68 + 4.69 +void rb_foreach(struct rbtree *rb, void (*func)(struct rbnode*, void*), void *cls); 4.70 + 4.71 +struct rbnode *rb_root(struct rbtree *rb); 4.72 + 4.73 +void rb_begin(struct rbtree *rb); 4.74 +struct rbnode *rb_next(struct rbtree *rb); 4.75 + 4.76 +void *rb_node_key(struct rbnode *node); 4.77 +int rb_node_keyi(struct rbnode *node); 4.78 +void *rb_node_data(struct rbnode *node); 4.79 + 4.80 +#ifdef __cplusplus 4.81 +} 4.82 +#endif 4.83 + 4.84 + 4.85 +#endif /* RBTREE_H_ */
5.1 --- a/src/vm.c Sun Oct 09 20:38:35 2011 +0300 5.2 +++ b/src/vm.c Mon Oct 10 04:16:01 2011 +0300 5.3 @@ -17,7 +17,6 @@ 5.4 5.5 #define ATTR_PGDIR_MASK 0x3f 5.6 #define ATTR_PGTBL_MASK 0x1ff 5.7 -#define ADDR_PGENT_MASK 0xfffff000 5.8 5.9 #define PAGEFAULT 14 5.10 5.11 @@ -68,7 +67,7 @@ 5.12 map_mem_range(IDMAP_START, idmap_end - IDMAP_START, IDMAP_START, 0); 5.13 5.14 /* make the last page directory entry point to the page directory */ 5.15 - pgdir[1023] = ((uint32_t)pgdir & ADDR_PGENT_MASK) | PG_PRESENT; 5.16 + pgdir[1023] = ((uint32_t)pgdir & PGENT_ADDR_MASK) | PG_PRESENT; 5.17 pgdir = (uint32_t*)PGDIR_ADDR; 5.18 5.19 /* set the page fault handler */ 5.20 @@ -149,7 +148,7 @@ 5.21 if(pgon) { 5.22 pgtbl = PGTBL(diridx); 5.23 } else { 5.24 - pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); 5.25 + pgtbl = (uint32_t*)(pgdir[diridx] & PGENT_ADDR_MASK); 5.26 } 5.27 } 5.28 5.29 @@ -614,7 +613,8 @@ 5.30 * page table and unset the writable bits. 5.31 */ 5.32 for(j=0; j<1024; j++) { 5.33 - PGTBL(i)[j] &= ~(uint32_t)PG_WRITABLE; 5.34 + clear_page_bit(i * 1024 + j, PG_WRITABLE, PAGE_ONLY); 5.35 + /*PGTBL(i)[j] &= ~(uint32_t)PG_WRITABLE;*/ 5.36 } 5.37 } 5.38 5.39 @@ -699,6 +699,40 @@ 5.40 } 5.41 5.42 5.43 +#define USER_PGDIR_ENTRIES PAGE_TO_PGTBL(KMEM_START_PAGE) 5.44 +int cons_vmmap(struct rbtree *vmmap) 5.45 +{ 5.46 + int i, j; 5.47 + 5.48 + rb_init(vmmap, RB_KEY_INT); 5.49 + 5.50 + for(i=0; i<USER_PGDIR_ENTRIES; i++) { 5.51 + if(pgdir[i] & PG_PRESENT) { 5.52 + /* page table is present, iterate through its 1024 pages */ 5.53 + uint32_t *pgtbl = PGTBL(i); 5.54 + 5.55 + for(j=0; j<1024; j++) { 5.56 + if(pgtbl[j] & PG_PRESENT) { 5.57 + struct vm_page *vmp; 5.58 + 5.59 + if(!(vmp = malloc(sizeof *vmp))) { 5.60 + panic("cons_vmap failed to allocate memory"); 5.61 + } 5.62 + vmp->vpage = i * 1024 + j; 5.63 + vmp->ppage = ADDR_TO_PAGE(pgtbl[j] & PGENT_ADDR_MASK); 5.64 + vmp->flags = pgtbl[j] & ATTR_PGTBL_MASK; 5.65 + vmp->nref = 1; /* when first created assume no sharing */ 5.66 + 5.67 + rb_inserti(vmmap, vmp->ppage, vmp); 5.68 + } 5.69 + } 5.70 + } 5.71 + } 5.72 + 5.73 + return 0; 5.74 +} 5.75 + 5.76 + 5.77 void dbg_print_vm(int area) 5.78 { 5.79 struct page_range *node;
6.1 --- a/src/vm.h Sun Oct 09 20:38:35 2011 +0300 6.2 +++ b/src/vm.h Mon Oct 10 04:16:01 2011 +0300 6.3 @@ -3,8 +3,10 @@ 6.4 6.5 #include <stdlib.h> 6.6 #include "mboot.h" 6.7 +#include "rbtree.h" 6.8 6.9 #define KMEM_START 0xc0000000 6.10 +#define KMEM_START_PAGE ADDR_TO_PAGE(KMEM_START) 6.11 6.12 /* page mapping flags */ 6.13 #define PG_PRESENT (1 << 0) 6.14 @@ -44,6 +46,13 @@ 6.15 #define PAGE_ONLY 0 6.16 #define WHOLE_PATH 1 6.17 6.18 +struct vm_page { 6.19 + int vpage, ppage; 6.20 + unsigned int flags; 6.21 + 6.22 + int nref; 6.23 +}; 6.24 + 6.25 void init_vm(void); 6.26 6.27 int map_page(int vpage, int ppage, unsigned int attr); 6.28 @@ -70,6 +79,9 @@ 6.29 void set_page_bit(int pgnum, uint32_t bit, int wholepath); 6.30 void clear_page_bit(int pgnum, uint32_t bit, int wholepath); 6.31 6.32 +/* construct the vm map for the current user mappings */ 6.33 +int cons_vmmap(struct rbtree *vmmap); 6.34 + 6.35 void dbg_print_vm(int area); 6.36 6.37 /* defined in vm-asm.S */