Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ boot/arch/sparc64/loader/asm.S	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -115,4 +115,5 @@
 	 */
 	
+#if defined (SUN4U)
 	/*
 	 * US3 processors have a write-invalidate cache, so explicitly
@@ -128,5 +129,5 @@
 		call icache_flush
 		nop
-	
+#endif	
 	1:
 		membar #StoreStore
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ boot/arch/sparc64/loader/main.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -57,6 +57,6 @@
 #endif
 
-/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
-static uint8_t subarchitecture;
+/** UltraSPARC subarchitecture - 1 for US, 3 for US3, 0 for other */
+static uint8_t subarchitecture = 0;
 
 /**
@@ -69,4 +69,5 @@
 static void version_print(void)
 {
+	
 	printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\n"
 	    "Copyright (c) 2006 HelenOS project\n",
@@ -83,6 +84,50 @@
 #define US_IIIi_CODE   0x15
 
-/**
- * Sets the global variables "subarchitecture" and "mid_mask" to
+/* max. length of the "compatible" property of the root node */
+#define COMPATIBLE_PROP_MAXLEN	64
+
+/*
+ * HelenOS bootloader will use these constants to distinguish particular
+ * UltraSPARC architectures
+ */
+#define COMPATIBLE_SUN4U	10
+#define COMPATIBLE_SUN4V	20
+
+/** US architecture. COMPATIBLE_SUN4U for sun4v, COMPATIBLE_SUN4V for sun4u */
+static uint8_t architecture;
+
+/**
+ * Detects the UltraSPARC architecture (sun4u and sun4v currently supported)
+ * by inspecting the property called "compatible" in the OBP root node.
+ */
+static void detect_architecture(void)
+{
+	phandle root = ofw_find_device("/");
+	char compatible[COMPATIBLE_PROP_MAXLEN];
+
+	if (ofw_get_property(root, "compatible", compatible,
+			COMPATIBLE_PROP_MAXLEN) <= 0) {
+		printf("Unable to determine architecture, default: sun4u.\n");
+		architecture = COMPATIBLE_SUN4U;
+		return;
+	}
+
+	if (strcmp(compatible, "sun4v") == 0) {
+		architecture = COMPATIBLE_SUN4V;
+	} else {
+		/*
+	 	 * As not all sun4u machines have "sun4u" in their "compatible"
+ 	 	 * OBP property (e.g. Serengeti's OBP "compatible" property is
+ 	 	 * "SUNW,Serengeti"), we will by default fallback to sun4u if
+	 	 * an unknown value of the "compatible" property is encountered.
+ 		 */
+		architecture = COMPATIBLE_SUN4U;
+	}
+}
+
+
+/**
+ * Detects the subarchitecture (US, US3) of the sun4u
+ * processor. Sets the global variables "subarchitecture" and "mid_mask" to
  * correct values.
  */
@@ -109,15 +154,86 @@
 }
 
+/**
+ * Performs sun4u-specific initialization. The components are expected
+ * to be already copied and boot allocator initialized.
+ *
+ * @param base	kernel base virtual address
+ * @param top	virtual address above which the boot allocator
+ * 		can make allocations
+ */
+static void bootstrap_sun4u(void *base, unsigned int top)
+{
+	void *balloc_base;
+	/*
+  	 * Claim and map the physical memory for the boot allocator.
+  	 * Initialize the boot allocator.
+  	 */
+	balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
+	(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
+	    BALLOC_MAX_SIZE);
+	(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
+	    BALLOC_MAX_SIZE, -1);
+	balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
+	    (uintptr_t) balloc_base);
+	
+	printf("Setting up screens...");
+	ofw_setup_screens();
+	printf("done.\n");
+	
+	printf("Canonizing OpenFirmware device tree...");
+	bootinfo.ofw_root = ofw_tree_build();
+	printf("done.\n");
+	
+#ifdef CONFIG_AP
+	printf("Checking for secondary processors...");
+	if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
+		printf("Error: unable to get CPU properties\n");
+	printf("done.\n");
+#endif
+
+}
+
+/**
+ *  * Performs sun4v-specific initialization. The components are expected
+ *   * to be already copied and boot allocator initialized.
+ *    */
+static void bootstrap_sun4v(void)
+{
+	/*
+	 * When SILO booted, the OBP had established a virtual to physical
+	 * memory mapping. This mapping is not an identity (because the
+	 * physical memory starts on non-zero address) - this is not
+	 * surprising. But! The mapping even does not map virtual address
+	 * 0 onto the starting address of the physical memory, but onto an
+	 * address which is 0x400000 bytes higher. The reason is that the
+	 * OBP had already used the memory just at the beginning of the
+	 * physical memory, so that memory cannot be used by SILO (nor
+	 * bootloader). As for now, we solve it by a nasty workaround:
+	 * we pretend that the physical memory starts 0x400000 bytes further
+	 * than it actually does (and hence pretend that the physical memory
+	 * is 0x400000 bytes smaller). Of course, the value 0x400000 will most
+	 * probably depend on the machine and OBP version (the workaround now
+	 * works on Simics). A solution would be to inspect the "available"
+	 * property of the "/memory" node to find out which parts of memory
+	 * are used by OBP and redesign the algorithm of copying
+	 * kernel/init tasks/ramdisk from the bootable image to memory
+	 * (which we must do anyway because of issues with claiming the memory
+	 * on Serengeti).
+ 	 */
+	bootinfo.physmem_start += 0x400000;
+	bootinfo.memmap.zones[0].start += 0x400000;
+	bootinfo.memmap.zones[0].size -= 0x400000;
+	printf("The sun4v init finished.");
+}
+
+
 void bootstrap(void)
 {
 	void *base = (void *) KERNEL_VIRTUAL_ADDRESS;
-	void *balloc_base;
 	unsigned int top = 0;
 	unsigned int i;
 	unsigned int j;
 	
-	version_print();
-	
-	detect_subarchitecture();
+	detect_architecture();
 	init_components(components);
 	
@@ -260,30 +376,13 @@
 	printf("done.\n");
 	
-	/*
-	 * Claim and map the physical memory for the boot allocator.
-	 * Initialize the boot allocator.
-	 */
-	balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
-	(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
-	    BALLOC_MAX_SIZE);
-	(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
-	    BALLOC_MAX_SIZE, -1);
-	balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
-	    (uintptr_t) balloc_base);
-	
-	printf("Setting up screens...");
-	ofw_setup_screens();
-	printf("done.\n");
-	
-	printf("Canonizing OpenFirmware device tree...");
-	bootinfo.ofw_root = ofw_tree_build();
-	printf("done.\n");
-	
-#ifdef CONFIG_AP
-	printf("Checking for secondary processors...");
-	if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
-		printf("Error: unable to get CPU properties\n");
-	printf("done.\n");
-#endif
+	/* perform architecture-specific initialization */
+	if (architecture == COMPATIBLE_SUN4U) {
+		bootstrap_sun4u(base, top);
+	} else if (architecture == COMPATIBLE_SUN4V) {
+		bootstrap_sun4v();
+	} else {
+		printf("Unknown architecture.\n");
+		halt();
+	}
 	
 	printf("Booting the kernel...\n");
Index: defaults/sparc64/sun4v/Makefile.config
===================================================================
--- defaults/sparc64/sun4v/Makefile.config	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ defaults/sparc64/sun4v/Makefile.config	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -4,2 +4,4 @@
 # CPU type
 PROCESSOR = sun4v
+
+CONFIG_RD_EXTERNAL = n
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ kernel/arch/sparc64/Makefile.inc	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -46,12 +46,17 @@
 ifeq ($(PROCESSOR),us)
 	DEFS += -DUS
+	DEFS += -DSUN4U
+	USARCH = sun4u
 endif
 
 ifeq ($(PROCESSOR),us3)
 	DEFS += -DUS3
+	DEFS += -DSUN4U
+	USARCH = sun4u
 endif
 
 ifeq ($(PROCESSOR),sun4v)
 	DEFS += -DSUN4V
+	USARCH = sun4v
 #MH
 	DEFS += -DUS
@@ -68,9 +73,9 @@
 	arch/$(KARCH)/src/mm/as.c \
 	arch/$(KARCH)/src/mm/cache.S \
-	arch/$(KARCH)/src/mm/frame.c \
+	arch/$(KARCH)/src/mm/$(USARCH)/frame.c \
 	arch/$(KARCH)/src/mm/page.c \
-	arch/$(KARCH)/src/mm/tlb.c \
-	arch/$(KARCH)/src/sparc64.c \
-	arch/$(KARCH)/src/start.S \
+	arch/$(KARCH)/src/mm/$(USARCH)/tlb.c \
+	arch/$(KARCH)/src/$(USARCH)/sparc64.c \
+	arch/$(KARCH)/src/$(USARCH)/start.S \
 	arch/$(KARCH)/src/proc/scheduler.c \
 	arch/$(KARCH)/src/proc/thread.c \
Index: kernel/arch/sparc64/include/mm/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/frame.h	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ kernel/arch/sparc64/include/mm/frame.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -36,48 +36,8 @@
 #define KERN_sparc64_FRAME_H_
 
-/*
- * Page size supported by the MMU.
- * For 8K there is the nasty illegal virtual aliasing problem.
- * Therefore, the kernel uses 8K only internally on the TLB and TSB levels.
- */
-#define MMU_FRAME_WIDTH		13	/* 8K */
-#define MMU_FRAME_SIZE		(1 << MMU_FRAME_WIDTH)
-
-/*
- * Page size exported to the generic memory management subsystems.
- * This page size is not directly supported by the MMU, but we can emulate
- * each 16K page with a pair of adjacent 8K pages.
- */
-#define FRAME_WIDTH		14	/* 16K */
-#define FRAME_SIZE		(1 << FRAME_WIDTH)
-
-#ifdef KERNEL
-#ifndef __ASM__
-
-#include <arch/types.h>
-
-union frame_address {
-	uintptr_t address;
-	struct {
-#if defined (US)
-		unsigned : 23;
-		uint64_t pfn : 28;		/**< Physical Frame Number. */
-#elif defined (US3)
-		unsigned : 21;
-		uint64_t pfn : 30;		/**< Physical Frame Number. */
-#endif
-		unsigned offset : 13;		/**< Offset. */
-	} __attribute__ ((packed));
-};
-
-typedef union frame_address frame_address_t;
-
-extern uintptr_t last_frame;
-extern uintptr_t end_of_identity;
-
-extern void frame_arch_init(void);
-#define physmem_print()
-
-#endif
+#if defined (SUN4U)
+#include <arch/mm/sun4u/frame.h>
+#elif defined (SUN4V)
+#include <arch/mm/sun4v/frame.h>
 #endif
 
Index: kernel/arch/sparc64/include/mm/pagesize.h
===================================================================
--- kernel/arch/sparc64/include/mm/pagesize.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/pagesize.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2008 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_PAGESIZE_H
+#define KERN_sparc64_PAGESIZE_H
+
+/** Page sizes. */
+#define PAGESIZE_8K	0
+#define PAGESIZE_64K	1
+#define PAGESIZE_512K	2
+#define PAGESIZE_4M	3
+
+#endif
Index: kernel/arch/sparc64/include/mm/sun4u/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4u/frame.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4u/frame.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_SUN4U_FRAME_H_
+#define KERN_sparc64_SUN4U_FRAME_H_
+
+/*
+ * Page size supported by the MMU.
+ * For 8K there is the nasty illegal virtual aliasing problem.
+ * Therefore, the kernel uses 8K only internally on the TLB and TSB levels.
+ */
+#define MMU_FRAME_WIDTH		13	/* 8K */
+#define MMU_FRAME_SIZE		(1 << MMU_FRAME_WIDTH)
+
+/*
+ * Page size exported to the generic memory management subsystems.
+ * This page size is not directly supported by the MMU, but we can emulate
+ * each 16K page with a pair of adjacent 8K pages.
+ */
+#define FRAME_WIDTH		14	/* 16K */
+#define FRAME_SIZE		(1 << FRAME_WIDTH)
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+union frame_address {
+	uintptr_t address;
+	struct {
+#if defined (US)
+		unsigned : 23;
+		uint64_t pfn : 28;		/**< Physical Frame Number. */
+#elif defined (US3)
+		unsigned : 21;
+		uint64_t pfn : 30;		/**< Physical Frame Number. */
+#endif
+		unsigned offset : 13;		/**< Offset. */
+	} __attribute__ ((packed));
+};
+
+typedef union frame_address frame_address_t;
+
+extern uintptr_t last_frame;
+extern uintptr_t end_of_identity;
+
+extern void frame_arch_init(void);
+#define physmem_print()
+
+#endif
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/as.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/as.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/as.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2009 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_AS_H_
+#define KERN_sparc64_sun4v_AS_H_
+
+#include <arch/mm/tte.h>
+#include <arch/mm/tsb.h>
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	1
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x0000000000000000
+#define KERNEL_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xffffffffffffffff
+#define USER_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x0000000000000000
+#define USER_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xffffffffffffffff
+
+#define USTACK_ADDRESS_ARCH	(0xffffffffffffffffULL - (PAGE_SIZE - 1))
+
+#ifdef CONFIG_TSB
+
+/**
+ * TTE Tag.
+ *
+ * Even though for sun4v the format of the TSB Tag states that the context
+ * field has 16 bits, the T1 CPU still only supports 13-bit contexts and the
+ * three most significant bits are always zero. 
+ */
+typedef union tte_tag {
+	uint64_t value;
+	struct {
+		unsigned : 3;
+		unsigned context : 13;	/**< Software ASID. */
+		unsigned : 6;
+		uint64_t va_tag : 42;	/**< Virtual address bits <63:22>. */
+	} __attribute__ ((packed));
+} tte_tag_t;
+
+/** TSB entry. */
+typedef struct tsb_entry {
+	tte_tag_t tag;
+	tte_data_t data;
+} __attribute__ ((packed)) tsb_entry_t;
+
+typedef struct {
+	tsb_descr_t tsb_description;
+} as_arch_t;
+
+#else
+
+typedef struct {
+} as_arch_t;
+
+#endif /* CONFIG_TSB */
+
+#include <genarch/mm/as_ht.h>
+
+#ifdef CONFIG_TSB
+#include <arch/mm/tsb.h>
+#define as_invalidate_translation_cache(as, page, cnt) \
+	tsb_invalidate((as), (page), (cnt))
+#else
+#define as_invalidate_translation_cache(as, page, cnt)
+#endif
+
+extern void as_arch_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/frame.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/frame.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_SUN4V_FRAME_H_
+#define KERN_sparc64_SUN4V_FRAME_H_
+
+/*
+ * Page size supported by the MMU.
+ * For 8K there is the nasty illegal virtual aliasing problem.
+ * Therefore, the kernel uses 8K only internally on the TLB and TSB levels.
+ */
+#define MMU_FRAME_WIDTH		13	/* 8K */
+#define MMU_FRAME_SIZE		(1 << MMU_FRAME_WIDTH)
+
+/*
+ * Page size exported to the generic memory management subsystems.
+ * This page size is not directly supported by the MMU, but we can emulate
+ * each 16K page with a pair of adjacent 8K pages.
+ */
+#define FRAME_WIDTH		14	/* 16K */
+#define FRAME_SIZE		(1 << FRAME_WIDTH)
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+union frame_address {
+	uintptr_t address;
+	struct {
+#if defined (US)
+		unsigned : 23;
+		uint64_t pfn : 28;		/**< Physical Frame Number. */
+#elif defined (US3)
+		unsigned : 21;
+		uint64_t pfn : 30;		/**< Physical Frame Number. */
+#endif
+		unsigned offset : 13;		/**< Offset. */
+	} __attribute__ ((packed));
+};
+
+typedef union frame_address frame_address_t;
+
+extern uintptr_t last_frame;
+//MH
+//extern uintptr_t end_of_identity;
+
+extern void frame_arch_init(void);
+#define physmem_print()
+
+#endif
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/mmu.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2008 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_MMU_H_
+#define KERN_sparc64_sun4v_MMU_H_
+
+#define ASI_REAL			0x14	/**< MMU bypass ASI */
+
+#define VA_PRIMARY_CONTEXT_REG		0x8	/**< primary context register VA. */
+#define ASI_PRIMARY_CONTEXT_REG		0x21	/**< primary context register ASI. */
+ 
+#define VA_SECONDARY_CONTEXT_REG	0x10	/**< secondary context register VA. */
+#define ASI_SECONDARY_CONTEXT_REG	0x21	/**< secondary context register ASI. */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/page.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/page.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/page.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_PAGE_H_
+#define KERN_sparc64_sun4v_PAGE_H_
+
+#include <arch/mm/frame.h>
+
+#define MMU_PAGE_WIDTH	MMU_FRAME_WIDTH
+#define MMU_PAGE_SIZE	MMU_FRAME_SIZE
+
+#define PAGE_WIDTH	FRAME_WIDTH
+#define PAGE_SIZE	FRAME_SIZE
+
+#define MMU_PAGES_PER_PAGE	(1 << (PAGE_WIDTH - MMU_PAGE_WIDTH))
+
+#ifdef KERNEL
+
+#ifndef __ASM__
+
+#include <arch/interrupt.h>
+
+extern uintptr_t physmem_base;
+
+#define KA2PA(x)	(((uintptr_t) (x)) + physmem_base)
+#define PA2KA(x)	(((uintptr_t) (x)) - physmem_base)
+
+typedef union {
+	uintptr_t address;
+	struct {
+		uint64_t vpn : 51;		/**< Virtual Page Number. */
+		unsigned offset : 13;		/**< Offset. */
+	} __attribute__ ((packed));
+} page_address_t;
+
+extern void page_arch_init(void);
+
+#endif /* !def __ASM__ */
+
+#endif /* KERNEL */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/tlb.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/tlb.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2008 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_TLB_H_
+#define KERN_sparc64_sun4v_TLB_H_
+
+#define MMU_FSA_ALIGNMENT	64
+#define MMU_FSA_SIZE		128
+
+#ifndef __ASM__
+
+#include <arch/mm/tte.h>
+#include <print.h>
+#include <arch/mm/mmu.h>
+#include <arch/mm/page.h>
+#include <arch/asm.h>
+#include <arch/barrier.h>
+#include <arch/types.h>
+#include <arch/register.h>
+#include <arch/cpu.h>
+#include <arch/sun4v/hypercall.h>
+
+/**
+ * Structure filled by hypervisor (or directly CPU, if implemented so) when
+ * a MMU fault occurs. The structure describes the exact condition which
+ * has caused the fault.
+ */
+typedef struct mmu_fault_status_area {
+	uint64_t ift;		/**< Instruction fault type (IFT) */
+	uint64_t ifa;		/**< Instruction fault address (IFA) */
+	uint64_t ifc;		/**< Instruction fault context (IFC) */
+	uint8_t reserved1[0x28];
+
+	uint64_t dft;		/**< Data fault type (DFT) */
+	uint64_t dfa;		/**< Data fault address (DFA) */
+	uint64_t dfc;		/**< Data fault context (DFC) */
+	uint8_t reserved2[0x28];
+} __attribute__ ((packed)) mmu_fault_status_area_t;
+
+#define DTLB_MAX_LOCKED_ENTRIES		8
+
+/** Bit width of the TLB-locked portion of kernel address space. */
+#define KERNEL_PAGE_WIDTH       22	/* 4M */
+
+/*
+ * Reading and writing context registers.
+ *
+ * Note that UltraSPARC Architecture-compatible processors do not require
+ * a MEMBAR #Sync, FLUSH, DONE, or RETRY instruction after a store to an
+ * MMU register for proper operation.
+ *
+ */
+
+/** Read MMU Primary Context Register.
+ *
+ * @return	Current value of Primary Context Register.
+ */
+static inline uint64_t mmu_primary_context_read(void)
+{
+	return asi_u64_read(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG);
+}
+ 
+/** Write MMU Primary Context Register.
+ *
+ * @param v	New value of Primary Context Register.
+ */
+static inline void mmu_primary_context_write(uint64_t v)
+{
+	asi_u64_write(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG, v);
+}
+ 
+/** Read MMU Secondary Context Register.
+ *
+ * @return	Current value of Secondary Context Register.
+ */
+static inline uint64_t mmu_secondary_context_read(void)
+{
+	return asi_u64_read(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG);
+}
+ 
+/** Write MMU Secondary Context Register.
+ *
+ * @param v	New value of Secondary Context Register.
+ */
+static inline void mmu_secondary_context_write(uint64_t v)
+{
+	asi_u64_write(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG, v);
+}
+
+/**
+ * Demaps all mappings in a context.
+ *
+ * @param context	number of the context
+ * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
+ */
+static inline void mmu_demap_ctx(int context, int mmu_flag) {
+	__hypercall_fast4(MMU_DEMAP_CTX, 0, 0, context, mmu_flag);
+}
+
+/**
+ * Demaps given page.
+ *
+ * @param vaddr		VA of the page to be demapped
+ * @param context	number of the context
+ * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
+ */
+static inline void mmu_demap_page(uintptr_t vaddr, int context, int mmu_flag) {
+	__hypercall_fast5(MMU_DEMAP_PAGE, 0, 0, vaddr, context, mmu_flag);
+}
+
+extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
+extern void fast_data_access_mmu_miss(unative_t, istate_t *);
+extern void fast_data_access_protection(unative_t, istate_t *);
+
+extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
+
+extern void describe_dmmu_fault(void);
+
+#endif /* !def __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/tsb.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/tsb.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/tsb.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2009 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_TSB_H_
+#define KERN_sparc64_sun4v_TSB_H_
+
+/*
+ * TSB will claim 64K of memory, which
+ * is a nice number considered that it is one of
+ * the page sizes supported by hardware, which,
+ * again, is nice because TSBs need to be locked
+ * in TLBs - only one TLB entry will do.
+ */
+#define TSB_SIZE			3	/* when changing this, change
+						 * as.c as well */
+#define TSB_ENTRY_COUNT			(512 * (1 << TSB_SIZE))
+
+#ifndef __ASM__
+
+#include <typedefs.h>
+#include <arch/mm/tte.h>
+#include <arch/mm/mmu.h>
+#include <arch/types.h>
+
+/** TSB description, used in hypercalls */
+typedef struct tsb_descr {
+	uint16_t page_size;	/**< Page size (0 = 8K, 1 = 64K,...). */
+	uint16_t associativity;	/**< TSB associativity (will be 1). */
+	uint32_t num_ttes;	/**< Number of TTEs. */
+	uint32_t context;	/**< Context number. */
+	uint32_t pgsize_mask;	/**< Equals "1 << page_size". */
+	uint64_t tsb_base;	/**< Real address of TSB base. */
+	uint64_t reserved;
+} __attribute__ ((packed)) tsb_descr_t;
+
+
+/* Forward declarations. */
+struct as;
+struct pte;
+
+extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages);
+extern void itsb_pte_copy(struct pte *t);
+extern void dtsb_pte_copy(struct pte *t, bool ro);
+
+#endif /* !def __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/sun4v/tte.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/tte.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/mm/sun4v/tte.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_TTE_H_
+#define KERN_sparc64_sun4v_TTE_H_
+
+#define TTE_V_SHIFT	63	/**< valid */
+#define TTE_TADDR_SHIFT	13	/**< target address */
+#define TTE_CP_SHIFT	10	/**< cacheable physically */
+#define TTE_CV_SHIFT	9	/**< caheable virtually */
+#define TTE_P_SHIFT	8	/**< privileged */
+#define TTE_EP_SHIFT	7	/**< execute permission */
+#define TTE_W_SHIFT	6	/**< writable */
+#define TTE_SZ_SHIFT	0	/**< size */
+
+#define MMU_FLAG_ITLB	2	/**< operation applies to ITLB */
+#define MMU_FLAG_DTLB	1	/**< operation applies to DTLB */
+
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+/** Translation Table Entry - Data. */
+union tte_data {
+	uint64_t value;
+	struct {
+		unsigned v : 1;		/**< Valid. */
+		unsigned nfo : 1;	/**< No-Fault-Only. */
+		unsigned soft : 6;	/**< Software defined field. */
+		unsigned long ra : 43;	/**< Real address. */
+		unsigned ie : 1;	/**< Invert endianess. */
+		unsigned e : 1;		/**< Side-effect. */
+		unsigned cp : 1;	/**< Cacheable in physically indexed cache. */
+		unsigned cv : 1;	/**< Cacheable in virtually indexed cache. */
+		unsigned p : 1;		/**< Privileged. */
+		unsigned x : 1;		/**< Executable. */
+		unsigned w : 1;		/**< Writable. */
+		unsigned soft2 : 2;	/**< Software defined field. */
+		unsigned size : 4;	/**< Page size. */
+	} __attribute__ ((packed));
+};
+
+typedef union tte_data tte_data_t;
+
+#define VA_TAG_PAGE_SHIFT	22
+
+#endif /* !def __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/arch.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/arch.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/arch.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Various sun4v-specific macros.
+ */
+
+#ifndef KERN_sparc64_sun4v_ARCH_H_
+#define KERN_sparc64_sun4v_ARCH_H_
+
+/* scratch pad registers ASI */
+#define	ASI_SCRATCHPAD		0x20
+
+/*
+ * Assignment of scratchpad register virtual addresses. The same convention is
+ * used by both Linux and Solaris.
+ */
+
+/* register where the address of the MMU fault status area will be stored */
+#define SCRATCHPAD_MMU_FSA	0x00	
+
+/* register where the CPUID will be stored */
+#define SCRATCHPAD_CPUID	0x08
+
+/* register where the kernel stack address will be stored */
+#define SCRATCHPAD_KSTACK	0x10
+
+/* register where the userspace window buffer address will be stored */
+#define SCRATCHPAD_WBUF		0x18
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/asm.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/asm.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/asm.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_ASM_H_
+#define KERN_sparc64_sun4v_ASM_H_
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/cpu.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/cpu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/cpu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_CPU_H_
+#define KERN_sparc64_sun4v_CPU_H_
+
+/** Maximum number of virtual processors. */
+#define MAX_NUM_STRANDS		64
+
+/** Maximum number of logical processors in a processor core */
+#define MAX_CORE_STRANDS	8
+
+#ifndef __ASM__
+
+struct cpu;
+
+typedef struct {
+	uint64_t exec_unit_id;
+	uint8_t strand_count;
+	uint64_t cpuids[MAX_CORE_STRANDS];
+	struct cpu *cpus[MAX_CORE_STRANDS];
+	atomic_t nrdy;
+	SPINLOCK_DECLARE(proposed_nrdy_lock);
+} exec_unit_t;
+
+typedef struct cpu_arch {
+	uint64_t id;			/**< virtual processor ID */
+	uint32_t clock_frequency;	/**< Processor frequency in Hz. */
+	uint64_t next_tick_cmpr;	/**< Next clock interrupt should be
+					     generated when the TICK register
+					     matches this value. */
+	exec_unit_t *exec_unit;		/**< Physical core. */
+	unsigned long proposed_nrdy;	/**< Proposed No. of ready threads
+					     so that cores are equally balanced. */
+} cpu_arch_t;
+
+#endif	
+
+#ifdef __ASM__
+
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/hypercall.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/hypercall.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/hypercall.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Macros, constants and functions needed to perform a call to the
+ * 		hypervisor API. For details and terminology see this document:
+ *		UltraSPARC Virtual Machine Specification (The Hypervisor API
+ *		specification for Logical Domains).
+ *
+ */
+
+#ifndef KERN_sparc64_sun4v_HYPERCALL_H_
+#define KERN_sparc64_sun4v_HYPERCALL_H_
+
+/* SW trap numbers for hyperfast traps */
+#define FAST_TRAP		0x80
+#define MMU_MAP_ADDR		0x83
+#define MMU_UNMAP_ADDR		0x84
+
+/* function codes for fast traps */
+#define MACH_DESC		0x01
+#define CPU_START		0x10
+#define CPU_STOP		0x11
+#define CPU_YIELD		0x12
+#define CPU_QCONF		0x14
+#define CPU_MYID		0x16
+#define CPU_STATE		0x17
+#define CPU_SET_RTBA		0x18
+#define CPU_GET_RTBA		0x19
+#define MMU_TSB_CTX0		0x20
+#define MMU_TSB_CTXNON0		0x21
+#define MMU_DEMAP_PAGE		0x22
+#define MMU_DEMAP_CTX		0x23
+#define MMU_DEMAP_ALL		0x24
+#define MMU_MAP_PERM_ADDR	0x25
+#define MMU_FAULT_AREA_CONF	0x26
+#define MMU_ENABLE		0x27
+#define MMU_UNMAP_PERM_ADDR	0x28
+#define MMU_TSB_CTX0_INFO	0x29
+#define MMU_TSB_CTXNON0_INFO	0x2a
+#define MMU_FAULT_AREA_INFO	0x2b
+#define CPU_MONDO_SEND		0x42
+#define CONS_GETCHAR		0x60
+#define CONS_PUTCHAR		0x61
+
+
+/* return codes */
+#define EOK		0	/**< Successful return */
+#define ENOCPU		1	/**< Invalid CPU id */
+#define ENORADDR	2	/**< Invalid real address */
+#define ENOINTR		3	/**< Invalid interrupt id */
+#define EBADPGSZ	4	/**< Invalid pagesize encoding */
+#define EBADTSB		5	/**< Invalid TSB description */
+#define	EINVAL		6	/**< Invalid argument */
+#define EBADTRAP	7	/**< Invalid function number */
+#define EBADALIGN	8	/**< Invalid address alignment */
+#define EWOULDBLOCK	9	/**< Cannot complete operation without blocking */
+#define ENOACCESS	10	/**< No access to specified resource */
+#define EIO		11	/**< I/O Error */
+#define ECPUERROR	12	/**< CPU is in error state */
+#define ENOTSUPPORTED	13	/**< Function not supported */
+#define ENOMAP		14	/**< No mapping found */
+#define ETOOMANY	15	/**< Too many items specified / limit reached */
+#define ECHANNEL	16	/**< Invalid LDC channel */
+#define EBUSY		17	/**< Operation failed as resource is otherwise busy */
+
+
+/**
+ * Performs a hyperfast hypervisor API call from the assembly language code.
+ * Expects the registers %o1-%o4 are properly filled with the arguments of the
+ * call.
+ *
+ * @param function_number	hyperfast call function number
+ */
+#define __HYPERCALL_FAST(function_number) \
+	set function_number, %o5; \
+	ta FAST_TRAP;
+	
+/**
+ * Performs a fast hypervisor API call from the assembly language code.
+ * Expects the registers %o1-%o4 are properly filled with the arguments of the
+ * call.
+ *
+ * @param sw_trap_number	software trap number
+ */
+#define __HYPERCALL_HYPERFAST(sw_trap_number) \
+	ta (sw_trap_number);
+
+
+#ifndef __ASM__
+
+#include <typedefs.h>
+#include <arch/types.h>
+
+/*
+ * Macros to be used from the C-language code; __hypercall_fastN performs
+ * a fast hypervisor API call taking exactly N arguments.
+ */
+
+#define __hypercall_fast0(function_number) \
+	__hypercall_fast(0, 0, 0, 0, 0, function_number)
+#define __hypercall_fast1(function_number, p1) \
+	__hypercall_fast(p1, 0, 0, 0, 0, function_number)
+#define __hypercall_fast2(function_number, p1, p2) \
+	__hypercall_fast(p1, p2, 0, 0, 0, function_number)
+#define __hypercall_fast3(function_number, p1, p2, p3) \
+	__hypercall_fast(p1, p2, p3, 0, 0, function_number)
+#define __hypercall_fast4(function_number, p1, p2, p3, p4) \
+	__hypercall_fast(p1, p2, p3, p4, 0, function_number)
+#define __hypercall_fast5(function_number, p1, p2, p3, p4, p5) \
+	__hypercall_fast(p1, p2, p3, p4, p5, function_number)
+
+/**
+ * Performs a fast hypervisor API call which returns no value except for the
+ * error status.
+ *
+ * @param p1			the 1st argument of the hypervisor API call
+ * @param p2			the 2nd argument of the hypervisor API call
+ * @param p3			the 3rd argument of the hypervisor API call
+ * @param p4			the 4th argument of the hypervisor API call
+ * @param p5			the 5th argument of the hypervisor API call
+ * @param function_number	function number of the call
+ * @return			error status
+ */
+static inline uint64_t
+__hypercall_fast(const uint64_t p1, const uint64_t p2, const uint64_t p3,
+    const uint64_t p4, const uint64_t p5, const uint64_t function_number)
+{
+	register uint64_t a6 asm("o5") = function_number;
+	register uint64_t a1 asm("o0") = p1;
+	register uint64_t a2 asm("o1") = p2;
+	register uint64_t a3 asm("o2") = p3;
+	register uint64_t a4 asm("o3") = p4;
+	register uint64_t a5 asm("o4") = p5;
+
+	asm volatile (
+		"ta %7\n"
+		: "=r" (a1)
+		: "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6),
+		  "i" (FAST_TRAP)
+		: "memory"
+	);
+
+	return a1;
+}
+
+/**
+ * Performs a fast hypervisor API call which can return a value.
+ *
+ * @param p1			the 1st argument of the hypervisor API call
+ * @param p2			the 2nd argument of the hypervisor API call
+ * @param p3			the 3rd argument of the hypervisor API call
+ * @param p4			the 4th argument of the hypervisor API call
+ * @param p5			the 5th argument of the hypervisor API call
+ * @param function_number	function number of the call
+ * @param ret1			pointer to an address where the return value
+ * 				of the hypercall should be saved, or NULL
+ * @return			error status
+ */
+static inline uint64_t
+__hypercall_fast_ret1(const uint64_t p1, const uint64_t p2, const uint64_t p3,
+    const uint64_t p4, const uint64_t p5, const uint64_t function_number,
+    uint64_t * const ret1)
+{
+	uint64_t errno = __hypercall_fast(p1, p2, p3, p4, p5, function_number);
+	if (ret1 != NULL) {
+		asm volatile ("mov %%o1, %0\n" : "=r" (*ret1));
+	}
+	return errno;
+}
+
+/**
+ * Performs a hyperfast hypervisor API call.
+ *
+ * @param p1			the 1st argument of the hypervisor API call
+ * @param p2			the 2nd argument of the hypervisor API call
+ * @param p3			the 3rd argument of the hypervisor API call
+ * @param p4			the 4th argument of the hypervisor API call
+ * @param p5			the 5th argument of the hypervisor API call
+ * @param sw_trap_number	software trap number
+ */
+static inline uint64_t
+__hypercall_hyperfast(const uint64_t p1, const uint64_t p2, const uint64_t p3,
+    const uint64_t p4, const uint64_t p5, const uint64_t sw_trap_number)
+{
+	register uint64_t a1 asm("o0") = p1;
+	register uint64_t a2 asm("o1") = p2;
+	register uint64_t a3 asm("o2") = p3;
+	register uint64_t a4 asm("o3") = p4;
+	register uint64_t a5 asm("o4") = p5;
+
+	asm volatile (
+		"ta %6\n"
+		: "=r" (a1)
+		: "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5),
+		  "i" (sw_trap_number)
+		: "memory"
+	);
+	
+	return a1;
+}
+
+#endif /* ASM */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/ipi.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/ipi.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/ipi.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/**
+ * @file
+ * @brief	sun4v-specific IPI functions
+ */
+
+#ifndef KERN_sparc64_sun4v_IPI_H_
+#define KERN_sparc64_sun4v_IPI_H_
+
+uint64_t ipi_brodcast_to(void (*func)(void), uint16_t cpu_list[MAX_NUM_STRANDS],
+		uint64_t list_size);
+uint64_t ipi_unicast_to(void (*func)(void), uint16_t cpu_id);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/md.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/md.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/md.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_MD_H_
+#define KERN_sparc64_sun4v_MD_H_
+
+#include <typedefs.h>
+
+/**
+ * Data type used to iterate through MD nodes. Internally represented as
+ * an index to the first element of the node.
+ */
+typedef unsigned int md_node_t;
+
+/** used to iterate over children of a given node */
+typedef unsigned int md_child_iter_t;
+
+md_node_t md_get_root(void);
+md_node_t md_get_child(md_node_t node, char *name);
+md_child_iter_t md_get_child_iterator(md_node_t node);
+bool md_next_child(md_child_iter_t *it);
+md_node_t md_get_child_node(md_child_iter_t it);
+const char *md_get_node_name(md_node_t node);
+bool md_get_integer_property(md_node_t node, const char *key,
+	uint64_t *result);
+bool md_get_string_property(md_node_t node, const char *key,
+	const char **result);
+bool md_next_node(md_node_t *node, const char *name);
+void md_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/regdef.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/regdef.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/regdef.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2008 Pavel Rimsky
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_REGDEF_H_
+#define KERN_sparc64_sun4v_REGDEF_H_
+
+#define PSTATE_IE_BIT	(1 << 1)
+#define PSTATE_PRIV_BIT	(1 << 2)
+#define PSTATE_PEF_BIT	(1 << 4)
+
+#define TSTATE_PSTATE_SHIFT	8
+#define TSTATE_PRIV_BIT		(PSTATE_PRIV_BIT << TSTATE_PSTATE_SHIFT)
+#define TSTATE_CWP_MASK		0x1f
+#define TSTATE_IE_BIT		(PSTATE_IE_BIT << TSTATE_PSTATE_SHIFT)
+
+#define WSTATE_NORMAL(n)	(n)
+#define WSTATE_OTHER(n)		((n) << 3)
+
+#define TSTATE_PEF_BIT		(PSTATE_PEF_BIT << TSTATE_PSTATE_SHIFT)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/sun4v/register.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/register.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/sun4v/register.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_sun4v_REGISTER_H_
+#define KERN_sparc64_sun4v_REGISTER_H_
+
+#include <arch/regdef.h>
+#include <arch/types.h>
+
+/** Processor State Register. */
+union pstate_reg {
+	uint64_t value;
+	struct {
+		uint64_t : 54;
+		unsigned cle : 1;	/**< Current Little Endian. */
+		unsigned tle : 1;	/**< Trap Little Endian. */
+		unsigned mm : 2;	/**< Memory Model. */
+		unsigned : 1;		/**< RED state. */
+		unsigned pef : 1;	/**< Enable floating-point. */
+		unsigned am : 1;	/**< 32-bit Address Mask. */
+		unsigned priv : 1;	/**< Privileged Mode. */
+		unsigned ie : 1;	/**< Interrupt Enable. */
+		unsigned : 1;
+	} __attribute__ ((packed));
+};
+typedef union pstate_reg pstate_reg_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/trap/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/mmu.h	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ kernel/arch/sparc64/include/trap/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -38,144 +38,9 @@
 #define KERN_sparc64_MMU_TRAP_H_
 
-#include <arch/stack.h>
-#include <arch/regdef.h>
-#include <arch/mm/tlb.h>
-#include <arch/mm/mmu.h>
-#include <arch/mm/tte.h>
-#include <arch/trap/regwin.h>
-
-#ifdef CONFIG_TSB
-#include <arch/mm/tsb.h>
+#if defined (SUN4U)
+#include <arch/trap/sun4u/mmu.h>
+#elif defined (SUN4V)
+#include <arch/trap/sun4v/mmu.h>
 #endif
-
-#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS	0x64
-#define TT_FAST_DATA_ACCESS_MMU_MISS		0x68
-#define TT_FAST_DATA_ACCESS_PROTECTION		0x6c
-
-#define FAST_MMU_HANDLER_SIZE			128
-
-#ifdef __ASM__
-
-.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
-	/*
-	 * First, try to refill TLB from TSB.
-	 */
-#ifdef CONFIG_TSB
-	ldxa [%g0] ASI_IMMU, %g1			! read TSB Tag Target Register
-	ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2	! read TSB 8K Pointer
-	ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
-	cmp %g1, %g4					! is this the entry we are looking for?
-	bne,pn %xcc, 0f
-	nop
-	stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG		! copy mapping from ITSB to ITLB
-	retry
-#endif
-
-0:
-	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
-	PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
-.endm
-
-.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
-	/*
-	 * First, try to refill TLB from TSB.
-	 */
-
-#ifdef CONFIG_TSB
-	ldxa [%g0] ASI_DMMU, %g1			! read TSB Tag Target Register
-	srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2	! is this a kernel miss?
-	brz,pn %g2, 0f
-	ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3	! read TSB 8K Pointer
-	ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
-	cmp %g1, %g4					! is this the entry we are looking for?
-	bne,pn %xcc, 0f
-	nop
-	stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG		! copy mapping from DTSB to DTLB
-	retry
-#endif
-
-	/*
-	 * Second, test if it is the portion of the kernel address space
-	 * which is faulting. If that is the case, immediately create
-	 * identity mapping for that page in DTLB. VPN 0 is excluded from
-	 * this treatment.
-	 *
-	 * Note that branch-delay slots are used in order to save space.
-	 */
-0:
-	sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
-	wr %g0, ASI_DMMU, %asi
-	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1		! read the faulting Context and VPN
-	set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
-	andcc %g1, %g2, %g3				! get Context
-	bnz %xcc, 0f					! Context is non-zero
-	andncc %g1, %g2, %g3				! get page address into %g3
-	bz  %xcc, 0f					! page address is zero
-	ldx [%g7 + %lo(end_of_identity)], %g4
-	cmp %g3, %g4
-	bgeu %xcc, 0f
-
-	ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
-	add %g3, %g2, %g2
-	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
-	retry
-
-	/*
-	 * Third, catch and handle special cases when the trap is caused by
-	 * the userspace register window spill or fill handler. In case
-	 * one of these two traps caused this trap, we just lower the trap
-	 * level and service the DTLB miss. In the end, we restart
-	 * the offending SAVE or RESTORE.
-	 */
-0:
-.if (\tl > 0)
-	wrpr %g0, 1, %tl
-.endif
-
-	/*
-	 * Switch from the MM globals.
-	 */
-	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
-
-	/*
-	 * Read the Tag Access register for the higher-level handler.
-	 * This is necessary to survive nested DTLB misses.
-	 */	
-	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
-
-	/*
-	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
-	 */
-	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
-.endm
-
-.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
-	/*
-	 * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
-	 */
-
-.if (\tl > 0)
-	wrpr %g0, 1, %tl
-.endif
-
-	/*
-	 * Switch from the MM globals.
-	 */
-	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
-
-	/*
-	 * Read the Tag Access register for the higher-level handler.
-	 * This is necessary to survive nested DTLB misses.
-	 */	
-	mov VA_DMMU_TAG_ACCESS, %g2
-	ldxa [%g2] ASI_DMMU, %g2
-
-	/*
-	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
-	 */
-	PREEMPTIBLE_HANDLER fast_data_access_protection
-.endm
-
-#endif /* __ASM__ */
 
 #endif
Index: kernel/arch/sparc64/include/trap/sun4u/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/sun4u/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/trap/sun4u/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64interrupt
+ * @{
+ */
+/**
+ * @file
+ * @brief This file contains fast MMU trap handlers.
+ */
+
+#ifndef KERN_sparc64_SUN4U_MMU_TRAP_H_
+#define KERN_sparc64_SUN4U_MMU_TRAP_H_
+
+#include <arch/stack.h>
+#include <arch/regdef.h>
+#include <arch/mm/tlb.h>
+#include <arch/mm/mmu.h>
+#include <arch/mm/tte.h>
+#include <arch/trap/regwin.h>
+
+#ifdef CONFIG_TSB
+#include <arch/mm/tsb.h>
+#endif
+
+#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS	0x64
+#define TT_FAST_DATA_ACCESS_MMU_MISS		0x68
+#define TT_FAST_DATA_ACCESS_PROTECTION		0x6c
+
+#define FAST_MMU_HANDLER_SIZE			128
+
+#ifdef __ASM__
+
+.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+#ifdef CONFIG_TSB
+	ldxa [%g0] ASI_IMMU, %g1			! read TSB Tag Target Register
+	ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2	! read TSB 8K Pointer
+	ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
+	cmp %g1, %g4					! is this the entry we are looking for?
+	bne,pn %xcc, 0f
+	nop
+	stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG		! copy mapping from ITSB to ITLB
+	retry
+#endif
+
+0:
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+	PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
+.endm
+
+.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+
+#ifdef CONFIG_TSB
+	ldxa [%g0] ASI_DMMU, %g1			! read TSB Tag Target Register
+	srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2	! is this a kernel miss?
+	brz,pn %g2, 0f
+	ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3	! read TSB 8K Pointer
+	ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
+	cmp %g1, %g4					! is this the entry we are looking for?
+	bne,pn %xcc, 0f
+	nop
+	stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG		! copy mapping from DTSB to DTLB
+	retry
+#endif
+
+	/*
+	 * Second, test if it is the portion of the kernel address space
+	 * which is faulting. If that is the case, immediately create
+	 * identity mapping for that page in DTLB. VPN 0 is excluded from
+	 * this treatment.
+	 *
+	 * Note that branch-delay slots are used in order to save space.
+	 */
+0:
+	sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
+	wr %g0, ASI_DMMU, %asi
+	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1		! read the faulting Context and VPN
+	set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
+	andcc %g1, %g2, %g3				! get Context
+	bnz %xcc, 0f					! Context is non-zero
+	andncc %g1, %g2, %g3				! get page address into %g3
+	bz  %xcc, 0f					! page address is zero
+	ldx [%g7 + %lo(end_of_identity)], %g4
+	cmp %g3, %g4
+	bgeu %xcc, 0f
+
+	ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
+	add %g3, %g2, %g2
+	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
+	retry
+
+	/*
+	 * Third, catch and handle special cases when the trap is caused by
+	 * the userspace register window spill or fill handler. In case
+	 * one of these two traps caused this trap, we just lower the trap
+	 * level and service the DTLB miss. In the end, we restart
+	 * the offending SAVE or RESTORE.
+	 */
+0:
+.if (\tl > 0)
+	wrpr %g0, 1, %tl
+.endif
+
+	/*
+	 * Switch from the MM globals.
+	 */
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+
+	/*
+	 * Read the Tag Access register for the higher-level handler.
+	 * This is necessary to survive nested DTLB misses.
+	 */	
+	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
+
+	/*
+	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
+	 */
+	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
+.endm
+
+.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
+	/*
+	 * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
+	 */
+
+.if (\tl > 0)
+	wrpr %g0, 1, %tl
+.endif
+
+	/*
+	 * Switch from the MM globals.
+	 */
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+
+	/*
+	 * Read the Tag Access register for the higher-level handler.
+	 * This is necessary to survive nested DTLB misses.
+	 */	
+	mov VA_DMMU_TAG_ACCESS, %g2
+	ldxa [%g2] ASI_DMMU, %g2
+
+	/*
+	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
+	 */
+	PREEMPTIBLE_HANDLER fast_data_access_protection
+.endm
+
+#endif /* __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/trap/sun4v/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/sun4v/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/include/trap/sun4v/mmu.h	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64interrupt
+ * @{
+ */
+/**
+ * @file
+ * @brief This file contains fast MMU trap handlers.
+ */
+
+#ifndef KERN_sparc64_SUN4V_MMU_TRAP_H_
+#define KERN_sparc64_SUN4V_MMU_TRAP_H_
+
+#include <arch/stack.h>
+#include <arch/regdef.h>
+#include <arch/mm/tlb.h>
+#include <arch/mm/mmu.h>
+#include <arch/mm/tte.h>
+#include <arch/trap/regwin.h>
+
+#ifdef CONFIG_TSB
+#include <arch/mm/tsb.h>
+#endif
+
+#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS	0x64
+#define TT_FAST_DATA_ACCESS_MMU_MISS		0x68
+#define TT_FAST_DATA_ACCESS_PROTECTION		0x6c
+
+#define FAST_MMU_HANDLER_SIZE			128
+
+#ifdef __ASM__
+
+.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+#ifdef CONFIG_TSB
+	ldxa [%g0] ASI_IMMU, %g1			! read TSB Tag Target Register
+	ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2	! read TSB 8K Pointer
+	ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
+	cmp %g1, %g4					! is this the entry we are looking for?
+	bne,pn %xcc, 0f
+	nop
+	stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG		! copy mapping from ITSB to ITLB
+	retry
+#endif
+
+0:
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+	PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
+.endm
+
+.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
+//MH
+	set 0x8000, %o0
+	set 0x0, %o1
+	setx 0x80000000804087c3, %g1, %o2
+	set 0x3, %o3
+	ta 0x83
+	retry
+#if 0
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+
+#ifdef CONFIG_TSB
+	ldxa [%g0] ASI_DMMU, %g1			! read TSB Tag Target Register
+	srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2	! is this a kernel miss?
+	brz,pn %g2, 0f
+	ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3	! read TSB 8K Pointer
+	ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4		! 16-byte atomic load into %g4 and %g5
+	cmp %g1, %g4					! is this the entry we are looking for?
+	bne,pn %xcc, 0f
+	nop
+	stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG		! copy mapping from DTSB to DTLB
+	retry
+#endif
+
+	/*
+	 * Second, test if it is the portion of the kernel address space
+	 * which is faulting. If that is the case, immediately create
+	 * identity mapping for that page in DTLB. VPN 0 is excluded from
+	 * this treatment.
+	 *
+	 * Note that branch-delay slots are used in order to save space.
+	 */
+0:
+//MH
+//	sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
+	wr %g0, ASI_DMMU, %asi
+	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1		! read the faulting Context and VPN
+	set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
+	andcc %g1, %g2, %g3				! get Context
+	bnz %xcc, 0f					! Context is non-zero
+	andncc %g1, %g2, %g3				! get page address into %g3
+	bz  %xcc, 0f					! page address is zero
+//MH
+//	ldx [%g7 + %lo(end_of_identity)], %g4
+	cmp %g3, %g4
+	bgeu %xcc, 0f
+
+	ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
+	add %g3, %g2, %g2
+	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
+	retry
+
+	/*
+	 * Third, catch and handle special cases when the trap is caused by
+	 * the userspace register window spill or fill handler. In case
+	 * one of these two traps caused this trap, we just lower the trap
+	 * level and service the DTLB miss. In the end, we restart
+	 * the offending SAVE or RESTORE.
+	 */
+0:
+.if (\tl > 0)
+	wrpr %g0, 1, %tl
+.endif
+
+	/*
+	 * Switch from the MM globals.
+	 */
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+
+	/*
+	 * Read the Tag Access register for the higher-level handler.
+	 * This is necessary to survive nested DTLB misses.
+	 */	
+	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
+
+	/*
+	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
+	 */
+	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
+#endif
+.endm
+
+.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
+	/*
+	 * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
+	 */
+
+.if (\tl > 0)
+	wrpr %g0, 1, %tl
+.endif
+
+	/*
+	 * Switch from the MM globals.
+	 */
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+
+	/*
+	 * Read the Tag Access register for the higher-level handler.
+	 * This is necessary to survive nested DTLB misses.
+	 */	
+	mov VA_DMMU_TAG_ACCESS, %g2
+	ldxa [%g2] ASI_DMMU, %g2
+
+	/*
+	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
+	 */
+	PREEMPTIBLE_HANDLER fast_data_access_protection
+.endm
+
+#endif /* __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: rnel/arch/sparc64/src/mm/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/frame.c	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ 	(revision )
@@ -1,87 +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.
- */
-
-/** @addtogroup sparc64mm
- * @{
- */
-/** @file
- */
-
-#include <arch/mm/frame.h>
-#include <mm/frame.h>
-#include <arch/boot/boot.h>
-#include <arch/types.h>
-#include <config.h>
-#include <align.h>
-#include <macros.h>
-
-uintptr_t last_frame = NULL;
-
-/** Create memory zones according to information stored in bootinfo.
- *
- * Walk the bootinfo memory map and create frame zones according to it.
- */
-void frame_arch_init(void)
-{
-	unsigned int i;
-	pfn_t confdata;
-
-	if (config.cpu_active == 1) {
-		for (i = 0; i < bootinfo.memmap.count; i++) {
-			uintptr_t start = bootinfo.memmap.zones[i].start;
-			size_t size = bootinfo.memmap.zones[i].size;
-
-			/*
-			 * The memmap is created by HelenOS boot loader.
-			 * It already contains no holes.
-			 */
-
-			confdata = ADDR2PFN(start);
-			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
-				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
-			zone_create(ADDR2PFN(start),
-			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
-			    confdata, 0);
-			last_frame = max(last_frame, start + ALIGN_UP(size,
-			    FRAME_SIZE));
-		}
-
-		/*
-		 * On sparc64, physical memory can start on a non-zero address.
-		 * The generic frame_init() only marks PFN 0 as not free, so we
-		 * must mark the physically first frame not free explicitly
-		 * here, no matter what is its address.
-		 */
-		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
-	}
-
-	end_of_identity = PA2KA(last_frame);
-}
-
-/** @}
- */
Index: kernel/arch/sparc64/src/mm/sun4u/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <arch/boot/boot.h>
+#include <arch/types.h>
+#include <config.h>
+#include <align.h>
+#include <macros.h>
+
+uintptr_t last_frame = NULL;
+
+/** Create memory zones according to information stored in bootinfo.
+ *
+ * Walk the bootinfo memory map and create frame zones according to it.
+ */
+void frame_arch_init(void)
+{
+	unsigned int i;
+	pfn_t confdata;
+
+	if (config.cpu_active == 1) {
+		for (i = 0; i < bootinfo.memmap.count; i++) {
+			uintptr_t start = bootinfo.memmap.zones[i].start;
+			size_t size = bootinfo.memmap.zones[i].size;
+
+			/*
+			 * The memmap is created by HelenOS boot loader.
+			 * It already contains no holes.
+			 */
+
+			confdata = ADDR2PFN(start);
+			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
+				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
+			zone_create(ADDR2PFN(start),
+			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			    confdata, 0);
+			last_frame = max(last_frame, start + ALIGN_UP(size,
+			    FRAME_SIZE));
+		}
+
+		/*
+		 * On sparc64, physical memory can start on a non-zero address.
+		 * The generic frame_init() only marks PFN 0 as not free, so we
+		 * must mark the physically first frame not free explicitly
+		 * here, no matter what is its address.
+		 */
+		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
+	}
+
+	end_of_identity = PA2KA(last_frame);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,607 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/tlb.h>
+#include <mm/tlb.h>
+#include <mm/as.h>
+#include <mm/asid.h>
+#include <arch/mm/frame.h>
+#include <arch/mm/page.h>
+#include <arch/mm/mmu.h>
+#include <arch/interrupt.h>
+#include <interrupt.h>
+#include <arch.h>
+#include <print.h>
+#include <arch/types.h>
+#include <config.h>
+#include <arch/trap/trap.h>
+#include <arch/trap/exception.h>
+#include <panic.h>
+#include <arch/asm.h>
+
+#ifdef CONFIG_TSB
+#include <arch/mm/tsb.h>
+#endif
+
+static void dtlb_pte_copy(pte_t *, size_t, bool);
+static void itlb_pte_copy(pte_t *, size_t);
+static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
+static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
+    const char *);
+static void do_fast_data_access_protection_fault(istate_t *,
+    tlb_tag_access_reg_t, const char *);
+
+char *context_encoding[] = {
+	"Primary",
+	"Secondary",
+	"Nucleus",
+	"Reserved"
+};
+
+void tlb_arch_init(void)
+{
+	/*
+	 * Invalidate all non-locked DTLB and ITLB entries.
+	 */
+	tlb_invalidate_all();
+
+	/*
+	 * Clear both SFSRs.
+	 */
+	dtlb_sfsr_write(0);
+	itlb_sfsr_write(0);
+}
+
+/** Insert privileged mapping into DMMU TLB.
+ *
+ * @param page		Virtual page address.
+ * @param frame		Physical frame address.
+ * @param pagesize	Page size.
+ * @param locked	True for permanent mappings, false otherwise.
+ * @param cacheable	True if the mapping is cacheable, false otherwise.
+ */
+void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
+    bool locked, bool cacheable)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = page;
+	fr.address = frame;
+
+	tag.context = ASID_KERNEL;
+	tag.vpn = pg.vpn;
+
+	dtlb_tag_access_write(tag.value);
+
+	data.value = 0;
+	data.v = true;
+	data.size = pagesize;
+	data.pfn = fr.pfn;
+	data.l = locked;
+	data.cp = cacheable;
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	data.cv = cacheable;
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+	data.p = true;
+	data.w = true;
+	data.g = false;
+
+	dtlb_data_in_write(data.value);
+}
+
+/** Copy PTE to TLB.
+ *
+ * @param t 		Page Table Entry to be copied.
+ * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
+ * @param ro		If true, the entry will be created read-only, regardless
+ * 			of its w field.
+ */
+void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page + (index << MMU_PAGE_WIDTH);
+	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+
+	dtlb_tag_access_write(tag.value);
+
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	data.cv = t->c;
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+	data.p = t->k;		/* p like privileged */
+	data.w = ro ? false : t->w;
+	data.g = t->g;
+
+	dtlb_data_in_write(data.value);
+}
+
+/** Copy PTE to ITLB.
+ *
+ * @param t		Page Table Entry to be copied.
+ * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
+ */
+void itlb_pte_copy(pte_t *t, size_t index)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page + (index << MMU_PAGE_WIDTH);
+	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+	
+	itlb_tag_access_write(tag.value);
+	
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+	data.p = t->k;		/* p like privileged */
+	data.w = false;
+	data.g = t->g;
+	
+	itlb_data_in_write(data.value);
+}
+
+/** ITLB miss handler. */
+void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
+{
+	uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
+	size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
+	pte_t *t;
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t && PTE_EXECUTABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into ITLB.
+		 */
+		t->a = true;
+		itlb_pte_copy(t, index);
+#ifdef CONFIG_TSB
+		itsb_pte_copy(t, index);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_instruction_access_mmu_miss_fault(istate,
+			    __func__);
+		}
+	}
+}
+
+/** DTLB miss handler.
+ *
+ * Note that some faults (e.g. kernel faults) were already resolved by the
+ * low-level, assembly language part of the fast_data_access_mmu_miss handler.
+ *
+ * @param tag		Content of the TLB Tag Access register as it existed
+ * 			when the trap happened. This is to prevent confusion
+ * 			created by clobbered Tag Access register during a nested
+ * 			DTLB miss.
+ * @param istate	Interrupted state saved on the stack.
+ */
+void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
+{
+	uintptr_t page_8k;
+	uintptr_t page_16k;
+	size_t index;
+	pte_t *t;
+
+	page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
+	page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
+	index = tag.vpn % MMU_PAGES_PER_PAGE;
+
+	if (tag.context == ASID_KERNEL) {
+		if (!tag.vpn) {
+			/* NULL access in kernel */
+			do_fast_data_access_mmu_miss_fault(istate, tag,
+			    __func__);
+		} else if (page_8k >= end_of_identity) {
+			/*
+			 * The kernel is accessing the I/O space.
+			 * We still do identity mapping for I/O,
+			 * but without caching.
+			 */
+			dtlb_insert_mapping(page_8k, KA2PA(page_8k),
+			    PAGESIZE_8K, false, false);
+			return;
+		}
+		do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
+		    "kernel page fault.");
+	}
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into DTLB.
+		 */
+		t->a = true;
+		dtlb_pte_copy(t, index, true);
+#ifdef CONFIG_TSB
+		dtsb_pte_copy(t, index, true);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_data_access_mmu_miss_fault(istate, tag,
+			    __func__);
+		}
+	}
+}
+
+/** DTLB protection fault handler.
+ *
+ * @param tag		Content of the TLB Tag Access register as it existed
+ * 			when the trap happened. This is to prevent confusion
+ * 			created by clobbered Tag Access register during a nested
+ * 			DTLB miss.
+ * @param istate	Interrupted state saved on the stack.
+ */
+void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
+{
+	uintptr_t page_16k;
+	size_t index;
+	pte_t *t;
+
+	page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
+	index = tag.vpn % MMU_PAGES_PER_PAGE;	/* 16K-page emulation */
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t && PTE_WRITABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table and is
+		 * writable. Demap the old mapping and insert an updated mapping
+		 * into DTLB.
+		 */
+		t->a = true;
+		t->d = true;
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
+		    page_16k + index * MMU_PAGE_SIZE);
+		dtlb_pte_copy(t, index, false);
+#ifdef CONFIG_TSB
+		dtsb_pte_copy(t, index, false);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_data_access_protection_fault(istate, tag,
+			    __func__);
+		}
+	}
+}
+
+/** Print TLB entry (for debugging purposes).
+ *
+ * The diag field has been left out in order to make this function more generic
+ * (there is no diag field in US3 architeture). 
+ *
+ * @param i		TLB entry number 
+ * @param t		TLB entry tag
+ * @param d		TLB entry data 
+ */
+static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
+{
+	printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
+	    "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
+	    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
+	    t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
+	    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
+}
+
+#if defined (US)
+
+/** Print contents of both TLBs. */
+void tlb_print(void)
+{
+	int i;
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+	
+	printf("I-TLB contents:\n");
+	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
+		d.value = itlb_data_access_read(i);
+		t.value = itlb_tag_read_read(i);
+		print_tlb_entry(i, t, d);
+	}
+
+	printf("D-TLB contents:\n");
+	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
+		d.value = dtlb_data_access_read(i);
+		t.value = dtlb_tag_read_read(i);
+		print_tlb_entry(i, t, d);
+	}
+}
+
+#elif defined (US3)
+
+/** Print contents of all TLBs. */
+void tlb_print(void)
+{
+	int i;
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+	
+	printf("TLB_ISMALL contents:\n");
+	for (i = 0; i < tlb_ismall_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_ISMALL, i);
+		t.value = dtlb_tag_read_read(TLB_ISMALL, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_IBIG contents:\n");
+	for (i = 0; i < tlb_ibig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_IBIG, i);
+		t.value = dtlb_tag_read_read(TLB_IBIG, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DSMALL contents:\n");
+	for (i = 0; i < tlb_dsmall_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DSMALL, i);
+		t.value = dtlb_tag_read_read(TLB_DSMALL, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DBIG_1 contents:\n");
+	for (i = 0; i < tlb_dbig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DBIG_0, i);
+		t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DBIG_2 contents:\n");
+	for (i = 0; i < tlb_dbig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DBIG_1, i);
+		t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
+		print_tlb_entry(i, t, d);
+	}
+}
+
+#endif
+
+void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
+    const char *str)
+{
+	fault_if_from_uspace(istate, "%s.", str);
+	dump_istate(istate);
+	panic("%s.", str);
+}
+
+void do_fast_data_access_mmu_miss_fault(istate_t *istate,
+    tlb_tag_access_reg_t tag, const char *str)
+{
+	uintptr_t va;
+
+	va = tag.vpn << MMU_PAGE_WIDTH;
+	if (tag.context) {
+		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+		    tag.context);
+	}
+	dump_istate(istate);
+	printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
+	panic("%s.", str);
+}
+
+void do_fast_data_access_protection_fault(istate_t *istate,
+    tlb_tag_access_reg_t tag, const char *str)
+{
+	uintptr_t va;
+
+	va = tag.vpn << MMU_PAGE_WIDTH;
+
+	if (tag.context) {
+		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+		    tag.context);
+	}
+	printf("Faulting page: %p, ASID=%d\n", va, tag.context);
+	dump_istate(istate);
+	panic("%s.", str);
+}
+
+void dump_sfsr_and_sfar(void)
+{
+	tlb_sfsr_reg_t sfsr;
+	uintptr_t sfar;
+
+	sfsr.value = dtlb_sfsr_read();
+	sfar = dtlb_sfar_read();
+	
+#if defined (US)
+	printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
+	    "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
+	    sfsr.ow, sfsr.fv);
+#elif defined (US3)
+	printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
+	    "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
+	    sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
+#endif
+	    
+	printf("DTLB SFAR: address=%p\n", sfar);
+	
+	dtlb_sfsr_write(0);
+}
+
+#if defined (US)
+/** Invalidate all unlocked ITLB and DTLB entries. */
+void tlb_invalidate_all(void)
+{
+	int i;
+	
+	/*
+	 * Walk all ITLB and DTLB entries and remove all unlocked mappings.
+	 *
+	 * The kernel doesn't use global mappings so any locked global mappings
+	 * found must have been created by someone else. Their only purpose now
+	 * is to collide with proper mappings. Invalidate immediately. It should
+	 * be safe to invalidate them as late as now.
+	 */
+
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+
+	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
+		d.value = itlb_data_access_read(i);
+		if (!d.l || d.g) {
+			t.value = itlb_tag_read_read(i);
+			d.v = false;
+			itlb_tag_access_write(t.value);
+			itlb_data_access_write(i, d.value);
+		}
+	}
+
+	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
+		d.value = dtlb_data_access_read(i);
+		if (!d.l || d.g) {
+			t.value = dtlb_tag_read_read(i);
+			d.v = false;
+			dtlb_tag_access_write(t.value);
+			dtlb_data_access_write(i, d.value);
+		}
+	}
+
+}
+
+#elif defined (US3)
+
+/** Invalidate all unlocked ITLB and DTLB entries. */
+void tlb_invalidate_all(void)
+{
+	itlb_demap(TLB_DEMAP_ALL, 0, 0);
+	dtlb_demap(TLB_DEMAP_ALL, 0, 0);
+}
+
+#endif
+
+/** Invalidate all ITLB and DTLB entries that belong to specified ASID
+ * (Context).
+ *
+ * @param asid Address Space ID.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	tlb_context_reg_t pc_save, ctx;
+	
+	/* switch to nucleus because we are mapped by the primary context */
+	nucleus_enter();
+	
+	ctx.v = pc_save.v = mmu_primary_context_read();
+	ctx.context = asid;
+	mmu_primary_context_write(ctx.v);
+	
+	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
+	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
+	
+	mmu_primary_context_write(pc_save.v);
+	
+	nucleus_leave();
+}
+
+/** Invalidate all ITLB and DTLB entries for specified page range in specified
+ * address space.
+ *
+ * @param asid		Address Space ID.
+ * @param page		First page which to sweep out from ITLB and DTLB.
+ * @param cnt		Number of ITLB and DTLB entries to invalidate.
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
+{
+	unsigned int i;
+	tlb_context_reg_t pc_save, ctx;
+	
+	/* switch to nucleus because we are mapped by the primary context */
+	nucleus_enter();
+	
+	ctx.v = pc_save.v = mmu_primary_context_read();
+	ctx.context = asid;
+	mmu_primary_context_write(ctx.v);
+	
+	for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
+		itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
+		    page + i * MMU_PAGE_SIZE);
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
+		    page + i * MMU_PAGE_SIZE);
+	}
+	
+	mmu_primary_context_write(pc_save.v);
+	
+	nucleus_leave();
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/mm/sun4v/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <arch/boot/boot.h>
+#include <arch/types.h>
+#include <config.h>
+#include <align.h>
+#include <macros.h>
+
+uintptr_t last_frame = NULL;
+
+/** Create memory zones according to information stored in bootinfo.
+ *
+ * Walk the bootinfo memory map and create frame zones according to it.
+ */
+void frame_arch_init(void)
+{
+	unsigned int i;
+	pfn_t confdata;
+
+	if (config.cpu_active == 1) {
+		for (i = 0; i < bootinfo.memmap.count; i++) {
+			uintptr_t start = bootinfo.memmap.zones[i].start;
+			size_t size = bootinfo.memmap.zones[i].size;
+
+			/*
+			 * The memmap is created by HelenOS boot loader.
+			 * It already contains no holes.
+			 */
+
+			confdata = ADDR2PFN(start);
+			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
+				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
+			zone_create(ADDR2PFN(start),
+			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			    confdata, 0);
+			last_frame = max(last_frame, start + ALIGN_UP(size,
+			    FRAME_SIZE));
+		}
+
+		/*
+		 * On sparc64, physical memory can start on a non-zero address.
+		 * The generic frame_init() only marks PFN 0 as not free, so we
+		 * must mark the physically first frame not free explicitly
+		 * here, no matter what is its address.
+		 */
+		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
+	}
+
+//MH
+//	end_of_identity = PA2KA(last_frame);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,609 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64mm	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/tlb.h>
+#include <mm/tlb.h>
+#include <mm/as.h>
+#include <mm/asid.h>
+#include <arch/mm/frame.h>
+#include <arch/mm/page.h>
+#include <arch/mm/mmu.h>
+#include <arch/interrupt.h>
+#include <interrupt.h>
+#include <arch.h>
+#include <print.h>
+#include <arch/types.h>
+#include <config.h>
+#include <arch/trap/trap.h>
+#include <arch/trap/exception.h>
+#include <panic.h>
+#include <arch/asm.h>
+
+#ifdef CONFIG_TSB
+#include <arch/mm/tsb.h>
+#endif
+
+static void dtlb_pte_copy(pte_t *, size_t, bool);
+static void itlb_pte_copy(pte_t *, size_t);
+static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
+static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
+    const char *);
+static void do_fast_data_access_protection_fault(istate_t *,
+    tlb_tag_access_reg_t, const char *);
+
+char *context_encoding[] = {
+	"Primary",
+	"Secondary",
+	"Nucleus",
+	"Reserved"
+};
+
+void tlb_arch_init(void)
+{
+	/*
+	 * Invalidate all non-locked DTLB and ITLB entries.
+	 */
+	tlb_invalidate_all();
+
+	/*
+	 * Clear both SFSRs.
+	 */
+	dtlb_sfsr_write(0);
+	itlb_sfsr_write(0);
+}
+
+/** Insert privileged mapping into DMMU TLB.
+ *
+ * @param page		Virtual page address.
+ * @param frame		Physical frame address.
+ * @param pagesize	Page size.
+ * @param locked	True for permanent mappings, false otherwise.
+ * @param cacheable	True if the mapping is cacheable, false otherwise.
+ */
+void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
+    bool locked, bool cacheable)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = page;
+	fr.address = frame;
+
+	tag.context = ASID_KERNEL;
+	tag.vpn = pg.vpn;
+
+	dtlb_tag_access_write(tag.value);
+
+	data.value = 0;
+	data.v = true;
+	data.size = pagesize;
+	data.pfn = fr.pfn;
+	data.l = locked;
+	data.cp = cacheable;
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	data.cv = cacheable;
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+	data.p = true;
+	data.w = true;
+	data.g = false;
+
+	dtlb_data_in_write(data.value);
+}
+
+/** Copy PTE to TLB.
+ *
+ * @param t 		Page Table Entry to be copied.
+ * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
+ * @param ro		If true, the entry will be created read-only, regardless
+ * 			of its w field.
+ */
+void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page + (index << MMU_PAGE_WIDTH);
+	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+
+	dtlb_tag_access_write(tag.value);
+
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	data.cv = t->c;
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+	data.p = t->k;		/* p like privileged */
+	data.w = ro ? false : t->w;
+	data.g = t->g;
+
+	dtlb_data_in_write(data.value);
+}
+
+/** Copy PTE to ITLB.
+ *
+ * @param t		Page Table Entry to be copied.
+ * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
+ */
+void itlb_pte_copy(pte_t *t, size_t index)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page + (index << MMU_PAGE_WIDTH);
+	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+	
+	itlb_tag_access_write(tag.value);
+	
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+	data.p = t->k;		/* p like privileged */
+	data.w = false;
+	data.g = t->g;
+	
+	itlb_data_in_write(data.value);
+}
+
+/** ITLB miss handler. */
+void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
+{
+	uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
+	size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
+	pte_t *t;
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t && PTE_EXECUTABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into ITLB.
+		 */
+		t->a = true;
+		itlb_pte_copy(t, index);
+#ifdef CONFIG_TSB
+		itsb_pte_copy(t, index);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_instruction_access_mmu_miss_fault(istate,
+			    __func__);
+		}
+	}
+}
+
+/** DTLB miss handler.
+ *
+ * Note that some faults (e.g. kernel faults) were already resolved by the
+ * low-level, assembly language part of the fast_data_access_mmu_miss handler.
+ *
+ * @param tag		Content of the TLB Tag Access register as it existed
+ * 			when the trap happened. This is to prevent confusion
+ * 			created by clobbered Tag Access register during a nested
+ * 			DTLB miss.
+ * @param istate	Interrupted state saved on the stack.
+ */
+void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
+{
+	uintptr_t page_8k;
+	uintptr_t page_16k;
+	size_t index;
+	pte_t *t;
+
+	page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
+	page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
+	index = tag.vpn % MMU_PAGES_PER_PAGE;
+
+	if (tag.context == ASID_KERNEL) {
+		if (!tag.vpn) {
+			/* NULL access in kernel */
+			do_fast_data_access_mmu_miss_fault(istate, tag,
+			    __func__);
+//MH
+		} else {
+//		} else if (page_8k >= end_of_identity) {
+			/*
+			 * The kernel is accessing the I/O space.
+			 * We still do identity mapping for I/O,
+			 * but without caching.
+			 */
+			dtlb_insert_mapping(page_8k, KA2PA(page_8k),
+			    PAGESIZE_8K, false, false);
+			return;
+		}
+		do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
+		    "kernel page fault.");
+	}
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into DTLB.
+		 */
+		t->a = true;
+		dtlb_pte_copy(t, index, true);
+#ifdef CONFIG_TSB
+		dtsb_pte_copy(t, index, true);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_data_access_mmu_miss_fault(istate, tag,
+			    __func__);
+		}
+	}
+}
+
+/** DTLB protection fault handler.
+ *
+ * @param tag		Content of the TLB Tag Access register as it existed
+ * 			when the trap happened. This is to prevent confusion
+ * 			created by clobbered Tag Access register during a nested
+ * 			DTLB miss.
+ * @param istate	Interrupted state saved on the stack.
+ */
+void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
+{
+	uintptr_t page_16k;
+	size_t index;
+	pte_t *t;
+
+	page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
+	index = tag.vpn % MMU_PAGES_PER_PAGE;	/* 16K-page emulation */
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, page_16k);
+	if (t && PTE_WRITABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table and is
+		 * writable. Demap the old mapping and insert an updated mapping
+		 * into DTLB.
+		 */
+		t->a = true;
+		t->d = true;
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
+		    page_16k + index * MMU_PAGE_SIZE);
+		dtlb_pte_copy(t, index, false);
+#ifdef CONFIG_TSB
+		dtsb_pte_copy(t, index, false);
+#endif
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault
+		 * handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
+		    AS_PF_FAULT) {
+			do_fast_data_access_protection_fault(istate, tag,
+			    __func__);
+		}
+	}
+}
+
+/** Print TLB entry (for debugging purposes).
+ *
+ * The diag field has been left out in order to make this function more generic
+ * (there is no diag field in US3 architeture). 
+ *
+ * @param i		TLB entry number 
+ * @param t		TLB entry tag
+ * @param d		TLB entry data 
+ */
+static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
+{
+	printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
+	    "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
+	    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
+	    t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
+	    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
+}
+
+#if defined (US)
+
+/** Print contents of both TLBs. */
+void tlb_print(void)
+{
+	int i;
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+	
+	printf("I-TLB contents:\n");
+	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
+		d.value = itlb_data_access_read(i);
+		t.value = itlb_tag_read_read(i);
+		print_tlb_entry(i, t, d);
+	}
+
+	printf("D-TLB contents:\n");
+	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
+		d.value = dtlb_data_access_read(i);
+		t.value = dtlb_tag_read_read(i);
+		print_tlb_entry(i, t, d);
+	}
+}
+
+#elif defined (US3)
+
+/** Print contents of all TLBs. */
+void tlb_print(void)
+{
+	int i;
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+	
+	printf("TLB_ISMALL contents:\n");
+	for (i = 0; i < tlb_ismall_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_ISMALL, i);
+		t.value = dtlb_tag_read_read(TLB_ISMALL, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_IBIG contents:\n");
+	for (i = 0; i < tlb_ibig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_IBIG, i);
+		t.value = dtlb_tag_read_read(TLB_IBIG, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DSMALL contents:\n");
+	for (i = 0; i < tlb_dsmall_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DSMALL, i);
+		t.value = dtlb_tag_read_read(TLB_DSMALL, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DBIG_1 contents:\n");
+	for (i = 0; i < tlb_dbig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DBIG_0, i);
+		t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
+		print_tlb_entry(i, t, d);
+	}
+	
+	printf("TLB_DBIG_2 contents:\n");
+	for (i = 0; i < tlb_dbig_size(); i++) {
+		d.value = dtlb_data_access_read(TLB_DBIG_1, i);
+		t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
+		print_tlb_entry(i, t, d);
+	}
+}
+
+#endif
+
+void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
+    const char *str)
+{
+	fault_if_from_uspace(istate, "%s.", str);
+	dump_istate(istate);
+	panic("%s.", str);
+}
+
+void do_fast_data_access_mmu_miss_fault(istate_t *istate,
+    tlb_tag_access_reg_t tag, const char *str)
+{
+	uintptr_t va;
+
+	va = tag.vpn << MMU_PAGE_WIDTH;
+	if (tag.context) {
+		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+		    tag.context);
+	}
+	dump_istate(istate);
+	printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
+	panic("%s.", str);
+}
+
+void do_fast_data_access_protection_fault(istate_t *istate,
+    tlb_tag_access_reg_t tag, const char *str)
+{
+	uintptr_t va;
+
+	va = tag.vpn << MMU_PAGE_WIDTH;
+
+	if (tag.context) {
+		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+		    tag.context);
+	}
+	printf("Faulting page: %p, ASID=%d\n", va, tag.context);
+	dump_istate(istate);
+	panic("%s.", str);
+}
+
+void dump_sfsr_and_sfar(void)
+{
+	tlb_sfsr_reg_t sfsr;
+	uintptr_t sfar;
+
+	sfsr.value = dtlb_sfsr_read();
+	sfar = dtlb_sfar_read();
+	
+#if defined (US)
+	printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
+	    "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
+	    sfsr.ow, sfsr.fv);
+#elif defined (US3)
+	printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
+	    "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
+	    sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
+#endif
+	    
+	printf("DTLB SFAR: address=%p\n", sfar);
+	
+	dtlb_sfsr_write(0);
+}
+
+#if defined (US)
+/** Invalidate all unlocked ITLB and DTLB entries. */
+void tlb_invalidate_all(void)
+{
+	int i;
+	
+	/*
+	 * Walk all ITLB and DTLB entries and remove all unlocked mappings.
+	 *
+	 * The kernel doesn't use global mappings so any locked global mappings
+	 * found must have been created by someone else. Their only purpose now
+	 * is to collide with proper mappings. Invalidate immediately. It should
+	 * be safe to invalidate them as late as now.
+	 */
+
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+
+	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
+		d.value = itlb_data_access_read(i);
+		if (!d.l || d.g) {
+			t.value = itlb_tag_read_read(i);
+			d.v = false;
+			itlb_tag_access_write(t.value);
+			itlb_data_access_write(i, d.value);
+		}
+	}
+
+	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
+		d.value = dtlb_data_access_read(i);
+		if (!d.l || d.g) {
+			t.value = dtlb_tag_read_read(i);
+			d.v = false;
+			dtlb_tag_access_write(t.value);
+			dtlb_data_access_write(i, d.value);
+		}
+	}
+
+}
+
+#elif defined (US3)
+
+/** Invalidate all unlocked ITLB and DTLB entries. */
+void tlb_invalidate_all(void)
+{
+	itlb_demap(TLB_DEMAP_ALL, 0, 0);
+	dtlb_demap(TLB_DEMAP_ALL, 0, 0);
+}
+
+#endif
+
+/** Invalidate all ITLB and DTLB entries that belong to specified ASID
+ * (Context).
+ *
+ * @param asid Address Space ID.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	tlb_context_reg_t pc_save, ctx;
+	
+	/* switch to nucleus because we are mapped by the primary context */
+	nucleus_enter();
+	
+	ctx.v = pc_save.v = mmu_primary_context_read();
+	ctx.context = asid;
+	mmu_primary_context_write(ctx.v);
+	
+	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
+	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
+	
+	mmu_primary_context_write(pc_save.v);
+	
+	nucleus_leave();
+}
+
+/** Invalidate all ITLB and DTLB entries for specified page range in specified
+ * address space.
+ *
+ * @param asid		Address Space ID.
+ * @param page		First page which to sweep out from ITLB and DTLB.
+ * @param cnt		Number of ITLB and DTLB entries to invalidate.
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
+{
+	unsigned int i;
+	tlb_context_reg_t pc_save, ctx;
+	
+	/* switch to nucleus because we are mapped by the primary context */
+	nucleus_enter();
+	
+	ctx.v = pc_save.v = mmu_primary_context_read();
+	ctx.context = asid;
+	mmu_primary_context_write(ctx.v);
+	
+	for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
+		itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
+		    page + i * MMU_PAGE_SIZE);
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
+		    page + i * MMU_PAGE_SIZE);
+	}
+	
+	mmu_primary_context_write(pc_save.v);
+	
+	nucleus_leave();
+}
+
+/** @}
+ */
Index: rnel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ 	(revision )
@@ -1,607 +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.
- */
-
-/** @addtogroup sparc64mm	
- * @{
- */
-/** @file
- */
-
-#include <arch/mm/tlb.h>
-#include <mm/tlb.h>
-#include <mm/as.h>
-#include <mm/asid.h>
-#include <arch/mm/frame.h>
-#include <arch/mm/page.h>
-#include <arch/mm/mmu.h>
-#include <arch/interrupt.h>
-#include <interrupt.h>
-#include <arch.h>
-#include <print.h>
-#include <arch/types.h>
-#include <config.h>
-#include <arch/trap/trap.h>
-#include <arch/trap/exception.h>
-#include <panic.h>
-#include <arch/asm.h>
-
-#ifdef CONFIG_TSB
-#include <arch/mm/tsb.h>
-#endif
-
-static void dtlb_pte_copy(pte_t *, size_t, bool);
-static void itlb_pte_copy(pte_t *, size_t);
-static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
-static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
-    const char *);
-static void do_fast_data_access_protection_fault(istate_t *,
-    tlb_tag_access_reg_t, const char *);
-
-char *context_encoding[] = {
-	"Primary",
-	"Secondary",
-	"Nucleus",
-	"Reserved"
-};
-
-void tlb_arch_init(void)
-{
-	/*
-	 * Invalidate all non-locked DTLB and ITLB entries.
-	 */
-	tlb_invalidate_all();
-
-	/*
-	 * Clear both SFSRs.
-	 */
-	dtlb_sfsr_write(0);
-	itlb_sfsr_write(0);
-}
-
-/** Insert privileged mapping into DMMU TLB.
- *
- * @param page		Virtual page address.
- * @param frame		Physical frame address.
- * @param pagesize	Page size.
- * @param locked	True for permanent mappings, false otherwise.
- * @param cacheable	True if the mapping is cacheable, false otherwise.
- */
-void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
-    bool locked, bool cacheable)
-{
-	tlb_tag_access_reg_t tag;
-	tlb_data_t data;
-	page_address_t pg;
-	frame_address_t fr;
-
-	pg.address = page;
-	fr.address = frame;
-
-	tag.context = ASID_KERNEL;
-	tag.vpn = pg.vpn;
-
-	dtlb_tag_access_write(tag.value);
-
-	data.value = 0;
-	data.v = true;
-	data.size = pagesize;
-	data.pfn = fr.pfn;
-	data.l = locked;
-	data.cp = cacheable;
-#ifdef CONFIG_VIRT_IDX_DCACHE
-	data.cv = cacheable;
-#endif /* CONFIG_VIRT_IDX_DCACHE */
-	data.p = true;
-	data.w = true;
-	data.g = false;
-
-	dtlb_data_in_write(data.value);
-}
-
-/** Copy PTE to TLB.
- *
- * @param t 		Page Table Entry to be copied.
- * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
- * @param ro		If true, the entry will be created read-only, regardless
- * 			of its w field.
- */
-void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
-{
-	tlb_tag_access_reg_t tag;
-	tlb_data_t data;
-	page_address_t pg;
-	frame_address_t fr;
-
-	pg.address = t->page + (index << MMU_PAGE_WIDTH);
-	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
-
-	tag.value = 0;
-	tag.context = t->as->asid;
-	tag.vpn = pg.vpn;
-
-	dtlb_tag_access_write(tag.value);
-
-	data.value = 0;
-	data.v = true;
-	data.size = PAGESIZE_8K;
-	data.pfn = fr.pfn;
-	data.l = false;
-	data.cp = t->c;
-#ifdef CONFIG_VIRT_IDX_DCACHE
-	data.cv = t->c;
-#endif /* CONFIG_VIRT_IDX_DCACHE */
-	data.p = t->k;		/* p like privileged */
-	data.w = ro ? false : t->w;
-	data.g = t->g;
-
-	dtlb_data_in_write(data.value);
-}
-
-/** Copy PTE to ITLB.
- *
- * @param t		Page Table Entry to be copied.
- * @param index		Zero if lower 8K-subpage, one if higher 8K-subpage.
- */
-void itlb_pte_copy(pte_t *t, size_t index)
-{
-	tlb_tag_access_reg_t tag;
-	tlb_data_t data;
-	page_address_t pg;
-	frame_address_t fr;
-
-	pg.address = t->page + (index << MMU_PAGE_WIDTH);
-	fr.address = t->frame + (index << MMU_PAGE_WIDTH);
-
-	tag.value = 0;
-	tag.context = t->as->asid;
-	tag.vpn = pg.vpn;
-	
-	itlb_tag_access_write(tag.value);
-	
-	data.value = 0;
-	data.v = true;
-	data.size = PAGESIZE_8K;
-	data.pfn = fr.pfn;
-	data.l = false;
-	data.cp = t->c;
-	data.p = t->k;		/* p like privileged */
-	data.w = false;
-	data.g = t->g;
-	
-	itlb_data_in_write(data.value);
-}
-
-/** ITLB miss handler. */
-void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
-{
-	uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
-	size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
-	pte_t *t;
-
-	page_table_lock(AS, true);
-	t = page_mapping_find(AS, page_16k);
-	if (t && PTE_EXECUTABLE(t)) {
-		/*
-		 * The mapping was found in the software page hash table.
-		 * Insert it into ITLB.
-		 */
-		t->a = true;
-		itlb_pte_copy(t, index);
-#ifdef CONFIG_TSB
-		itsb_pte_copy(t, index);
-#endif
-		page_table_unlock(AS, true);
-	} else {
-		/*
-		 * Forward the page fault to the address space page fault
-		 * handler.
-		 */		
-		page_table_unlock(AS, true);
-		if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
-		    AS_PF_FAULT) {
-			do_fast_instruction_access_mmu_miss_fault(istate,
-			    __func__);
-		}
-	}
-}
-
-/** DTLB miss handler.
- *
- * Note that some faults (e.g. kernel faults) were already resolved by the
- * low-level, assembly language part of the fast_data_access_mmu_miss handler.
- *
- * @param tag		Content of the TLB Tag Access register as it existed
- * 			when the trap happened. This is to prevent confusion
- * 			created by clobbered Tag Access register during a nested
- * 			DTLB miss.
- * @param istate	Interrupted state saved on the stack.
- */
-void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
-{
-	uintptr_t page_8k;
-	uintptr_t page_16k;
-	size_t index;
-	pte_t *t;
-
-	page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
-	page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
-	index = tag.vpn % MMU_PAGES_PER_PAGE;
-
-	if (tag.context == ASID_KERNEL) {
-		if (!tag.vpn) {
-			/* NULL access in kernel */
-			do_fast_data_access_mmu_miss_fault(istate, tag,
-			    __func__);
-		} else if (page_8k >= end_of_identity) {
-			/*
-			 * The kernel is accessing the I/O space.
-			 * We still do identity mapping for I/O,
-			 * but without caching.
-			 */
-			dtlb_insert_mapping(page_8k, KA2PA(page_8k),
-			    PAGESIZE_8K, false, false);
-			return;
-		}
-		do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
-		    "kernel page fault.");
-	}
-
-	page_table_lock(AS, true);
-	t = page_mapping_find(AS, page_16k);
-	if (t) {
-		/*
-		 * The mapping was found in the software page hash table.
-		 * Insert it into DTLB.
-		 */
-		t->a = true;
-		dtlb_pte_copy(t, index, true);
-#ifdef CONFIG_TSB
-		dtsb_pte_copy(t, index, true);
-#endif
-		page_table_unlock(AS, true);
-	} else {
-		/*
-		 * Forward the page fault to the address space page fault
-		 * handler.
-		 */		
-		page_table_unlock(AS, true);
-		if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
-		    AS_PF_FAULT) {
-			do_fast_data_access_mmu_miss_fault(istate, tag,
-			    __func__);
-		}
-	}
-}
-
-/** DTLB protection fault handler.
- *
- * @param tag		Content of the TLB Tag Access register as it existed
- * 			when the trap happened. This is to prevent confusion
- * 			created by clobbered Tag Access register during a nested
- * 			DTLB miss.
- * @param istate	Interrupted state saved on the stack.
- */
-void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
-{
-	uintptr_t page_16k;
-	size_t index;
-	pte_t *t;
-
-	page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
-	index = tag.vpn % MMU_PAGES_PER_PAGE;	/* 16K-page emulation */
-
-	page_table_lock(AS, true);
-	t = page_mapping_find(AS, page_16k);
-	if (t && PTE_WRITABLE(t)) {
-		/*
-		 * The mapping was found in the software page hash table and is
-		 * writable. Demap the old mapping and insert an updated mapping
-		 * into DTLB.
-		 */
-		t->a = true;
-		t->d = true;
-		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
-		    page_16k + index * MMU_PAGE_SIZE);
-		dtlb_pte_copy(t, index, false);
-#ifdef CONFIG_TSB
-		dtsb_pte_copy(t, index, false);
-#endif
-		page_table_unlock(AS, true);
-	} else {
-		/*
-		 * Forward the page fault to the address space page fault
-		 * handler.
-		 */		
-		page_table_unlock(AS, true);
-		if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
-		    AS_PF_FAULT) {
-			do_fast_data_access_protection_fault(istate, tag,
-			    __func__);
-		}
-	}
-}
-
-/** Print TLB entry (for debugging purposes).
- *
- * The diag field has been left out in order to make this function more generic
- * (there is no diag field in US3 architeture). 
- *
- * @param i		TLB entry number 
- * @param t		TLB entry tag
- * @param d		TLB entry data 
- */
-static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
-{
-	printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
-	    "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
-	    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
-	    t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
-	    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
-}
-
-#if defined (US)
-
-/** Print contents of both TLBs. */
-void tlb_print(void)
-{
-	int i;
-	tlb_data_t d;
-	tlb_tag_read_reg_t t;
-	
-	printf("I-TLB contents:\n");
-	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
-		d.value = itlb_data_access_read(i);
-		t.value = itlb_tag_read_read(i);
-		print_tlb_entry(i, t, d);
-	}
-
-	printf("D-TLB contents:\n");
-	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
-		d.value = dtlb_data_access_read(i);
-		t.value = dtlb_tag_read_read(i);
-		print_tlb_entry(i, t, d);
-	}
-}
-
-#elif defined (US3)
-
-/** Print contents of all TLBs. */
-void tlb_print(void)
-{
-	int i;
-	tlb_data_t d;
-	tlb_tag_read_reg_t t;
-	
-	printf("TLB_ISMALL contents:\n");
-	for (i = 0; i < tlb_ismall_size(); i++) {
-		d.value = dtlb_data_access_read(TLB_ISMALL, i);
-		t.value = dtlb_tag_read_read(TLB_ISMALL, i);
-		print_tlb_entry(i, t, d);
-	}
-	
-	printf("TLB_IBIG contents:\n");
-	for (i = 0; i < tlb_ibig_size(); i++) {
-		d.value = dtlb_data_access_read(TLB_IBIG, i);
-		t.value = dtlb_tag_read_read(TLB_IBIG, i);
-		print_tlb_entry(i, t, d);
-	}
-	
-	printf("TLB_DSMALL contents:\n");
-	for (i = 0; i < tlb_dsmall_size(); i++) {
-		d.value = dtlb_data_access_read(TLB_DSMALL, i);
-		t.value = dtlb_tag_read_read(TLB_DSMALL, i);
-		print_tlb_entry(i, t, d);
-	}
-	
-	printf("TLB_DBIG_1 contents:\n");
-	for (i = 0; i < tlb_dbig_size(); i++) {
-		d.value = dtlb_data_access_read(TLB_DBIG_0, i);
-		t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
-		print_tlb_entry(i, t, d);
-	}
-	
-	printf("TLB_DBIG_2 contents:\n");
-	for (i = 0; i < tlb_dbig_size(); i++) {
-		d.value = dtlb_data_access_read(TLB_DBIG_1, i);
-		t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
-		print_tlb_entry(i, t, d);
-	}
-}
-
-#endif
-
-void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
-    const char *str)
-{
-	fault_if_from_uspace(istate, "%s.", str);
-	dump_istate(istate);
-	panic("%s.", str);
-}
-
-void do_fast_data_access_mmu_miss_fault(istate_t *istate,
-    tlb_tag_access_reg_t tag, const char *str)
-{
-	uintptr_t va;
-
-	va = tag.vpn << MMU_PAGE_WIDTH;
-	if (tag.context) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-		    tag.context);
-	}
-	dump_istate(istate);
-	printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
-	panic("%s.", str);
-}
-
-void do_fast_data_access_protection_fault(istate_t *istate,
-    tlb_tag_access_reg_t tag, const char *str)
-{
-	uintptr_t va;
-
-	va = tag.vpn << MMU_PAGE_WIDTH;
-
-	if (tag.context) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-		    tag.context);
-	}
-	printf("Faulting page: %p, ASID=%d\n", va, tag.context);
-	dump_istate(istate);
-	panic("%s.", str);
-}
-
-void dump_sfsr_and_sfar(void)
-{
-	tlb_sfsr_reg_t sfsr;
-	uintptr_t sfar;
-
-	sfsr.value = dtlb_sfsr_read();
-	sfar = dtlb_sfar_read();
-	
-#if defined (US)
-	printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
-	    "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
-	    sfsr.ow, sfsr.fv);
-#elif defined (US3)
-	printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
-	    "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
-	    sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
-#endif
-	    
-	printf("DTLB SFAR: address=%p\n", sfar);
-	
-	dtlb_sfsr_write(0);
-}
-
-#if defined (US)
-/** Invalidate all unlocked ITLB and DTLB entries. */
-void tlb_invalidate_all(void)
-{
-	int i;
-	
-	/*
-	 * Walk all ITLB and DTLB entries and remove all unlocked mappings.
-	 *
-	 * The kernel doesn't use global mappings so any locked global mappings
-	 * found must have been created by someone else. Their only purpose now
-	 * is to collide with proper mappings. Invalidate immediately. It should
-	 * be safe to invalidate them as late as now.
-	 */
-
-	tlb_data_t d;
-	tlb_tag_read_reg_t t;
-
-	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
-		d.value = itlb_data_access_read(i);
-		if (!d.l || d.g) {
-			t.value = itlb_tag_read_read(i);
-			d.v = false;
-			itlb_tag_access_write(t.value);
-			itlb_data_access_write(i, d.value);
-		}
-	}
-
-	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
-		d.value = dtlb_data_access_read(i);
-		if (!d.l || d.g) {
-			t.value = dtlb_tag_read_read(i);
-			d.v = false;
-			dtlb_tag_access_write(t.value);
-			dtlb_data_access_write(i, d.value);
-		}
-	}
-
-}
-
-#elif defined (US3)
-
-/** Invalidate all unlocked ITLB and DTLB entries. */
-void tlb_invalidate_all(void)
-{
-	itlb_demap(TLB_DEMAP_ALL, 0, 0);
-	dtlb_demap(TLB_DEMAP_ALL, 0, 0);
-}
-
-#endif
-
-/** Invalidate all ITLB and DTLB entries that belong to specified ASID
- * (Context).
- *
- * @param asid Address Space ID.
- */
-void tlb_invalidate_asid(asid_t asid)
-{
-	tlb_context_reg_t pc_save, ctx;
-	
-	/* switch to nucleus because we are mapped by the primary context */
-	nucleus_enter();
-	
-	ctx.v = pc_save.v = mmu_primary_context_read();
-	ctx.context = asid;
-	mmu_primary_context_write(ctx.v);
-	
-	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
-	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
-	
-	mmu_primary_context_write(pc_save.v);
-	
-	nucleus_leave();
-}
-
-/** Invalidate all ITLB and DTLB entries for specified page range in specified
- * address space.
- *
- * @param asid		Address Space ID.
- * @param page		First page which to sweep out from ITLB and DTLB.
- * @param cnt		Number of ITLB and DTLB entries to invalidate.
- */
-void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
-{
-	unsigned int i;
-	tlb_context_reg_t pc_save, ctx;
-	
-	/* switch to nucleus because we are mapped by the primary context */
-	nucleus_enter();
-	
-	ctx.v = pc_save.v = mmu_primary_context_read();
-	ctx.context = asid;
-	mmu_primary_context_write(ctx.v);
-	
-	for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
-		itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
-		    page + i * MMU_PAGE_SIZE);
-		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
-		    page + i * MMU_PAGE_SIZE);
-	}
-	
-	mmu_primary_context_write(pc_save.v);
-	
-	nucleus_leave();
-}
-
-/** @}
- */
Index: rnel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ 	(revision )
@@ -1,169 +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.
- */
-
-/** @addtogroup sparc64
- * @{
- */
-/** @file
- */
-
-#include <arch.h>
-#include <debug.h>
-#include <config.h>
-#include <arch/trap/trap.h>
-#include <arch/console.h>
-#include <console/console.h>
-#include <arch/boot/boot.h>
-#include <arch/arch.h>
-#include <arch/asm.h>
-#include <arch/mm/page.h>
-#include <arch/stack.h>
-#include <genarch/ofw/ofw_tree.h>
-#include <userspace.h>
-#include <ddi/irq.h>
-#include <string.h>
-
-bootinfo_t bootinfo;
-
-/** Perform sparc64-specific initialization before main_bsp() is called. */
-void arch_pre_main(void)
-{
-	/* Copy init task info. */
-	init.cnt = bootinfo.taskmap.count;
-	
-	uint32_t i;
-
-	for (i = 0; i < bootinfo.taskmap.count; i++) {
-		init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr;
-		init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
-		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
-		    bootinfo.taskmap.tasks[i].name);
-	}
-	
-	/* Copy boot allocations info. */
-	ballocs.base = bootinfo.ballocs.base;
-	ballocs.size = bootinfo.ballocs.size;
-	
-	ofw_tree_init(bootinfo.ofw_root);
-}
-
-/** Perform sparc64 specific initialization before mm is initialized. */
-void arch_pre_mm_init(void)
-{
-	if (config.cpu_active == 1)
-		trap_init();
-}
-
-/** Perform sparc64 specific initialization afterr mm is initialized. */
-void arch_post_mm_init(void)
-{
-	if (config.cpu_active == 1) {
-		/*
-		 * We have 2^11 different interrupt vectors.
-		 * But we only create 128 buckets.
-		 */
-		irq_init(1 << 11, 128);
-	}
-}
-
-void arch_post_cpu_init(void)
-{
-}
-
-void arch_pre_smp_init(void)
-{
-}
-
-void arch_post_smp_init(void)
-{
-	standalone_sparc64_console_init();
-}
-
-/** Calibrate delay loop.
- *
- * On sparc64, we implement delay() by waiting for the TICK register to
- * reach a pre-computed value, as opposed to performing some pre-computed
- * amount of instructions of known duration. We set the delay_loop_const
- * to 1 in order to neutralize the multiplication done by delay().
- */
-void calibrate_delay_loop(void)
-{
-	CPU->delay_loop_const = 1;
-}
-
-/** Wait several microseconds.
- *
- * We assume that interrupts are already disabled.
- *
- * @param t Microseconds to wait.
- */
-void asm_delay_loop(const uint32_t usec)
-{
-	uint64_t stop = tick_read() + (uint64_t) usec * (uint64_t)
-	    CPU->arch.clock_frequency / 1000000;
-
-	while (tick_read() < stop)
-		;
-}
-
-/** Switch to userspace. */
-void userspace(uspace_arg_t *kernel_uarg)
-{
-	(void) interrupts_disable();
-	switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
-	    ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE
-	    - (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
-	    (uintptr_t) kernel_uarg->uspace_uarg);
-
-	for (;;)
-		;
-	/* not reached */
-}
-
-void arch_reboot(void)
-{
-	// TODO
-	while (1);
-}
-
-/** Construct function pointer
- *
- * @param fptr   function pointer structure
- * @param addr   function address
- * @param caller calling function address
- *
- * @return address of the function pointer
- *
- */
-void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
-{
-	return addr;
-}
-
-/** @}
- */
Index: rnel/arch/sparc64/src/start.S
===================================================================
--- kernel/arch/sparc64/src/start.S	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ 	(revision )
@@ -1,417 +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.
-#
-
-#include <arch/arch.h>
-#include <arch/cpu.h>
-#include <arch/regdef.h>
-#include <arch/boot/boot.h>
-#include <arch/stack.h>
-
-#include <arch/mm/mmu.h>
-#include <arch/mm/tlb.h>
-#include <arch/mm/tte.h>
-
-#ifdef CONFIG_SMP
-#include <arch/context_offset.h>
-#endif
-
-.register %g2, #scratch
-.register %g3, #scratch
-
-.section K_TEXT_START, "ax"
-
-#define BSP_FLAG	1
-
-/*
- * 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
- * a given processor.
- */
-#if defined (US)
-    #define PHYSMEM_ADDR_SIZE	41
-#elif defined (US3)
-    #define PHYSMEM_ADDR_SIZE	43
-#endif
-
-/*
- * Here is where the kernel is passed control from the boot loader.
- * 
- * The registers are expected to be in this state:
- * - %o0 starting address of physical memory + bootstrap processor flag
- * 	bits 63...1:	physical memory starting address / 2
- *	bit 0:		non-zero on BSP processor, zero on AP processors
- * - %o1 bootinfo structure address (BSP only)
- * - %o2 bootinfo structure size (BSP only)
- *
- * Moreover, we depend on boot having established the following environment:
- * - TLBs are on
- * - identity mapping for the kernel image
- */
-
-.global kernel_image_start
-kernel_image_start:
-	mov BSP_FLAG, %l0
-	and %o0, %l0, %l7			! l7 <= bootstrap processor?
-	andn %o0, %l0, %l6			! l6 <= start of physical memory
-
-	! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
-	srlx %l6, 13, %l5
-	
-	! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
-	sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
-	srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5	
-
-	/*
-	 * Setup basic runtime environment.
-	 */
-
-	wrpr %g0, NWINDOWS - 2, %cansave	! set maximum saveable windows
-	wrpr %g0, 0, %canrestore		! get rid of windows we will
-						! never need again
-	wrpr %g0, 0, %otherwin			! make sure the window state is
-						! consistent
-	wrpr %g0, NWINDOWS - 1, %cleanwin	! prevent needless clean_window
-						! traps for kernel
-						
-	wrpr %g0, 0, %wstate			! use default spill/fill trap
-
-	wrpr %g0, 0, %tl			! TL = 0, primary context
-						! register is used
-
-	wrpr %g0, PSTATE_PRIV_BIT, %pstate	! disable interrupts and disable
-						! 32-bit address masking
-
-	wrpr %g0, 0, %pil			! intialize %pil
-
-	/*
-	 * Switch to kernel trap table.
-	 */
-	sethi %hi(trap_table), %g1
-	wrpr %g1, %lo(trap_table), %tba
-
-	/* 
-	 * Take over the DMMU by installing locked TTE entry identically
-	 * mapping the first 4M of memory.
-	 *
-	 * In case of DMMU, no FLUSH instructions need to be issued. Because of
-	 * that, the old DTLB contents can be demapped pretty straightforwardly
-	 * and without causing any traps.
-	 */
-
-	wr %g0, ASI_DMMU, %asi
-
-#define SET_TLB_DEMAP_CMD(r1, context_id) \
-	set (TLB_DEMAP_CONTEXT << TLB_DEMAP_TYPE_SHIFT) | (context_id << \
-		TLB_DEMAP_CONTEXT_SHIFT), %r1
-	
-	! demap context 0
-	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
-	stxa %g0, [%g1] ASI_DMMU_DEMAP			
-	membar #Sync
-
-#define SET_TLB_TAG(r1, context) \
-	set VMA | (context << TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1
-
-	! write DTLB tag
-	SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
-	stxa %g1, [VA_DMMU_TAG_ACCESS] %asi			
-	membar #Sync
-
-#ifdef CONFIG_VIRT_IDX_DCACHE
-#define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_CV | TTE_P | LMA | (imm))
-#else /* CONFIG_VIRT_IDX_DCACHE */
-#define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_P | LMA | (imm))
-#endif /* CONFIG_VIRT_IDX_DCACHE */
-
-#define SET_TLB_DATA(r1, r2, imm) \
-	set TTE_LOW_DATA(imm), %r1; \
-	or %r1, %l5, %r1; \
-	mov PAGESIZE_4M, %r2; \
-	sllx %r2, TTE_SIZE_SHIFT, %r2; \
-	or %r1, %r2, %r1; \
-	mov 1, %r2; \
-	sllx %r2, TTE_V_SHIFT, %r2; \
-	or %r1, %r2, %r1;
-	
-	! write DTLB data and install the kernel mapping
-	SET_TLB_DATA(g1, g2, TTE_L | TTE_W)	! use non-global mapping
-	stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG		
-	membar #Sync
-
-	/*
-	 * Because we cannot use global mappings (because we want to have
-	 * separate 64-bit address spaces for both the kernel and the
-	 * userspace), we prepare the identity mapping also in context 1. This
-	 * step is required by the code installing the ITLB mapping.
-	 */
-	! write DTLB tag of context 1 (i.e. MEM_CONTEXT_TEMP)
-	SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
-	stxa %g1, [VA_DMMU_TAG_ACCESS] %asi			
-	membar #Sync
-
-	! write DTLB data and install the kernel mapping in context 1
-	SET_TLB_DATA(g1, g2, TTE_W)			! use non-global mapping
-	stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG		
-	membar #Sync
-	
-	/*
-	 * Now is time to take over the IMMU. Unfortunatelly, it cannot be done
-	 * as easily as the DMMU, because the IMMU is mapping the code it
-	 * executes.
-	 *
-	 * [ Note that brave experiments with disabling the IMMU and using the
-	 * DMMU approach failed after a dozen of desparate days with only little
-	 * success. ]
-	 *
-	 * The approach used here is inspired from OpenBSD. First, the kernel
-	 * creates IMMU mapping for itself in context 1 (MEM_CONTEXT_TEMP) and
-	 * switches to it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped
-	 * afterwards and replaced with the kernel permanent mapping. Finally,
-	 * the kernel switches back to context 0 and demaps context 1.
-	 *
-	 * Moreover, the IMMU requires use of the FLUSH instructions. But that
-	 * is OK because we always use operands with addresses already mapped by
-	 * the taken over DTLB.
-	 */
-	
-	set kernel_image_start, %g5
-	
-	! write ITLB tag of context 1
-	SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
-	mov VA_DMMU_TAG_ACCESS, %g2
-	stxa %g1, [%g2] ASI_IMMU
-	flush %g5
-
-	! write ITLB data and install the temporary mapping in context 1
-	SET_TLB_DATA(g1, g2, 0)			! use non-global mapping
-	stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG		
-	flush %g5
-	
-	! switch to context 1
-	mov MEM_CONTEXT_TEMP, %g1
-	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi	! ASI_DMMU is correct here !!!
-	flush %g5
-	
-	! demap context 0
-	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
-	stxa %g0, [%g1] ASI_IMMU_DEMAP			
-	flush %g5
-	
-	! write ITLB tag of context 0
-	SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
-	mov VA_DMMU_TAG_ACCESS, %g2
-	stxa %g1, [%g2] ASI_IMMU
-	flush %g5
-
-	! write ITLB data and install the permanent kernel mapping in context 0
-	SET_TLB_DATA(g1, g2, TTE_L)		! use non-global mapping
-	stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG		
-	flush %g5
-
-	! enter nucleus - using context 0
-	wrpr %g0, 1, %tl
-
-	! demap context 1
-	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY)
-	stxa %g0, [%g1] ASI_IMMU_DEMAP			
-	flush %g5
-	
-	! set context 0 in the primary context register
-	stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi	! ASI_DMMU is correct here !!!
-	flush %g5
-	
-	! leave nucleus - using primary context, i.e. context 0
-	wrpr %g0, 0, %tl
-
-	brz %l7, 1f				! skip if you are not the bootstrap CPU
-	nop
-
-	/*
-	 * Save physmem_base for use by the mm subsystem.
-	 * %l6 contains starting physical address
-	 */
-	sethi %hi(physmem_base), %l4
-	stx %l6, [%l4 + %lo(physmem_base)]
-
-	/*
-	 * Precompute kernel 8K TLB data template.
-	 * %l5 contains starting physical address
-	 * bits [(PHYSMEM_ADDR_SIZE - 1):13]
-	 */
-	sethi %hi(kernel_8k_tlb_data_template), %l4
-	ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
-	or %l3, %l5, %l3
-	stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)]
-
-	/*
-	 * Flush D-Cache.
-	 */
-	call dcache_flush
-	nop
-
-	/*
-	 * So far, we have not touched the stack.
-	 * It is a good idea to set the kernel stack to a known state now.
-	 */
-	sethi %hi(temporary_boot_stack), %sp
-	or %sp, %lo(temporary_boot_stack), %sp
-	sub %sp, STACK_BIAS, %sp
-
-	sethi %hi(bootinfo), %o0
-	call memcpy				! copy bootinfo
-	or %o0, %lo(bootinfo), %o0
-
-	call arch_pre_main
-	nop
-	
-	call main_bsp
-	nop
-
-	/* Not reached. */
-
-0:
-	ba %xcc, 0b
-	nop
-
-
-1:
-#ifdef CONFIG_SMP
-	/*
-	 * Determine the width of the MID and save its mask to %g3. The width
-	 * is
-	 * 	* 5 for US and US-IIIi,
-	 * 	* 10 for US3 except US-IIIi.
-	 */
-#if defined(US)
-	mov 0x1f, %g3
-#elif defined(US3)
-	mov 0x3ff, %g3
-	rdpr %ver, %g2
-	sllx %g2, 16, %g2
-	srlx %g2, 48, %g2
-	cmp %g2, IMPL_ULTRASPARCIII_I
-	move %xcc, 0x1f, %g3
-#endif
-
-	/*
-	 * Read MID from the processor.
-	 */
-	ldxa [%g0] ASI_ICBUS_CONFIG, %g1
-	srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
-	and %g1, %g3, %g1
-
-	/*
-	 * Active loop for APs until the BSP picks them up. A processor cannot
-	 * leave the loop until the global variable 'waking_up_mid' equals its
-	 * MID.
-	 */
-	set waking_up_mid, %g2
-2:
-	ldx [%g2], %g3
-	cmp %g3, %g1
-	bne %xcc, 2b
-	nop
-
-	/*
-	 * Configure stack for the AP.
-	 * The AP is expected to use the stack saved
-	 * in the ctx global variable.
-	 */
-	set ctx, %g1
-	add %g1, OFFSET_SP, %g1
-	ldx [%g1], %o6
-
-	call main_ap
-	nop
-
-	/* Not reached. */
-#endif
-	
-0:
-	ba %xcc, 0b
-	nop
-
-
-.section K_DATA_START, "aw", @progbits
-
-/*
- * Create small stack to be used by the bootstrap processor. It is going to be
- * used only for a very limited period of time, but we switch to it anyway,
- * just to be sure we are properly initialized.
- */
-
-#define INITIAL_STACK_SIZE	1024
-
-.align STACK_ALIGNMENT
-	.space INITIAL_STACK_SIZE
-.align STACK_ALIGNMENT
-temporary_boot_stack:
-	.space STACK_WINDOW_SAVE_AREA_SIZE
-
-
-.data
-
-.align 8
-.global physmem_base		! copy of the physical memory base address
-physmem_base:
-	.quad 0
-
-/*
- * The fast_data_access_mmu_miss_data_hi label and the end_of_identity and
- * kernel_8k_tlb_data_template variables are meant to stay together,
- * aligned on 16B boundary.
- */
-.global fast_data_access_mmu_miss_data_hi
-.global end_of_identity 
-.global kernel_8k_tlb_data_template
-
-.align 16
-/*
- * This label is used by the fast_data_access_MMU_miss trap handler.
- */
-fast_data_access_mmu_miss_data_hi:
-/*
- * This variable is used by the fast_data_access_MMU_miss trap handler.
- * In runtime, it is modified to contain the address of the end of physical
- * memory.
- */
-end_of_identity:
-	.quad -1 
-/*
- * This variable is used by the fast_data_access_MMU_miss trap handler.
- * In runtime, it is further modified to reflect the starting address of
- * physical memory.
- */
-kernel_8k_tlb_data_template:
-#ifdef CONFIG_VIRT_IDX_DCACHE
-	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
-		 TTE_CV | TTE_P | TTE_W)
-#else /* CONFIG_VIRT_IDX_DCACHE */
-	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
-		TTE_P | TTE_W)
-#endif /* CONFIG_VIRT_IDX_DCACHE */
-
Index: kernel/arch/sparc64/src/sun4u/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/start.S	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/sun4u/start.S	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,417 @@
+#
+# 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.
+#
+
+#include <arch/arch.h>
+#include <arch/cpu.h>
+#include <arch/regdef.h>
+#include <arch/boot/boot.h>
+#include <arch/stack.h>
+
+#include <arch/mm/mmu.h>
+#include <arch/mm/tlb.h>
+#include <arch/mm/tte.h>
+
+#ifdef CONFIG_SMP
+#include <arch/context_offset.h>
+#endif
+
+.register %g2, #scratch
+.register %g3, #scratch
+
+.section K_TEXT_START, "ax"
+
+#define BSP_FLAG	1
+
+/*
+ * 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
+ * a given processor.
+ */
+#if defined (US)
+    #define PHYSMEM_ADDR_SIZE	41
+#elif defined (US3)
+    #define PHYSMEM_ADDR_SIZE	43
+#endif
+
+/*
+ * Here is where the kernel is passed control from the boot loader.
+ * 
+ * The registers are expected to be in this state:
+ * - %o0 starting address of physical memory + bootstrap processor flag
+ * 	bits 63...1:	physical memory starting address / 2
+ *	bit 0:		non-zero on BSP processor, zero on AP processors
+ * - %o1 bootinfo structure address (BSP only)
+ * - %o2 bootinfo structure size (BSP only)
+ *
+ * Moreover, we depend on boot having established the following environment:
+ * - TLBs are on
+ * - identity mapping for the kernel image
+ */
+
+.global kernel_image_start
+kernel_image_start:
+	mov BSP_FLAG, %l0
+	and %o0, %l0, %l7			! l7 <= bootstrap processor?
+	andn %o0, %l0, %l6			! l6 <= start of physical memory
+
+	! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
+	srlx %l6, 13, %l5
+	
+	! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
+	sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
+	srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5	
+
+	/*
+	 * Setup basic runtime environment.
+	 */
+
+	wrpr %g0, NWINDOWS - 2, %cansave	! set maximum saveable windows
+	wrpr %g0, 0, %canrestore		! get rid of windows we will
+						! never need again
+	wrpr %g0, 0, %otherwin			! make sure the window state is
+						! consistent
+	wrpr %g0, NWINDOWS - 1, %cleanwin	! prevent needless clean_window
+						! traps for kernel
+						
+	wrpr %g0, 0, %wstate			! use default spill/fill trap
+
+	wrpr %g0, 0, %tl			! TL = 0, primary context
+						! register is used
+
+	wrpr %g0, PSTATE_PRIV_BIT, %pstate	! disable interrupts and disable
+						! 32-bit address masking
+
+	wrpr %g0, 0, %pil			! intialize %pil
+
+	/*
+	 * Switch to kernel trap table.
+	 */
+	sethi %hi(trap_table), %g1
+	wrpr %g1, %lo(trap_table), %tba
+
+	/* 
+	 * Take over the DMMU by installing locked TTE entry identically
+	 * mapping the first 4M of memory.
+	 *
+	 * In case of DMMU, no FLUSH instructions need to be issued. Because of
+	 * that, the old DTLB contents can be demapped pretty straightforwardly
+	 * and without causing any traps.
+	 */
+
+	wr %g0, ASI_DMMU, %asi
+
+#define SET_TLB_DEMAP_CMD(r1, context_id) \
+	set (TLB_DEMAP_CONTEXT << TLB_DEMAP_TYPE_SHIFT) | (context_id << \
+		TLB_DEMAP_CONTEXT_SHIFT), %r1
+	
+	! demap context 0
+	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
+	stxa %g0, [%g1] ASI_DMMU_DEMAP			
+	membar #Sync
+
+#define SET_TLB_TAG(r1, context) \
+	set VMA | (context << TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1
+
+	! write DTLB tag
+	SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
+	stxa %g1, [VA_DMMU_TAG_ACCESS] %asi			
+	membar #Sync
+
+#ifdef CONFIG_VIRT_IDX_DCACHE
+#define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_CV | TTE_P | LMA | (imm))
+#else /* CONFIG_VIRT_IDX_DCACHE */
+#define TTE_LOW_DATA(imm) 	(TTE_CP | TTE_P | LMA | (imm))
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+
+#define SET_TLB_DATA(r1, r2, imm) \
+	set TTE_LOW_DATA(imm), %r1; \
+	or %r1, %l5, %r1; \
+	mov PAGESIZE_4M, %r2; \
+	sllx %r2, TTE_SIZE_SHIFT, %r2; \
+	or %r1, %r2, %r1; \
+	mov 1, %r2; \
+	sllx %r2, TTE_V_SHIFT, %r2; \
+	or %r1, %r2, %r1;
+	
+	! write DTLB data and install the kernel mapping
+	SET_TLB_DATA(g1, g2, TTE_L | TTE_W)	! use non-global mapping
+	stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG		
+	membar #Sync
+
+	/*
+	 * Because we cannot use global mappings (because we want to have
+	 * separate 64-bit address spaces for both the kernel and the
+	 * userspace), we prepare the identity mapping also in context 1. This
+	 * step is required by the code installing the ITLB mapping.
+	 */
+	! write DTLB tag of context 1 (i.e. MEM_CONTEXT_TEMP)
+	SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
+	stxa %g1, [VA_DMMU_TAG_ACCESS] %asi			
+	membar #Sync
+
+	! write DTLB data and install the kernel mapping in context 1
+	SET_TLB_DATA(g1, g2, TTE_W)			! use non-global mapping
+	stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG		
+	membar #Sync
+	
+	/*
+	 * Now is time to take over the IMMU. Unfortunatelly, it cannot be done
+	 * as easily as the DMMU, because the IMMU is mapping the code it
+	 * executes.
+	 *
+	 * [ Note that brave experiments with disabling the IMMU and using the
+	 * DMMU approach failed after a dozen of desparate days with only little
+	 * success. ]
+	 *
+	 * The approach used here is inspired from OpenBSD. First, the kernel
+	 * creates IMMU mapping for itself in context 1 (MEM_CONTEXT_TEMP) and
+	 * switches to it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped
+	 * afterwards and replaced with the kernel permanent mapping. Finally,
+	 * the kernel switches back to context 0 and demaps context 1.
+	 *
+	 * Moreover, the IMMU requires use of the FLUSH instructions. But that
+	 * is OK because we always use operands with addresses already mapped by
+	 * the taken over DTLB.
+	 */
+	
+	set kernel_image_start, %g5
+	
+	! write ITLB tag of context 1
+	SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
+	mov VA_DMMU_TAG_ACCESS, %g2
+	stxa %g1, [%g2] ASI_IMMU
+	flush %g5
+
+	! write ITLB data and install the temporary mapping in context 1
+	SET_TLB_DATA(g1, g2, 0)			! use non-global mapping
+	stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG		
+	flush %g5
+	
+	! switch to context 1
+	mov MEM_CONTEXT_TEMP, %g1
+	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi	! ASI_DMMU is correct here !!!
+	flush %g5
+	
+	! demap context 0
+	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
+	stxa %g0, [%g1] ASI_IMMU_DEMAP			
+	flush %g5
+	
+	! write ITLB tag of context 0
+	SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
+	mov VA_DMMU_TAG_ACCESS, %g2
+	stxa %g1, [%g2] ASI_IMMU
+	flush %g5
+
+	! write ITLB data and install the permanent kernel mapping in context 0
+	SET_TLB_DATA(g1, g2, TTE_L)		! use non-global mapping
+	stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG		
+	flush %g5
+
+	! enter nucleus - using context 0
+	wrpr %g0, 1, %tl
+
+	! demap context 1
+	SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY)
+	stxa %g0, [%g1] ASI_IMMU_DEMAP			
+	flush %g5
+	
+	! set context 0 in the primary context register
+	stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi	! ASI_DMMU is correct here !!!
+	flush %g5
+	
+	! leave nucleus - using primary context, i.e. context 0
+	wrpr %g0, 0, %tl
+
+	brz %l7, 1f				! skip if you are not the bootstrap CPU
+	nop
+
+	/*
+	 * Save physmem_base for use by the mm subsystem.
+	 * %l6 contains starting physical address
+	 */
+	sethi %hi(physmem_base), %l4
+	stx %l6, [%l4 + %lo(physmem_base)]
+
+	/*
+	 * Precompute kernel 8K TLB data template.
+	 * %l5 contains starting physical address
+	 * bits [(PHYSMEM_ADDR_SIZE - 1):13]
+	 */
+	sethi %hi(kernel_8k_tlb_data_template), %l4
+	ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
+	or %l3, %l5, %l3
+	stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)]
+
+	/*
+	 * Flush D-Cache.
+	 */
+	call dcache_flush
+	nop
+
+	/*
+	 * So far, we have not touched the stack.
+	 * It is a good idea to set the kernel stack to a known state now.
+	 */
+	sethi %hi(temporary_boot_stack), %sp
+	or %sp, %lo(temporary_boot_stack), %sp
+	sub %sp, STACK_BIAS, %sp
+
+	sethi %hi(bootinfo), %o0
+	call memcpy				! copy bootinfo
+	or %o0, %lo(bootinfo), %o0
+
+	call arch_pre_main
+	nop
+	
+	call main_bsp
+	nop
+
+	/* Not reached. */
+
+0:
+	ba %xcc, 0b
+	nop
+
+
+1:
+#ifdef CONFIG_SMP
+	/*
+	 * Determine the width of the MID and save its mask to %g3. The width
+	 * is
+	 * 	* 5 for US and US-IIIi,
+	 * 	* 10 for US3 except US-IIIi.
+	 */
+#if defined(US)
+	mov 0x1f, %g3
+#elif defined(US3)
+	mov 0x3ff, %g3
+	rdpr %ver, %g2
+	sllx %g2, 16, %g2
+	srlx %g2, 48, %g2
+	cmp %g2, IMPL_ULTRASPARCIII_I
+	move %xcc, 0x1f, %g3
+#endif
+
+	/*
+	 * Read MID from the processor.
+	 */
+	ldxa [%g0] ASI_ICBUS_CONFIG, %g1
+	srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
+	and %g1, %g3, %g1
+
+	/*
+	 * Active loop for APs until the BSP picks them up. A processor cannot
+	 * leave the loop until the global variable 'waking_up_mid' equals its
+	 * MID.
+	 */
+	set waking_up_mid, %g2
+2:
+	ldx [%g2], %g3
+	cmp %g3, %g1
+	bne %xcc, 2b
+	nop
+
+	/*
+	 * Configure stack for the AP.
+	 * The AP is expected to use the stack saved
+	 * in the ctx global variable.
+	 */
+	set ctx, %g1
+	add %g1, OFFSET_SP, %g1
+	ldx [%g1], %o6
+
+	call main_ap
+	nop
+
+	/* Not reached. */
+#endif
+	
+0:
+	ba %xcc, 0b
+	nop
+
+
+.section K_DATA_START, "aw", @progbits
+
+/*
+ * Create small stack to be used by the bootstrap processor. It is going to be
+ * used only for a very limited period of time, but we switch to it anyway,
+ * just to be sure we are properly initialized.
+ */
+
+#define INITIAL_STACK_SIZE	1024
+
+.align STACK_ALIGNMENT
+	.space INITIAL_STACK_SIZE
+.align STACK_ALIGNMENT
+temporary_boot_stack:
+	.space STACK_WINDOW_SAVE_AREA_SIZE
+
+
+.data
+
+.align 8
+.global physmem_base		! copy of the physical memory base address
+physmem_base:
+	.quad 0
+
+/*
+ * The fast_data_access_mmu_miss_data_hi label and the end_of_identity and
+ * kernel_8k_tlb_data_template variables are meant to stay together,
+ * aligned on 16B boundary.
+ */
+.global fast_data_access_mmu_miss_data_hi
+.global end_of_identity 
+.global kernel_8k_tlb_data_template
+
+.align 16
+/*
+ * This label is used by the fast_data_access_MMU_miss trap handler.
+ */
+fast_data_access_mmu_miss_data_hi:
+/*
+ * This variable is used by the fast_data_access_MMU_miss trap handler.
+ * In runtime, it is modified to contain the address of the end of physical
+ * memory.
+ */
+end_of_identity:
+	.quad -1 
+/*
+ * This variable is used by the fast_data_access_MMU_miss trap handler.
+ * In runtime, it is further modified to reflect the starting address of
+ * physical memory.
+ */
+kernel_8k_tlb_data_template:
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
+		 TTE_CV | TTE_P | TTE_W)
+#else /* CONFIG_VIRT_IDX_DCACHE */
+	.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
+		TTE_P | TTE_W)
+#endif /* CONFIG_VIRT_IDX_DCACHE */
+
Index: kernel/arch/sparc64/src/sun4v/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4v/start.S	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
+++ kernel/arch/sparc64/src/sun4v/start.S	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -0,0 +1,345 @@
+#
+# Copyright (c) 2005 Jakub Jermar
+# Copyright (c) 2008 Pavel Rimsky
+# 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/arch.h>
+#include <arch/stack.h>
+#include <arch/context_offset.h>
+#include <arch/sun4v/regdef.h>
+#include <arch/sun4v/hypercall.h>
+#include <arch/sun4v/arch.h>
+#include <arch/sun4v/cpu.h>
+#include <arch/mm/pagesize.h>
+#include <arch/mm/sun4v/tte.h>
+#include <arch/mm/sun4v/mmu.h>
+#include <arch/mm/sun4v/tlb.h>
+
+.register %g2, #scratch
+.register %g3, #scratch
+
+.section K_TEXT_START, "ax"
+
+#define BSP_FLAG		1
+#define PHYSMEM_ADDR_SIZE	56
+
+/*
+ * Flags set in the TTE data entry mapping the kernel.
+ */
+#ifdef CONFIG_VIRT_IDX_DCACHE
+	#define TTE_FLAGS \
+		(1 << TTE_V_SHIFT) \
+		| (1 << TTE_EP_SHIFT) \
+		| (1 << TTE_CP_SHIFT) \
+		| (1 << TTE_CV_SHIFT) \
+		| (1 << TTE_P_SHIFT) \
+		| (1 << TTE_W_SHIFT)
+#else
+	#define TTE_FLAGS \
+		(1 << TTE_V_SHIFT) \
+		| (1 << TTE_EP_SHIFT) \
+		| (1 << TTE_CP_SHIFT) \
+		| (1 << TTE_P_SHIFT) \
+		| (1 << TTE_W_SHIFT)
+#endif
+
+
+/*
+ * Fills a register with a TTE Data item. The item will map the given virtual
+ * address to a real address which will be computed by adding the starting
+ * address of the physical memory to the virtual address.
+ *
+ * parameters:
+ * 	addr:			virtual address to be mapped
+ *	rphysmem_start:		register containing the starting address of the
+ *				physical memory
+ *	rtmp1:			a register to be used as temporary
+ *	rtmp2:			a register to be used as temporary
+ *	rd:			register where the result will be saved
+ */
+#define TTE_DATA(addr, rphysmem_start, rtmp1, rtmp2, rd) \
+	setx TTE_FLAGS | PAGESIZE_4M, rtmp1, rd; \
+	add rd, rphysmem_start, rd; \
+	setx (addr), rtmp1, rtmp2; \
+	add rd, rtmp2, rd;
+
+/*
+ * Here is where the kernel is passed control from the boot loader.
+ * 
+ * The registers are expected to be in this state:
+ * - %o0 starting address of physical memory + bootstrap processor flag
+ * 	bits 63...1:	physical memory starting address / 2
+ *	bit 0:		non-zero on BSP processor, zero on AP processors
+ * - %o1 bootinfo structure address (BSP only)
+ * - %o2 bootinfo structure size (BSP only)
+ *
+ * Moreover, we depend on boot having established the following environment:
+ * - TLBs are on
+ * - identity mapping for the kernel image
+ */
+.global kernel_image_start
+kernel_image_start:
+	mov BSP_FLAG, %l0
+	and %o0, %l0, %l7			! l7 <= bootstrap processor?
+	andn %o0, %l0, %l6			! l6 <= start of physical memory
+	or %o1, %g0, %l1
+	or %o2, %g0, %l2
+
+	! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
+	srlx %l6, 13, %l5
+	
+	! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
+	sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
+	srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5	
+
+	/*
+	 * Setup basic runtime environment.
+	 */
+	wrpr %g0, NWINDOWS - 2, %cansave	! set maximum saveable windows
+	wrpr %g0, 0, %canrestore		! get rid of windows we will
+						! never need again
+	wrpr %g0, 0, %otherwin			! make sure the window state is
+						! consistent
+	wrpr %g0, NWINDOWS - 1, %cleanwin	! prevent needless clean_window
+						! traps for kernel
+						
+	wrpr %g0, 0, %wstate			! use default spill/fill trap
+
+	wrpr %g0, 0, %tl			! TL = 0, primary context
+						! register is used
+	wrpr %g0, 0, %gl
+
+	wrpr %g0, PSTATE_PRIV_BIT, %pstate	! disable interrupts and disable
+						! 32-bit address masking
+
+	wrpr %g0, 0, %pil			! intialize %pil
+
+	/*
+	 * Switch to kernel trap table.
+	 */
+	sethi %hi(trap_table), %g1
+	wrpr %g1, %lo(trap_table), %tba
+
+	/* Explicitly switch to hypervisor API 1.1. */
+	mov 1, %o0
+   	mov 1, %o1
+   	mov 1, %o2
+   	mov 0, %o3
+   	mov 0, %o4
+   	mov 0, %o5
+   	ta 0xff
+   	nop
+
+	/*
+	 * Take over the MMU.
+	 */
+
+	! map kernel in context 1
+	set kernel_image_start, %o0				! virt. address
+	set 1, %o1						! context
+	TTE_DATA(kernel_image_start, %l5, %g2, %g3, %o2)	! TTE data
+	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
+	__HYPERCALL_HYPERFAST(MMU_MAP_ADDR)
+
+	! switch to context 1
+	set 1, %o0
+	set VA_PRIMARY_CONTEXT_REG, %o1
+	stxa %o0, [%o1] ASI_PRIMARY_CONTEXT_REG
+
+	! demap all in context 0
+	set 0, %o0						! reserved
+	set 0, %o1						! reserved
+	set 0, %o2						! context
+	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
+	__HYPERCALL_FAST(MMU_DEMAP_CTX)
+
+	! install permanent mapping for kernel in context 0
+	set kernel_image_start, %o0				! virtual address
+	set 0, %o1						! context
+	TTE_DATA(kernel_image_start, %l5, %g2, %g3, %o2)	! TTE data
+	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
+	__HYPERCALL_FAST(MMU_MAP_PERM_ADDR)
+
+	! switch to context 0
+	mov 0, %o0
+	set VA_PRIMARY_CONTEXT_REG, %o1
+	stxa %o0, [%o1] ASI_PRIMARY_CONTEXT_REG
+
+	! demap all in context 1 (cleanup)
+	set 0, %o0						! reserved
+	set 0, %o1						! reserved
+	set 1, %o2						! context
+	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
+	__HYPERCALL_FAST(MMU_DEMAP_CTX)
+
+	/*
+	 * Set CPUID.
+	 */
+	__HYPERCALL_FAST(CPU_MYID)
+	mov SCRATCHPAD_CPUID, %g1
+	stxa %o1, [%g1] ASI_SCRATCHPAD
+
+	/*
+	 * Set MMU fault status area for the current CPU.
+	 */
+	set mmu_fsas, %o0			! o0 <= addr. of fault status areas array
+	add %o0, %l6, %o0			! kernel address to real address
+	mulx %o1, MMU_FSA_SIZE, %g1		! g1 <= offset of current CPU's fault status area
+	add %g1, %o0, %o0			! o0 <= FSA of the current CPU
+	mov SCRATCHPAD_MMU_FSA, %g1
+	stxa %o0, [%g1] ASI_SCRATCHPAD		! remember MMU fault status area to speed up miss handler
+	__HYPERCALL_FAST(MMU_FAULT_AREA_CONF)
+
+	! on APs skip executing the following code
+	cmp %l7, 0
+	be 1f
+	nop
+
+	/*
+	 * Save physmem_base for use by the mm subsystem.
+	 * %l6 contains starting physical address
+	 */	
+	sethi %hi(physmem_base), %l4
+	stx %l6, [%l4 + %lo(physmem_base)]
+
+	/*
+	 * Store a template of a TTE Data entry for kernel mappings.
+	 * This template will be used from the kernel MMU miss handler.
+	 */
+	!TTE_DATA(0, %l5, %g2, %g3, %g1)
+	setx TTE_FLAGS | PAGESIZE_8K, %g2, %g1; \
+	add %g1, %l5, %g1; \
+	set kernel_8k_tlb_data_template, %g4
+	stx %g1, [%g4]
+
+	/*
+	 * So far, we have not touched the stack.
+	 * It is a good idea to set the kernel stack to a known state now.
+	 */
+	sethi %hi(temporary_boot_stack), %sp
+	or %sp, %lo(temporary_boot_stack), %sp
+	sub %sp, STACK_BIAS, %sp
+
+	or %l1, %g0, %o1
+	or %l2, %g0, %o2
+	sethi %hi(bootinfo), %o0
+	call memcpy				! copy bootinfo
+	or %o0, %lo(bootinfo), %o0
+
+	call arch_pre_main
+	nop
+	
+	call main_bsp
+	nop
+
+	/* Not reached. */
+
+0:
+	ba 0b
+	nop
+
+1:
+
+#ifdef CONFIG_SMP
+
+	/*
+	 * Configure stack for the AP.
+	 * The AP is expected to use the stack saved
+	 * in the ctx global variable.
+	 */
+
+	mov	1, %o0			! MMU enable flag
+	set	mmu_enabled, %o1
+	mov	MMU_ENABLE, %o5	! MMU enable HV call
+	ta	0x80		! call HV
+
+	mmu_enabled:
+
+	/*
+	 * Configure stack for the AP.
+	 * The AP is expected to use the stack saved
+	 * in the ctx global variable.
+	 */
+	set ctx, %g1
+	add %g1, OFFSET_SP, %g1
+	ldx [%g1], %o6
+
+	call main_ap
+	nop
+#endif
+
+	/* Not reached. */
+0:
+	ba 0b
+	nop
+
+.align 8
+.global temp_cpu_mondo_handler
+temp_cpu_mondo_handler:
+
+	set 0x3c, %o0
+	set 0x15, %o5
+	ta 0x80
+
+	mov 0, %o0
+	setx before_ap_boots, %g1, %o1
+	setx 0x80400000, %g1, %o2
+	add %o1, %o2, %o1
+	__HYPERCALL_FAST(MMU_ENABLE)
+
+before_ap_boots:
+	setx 0x80400000, %g0, %o0
+	ba kernel_image_start
+	nop
+
+.section K_DATA_START, "aw", @progbits
+
+#define INITIAL_STACK_SIZE		1024
+
+.align STACK_ALIGNMENT
+	.space INITIAL_STACK_SIZE
+.align STACK_ALIGNMENT
+temporary_boot_stack:
+	.space STACK_WINDOW_SAVE_AREA_SIZE
+
+
+.data
+
+.align 8
+.global physmem_base		! copy of the physical memory base address
+physmem_base:
+	.quad 0
+
+.global kernel_8k_tlb_data_template
+kernel_8k_tlb_data_template:
+	.quad 0
+
+/* MMU fault status areas for all CPUs */
+.align MMU_FSA_ALIGNMENT
+.global mmu_fsas
+mmu_fsas:
+	.space (MMU_FSA_SIZE * MAX_NUM_STRANDS)
Index: kernel/generic/src/main/version.c
===================================================================
--- kernel/generic/src/main/version.c	(revision 68834d85136ffcc33645830b2453ac1352a8802a)
+++ kernel/generic/src/main/version.c	(revision f238e86a305ceb15005422c1105e13fd7fac1881)
@@ -58,4 +58,5 @@
 void version_print(void)
 {
+	asm volatile ("sethi 0x41923, %g0");
 	printf("%s, release %s (%s)%s\nBuilt%s for %s\n%s\n",
 		project, release, name, revision, timestamp, arch, copyright);
