Index: kernel/arch/amd64/src/mm/km.c
===================================================================
--- kernel/arch/amd64/src/mm/km.c	(revision c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
+++ kernel/arch/amd64/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 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 c868e2d76f25a71fcfed3d81a934a16b64b0ce81)
@@ -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;
-}
-
 /** @}
  */
