Index: arch/mips32/src/mm/tlb.c
===================================================================
--- arch/mips32/src/mm/tlb.c	(revision 2d43f3ef0767f048ffa7ee2ebbd09492e61a44de)
+++ arch/mips32/src/mm/tlb.c	(revision bc504ef2f35f18a589fe5c41042fd4a533bfe7cb)
@@ -367,5 +367,5 @@
 	 */
 	if (!pte) {
-		printf("No such mapping.\n");
+		printf("No such mapping: %P.\n", badvaddr);
 		return NULL;
 	}
Index: generic/include/mm/slab.h
===================================================================
--- generic/include/mm/slab.h	(revision 2d43f3ef0767f048ffa7ee2ebbd09492e61a44de)
+++ generic/include/mm/slab.h	(revision bc504ef2f35f18a589fe5c41042fd4a533bfe7cb)
@@ -32,4 +32,5 @@
 #include <list.h>
 #include <synch/spinlock.h>
+#include <arch/atomic.h>
 
 /** Initial Magazine size (TODO: dynamically growing magazines) */
@@ -73,4 +74,6 @@
 
 	/* Statistics */
+	atomic_t allocated_slabs;
+	atomic_t allocated_objs;
 
 	/* Slabs */
Index: generic/src/mm/frame.c
===================================================================
--- generic/src/mm/frame.c	(revision 2d43f3ef0767f048ffa7ee2ebbd09492e61a44de)
+++ generic/src/mm/frame.c	(revision bc504ef2f35f18a589fe5c41042fd4a533bfe7cb)
@@ -185,8 +185,7 @@
 		v = PA2KA(v);
 	
-	if (flags & FRAME_ATOMIC) {
-		ASSERT(status != NULL);
+	if (status)
 		*status = FRAME_OK;
-	}
+
 	if (pzone)
 		*pzone = zone;
Index: generic/src/mm/slab.c
===================================================================
--- generic/src/mm/slab.c	(revision 2d43f3ef0767f048ffa7ee2ebbd09492e61a44de)
+++ generic/src/mm/slab.c	(revision bc504ef2f35f18a589fe5c41042fd4a533bfe7cb)
@@ -70,9 +70,10 @@
 	zone_t *zone = NULL;
 	int status;
+	frame_t *frame;
 
 	data = (void *)frame_alloc(FRAME_KA | flags, cache->order, &status, &zone);
-	if (status != FRAME_OK)
+	if (status != FRAME_OK) {
 		return NULL;
-
+	}
 	if (! cache->flags & SLAB_CACHE_SLINSIDE) {
 		slab = malloc(sizeof(*slab)); // , flags);
@@ -85,9 +86,10 @@
 		slab = data + fsize - sizeof(*slab);
 	}
-
+		
 	/* Fill in slab structures */
 	/* TODO: some better way of accessing the frame */
 	for (i=0; i< (1<<cache->order); i++) {
-		ADDR2FRAME(zone, (__address)(data+i*PAGE_SIZE))->parent = slab;
+		frame = ADDR2FRAME(zone, KA2PA((__address)(data+i*PAGE_SIZE)));
+		frame->parent = slab;
 	}
 
@@ -98,4 +100,7 @@
 	for (i=0; i<cache->objects;i++)
 		*((int *) (slab->start + i*cache->size)) = i+1;
+
+	atomic_inc(&cache->allocated_slabs);
+
 	return slab;
 }
@@ -111,4 +116,7 @@
 	if (! cache->flags & SLAB_CACHE_SLINSIDE)
 		free(slab);
+
+	atomic_dec(&cache->allocated_slabs);
+	
 	return 1 << cache->order;
 }
@@ -154,5 +162,5 @@
 		/* It was in full, move to partial */
 		list_remove(&slab->link);
-		list_prepend(&cache->partial_slabs, &slab->link);
+		list_prepend(&slab->link, &cache->partial_slabs);
 	}
 	if (slab->available == cache->objects) {
@@ -192,6 +200,7 @@
 		slab = slab_space_alloc(cache, flags);
 		spinlock_lock(&cache->lock);
-		if (!slab)
+		if (!slab) {
 			return NULL;
+		}
 	} else {
 		slab = list_get_instance(cache->partial_slabs.next,
@@ -204,7 +213,7 @@
 	slab->available--;
 	if (! slab->available)
-		list_prepend(&cache->full_slabs, &slab->link);
+		list_prepend(&slab->link, &cache->full_slabs);
 	else
-		list_prepend(&cache->partial_slabs, &slab->link);
+		list_prepend(&slab->link, &cache->partial_slabs);
 	return obj;
 }
@@ -316,5 +325,5 @@
 		if (!mag || mag->size == mag->busy) {
 			if (mag) 
-				list_prepend(&cache->magazines, &mag->link);
+				list_prepend(&mag->link, &cache->magazines);
 
 			mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
@@ -534,5 +543,9 @@
 	}
 
+	if (result)
+		atomic_inc(&cache->allocated_objs);
+
 	interrupts_restore(ipl);
+
 
 	return result;
@@ -553,4 +566,5 @@
 		spinlock_unlock(&cache->lock);
 	}
+	atomic_dec(&cache->allocated_objs);
 	interrupts_restore(ipl);
 }
@@ -583,8 +597,11 @@
 
 	spinlock_lock(&slab_cache_lock);
-	printf("SLAB name\tOsize\tOrder\n");
+	printf("SLAB name\tOsize\tOrder\tOcnt\tSlabs\tAllocobjs\n");
 	for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) {
 		cache = list_get_instance(cur, slab_cache_t, link);
-		printf("%s\t%d\t%d\n", cache->name, cache->size, cache->order);
+		printf("%s\t%d\t%d\t%d\t%d\t%d\n", cache->name, cache->size, 
+		       cache->order, cache->objects,
+		       atomic_get(&cache->allocated_slabs), 
+		       atomic_get(&cache->allocated_objs));
 	}
 	spinlock_unlock(&slab_cache_lock);
Index: test/mm/slab1/test.c
===================================================================
--- test/mm/slab1/test.c	(revision 2d43f3ef0767f048ffa7ee2ebbd09492e61a44de)
+++ test/mm/slab1/test.c	(revision bc504ef2f35f18a589fe5c41042fd4a533bfe7cb)
@@ -44,5 +44,4 @@
 	printf("Creating cache.\n");
 	cache = slab_cache_create("test_cache", VAL_SIZE, 0, NULL, NULL, SLAB_CACHE_NOMAGAZINE);
-	slab_print_list();
 	printf("Destroying cache.\n");
 	slab_cache_destroy(cache);
@@ -62,3 +61,31 @@
 	}
 	printf("done.\n");
+
+	printf("Allocating %d items...", VAL_COUNT);
+	for (i=0; i < VAL_COUNT; i++) {
+		data[i] = slab_alloc(cache, 0);
+	}
+	printf("done.\n");
+
+	slab_print_list();
+	printf("Freeing %d items...", VAL_COUNT/2);
+	for (i=VAL_COUNT-1; i >= VAL_COUNT/2; i--) {
+		slab_free(cache, data[i]);
+	}
+	printf("done.\n");	
+
+	printf("Allocating %d items...", VAL_COUNT/2);
+	for (i=VAL_COUNT/2; i < VAL_COUNT; i++) {
+		data[i] = slab_alloc(cache, 0);
+	}
+	printf("done.\n");
+	printf("Freeing %d items...", VAL_COUNT);
+	for (i=0; i < VAL_COUNT; i++) {
+		slab_free(cache, data[i]);
+	}
+	printf("done.\n");	
+	slab_print_list();
+	slab_cache_destroy(cache);
+
+	printf("Test complete.\n");
 }
