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 */