Index: arch/ppc32/include/asm.h
===================================================================
--- arch/ppc32/include/asm.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/asm.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -141,4 +141,5 @@
 void cpu_halt(void);
 void asm_delay_loop(__u32 t);
+void invalidate_bat(void);
 
 extern void userspace_asm(__address uspace_uarg, __address stack, __address entry);
Index: arch/ppc32/include/asm/regname.h
===================================================================
--- arch/ppc32/include/asm/regname.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/asm/regname.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -190,4 +190,20 @@
 #define	sprg3	275
 #define	prv		287
+#define ibat0u	528
+#define ibat0l	529
+#define ibat1u	530
+#define ibat1l	531
+#define ibat2u	532
+#define ibat2l	533
+#define ibat3u	534
+#define ibat3l	535
+#define dbat0u	536
+#define dbat0l	537
+#define dbat1u	538
+#define dbat1l	539
+#define dbat2u	540
+#define dbat2l	541
+#define dbat3u	542
+#define dbat3l	543
 #define hid0	1008
 
Index: ch/ppc32/include/console.h
===================================================================
--- arch/ppc32/include/console.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-#ifndef __ppc32_CONSOLE_H__
-#define __ppc32_CONSOLE_H__
-
-extern void ppc32_console_init(void);
-extern void ppc32_console_register(void);
-
-#endif
Index: arch/ppc32/include/mm/frame.h
===================================================================
--- arch/ppc32/include/mm/frame.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/mm/frame.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -36,4 +36,8 @@
 #ifndef __ASM__
 
+#include <arch/types.h> 
+
+extern __address last_frame;
+
 extern void frame_arch_init(void);
 
Index: arch/ppc32/include/mm/page.h
===================================================================
--- arch/ppc32/include/mm/page.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/mm/page.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -109,5 +109,6 @@
 		(1 << PAGE_READ_SHIFT) |
 		(1 << PAGE_WRITE_SHIFT) |
-		(1 << PAGE_EXEC_SHIFT)
+		(1 << PAGE_EXEC_SHIFT) |
+		(p->g << PAGE_GLOBAL_SHIFT)
 	);
 }
@@ -118,8 +119,29 @@
 	
 	p->p = !(flags & PAGE_NOT_PRESENT);
+	p->g = (flags & PAGE_GLOBAL) != 0;
 	p->valid = 1;
 }
 
 extern void page_arch_init(void);
+
+#define PHT_BITS	16
+#define PHT_ORDER	4
+
+typedef struct {
+	unsigned v : 1;          /**< Valid */
+	unsigned vsid : 24;      /**< Virtual Segment ID */
+	unsigned h : 1;          /**< Primary/secondary hash */
+	unsigned api : 6;        /**< Abbreviated Page Index */
+	unsigned rpn : 20;       /**< Real Page Number */
+	unsigned reserved0 : 3;
+	unsigned r : 1;          /**< Reference */
+	unsigned c : 1;          /**< Change */
+	unsigned wimg : 4;       /**< Access control */
+	unsigned reserved1 : 1;
+	unsigned pp : 2;         /**< Page protection */
+} phte_t;
+
+extern void pht_refill(bool data, istate_t *istate);
+extern void pht_init(void);
 
 #endif /* __ASM__ */
Index: arch/ppc32/include/mm/tlb.h
===================================================================
--- arch/ppc32/include/mm/tlb.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/mm/tlb.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -30,25 +30,4 @@
 #define __ppc32_TLB_H__
 
-#include <arch/exception.h>
-#include <typedefs.h>
-
-#define PHT_BITS	16
-#define PHT_ORDER	4
-
-typedef struct {
-	unsigned v : 1;          /**< Valid */
-	unsigned vsid : 24;      /**< Virtual Segment ID */
-	unsigned h : 1;          /**< Primary/secondary hash */
-	unsigned api : 6;        /**< Abbreviated Page Index */
-	unsigned rpn : 20;       /**< Real Page Number */
-	unsigned reserved0 : 3;
-	unsigned r : 1;          /**< Reference */
-	unsigned c : 1;          /**< Change */
-	unsigned wimg : 4;       /**< Access control */
-	unsigned reserved1 : 1;
-	unsigned pp : 2;         /**< Page protection */
-} phte_t;
-
-extern void pht_refill(bool data, istate_t *istate);
 
 #endif
Index: arch/ppc32/include/types.h
===================================================================
--- arch/ppc32/include/types.h	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/include/types.h	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -53,4 +53,5 @@
 	unsigned p : 1;       /**< Present bit. */
 	unsigned a : 1;       /**< Accessed bit. */
+	unsigned g : 1;       /**< Global bit. */
 	unsigned valid : 1;   /**< Valid content even if not present. */
 	unsigned pfn : 20;    /**< Physical frame number. */
Index: arch/ppc32/src/asm.S
===================================================================
--- arch/ppc32/src/asm.S	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/src/asm.S	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -34,4 +34,5 @@
 .global iret
 .global iret_syscall
+.global invalidate_bat
 .global memsetb
 .global memcpy
@@ -194,4 +195,36 @@
 	rfi
 	
+invalidate_bat:
+	
+	# invalidate block address translation registers
+	
+	li r14, 0
+	
+	mtspr ibat0u, r14
+	mtspr ibat0l, r14
+	
+	mtspr ibat1u, r14
+	mtspr ibat1l, r14
+	
+	mtspr ibat2u, r14
+	mtspr ibat2l, r14
+	
+	mtspr ibat3u, r14
+	mtspr ibat3l, r14
+	
+	mtspr dbat0u, r14
+	mtspr dbat0l, r14
+	
+	mtspr dbat1u, r14
+	mtspr dbat1l, r14
+	
+	mtspr dbat2u, r14
+	mtspr dbat2l, r14
+	
+	mtspr dbat3u, r14
+	mtspr dbat3l, r14
+	
+	blr
+	
 memsetb:
 	rlwimi r5, r5, 8, 16, 23
Index: arch/ppc32/src/mm/page.c
===================================================================
--- arch/ppc32/src/mm/page.c	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/src/mm/page.c	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -30,10 +30,235 @@
 #include <genarch/mm/page_pt.h>
 #include <arch/mm/frame.h>
+#include <arch/asm.h>
 #include <mm/frame.h>
 #include <mm/page.h>
+#include <mm/as.h>
+#include <arch.h>
 #include <arch/types.h>
+#include <arch/exception.h>
+#include <config.h>
+#include <print.h>
+#include <symtab.h>
+
+static phte_t *phte;
+
+
+/** Try to find PTE for faulting address
+ *
+ * Try to find PTE for faulting address.
+ * The AS->lock must be held on entry to this function.
+ *
+ * @param badvaddr Faulting virtual address.
+ * @param istate Pointer to interrupted state.
+ * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
+ * @return         PTE on success, NULL otherwise.
+ *
+ */
+static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
+{
+	/*
+	 * Check if the mapping exists in page tables.
+	 */	
+	pte_t *pte = page_mapping_find(AS, badvaddr);
+	if ((pte) && (pte->p)) {
+		/*
+		 * Mapping found in page tables.
+		 * Immediately succeed.
+		 */
+		return pte;
+	} else {
+		int rc;
+	
+		/*
+		 * Mapping not found in page tables.
+		 * Resort to higher-level page fault handler.
+		 */
+		page_table_unlock(AS, true);
+		switch (rc = as_page_fault(badvaddr, istate)) {
+			case AS_PF_OK:
+				/*
+				 * The higher-level page fault handler succeeded,
+				 * The mapping ought to be in place.
+				 */
+				page_table_lock(AS, true);
+				pte = page_mapping_find(AS, badvaddr);
+				ASSERT((pte) && (pte->p));
+				return pte;
+			case AS_PF_DEFER:
+				page_table_lock(AS, true);
+				*pfcr = rc;
+				return NULL;
+			case AS_PF_FAULT:
+				page_table_lock(AS, true);
+				printf("Page fault.\n");
+				*pfcr = rc;
+				return NULL;
+			default:
+				panic("unexpected rc (%d)\n", rc);
+		}	
+	}
+}
+
+
+static void pht_refill_fail(__address badvaddr, istate_t *istate)
+{
+	char *symbol = "";
+	char *sym2 = "";
+
+	char *s = get_symtab_entry(istate->pc);
+	if (s)
+		symbol = s;
+	s = get_symtab_entry(istate->lr);
+	if (s)
+		sym2 = s;
+	panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
+}
+
+static void pht_insert(const __address vaddr, const pfn_t pfn)
+{
+	__u32 page = (vaddr >> 12) & 0xffff;
+	__u32 api = (vaddr >> 22) & 0x3f;
+	__u32 vsid;
+	
+	asm volatile (
+		"mfsrin %0, %1\n"
+		: "=r" (vsid)
+		: "r" (vaddr)
+	);
+	
+	/* Primary hash (xor) */
+	__u32 hash = ((vsid ^ page) & 0x3ff) << 3;
+	
+	__u32 i;
+	/* Find unused PTE in PTEG */
+	for (i = 0; i < 8; i++) {
+		if (!phte[hash + i].v)
+			break;
+	}
+	
+	// TODO: Check access/change bits, secondary hash
+	
+	if (i == 8) 
+		i = page % 8;
+	
+	phte[hash + i].v = 1;
+	phte[hash + i].vsid = vsid;
+	phte[hash + i].h = 0;
+	phte[hash + i].api = api;
+	phte[hash + i].rpn = pfn;
+	phte[hash + i].r = 0;
+	phte[hash + i].c = 0;
+	phte[hash + i].pp = 2; // FIXME
+}
+
+
+/** Process Instruction/Data Storage Interrupt
+ *
+ * @param data   True if Data Storage Interrupt.
+ * @param istate Interrupted register context.
+ *
+ */
+void pht_refill(bool data, istate_t *istate)
+{
+	asid_t asid;
+	__address badvaddr;
+	pte_t *pte;
+	
+	int pfcr;
+	
+	if (data) {
+		asm volatile (
+			"mfdar %0\n"
+			: "=r" (badvaddr)
+		);
+	} else
+		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);
+	if (!pte) {
+		switch (pfcr) {
+		case AS_PF_FAULT:
+			goto fail;
+			break;
+		case AS_PF_DEFER:
+			/*
+		 	 * The page fault came during copy_from_uspace()
+			 * or copy_to_uspace().
+			 */
+			page_table_unlock(AS, true);
+			return;
+		default:
+			panic("Unexpected pfrc (%d)\n", pfcr);
+			break;
+		}
+	}
+	
+	pte->a = 1; /* Record access to PTE */
+	pht_insert(badvaddr, pte->pfn);
+	
+	page_table_unlock(AS, true);
+	return;
+	
+fail:
+	page_table_unlock(AS, true);
+	pht_refill_fail(badvaddr, istate);
+}
+
+
+void pht_init(void)
+{
+	memsetb((__address) phte, 1 << PHT_BITS, 0);
+	
+	/* Insert global kernel mapping */
+	
+	__address cur;
+	for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
+		pte_t *pte = page_mapping_find(AS_KERNEL, PA2KA(cur));
+		if ((pte) && (pte->p) && (pte->g))
+			pht_insert(PA2KA(cur), pte->pfn);
+	}
+}
+
 
 void page_arch_init(void)
 {
-	page_mapping_operations = &pt_mapping_operations;
-}
+	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 */
+		phte_t *physical_phte = (phte_t *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC));
+		phte = (phte_t *) PA2KA((__address) physical_phte);
+		
+		ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0);
+		pht_init();
+		
+		asm volatile (
+			"mtsdr1 %0\n"
+			:
+			: "r" ((__address) physical_phte)
+		);
+		
+		/* Invalidate block address translation registers,
+		   thus remove the temporary mapping */
+//		invalidate_bat();
+	}
+}
Index: arch/ppc32/src/mm/tlb.c
===================================================================
--- arch/ppc32/src/mm/tlb.c	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/src/mm/tlb.c	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -27,16 +27,5 @@
  */
 
-#include <arch/mm/tlb.h>
-#include <arch/types.h>
 #include <mm/tlb.h>
-#include <mm/frame.h>
-#include <mm/page.h>
-#include <mm/as.h>
-#include <arch.h>
-#include <print.h>
-#include <symtab.h>
-
-
-static phte_t *phte;
 
 
@@ -48,186 +37,7 @@
 void tlb_arch_init(void)
 {
-	phte_t *physical_phte = (phte_t *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC));
-	phte =(phte_t *) PA2KA((__address) physical_phte);
-	
-	ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0);
-	
-	memsetb((__address) phte, 1 << PHT_BITS, 0);
-	
 	asm volatile (
-		"mtsdr1 %0\n"
-		:
-		: "r" ((__address) physical_phte)
+		"tlbia\n"
 	);
-}
-
-
-/** Try to find PTE for faulting address
- *
- * Try to find PTE for faulting address.
- * The AS->lock must be held on entry to this function.
- *
- * @param badvaddr Faulting virtual address.
- * @param istate Pointer to interrupted state.
- * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
- * @return         PTE on success, NULL otherwise.
- *
- */
-static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
-{
-	/*
-	 * Check if the mapping exists in page tables.
-	 */	
-	pte_t *pte = page_mapping_find(AS, badvaddr);
-	if ((pte) && (pte->p)) {
-		/*
-		 * Mapping found in page tables.
-		 * Immediately succeed.
-		 */
-		return pte;
-	} else {
-		int rc;
-	
-		/*
-		 * Mapping not found in page tables.
-		 * Resort to higher-level page fault handler.
-		 */
-		page_table_unlock(AS, true);
-		switch (rc = as_page_fault(badvaddr, istate)) {
-		case AS_PF_OK:
-			/*
-			 * The higher-level page fault handler succeeded,
-			 * The mapping ought to be in place.
-			 */
-			page_table_lock(AS, true);
-			pte = page_mapping_find(AS, badvaddr);
-			ASSERT((pte) && (pte->p));
-			return pte;
-			break;
-		case AS_PF_DEFER:
-			page_table_lock(AS, true);
-			*pfcr = rc;
-			return NULL;
-			break;
-		case AS_PF_FAULT:
-			page_table_lock(AS, true);
-			printf("Page fault.\n");
-			*pfcr = rc;
-			return NULL;
-			break;
-		default:
-			panic("unexpected rc (%d)\n", rc);
-			break;
-		}	
-	}
-}
-
-
-static void pht_refill_fail(__address badvaddr, istate_t *istate)
-{
-	char *symbol = "";
-	char *sym2 = "";
-
-	char *s = get_symtab_entry(istate->pc);
-	if (s)
-		symbol = s;
-	s = get_symtab_entry(istate->lr);
-	if (s)
-		sym2 = s;
-	panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
-}
-
-
-/** Process Instruction/Data Storage Interrupt
- *
- * @param data   True if Data Storage Interrupt.
- * @param istate Interrupted register context.
- *
- */
-void pht_refill(bool data, istate_t *istate)
-{
-	asid_t asid;
-	__address badvaddr;
-	pte_t *pte;
-	__u32 page;
-	__u32 api;
-	__u32 vsid;
-	__u32 hash;
-	__u32 i;
-	int pfcr;
-	
-	if (data) {
-		asm volatile (
-			"mfdar %0\n"
-			: "=r" (badvaddr)
-		);
-	} else
-		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);
-	if (!pte) {
-		switch (pfcr) {
-		case AS_PF_FAULT:
-			goto fail;
-			break;
-		case AS_PF_DEFER:
-			/*
-		 	 * The page fault came during copy_from_uspace()
-			 * or copy_to_uspace().
-			 */
-			page_table_unlock(AS, true);
-			return;
-		default:
-			panic("Unexpected pfrc (%d)\n", pfcr);
-			break;
-		}
-	}
-
-	/* Record access to PTE */
-	pte->a = 1;
-	
-	page = (badvaddr >> 12) & 0xffff;
-	api = (badvaddr >> 22) & 0x3f;
-	asm volatile (
-		"mfsrin %0, %1\n"
-		: "=r" (vsid)
-		: "r" (badvaddr)
-	);
-	
-	/* Primary hash (xor) */
-	hash = ((vsid ^ page) & 0x3ff) << 3;
-	
-	/* Find invalid PTE in PTEG */
-	for (i = 0; i < 8; i++) {
-		if (!phte[hash + i].v)
-			break;
-	}
-	
-	// TODO: Check access/change bits, secondary hash
-	
-	if (i == 8)
-		i = page % 8;
-	
-	phte[hash + i].v = 1;
-	phte[hash + i].vsid = vsid;
-	phte[hash + i].h = 0;
-	phte[hash + i].api = api;
-	phte[hash + i].rpn = pte->pfn;
-	phte[hash + i].r = 0;
-	phte[hash + i].c = 0;
-	phte[hash + i].pp = 2; // FIXME
-	
-	page_table_unlock(AS, true);
-	return;
-	
-fail:
-	page_table_unlock(AS, true);
-	pht_refill_fail(badvaddr, istate);
 }
 
@@ -235,9 +45,4 @@
 void tlb_invalidate_all(void)
 {
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	memsetb((__address) phte, 1 << PHT_BITS, 0);
-	interrupts_restore(ipl);
 }
 
Index: arch/ppc32/src/ppc32.c
===================================================================
--- arch/ppc32/src/ppc32.c	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/src/ppc32.c	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -29,8 +29,8 @@
 #include <arch.h>
 #include <arch/boot/boot.h>
-#include <arch/console.h>
 #include <arch/drivers/cuda.h>
 #include <arch/mm/memory_init.h>
 #include <arch/interrupt.h>
+#include <genarch/fb/fb.h>
 #include <userspace.h>
 #include <proc/uarg.h>
@@ -68,6 +68,4 @@
 		/* Merge all zones to 1 big zone */
 		zone_merge_all();
-		
-		ppc32_console_register();
 	}
 }
Index: arch/ppc32/src/proc/scheduler.c
===================================================================
--- arch/ppc32/src/proc/scheduler.c	(revision 8424198577d06b5b35db73507a7a328cd146a2c5)
+++ arch/ppc32/src/proc/scheduler.c	(revision 35f3b8c44766ef68bd672f9ab14503759d3d269a)
@@ -41,5 +41,5 @@
 void before_thread_runs_arch(void)
 {
-	tlb_invalidate_all();
+	pht_init();
 	asm volatile (
 		"mtsprg0 %0\n"
