Index: kernel/arch/ia64/Makefile.inc
===================================================================
--- kernel/arch/ia64/Makefile.inc	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/Makefile.inc	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -52,4 +52,5 @@
 	arch/$(KARCH)/src/ivt.S \
 	arch/$(KARCH)/src/interrupt.c \
+	arch/$(KARCH)/src/mm/km.c \
 	arch/$(KARCH)/src/mm/as.c \
 	arch/$(KARCH)/src/mm/frame.c \
Index: kernel/arch/ia64/include/mm/frame.h
===================================================================
--- kernel/arch/ia64/include/mm/frame.h	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/include/mm/frame.h	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -43,7 +43,6 @@
 #include <typedefs.h>
 
-extern uintptr_t last_frame;
-
-extern void frame_arch_init(void);
+extern void frame_low_arch_init(void);
+extern void frame_high_arch_init(void);
 #define physmem_print()
 
Index: kernel/arch/ia64/include/mm/km.h
===================================================================
--- kernel/arch/ia64/include/mm/km.h	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
+++ kernel/arch/ia64/include/mm/km.h	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Jakub Jermar
+ * 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 ia64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_ia64_KM_H_
+#define KERN_ia64_KM_H_
+
+#include <typedefs.h>
+
+/*
+ * Be conservative and assume the minimal (3 + 51)-bit virtual address width
+ * of the Itanium CPU even if running on CPU with full 64-bit virtual
+ * address width, such as Itanium 2.
+ */
+
+#define KM_IA64_IDENTITY_START		UINT64_C(0xe000000000000000)
+#define KM_IA64_IDENTITY_SIZE		UINT64_C(0x0004000000000000)
+
+#define KM_IA64_NON_IDENTITY_START	UINT64_C(0xfffc000000000000)
+#define KM_IA64_NON_IDENTITY_SIZE	UINT64_C(0x0004000000000000)
+
+extern void km_identity_arch_init(void);
+extern void km_non_identity_arch_init(void);
+extern bool km_is_non_identity_arch(uintptr_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/ia64/include/mm/page.h
===================================================================
--- kernel/arch/ia64/include/mm/page.h	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/include/mm/page.h	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -57,9 +57,9 @@
 
 /* Firmware area (bellow 4GB in phys mem) */
-#define FW_OFFSET   0x00000000F0000000
+#define FW_OFFSET   0x00000000F0000000	// FIXME: [non-ident]
 /* Legacy IO space */
-#define IO_OFFSET   0x0001000000000000
+#define IO_OFFSET   0x0001000000000000	// FIXME: [non-ident]
 /* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */
-#define VIO_OFFSET  0x0002000000000000
+#define VIO_OFFSET  0x0002000000000000	// FIXME: [non-ident]
 
 
Index: kernel/arch/ia64/src/mm/frame.c
===================================================================
--- kernel/arch/ia64/src/mm/frame.c	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/src/mm/frame.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -51,39 +51,63 @@
 #define MINCONF 1
 
-uintptr_t last_frame = 0;
+static void frame_common_arch_init(bool low)
+{
+	unsigned int i;
 
-void frame_arch_init(void)
-{
-	if (config.cpu_active == 1) {
-		unsigned int i;
-		for (i = 0; i < bootinfo->memmap_items; i++) {
-			if (bootinfo->memmap[i].type == MEMMAP_FREE_MEM) {
-				uint64_t base = bootinfo->memmap[i].base;
-				uint64_t size = bootinfo->memmap[i].size;
-				uint64_t abase = ALIGN_UP(base, FRAME_SIZE);
+	for (i = 0; i < bootinfo->memmap_items; i++) {
+		if (bootinfo->memmap[i].type != MEMMAP_FREE_MEM)
+			continue;
 
-				if (size > FRAME_SIZE)
-					size -= abase - base;
+		uintptr_t base = bootinfo->memmap[i].base;
+		size_t size = bootinfo->memmap[i].size;
+		uintptr_t abase = ALIGN_UP(base, FRAME_SIZE);
 
-				if (size > MIN_ZONE_SIZE) {
-					zone_create(abase >> FRAME_WIDTH,
-					    size >> FRAME_WIDTH,
-					    max(MINCONF, abase >> FRAME_WIDTH),
-					    0);
-				}
-				if (abase + size > last_frame)
-					last_frame = abase + size;
+		if (size > FRAME_SIZE)
+			size -= abase - base;
+
+		if (!frame_adjust_zone_bounds(low, &abase, &size))
+			continue;
+
+		if (size > MIN_ZONE_SIZE) {
+			pfn_t pfn = ADDR2PFN(abase);
+			size_t count = SIZE2FRAMES(size);
+
+			if (low) {
+				zone_create(pfn, count, max(MINCONF, pfn),
+				    ZONE_AVAILABLE | ZONE_LOWMEM);
+			} else {
+				pfn_t conf;
+
+				conf = zone_external_conf_alloc(count);
+				zone_create(pfn, count, conf,
+				    ZONE_AVAILABLE | ZONE_HIGHMEM);
 			}
 		}
-		
-		/*
-		 * Blacklist ROM regions.
-		 */
-		frame_mark_unavailable(ADDR2PFN(ROM_BASE),
-		    SIZE2FRAMES(ROM_SIZE));
+	}
+}
 
-		frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
-		    SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
-	}	
+void frame_low_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+	
+	frame_common_arch_init(true);
+	
+	/*
+	 * Blacklist ROM regions.
+	 */
+	frame_mark_unavailable(ADDR2PFN(ROM_BASE),
+	    SIZE2FRAMES(ROM_SIZE));
+
+	frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
+	    SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
+}
+
+void frame_high_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+	
+	frame_common_arch_init(false);
 }
 
Index: kernel/arch/ia64/src/mm/km.c
===================================================================
--- kernel/arch/ia64/src/mm/km.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
+++ kernel/arch/ia64/src/mm/km.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Jakub Jermar
+ * 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 ia64mm
+ * @{
+ */
+
+#include <arch/mm/km.h>
+#include <mm/km.h>
+#include <config.h>
+#include <typedefs.h>
+#include <macros.h>
+
+void km_identity_arch_init(void)
+{
+	config.identity_base = KM_IA64_IDENTITY_START;
+	config.identity_size = KM_IA64_IDENTITY_SIZE;	
+}
+
+void km_non_identity_arch_init(void)
+{
+	km_non_identity_span_add(KM_IA64_NON_IDENTITY_START,
+	    KM_IA64_NON_IDENTITY_SIZE);
+}
+
+bool km_is_non_identity_arch(uintptr_t addr)
+{
+	return iswithin(KM_IA64_NON_IDENTITY_START, KM_IA64_NON_IDENTITY_SIZE,
+	    addr, 1);
+}
+
+/** @}
+ */
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/src/mm/page.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -255,10 +255,4 @@
 }
 
-uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
-{
-	/* THIS is a dirty hack. */
-	return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET);
-}
-
 /** @}
  */
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -480,5 +480,4 @@
 	va = istate->cr_ifa; /* faulting address */
 	
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	if (t) {
@@ -488,10 +487,8 @@
 		 */
 		itc_pte_copy(t);
-		page_table_unlock(AS, true);
 	} else {
 		/*
 		 * Forward the page fault to address space page fault handler.
 		 */
-		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.",
@@ -598,5 +595,4 @@
 	
 	
-	page_table_lock(AS, true);
 	pte_t *entry = page_mapping_find(AS, va, true);
 	if (entry) {
@@ -606,7 +602,5 @@
 		 */
 		dtc_pte_copy(entry);
-		page_table_unlock(AS, true);
 	} else {
-		page_table_unlock(AS, true);
 		if (try_memmap_io_insertion(va, istate))
 			return;
@@ -650,5 +644,4 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	ASSERT((t) && (t->p));
@@ -667,5 +660,4 @@
 		}
 	}
-	page_table_unlock(AS, true);
 }
 
@@ -683,5 +675,4 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	ASSERT((t) && (t->p));
@@ -700,5 +691,4 @@
 		}
 	}
-	page_table_unlock(AS, true);
 }
 
@@ -716,5 +706,4 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	ASSERT((t) && (t->p));
@@ -733,5 +722,4 @@
 		}
 	}
-	page_table_unlock(AS, true);
 }
 
@@ -752,5 +740,4 @@
 	 * Assume a write to a read-only page.
 	 */
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	ASSERT((t) && (t->p));
@@ -761,5 +748,4 @@
 		panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
 	}
-	page_table_unlock(AS, true);
 }
 
@@ -777,5 +763,4 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
-	page_table_lock(AS, true);
 	t = page_mapping_find(AS, va, true);
 	ASSERT(t);
@@ -790,7 +775,5 @@
 		else
 			dtc_pte_copy(t);
-		page_table_unlock(AS, true);
 	} else {
-		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.",
Index: kernel/arch/ia64/src/start.S
===================================================================
--- kernel/arch/ia64/src/start.S	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/ia64/src/start.S	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -38,7 +38,7 @@
 #define KERNEL_TRANSLATION_I    0x0010000000000661
 #define KERNEL_TRANSLATION_D    0x0010000000000661
-#define KERNEL_TRANSLATION_VIO  0x0010000000000671
-#define KERNEL_TRANSLATION_IO   0x00100FFFFC000671
-#define KERNEL_TRANSLATION_FW   0x00100000F0000671
+#define KERNEL_TRANSLATION_VIO  0x0010000000000671	// FIXME: [non-ident]
+#define KERNEL_TRANSLATION_IO   0x00100FFFFC000671	// FIXME: [non-ident]
+#define KERNEL_TRANSLATION_FW   0x00100000F0000671	// FIXME: [non-ident]
 
 .section K_TEXT_START, "ax"
