Index: genarch/Makefile.inc
===================================================================
--- genarch/Makefile.inc	(revision 65fb232f572bc21a808b3769b83436d82fe4a950)
+++ genarch/Makefile.inc	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
@@ -38,2 +38,10 @@
 		genarch/src/acpi/matd.c
 endif
+ifeq ($(CONFIG_PAGE_PT),y)
+	GENARCH_SOURCES += \
+		genarch/src/mm/page_pt.c
+endif
+ifeq ($(CONFIG_PAGE_HT),y)
+	GENARCH_SOURCES += \
+		genarch/src/mm/page_ht.c
+endif
Index: genarch/include/mm/page_ht.h
===================================================================
--- genarch/include/mm/page_ht.h	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
+++ genarch/include/mm/page_ht.h	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+/*
+ * This is the generic page hash table interface.
+ */
+
+#ifndef __PAGE_HT_H__
+#define __PAGE_HT_H__
+
+#include <mm/page.h>
+
+extern page_operations_t page_ht_operations;
+
+#endif
Index: genarch/include/mm/page_pt.h
===================================================================
--- genarch/include/mm/page_pt.h	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
+++ genarch/include/mm/page_pt.h	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+/*
+ * This is the generic 4-level page table interface.
+ * Architectures that use hierarchical page tables
+ * are supposed to implement *_ARCH macros.
+ */
+
+#ifndef __PAGE_PT_H__
+#define __PAGE_PT_H__
+
+#include <arch/types.h>
+#include <typedefs.h>
+#include <mm/page.h>
+
+/*
+ * These macros process vaddr and extract those portions
+ * of it that function as indices to respective page tables.
+ */
+#define PTL0_INDEX(vaddr)		PTL0_INDEX_ARCH(vaddr)
+#define PTL1_INDEX(vaddr)		PTL1_INDEX_ARCH(vaddr)
+#define PTL2_INDEX(vaddr)		PTL2_INDEX_ARCH(vaddr)
+#define PTL3_INDEX(vaddr)		PTL3_INDEX_ARCH(vaddr)
+
+#define GET_PTL0_ADDRESS()		GET_PTL0_ADDRESS_ARCH()
+#define SET_PTL0_ADDRESS(ptl0)		SET_PTL0_ADDRESS_ARCH(ptl0)
+
+/*
+ * These macros traverse the 4-level tree of page tables,
+ * each descending by one level.
+ */
+#define GET_PTL1_ADDRESS(ptl0, i)	GET_PTL1_ADDRESS_ARCH(ptl0, i)
+#define GET_PTL2_ADDRESS(ptl1, i)	GET_PTL2_ADDRESS_ARCH(ptl1, i)
+#define GET_PTL3_ADDRESS(ptl2, i)	GET_PTL3_ADDRESS_ARCH(ptl2, i)
+#define GET_FRAME_ADDRESS(ptl3, i)	GET_FRAME_ADDRESS_ARCH(ptl3, i)
+
+/*
+ * These macros are provided to change shape of the 4-level
+ * tree of page tables on respective level.
+ */
+#define SET_PTL1_ADDRESS(ptl0, i, a)	SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
+#define SET_PTL2_ADDRESS(ptl1, i, a)	SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS(ptl2, i, a)	SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+#define SET_FRAME_ADDRESS(ptl3, i, a)	SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
+
+/*
+ * These macros are provided to query various flags within the page tables.
+ */
+#define GET_PTL1_FLAGS(ptl0, i)		GET_PTL1_FLAGS_ARCH(ptl0, i)
+#define GET_PTL2_FLAGS(ptl1, i)		GET_PTL2_FLAGS_ARCH(ptl1, i)
+#define GET_PTL3_FLAGS(ptl2, i)		GET_PTL3_FLAGS_ARCH(ptl2, i)
+#define GET_FRAME_FLAGS(ptl3, i)	GET_FRAME_FLAGS_ARCH(ptl3, i)
+
+/*
+ * These macros are provided to set/clear various flags within the page tables.
+ */
+#define SET_PTL1_FLAGS(ptl0, i, x)	SET_PTL1_FLAGS_ARCH(ptl0, i, x)
+#define SET_PTL2_FLAGS(ptl1, i, x)	SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS(ptl2, i, x)	SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS(ptl3, i, x)	SET_FRAME_FLAGS_ARCH(ptl3, i, x)
+
+extern page_operations_t page_pt_operations;
+
+extern void page_mapping_insert_pt(__address page, __address frame, int flags, __address root);
+extern pte_t *page_mapping_find_pt(__address page, __address root);
+
+#endif
Index: genarch/src/mm/page_ht.c
===================================================================
--- genarch/src/mm/page_ht.c	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
+++ genarch/src/mm/page_ht.c	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+#include <genarch/mm/page_ht.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <arch/asm.h>
+
+static void ht_mapping_insert(__address page, __address frame, int flags, __address root);
+static pte_t *ht_mapping_find(__address page, __address root);
+
+page_operations_t page_ht_operations = {
+	.mapping_insert = ht_mapping_insert,
+	.mapping_find = ht_mapping_find
+};
+
+/** Map page to frame using page hash table.
+ *
+ * Map virtual address 'page' to physical address 'frame'
+ * using 'flags'.
+ *
+ * @param page Virtual address of the page to be mapped.
+ * @param frame Physical address of memory frame to which the mapping is done.
+ * @param flags Flags to be used for mapping.
+ * @param root Explicit PTL0 address.
+ */
+void ht_mapping_insert(__address page, __address frame, int flags, __address root)
+{
+}
+
+/** Find mapping for virtual page in page hash table.
+ *
+ * Find mapping for virtual page.
+ *
+ * @param page Virtual page.
+ * @param root PTL0 address if non-zero.
+ *
+ * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
+ */
+pte_t *ht_mapping_find(__address page, __address root)
+{
+	return NULL;
+}
Index: genarch/src/mm/page_pt.c
===================================================================
--- genarch/src/mm/page_pt.c	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
+++ genarch/src/mm/page_pt.c	(revision 1a675955a140a3b614cb1280dfa395e1f3f1a12a)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+#include <genarch/mm/page_pt.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+#include <arch/mm/page.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <arch/asm.h>
+#include <memstr.h>
+
+static void pt_mapping_insert(__address page, __address frame, int flags, __address root);
+static pte_t *pt_mapping_find(__address page, __address root);
+
+page_operations_t page_pt_operations = {
+	.mapping_insert = pt_mapping_insert,
+	.mapping_find = pt_mapping_find
+};
+
+/** Map page to frame using hierarchical page tables.
+ *
+ * Map virtual address 'page' to physical address 'frame'
+ * using 'flags'.
+ *
+ * @param page Virtual address of the page to be mapped.
+ * @param frame Physical address of memory frame to which the mapping is done.
+ * @param flags Flags to be used for mapping.
+ * @param root Explicit PTL0 address.
+ */
+void pt_mapping_insert(__address page, __address frame, int flags, __address root)
+{
+	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
+	__address newpt;
+
+	ptl0 = (pte_t *) PA2KA(root ? root : (__address) GET_PTL0_ADDRESS());
+
+	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		memsetb(newpt, PAGE_SIZE, 0);
+		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
+		SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
+	}
+
+	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
+
+	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		memsetb(newpt, PAGE_SIZE, 0);
+		SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
+		SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
+	}
+
+	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
+
+	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		memsetb(newpt, PAGE_SIZE, 0);
+		SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
+		SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
+	}
+
+	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+
+	SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
+	SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
+}
+
+/** Find mapping for virtual page in hierarchical page tables.
+ *
+ * Find mapping for virtual page.
+ *
+ * @param page Virtual page.
+ * @param root PTL0 address if non-zero.
+ *
+ * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
+ */
+pte_t *pt_mapping_find(__address page, __address root)
+{
+	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
+
+	ptl0 = (pte_t *) PA2KA(root ? root : (__address) GET_PTL0_ADDRESS());
+
+	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
+
+	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
+
+	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+
+	return &ptl3[PTL3_INDEX(page)];
+}
