Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/amd64/Makefile.inc	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -86,4 +86,5 @@
 	arch/$(KARCH)/src/bios/bios.c \
 	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/amd64/include/mm/frame.h
===================================================================
--- kernel/arch/amd64/include/mm/frame.h	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/amd64/include/mm/frame.h	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -43,6 +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);
 extern void physmem_print(void);
 
Index: kernel/arch/amd64/include/mm/km.h
===================================================================
--- kernel/arch/amd64/include/mm/km.h	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
+++ kernel/arch/amd64/include/mm/km.h	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -0,0 +1,53 @@
+/*
+ * 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 amd64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_amd64_KM_H_
+#define KERN_amd64_KM_H_
+
+#include <typedefs.h>
+
+#define KM_AMD64_IDENTITY_START		UINT64_C(0xffff800000000000)
+#define KM_AMD64_IDENTITY_SIZE		UINT64_C(0x0000400000000000)
+
+#define KM_AMD64_NON_IDENTITY_START	UINT64_C(0xffffc00000000000)
+#define KM_AMD64_NON_IDENTITY_SIZE	UINT64_C(0x0000400000000000)
+
+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/amd64/src/mm/km.c
===================================================================
--- kernel/arch/amd64/src/mm/km.c	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
+++ kernel/arch/amd64/src/mm/km.c	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -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 amd64mm
+ * @{
+ */
+
+#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_AMD64_IDENTITY_START;
+	config.identity_size = KM_AMD64_IDENTITY_SIZE;	
+}
+
+void km_non_identity_arch_init(void)
+{
+	km_non_identity_span_add(KM_AMD64_NON_IDENTITY_START,
+	    KM_AMD64_NON_IDENTITY_SIZE);
+}
+
+bool km_is_non_identity_arch(uintptr_t addr)
+{
+	return iswithin(KM_AMD64_NON_IDENTITY_START,
+	    KM_AMD64_NON_IDENTITY_SIZE, addr, 1);
+}
+
+/** @}
+ */
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision d8db519fc389e77afc616e76c57b7406a9b9fad0)
+++ kernel/arch/amd64/src/mm/page.c	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -46,28 +46,32 @@
 #include <panic.h>
 #include <align.h>
+#include <macros.h>
 
 void page_arch_init(void)
 {
-	if (config.cpu_active == 1) {
-		uintptr_t cur;
-		unsigned int identity_flags =
-		    PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
+	if (config.cpu_active > 1) {
+		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
+		return;
+	}
+
+	uintptr_t cur;
+	unsigned int identity_flags =
+	    PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
 		
-		page_mapping_operations = &pt_mapping_operations;
+	page_mapping_operations = &pt_mapping_operations;
 		
-		page_table_lock(AS_KERNEL, true);
+	page_table_lock(AS_KERNEL, true);
 		
-		/*
-		 * PA2KA(identity) mapping for all frames.
-		 */
-		for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
-			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
+	/*
+	 * PA2KA(identity) mapping for all low-memory frames.
+	 */
+	for (cur = 0; cur < min(config.identity_size, config.physmem_end);
+	    cur += FRAME_SIZE)
+		page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
 		
-		page_table_unlock(AS_KERNEL, true);
+	page_table_unlock(AS_KERNEL, true);
 		
-		exc_register(14, "page_fault", true, (iroutine_t) page_fault);
-		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
-	} else
-		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
+	exc_register(14, "page_fault", true, (iroutine_t) page_fault);
+	write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 }
 
@@ -94,25 +98,4 @@
 }
 
-uintptr_t hw_map(uintptr_t physaddr, size_t size)
-{
-	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%zu bytes).",
-		    (void *) physaddr, size);
-	
-	uintptr_t virtaddr = PA2KA(last_frame);
-	pfn_t i;
-	
-	page_table_lock(AS_KERNEL, true);
-	
-	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
-		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
-	
-	page_table_unlock(AS_KERNEL, true);
-	
-	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
-	
-	return virtaddr;
-}
-
 /** @}
  */
