Index: kernel/arch/amd64/include/arch.h
===================================================================
--- kernel/arch/amd64/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/amd64/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup amd64	
+/** @addtogroup amd64	
  * @{
  */
@@ -33,10 +33,9 @@
  */
 
-#ifndef __amd64_ARCH_H__
-#define __amd64_ARCH_H__
+#ifndef KERN_amd64_ARCH_H_
+#define KERN_amd64_ARCH_H_
 
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/ia32/include/arch.h
===================================================================
--- kernel/arch/ia32/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/ia32/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup ia32	
+/** @addtogroup ia32	
  * @{
  */
@@ -33,10 +33,9 @@
  */
 
-#ifndef __ia32_ARCH_H__
-#define __ia32_ARCH_H__
+#ifndef KERN_ia32_ARCH_H_
+#define KERN_ia32_ARCH_H_
 
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/ia64/include/arch.h
===================================================================
--- kernel/arch/ia64/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/ia64/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup ia64	
+/** @addtogroup ia64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __ia64_ARCH_H__
-#define __ia64_ARCH_H__
+#ifndef KERN_ia64_ARCH_H_
+#define KERN_ia64_ARCH_H_
 
 #define LOADED_PROG_STACK_PAGES_NO 2
@@ -42,5 +42,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/ia64/src/interrupt.c
===================================================================
--- kernel/arch/ia64/src/interrupt.c	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/ia64/src/interrupt.c	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -158,24 +158,24 @@
 
 	switch (istate->cr_isr.ge_code) {
-	    case GE_ILLEGALOP:
+	case GE_ILLEGALOP:
 		desc = "Illegal Operation fault";
 		break;
-	    case GE_PRIVOP:
+	case GE_PRIVOP:
 		desc = "Privileged Operation fault";
 		break;
-	    case GE_PRIVREG:
+	case GE_PRIVREG:
 		desc = "Privileged Register fault";
 		break;
-	    case GE_RESREGFLD:
+	case GE_RESREGFLD:
 		desc = "Reserved Register/Field fault";
 		break;
-	    case GE_DISBLDISTRAN:
+	case GE_DISBLDISTRAN:
 		desc = "Disabled Instruction Set Transition fault";
 		break;
-	    case GE_ILLEGALDEP:
+	case GE_ILLEGALDEP:
 		desc = "Illegal Dependency fault";
 		break;
-	    default:
-	    	desc = "unknown";
+	default:
+		desc = "unknown";
 		break;
 	}
@@ -186,6 +186,4 @@
 	panic("General Exception (%s)\n", desc);
 }
-
-void fpu_enable(void);
 
 void disabled_fp_register(uint64_t vector, istate_t *istate)
@@ -204,5 +202,4 @@
 {
 }
-
 
 
@@ -243,11 +240,11 @@
 
 	switch(ivr.vector) {
-	    case INTERRUPT_TIMER:
+	case INTERRUPT_TIMER:
 		it_interrupt();
-	    	break;
-	    case INTERRUPT_SPURIOUS:
+		break;
+	case INTERRUPT_SPURIOUS:
 	    	printf("cpu%d: spurious interrupt\n", CPU->id);
 		break;
-	    default:
+	default:
 		panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector);
 		break;
@@ -255,12 +252,13 @@
 }
 
-void virtual_interrupt(uint64_t irq,void *param)
+void virtual_interrupt(uint64_t irq, void *param)
 {
 	switch(irq) {
-		case IRQ_KBD:
-			if(kbd_uspace) ipc_irq_send_notif(irq);
-			break;
-		default:
-			panic("\nUnhandled Virtual Interrupt request %d\n", irq);
+	case IRQ_KBD:
+		if (kbd_uspace)
+			ipc_irq_send_notif(irq);
+		break;
+	default:
+		panic("\nUnhandled Virtual Interrupt request %d\n", irq);
 		break;
 	}
@@ -270,6 +268,6 @@
 void irq_ipc_bind_arch(unative_t irq)
 {
-	if(irq==IRQ_KBD) {
-		kbd_uspace=1;
+	if(irq == IRQ_KBD) {
+		kbd_uspace = 1;
 		return;
 	}
@@ -281,3 +279,2 @@
 /** @}
  */
-
Index: kernel/arch/mips32/include/arch.h
===================================================================
--- kernel/arch/mips32/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/mips32/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __mips32_ARCH_H__
-#define __mips32_ARCH_H__
+#ifndef KERN_mips32_ARCH_H_
+#define KERN_mips32_ARCH_H_
 
 #endif
Index: kernel/arch/mips32/src/fpu_context.c
===================================================================
--- kernel/arch/mips32/src/fpu_context.c	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/mips32/src/fpu_context.c	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup mips32	
+/** @addtogroup mips32	
  * @{
  */
@@ -58,5 +58,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/ppc32/include/arch.h
===================================================================
--- kernel/arch/ppc32/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/ppc32/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __ppc32_ARCH_H__
-#define __ppc32_ARCH_H__
+#ifndef KERN_ppc32_ARCH_H_
+#define KERN_ppc32_ARCH_H_
 
 #include <arch/drivers/cuda.h>
Index: kernel/arch/ppc64/include/arch.h
===================================================================
--- kernel/arch/ppc64/include/arch.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/ppc64/include/arch.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup ppc64	
+/** @addtogroup ppc64	
  * @{
  */
@@ -33,10 +33,9 @@
  */
 
-#ifndef __ppc64_ARCH_H__
-#define __ppc64_ARCH_H__
+#ifndef KERN_ppc64_ARCH_H_
+#define KERN_ppc64_ARCH_H_
 
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/Makefile.inc	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -88,4 +88,5 @@
 	arch/$(ARCH)/src/console.c \
 	arch/$(ARCH)/src/context.S \
+	arch/$(ARCH)/src/fpu_context.c \
 	arch/$(ARCH)/src/dummy.s \
 	arch/$(ARCH)/src/mm/as.c \
Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/include/asm.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -109,4 +109,26 @@
 }
 
+/** Read FPRS Register.
+ *
+ * @return Value of FPRS register.
+ */
+static inline uint64_t fprs_read(void)
+{
+	uint64_t v;
+	
+	__asm__ volatile ("rd %%fprs, %0\n" : "=r" (v));
+	
+	return v;
+}
+
+/** Write FPRS Register.
+ *
+ * @param v New value of FPRS register.
+ */
+static inline void fprs_write(uint64_t v)
+{
+	__asm__ volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
+}
+
 /** Read SOFTINT Register.
  *
Index: kernel/arch/sparc64/include/fpu_context.h
===================================================================
--- kernel/arch/sparc64/include/fpu_context.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/include/fpu_context.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -38,5 +38,10 @@
 #include <arch/types.h>
 
+#define ARCH_HAS_FPU
+#define FPU_CONTEXT_ALIGN	8
+
 struct fpu_context {
+	uint64_t	d[32];
+	uint64_t	fsr;
 };
 
Index: kernel/arch/sparc64/include/regdef.h
===================================================================
--- kernel/arch/sparc64/include/regdef.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/include/regdef.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -44,8 +44,10 @@
 
 #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_IE_BIT		(PSTATE_IE_BIT<<TSTATE_PSTATE_SHIFT)
+#define TSTATE_PEF_BIT		(PSTATE_PEF_BIT<<TSTATE_PSTATE_SHIFT)
 
 #define TSTATE_CWP_MASK		0x1f
Index: kernel/arch/sparc64/include/register.h
===================================================================
--- kernel/arch/sparc64/include/register.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/include/register.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -88,5 +88,5 @@
 	uint64_t value;
 	struct {
-		unsigned int_dis : 1;	/**< TICK_INT interrupt disabled flag. */
+		unsigned int_dis : 1;		/**< TICK_INT interrupt disabled flag. */
 		uint64_t tick_cmpr : 63;	/**< Compare value for TICK interrupts. */
 	} __attribute__ ((packed));
@@ -106,4 +106,16 @@
 typedef union softint_reg softint_reg_t;
 
+/** Floating-point Registers State Register. */
+union fprs_reg {
+	uint64_t value;
+	struct {
+		uint64_t : 61;
+		unsigned fef : 1;
+		unsigned du : 1;
+		unsigned dl : 1;
+	} __attribute__ ((packed));
+};
+typedef union fprs_reg fprs_reg_t;
+
 #endif
 
Index: kernel/arch/sparc64/include/trap/exception.h
===================================================================
--- kernel/arch/sparc64/include/trap/exception.h	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/include/trap/exception.h	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -41,4 +41,5 @@
 #define TT_ILLEGAL_INSTRUCTION			0x10
 #define TT_PRIVILEGED_OPCODE			0x11
+#define TT_FP_DISABLED				0x20
 #define TT_DIVISION_BY_ZERO			0x28
 #define TT_DATA_ACCESS_EXCEPTION		0x30
@@ -57,4 +58,5 @@
 extern void illegal_instruction(int n, istate_t *istate);
 extern void privileged_opcode(int n, istate_t *istate);
+extern void fp_disabled(int n, istate_t *istate);
 extern void division_by_zero(int n, istate_t *istate);
 extern void data_access_exception(int n, istate_t *istate);
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/src/asm.S	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -228,15 +228,19 @@
 
 .macro WRITE_ALTERNATE_REGISTER reg, bit
+	rdpr %pstate, %g1				! save PSTATE.PEF
 	wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
 	mov %o0, \reg
+	wrpr %g0, PSTATE_PRIV_BIT, %pstate
 	retl
-	wrpr %g0, PSTATE_PRIV_BIT, %pstate
+	wrpr %g1, 0, %pstate				! restore PSTATE.PEF
 .endm
 
 .macro READ_ALTERNATE_REGISTER reg, bit
+	rdpr %pstate, %g1				! save PSTATE.PEF
 	wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
 	mov \reg, %o0
+	wrpr %g0, PSTATE_PRIV_BIT, %pstate
 	retl
-	wrpr %g0, PSTATE_PRIV_BIT, %pstate
+	wrpr %g1, 0, %pstate				! restore PSTATE.PEF
 .endm
 
Index: kernel/arch/sparc64/src/dummy.s
===================================================================
--- kernel/arch/sparc64/src/dummy.s	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/src/dummy.s	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -30,8 +30,4 @@
 
 .global cpu_sleep
-.global fpu_context_restore
-.global fpu_context_save
-.global fpu_enable
-.global fpu_init
 .global sys_tls_set
 
@@ -39,8 +35,4 @@
 
 cpu_sleep:
-fpu_context_restore:
-fpu_context_save:
-fpu_enable:
-fpu_init:
 sys_tls_set:
 
Index: kernel/arch/sparc64/src/fpu_context.c
===================================================================
--- kernel/arch/sparc64/src/fpu_context.c	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
+++ kernel/arch/sparc64/src/fpu_context.c	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -0,0 +1,200 @@
+/*
+ * 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 sparc64
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <fpu_context.h>
+#include <arch/register.h>
+#include <arch/asm.h>
+
+void fpu_context_save(fpu_context_t *fctx)
+{
+	fprs_reg_t fprs;
+	
+	fprs.value = fprs_read();
+
+	if (fprs.dl) {
+		/*
+		 * The lower half of floating-point registers is dirty.
+		 * Spill it to memory.
+		 */
+		__asm__ volatile (
+			"std %%f0, %0\n"
+			"std %%f2, %1\n"
+			"std %%f4, %2\n"
+			"std %%f6, %3\n"
+			"std %%f8, %4\n"
+			"std %%f10, %5\n"
+			"std %%f12, %6\n"
+			"std %%f14, %7\n"
+			"std %%f16, %8\n"
+			"std %%f18, %9\n"
+			"std %%f20, %10\n"
+			"std %%f22, %11\n"
+			"std %%f24, %12\n"
+			"std %%f26, %13\n"
+			"std %%f28, %14\n"
+			"std %%f30, %15\n"
+			: "=m" (fctx->d[0]), "=m" (fctx->d[1]), "=m" (fctx->d[2]), "=m" (fctx->d[3]),
+			  "=m" (fctx->d[4]), "=m" (fctx->d[5]), "=m" (fctx->d[6]), "=m" (fctx->d[7]),
+			  "=m" (fctx->d[8]), "=m" (fctx->d[9]), "=m" (fctx->d[10]), "=m" (fctx->d[11]),
+			  "=m" (fctx->d[12]), "=m" (fctx->d[13]), "=m" (fctx->d[14]), "=m" (fctx->d[15])
+		);
+		fprs.dl = false;
+	}
+	
+	if (fprs.du) {	
+		/*
+		 * The upper half of floating-point registers is dirty.
+		 * Spill it to memory.
+		 */
+		__asm__ volatile (
+			"std %%f32, %0\n"
+			"std %%f34, %1\n"
+			"std %%f36, %2\n"
+			"std %%f38, %3\n"
+			"std %%f40, %4\n"
+			"std %%f42, %5\n"
+			"std %%f44, %6\n"
+			"std %%f46, %7\n"
+			"std %%f48, %8\n"
+			"std %%f50, %9\n"
+			"std %%f52, %10\n"
+			"std %%f54, %11\n"
+			"std %%f56, %12\n"
+			"std %%f58, %13\n"
+			"std %%f60, %14\n"
+			"std %%f62, %15\n"
+			: "=m" (fctx->d[16]), "=m" (fctx->d[17]), "=m" (fctx->d[18]), "=m" (fctx->d[19]),
+			  "=m" (fctx->d[20]), "=m" (fctx->d[21]), "=m" (fctx->d[22]), "=m" (fctx->d[23]),
+			  "=m" (fctx->d[24]), "=m" (fctx->d[25]), "=m" (fctx->d[26]), "=m" (fctx->d[27]),
+			  "=m" (fctx->d[28]), "=m" (fctx->d[29]), "=m" (fctx->d[30]), "=m" (fctx->d[31])
+		);
+		fprs.du = false;
+	}
+	
+	fprs_write(fprs.value);
+	
+	__asm__ volatile ("stx %%fsr, %0\n" : "=m" (fctx->fsr));
+}
+
+void fpu_context_restore(fpu_context_t *fctx)
+{
+	fprs_reg_t fprs;
+	
+	fprs.value = fprs_read();
+	
+	__asm__ volatile (
+		"ldd %0, %%f0\n"
+		"ldd %1, %%f2\n"
+		"ldd %2, %%f4\n"
+		"ldd %3, %%f6\n"
+		"ldd %4, %%f8\n"
+		"ldd %5, %%f10\n"
+		"ldd %6, %%f12\n"
+		"ldd %7, %%f14\n"
+		"ldd %8, %%f16\n"
+		"ldd %9, %%f18\n"
+		"ldd %10, %%f20\n"
+		"ldd %11, %%f22\n"
+		"ldd %12, %%f24\n"
+		"ldd %13, %%f26\n"
+		"ldd %14, %%f28\n"
+		"ldd %15, %%f30\n"
+		:
+		: "m" (fctx->d[0]), "m" (fctx->d[1]), "m" (fctx->d[2]), "m" (fctx->d[3]),
+		  "m" (fctx->d[4]), "m" (fctx->d[5]), "m" (fctx->d[6]), "m" (fctx->d[7]),
+		  "m" (fctx->d[8]), "m" (fctx->d[9]), "m" (fctx->d[10]), "m" (fctx->d[11]),
+		  "m" (fctx->d[12]), "m" (fctx->d[13]), "m" (fctx->d[14]), "m" (fctx->d[15])
+	);
+	
+	/*
+	 * We need to split loading of the floating-point registers because
+	 * GCC (4.1.1) can't handle more than 30 operands in one asm statement.
+	 */
+	
+	__asm__ volatile (
+		"ldd %0, %%f32\n"
+		"ldd %1, %%f34\n"
+		"ldd %2, %%f36\n"
+		"ldd %3, %%f38\n"
+		"ldd %4, %%f40\n"
+		"ldd %5, %%f42\n"
+		"ldd %6, %%f44\n"
+		"ldd %7, %%f46\n"
+		"ldd %8, %%f48\n"
+		"ldd %9, %%f50\n"
+		"ldd %10, %%f52\n"
+		"ldd %11, %%f54\n"
+		"ldd %12, %%f56\n"
+		"ldd %13, %%f58\n"
+		"ldd %14, %%f60\n"
+		"ldd %15, %%f62\n"
+		:
+		: "m" (fctx->d[16]), "m" (fctx->d[17]), "m" (fctx->d[18]), "m" (fctx->d[19]),
+		  "m" (fctx->d[20]), "m" (fctx->d[21]), "m" (fctx->d[22]), "m" (fctx->d[23]),
+		  "m" (fctx->d[24]), "m" (fctx->d[25]), "m" (fctx->d[26]), "m" (fctx->d[27]),
+		  "m" (fctx->d[28]), "m" (fctx->d[29]), "m" (fctx->d[30]), "m" (fctx->d[31])
+	);
+	
+	fprs.dl = fprs.du = false;
+	fprs_write(fprs.value);
+	
+	__asm__ volatile ("ldx %0, %%fsr\n" : : "m" (fctx->fsr));
+}
+
+void fpu_enable(void)
+{
+	pstate_reg_t pstate;
+	
+	pstate.value = pstate_read();
+	pstate.pef = true;
+	pstate_write(pstate.value);
+}
+
+void fpu_disable(void)
+{
+	pstate_reg_t pstate;
+	
+	pstate.value = pstate_read();
+	pstate.pef = false;
+	pstate_write(pstate.value);
+}
+
+void fpu_init(void)
+{
+	fpu_enable();
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/trap/exception.c
===================================================================
--- kernel/arch/sparc64/src/trap/exception.c	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/src/trap/exception.c	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -38,4 +38,5 @@
 #include <interrupt.h>
 #include <arch/asm.h>
+#include <arch/register.h>
 #include <debug.h>
 #include <typedefs.h>
@@ -82,4 +83,25 @@
 }
 
+/** Handle fp_disabled. (0x20) */
+void fp_disabled(int n, istate_t *istate)
+{
+	fprs_reg_t fprs;
+	
+	fprs.value = fprs_read();
+	if (!fprs.fef) {
+		fprs.fef = true;
+		fprs_write(fprs.value);
+		return;
+	}
+
+#ifdef CONFIG_FPU_LAZY
+	scheduler_fpu_lazy_request();
+#else
+	fault_if_from_uspace(istate, "%s\n", __FUNCTION__);
+	dump_istate(istate);
+	panic("%s\n", __FUNCTION__);
+#endif
+}
+
 /** Handle division_by_zero. (0x28) */
 void division_by_zero(int n, istate_t *istate)
Index: kernel/arch/sparc64/src/trap/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/trap_table.S	(revision 9a5b556abb26634c82cbd3954b0fdb4db62b828e)
+++ kernel/arch/sparc64/src/trap/trap_table.S	(revision 6eabb6e6dd5893162a9219e82db2afee1e5b1cb0)
@@ -83,8 +83,14 @@
 	PREEMPTIBLE_HANDLER privileged_opcode
 
+/* TT = 0x20, TL = 0, fb_disabled handler */
+.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
+.global fb_disabled_tl0
+fp_disabled_tl0:
+	PREEMPTIBLE_HANDLER fp_disabled
+
 /* TT = 0x24, TL = 0, clean_window handler */
 .org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
-.global clean_window_handler_tl0
-clean_window_handler_tl0:
+.global clean_window_tl0
+clean_window_tl0:
 	CLEAN_WINDOW_HANDLER
 
@@ -490,6 +496,6 @@
 /* TT = 0x24, TL > 0, clean_window handler */
 .org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
-.global clean_window_handler_tl1
-clean_window_handler_tl1:
+.global clean_window_tl1
+clean_window_tl1:
 	CLEAN_WINDOW_HANDLER
 
@@ -689,5 +695,5 @@
 	
 	wrpr %g0, 0, %tl
-	wrpr %g0, PSTATE_PRIV_BIT, %pstate
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
 	SAVE_GLOBALS
 	
@@ -706,4 +712,5 @@
 
 	RESTORE_GLOBALS
+	rdpr %pstate, %l1			! we must preserve the PEF bit
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
 	wrpr %g0, 1, %tl
@@ -717,4 +724,13 @@
 
 	/*
+	 * Copy PSTATE.PEF to the in-register copy of TSTATE.
+	 */
+	and %l1, PSTATE_PEF_BIT, %l1
+	sllx %l1, TSTATE_PSTATE_SHIFT, %l1
+	sethi %hi(TSTATE_PEF_BIT), %g4
+	andn %g1, %g4, %g1
+	or %g1, %l1, %g1
+
+	/*
 	 * Restore TSTATE, TPC and TNPC from saved copies.
 	 */
@@ -722,4 +738,5 @@
 	wrpr %g2, 0, %tpc
 	wrpr %g3, 0, %tnpc
+
 
 	/*
