Index: kernel/arch/amd64/include/mm/frame.h
===================================================================
--- kernel/arch/amd64/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/amd64/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64mm	
+/** @addtogroup amd64mm
  * @{
  */
@@ -40,10 +40,9 @@
 #endif /* __ASM__ */
 
-#define FRAME_WIDTH		12	/* 4K */
-#define FRAME_SIZE		(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifndef __ASM__
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 extern void frame_arch_init(void);
 extern void physmem_print(void);
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/amd64/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -35,6 +35,4 @@
 #include <arch/mm/page.h>
 #include <genarch/mm/page_pt.h>
-#include <genarch/drivers/ega/ega.h>
-#include <genarch/drivers/legacy/ia32/io.h>
 #include <arch/mm/frame.h>
 #include <mm/page.h>
@@ -49,9 +47,4 @@
 #include <panic.h>
 #include <align.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
-static parea_t ega_area;
 
 /* Definitions for identity page mapper */
@@ -222,15 +215,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xfffffffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-	
-	ega_area.pbase = EGA_VIDEORAM;
-	ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE);
-	ddi_parea_register(&ega_area);
-}
-
 /** @}
  */
Index: kernel/arch/arm32/include/mm/frame.h
===================================================================
--- kernel/arch/arm32/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/arm32/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32mm	
+/** @addtogroup arm32mm
  * @{
  */
@@ -37,6 +37,6 @@
 #define KERN_arm32_FRAME_H_
 
-#define FRAME_WIDTH		12 /* 4KB frames */
-#define FRAME_SIZE		(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  12  /* 4KB frames */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifdef KERNEL
@@ -45,6 +45,6 @@
 #include <arch/types.h>
 
-#define BOOT_PAGE_TABLE_SIZE    0x4000
-#define BOOT_PAGE_TABLE_ADDRESS 0x4000
+#define BOOT_PAGE_TABLE_SIZE     0x4000
+#define BOOT_PAGE_TABLE_ADDRESS  0x4000
 
 #define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
@@ -52,5 +52,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 
 extern void frame_arch_init(void);
Index: kernel/arch/arm32/src/mm/frame.c
===================================================================
--- kernel/arch/arm32/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/arm32/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32mm	
+/** @addtogroup arm32mm
  * @{
  */
@@ -42,5 +42,4 @@
 /** Address of the last frame in the memory. */
 uintptr_t last_frame = 0;
-uintptr_t end_frame = 0;
 
 /** Creates memory zones. */
@@ -51,5 +50,4 @@
 	    BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
 	last_frame = machine_get_memory_size();
-	end_frame = last_frame;
 	
 	/* blacklist boot page table */
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/arm32/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -44,8 +44,4 @@
 #include <interrupt.h>
 #include <arch/mm/frame.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
 
 /** Initializes page tables.
@@ -111,11 +107,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-}
-
 /** @}
  */
Index: kernel/arch/ia32/include/boot/memmap.h
===================================================================
--- kernel/arch/ia32/include/boot/memmap.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/include/boot/memmap.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -36,21 +36,26 @@
 #define KERN_ia32_MEMMAP_H_
 
-/* E820h memory range types - other values*/
-	/* Free memory */
-#define MEMMAP_MEMORY_AVAILABLE	1
-	/* Not available for OS */
-#define MEMMAP_MEMORY_RESERVED	2 
-	/* OS may use it after reading ACPI table */
-#define MEMMAP_MEMORY_ACPI	3 
-	/* Unusable, required to be saved and restored across an NVS sleep */
-#define MEMMAP_MEMORY_NVS	4 
-	/* Corrupted memory */
-#define MEMMAP_MEMORY_UNUSABLE	5 
+/* E820h memory range types */
 
-	 /* size of one entry */
-#define MEMMAP_E820_RECORD_SIZE 20 
-	/* maximum entries */
-#define MEMMAP_E820_MAX_RECORDS 32 
+/* Free memory */
+#define MEMMAP_MEMORY_AVAILABLE  1
 
+/* Not available for OS */
+#define MEMMAP_MEMORY_RESERVED   2
+
+/* OS may use it after reading ACPI table */
+#define MEMMAP_MEMORY_ACPI       3
+
+/* Unusable, required to be saved and restored across an NVS sleep */
+#define MEMMAP_MEMORY_NVS        4
+
+/* Corrupted memory */
+#define MEMMAP_MEMORY_UNUSABLE   5
+
+/* Size of one entry */
+#define MEMMAP_E820_RECORD_SIZE  20
+
+/* Maximum entries */
+#define MEMMAP_E820_MAX_RECORDS  32
 
 #ifndef __ASM__
Index: kernel/arch/ia32/include/mm/frame.h
===================================================================
--- kernel/arch/ia32/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
@@ -36,6 +36,6 @@
 #define KERN_ia32_FRAME_H_
 
-#define FRAME_WIDTH	12	/* 4K */
-#define FRAME_SIZE	(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifdef KERNEL
@@ -45,5 +45,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 
 extern void frame_arch_init(void);
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -51,32 +51,60 @@
 
 uintptr_t last_frame = 0;
-uintptr_t end_frame = 0;
 
 static void init_e820_memory(pfn_t minconf)
 {
 	unsigned int i;
-	pfn_t start, conf;
-	size_t size;
-	
 	for (i = 0; i < e820counter; i++) {
+		uint64_t base = e820table[i].base_address;
+		uint64_t size = e820table[i].size;
+		
+#ifdef __32_BITS__
+		
+		/* Ignore physical memory above 4 GB */
+		if ((base >> 32) != 0)
+			continue;
+		
+		/* Clip regions above 4 GB */
+		if (((base + size) >> 32) != 0)
+			size = 0xffffffff - base;
+		
+#endif
+		pfn_t pfn;
+		count_t count;
+		
 		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
-			start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE));
-			size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE));
+			/* To be safe, make available zone possibly smaller */
+			pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE));
 			
-			if ((minconf < start) || (minconf >= start + size))
-				conf = start;
+			pfn_t conf;
+			if ((minconf < pfn) || (minconf >= pfn + count))
+				conf = pfn;
 			else
 				conf = minconf;
 			
-			zone_create(start, size, conf, 0);
+			zone_create(pfn, count, conf, ZONE_AVAILABLE);
 			
-			if (last_frame < ALIGN_UP(e820table[i].base_address +
-			    e820table[i].size, FRAME_SIZE))
-				last_frame =
-				    ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
+			// XXX this has to be removed
+			if (last_frame < ALIGN_UP(base + size, FRAME_SIZE))
+				last_frame = ALIGN_UP(base + size, FRAME_SIZE);
+		}
+		
+		if (e820table[i].type == MEMMAP_MEMORY_RESERVED) {
+			/* To be safe, make reserved zone possibly larger */
+			pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE));
+			
+			zone_create(pfn, count, 0, ZONE_RESERVED);
+		}
+		
+		if (e820table[i].type == MEMMAP_MEMORY_ACPI) {
+			/* To be safe, make firmware zone possibly larger */
+			pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE));
+			
+			zone_create(pfn, count, 0, ZONE_FIRMWARE);
 		}
 	}
-	
-	end_frame = last_frame;
 }
 
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -35,6 +35,4 @@
 #include <arch/mm/page.h>
 #include <genarch/mm/page_pt.h>
-#include <genarch/drivers/ega/ega.h>
-#include <genarch/drivers/legacy/ia32/io.h>
 #include <arch/mm/frame.h>
 #include <mm/frame.h>
@@ -51,9 +49,4 @@
 #include <print.h>
 #include <interrupt.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
-static parea_t ega_area;
 
 void page_arch_init(void)
@@ -61,5 +54,5 @@
 	uintptr_t cur;
 	int flags;
-
+	
 	if (config.cpu_active == 1) {
 		page_mapping_operations = &pt_mapping_operations;
@@ -74,10 +67,10 @@
 			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
 		}
-
+		
 		exc_register(14, "page_fault", (iroutine) page_fault);
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 	} else
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
-
+	
 	paging_on();
 }
@@ -99,15 +92,4 @@
 	
 	return virtaddr;
-}
-
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-	
-	ega_area.pbase = EGA_VIDEORAM;
-	ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE);
-	ddi_parea_register(&ega_area);
 }
 
Index: kernel/arch/ia64/include/mm/frame.h
===================================================================
--- kernel/arch/ia64/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia64/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -36,6 +36,6 @@
 #define KERN_ia64_FRAME_H_
 
-#define FRAME_WIDTH		14	/* 16K */
-#define FRAME_SIZE		(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  14  /* 16K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifdef KERNEL
@@ -45,5 +45,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 
 extern void frame_arch_init(void);
Index: kernel/arch/ia64/src/mm/frame.c
===================================================================
--- kernel/arch/ia64/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia64/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64mm	
+/** @addtogroup ia64mm
  * @{
  */
@@ -52,5 +52,4 @@
 
 uintptr_t last_frame = 0;
-uintptr_t end_frame = 0;
 
 void frame_arch_init(void)
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia64/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -49,8 +49,4 @@
 #include <memstr.h>
 #include <align.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
 
 static void set_environment(void);
@@ -68,7 +64,7 @@
 {
 	region_register rr;
-	pta_register pta;	
+	pta_register pta;
 	int i;
-#ifdef CONFIG_VHPT	
+#ifdef CONFIG_VHPT
 	uintptr_t vhpt_base;
 #endif
@@ -279,11 +275,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0x7fffffffffffffffUL - end_frame);
-	ddi_parea_register(&dev_area);
-}
-
 /** @}
  */
Index: kernel/arch/mips32/include/mm/frame.h
===================================================================
--- kernel/arch/mips32/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/mips32/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32mm	
+/** @addtogroup mips32mm
  * @{
  */
@@ -47,6 +47,4 @@
 extern void physmem_print(void);
 
-extern uintptr_t end_frame;
-
 #endif /* __ASM__ */
 #endif /* KERNEL */
Index: kernel/arch/mips32/src/mm/frame.c
===================================================================
--- kernel/arch/mips32/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/mips32/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -65,6 +65,4 @@
 static count_t phys_regions_count = 0;
 static phys_region_t phys_regions[MAX_REGIONS];
-
-uintptr_t end_frame = 0;
 
 
@@ -239,7 +237,5 @@
 	}
 	
-	end_frame = frame;
-	
-	frame_add_region(start_frame, end_frame);
+	frame_add_region(start_frame, frame);
 	
 	/* Blacklist interrupt vector frame */
Index: kernel/arch/mips32/src/mm/page.c
===================================================================
--- kernel/arch/mips32/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/mips32/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -37,8 +37,4 @@
 #include <mm/page.h>
 #include <mm/frame.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
 
 void page_arch_init(void)
@@ -56,11 +52,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-}
-
 /** @}
  */
Index: kernel/arch/ppc32/include/mm/frame.h
===================================================================
--- kernel/arch/ppc32/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ppc32/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -36,6 +36,6 @@
 #define KERN_ppc32_FRAME_H_
 
-#define FRAME_WIDTH		12	/* 4K */
-#define FRAME_SIZE		(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifdef KERNEL
@@ -45,5 +45,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 
 extern void frame_arch_init(void);
Index: kernel/arch/ppc32/src/mm/frame.c
===================================================================
--- kernel/arch/ppc32/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ppc32/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -41,5 +41,4 @@
 
 uintptr_t last_frame = 0;
-uintptr_t end_frame = 0;
 
 void physmem_print(void)
@@ -77,6 +76,4 @@
 	}
 	
-	end_frame = last_frame;
-	
 	/* First is exception vector, second is 'implementation specific',
 	   third and fourth is reserved, other contain real mode code */
Index: kernel/arch/ppc32/src/mm/page.c
===================================================================
--- kernel/arch/ppc32/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ppc32/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -38,8 +38,4 @@
 #include <align.h>
 #include <config.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
 
 void page_arch_init(void)
@@ -68,11 +64,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-}
-
 /** @}
  */
Index: kernel/arch/sparc64/include/mm/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/sparc64/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -74,5 +74,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 extern void frame_arch_init(void);
 #define physmem_print()
Index: kernel/arch/sparc64/src/mm/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/sparc64/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -42,5 +42,4 @@
 
 uintptr_t last_frame = NULL;
-uintptr_t end_frame = NULL;
 
 /** Create memory zones according to information stored in bootinfo.
@@ -81,6 +80,4 @@
 		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
 	}
-	
-	end_frame = last_frame;
 }
 
Index: kernel/arch/sparc64/src/mm/page.c
===================================================================
--- kernel/arch/sparc64/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/sparc64/src/mm/page.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -42,8 +42,4 @@
 #include <align.h>
 #include <config.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
 
 #ifdef CONFIG_SMP
@@ -169,11 +165,4 @@
 }
 
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0x7ffffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-}
-
 /** @}
  */
Index: kernel/generic/include/align.h
===================================================================
--- kernel/generic/include/align.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/generic/include/align.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @ingroup others
  * @{
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Macros for making values and addresses aligned.
+ * @brief Macros for making values and addresses aligned.
  */
 
@@ -44,5 +44,5 @@
  * @param a Size of alignment, must be power of 2.
  */
-#define ALIGN_DOWN(s, a)	((s) & ~((a) - 1))
+#define ALIGN_DOWN(s, a)  ((s) & ~((a) - 1))
 
 
@@ -52,5 +52,5 @@
  * @param a Size of alignment, must be power of 2.
  */
-#define ALIGN_UP(s, a)		(((s) + ((a) - 1)) & ~((a) - 1))
+#define ALIGN_UP(s, a)  (((s) + ((a) - 1)) & ~((a) - 1))
 
 #endif
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/generic/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -40,4 +40,5 @@
 #include <adt/list.h>
 #include <mm/buddy.h>
+#include <synch/spinlock.h>
 #include <arch/mm/page.h>
 #include <arch/mm/frame.h>
@@ -68,12 +69,49 @@
 typedef uint8_t zone_flags_t;
 
+/** Available zone (free for allocation) */
+#define ZONE_AVAILABLE  0x00
 /** Zone is reserved (not available for allocation) */
-#define ZONE_RESERVED  0x08
+#define ZONE_RESERVED   0x08
 /** Zone is used by firmware (not available for allocation) */
-#define ZONE_FIRMWARE  0x10
+#define ZONE_FIRMWARE   0x10
 
 /** Currently there is no equivalent zone flags
     for frame flags */
 #define FRAME_TO_ZONE_FLAGS(frame_flags)  0
+
+typedef struct {
+	count_t refcount;     /**< Tracking of shared frames */
+	uint8_t buddy_order;  /**< Buddy system block order */
+	link_t buddy_link;    /**< Link to the next free block inside
+                               one order */
+	void *parent;         /**< If allocated by slab, this points there */
+} frame_t;
+
+typedef struct {
+	pfn_t base;                    /**< Frame_no of the first frame
+                                        in the frames array */
+	count_t count;                 /**< Size of zone */
+	count_t free_count;            /**< Number of free frame_t
+                                        structures */
+	count_t busy_count;            /**< Number of busy frame_t
+                                        structures */
+	zone_flags_t flags;            /**< Type of the zone */
+	
+	frame_t *frames;               /**< Array of frame_t structures
+                                        in this zone */
+	buddy_system_t *buddy_system;  /**< Buddy system for the zone */
+} zone_t;
+
+/*
+ * The zoneinfo.lock must be locked when accessing zoneinfo structure.
+ * Some of the attributes in zone_t structures are 'read-only'
+ */
+typedef struct {
+	SPINLOCK_DECLARE(lock);
+	count_t count;
+	zone_t info[ZONES_MAX];
+} zones_t;
+
+extern zones_t zones;
 
 static inline uintptr_t PFN2ADDR(pfn_t frame)
@@ -99,4 +137,9 @@
 }
 
+static inline bool zone_flags_available(zone_flags_t flags)
+{
+	return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
+}
+
 #define IS_BUDDY_ORDER_OK(index, order) \
     ((~(((unative_t) -1) << (order)) & (index)) == 0)
@@ -118,4 +161,5 @@
 extern void frame_reference_add(pfn_t);
 
+extern count_t find_zone(pfn_t frame, count_t count, count_t hint);
 extern count_t zone_create(pfn_t, count_t, pfn_t, zone_flags_t);
 extern void *frame_get_parent(pfn_t, count_t);
Index: kernel/generic/include/mm/page.h
===================================================================
--- kernel/generic/include/mm/page.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/generic/include/mm/page.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -62,5 +62,4 @@
 
 extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
-extern void hw_area(void);
 
 #endif
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/generic/src/ddi/ddi.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -30,8 +30,8 @@
  * @{
  */
- 
+
 /**
  * @file
- * @brief	Device Driver Interface functions.
+ * @brief Device Driver Interface functions.
  *
  * This file contains functions that comprise the Device Driver Interface.
@@ -48,5 +48,5 @@
 #include <synch/spinlock.h>
 #include <syscall/copy.h>
-#include <adt/list.h>
+#include <adt/btree.h>
 #include <arch.h>
 #include <align.h>
@@ -56,11 +56,11 @@
 SPINLOCK_INITIALIZE(parea_lock);
 
-/** List with enabled physical memory areas. */
-static LIST_INITIALIZE(parea_head);
+/** B+tree with enabled physical memory areas. */
+static btree_t parea_btree;
 
 /** Initialize DDI. */
 void ddi_init(void)
 {
-	hw_area();
+	btree_create(&parea_btree);
 }
 
@@ -69,20 +69,14 @@
  * @param parea Pointer to physical area structure.
  *
- * @todo This function doesn't check for overlaps. It depends on the kernel to
- * create disjunct physical memory areas.
  */
 void ddi_parea_register(parea_t *parea)
 {
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
+	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&parea_lock);
 	
 	/*
-	 * TODO: we should really check for overlaps here.
-	 * However, we should be safe because the kernel is pretty sane.
-	 */
-	link_initialize(&parea->link);
-	list_append(&parea->link, &parea_head);
+	 * We don't check for overlaps here as the kernel is pretty sane.
+	 */
+	btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL);
 	
 	spinlock_unlock(&parea_lock);
@@ -92,62 +86,81 @@
 /** Map piece of physical memory into virtual address space of current task.
  *
- * @param pf Physical address of the starting frame.
- * @param vp Virtual address of the starting page.
+ * @param pf    Physical address of the starting frame.
+ * @param vp    Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Address space area flags for the mapping.
  *
  * @return 0 on success, EPERM if the caller lacks capabilities to use this
- *  syscall, ENOENT if there is no task matching the specified ID or the
- *  physical address space is not enabled for mapping and ENOMEM if there
- *  was a problem in creating address space area.
- */
-static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, pfn_t pages, int flags)
-{
-	ipl_t ipl;
-	cap_t caps;
+ *         syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there
+ *         is no task matching the specified ID or the physical address space
+ *         is not enabled for mapping and ENOMEM if there was a problem in
+ *         creating address space area.
+ *
+ */
+static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags)
+{
+	ASSERT(TASK);
+	ASSERT((pf % FRAME_SIZE) == 0);
+	ASSERT((vp % PAGE_SIZE) == 0);
+	
+	/*
+	 * Make sure the caller is authorised to make this syscall.
+	 */
+	cap_t caps = cap_get(TASK);
+	if (!(caps & CAP_MEM_MANAGER))
+		return EPERM;
+	
 	mem_backend_data_t backend_data;
-	
 	backend_data.base = pf;
 	backend_data.frames = pages;
 	
-	/*
-	 * Make sure the caller is authorised to make this syscall.
-	 */
-	caps = cap_get(TASK);
-	if (!(caps & CAP_MEM_MANAGER))
-		return EPERM;
-	
-	ipl = interrupts_disable();
-	
-	/*
-	 * Check if the physical memory area is enabled for mapping.
-	 */
-	spinlock_lock(&parea_lock);
-	
-	bool fnd = false;
-	link_t *cur;
-	
-	for (cur = parea_head.next; cur != &parea_head; cur = cur->next) {
-		parea_t *parea = list_get_instance(cur, parea_t, link);
-		if ((parea->pbase <= pf) && (ADDR2PFN(pf - parea->pbase) + pages <= parea->frames)) {
-			fnd = true;
-			break;
-		}
-	}
-	
-	spinlock_unlock(&parea_lock);
-	
-	if (!fnd) {
-		/*
-		 * Physical memory area cannot be mapped.
-		 */
-		interrupts_restore(ipl);
-		return ENOENT;
-	}
-	
+	ipl_t ipl = interrupts_disable();
+	
+	/* Find the zone of the physical memory */
+	spinlock_lock(&zones.lock);
+	count_t znum = find_zone(ADDR2PFN(pf), pages, 0);
+	
+	if (znum == (count_t) -1) {
+		/* Frames not found in any zones
+		 * -> assume it is hardware device and allow mapping
+		 */
+		spinlock_unlock(&zones.lock);
+		goto map;
+	}
+	
+	if (zones.info[znum].flags & ZONE_FIRMWARE) {
+		/* Frames are part of firmware */
+		spinlock_unlock(&zones.lock);
+		goto map;
+	}
+	
+	if (zone_flags_available(zones.info[znum].flags)) {
+		/* Frames are part of physical memory, check if the memory
+		 * region is enabled for mapping.
+		 */
+		spinlock_unlock(&zones.lock);
+		
+		spinlock_lock(&parea_lock);
+		btree_node_t *nodep;
+		parea_t *parea = (parea_t *) btree_search(&parea_btree,
+		    (btree_key_t) pf, &nodep);
+		
+		if ((!parea) || (parea->frames < pages))
+			goto err;
+		
+		spinlock_unlock(&parea_lock);
+		goto map;
+	}
+	
+err:
+	spinlock_unlock(&zones.lock);
+	interrupts_restore(ipl);
+	return ENOENT;
+	
+map:
 	spinlock_lock(&TASK->lock);
 	
-	if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
-		&phys_backend, &backend_data)) {
+	if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
+	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
 		/*
 		 * The address space area could not have been created.
@@ -175,26 +188,22 @@
  *
  * @return 0 on success, EPERM if the caller lacks capabilities to use this
- * 	syscall, ENOENT if there is no task matching the specified ID.
+ *           syscall, ENOENT if there is no task matching the specified ID.
+ *
  */
 static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
 {
-	ipl_t ipl;
-	cap_t caps;
-	task_t *t;
-	int rc;
-	
 	/*
 	 * Make sure the caller is authorised to make this syscall.
 	 */
-	caps = cap_get(TASK);
+	cap_t caps = cap_get(TASK);
 	if (!(caps & CAP_IO_MANAGER))
 		return EPERM;
 	
-	ipl = interrupts_disable();
+	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&tasks_lock);
 	
-	t = task_find_by_id(id);
-	
-	if ((!t) || (!context_check(CONTEXT, t->context))) {
+	task_t *task = task_find_by_id(id);
+	
+	if ((!task) || (!context_check(CONTEXT, task->context))) {
 		/*
 		 * There is no task with the specified ID
@@ -206,13 +215,14 @@
 		return ENOENT;
 	}
-
+	
 	/* Lock the task and release the lock protecting tasks_btree. */
-	spinlock_lock(&t->lock);
+	spinlock_lock(&task->lock);
 	spinlock_unlock(&tasks_lock);
-
-	rc = ddi_iospace_enable_arch(t, ioaddr, size);
-	
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
+	
+	int rc = ddi_iospace_enable_arch(task, ioaddr, size);
+	
+	spinlock_unlock(&task->lock);
+	interrupts_restore(ipl);
+	
 	return rc;
 }
@@ -226,5 +236,6 @@
  *
  * @return 0 on success, otherwise it returns error code found in errno.h
- */ 
+ *
+ */
 unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base,
     unative_t pages, unative_t flags)
@@ -232,5 +243,5 @@
 	return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
 	    FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
-	    (pfn_t) pages, (int) flags);
+	    (count_t) pages, (int) flags);
 }
 
@@ -240,14 +251,13 @@
  *
  * @return 0 on success, otherwise it returns error code found in errno.h
- */ 
+ *
+ */
 unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg)
 {
 	ddi_ioarg_t arg;
-	int rc;
-	
-	rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
+	int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
 	if (rc != 0)
 		return (unative_t) rc;
-		
+	
 	return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id,
 	    (uintptr_t) arg.ioaddr, (size_t) arg.size);
@@ -257,17 +267,21 @@
  *
  * @param enable If non-zero, the preemption counter will be decremented,
- * 	leading to potential enabling of preemption. Otherwise the preemption
- * 	counter will be incremented, preventing preemption from occurring.
+ *               leading to potential enabling of preemption. Otherwise
+ *               the preemption counter will be incremented, preventing
+ *               preemption from occurring.
  *
  * @return Zero on success or EPERM if callers capabilities are not sufficient.
- */ 
+ *
+ */
 unative_t sys_preempt_control(int enable)
 {
 	if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
 		return EPERM;
+	
 	if (enable)
 		preemption_enable();
 	else
 		preemption_disable();
+	
 	return 0;
 }
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/generic/src/mm/frame.c	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -49,5 +49,4 @@
 #include <debug.h>
 #include <adt/list.h>
-#include <synch/spinlock.h>
 #include <synch/mutex.h>
 #include <synch/condvar.h>
@@ -61,38 +60,5 @@
 #include <config.h>
 
-typedef struct {
-	count_t refcount;     /**< Tracking of shared frames */
-	uint8_t buddy_order;  /**< Buddy system block order */
-	link_t buddy_link;    /**< Link to the next free block inside
-                               one order */
-	void *parent;         /**< If allocated by slab, this points there */
-} frame_t;
-
-typedef struct {
-	pfn_t base;                    /**< Frame_no of the first frame
-                                        in the frames array */
-	count_t count;                 /**< Size of zone */
-	count_t free_count;            /**< Number of free frame_t
-                                        structures */
-	count_t busy_count;            /**< Number of busy frame_t
-                                        structures */
-	zone_flags_t flags;            /**< Type of the zone */
-	
-	frame_t *frames;               /**< Array of frame_t structures
-                                        in this zone */
-	buddy_system_t *buddy_system;  /**< Buddy system for the zone */
-} zone_t;
-
-/*
- * The zoneinfo.lock must be locked when accessing zoneinfo structure.
- * Some of the attributes in zone_t structures are 'read-only'
- */
-typedef struct {
-	SPINLOCK_DECLARE(lock);
-	count_t count;
-	zone_t info[ZONES_MAX];
-} zones_t;
-
-static zones_t zones;
+zones_t zones;
 
 /*
@@ -127,9 +93,4 @@
 {
 	return (frame - zone->frames);
-}
-
-static inline bool zone_flags_available(zone_flags_t flags)
-{
-	return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
 }
 
@@ -181,6 +142,9 @@
 	/* Move other zones up */
 	count_t j;
-	for (j = i; j < zones.count; j++)
-		zones.info[j + 1] = zones.info[j];
+	for (j = zones.count; j > i; j--) {
+		zones.info[j] = zones.info[j - 1];
+		zones.info[j].buddy_system->data =
+		    (void *) &zones.info[j - 1];
+	}
 	
 	zones.count++;
@@ -207,5 +171,5 @@
 }
 
-/** Find a zone with a given frame.
+/** Find a zone with a given frames.
  *
  * Assume interrupts are disabled and zones lock is
@@ -213,4 +177,5 @@
  *
  * @param frame Frame number contained in zone.
+ * @param count Number of frames to look for.
  * @param hint  Used as zone hint.
  *
@@ -218,5 +183,5 @@
  *
  */
-static count_t find_zone(pfn_t frame, count_t hint)
+count_t find_zone(pfn_t frame, count_t count, count_t hint)
 {
 	if (hint >= zones.count)
@@ -226,5 +191,5 @@
 	do {
 		if ((zones.info[i].base <= frame)
-		    && (zones.info[i].base + zones.info[i].count > frame))
+		    && (zones.info[i].base + zones.info[i].count >= frame + count))
 			return i;
 		
@@ -766,8 +731,12 @@
 	    zones.info[z2].count);
 	
-	/* Shift existing zones */
+	/* Move zones down */
 	count_t i;
-	for (i = z2 + 1; i < zones.count; i++)
+	for (i = z2 + 1; i < zones.count; i++) {
 		zones.info[i - 1] = zones.info[i];
+		zones.info[i - 1].buddy_system->data =
+		    (void *) &zones.info[i - 1];
+	}
+	
 	zones.count--;
 	
@@ -965,5 +934,5 @@
 	spinlock_lock(&zones.lock);
 	
-	count_t znum = find_zone(pfn, hint);
+	count_t znum = find_zone(pfn, 1, hint);
 	
 	ASSERT(znum != (count_t) -1);
@@ -981,5 +950,5 @@
 	spinlock_lock(&zones.lock);
 	
-	count_t znum = find_zone(pfn, hint);
+	count_t znum = find_zone(pfn, 1, hint);
 	
 	ASSERT(znum != (count_t) -1);
@@ -1112,5 +1081,5 @@
 	 */
 	pfn_t pfn = ADDR2PFN(frame);
-	count_t znum = find_zone(pfn, NULL);
+	count_t znum = find_zone(pfn, 1, NULL);
 	
 	ASSERT(znum != (count_t) -1);
@@ -1151,5 +1120,5 @@
 	 * First, find host frame zone for addr.
 	 */
-	count_t znum = find_zone(pfn, NULL);
+	count_t znum = find_zone(pfn, 1, NULL);
 	
 	ASSERT(znum != (count_t) -1);
@@ -1169,5 +1138,5 @@
 	count_t i;
 	for (i = 0; i < count; i++) {
-		count_t znum = find_zone(start + i, 0);
+		count_t znum = find_zone(start + i, 1, 0);
 		if (znum == (count_t) -1)  /* PFN not found */
 			continue;
@@ -1238,11 +1207,11 @@
 {
 #ifdef __32_BITS__
-	printf("#  base address flags    free frames  busy frames\n");
-	printf("-- ------------ -------- ------------ ------------\n");
+	printf("#  base address frames       flags    free frames  busy frames\n");
+	printf("-- ------------ ------------ -------- ------------ ------------\n");
 #endif
 
 #ifdef __64_BITS__
-	printf("#  base address         flags    free frames  busy frames\n");
-	printf("-- -------------------- -------- ------------ ------------\n");
+	printf("#  base address          frames      flags    free frames  busy frames\n");
+	printf("-- -------------------- ------------ -------- ------------ ------------\n");
 #endif
 	
@@ -1270,4 +1239,5 @@
 		
 		uintptr_t base = PFN2ADDR(zones.info[i].base);
+		count_t count = zones.info[i].count;
 		zone_flags_t flags = zones.info[i].flags;
 		count_t free_count = zones.info[i].free_count;
@@ -1279,21 +1249,23 @@
 		bool available = zone_flags_available(flags);
 		
+		printf("%-2" PRIc, i);
+		
 #ifdef __32_BITS__
-		printf("%-2" PRIc "   %10p %c%c%c      ", i, base,
+		printf("   %10p", base);
+#endif
+		
+#ifdef __64_BITS__
+		printf("   %18p", base);
+#endif
+		
+		printf(" %12" PRIc " %c%c%c      ", count,
 		    available ? 'A' : ' ',
 		    (flags & ZONE_RESERVED) ? 'R' : ' ',
 		    (flags & ZONE_FIRMWARE) ? 'F' : ' ');
-#endif
-		
-#ifdef __64_BITS__
-		printf("%-2" PRIc "   %18p %c%c%c      ", i, base,
-		    available ? 'A' : ' ',
-		    (flags & ZONE_RESERVED) ? 'R' : ' ',
-		    (flags & ZONE_FIRMWARE) ? 'F' : ' ');
-#endif
 		
 		if (available)
 			printf("%12" PRIc " %12" PRIc,
 			    free_count, busy_count);
+		
 		printf("\n");
 	}
