Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -36,8 +36,11 @@
 #include <syscall/copy.h>
 #include <typedefs.h>
+#include <proc/thread.h>
 
 #include <arch.h>
 #include <arch/stack.h>
 #include <arch/trap/trap_table.h>
+
+#include <arch/istate_struct.h>
 
 #if defined(SUN4V)
@@ -61,5 +64,5 @@
 
 	kstack += STACK_BIAS;
-	kstack -= PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE;
+	kstack -= ISTATE_SIZE;
 
 	if (THREAD && (ctx->fp == kstack))
Index: kernel/arch/sparc64/src/drivers/tick.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tick.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/drivers/tick.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -35,4 +35,5 @@
 #include <arch/drivers/tick.h>
 #include <arch/interrupt.h>
+#include <arch/trap/interrupt.h>
 #include <arch/sparc64.h>
 #include <arch/asm.h>
@@ -51,5 +52,4 @@
 	softint_reg_t clear;
 
-	interrupt_register(14, "tick_int", tick_interrupt);
 	compare.int_dis = false;
 	compare.tick_cmpr = tick_counter_read() +
@@ -79,5 +79,5 @@
 /** Process tick interrupt.
  *
- * @param n      Interrupt Level (14, can be ignored)
+ * @param n      Trap type (0x4e, can be ignored)
  * @param istate Interrupted state.
  *
@@ -93,5 +93,5 @@
 	 * Make sure we are servicing interrupt_level_14
 	 */
-	ASSERT(n == 14);
+	ASSERT(n == TT_INTERRUPT_LEVEL_14);
 	
 	/*
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -194,5 +194,5 @@
 
 /** ITLB miss handler. */
-void fast_instruction_access_mmu_miss(sysarg_t unused, istate_t *istate)
+void fast_instruction_access_mmu_miss(unsigned int tt, istate_t *istate)
 {
 	size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
@@ -224,12 +224,10 @@
  * 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 tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
-{
+void fast_data_access_mmu_miss(unsigned int tt, istate_t *istate)
+{
+	tlb_tag_access_reg_t tag;
 	uintptr_t page_8k;
 	uintptr_t page_16k;
@@ -238,4 +236,5 @@
 	as_t *as = AS;
 
+	tag.value = istate->tlb_tag_access;
 	page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
 	page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
@@ -276,12 +275,10 @@
 /** 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 tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
-{
+void fast_data_access_protection(unsigned int tt, istate_t *istate)
+{
+	tlb_tag_access_reg_t tag;
 	uintptr_t page_16k;
 	size_t index;
@@ -289,4 +286,5 @@
 	as_t *as = AS;
 
+	tag.value = istate->tlb_tag_access;
 	page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
 	index = tag.vpn % MMU_PAGES_PER_PAGE;	/* 16K-page emulation */
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -208,5 +208,5 @@
 
 /** ITLB miss handler. */
-void fast_instruction_access_mmu_miss(sysarg_t unused, istate_t *istate)
+void fast_instruction_access_mmu_miss(unsigned int tt, istate_t *istate)
 {
 	uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
@@ -239,17 +239,12 @@
  * low-level, assembly language part of the fast_data_access_mmu_miss handler.
  *
- * @param page_and_ctx	A 64-bit value describing the fault. The most
- * 			significant 51 bits of the value contain the virtual
- * 			address which caused the fault truncated to the page
- * 			boundary. The least significant 13 bits of the value
- * 			contain the number of the context in which the fault
- * 			occurred.
+ * @param tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_mmu_miss(uint64_t page_and_ctx, istate_t *istate)
+void fast_data_access_mmu_miss(unsigned int tt, istate_t *istate)
 {
 	pte_t *t;
-	uintptr_t va = DMISS_ADDRESS(page_and_ctx);
-	uint16_t ctx = DMISS_CONTEXT(page_and_ctx);
+	uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
+	uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
 	as_t *as = AS;
 
@@ -288,17 +283,12 @@
 /** DTLB protection fault handler.
  *
- * @param page_and_ctx	A 64-bit value describing the fault. The most
- * 			significant 51 bits of the value contain the virtual
- * 			address which caused the fault truncated to the page
- * 			boundary. The least significant 13 bits of the value
- * 			contain the number of the context in which the fault
- * 			occurred.
+ * @param tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_protection(uint64_t page_and_ctx, istate_t *istate)
+void fast_data_access_protection(unsigned int tt, istate_t *istate)
 {
 	pte_t *t;
-	uintptr_t va = DMISS_ADDRESS(page_and_ctx);
-	uint16_t ctx = DMISS_CONTEXT(page_and_ctx);
+	uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
+	uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
 	as_t *as = AS;
 
Index: kernel/arch/sparc64/src/smp/sun4u/ipi.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4u/ipi.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/smp/sun4u/ipi.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -34,4 +34,5 @@
 
 #include <smp/ipi.h>
+#include <arch/smp/sun4u/ipi.h>
 #include <cpu.h>
 #include <arch.h>
@@ -40,4 +41,5 @@
 #include <config.h>
 #include <mm/tlb.h>
+#include <smp/smp_call.h>
 #include <arch/interrupt.h>
 #include <arch/trap/interrupt.h>
@@ -171,4 +173,26 @@
 }
 
+
+/*
+ * Deliver an IPI to the specified processors (except the current one).
+ *
+ * Interrupts must be disabled.
+ *
+ * @param cpu_id Destination cpu id (index into cpus array). Must not 
+ *               be the current cpu.
+ * @param ipi    IPI number.
+ */
+void ipi_unicast_arch(unsigned int cpu_id, int ipi)
+{
+	ASSERT(&cpus[cpu_id] != CPU);
+	
+	if (ipi == IPI_SMP_CALL) {
+		cross_call(cpus[cpu_id].arch.mid, smp_call_ipi_recv);
+	} else {
+		panic("Unknown IPI (%d).\n", ipi);
+		return;
+	}
+}
+
 /** @}
  */
Index: kernel/arch/sparc64/src/smp/sun4u/smp_call.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4u/smp_call.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
+++ kernel/arch/sparc64/src/smp/sun4u/smp_call.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Adam Hraska
+ * 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 Sun4u specific smp call support.
+ */
+
+#include <smp/smp_call.h>
+#include <arch/smp/sun4u/ipi.h>
+#include <arch/interrupt.h>
+
+void arch_smp_call_ipi(unsigned int cpu_id)
+{
+	/* 
+	 * Required by ipi_unicast_arch(). That functions resolves a potential
+	 * deadlock should both the destination and source cpus be sending
+	 * unicast ipis to each other with interrupts disabled.
+	 */
+	ipl_t ipl = interrupts_disable();
+	ipi_unicast_arch(cpu_id, IPI_SMP_CALL);
+	interrupts_restore(ipl);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/sun4u/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4u/sparc64.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/sun4u/sparc64.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -86,6 +86,8 @@
 void arch_pre_mm_init(void)
 {
-	if (config.cpu_active == 1)
+	if (config.cpu_active == 1) {
 		trap_init();
+		exc_arch_init();
+	}
 }
 
Index: kernel/arch/sparc64/src/sun4u/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/start.S	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/sun4u/start.S	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -401,13 +401,14 @@
 
 /*
- * 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.
+ * The fast_data_access_mmu_miss_data_hi label, the end_of_identity,
+ * kernel_8k_tlb_data_template and tlb_tag_access_context_mask variables
+ * are meant to stay together, aligned on a 32B boundary.
  */
 .global fast_data_access_mmu_miss_data_hi
 .global end_of_identity 
 .global kernel_8k_tlb_data_template
-
-.align 16
+.global tlb_tag_access_context_mask
+
+.align 32 
 /*
  * This label is used by the fast_data_access_MMU_miss trap handler.
@@ -435,2 +436,9 @@
 #endif /* CONFIG_VIRT_IDX_DCACHE */
 
+/*
+ * This variable is used by the fast_data_access_MMU_miss trap handler.
+ * It allows us to save one precious instruction slot of this handler.
+ */
+tlb_tag_access_context_mask:
+	.quad TLB_TAG_ACCESS_CONTEXT_MASK
+
Index: kernel/arch/sparc64/src/sun4v/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4v/sparc64.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/sun4v/sparc64.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -84,6 +84,8 @@
 void arch_pre_mm_init(void)
 {
-	if (config.cpu_active == 1)
+	if (config.cpu_active == 1) {
 		trap_init();
+		exc_arch_init();
+	}
 }
 
Index: kernel/arch/sparc64/src/trap/exception.c
===================================================================
--- kernel/arch/sparc64/src/trap/exception.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/exception.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -55,5 +55,5 @@
 
 /** Handle instruction_access_exception. (0x8) */
-void instruction_access_exception(int n, istate_t *istate)
+void instruction_access_exception(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -62,5 +62,5 @@
 
 /** Handle instruction_access_error. (0xa) */
-void instruction_access_error(int n, istate_t *istate)
+void instruction_access_error(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -69,5 +69,5 @@
 
 /** Handle illegal_instruction. (0x10) */
-void illegal_instruction(int n, istate_t *istate)
+void illegal_instruction(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -76,5 +76,5 @@
 
 /** Handle privileged_opcode. (0x11) */
-void privileged_opcode(int n, istate_t *istate)
+void privileged_opcode(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -83,5 +83,5 @@
 
 /** Handle unimplemented_LDD. (0x12) */
-void unimplemented_LDD(int n, istate_t *istate)
+void unimplemented_LDD(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -90,5 +90,5 @@
 
 /** Handle unimplemented_STD. (0x13) */
-void unimplemented_STD(int n, istate_t *istate)
+void unimplemented_STD(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -97,5 +97,5 @@
 
 /** Handle fp_disabled. (0x20) */
-void fp_disabled(int n, istate_t *istate)
+void fp_disabled(unsigned int n, istate_t *istate)
 {
 	fprs_reg_t fprs;
@@ -117,5 +117,5 @@
 
 /** Handle fp_exception_ieee_754. (0x21) */
-void fp_exception_ieee_754(int n, istate_t *istate)
+void fp_exception_ieee_754(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -124,5 +124,5 @@
 
 /** Handle fp_exception_other. (0x22) */
-void fp_exception_other(int n, istate_t *istate)
+void fp_exception_other(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -131,5 +131,5 @@
 
 /** Handle tag_overflow. (0x23) */
-void tag_overflow(int n, istate_t *istate)
+void tag_overflow(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -138,5 +138,5 @@
 
 /** Handle division_by_zero. (0x28) */
-void division_by_zero(int n, istate_t *istate)
+void division_by_zero(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -145,5 +145,5 @@
 
 /** Handle data_access_exception. (0x30) */
-void data_access_exception(int n, istate_t *istate)
+void data_access_exception(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -152,5 +152,5 @@
 
 /** Handle data_access_error. (0x32) */
-void data_access_error(int n, istate_t *istate)
+void data_access_error(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -159,5 +159,5 @@
 
 /** Handle mem_address_not_aligned. (0x34) */
-void mem_address_not_aligned(int n, istate_t *istate)
+void mem_address_not_aligned(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -166,5 +166,5 @@
 
 /** Handle LDDF_mem_address_not_aligned. (0x35) */
-void LDDF_mem_address_not_aligned(int n, istate_t *istate)
+void LDDF_mem_address_not_aligned(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -173,5 +173,5 @@
 
 /** Handle STDF_mem_address_not_aligned. (0x36) */
-void STDF_mem_address_not_aligned(int n, istate_t *istate)
+void STDF_mem_address_not_aligned(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -180,5 +180,5 @@
 
 /** Handle privileged_action. (0x37) */
-void privileged_action(int n, istate_t *istate)
+void privileged_action(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -187,5 +187,5 @@
 
 /** Handle LDQF_mem_address_not_aligned. (0x38) */
-void LDQF_mem_address_not_aligned(int n, istate_t *istate)
+void LDQF_mem_address_not_aligned(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
@@ -194,5 +194,5 @@
 
 /** Handle STQF_mem_address_not_aligned. (0x39) */
-void STQF_mem_address_not_aligned(int n, istate_t *istate)
+void STQF_mem_address_not_aligned(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -36,4 +36,6 @@
 #include <arch/interrupt.h>
 #include <arch/trap/interrupt.h>
+#include <arch/trap/exception.h>
+#include <arch/trap/mmu.h>
 #include <arch/sparc64.h>
 #include <interrupt.h>
@@ -43,4 +45,5 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
+#include <arch/drivers/tick.h>
 #include <print.h>
 #include <arch.h>
@@ -49,17 +52,119 @@
 #include <synch/spinlock.h>
 
-/** Register Interrupt Level Handler.
- *
- * @param n       Interrupt Level (1 - 15).
- * @param name    Short descriptive string.
- * @param handler Handler.
- *
- */
-void interrupt_register(unsigned int n, const char *name, iroutine_t handler)
+void exc_arch_init(void)
 {
-	ASSERT(n >= IVT_FIRST);
-	ASSERT(n <= IVT_ITEMS);
-	
-	exc_register(n - IVT_FIRST, name, true, handler);
+	exc_register(TT_INSTRUCTION_ACCESS_EXCEPTION,
+	    "instruction_access_exception", false,
+	    instruction_access_exception);
+	exc_register(TT_INSTRUCTION_ACCESS_ERROR,
+	    "instruction_access_error", false,
+	    instruction_access_error);
+
+#ifdef SUN4V
+	exc_register(TT_IAE_UNAUTH_ACCESS,
+	    "iae_unauth_access", false,
+	    instruction_access_exception);
+	exc_register(TT_IAE_NFO_PAGE,
+	    "iae_nfo_page", false,
+	    instruction_access_exception);
+#endif
+
+	exc_register(TT_ILLEGAL_INSTRUCTION,
+	    "illegal_instruction", false,
+	    illegal_instruction);
+	exc_register(TT_PRIVILEGED_OPCODE,
+	    "privileged_opcode", false,
+	    privileged_opcode);
+	exc_register(TT_UNIMPLEMENTED_LDD,
+	    "unimplemented_LDD", false,
+	    unimplemented_LDD);
+	exc_register(TT_UNIMPLEMENTED_STD,
+	    "unimplemented_STD", false,
+	    unimplemented_STD);
+
+#ifdef SUN4V
+	exc_register(TT_DAE_INVALID_ASI,
+	    "dae_invalid_asi", false,
+	    data_access_exception);
+	exc_register(TT_DAE_PRIVILEGE_VIOLATION,
+	    "dae_privilege_violation", false,
+	    data_access_exception);
+	exc_register(TT_DAE_NC_PAGE,
+	    "dae_nc_page", false,
+	    data_access_exception);
+	exc_register(TT_DAE_NC_PAGE,
+	    "dae_nc_page", false,
+	    data_access_exception);
+	exc_register(TT_DAE_NFO_PAGE,
+	    "dae_nfo_page", false,
+	    data_access_exception);
+#endif
+
+	exc_register(TT_FP_DISABLED,
+	    "fp_disabled", true,
+	    fp_disabled);
+	exc_register(TT_FP_EXCEPTION_IEEE_754,
+	    "fp_exception_ieee_754", false,
+	    fp_exception_ieee_754);
+	exc_register(TT_FP_EXCEPTION_OTHER,
+	    "fp_exception_other", false,
+	    fp_exception_other);
+	exc_register(TT_TAG_OVERFLOW,
+	    "tag_overflow", false,
+	    tag_overflow);	
+	exc_register(TT_DIVISION_BY_ZERO,
+	    "division_by_zero", false,
+	    division_by_zero);
+	exc_register(TT_DATA_ACCESS_EXCEPTION,
+	    "data_access_exception", false,
+	    data_access_exception);
+	exc_register(TT_DATA_ACCESS_ERROR,
+	    "data_access_error", false,
+	    data_access_error);
+	exc_register(TT_MEM_ADDRESS_NOT_ALIGNED,
+	    "mem_address_not_aligned", false,
+	    mem_address_not_aligned);
+	exc_register(TT_LDDF_MEM_ADDRESS_NOT_ALIGNED,
+	    "LDDF_mem_address_not_aligned", false,
+	    LDDF_mem_address_not_aligned);
+	exc_register(TT_STDF_MEM_ADDRESS_NOT_ALIGNED,
+	    "STDF_mem_address_not_aligned", false,
+	    STDF_mem_address_not_aligned);
+	exc_register(TT_PRIVILEGED_ACTION,
+	    "privileged_action", false,
+	    privileged_action);
+	exc_register(TT_LDQF_MEM_ADDRESS_NOT_ALIGNED,
+	    "LDQF_mem_address_not_aligned", false,
+	    LDQF_mem_address_not_aligned);
+	exc_register(TT_STQF_MEM_ADDRESS_NOT_ALIGNED,
+	    "STQF_mem_address_not_aligned", false,
+	    STQF_mem_address_not_aligned);
+
+	exc_register(TT_INTERRUPT_LEVEL_14,
+	    "interrupt_level_14", true,
+	    tick_interrupt);
+
+#ifdef SUN4U 
+	exc_register(TT_INTERRUPT_VECTOR_TRAP,
+	    "interrupt_vector_trap", true,
+	    interrupt);
+#endif
+
+	exc_register(TT_FAST_INSTRUCTION_ACCESS_MMU_MISS,
+	    "fast_instruction_access_mmu_miss", true,
+	    fast_instruction_access_mmu_miss);
+	exc_register(TT_FAST_DATA_ACCESS_MMU_MISS,
+	    "fast_data_access_mmu_miss", true,
+	    fast_data_access_mmu_miss);
+	exc_register(TT_FAST_DATA_ACCESS_PROTECTION,
+	    "fast_data_access_protection", true,
+	    fast_data_access_protection);	
+
+#ifdef SUN4V
+	exc_register(TT_CPU_MONDO,
+	    "cpu_mondo", true,
+	    cpu_mondo);
+#endif
+
 }
 
Index: kernel/arch/sparc64/src/trap/sun4u/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -53,5 +53,5 @@
  * @param istate Ignored.
  */
-void interrupt(int n, istate_t *istate)
+void interrupt(unsigned int n, istate_t *istate)
 {
 	uint64_t status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
Index: kernel/arch/sparc64/src/trap/sun4u/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -63,5 +63,7 @@
 instruction_access_exception_tl0:
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x0a, TL = 0, instruction_access_error */
@@ -69,5 +71,7 @@
 .global instruction_access_error_tl0
 instruction_access_error_tl0:
-	PREEMPTIBLE_HANDLER instruction_access_error
+	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x10, TL = 0, illegal_instruction */
@@ -75,5 +79,7 @@
 .global illegal_instruction_tl0
 illegal_instruction_tl0:
-	PREEMPTIBLE_HANDLER illegal_instruction
+	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x11, TL = 0, privileged_opcode */
@@ -81,5 +87,7 @@
 .global privileged_opcode_tl0
 privileged_opcode_tl0:
-	PREEMPTIBLE_HANDLER privileged_opcode
+	mov TT_PRIVILEGED_OPCODE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x12, TL = 0, unimplemented_LDD */
@@ -87,5 +95,7 @@
 .global unimplemented_LDD_tl0
 unimplemented_LDD_tl0:
-	PREEMPTIBLE_HANDLER unimplemented_LDD
+	mov TT_UNIMPLEMENTED_LDD, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x13, TL = 0, unimplemented_STD */
@@ -93,5 +103,7 @@
 .global unimplemented_STD_tl0
 unimplemented_STD_tl0:
-	PREEMPTIBLE_HANDLER unimplemented_STD
+	mov TT_UNIMPLEMENTED_STD, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x20, TL = 0, fb_disabled handler */
@@ -99,5 +111,7 @@
 .global fb_disabled_tl0
 fp_disabled_tl0:
-	PREEMPTIBLE_HANDLER fp_disabled
+	mov TT_FP_DISABLED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
@@ -105,5 +119,7 @@
 .global fb_exception_ieee_754_tl0
 fp_exception_ieee_754_tl0:
-	PREEMPTIBLE_HANDLER fp_exception_ieee_754
+	mov TT_FP_EXCEPTION_IEEE_754, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x22, TL = 0, fb_exception_other handler */
@@ -111,5 +127,7 @@
 .global fb_exception_other_tl0
 fp_exception_other_tl0:
-	PREEMPTIBLE_HANDLER fp_exception_other
+	mov TT_FP_EXCEPTION_OTHER, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x23, TL = 0, tag_overflow */
@@ -117,5 +135,7 @@
 .global tag_overflow_tl0
 tag_overflow_tl0:
-	PREEMPTIBLE_HANDLER tag_overflow
+	mov TT_TAG_OVERFLOW, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x24, TL = 0, clean_window handler */
@@ -129,5 +149,7 @@
 .global division_by_zero_tl0
 division_by_zero_tl0:
-	PREEMPTIBLE_HANDLER division_by_zero
+	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x30, TL = 0, data_access_exception */
@@ -136,5 +158,7 @@
 data_access_exception_tl0:
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x32, TL = 0, data_access_error */
@@ -142,5 +166,7 @@
 .global data_access_error_tl0
 data_access_error_tl0:
-	PREEMPTIBLE_HANDLER data_access_error
+	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x34, TL = 0, mem_address_not_aligned */
@@ -148,5 +174,7 @@
 .global mem_address_not_aligned_tl0
 mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER mem_address_not_aligned
+	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
@@ -154,5 +182,7 @@
 .global LDDF_mem_address_not_aligned_tl0
 LDDF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
+	mov TT_LDDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
@@ -160,5 +190,7 @@
 .global STDF_mem_address_not_aligned_tl0
 STDF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
+	mov TT_STDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x37, TL = 0, privileged_action */
@@ -166,5 +198,7 @@
 .global privileged_action_tl0
 privileged_action_tl0:
-	PREEMPTIBLE_HANDLER privileged_action
+	mov TT_PRIVILEGED_ACTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
@@ -172,5 +206,7 @@
 .global LDQF_mem_address_not_aligned_tl0
 LDQF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
+	mov TT_LDQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
@@ -178,5 +214,7 @@
 .global STQF_mem_address_not_aligned_tl0
 STQF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
+	mov TT_STQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x41, TL = 0, interrupt_level_1 handler */
@@ -184,5 +222,7 @@
 .global interrupt_level_1_handler_tl0
 interrupt_level_1_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 1
+	mov TT_INTERRUPT_LEVEL_1, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x42, TL = 0, interrupt_level_2 handler */
@@ -190,5 +230,7 @@
 .global interrupt_level_2_handler_tl0
 interrupt_level_2_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 2
+	mov TT_INTERRUPT_LEVEL_2, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x43, TL = 0, interrupt_level_3 handler */
@@ -196,5 +238,7 @@
 .global interrupt_level_3_handler_tl0
 interrupt_level_3_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 3
+	mov TT_INTERRUPT_LEVEL_3, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x44, TL = 0, interrupt_level_4 handler */
@@ -202,5 +246,7 @@
 .global interrupt_level_4_handler_tl0
 interrupt_level_4_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 4
+	mov TT_INTERRUPT_LEVEL_4, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x45, TL = 0, interrupt_level_5 handler */
@@ -208,5 +254,7 @@
 .global interrupt_level_5_handler_tl0
 interrupt_level_5_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 5
+	mov TT_INTERRUPT_LEVEL_5, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x46, TL = 0, interrupt_level_6 handler */
@@ -214,5 +262,7 @@
 .global interrupt_level_6_handler_tl0
 interrupt_level_6_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 6
+	mov TT_INTERRUPT_LEVEL_6, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x47, TL = 0, interrupt_level_7 handler */
@@ -220,5 +270,7 @@
 .global interrupt_level_7_handler_tl0
 interrupt_level_7_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 7
+	mov TT_INTERRUPT_LEVEL_7, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x48, TL = 0, interrupt_level_8 handler */
@@ -226,5 +278,7 @@
 .global interrupt_level_8_handler_tl0
 interrupt_level_8_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 8
+	mov TT_INTERRUPT_LEVEL_8, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x49, TL = 0, interrupt_level_9 handler */
@@ -232,5 +286,7 @@
 .global interrupt_level_9_handler_tl0
 interrupt_level_9_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 9
+	mov TT_INTERRUPT_LEVEL_9, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4a, TL = 0, interrupt_level_10 handler */
@@ -238,5 +294,7 @@
 .global interrupt_level_10_handler_tl0
 interrupt_level_10_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 10
+	mov TT_INTERRUPT_LEVEL_10, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4b, TL = 0, interrupt_level_11 handler */
@@ -244,5 +302,7 @@
 .global interrupt_level_11_handler_tl0
 interrupt_level_11_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 11
+	mov TT_INTERRUPT_LEVEL_11, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4c, TL = 0, interrupt_level_12 handler */
@@ -250,5 +310,7 @@
 .global interrupt_level_12_handler_tl0
 interrupt_level_12_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 12
+	mov TT_INTERRUPT_LEVEL_12, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4d, TL = 0, interrupt_level_13 handler */
@@ -256,5 +318,7 @@
 .global interrupt_level_13_handler_tl0
 interrupt_level_13_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 13
+	mov TT_INTERRUPT_LEVEL_13, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4e, TL = 0, interrupt_level_14 handler */
@@ -262,5 +326,7 @@
 .global interrupt_level_14_handler_tl0
 interrupt_level_14_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 14
+	mov TT_INTERRUPT_LEVEL_14, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4f, TL = 0, interrupt_level_15 handler */
@@ -268,5 +334,7 @@
 .global interrupt_level_15_handler_tl0
 interrupt_level_15_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 15
+	mov TT_INTERRUPT_LEVEL_15, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x60, TL = 0, interrupt_vector_trap handler */
@@ -274,5 +342,7 @@
 .global interrupt_vector_trap_handler_tl0
 interrupt_vector_trap_handler_tl0:
-	INTERRUPT_VECTOR_TRAP_HANDLER
+	mov TT_INTERRUPT_VECTOR_TRAP, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
@@ -342,6 +412,7 @@
 .global trap_instruction_\cur\()_tl0
 trap_instruction_\cur\()_tl0:
+	mov \cur, %g2
 	ba %xcc, trap_instruction_handler
-	mov \cur, %g2
+	clr %g5
 .endr
 
@@ -356,5 +427,7 @@
 	wrpr %g0, 1, %tl
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x0a, TL > 0, instruction_access_error */
@@ -363,5 +436,7 @@
 instruction_access_error_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER instruction_access_error
+	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x10, TL > 0, illegal_instruction */
@@ -370,5 +445,7 @@
 illegal_instruction_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER illegal_instruction
+	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x24, TL > 0, clean_window handler */
@@ -383,5 +460,7 @@
 division_by_zero_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER division_by_zero
+	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x30, TL > 0, data_access_exception */
@@ -391,5 +470,7 @@
 	wrpr %g0, 1, %tl
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x32, TL > 0, data_access_error */
@@ -398,5 +479,7 @@
 data_access_error_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_error
+	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x34, TL > 0, mem_address_not_aligned */
@@ -405,5 +488,7 @@
 mem_address_not_aligned_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER mem_address_not_aligned
+	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
@@ -470,19 +555,9 @@
  *	%g1		Address of function to call if this is not a syscall.
  * 	%g2	 	First argument for the function.
+ *	%g5		I/DTLB_TAG_ACCESS register if applicable.
  *	%g6		Pre-set as kernel stack base if trap from userspace.
  *	%g7		Pre-set as address of the userspace window buffer.
  */
 .macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
-	/*
-	 * ASSERT(%tl == 1)
-	 */
-	rdpr %tl, %g3
-	cmp %g3, 1
-	be %xcc, 1f
-	nop
-	! this is for debugging, if we ever get here it will be easy to find
-0:	ba,a %xcc, 0b
-
-1:
 .if NOT(\is_syscall)
 	rdpr %tstate, %g3
@@ -502,6 +577,6 @@
 	bnz %xcc, 0f				! ...skip setting of kernel stack and primary context
 	nop
-	
 .endif
+
 	/*
 	 * Normal window spills will go to the userspace window buffer.
@@ -516,5 +591,5 @@
 	 * and the new window's %fp.
 	 */
-	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %g6, -ISTATE_SIZE, %sp
 
 .if \is_syscall
@@ -548,5 +623,5 @@
 	ba,a %xcc, 1f
 0:
-	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %sp, -ISTATE_SIZE, %sp
 
 	/*
@@ -570,9 +645,9 @@
 .else
 	! store the syscall number on the stack as 7th argument
-	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_ARG6] 
 .endif
 
 	/*
-	 * Save TSTATE, TPC and TNPC aside.
+	 * Save TSTATE, TPC, TNPC and I/DTLB_TAG_ACCESS aside.
 	 */
 	rdpr %tstate, %g1
@@ -581,16 +656,13 @@
 	rd %y, %g4
 
-	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
-	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
-	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
+	stx %g1, [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE]
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_TPC]
+	stx %g3, [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC]
+	stx %g5, [%sp + STACK_BIAS + ISTATE_OFFSET_TLB_TAG_ACCESS]
 
 	/*
 	 * Save the Y register.
-	 * This register is deprecated according to SPARC V9 specification
-	 * and is only present for backward compatibility with previous
-	 * versions of the SPARC architecture.
-	 * Surprisingly, gcc makes use of this register without a notice.
-	 */
-	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
+	 */
+	stx %g4, [%sp + STACK_BIAS + ISTATE_OFFSET_Y]
 	
 	wrpr %g0, 0, %tl
@@ -603,5 +675,5 @@
 	 */
 	call %l0
-	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
+	add %sp, STACK_BIAS, %o1
 .else
 	/*
@@ -621,7 +693,7 @@
 	 * Read TSTATE, TPC and TNPC from saved copy.
 	 */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE], %g1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TPC], %g2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC], %g3
 
 	/*
@@ -644,5 +716,5 @@
 	 * Restore Y.
 	 */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_Y], %g4
 	wr %g4, %y
 
@@ -684,22 +756,22 @@
 	 */
 	mov %sp, %g2
-	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
-	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
-	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
-	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
-	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
-	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
-	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
-	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
+	stx %i0, [%sp + STACK_BIAS + ISTATE_OFFSET_O0]
+	stx %i1, [%sp + STACK_BIAS + ISTATE_OFFSET_O1]
+	stx %i2, [%sp + STACK_BIAS + ISTATE_OFFSET_O2]
+	stx %i3, [%sp + STACK_BIAS + ISTATE_OFFSET_O3]
+	stx %i4, [%sp + STACK_BIAS + ISTATE_OFFSET_O4]
+	stx %i5, [%sp + STACK_BIAS + ISTATE_OFFSET_O5]
+	stx %i6, [%sp + STACK_BIAS + ISTATE_OFFSET_O6]
+	stx %i7, [%sp + STACK_BIAS + ISTATE_OFFSET_O7]
 	wrpr %l0, 0, %cwp
 	mov %g2, %sp
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O0], %i0
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O1], %i1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O2], %i2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O3], %i3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O4], %i4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O5], %i5
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O6], %i6
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O7], %i7
 
 	/*
@@ -807,5 +879,5 @@
 	 * If the:
 	 *
-	 * 	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	 * 	save %g6, -ISTATE_SIZE, %sp
 	 *
 	 * instruction trapped and spilled a register window into the userspace
Index: kernel/arch/sparc64/src/trap/sun4v/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -95,5 +95,5 @@
  * register and processes the message (invokes a function call).
  */
-void cpu_mondo(void)
+void cpu_mondo(unsigned int tt, istate_t *istate)
 {
 #ifdef CONFIG_SMP
Index: kernel/arch/sparc64/src/trap/sun4v/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/trap_table.S	(revision 3da166f05b0e0513fe18f82b34f75ef99bef955a)
+++ kernel/arch/sparc64/src/trap/sun4v/trap_table.S	(revision a18a8b98aaf4c1d3de4b05b95565daf1aa01a1c8)
@@ -66,5 +66,7 @@
 .global instruction_access_exception_tl0
 instruction_access_exception_tl0:
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x09, TL = 0, instruction_access_mmu_miss */
@@ -77,5 +79,7 @@
 .global instruction_access_error_tl0
 instruction_access_error_tl0:
-	PREEMPTIBLE_HANDLER instruction_access_error
+	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x0b, TL = 0, IAE_unauth_access */
@@ -83,5 +87,7 @@
 .global iae_unauth_access_tl0
 iae_unauth_access_tl0:
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_IAE_UNAUTH_ACCESS, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x0c, TL = 0, IAE_nfo_page */
@@ -89,5 +95,7 @@
 .global iae_nfo_page_tl0
 iae_nfo_page_tl0:
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_IAE_NFO_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x10, TL = 0, illegal_instruction */
@@ -95,5 +103,7 @@
 .global illegal_instruction_tl0
 illegal_instruction_tl0:
-	PREEMPTIBLE_HANDLER illegal_instruction
+	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x11, TL = 0, privileged_opcode */
@@ -101,5 +111,7 @@
 .global privileged_opcode_tl0
 privileged_opcode_tl0:
-	PREEMPTIBLE_HANDLER privileged_opcode
+	mov TT_PRIVILEGED_OPCODE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x12, TL = 0, unimplemented_LDD */
@@ -107,5 +119,7 @@
 .global unimplemented_LDD_tl0
 unimplemented_LDD_tl0:
-	PREEMPTIBLE_HANDLER unimplemented_LDD
+	mov TT_UNIMPLEMENTED_LDD, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x13, TL = 0, unimplemented_STD */
@@ -113,5 +127,7 @@
 .global unimplemented_STD_tl0
 unimplemented_STD_tl0:
-	PREEMPTIBLE_HANDLER unimplemented_STD
+	mov TT_UNIMPLEMENTED_STD, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x14, TL = 0, DAE_invalid_asi */
@@ -119,5 +135,7 @@
 .global dae_invalid_asi_tl0
 dae_invalid_asi_tl0:
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_INVALID_ASI, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x15, TL = 0, DAE_privilege_violation */
@@ -125,5 +143,7 @@
 .global dae_privilege_violation_tl0
 dae_privilege_violation_tl0:
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_PRIVILEGE_VIOLATION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x16, TL = 0, DAE_nc_page */
@@ -131,5 +151,7 @@
 .global dae_nc_page_tl0
 dae_nc_page_tl0:
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_NC_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x17, TL = 0, DAE_nfo_page */
@@ -137,5 +159,7 @@
 .global dae_nfo_page_tl0
 dae_nfo_page_tl0:
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_NFO_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x20, TL = 0, fb_disabled handler */
@@ -143,5 +167,7 @@
 .global fb_disabled_tl0
 fp_disabled_tl0:
-	PREEMPTIBLE_HANDLER fp_disabled
+	mov TT_FP_DISABLED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
@@ -149,5 +175,7 @@
 .global fb_exception_ieee_754_tl0
 fp_exception_ieee_754_tl0:
-	PREEMPTIBLE_HANDLER fp_exception_ieee_754
+	mov TT_FP_EXCEPTION_IEEE_754, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x22, TL = 0, fb_exception_other handler */
@@ -155,5 +183,7 @@
 .global fb_exception_other_tl0
 fp_exception_other_tl0:
-	PREEMPTIBLE_HANDLER fp_exception_other
+	mov TT_FP_EXCEPTION_OTHER, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x23, TL = 0, tag_overflow */
@@ -161,5 +191,7 @@
 .global tag_overflow_tl0
 tag_overflow_tl0:
-	PREEMPTIBLE_HANDLER tag_overflow
+	mov TT_TAG_OVERFLOW, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x24, TL = 0, clean_window handler */
@@ -173,5 +205,7 @@
 .global division_by_zero_tl0
 division_by_zero_tl0:
-	PREEMPTIBLE_HANDLER division_by_zero
+	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x30, TL = 0, data_access_exception */
@@ -180,5 +214,7 @@
 .global data_access_exception_tl0
 data_access_exception_tl0:
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x31, TL = 0, data_access_mmu_miss */
@@ -192,5 +228,7 @@
 .global data_access_error_tl0
 data_access_error_tl0:
-	PREEMPTIBLE_HANDLER data_access_error
+	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x34, TL = 0, mem_address_not_aligned */
@@ -198,5 +236,7 @@
 .global mem_address_not_aligned_tl0
 mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER mem_address_not_aligned
+	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
@@ -204,5 +244,7 @@
 .global LDDF_mem_address_not_aligned_tl0
 LDDF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
+	mov TT_LDDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
@@ -210,5 +252,7 @@
 .global STDF_mem_address_not_aligned_tl0
 STDF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
+	mov TT_STDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x37, TL = 0, privileged_action */
@@ -216,5 +260,7 @@
 .global privileged_action_tl0
 privileged_action_tl0:
-	PREEMPTIBLE_HANDLER privileged_action
+	mov TT_PRIVILEGED_ACTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
@@ -222,5 +268,7 @@
 .global LDQF_mem_address_not_aligned_tl0
 LDQF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
+	mov TT_LDQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
@@ -228,5 +276,7 @@
 .global STQF_mem_address_not_aligned_tl0
 STQF_mem_address_not_aligned_tl0:
-	PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
+	mov TT_STQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x41, TL = 0, interrupt_level_1 handler */
@@ -234,5 +284,7 @@
 .global interrupt_level_1_handler_tl0
 interrupt_level_1_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 1
+	mov TT_INTERRUPT_LEVEL_1, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x42, TL = 0, interrupt_level_2 handler */
@@ -240,5 +292,7 @@
 .global interrupt_level_2_handler_tl0
 interrupt_level_2_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 2
+	mov TT_INTERRUPT_LEVEL_2, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x43, TL = 0, interrupt_level_3 handler */
@@ -246,5 +300,7 @@
 .global interrupt_level_3_handler_tl0
 interrupt_level_3_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 3
+	mov TT_INTERRUPT_LEVEL_3, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x44, TL = 0, interrupt_level_4 handler */
@@ -252,5 +308,7 @@
 .global interrupt_level_4_handler_tl0
 interrupt_level_4_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 4
+	mov TT_INTERRUPT_LEVEL_4, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x45, TL = 0, interrupt_level_5 handler */
@@ -258,5 +316,7 @@
 .global interrupt_level_5_handler_tl0
 interrupt_level_5_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 5
+	mov TT_INTERRUPT_LEVEL_5, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x46, TL = 0, interrupt_level_6 handler */
@@ -264,5 +324,7 @@
 .global interrupt_level_6_handler_tl0
 interrupt_level_6_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 6
+	mov TT_INTERRUPT_LEVEL_6, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x47, TL = 0, interrupt_level_7 handler */
@@ -270,5 +332,7 @@
 .global interrupt_level_7_handler_tl0
 interrupt_level_7_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 7
+	mov TT_INTERRUPT_LEVEL_7, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x48, TL = 0, interrupt_level_8 handler */
@@ -276,5 +340,7 @@
 .global interrupt_level_8_handler_tl0
 interrupt_level_8_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 8
+	mov TT_INTERRUPT_LEVEL_8, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x49, TL = 0, interrupt_level_9 handler */
@@ -282,5 +348,7 @@
 .global interrupt_level_9_handler_tl0
 interrupt_level_9_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 9
+	mov TT_INTERRUPT_LEVEL_9, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4a, TL = 0, interrupt_level_10 handler */
@@ -288,5 +356,7 @@
 .global interrupt_level_10_handler_tl0
 interrupt_level_10_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 10
+	mov TT_INTERRUPT_LEVEL_10, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4b, TL = 0, interrupt_level_11 handler */
@@ -294,5 +364,7 @@
 .global interrupt_level_11_handler_tl0
 interrupt_level_11_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 11
+	mov TT_INTERRUPT_LEVEL_11, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4c, TL = 0, interrupt_level_12 handler */
@@ -300,5 +372,7 @@
 .global interrupt_level_12_handler_tl0
 interrupt_level_12_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 12
+	mov TT_INTERRUPT_LEVEL_12, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4d, TL = 0, interrupt_level_13 handler */
@@ -306,5 +380,7 @@
 .global interrupt_level_13_handler_tl0
 interrupt_level_13_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 13
+	mov TT_INTERRUPT_LEVEL_13, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4e, TL = 0, interrupt_level_14 handler */
@@ -312,5 +388,7 @@
 .global interrupt_level_14_handler_tl0
 interrupt_level_14_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 14
+	mov TT_INTERRUPT_LEVEL_14, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x4f, TL = 0, interrupt_level_15 handler */
@@ -318,5 +396,7 @@
 .global interrupt_level_15_handler_tl0
 interrupt_level_15_handler_tl0:
-	INTERRUPT_LEVEL_N_HANDLER 15
+	mov TT_INTERRUPT_LEVEL_15, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch
 
 /* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
@@ -342,5 +422,7 @@
 .global cpu_mondo_handler_tl0
 cpu_mondo_handler_tl0:
-PREEMPTIBLE_HANDLER cpu_mondo
+	mov TT_CPU_MONDO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x80, TL = 0, spill_0_normal handler */
@@ -392,6 +474,7 @@
 .global trap_instruction_\cur\()_tl0
 trap_instruction_\cur\()_tl0:
+	mov \cur, %g2
 	ba %xcc, trap_instruction_handler
-	mov \cur, %g2
+	clr %g5
 .endr
 
@@ -406,5 +489,7 @@
 instruction_access_exception_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x09, TL > 0, instruction_access_mmu_miss */
@@ -419,5 +504,7 @@
 instruction_access_error_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER instruction_access_error
+	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x0b, TL > 0, IAE_unauth_access */
@@ -426,5 +513,7 @@
 iae_unauth_access_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_IAE_UNAUTH_ACCESS, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x0c, TL > 0, IAE_nfo_page */
@@ -433,5 +522,7 @@
 iae_nfo_page_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER instruction_access_exception
+	mov TT_IAE_NFO_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x10, TL > 0, illegal_instruction */
@@ -440,5 +531,7 @@
 illegal_instruction_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER illegal_instruction
+	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x14, TL > 0, DAE_invalid_asi */
@@ -447,5 +540,7 @@
 dae_invalid_asi_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_INVALID_ASI, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x15, TL > 0, DAE_privilege_violation */
@@ -454,5 +549,7 @@
 dae_privilege_violation_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_PRIVILEGE_VIOLATION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x16, TL > 0, DAE_nc_page */
@@ -461,5 +558,7 @@
 dae_nc_page_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_NC_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x17, TL > 0, DAE_nfo_page */
@@ -468,5 +567,7 @@
 dae_nfo_page_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_exception
+	mov TT_DAE_NFO_PAGE, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x24, TL > 0, clean_window handler */
@@ -481,5 +582,7 @@
 division_by_zero_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER division_by_zero
+	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x30, TL > 0, data_access_exception */
@@ -487,7 +590,8 @@
 .global data_access_exception_tl1
 data_access_exception_tl1:
-	/*wrpr %g0, 1, %tl
-	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
-	PREEMPTIBLE_HANDLER data_access_exception*/
+	wrpr %g0, 1, %tl
+	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x31, TL > 0, data_access_mmu_miss */
@@ -502,5 +606,7 @@
 data_access_error_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER data_access_error
+	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x34, TL > 0, mem_address_not_aligned */
@@ -509,5 +615,7 @@
 mem_address_not_aligned_tl1:
 	wrpr %g0, 1, %tl
-	PREEMPTIBLE_HANDLER mem_address_not_aligned
+	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
@@ -528,5 +636,7 @@
 cpu_mondo_handler_tl1:
 	wrpr %g0, %tl
-	PREEMPTIBLE_HANDLER cpu_mondo
+	mov TT_CPU_MONDO, %g2
+	clr %g5
+	PREEMPTIBLE_HANDLER exc_dispatch 
 
 /* TT = 0x80, TL > 0, spill_0_normal handler */
@@ -654,5 +764,5 @@
 .else
 	! store the syscall number on the stack as 7th argument
-	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_ARG6] 
 .endif
 
@@ -664,17 +774,18 @@
 	rdpr %tnpc, %g3
 
-	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
-	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
-	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
+	stx %g1, [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE]
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_TPC]
+	stx %g3, [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC]
 
 	/*
 	 * Save the Y register.
-	 * This register is deprecated according to SPARC V9 specification
-	 * and is only present for backward compatibility with previous
-	 * versions of the SPARC architecture.
-	 * Surprisingly, gcc makes use of this register without a notice.
 	 */
 	rd %y, %g4
-	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
+	stx %g4, [%sp + STACK_BIAS + ISTATE_OFFSET_Y]
+
+	/*
+	 * Save the faulting page and context.
+	 */
+	stx %g5, [%sp + STACK_BIAS + ISTATE_OFFSET_TLB_TAG_ACCESS]
 
 	/* switch to TL = 0, explicitly enable FPU */
@@ -689,5 +800,5 @@
 	/* call higher-level service routine, pass istate as its 2nd parameter */
 	call %l0
-	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
+	add %sp, STACK_BIAS, %o1
 .else
 	/* Call the higher-level syscall handler. */
@@ -711,7 +822,7 @@
 
 	/* Read TSTATE, TPC and TNPC from saved copy. */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE], %g1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TPC], %g2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC], %g3
 
 	/* Copy PSTATE.PEF to the in-register copy of TSTATE. */
@@ -728,5 +839,5 @@
 
 	/* Restore Y. */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_Y], %g4
 	wr %g4, %y
 	
@@ -750,22 +861,22 @@
 	 */
 	mov %sp, %g2
-	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
-	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
-	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
-	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
-	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
-	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
-	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
-	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
+	stx %i0, [%sp + STACK_BIAS + ISTATE_OFFSET_O0]
+	stx %i1, [%sp + STACK_BIAS + ISTATE_OFFSET_O1]
+	stx %i2, [%sp + STACK_BIAS + ISTATE_OFFSET_O2]
+	stx %i3, [%sp + STACK_BIAS + ISTATE_OFFSET_O3]
+	stx %i4, [%sp + STACK_BIAS + ISTATE_OFFSET_O4]
+	stx %i5, [%sp + STACK_BIAS + ISTATE_OFFSET_O5]
+	stx %i6, [%sp + STACK_BIAS + ISTATE_OFFSET_O6]
+	stx %i7, [%sp + STACK_BIAS + ISTATE_OFFSET_O7]
 	wrpr %l0, 0, %cwp
 	mov %g2, %sp
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O0], %i0
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O1], %i1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O2], %i2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O3], %i3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O4], %i4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O5], %i5
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O6], %i6
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O7], %i7
 .endm
 
@@ -774,17 +885,4 @@
  */
 .macro PREEMPTIBLE_HANDLER_KERNEL
-
-	/*
-	 * ASSERT(%tl == 1)
-	 */
-	rdpr %tl, %g3
-	cmp %g3, 1
-	be %xcc, 1f
-	nop
-
-	! this is for debugging, if we ever get here it will be easy to find
-0:	ba,a %xcc, 0b
-
-1:
 	/* prevent unnecessary CLEANWIN exceptions */
 	wrpr %g0, NWINDOWS - 1, %cleanwin
@@ -799,9 +897,19 @@
 	brnz %g3, 2f
 	nop
+	rdpr %otherwin, %g4
+	brnz %g4, 1f
+	nop
+
+	/* OTHERWIN is zero, we are spilling a kernel window. */
 	INLINE_SPILL %g3, %g4
+	ba,a %xcc, 2f
+
+1:
+	/* OTHERWIN is non-zero, we are spilling a uspace window. */
+	INLINE_SPILL_TO_WBUF %g3, %g4, %g7
 
 2:
 	/* ask for new register window */
-	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %sp, -ISTATE_SIZE, %sp
 
 	MIDDLE_PART 0
@@ -882,5 +990,5 @@
 	set SCRATCHPAD_KSTACK, %g4
 	ldxa [%g4] ASI_SCRATCHPAD, %g6
-	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %g6, -ISTATE_SIZE, %sp
 
 .if \is_syscall
@@ -1015,5 +1123,5 @@
 	 * If the:
 	 *
-	 * 	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	 * 	save %g6, -ISTATE_SIZE, %sp
 	 *
 	 * instruction trapped and spilled a register window into the userspace
