Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ HelenOS.config	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -397,4 +397,7 @@
 ! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia64|PLATFORM=sparc64] CONFIG_FPU (y)
 
+% FPU support
+! [PLATFORM=ppc32] CONFIG_FPU (n/y)
+
 ## ARMv7 made FPU hardware compulsory
 % FPU support
Index: kernel/arch/ppc32/include/arch/context_offset.h
===================================================================
--- kernel/arch/ppc32/include/arch/context_offset.h	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/include/arch/context_offset.h	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -54,23 +54,37 @@
 #define OFFSET_CR    0x58
 
-#define OFFSET_FR14  0x0
-#define OFFSET_FR15  0x8
-#define OFFSET_FR16  0x10
-#define OFFSET_FR17  0x18
-#define OFFSET_FR18  0x20
-#define OFFSET_FR19  0x28
-#define OFFSET_FR20  0x30
-#define OFFSET_FR21  0x38
-#define OFFSET_FR22  0x40
-#define OFFSET_FR23  0x48
-#define OFFSET_FR24  0x50
-#define OFFSET_FR25  0x58
-#define OFFSET_FR26  0x60
-#define OFFSET_FR27  0x68
-#define OFFSET_FR28  0x70
-#define OFFSET_FR29  0x78
-#define OFFSET_FR30  0x80
-#define OFFSET_FR31  0x88
-#define OFFSET_FPSCR 0x90
+#define OFFSET_FR0  0x0
+#define OFFSET_FR1  0x8
+#define OFFSET_FR2  0x10
+#define OFFSET_FR3  0x18
+#define OFFSET_FR4  0x20
+#define OFFSET_FR5  0x28
+#define OFFSET_FR6  0x30
+#define OFFSET_FR7  0x38
+#define OFFSET_FR8  0x40
+#define OFFSET_FR9  0x48
+#define OFFSET_FR10  0x50
+#define OFFSET_FR11  0x58
+#define OFFSET_FR12  0x60
+#define OFFSET_FR13  0x68
+#define OFFSET_FR14  0x70
+#define OFFSET_FR15  0x78
+#define OFFSET_FR16  0x80
+#define OFFSET_FR17  0x88
+#define OFFSET_FR18  0x90
+#define OFFSET_FR19  0x98
+#define OFFSET_FR20  0xa0
+#define OFFSET_FR21  0xa8
+#define OFFSET_FR22  0xb0
+#define OFFSET_FR23  0xb8
+#define OFFSET_FR24  0xc0
+#define OFFSET_FR25  0xc8
+#define OFFSET_FR26  0xd0
+#define OFFSET_FR27  0xd8
+#define OFFSET_FR28  0xe0
+#define OFFSET_FR29  0xe8
+#define OFFSET_FR30  0xf0
+#define OFFSET_FR31  0xf8
+#define OFFSET_FPSCR 0x100
 
 #ifdef __ASM__
Index: kernel/arch/ppc32/include/arch/fpu_context.h
===================================================================
--- kernel/arch/ppc32/include/arch/fpu_context.h	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/include/arch/fpu_context.h	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -36,7 +36,23 @@
 #define KERN_ppc32_FPU_CONTEXT_H_
 
+#define FPU_CONTEXT_ALIGN	8	
+
 #include <typedefs.h>
 
 typedef struct {
+	uint64_t fr0;
+	uint64_t fr1;
+	uint64_t fr2;
+	uint64_t fr3;
+	uint64_t fr4;
+	uint64_t fr5;
+	uint64_t fr6;
+	uint64_t fr7;
+	uint64_t fr8;
+	uint64_t fr9;
+	uint64_t fr10;
+	uint64_t fr11;
+	uint64_t fr12;
+	uint64_t fr13;
 	uint64_t fr14;
 	uint64_t fr15;
@@ -57,5 +73,5 @@
 	uint64_t fr30;
 	uint64_t fr31;
-	uint32_t fpscr;
+	uint64_t fpscr;
 } __attribute__ ((packed)) fpu_context_t;
 
Index: kernel/arch/ppc32/include/arch/interrupt.h
===================================================================
--- kernel/arch/ppc32/include/arch/interrupt.h	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/include/arch/interrupt.h	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -44,4 +44,5 @@
 #define VECTOR_INSTRUCTION_STORAGE  3
 #define VECTOR_EXTERNAL             4
+#define VECTOR_FP_UNAVAILABLE       7
 #define VECTOR_DECREMENTER          8
 #define VECTOR_ITLB_MISS            13
Index: kernel/arch/ppc32/include/arch/msr.h
===================================================================
--- kernel/arch/ppc32/include/arch/msr.h	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/include/arch/msr.h	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -39,4 +39,7 @@
 #define MSR_DR  (1 << 4)
 #define MSR_IR  (1 << 5)
+#define MSR_FE1 (1 << 8)
+#define MSR_FE0 (1 << 11)
+#define MSR_FP  (1 << 13)
 #define MSR_PR  (1 << 14)
 #define MSR_EE  (1 << 15)
Index: kernel/arch/ppc32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ppc32/src/cpu/cpu.c	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/src/cpu/cpu.c	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -37,7 +37,11 @@
 #include <arch.h>
 #include <print.h>
+#include <fpu_context.h>
 
 void cpu_arch_init(void)
 {
+#ifdef CONFIG_FPU
+	fpu_enable();
+#endif
 }
 
@@ -52,18 +56,18 @@
 	
 	switch (cpu->arch.version) {
-		case 8:
-			name = "PowerPC 750";
-			break;
-		case 9:
-			name = "PowerPC 604e";
-			break;
-		case 0x81:
-			name = "PowerPC 8260";
-			break;
-		case 0x8081:
-			name = "PowerPC 826xA";
-			break;
-		default:
-			name = "unknown";
+	case 8:
+		name = "PowerPC 750";
+		break;
+	case 9:
+		name = "PowerPC 604e";
+		break;
+	case 0x81:
+		name = "PowerPC 8260";
+		break;
+	case 0x8081:
+		name = "PowerPC 826xA";
+		break;
+	default:
+		name = "unknown";
 	}
 	
Index: kernel/arch/ppc32/src/exception.S
===================================================================
--- kernel/arch/ppc32/src/exception.S	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/src/exception.S	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -258,5 +258,8 @@
 	mtsrr0 r12
 	
+	mfsrr1 r5
+	andi. r5, r5, MSR_FP
 	mfmsr r12
+	or r12, r12, r5		# Propagate MSR_FP from SRR1 to MSR
 	ori r12, r12, (MSR_IR | MSR_DR)@l
 	mtsrr1 r12
@@ -276,6 +279,9 @@
 	addi r12, r12, iret_syscall@l
 	mtlr r12
-	
+
+	mfsrr1 r0
+	andi. r0, r0, MSR_FP
 	mfmsr r12
+	or r12, r12, r0		# Propagate MSR_FP from SRR1 to MSR
 	ori r12, r12, (MSR_IR | MSR_DR)@l
 	mtsrr1 r12
Index: kernel/arch/ppc32/src/fpu_context.S
===================================================================
--- kernel/arch/ppc32/src/fpu_context.S	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/src/fpu_context.S	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -29,4 +29,5 @@
 #include <arch/asm/regname.h>
 #include <arch/context_offset.h>
+#include <arch/msr.h>
 
 .text
@@ -39,4 +40,18 @@
 
 .macro FPU_CONTEXT_STORE r
+	stfd fr0, OFFSET_FR0(\r)
+	stfd fr1, OFFSET_FR1(\r)
+	stfd fr2, OFFSET_FR2(\r)
+	stfd fr3, OFFSET_FR3(\r)
+	stfd fr4, OFFSET_FR4(\r)
+	stfd fr5, OFFSET_FR5(\r)
+	stfd fr6, OFFSET_FR6(\r)
+	stfd fr7, OFFSET_FR7(\r)
+	stfd fr8, OFFSET_FR8(\r)
+	stfd fr9, OFFSET_FR9(\r)
+	stfd fr10, OFFSET_FR10(\r)
+	stfd fr11, OFFSET_FR11(\r)
+	stfd fr12, OFFSET_FR12(\r)
+	stfd fr13, OFFSET_FR13(\r)
 	stfd fr14, OFFSET_FR14(\r)
 	stfd fr15, OFFSET_FR15(\r)
@@ -60,4 +75,18 @@
 
 .macro FPU_CONTEXT_LOAD r
+	lfd fr0, OFFSET_FR0(\r)
+	lfd fr1, OFFSET_FR1(\r)
+	lfd fr2, OFFSET_FR2(\r)
+	lfd fr3, OFFSET_FR3(\r)
+	lfd fr4, OFFSET_FR4(\r)
+	lfd fr5, OFFSET_FR5(\r)
+	lfd fr6, OFFSET_FR6(\r)
+	lfd fr7, OFFSET_FR7(\r)
+	lfd fr8, OFFSET_FR8(\r)
+	lfd fr9, OFFSET_FR9(\r)
+	lfd fr10, OFFSET_FR10(\r)
+	lfd fr11, OFFSET_FR11(\r)
+	lfd fr12, OFFSET_FR12(\r)
+	lfd fr13, OFFSET_FR13(\r)
 	lfd fr14, OFFSET_FR14(\r)
 	lfd fr15, OFFSET_FR15(\r)
@@ -81,25 +110,41 @@
 
 fpu_context_save:
-//	FPU_CONTEXT_STORE r3
-//	
-//	mffs fr0
-//	stfd fr0, OFFSET_FPSCR(r3)
+	FPU_CONTEXT_STORE r3
+	
+	mffs fr0
+	stfd fr0, OFFSET_FPSCR(r3)
 	
 	blr
 
 fpu_context_restore:
-//	FPU_CONTEXT_LOAD r3
-//	
-//	lfd fr0, OFFSET_FPSCR(r3)
-//	mtfsf 7, fr0
+	lfd fr0, OFFSET_FPSCR(r3)
+	mtfsf 7, fr0
+
+	FPU_CONTEXT_LOAD r3
 	
 	blr
 
 fpu_init:
+	mfmsr r0
+	ori r0, r0, MSR_FP
+
+	# Disable FPU exceptions
+	li r3, MSR_FE0 | MSR_FE1
+	andc r0, r0, r3
+
+	mtmsr r0
 	blr
 
 fpu_enable:
+	mfmsr r0
+	ori r0, r0, MSR_FP
+	mtmsr r0
 	blr
 
 fpu_disable:
+	mfmsr r0
+	li r3, MSR_FP
+	andc r0, r0, r3
+	mtmsr r0
 	blr
+
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ kernel/arch/ppc32/src/interrupt.c	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -112,5 +112,5 @@
 {
 	uint8_t inum;
-	
+
 	while ((inum = pic_get_pending()) != 255) {
 		irq_t *irq = irq_dispatch_and_lock(inum);
@@ -146,4 +146,19 @@
 }
 
+static void exception_fp_unavailable(unsigned int n, istate_t *istate)
+{
+#ifdef CONFIG_FPU_LAZY
+	scheduler_fpu_lazy_request();
+	/*
+	 * Propagate MSR_FP from MSR back to istate's SRR1, which will become
+	 * the next MSR.
+	 */
+	istate->srr1 |= msr_read() & MSR_FP;
+#else
+	fault_if_from_uspace(istate, "FPU fault.");
+	panic_badtrap(istate, n, "FPU fault.");
+#endif
+}
+
 static void exception_decrementer(unsigned int n, istate_t *istate)
 {
@@ -161,4 +176,6 @@
 	exc_register(VECTOR_EXTERNAL, "external", true,
 	    exception_external);
+	exc_register(VECTOR_FP_UNAVAILABLE, "fp_unavailable", true,
+	    exception_fp_unavailable);
 	exc_register(VECTOR_DECREMENTER, "timer", true,
 	    exception_decrementer);
Index: uspace/lib/c/arch/ppc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.common	(revision 6dbe7f68034b7e32c3421c2992cd5663766d56be)
+++ uspace/lib/c/arch/ppc32/Makefile.common	(revision df7f5cea55c99ad82d12a32bcd20102e9fb8cbe2)
@@ -27,5 +27,12 @@
 #
 
-GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
+
+ifeq ($(CONFIG_FPU),y)
+FLOATS=hard
+else
+FLOATS=soft
+endif
+
+GCC_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
 AFLAGS = -a32
