Index: kernel/arch/ppc32/include/interrupt.h
===================================================================
--- kernel/arch/ppc32/include/interrupt.h	(revision f10edaebe31d7bce0bfacfed6cbed28895b60acf)
+++ kernel/arch/ppc32/include/interrupt.h	(revision 9c75782060ff62e5868fdca2b26e311fe5e9be29)
@@ -45,4 +45,7 @@
 #define VECTOR_EXTERNAL             4
 #define VECTOR_DECREMENTER          8
+#define VECTOR_ITLB_MISS            13
+#define VECTOR_DTLB_MISS_LOAD       14
+#define VECTOR_DTLB_MISS_STORE      15
 
 extern void start_decrementer(void);
Index: kernel/arch/ppc32/include/mm/tlb.h
===================================================================
--- kernel/arch/ppc32/include/mm/tlb.h	(revision f10edaebe31d7bce0bfacfed6cbed28895b60acf)
+++ kernel/arch/ppc32/include/mm/tlb.h	(revision 9c75782060ff62e5868fdca2b26e311fe5e9be29)
@@ -77,9 +77,5 @@
 extern void pht_init(void);
 extern void pht_refill(unsigned int, istate_t *);
-
-extern bool pht_refill_real(unsigned int, istate_t *)
-    __attribute__ ((section("K_UNMAPPED_TEXT_START")));
-extern void tlb_refill_real(unsigned int, uint32_t, ptehi_t, ptelo_t,
-    istate_t *) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
+extern void tlb_refill(unsigned int, istate_t *);
 
 #endif
Index: kernel/arch/ppc32/src/exception.S
===================================================================
--- kernel/arch/ppc32/src/exception.S	(revision f10edaebe31d7bce0bfacfed6cbed28895b60acf)
+++ kernel/arch/ppc32/src/exception.S	(revision 9c75782060ff62e5868fdca2b26e311fe5e9be29)
@@ -142,5 +142,6 @@
 	CONTEXT_STORE
 	
-	b data_storage
+	li r3, 2
+	b jump_to_kernel
 
 .org 0x400
@@ -149,5 +150,6 @@
 	CONTEXT_STORE
 	
-	b instruction_storage
+	li r3, 3
+	b jump_to_kernel
 
 .org 0x500
@@ -227,5 +229,6 @@
 	CONTEXT_STORE
 	
-	b tlb_miss
+	li r3, 13
+	b jump_to_kernel
 
 .org 0x1100
@@ -234,5 +237,6 @@
 	CONTEXT_STORE
 	
-	b tlb_miss
+	li r3, 14
+	b jump_to_kernel
 
 .org 0x1200
@@ -241,42 +245,8 @@
 	CONTEXT_STORE
 	
-	b tlb_miss
+	li r3, 15
+	b jump_to_kernel
 
 .org 0x4000
-data_storage:
-	li r3, 2
-	mr r4, sp
-	addi r4, r4, 8
-	bl pht_refill_real
-	
-	cmpwi r3, 0
-	bne iret_real
-	
-	li r3, 2
-	b jump_to_kernel
-
-instruction_storage:
-	li r3, 3
-	mr r4, sp
-	addi r4, r4, 8
-	bl pht_refill_real
-	
-	cmpwi r3, 0
-	bne iret_real
-	
-	li r3, 3
-	b jump_to_kernel
-
-tlb_miss:
-	li r3, 16
-	mfspr r4, tlbmiss
-	mfspr r5, ptehi
-	mfspr r6, ptelo
-	mr r7, sp
-	addi r7, r7, 20
-	
-	bl tlb_refill_real
-	b iret_real
-
 jump_to_kernel:
 	lis r12, iret@ha
@@ -313,57 +283,2 @@
 	addis sp, sp, 0x8000
 	rfi
-
-iret_real:
-	lwz r0, 8(sp)
-	lwz r2, 12(sp)
-	lwz r3, 16(sp)
-	lwz r4, 20(sp)
-	lwz r5, 24(sp)
-	lwz r6, 28(sp)
-	lwz r7, 32(sp)
-	lwz r8, 36(sp)
-	lwz r9, 40(sp)
-	lwz r10, 44(sp)
-	lwz r11, 48(sp)
-	lwz r13, 52(sp)
-	lwz r14, 56(sp)
-	lwz r15, 60(sp)
-	lwz r16, 64(sp)
-	lwz r17, 68(sp)
-	lwz r18, 72(sp)
-	lwz r19, 76(sp)
-	lwz r20, 80(sp)
-	lwz r21, 84(sp)
-	lwz r22, 88(sp)
-	lwz r23, 92(sp)
-	lwz r24, 96(sp)
-	lwz r25, 100(sp)
-	lwz r26, 104(sp)
-	lwz r27, 108(sp)
-	lwz r28, 112(sp)
-	lwz r29, 116(sp)
-	lwz r30, 120(sp)
-	lwz r31, 124(sp)
-	
-	lwz r12, 128(sp)
-	mtcr r12
-	
-	lwz r12, 132(sp)
-	mtsrr0 r12
-	
-	lwz r12, 136(sp)
-	mtsrr1 r12
-	
-	lwz r12, 140(sp)
-	mtlr r12
-	
-	lwz r12, 144(sp)
-	mtctr r12
-	
-	lwz r12, 148(sp)
-	mtxer r12
-	
-	lwz r12, 156(sp)
-	lwz sp, 160(sp)
-	
-	rfi
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision f10edaebe31d7bce0bfacfed6cbed28895b60acf)
+++ kernel/arch/ppc32/src/interrupt.c	(revision 9c75782060ff62e5868fdca2b26e311fe5e9be29)
@@ -153,4 +153,10 @@
 	exc_register(VECTOR_DECREMENTER, "timer", true,
 	    exception_decrementer);
+	exc_register(VECTOR_ITLB_MISS, "itlb_miss", true,
+	    tlb_refill);
+	exc_register(VECTOR_DTLB_MISS_LOAD, "dtlb_miss_load", true,
+	    tlb_refill);
+	exc_register(VECTOR_DTLB_MISS_STORE, "dtlb_miss_store", true,
+	    tlb_refill);
 }
 
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision f10edaebe31d7bce0bfacfed6cbed28895b60acf)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision 9c75782060ff62e5868fdca2b26e311fe5e9be29)
@@ -44,7 +44,5 @@
 #include <symtab.h>
 
-static unsigned int seed = 10;
-static unsigned int seed_real
-    __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
+static unsigned int seed = 42;
 
 /** Try to find PTE for faulting address
@@ -251,119 +249,19 @@
 }
 
-/** Process Instruction/Data Storage Exception in Real Mode
- *
- * @param n      Exception vector number.
- * @param istate Interrupted register context.
- *
- */
-bool pht_refill_real(unsigned int n, istate_t *istate)
-{
-	uintptr_t badvaddr;
-	
-	if (n == VECTOR_DATA_STORAGE)
-		badvaddr = istate->dar;
-	else
-		badvaddr = istate->pc;
-	
-	uint32_t physmem = physmem_top();
-	
-	if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
-		return false;
-	
-	uint32_t page = (badvaddr >> 12) & 0xffff;
-	uint32_t api = (badvaddr >> 22) & 0x3f;
-	
-	uint32_t vsid = sr_get(badvaddr);
-	uint32_t sdr1 = sdr1_get();
-	
-	// FIXME: compute size of PHT exactly
-	phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
-	
-	/* Primary hash (xor) */
-	uint32_t h = 0;
-	uint32_t hash = vsid ^ page;
-	uint32_t base = (hash & 0x3ff) << 3;
-	uint32_t i;
-	bool found = false;
-	
-	/* Find colliding PTE in PTEG */
-	for (i = 0; i < 8; i++) {
-		if ((phte_real[base + i].v)
-		    && (phte_real[base + i].vsid == vsid)
-		    && (phte_real[base + i].api == api)
-		    && (phte_real[base + i].h == 0)) {
-			found = true;
-			break;
-		}
-	}
-	
-	if (!found) {
-		/* Find unused PTE in PTEG */
-		for (i = 0; i < 8; i++) {
-			if (!phte_real[base + i].v) {
-				found = true;
-				break;
-			}
-		}
-	}
-	
-	if (!found) {
-		/* Secondary hash (not) */
-		uint32_t base2 = (~hash & 0x3ff) << 3;
-		
-		/* Find colliding PTE in PTEG */
-		for (i = 0; i < 8; i++) {
-			if ((phte_real[base2 + i].v)
-			    && (phte_real[base2 + i].vsid == vsid)
-			    && (phte_real[base2 + i].api == api)
-			    && (phte_real[base2 + i].h == 1)) {
-				found = true;
-				base = base2;
-				h = 1;
-				break;
-			}
-		}
-		
-		if (!found) {
-			/* Find unused PTE in PTEG */
-			for (i = 0; i < 8; i++) {
-				if (!phte_real[base2 + i].v) {
-					found = true;
-					base = base2;
-					h = 1;
-					break;
-				}
-			}
-		}
-		
-		if (!found) {
-			/* Use secondary hash to avoid collisions
-			   with usual PHT refill handler. */
-			i = RANDI(seed_real) % 8;
-			base = base2;
-			h = 1;
-		}
-	}
-	
-	phte_real[base + i].v = 1;
-	phte_real[base + i].vsid = vsid;
-	phte_real[base + i].h = h;
-	phte_real[base + i].api = api;
-	phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
-	phte_real[base + i].r = 0;
-	phte_real[base + i].c = 0;
-	phte_real[base + i].wimg = 0;
-	phte_real[base + i].pp = 2; // FIXME
-	
-	return true;
-}
-
-/** Process ITLB/DTLB Miss Exception in Real Mode
- *
- *
- */
-void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi,
-    ptelo_t ptelo, istate_t *istate)
-{
+void tlb_refill(unsigned int n, istate_t *istate)
+{
+	uint32_t tlbmiss;
+	ptehi_t ptehi;
+	ptelo_t ptelo;
+	
+	asm volatile (
+		"mfspr %[tlbmiss], 980\n"
+		"mfspr %[ptehi], 981\n"
+		"mfspr %[ptelo], 982\n"
+		: [tlbmiss] "=r" (tlbmiss),
+		  [ptehi] "=r" (ptehi),
+		  [ptelo] "=r" (ptelo)
+	);
+	
 	uint32_t badvaddr = tlbmiss & 0xfffffffc;
 	uint32_t physmem = physmem_top();
