Index: arch/ppc32/Makefile.inc
===================================================================
--- arch/ppc32/Makefile.inc	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/Makefile.inc	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -31,5 +31,5 @@
 
 BFD_NAME = elf32-powerpc
-BFD_ARCH = powerpc
+BFD_ARCH = powerpc:common
 BFD = binary
 TARGET = ppc-linux-gnu
@@ -79,3 +79,4 @@
 	arch/$(ARCH)/src/mm/frame.c \
 	arch/$(ARCH)/src/mm/memory_init.c \
-	arch/$(ARCH)/src/mm/page.c 
+	arch/$(ARCH)/src/mm/page.c  \
+	arch/$(ARCH)/src/mm/tlb.c 
Index: arch/ppc32/include/exception.h
===================================================================
--- arch/ppc32/include/exception.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
+++ arch/ppc32/include/exception.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2006 Martin Decky
+ * 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_EXCEPTION_H__
+#define __ppc32_EXCEPTION_H__
+
+#ifndef __ppc32_TYPES_H__
+#  include <arch/types.h>
+#endif
+
+#include <typedefs.h>
+
+struct istate {
+	__u32 r0;
+	__u32 r2;
+	__u32 r3;
+	__u32 r4;
+	__u32 r5;
+	__u32 r6;
+	__u32 r7;
+	__u32 r8;
+	__u32 r9;
+	__u32 r10;
+	__u32 r11;
+	__u32 r12;
+	__u32 r13;
+	__u32 r14;
+	__u32 r15;
+	__u32 r16;
+	__u32 r17;
+	__u32 r18;
+	__u32 r19;
+	__u32 r20;
+	__u32 r21;
+	__u32 r22;
+	__u32 r23;
+	__u32 r24;
+	__u32 r25;
+	__u32 r26;
+	__u32 r27;
+	__u32 r28;
+	__u32 r29;
+	__u32 r30;
+	__u32 r31;
+	__u32 pc;
+	__u32 srr1;
+	__u32 lr;
+	__u32 cr;
+	__u32 ctr;
+	__u32 xer;
+};
+
+#endif
Index: arch/ppc32/include/mm/asid.h
===================================================================
--- arch/ppc32/include/mm/asid.h	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/include/mm/asid.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -27,12 +27,18 @@
  */
 
-#ifndef __ppc32_ASID_H__
-#define __ppc32_ASID_H__
+/*
+ * ia32 has no hardware support for address space identifiers.
+ * This file is provided to do nop-implementation of mm/asid.h
+ * interface.
+ */
+
+#ifndef __ia32_ASID_H__
+#define __ia32_ASID_H__
 
 typedef int asid_t;
 
-#define ASID_MAX_ARCH	3
+#define ASID_MAX_ARCH		3
 
-#define asid_get()	(ASID_START+1)
+#define asid_get()		(ASID_START+1)
 
 #endif
Index: arch/ppc32/include/mm/frame.h
===================================================================
--- arch/ppc32/include/mm/frame.h	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/include/mm/frame.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -31,5 +31,5 @@
 
 #define FRAME_WIDTH		12	/* 4K */
-#define FRAME_SIZE		(1<<FRAME_WIDTH)
+#define FRAME_SIZE		(1 << FRAME_WIDTH)
 
 #ifdef KERNEL
Index: arch/ppc32/include/mm/page.h
===================================================================
--- arch/ppc32/include/mm/page.h	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/include/mm/page.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -45,39 +45,52 @@
 #endif
 
-#define PTL0_ENTRIES_ARCH		0
-#define PTL1_ENTRIES_ARCH		0
-#define PTL2_ENTRIES_ARCH		0
-#define PTL3_ENTRIES_ARCH		0
+/*
+ * Implementation of generic 4-level page table interface,
+ * the hardware Page Hash Table is used as cache.
+ *
+ * Page table layout:
+ * - 32-bit virtual addressess
+ * - Offset is 12 bits => pages are 4K long
+ * - PTL0 has 1024 entries (10 bits)
+ * - PTL1 is not used
+ * - PTL2 is not used
+ * - PLT3 has 1024 entries (10 bits)
+ */
 
-#define PTL0_INDEX_ARCH(vaddr)		0
-#define PTL1_INDEX_ARCH(vaddr)		0
-#define PTL2_INDEX_ARCH(vaddr)		0
-#define PTL3_INDEX_ARCH(vaddr)		0
+#define PTL0_ENTRIES_ARCH	1024
+#define PTL1_ENTRIES_ARCH	0
+#define PTL2_ENTRIES_ARCH	0
+#define PTL3_ENTRIES_ARCH	1024
+
+#define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
+#define PTL1_INDEX_ARCH(vaddr)	0
+#define PTL2_INDEX_ARCH(vaddr)	0
+#define PTL3_INDEX_ARCH(vaddr)	(((vaddr) >> 12) & 0x3ff)
 
 #define SET_PTL0_ADDRESS_ARCH(ptl0)
 
-#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		((pte_t *) 0)
-#define GET_PTL2_ADDRESS_ARCH(ptl1, i)		((pte_t *) 0)
-#define GET_PTL3_ADDRESS_ARCH(ptl2, i)		((pte_t *) 0)
-#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		((pte_t *) 0)
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		(((pte_t *) (ptl0))[(i)].pfn << 12)
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i)		(ptl1)
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i)		(ptl2)
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		(((pte_t *) (ptl3))[(i)].pfn << 12)
 
-#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)	(((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
-#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)	(((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
 
-#define GET_PTL1_FLAGS_ARCH(ptl0, i)		0
-#define GET_PTL2_FLAGS_ARCH(ptl1, i)		0
-#define GET_PTL3_FLAGS_ARCH(ptl2, i)		0
-#define GET_FRAME_FLAGS_ARCH(ptl3, i)		0
+#define GET_PTL1_FLAGS_ARCH(ptl0, i)		get_pt_flags((pte_t *) (ptl0), (index_t) (i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i)		PAGE_PRESENT
+#define GET_PTL3_FLAGS_ARCH(ptl2, i)		PAGE_PRESENT
+#define GET_FRAME_FLAGS_ARCH(ptl3, i)		get_pt_flags((pte_t *) (ptl3), (index_t) (i))
 
-#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)		set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
-#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)	set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
 
-#define PTE_VALID_ARCH(p)		1
-#define PTE_PRESENT_ARCH(p)		1
-#define PTE_GET_FRAME_ARCH(p)		0
+#define PTE_VALID_ARCH(pte)			(*((__u32 *) (pte)) != 0)
+#define PTE_PRESENT_ARCH(pte)		((pte)->p != 0)
+#define PTE_GET_FRAME_ARCH(pte)		((pte)->pfn << 12)
 
 #ifndef __ASM__
@@ -86,4 +99,26 @@
 #include <arch/mm/frame.h>
 #include <arch/types.h>
+
+static inline int get_pt_flags(pte_t *pt, index_t i)
+{
+	pte_t *p = &pt[i];
+	
+	return (
+		(1 << PAGE_CACHEABLE_SHIFT) |
+		((!p->p) << PAGE_PRESENT_SHIFT) |
+		(1 << PAGE_USER_SHIFT) |
+		(1 << PAGE_READ_SHIFT) |
+		(1 << PAGE_WRITE_SHIFT) |
+		(1 << PAGE_EXEC_SHIFT)
+	);
+}
+
+static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
+{
+	pte_t *p = &pt[i];
+	
+	p->p = !(flags & PAGE_NOT_PRESENT);
+	p->valid = 1;
+}
 
 extern void page_arch_init(void);
Index: arch/ppc32/include/mm/tlb.h
===================================================================
--- arch/ppc32/include/mm/tlb.h	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/include/mm/tlb.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -1,4 +1,4 @@
 /*
- * Copyright (C) 2005 Jakub Jermar
+ * Copyright (C) 2006 Martin Decky
  * All rights reserved.
  *
@@ -30,6 +30,8 @@
 #define __ppc32_TLB_H__
 
-#define tlb_arch_init()
-#define tlb_print()
+#include <arch/exception.h>
+#include <typedefs.h>
+
+extern void pht_refill(istate_t *istate);
 
 #endif
Index: arch/ppc32/include/types.h
===================================================================
--- arch/ppc32/include/types.h	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/include/types.h	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -49,5 +49,11 @@
 typedef __u32 __native;
 
-typedef __u32 pte_t;
+/** Page Table Entry. */
+typedef struct {
+	unsigned p : 1;       /**< Present bit. */
+	unsigned a : 1;       /**< Accessed bit. */
+	unsigned valid : 1;   /**< Valid content even if not present. */
+	unsigned pfn : 20;    /**< Physical frame number. */
+} pte_t;
 
 #endif
Index: arch/ppc32/src/exception.S
===================================================================
--- arch/ppc32/src/exception.S	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc32/src/exception.S	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -32,57 +32,5 @@
 .section K_UNMAPPED_TEXT_START, "ax"
 
-.org 0x100
-.global exc_system_reset
-exc_system_reset:
-	b exc_system_reset
-
-.org 0x200
-.global exc_machine_check
-exc_machine_check:
-	b exc_machine_check
-
-.org 0x300
-.global exc_data_storage
-exc_data_storage:
-	b exc_data_storage
-
-.org 0x380
-.global exc_data_segment
-exc_data_segment:
-	b exc_data_segment
-
-.org 0x400
-.global exc_instruction_storage
-exc_instruction_storage:
-	b exc_instruction_storage
-
-.org 0x480
-.global exc_instruction_segment
-exc_instruction_segment:
-	b exc_instruction_segment
-
-.org 0x500
-.global exc_external
-exc_external:
-	b exc_external
-
-.org 0x600
-.global exc_alignment
-exc_alignment:
-	b exc_alignment
-
-.org 0x700
-.global exc_program
-exc_program:
-	b exc_program
-
-.org 0x800
-.global exc_fp_unavailable
-exc_fp_unavailable:
-	b exc_fp_unavailable
-
-.org 0x900
-.global exc_decrementer
-exc_decrementer:
+.macro CONTEXT_STORE
 	mtspr sprg1, sp
 	
@@ -139,4 +87,70 @@
 	mfxer r3
 	stw r3, 144(sp)
+.endm
+
+.org 0x100
+.global exc_system_reset
+exc_system_reset:
+	b exc_system_reset
+
+.org 0x200
+.global exc_machine_check
+exc_machine_check:
+	b exc_machine_check
+
+.org 0x300
+.global exc_data_storage
+exc_data_storage:
+	CONTEXT_STORE
+
+	lis r3, pht_refill@ha
+	addi r3, r3, pht_refill@l
+	mtspr srr0, r3
+	
+	mfmsr r3
+	ori r3, r3, (msr_ir | msr_dr)@l
+	mtspr srr1, r3
+	
+	lis r3, iret@ha
+	addi r3, r3, iret@l
+	mtlr r3
+	
+	addis sp, sp, 0x8000
+	rfi
+
+.org 0x400
+.global exc_instruction_storage
+exc_instruction_storage:
+	b exc_instruction_storage
+
+.org 0x480
+.global exc_instruction_segment
+exc_instruction_segment:
+	b exc_instruction_segment
+
+.org 0x500
+.global exc_external
+exc_external:
+	b exc_external
+
+.org 0x600
+.global exc_alignment
+exc_alignment:
+	b exc_alignment
+
+.org 0x700
+.global exc_program
+exc_program:
+	b exc_program
+
+.org 0x800
+.global exc_fp_unavailable
+exc_fp_unavailable:
+	b exc_fp_unavailable
+
+.org 0x900
+.global exc_decrementer
+exc_decrementer:
+	CONTEXT_STORE	
 
 	lis r3, exc_dispatch@ha
Index: arch/ppc32/src/mm/tlb.c
===================================================================
--- arch/ppc32/src/mm/tlb.c	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
+++ arch/ppc32/src/mm/tlb.c	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2006 Martin Decky
+ * 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.
+ */
+
+#include <arch/mm/tlb.h>
+#include <arch/types.h>
+#include <mm/tlb.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <arch.h>
+#include <print.h>
+#include <symtab.h>
+
+
+/** Initialize Page Hash Table.
+ *
+ * Setup the Page Hash Table with no entries.
+ *
+ */
+void tlb_arch_init(void)
+{
+}
+
+
+/** 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.
+ * @return         PTE on success, NULL otherwise.
+ *
+ */
+static pte_t *find_mapping_and_check(__address badvaddr)
+{
+	/*
+	 * 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 {
+		/*
+		 * Mapping not found in page tables.
+		 * Resort to higher-level page fault handler.
+		 */
+		page_table_unlock(AS, true);
+		if (as_page_fault(badvaddr)) {
+			/*
+			 * 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;
+		} else {
+			page_table_lock(AS, true);
+			printf("Page fault.\n");
+			return NULL;
+		}
+		
+	}
+}
+
+
+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("%X: PHT Refill Exception at %X(%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
+}
+
+
+/** Process Data Storage Interrupt
+ *
+ * @param istate Interrupted register context.
+ *
+ */
+void pht_refill(istate_t *istate)
+{
+	asid_t asid;
+	__address badvaddr;
+	pte_t *pte;
+	
+	__asm__ volatile (
+		"mfdar %0\n"
+		: "=r" (badvaddr)
+	);
+	
+	spinlock_lock(&AS->lock);
+	asid = AS->asid;
+	spinlock_unlock(&AS->lock);
+	
+	page_table_lock(AS, true);
+	
+	pte = find_mapping_and_check(badvaddr);
+	if (!pte)
+		goto fail;
+
+	/*
+	 * Record access to PTE.
+	 */
+	pte->a = 1;
+	
+	// FIXME: Insert entry into PHT
+
+	page_table_unlock(AS, true);
+	return;
+	
+fail:
+	page_table_unlock(AS, true);
+	pht_refill_fail(badvaddr, istate);
+}
+
+
+/** Print contents of Page Hash Table. */
+void tlb_print(void)
+{
+}
Index: arch/ppc64/Makefile.inc
===================================================================
--- arch/ppc64/Makefile.inc	(revision c7c0b89b6e6a42abfe99e8cb5d3d5882ffdeac6e)
+++ arch/ppc64/Makefile.inc	(revision 613bc54e40bd66aec3da7e1b368afbcd6e8c6453)
@@ -31,8 +31,8 @@
 
 BFD_NAME = elf64-powerpc
-BFD_ARCH = powerpc
+BFD_ARCH = powerpc:common64
 BFD = binary
-TARGET = ppc-linux-gnu
-TOOLCHAIN_DIR = /usr/local/ppc/bin
+TARGET = ppc64-linux-gnu
+TOOLCHAIN_DIR = /usr/local/ppc64/bin
 
 ## Make some default assumptions
