| 1 | MIPS: allow disabling the kernel FPU emulator |
| 2 | |
| 3 | This patch allows turning off the in-kernel Algorithmics |
| 4 | FPU emulator support, which allows one to save a couple of |
| 5 | precious blocks on an embedded system. |
| 6 | |
| 7 | Signed-off-by: Florian Fainelli <florian@openwrt.org> |
| 8 | -- |
| 9 | --- a/arch/mips/Kconfig |
| 10 | +++ b/arch/mips/Kconfig |
| 11 | @@ -961,6 +961,17 @@ config I8259 |
| 12 | config MIPS_BONITO64 |
| 13 | bool |
| 14 | |
| 15 | +config MIPS_FPU_EMU |
| 16 | + bool "Enable FPU emulation" |
| 17 | + default y |
| 18 | + help |
| 19 | + This option allows building a kernel with or without the Algorithmics |
| 20 | + FPU emulator enabled. Turning off this option results in a kernel which |
| 21 | + does not catch floating operations exceptions. Make sure that your toolchain |
| 22 | + is configured to enable software floating point emulation in that case. |
| 23 | + |
| 24 | + If unsure say Y here. |
| 25 | + |
| 26 | config MIPS_MSC |
| 27 | bool |
| 28 | |
| 29 | --- a/arch/mips/math-emu/Makefile |
| 30 | +++ b/arch/mips/math-emu/Makefile |
| 31 | @@ -2,11 +2,13 @@ |
| 32 | # Makefile for the Linux/MIPS kernel FPU emulation. |
| 33 | # |
| 34 | |
| 35 | -obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ |
| 36 | +obj-y := kernel_linkage.o dsemul.o cp1emu.o |
| 37 | + |
| 38 | +obj-$(CONFIG_MIPS_FPU_EMU) += ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ |
| 39 | ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \ |
| 40 | dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \ |
| 41 | dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ |
| 42 | sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ |
| 43 | sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ |
| 44 | - dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o |
| 45 | + dp_sqrt.o sp_sqrt.o |
| 46 | |
| 47 | --- a/arch/mips/math-emu/cp1emu.c |
| 48 | +++ b/arch/mips/math-emu/cp1emu.c |
| 49 | @@ -58,7 +58,11 @@ |
| 50 | #define __mips 4 |
| 51 | |
| 52 | /* Function which emulates a floating point instruction. */ |
| 53 | +#ifdef CONFIG_DEBUG_FS |
| 54 | +DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); |
| 55 | +#endif |
| 56 | |
| 57 | +#ifdef CONFIG_MIPS_FPU_EMU |
| 58 | static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, |
| 59 | mips_instruction); |
| 60 | |
| 61 | @@ -69,10 +73,6 @@ static int fpux_emu(struct pt_regs *, |
| 62 | |
| 63 | /* Further private data for which no space exists in mips_fpu_struct */ |
| 64 | |
| 65 | -#ifdef CONFIG_DEBUG_FS |
| 66 | -DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); |
| 67 | -#endif |
| 68 | - |
| 69 | /* Control registers */ |
| 70 | |
| 71 | #define FPCREG_RID 0 /* $0 = revision id */ |
| 72 | @@ -1360,7 +1360,6 @@ int fpu_emulator_cop1Handler(struct pt_r |
| 73 | |
| 74 | return sig; |
| 75 | } |
| 76 | - |
| 77 | #ifdef CONFIG_DEBUG_FS |
| 78 | |
| 79 | static int fpuemu_stat_get(void *data, u64 *val) |
| 80 | @@ -1409,4 +1408,11 @@ static int __init debugfs_fpuemu(void) |
| 81 | return 0; |
| 82 | } |
| 83 | __initcall(debugfs_fpuemu); |
| 84 | -#endif |
| 85 | +#endif /* CONFIG_DEBUGFS */ |
| 86 | +#else |
| 87 | +int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 88 | + int has_fpu) |
| 89 | +{ |
| 90 | + return 0; |
| 91 | +} |
| 92 | +#endif /* CONFIG_MIPS_FPU_EMU */ |
| 93 | --- a/arch/mips/math-emu/dsemul.c |
| 94 | +++ b/arch/mips/math-emu/dsemul.c |
| 95 | @@ -109,6 +109,7 @@ int mips_dsemul(struct pt_regs *regs, mi |
| 96 | return SIGILL; /* force out of emulation loop */ |
| 97 | } |
| 98 | |
| 99 | +#ifdef CONFIG_MIPS_FPU_EMU |
| 100 | int do_dsemulret(struct pt_regs *xcp) |
| 101 | { |
| 102 | struct emuframe __user *fr; |
| 103 | @@ -165,3 +166,9 @@ int do_dsemulret(struct pt_regs *xcp) |
| 104 | |
| 105 | return 1; |
| 106 | } |
| 107 | +#else |
| 108 | +int do_dsemulret(struct pt_regs *xcp) |
| 109 | +{ |
| 110 | + return 0; |
| 111 | +} |
| 112 | +#endif /* CONFIG_MIPS_FPU_EMU */ |
| 113 | --- a/arch/mips/math-emu/kernel_linkage.c |
| 114 | +++ b/arch/mips/math-emu/kernel_linkage.c |
| 115 | @@ -29,6 +29,7 @@ |
| 116 | |
| 117 | #define SIGNALLING_NAN 0x7ff800007ff80000LL |
| 118 | |
| 119 | +#ifdef CONFIG_MIPS_FPU_EMU |
| 120 | void fpu_emulator_init_fpu(void) |
| 121 | { |
| 122 | static int first = 1; |
| 123 | @@ -112,4 +113,36 @@ int fpu_emulator_restore_context32(struc |
| 124 | |
| 125 | return err; |
| 126 | } |
| 127 | -#endif |
| 128 | +#endif /* CONFIG_64BIT */ |
| 129 | +#else |
| 130 | + |
| 131 | +void fpu_emulator_init_fpu(void) |
| 132 | +{ |
| 133 | + printk(KERN_INFO "FPU emulator disabled, make sure your toolchain" |
| 134 | + "was compiled with software floating point support (soft-float)\n"); |
| 135 | + return; |
| 136 | +} |
| 137 | + |
| 138 | +int fpu_emulator_save_context(struct sigcontext __user *sc) |
| 139 | +{ |
| 140 | + return 0; |
| 141 | +} |
| 142 | + |
| 143 | +int fpu_emulator_restore_context(struct sigcontext __user *sc) |
| 144 | +{ |
| 145 | + return 0; |
| 146 | +} |
| 147 | + |
| 148 | +int fpu_emulator_save_context32(struct sigcontext32 __user *sc) |
| 149 | +{ |
| 150 | + return 0; |
| 151 | +} |
| 152 | + |
| 153 | +int fpu_emulator_restore_context32(struct sigcontext32 __user *sc) |
| 154 | +{ |
| 155 | + return 0; |
| 156 | +} |
| 157 | + |
| 158 | +#ifdef CONFIG_64BIT |
| 159 | +#endif /* CONFIG_64BIT */ |
| 160 | +#endif /* CONFIG_MIPS_FPU_EMU */ |
| 161 | |