Index: arch/amd64/src/pm.c
===================================================================
--- arch/amd64/src/pm.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ arch/amd64/src/pm.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -199,5 +199,5 @@
 	}
 	else {
-		tss_p = (struct tss *) malloc(sizeof(struct tss));
+		tss_p = (struct tss *) malloc(sizeof(struct tss),FRAME_ATOMIC);
 		if (!tss_p)
 			panic("could not allocate TSS\n");
Index: arch/ia32/src/mm/frame.c
===================================================================
--- arch/ia32/src/mm/frame.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ arch/ia32/src/mm/frame.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -132,4 +132,6 @@
 #endif
 #endif
+		/* Merge all zones to 1 big zone */
+		zone_merge_all();
 	}
 }
Index: arch/ia32/src/pm.c
===================================================================
--- arch/ia32/src/pm.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ arch/ia32/src/pm.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -191,5 +191,5 @@
 	}
 	else {
-		tss_p = (struct tss *) malloc(sizeof(struct tss));
+		tss_p = (struct tss *) malloc(sizeof(struct tss),FRAME_ATOMIC);
 		if (!tss_p)
 			panic("could not allocate TSS\n");
Index: arch/ia32/src/smp/smp.c
===================================================================
--- arch/ia32/src/smp/smp.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ arch/ia32/src/smp/smp.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -139,5 +139,5 @@
 		 * Prepare new GDT for CPU in question.
 		 */
-		if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor))))
+		if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC)))
 			panic("couldn't allocate memory for GDT\n");
 
Index: doc/mm
===================================================================
--- doc/mm	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ doc/mm	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -66,2 +66,21 @@
 There is only one global page hash table in the system shared by all address
 spaces.
+
+2.1 General allocator
+
+'malloc' function accepts flags as a second argument. The flags are directly
+passed to the underlying frame_alloc function. 
+
+1) If the flags parameter contains FRAME_ATOMIC, the allocator will not sleep.
+   The allocator CAN return NULL, when memory is not directly available.
+   The caller MUST check if NULL was not returned
+
+2) If the flags parameter does not contain FRAME_ATOMIC, the allocator
+   will never return NULL, but it CAN sleep indefinitely. The caller
+   does not have to check the return value.
+
+3) The maximum size that can be allocated using malloc is 128K
+
+Rules 1) and 2) apply to slab_alloc as well. Using SLAB allocator
+to allocate too large values is not recommended.
+
Index: genarch/src/acpi/matd.c
===================================================================
--- genarch/src/acpi/matd.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ genarch/src/acpi/matd.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -145,5 +145,7 @@
 
 	/* create madt apic entries index array */
-	madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
+	madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *), FRAME_ATOMIC);
+	if (!madt_entries_index)
+		panic("Memory allocation error.");
 
 	__u32 index = 0;
Index: generic/include/mm/buddy.h
===================================================================
--- generic/include/mm/buddy.h	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/include/mm/buddy.h	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -46,4 +46,5 @@
 	/** Find parent of block that has given order  */
 	link_t *(* find_block)(buddy_system_t *, link_t *, __u8);
+	void (* print_id)(buddy_system_t *, link_t *);
 };
 
Index: generic/include/mm/frame.h
===================================================================
--- generic/include/mm/frame.h	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/include/mm/frame.h	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -54,6 +54,8 @@
 
 /* Return true if the interlvals overlap */
-static inline int overlaps(__address s1,__address e1, __address s2, __address e2)
+static inline int overlaps(__address s1,__address sz1, __address s2, __address sz2)
 {
+	__address e1 = s1+sz1;
+	__address e2 = s2+sz2;
 	if (s1 >= s2 && s1 < e2)
 		return 1;
@@ -96,10 +98,11 @@
 extern void frame_free(__address addr);
 
-extern void zone_create(pfn_t start, count_t count, pfn_t confframe, int flags);
-
+extern int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags);
 void * frame_get_parent(pfn_t frame, int hint);
 void frame_set_parent(pfn_t frame, void *data, int hint);
 void frame_mark_unavailable(pfn_t start, count_t count);
-__address zone_conf_size(pfn_t start, count_t count);
+__address zone_conf_size(count_t count);
+void zone_merge(int z1, int z2);
+void zone_merge_all(void);
 
 /*
Index: generic/include/mm/slab.h
===================================================================
--- generic/include/mm/slab.h	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/include/mm/slab.h	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -126,7 +126,5 @@
 
 /* Malloc support */
-extern void * kalloc(unsigned int size, int flags);
-extern void kfree(void *obj);
-#define malloc(x)  kalloc(x, FRAME_ATOMIC)
-#define free(x)    kfree(x)
+extern void * malloc(unsigned int size, int flags);
+extern void free(void *obj);
 #endif
Index: generic/src/adt/hash_table.c
===================================================================
--- generic/src/adt/hash_table.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/adt/hash_table.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -52,5 +52,5 @@
 	ASSERT(max_keys > 0);
 	
-	h->entry = malloc(m * sizeof(link_t *));
+	h->entry = malloc(m * sizeof(link_t *), 0);
 	if (!h->entry) {
 		panic("cannot allocate memory for hash table\n");
Index: generic/src/cpu/cpu.c
===================================================================
--- generic/src/cpu/cpu.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/cpu/cpu.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -54,5 +54,6 @@
 	if (config.cpu_active == 1) {
 	#endif /* CONFIG_SMP */
-		cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count);
+		cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count,
+					FRAME_ATOMIC);
 		if (!cpus)
 			panic("malloc/cpus");
Index: generic/src/lib/sort.c
===================================================================
--- generic/src/lib/sort.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/lib/sort.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -42,4 +42,6 @@
  * the pivot and temporary elements for generic quicksort algorithm.
  * 
+ * This function _can_ sleep
+ *
  * @param data Pointer to data to be sorted.
  * @param n Number of elements to be sorted.
@@ -56,10 +58,6 @@
 
 	if (e_size > EBUFSIZE) {
-		pivot = (void *) malloc(e_size);
-		tmp = (void *) malloc(e_size);
-	
-		if (!tmp || !pivot) {
-			panic("Cannot allocate memory\n");
-		}
+		pivot = (void *) malloc(e_size, 0);
+		tmp = (void *) malloc(e_size, 0);
 	}
 
@@ -127,9 +125,5 @@
 	
 	if (e_size > EBUFSIZE) {
-		slot = (void *) malloc(e_size);
-		
-		if (!slot) {
-			panic("Cannot allocate memory\n");
-		}
+		slot = (void *) malloc(e_size, 0);
 	}
 
Index: generic/src/main/main.c
===================================================================
--- generic/src/main/main.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/main/main.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -116,6 +116,6 @@
 	stackaddr = config.base + config.kernel_size;
 	/* Avoid placing kernel on top of init */
-	if (overlaps(stackaddr,stackaddr+CONFIG_STACK_SIZE,
-		     config.init_addr, config.init_addr+config.init_size)) {
+	if (overlaps(stackaddr,CONFIG_STACK_SIZE,
+		     config.init_addr, config.init_size)) {
 		
 		stackaddr = ALIGN_UP(config.init_addr+config.init_size,
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/mm/as.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -79,17 +79,16 @@
 	as_t *as;
 
-	as = (as_t *) malloc(sizeof(as_t));
-	if (as) {
-		list_initialize(&as->as_with_asid_link);
-		spinlock_initialize(&as->lock, "as_lock");
-		list_initialize(&as->as_area_head);
-
-		if (flags & FLAG_AS_KERNEL)
-			as->asid = ASID_KERNEL;
-		else
-			as->asid = ASID_INVALID;
-
-		as->page_table = page_table_create(flags);
-	}
+	as = (as_t *) malloc(sizeof(as_t), 0);
+
+	list_initialize(&as->as_with_asid_link);
+	spinlock_initialize(&as->lock, "as_lock");
+	list_initialize(&as->as_area_head);
+	
+	if (flags & FLAG_AS_KERNEL)
+		as->asid = ASID_KERNEL;
+	else
+		as->asid = ASID_INVALID;
+	
+	as->page_table = page_table_create(flags);
 
 	return as;
@@ -122,15 +121,14 @@
 	 */
 	
-	a = (as_area_t *) malloc(sizeof(as_area_t));
-	if (a) {	
-		spinlock_initialize(&a->lock, "as_area_lock");
-			
-		link_initialize(&a->link);			
-		a->type = type;
-		a->size = size;
-		a->base = base;
-		
-		list_append(&a->link, &as->as_area_head);
-	}
+	a = (as_area_t *) malloc(sizeof(as_area_t), 0);
+
+	spinlock_initialize(&a->lock, "as_area_lock");
+	
+	link_initialize(&a->link);			
+	a->type = type;
+	a->size = size;
+	a->base = base;
+	
+	list_append(&a->link, &as->as_area_head);
 
 	spinlock_unlock(&as->lock);
Index: generic/src/mm/buddy.c
===================================================================
--- generic/src/mm/buddy.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/mm/buddy.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -140,5 +140,6 @@
 			right = left;
 			left = tmp;
-		}
+		} 
+		ASSERT(tmp == left);
 		b->op->mark_busy(b, left);
 		buddy_system_free(b, right);
@@ -291,6 +292,13 @@
 		}
 	
-		printf("#%d\t%d\t%dK\t\t%dK\t\t%d\n", i, cnt, (cnt * (1 << i) * elem_size) >> 10, ((1 << i) * elem_size) >> 10, 1 << i);
-		
+		printf("#%d\t%d\t%dK\t\t%dK\t\t%d\t", i, cnt, (cnt * (1 << i) * elem_size) >> 10, ((1 << i) * elem_size) >> 10, 1 << i);
+		if (!list_empty(&b->order[i])) {
+			for (cur = b->order[i].next; cur != &b->order[i]; cur = cur->next) {
+				b->op->print_id(b, cur);
+				printf(" ");
+			}
+		}
+		printf("\n");
+			
 		block_count += cnt;
 		elem_count += (1 << i) * cnt;
Index: generic/src/mm/frame.c
===================================================================
--- generic/src/mm/frame.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/mm/frame.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -51,4 +51,5 @@
 #include <align.h>
 #include <mm/slab.h>
+#include <bitops.h>
 
 typedef struct {
@@ -122,27 +123,41 @@
 /**
  * Insert-sort zone into zones list
- */
-static void zones_add_zone(zone_t *zone)
-{
-	int i;
-
+ *
+ * @return zone number on success, -1 on error
+ */
+static int zones_add_zone(zone_t *newzone)
+{
+	int i,j;
+	ipl_t ipl;
+	zone_t *z;
+
+	ipl = interrupts_disable();
 	spinlock_lock(&zones.lock);
 	/* Try to merge */
-	if (zone->flags & ZONE_JOIN) {
-		for (i=0; i < zones.count; i++) {
-			spinlock_lock(&zones.info[i]->lock);
-			
-			/* Join forward, join backward */
-			panic("Not implemented");
-
-			spinlock_unlock(&zones.info[i]->lock);
+	if (zones.count+1 == ZONES_MAX)
+		panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
+
+	for (i=0; i < zones.count; i++) {
+		/* Check for overflow */
+		z = zones.info[zones.count];
+		if (overlaps(newzone->base,newzone->count,
+			     z->base, z->count)) {
+			printf("Zones overlap!\n");
+			return -1;
 		}
-		spinlock_unlock(&zones.lock);
-	} else {
-		if (zones.count+1 == ZONES_MAX)
-			panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
-		zones.info[zones.count++] = zone;
-	}
+		if (z->base < newzone->base)
+			break;
+	}
+	/* Move other zones up */
+	for (j=i;j < zones.count;j++)
+		zones.info[j+1] = zones.info[j];
+
+	zones.info[i] = newzone;
+	zones.count++;
+
 	spinlock_unlock(&zones.lock);
+	interrupts_restore(ipl);
+
+	return i;
 }
 
@@ -187,4 +202,10 @@
 }
 
+/** @return True if zone can allocate specified order */
+static int zone_can_alloc(zone_t *z, __u8 order)
+{
+	return buddy_system_can_alloc(z->buddy_system, order);
+}
+
 /**
  * Find AND LOCK zone that can allocate order frames
@@ -210,5 +231,5 @@
 
 		/* Check if the zone has 2^order frames area available  */
-		if (buddy_system_can_alloc(z->buddy_system, order)) {
+		if (zone_can_alloc(z, order)) {
 			spinlock_unlock(&zones.lock);
 			if (pzone)
@@ -253,5 +274,15 @@
 }
 
-				     
+static void zone_buddy_print_id(buddy_system_t *b, link_t *block)
+{
+	frame_t * frame;
+	zone_t * zone;
+	index_t index;
+
+	frame = list_get_instance(block, frame_t, buddy_link);
+	zone = (zone_t *) b->data;
+	index = frame_index(zone, frame);
+	printf("%d", index);
+}				     
 
 /** Buddy system find_buddy implementation
@@ -319,5 +350,6 @@
  */
 static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, 
-				    link_t * block_2) {
+				    link_t * block_2) 
+{
 	frame_t *frame1, *frame2;
 	
@@ -361,4 +393,5 @@
 static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
 	frame_t * frame;
+
 	frame = list_get_instance(block, frame_t, buddy_link);
 	frame->refcount = 1;
@@ -385,5 +418,6 @@
 	.mark_busy = zone_buddy_mark_busy,
 	.mark_available = zone_buddy_mark_available,
-	.find_block = zone_buddy_find_block
+	.find_block = zone_buddy_find_block,
+	.print_id = zone_buddy_print_id
 };
 
@@ -394,8 +428,9 @@
  *
  * Assume zone is locked
+ * Panics, if allocation is impossible.
  *
  * @return Frame index in zone
  */
-static pfn_t zone_frame_alloc(zone_t *zone,__u8 order, int flags, int *status)
+static pfn_t zone_frame_alloc(zone_t *zone,__u8 order)
 {
 	pfn_t v;
@@ -459,4 +494,6 @@
 
 	frame = zone_get_frame(zone, frame_idx);
+	if (frame->refcount)
+		return;
 	link = buddy_system_alloc_block(zone->buddy_system, 
 					&frame->buddy_link);
@@ -465,4 +502,194 @@
 }
 
+/** 
+ * Join 2 zones
+ *
+ * Expect zone_t *z to point to space at least zone_conf_size large
+ *
+ * Assume z1 & z2 are locked 
+ */
+
+static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
+{
+	__u8 max_order;
+	int i, z2idx;
+	pfn_t frame_idx;
+	frame_t *frame;
+
+	ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count));
+	ASSERT(z1->base < z2->base);
+
+	spinlock_initialize(&z->lock, "zone_lock");
+	z->base = z1->base;
+	z->count = z2->base+z2->count - z1->base;
+	z->flags = z1->flags & z2->flags;
+
+	z->free_count = z1->free_count + z2->free_count;
+	z->busy_count = z1->busy_count + z2->busy_count;
+	
+	max_order = fnzb(z->count);
+
+	z->buddy_system = (buddy_system_t *)&z[1];
+	buddy_system_create(z->buddy_system, max_order, 
+			    &zone_buddy_system_operations, 
+			    (void *) z);
+
+	z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
+	for (i = 0; i < z->count; i++) {
+		/* This marks all frames busy */
+		frame_initialize(&z->frames[i]);
+	}
+	/* Copy frames from both zones to preserve full frame orders,
+	 * parents etc. Set all frames with refcount=0 to 1, because
+	 * we add all free frames to buddy allocator later again, clear
+	 * order to 0.
+	 */
+	for (i=0; i<z1->count; i++)
+		z->frames[i] = z1->frames[i];
+	for (i=0; i < z2->count; i++) {
+		z2idx = i + (z2->base - z1->base);
+		z->frames[z2idx] = z2->frames[i];
+	}
+	for (i=0; i < z->count; i++) {
+		if (!z->frames[i].refcount) {
+			z->frames[i].refcount = 1;
+			z->frames[i].buddy_order = 0;
+		}
+	}
+	/* Add free blocks from the 2 original zones */
+	while (zone_can_alloc(z1, 0)) {
+		frame_idx = zone_frame_alloc(z1, 0);
+		frame = &z->frames[frame_idx];
+		frame->refcount = 0;
+		buddy_system_free(z->buddy_system, &frame->buddy_link);
+	}
+	while (zone_can_alloc(z2, 0)) {
+		frame_idx = zone_frame_alloc(z2, 0);
+		frame = &z->frames[frame_idx + (z2->base-z1->base)];
+		frame->refcount = 0;
+		buddy_system_free(z->buddy_system, &frame->buddy_link);
+	}
+}
+
+/** Return old configuration frames into the zone
+ *
+ * We have several cases
+ * - the conf. data is outside of zone -> exit, shall we call frame_free??
+ * - the conf. data was created by zone_create -> free every frame
+ * - the conf. data was created by merge in frame_alloc -> free first frame
+ *   (the difference is in order)
+ */
+static void return_config_frames(zone_t *newzone, zone_t *oldzone)
+{
+	pfn_t pfn;
+	frame_t *frame;
+	count_t cframes;
+	int i;
+
+	pfn = ADDR2PFN((__address)KA2PA(oldzone));
+	cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
+	
+	if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
+		return;
+
+	frame = &newzone->frames[pfn - newzone->base];
+	if (frame->buddy_order) {
+		/* Normally zone config data is hidden, show it again */
+		newzone->busy_count += (1 << frame->buddy_order);
+		zone_frame_free(newzone, pfn - newzone->base);
+		return;
+	}
+
+	for (i=0; i < cframes; i++) {
+		newzone->busy_count++;
+		zone_frame_free(newzone, pfn+i-newzone->base);
+	}
+}
+
+/** Merge zones z1 and z2
+ *
+ * - the zones must be 2 zones with no zone existing in between,
+ *   which means that z2 = z1+1
+ *
+ * - When you create a new zone, the frame allocator configuration does
+ *   not to be 2^order size. Once the allocator is running it is no longer
+ *   possible, merged configuration data occupies more space :-/
+ */
+void zone_merge(int z1, int z2)
+{
+	ipl_t ipl;
+	zone_t *zone1, *zone2, *newzone;
+	int cframes;
+	__u8 order;
+	int i;
+	pfn_t pfn;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&zones.lock);
+
+	if (z1 < 0 || z1 >= zones.count || z2 < 0 || z2 >= zones.count)
+		goto errout;
+	/* We can join only 2 zones with none existing inbetween */
+	if (z2-z1 != 1)
+		goto errout;
+
+	zone1 = zones.info[z1];
+	zone2 = zones.info[z2];
+	spinlock_lock(&zone1->lock);
+	spinlock_lock(&zone2->lock);
+
+	cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base));
+	order = fnzb(cframes) + 1;
+
+	/* Allocate zonedata inside one of the zones */
+	if (zone_can_alloc(zone1, order))
+		pfn = zone1->base + zone_frame_alloc(zone1, order);
+	else if (zone_can_alloc(zone2, order))
+		pfn = zone2->base + zone_frame_alloc(zone2, order);
+	else
+		goto errout2;
+
+	newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
+
+	_zone_merge(newzone, zone1, zone2);
+
+	/* Subtract zone information from busy frames */
+	newzone->busy_count -= (1 << order);
+
+	zones.info[z1] = newzone;
+	for (i=z2+1;i < zones.count;i++)
+		zones.info[i-1] = zones.info[i];
+	zones.count--;
+
+	/* Free old zone information */
+	return_config_frames(newzone, zone1);
+	return_config_frames(newzone, zone2);
+errout2:
+	/* Nobody is allowed to enter to zone, so we are safe
+	 * to touch the spinlocks last time */
+	spinlock_unlock(&zone1->lock);
+	spinlock_unlock(&zone2->lock);
+errout:
+	spinlock_unlock(&zones.lock);
+	interrupts_restore(ipl);
+}
+
+
+/**
+ * Merge all zones into one big zone
+ *
+ * It is reasonable to do this on systems whose bios reports parts in chunks,
+ * so that we could have 1 zone (it's faster).
+ */
+void zone_merge_all(void)
+{
+	int count = zones.count;
+
+	while (zones.count > 1 && --count) {
+		zone_merge(0,1);
+		break;
+	}
+}
+
 /** Create frame zone
  *
@@ -476,6 +703,5 @@
  * @return Initialized zone.
  */
-static zone_t * zone_construct(pfn_t start, count_t count, 
-			       zone_t *z, int flags)
+static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
 {
 	int i;
@@ -492,6 +718,5 @@
 	 * Compute order for buddy system, initialize
 	 */
-	for (max_order = 0; count >> max_order; max_order++)
-		;
+	max_order = fnzb(count);
 	z->buddy_system = (buddy_system_t *)&z[1];
 	
@@ -503,8 +728,8 @@
 	/* Check sizes */
 	z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
-
 	for (i = 0; i<count; i++) {
 		frame_initialize(&z->frames[i]);
 	}
+
 	/* Stuffing frames */
 	for (i = 0; i < count; i++) {
@@ -512,19 +737,18 @@
 		buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
 	}
-	return z;
 }
 
 
 /** Compute configuration data size for zone */
-__address zone_conf_size(pfn_t start, count_t count)
+__address zone_conf_size(count_t count)
 {
 	int size = sizeof(zone_t) + count*sizeof(frame_t);
 	int max_order;
 
-	for (max_order = 0; count >> max_order; max_order++)
-		;
+	max_order = fnzb(count);
 	size += buddy_conf_size(max_order);
 	return size;
 }
+
 
 /** Create and add zone to system
@@ -535,11 +759,14 @@
  *                  that the area is already marked BUSY and big enough
  *                  to contain zone_conf_size() amount of data
- */
-void zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
+ *
+ * @return Zone number or -1 on error
+ */
+int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
 {
 	zone_t *z;
-	__address addr,endaddr;
+	__address addr;
 	count_t confcount;
 	int i;
+	int znum;
 
 	/* Theoretically we could have here 0, practically make sure
@@ -551,16 +778,15 @@
 	 * it does not span kernel & init
 	 */
-	confcount = SIZE2FRAMES(zone_conf_size(start,count));
+	confcount = SIZE2FRAMES(zone_conf_size(count));
 	if (confframe >= start && confframe < start+count) {
 		for (;confframe < start+count;confframe++) {
 			addr = PFN2ADDR(confframe);
-			endaddr =  PFN2ADDR (confframe + confcount);
-			if (overlaps(addr, endaddr, KA2PA(config.base),
-				     KA2PA(config.base+config.kernel_size)))
+			if (overlaps(addr, PFN2ADDR(confcount),
+				     KA2PA(config.base),config.kernel_size))
 				continue;
 			if (config.init_addr)
-				if (overlaps(addr,endaddr, 
+				if (overlaps(addr,PFN2ADDR(confcount), 
 					     KA2PA(config.init_addr),
-					     KA2PA(config.init_addr+config.init_size)))
+					     config.init_size))
 					continue;
 			break;
@@ -570,7 +796,10 @@
 	}
 
-	z = zone_construct(start, count, (zone_t *)PA2KA(PFN2ADDR(confframe)), flags);
-	zones_add_zone(z);
-	
+	z = (zone_t *)PA2KA(PFN2ADDR(confframe));
+	zone_construct(start, count, z, flags);
+	znum = zones_add_zone(z);
+	if (znum == -1)
+		return -1;
+
 	/* If confdata in zone, mark as unavailable */
 	if (confframe >= start && confframe < start+count)
@@ -578,4 +807,6 @@
 			zone_mark_unavailable(z, i - z->base);
 		}
+
+	return znum;
 }
 
@@ -658,5 +889,5 @@
 		goto loop;
 	}
-	v = zone_frame_alloc(zone,order,flags,status);
+	v = zone_frame_alloc(zone,order);
 	v += zone->base;
 
@@ -671,5 +902,5 @@
 /** Free a frame.
  *
- * Find respective frame structrue for supplied addr.
+ * Find respective frame structure for supplied addr.
  * Decrement frame reference count.
  * If it drops to zero, move the frame structure to free list.
@@ -705,5 +936,5 @@
 	int prefzone = 0;
 
-	for (i=0; i<count; i++) {
+	for (i=0; i < count; i++) {
 		zone = find_zone_and_lock(start+i,&prefzone);
 		if (!zone) /* PFN not found */
@@ -748,10 +979,10 @@
 	ipl = interrupts_disable();
 	spinlock_lock(&zones.lock);
-	printf("Base address\tFree Frames\tBusy Frames\n");
-	printf("------------\t-----------\t-----------\n");
+	printf("#  Base address\tFree Frames\tBusy Frames\n");
+	printf("   ------------\t-----------\t-----------\n");
 	for (i=0;i<zones.count;i++) {
 		zone = zones.info[i];
 		spinlock_lock(&zone->lock);
-		printf("%L\t%d\t\t%d\n",PFN2ADDR(zone->base), 
+		printf("%d  %L\t%d\t\t%d\n",i,PFN2ADDR(zone->base), 
 		       zone->free_count, zone->busy_count);
 		spinlock_unlock(&zone->lock);
@@ -763,33 +994,35 @@
 /** Prints zone details
  *
- * @param base Zone base address
- */
-void zone_print_one(int znum) {
+ * @param base Zone base address OR zone number
+ */
+void zone_print_one(int num) {
 	zone_t *zone = NULL;
 	ipl_t ipl;
+	int i;
 
 	ipl = interrupts_disable();
 	spinlock_lock(&zones.lock);
-	
-	if (znum >= zones.count || znum < 0) {
-		printf("Zone number out of bounds.\n");
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
-		return;
-	}
-	
-	zone = zones.info[znum];
+
+	for (i=0;i < zones.count; i++) {
+		if (i == num || zones.info[i]->base == ADDR2PFN(num)) {
+			zone = zones.info[i];
+			break;
+		}
+	}
+	if (!zone) {
+		printf("Zone not found.\n");
+		goto out;
+	}
 	
 	spinlock_lock(&zone->lock);
-	printf("Memory zone information\n\n");
+	printf("Memory zone information\n");
 	printf("Zone base address: %P\n", PFN2ADDR(zone->base));
 	printf("Zone size: %d frames (%dK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
 	printf("Allocated space: %d frames (%dK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
 	printf("Available space: %d (%dK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
-	
-	printf("\nBuddy allocator structures:\n\n");
 	buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
 	
 	spinlock_unlock(&zone->lock);
+out:
 	spinlock_unlock(&zones.lock);
 	interrupts_restore(ipl);
Index: generic/src/mm/slab.c
===================================================================
--- generic/src/mm/slab.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/mm/slab.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -543,5 +543,5 @@
 	ASSERT(_slab_initialized >= 2);
 
-	cache->mag_cache = kalloc(sizeof(slab_mag_cache_t)*config.cpu_count,0);
+	cache->mag_cache = malloc(sizeof(slab_mag_cache_t)*config.cpu_count,0);
 	for (i=0; i < config.cpu_count; i++) {
 		memsetb((__address)&cache->mag_cache[i],
@@ -706,5 +706,5 @@
 
 	if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
-		kfree(cache->mag_cache);
+		free(cache->mag_cache);
 	slab_free(&slab_cache_cache, cache);
 }
@@ -872,5 +872,5 @@
 /**************************************/
 /* kalloc/kfree functions             */
-void * kalloc(unsigned int size, int flags)
+void * malloc(unsigned int size, int flags)
 {
 	int idx;
@@ -888,5 +888,5 @@
 
 
-void kfree(void *obj)
+void free(void *obj)
 {
 	slab_t *slab;
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/proc/task.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -65,17 +65,17 @@
 	task_t *ta;
 	
-	ta = (task_t *) malloc(sizeof(task_t));
-	if (ta) {
-		spinlock_initialize(&ta->lock, "task_ta_lock");
-		list_initialize(&ta->th_head);
-		list_initialize(&ta->tasks_link);
-		ta->as = as;
-		
-		ipl = interrupts_disable();
-		spinlock_lock(&tasks_lock);
-		list_append(&ta->tasks_link, &tasks_head);
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
-	}
+	ta = (task_t *) malloc(sizeof(task_t), 0);
+
+	spinlock_initialize(&ta->lock, "task_ta_lock");
+	list_initialize(&ta->th_head);
+	list_initialize(&ta->tasks_link);
+	ta->as = as;
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	list_append(&ta->tasks_link, &tasks_head);
+	spinlock_unlock(&tasks_lock);
+	interrupts_restore(ipl);
+
 	return ta;
 }
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ generic/src/proc/thread.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -227,65 +227,63 @@
 {
 	thread_t *t;
-
+	ipl_t ipl;
+	
 	t = (thread_t *) slab_alloc(thread_slab, 0);
-	if (t) {
-		ipl_t ipl;
-	
-		/* Not needed, but good for debugging */
-		memsetb((__address)t->kstack, THREAD_STACK_SIZE, 0);
-
-		ipl = interrupts_disable();
-		spinlock_lock(&tidlock);
-		t->tid = ++last_tid;
-		spinlock_unlock(&tidlock);
-		interrupts_restore(ipl);
+	
+	/* Not needed, but good for debugging */
+	memsetb((__address)t->kstack, THREAD_STACK_SIZE, 0);
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&tidlock);
+	t->tid = ++last_tid;
+	spinlock_unlock(&tidlock);
+	interrupts_restore(ipl);
+	
+	context_save(&t->saved_context);
+	context_set(&t->saved_context, FADDR(cushion), (__address) t->kstack, THREAD_STACK_SIZE);
+	
+	the_initialize((the_t *) t->kstack);
+	
+	ipl = interrupts_disable();
+	t->saved_context.ipl = interrupts_read();
+	interrupts_restore(ipl);
+	
+	t->thread_code = func;
+	t->thread_arg = arg;
+	t->ticks = -1;
+	t->priority = -1;		/* start in rq[0] */
+	t->cpu = NULL;
+	t->flags = 0;
+	t->state = Entering;
+	t->call_me = NULL;
+	t->call_me_with = NULL;
+	
+	timeout_initialize(&t->sleep_timeout);
+	t->sleep_queue = NULL;
+	t->timeout_pending = 0;
+	
+	t->rwlock_holder_type = RWLOCK_NONE;
 		
-		context_save(&t->saved_context);
-		context_set(&t->saved_context, FADDR(cushion), (__address) t->kstack, THREAD_STACK_SIZE);
-		
-		the_initialize((the_t *) t->kstack);
-
-		ipl = interrupts_disable();
-		t->saved_context.ipl = interrupts_read();
-		interrupts_restore(ipl);
-		
-		t->thread_code = func;
-		t->thread_arg = arg;
-		t->ticks = -1;
-		t->priority = -1;		/* start in rq[0] */
-		t->cpu = NULL;
-		t->flags = 0;
-		t->state = Entering;
-		t->call_me = NULL;
-		t->call_me_with = NULL;
-		
-		timeout_initialize(&t->sleep_timeout);
-		t->sleep_queue = NULL;
-		t->timeout_pending = 0;
-		
-		t->rwlock_holder_type = RWLOCK_NONE;
-		
-		t->task = task;
-		
-		t->fpu_context_exists=0;
-		t->fpu_context_engaged=0;
-		
-		/*
-		 * Register this thread in the system-wide list.
-		 */
-		ipl = interrupts_disable();
-		spinlock_lock(&threads_lock);
-		list_append(&t->threads_link, &threads_head);
-		spinlock_unlock(&threads_lock);
-
-		/*
-		 * Attach to the containing task.
-		 */
-		spinlock_lock(&task->lock);
-		list_append(&t->th_link, &task->th_head);
-		spinlock_unlock(&task->lock);
-
-		interrupts_restore(ipl);
-	}
+	t->task = task;
+	
+	t->fpu_context_exists=0;
+	t->fpu_context_engaged=0;
+	
+	/*
+	 * Register this thread in the system-wide list.
+	 */
+	ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	list_append(&t->threads_link, &threads_head);
+	spinlock_unlock(&threads_lock);
+	
+	/*
+	 * Attach to the containing task.
+	 */
+	spinlock_lock(&task->lock);
+	list_append(&t->th_link, &task->th_head);
+	spinlock_unlock(&task->lock);
+	
+	interrupts_restore(ipl);
 
 	return t;
Index: test/mm/falloc2/test.c
===================================================================
--- test/mm/falloc2/test.c	(revision 85dc2e77222d3673eee1c67e4bf6f866fda4ca31)
+++ test/mm/falloc2/test.c	(revision bb68433fea16aec0b0b4240149c9c3e8fb347b34)
@@ -56,5 +56,5 @@
 	index_t k;
 	
-	__address * frames =  (__address *) malloc(MAX_FRAMES * sizeof(__address));
+	__address * frames =  (__address *) malloc(MAX_FRAMES * sizeof(__address), FRAME_ATOMIC);
 	ASSERT(frames != NULL);
 
