Index: arch/ppc32/src/mm/page.c
===================================================================
--- arch/ppc32/src/mm/page.c	(revision c1982e45cfd67b998329f3d32f3b52cbbc6caa5b)
+++ arch/ppc32/src/mm/page.c	(revision 125e9443d523f71aa23ce4cf31996b4c7a54ad2c)
@@ -37,4 +37,5 @@
 #include <arch/types.h>
 #include <arch/exception.h>
+#include <align.h>
 #include <config.h>
 #include <print.h>
@@ -47,6 +48,9 @@
  *
  * Try to find PTE for faulting address.
- * The AS->lock must be held on entry to this function.
- *
+ * The as->lock must be held on entry to this function
+ * if lock is true.
+ *
+ * @param as       Address space.
+ * @param lock     Lock/unlock the address space.
  * @param badvaddr Faulting virtual address.
  * @param istate   Pointer to interrupted state.
@@ -55,10 +59,10 @@
  *
  */
-static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
+static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, istate_t *istate, int *pfcr)
 {
 	/*
 	 * Check if the mapping exists in page tables.
 	 */	
-	pte_t *pte = page_mapping_find(AS, badvaddr);
+	pte_t *pte = page_mapping_find(as, badvaddr);
 	if ((pte) && (pte->p)) {
 		/*
@@ -74,5 +78,5 @@
 		 * Resort to higher-level page fault handler.
 		 */
-		page_table_unlock(AS, true);
+		page_table_unlock(as, lock);
 		switch (rc = as_page_fault(badvaddr, istate)) {
 			case AS_PF_OK:
@@ -81,14 +85,14 @@
 				 * The mapping ought to be in place.
 				 */
-				page_table_lock(AS, true);
-				pte = page_mapping_find(AS, badvaddr);
+				page_table_lock(as, lock);
+				pte = page_mapping_find(as, badvaddr);
 				ASSERT((pte) && (pte->p));
 				return pte;
 			case AS_PF_DEFER:
-				page_table_lock(AS, true);
+				page_table_lock(as, lock);
 				*pfcr = rc;
 				return NULL;
 			case AS_PF_FAULT:
-				page_table_lock(AS, true);
+				page_table_lock(as, lock);
 				printf("Page fault.\n");
 				*pfcr = rc;
@@ -181,6 +185,15 @@
 	__address badvaddr;
 	pte_t *pte;
-	
 	int pfcr;
+	as_t *as;
+	bool lock;
+	
+	if (AS == NULL) {
+		as = AS_KERNEL;
+		lock = false;
+	} else {
+		as = AS;
+		lock = true;
+	}
 	
 	if (data) {
@@ -192,11 +205,11 @@
 		badvaddr = istate->pc;
 		
-	spinlock_lock(&AS->lock);
-	asid = AS->asid;
-	spinlock_unlock(&AS->lock);
-	
-	page_table_lock(AS, true);
-	
-	pte = find_mapping_and_check(badvaddr, istate, &pfcr);
+	spinlock_lock(&as->lock);
+	asid = as->asid;
+	spinlock_unlock(&as->lock);
+	
+	page_table_lock(as, lock);
+	
+	pte = find_mapping_and_check(as, lock, badvaddr, istate, &pfcr);
 	if (!pte) {
 		switch (pfcr) {
@@ -209,5 +222,5 @@
 				 * or copy_to_uspace().
 				 */
-				page_table_unlock(AS, true);
+				page_table_unlock(as, lock);
 				return;
 			default:
@@ -219,9 +232,9 @@
 	pht_insert(badvaddr, pte->pfn);
 	
-	page_table_unlock(AS, true);
+	page_table_unlock(as, lock);
 	return;
 	
 fail:
-	page_table_unlock(AS, true);
+	page_table_unlock(as, lock);
 	pht_refill_fail(badvaddr, istate);
 }
@@ -238,17 +251,4 @@
 	if (config.cpu_active == 1) {
 		page_mapping_operations = &pt_mapping_operations;
-		
-		/*
-		 * PA2KA(identity) mapping for all frames until last_frame.
-		 */
-		__address cur;
-		int flags;
-		
-		for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
-			flags = PAGE_CACHEABLE;
-			if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
-				flags |= PAGE_GLOBAL;
-			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
-		}
 		
 		/* Allocate page hash table */
@@ -266,2 +266,18 @@
 	}
 }
+
+
+__address hw_map(__address 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 (%d bytes)", physaddr, size)
+	
+	__address virtaddr = PA2KA(last_frame);
+	pfn_t i;
+	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);
+	
+	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
+	
+	return virtaddr;
+}
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision c1982e45cfd67b998329f3d32f3b52cbbc6caa5b)
+++ generic/src/mm/as.c	(revision 125e9443d523f71aa23ce4cf31996b4c7a54ad2c)
@@ -98,6 +98,7 @@
 	as_arch_init();
 	AS_KERNEL = as_create(FLAG_AS_KERNEL);
-        if (!AS_KERNEL)
-                panic("can't create kernel address space\n");
+	if (!AS_KERNEL)
+		panic("can't create kernel address space\n");
+	
 }
 
