Index: uspace/fb/ega.c
===================================================================
--- uspace/fb/ega.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/fb/ega.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -35,5 +35,4 @@
  */
 
-
 #include <stdlib.h>
 #include <unistd.h>
@@ -63,5 +62,4 @@
 saved_screen saved_screens[MAX_SAVED_SCREENS];
 
-
 #define EGA_IO_ADDRESS 0x3d4
 #define EGA_IO_SIZE 2
@@ -127,10 +125,12 @@
 	int i;
 	if (rows > 0) {
-		memcpy (scr_addr,((char *)scr_addr) + rows * scr_width * 2, scr_width * scr_height * 2 - rows * scr_width * 2);
+		memcpy (scr_addr,((char *)scr_addr) + rows * scr_width * 2,
+			scr_width * scr_height * 2 - rows * scr_width * 2);
 		for (i = 0; i < rows * scr_width ; i ++)
-			(((short *)scr_addr) + scr_width * scr_height - rows * scr_width) [i] = ((style << 8) + ' ');
+			(((short *)scr_addr) + scr_width * scr_height - rows *
+				scr_width) [i] = ((style << 8) + ' ');
 	} else if (rows < 0) {
-
-		memcpy (((char *)scr_addr) - rows * scr_width * 2 ,scr_addr ,scr_width * scr_height * 2 + rows * scr_width * 2);
+		memcpy (((char *)scr_addr) - rows * scr_width * 2, scr_addr,
+			scr_width * scr_height * 2 + rows * scr_width * 2);
 		for (i = 0; i < - rows * scr_width ; i++)
 			((short *)scr_addr) [i] = ((style << 8 ) + ' ');
@@ -309,11 +309,12 @@
 	scr_width=sysinfo_value("fb.width");
 	scr_height=sysinfo_value("fb.height");
-	iospace_enable(task_get_id(),(void *)EGA_IO_ADDRESS,2);
-
-	sz = scr_width*scr_height*2;
-	scr_addr = as_get_mappable_page(sz);
-
-	physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> PAGE_WIDTH,
-		    AS_AREA_READ | AS_AREA_WRITE);
+	iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2);
+
+	sz = scr_width * scr_height * 2;
+	scr_addr = as_get_mappable_page(sz, (int)
+		sysinfo_value("fb.address.color"));
+
+	physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >>
+		PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
 
 	async_set_client_connection(ega_client_connection);
Index: uspace/fb/fb.c
===================================================================
--- uspace/fb/fb.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/fb/fb.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -705,7 +705,8 @@
 		/* We accept one area for data interchange */
 		if (IPC_GET_ARG1(*call) == shm_id) {
-			void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
+			void *dest = as_get_mappable_page(IPC_GET_ARG2(*call),
+				PAGE_COLOR(IPC_GET_ARG1(*call)));
 			shm_size = IPC_GET_ARG2(*call);
-			if (!ipc_answer_fast(callid, 0, (sysarg_t)dest, 0)) 
+			if (!ipc_answer_fast(callid, 0, (sysarg_t) dest, 0)) 
 				shm = dest;
 			else
@@ -717,5 +718,5 @@
 		} else {
 			intersize = IPC_GET_ARG2(*call);
-			receive_comm_area(callid,call,(void *)&interbuffer);
+			receive_comm_area(callid, call, (void *) &interbuffer);
 		}
 		return 1;
@@ -1283,10 +1284,11 @@
 
 	asz = fb_scanline * fb_height;
-	fb_addr = as_get_mappable_page(asz);
+	fb_addr = as_get_mappable_page(asz, (int) sysinfo_value("fb.address.color"));
 	
 	physmem_map(fb_ph_addr, fb_addr, ALIGN_UP(asz, PAGE_SIZE) >> PAGE_WIDTH,
 		    AS_AREA_READ | AS_AREA_WRITE);
 
-	if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual, fb_invert_colors))
+	if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual,
+		fb_invert_colors))
 		return 0;
 	
Index: uspace/fb/main.c
===================================================================
--- uspace/fb/main.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/fb/main.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -44,5 +44,6 @@
 	void *dest;
 
-	dest = as_get_mappable_page(IPC_GET_ARG2(*call));
+	dest = as_get_mappable_page(IPC_GET_ARG2(*call),
+		PAGE_COLOR(IPC_GET_ARG1(*call)));
 	if (ipc_answer_fast(callid, 0, (sysarg_t)dest, 0) == 0) {
 		if (*area)
Index: uspace/klog/klog.c
===================================================================
--- uspace/klog/klog.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/klog/klog.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -64,8 +64,8 @@
 	printf("Kernel console output.\n");
 	
-	mapping = as_get_mappable_page(PAGE_SIZE);
+	mapping = as_get_mappable_page(PAGE_SIZE, sysinfo_value("klog.fcolor"));
 	res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, 
-			      (sysarg_t)mapping, PAGE_SIZE, SERVICE_MEM_KLOG,
-			      NULL,NULL,NULL);
+			      (sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_KLOG,
+			      NULL, NULL, NULL);
 	if (res) {
 		printf("Failed to initialize klog memarea\n");
Index: uspace/libc/arch/amd64/include/config.h
===================================================================
--- uspace/libc/arch/amd64/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/amd64/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	12
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/ia32/include/config.h
===================================================================
--- uspace/libc/arch/ia32/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/ia32/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	12
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/ia64/include/config.h
===================================================================
--- uspace/libc/arch/ia64/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/ia64/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	14
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/mips32/include/config.h
===================================================================
--- uspace/libc/arch/mips32/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/mips32/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	14
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/ppc32/include/config.h
===================================================================
--- uspace/libc/arch/ppc32/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/ppc32/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	12
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/ppc64/include/config.h
===================================================================
--- uspace/libc/arch/ppc64/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/ppc64/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	12
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	0		/* dummy */
 
 #endif
Index: uspace/libc/arch/sparc64/include/config.h
===================================================================
--- uspace/libc/arch/sparc64/include/config.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/arch/sparc64/include/config.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #define PAGE_WIDTH	13
 #define PAGE_SIZE	(1<<PAGE_WIDTH)
+#define PAGE_COLOR_BITS	1		/**< Bit 13 is the page color. */
 
 #endif
Index: uspace/libc/generic/as.c
===================================================================
--- uspace/libc/generic/as.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/generic/as.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -38,4 +38,5 @@
 #include <align.h>
 #include <types.h>
+#include <bitops.h>
 
 /**
@@ -54,10 +55,12 @@
 void *as_area_create(void *address, size_t size, int flags)
 {
-	return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t ) address, (sysarg_t) size, (sysarg_t) flags);
+	return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t ) address,
+		(sysarg_t) size, (sysarg_t) flags);
 }
 
 /** Resize address space area.
  *
- * @param address Virtual address pointing into already existing address space area.
+ * @param address Virtual address pointing into already existing address space
+ * 	area.
  * @param size New requested size of the area.
  * @param flags Currently unused.
@@ -67,10 +70,12 @@
 int as_area_resize(void *address, size_t size, int flags)
 {
-	return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address, (sysarg_t) size, (sysarg_t) flags);
+	return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address, (sysarg_t)
+		size, (sysarg_t) flags);
 }
 
 /** Destroy address space area.
  *
- * @param address Virtual address pointing into the address space area being destroyed.
+ * @param address Virtual address pointing into the address space area being
+ * 	destroyed.
  *
  * @return Zero on success or a code from @ref errno.h on failure.
@@ -134,15 +139,27 @@
 	/* Return pointer to area not managed by sbrk */
 	return ((void *) &_heap + maxheapsize);
-
 }
 
 /** Return pointer to some unmapped area, where fits new as_area
  *
+ * @param sz Requested size of the allocation.
+ * @param color Requested virtual color of the allocation.
+ *
+ * @return Pointer to the beginning 
+ *
  * TODO: make some first_fit/... algorithm, we are now just incrementing
  *       the pointer to last area
  */
-void * as_get_mappable_page(size_t sz)
+#include <stdio.h>
+void *as_get_mappable_page(size_t sz, int color)
 {
 	void *res;
+	uint64_t asz;
+	int i;
+	
+	if (!sz)
+		return NULL;	
+
+	asz = 1 << (fnzb64(sz - 1) + 1);
 
 	/* Set heapsize to some meaningful value */
@@ -150,10 +167,23 @@
 		set_maxheapsize(MAX_HEAP_SIZE);
 	
-	if (!last_allocated)
-		last_allocated = (void *) ALIGN_UP((void *) &_heap + maxheapsize, PAGE_SIZE);
-	
-	sz = ALIGN_UP(sz, PAGE_SIZE);
+	/*
+	 * Make sure we allocate from naturally aligned address and a page of
+	 * appropriate color.
+	 */
+	i = 0;
+	do {
+		if (!last_allocated) {
+			last_allocated = (void *) ALIGN_UP((void *) &_heap +
+				maxheapsize, asz);
+		} else {
+			last_allocated = (void *) ALIGN_UP(((uintptr_t)
+				last_allocated) + (int) (i > 0), asz);
+		}
+	} while ((asz < (1 << (PAGE_COLOR_BITS + PAGE_WIDTH))) &&
+		(PAGE_COLOR((uintptr_t) last_allocated) != color) &&
+		(++i < (1 << PAGE_COLOR_BITS)));
+
 	res = last_allocated;
-	last_allocated += sz;
+	last_allocated += ALIGN_UP(sz, PAGE_SIZE);
 
 	return res;
Index: uspace/libc/generic/mman.c
===================================================================
--- uspace/libc/generic/mman.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/generic/mman.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -40,5 +40,5 @@
 {
 	if (!start)
-		start = as_get_mappable_page(length);
+		start = as_get_mappable_page(length, 0);
 	
 //	if (! ((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
Index: uspace/libc/generic/time.c
===================================================================
--- uspace/libc/generic/time.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/generic/time.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -41,4 +41,5 @@
 #include <atomic.h>
 #include <futex.h>
+#include <sysinfo.h>
 #include <ipc/services.h>
 
@@ -72,7 +73,10 @@
 
 	if (!ktime) {
-		mapping = as_get_mappable_page(PAGE_SIZE);
+		mapping = as_get_mappable_page(PAGE_SIZE, (int)
+			sysinfo_value("clock.fcolor"));
 		/* Get the mapping of kernel clock */
-		res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, (sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, NULL, &rights, NULL);
+		res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, (sysarg_t)
+			mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, NULL, &rights,
+			NULL);
 		if (res) {
 			printf("Failed to initialize timeofday memarea\n");
Index: uspace/libc/include/as.h
===================================================================
--- uspace/libc/include/as.h	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/libc/include/as.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -40,4 +40,7 @@
 #include <kernel/arch/mm/as.h>
 #include <kernel/mm/as.h>
+#include <libarch/config.h>
+
+#define PAGE_COLOR(va)	(((va) >> PAGE_WIDTH) & ((1 << PAGE_COLOR_BITS) - 1))
 
 extern void *as_area_create(void *address, size_t size, int flags);
@@ -45,5 +48,5 @@
 extern int as_area_destroy(void *address);
 extern void *set_maxheapsize(size_t mhs);
-extern void * as_get_mappable_page(size_t sz);
+extern void * as_get_mappable_page(size_t sz, int color);
 
 #endif
Index: uspace/libc/include/bitops.h
===================================================================
--- uspace/libc/include/bitops.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
+++ uspace/libc/include/bitops.h	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_BITOPS_H_
+#define LIBC_BITOPS_H_
+
+#include <types.h>
+
+
+/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
+ *
+ * If number is zero, it returns 0
+ */
+static inline int fnzb32(uint32_t arg)
+{
+	int n = 0;
+
+	if (arg >> 16) {
+		arg >>= 16;
+		n += 16;
+	}
+	
+	if (arg >> 8) {
+		arg >>= 8;
+		n += 8;
+	}
+	
+	if (arg >> 4) {
+		arg >>= 4;
+		n += 4;
+	}
+	
+	if (arg >> 2) {
+		arg >>= 2;
+		n += 2;
+	}
+	
+	if (arg >> 1) {
+		arg >>= 1;
+		n += 1;
+	}
+	
+	return n;
+}
+
+static inline int fnzb64(uint64_t arg)
+{
+	int n = 0;
+
+	if (arg >> 32) {
+		arg >>= 32;
+		n += 32;
+	}
+	
+	return n + fnzb32((uint32_t) arg);
+}
+
+#define fnzb(x) fnzb32(x)
+
+#endif
+
+/** @}
+ */
Index: uspace/ns/ns.c
===================================================================
--- uspace/ns/ns.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/ns/ns.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -84,15 +84,17 @@
 static void *klogaddr = NULL;
 
-static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, void **addr)
+static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, char *colstr, void **addr)
 {
 	void *ph_addr;
+	int ph_color;
 
 	if (!*addr) {
-		ph_addr = (void *)sysinfo_value(name);
+		ph_addr = (void *) sysinfo_value(name);
 		if (!ph_addr) {
 			ipc_answer_fast(callid, ENOENT, 0, 0);
 			return;
 		}
-		*addr = as_get_mappable_page(PAGE_SIZE);
+		ph_color = (int) sysinfo_value(colstr);
+		*addr = as_get_mappable_page(PAGE_SIZE, ph_color);
 		physmem_map(ph_addr, *addr, 1, AS_AREA_READ | AS_AREA_CACHEABLE);
 	}
@@ -117,8 +119,10 @@
 			switch (IPC_GET_ARG3(call)) {
 			case SERVICE_MEM_REALTIME:
-				get_as_area(callid, &call, "clock.faddr", &clockaddr);
+				get_as_area(callid, &call, "clock.faddr",
+					"clock.fcolor", &clockaddr);
 				break;
 			case SERVICE_MEM_KLOG:
-				get_as_area(callid, &call, "klog.faddr", &klogaddr);
+				get_as_area(callid, &call, "klog.faddr",
+					"klog.fcolor", &klogaddr);
 				break;
 			default:
Index: uspace/rd/rd.c
===================================================================
--- uspace/rd/rd.c	(revision 5a8b2a2e58c0aff599e30b00eed3a773ff644968)
+++ uspace/rd/rd.c	(revision f8ddd176406660da88b0e9d63695413731cd58ff)
@@ -74,9 +74,10 @@
 	size_t rd_size = sysinfo_value("rd.size");
 	void * rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
+	int rd_color = (int) sysinfo_value("rd.address.color");
 	
 	if (rd_size == 0)
 		return false;
 	
-	void * rd_addr = as_get_mappable_page(rd_size);
+	void * rd_addr = as_get_mappable_page(rd_size, rd_color);
 	
 	physmem_map(rd_ph_addr, rd_addr, ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
