aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2009-11-23 20:24:58 -0500
committerRalf Baechle <ralf@linux-mips.org>2009-12-16 20:57:30 -0500
commit69f3a7de1f1ec935924b1b13f83812f8b30e92ce (patch)
treea5f8a71b9cb3026a44ae7a1564488de8c3d8d2a9 /arch/mips/kernel/traps.c
parent4dd92e15b316d1a782772f16074571a70ceb9184 (diff)
MIPS: Modularize COP2 handling
Away with the daemons of ifdef; get ready for future COP2 users. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Patchwork: http://patchwork.linux-mips.org/patch/708/
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 0a18b4c62afb..9fe21fb65305 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -25,10 +25,12 @@
25#include <linux/ptrace.h> 25#include <linux/ptrace.h>
26#include <linux/kgdb.h> 26#include <linux/kgdb.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/notifier.h>
28 29
29#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
30#include <asm/branch.h> 31#include <asm/branch.h>
31#include <asm/break.h> 32#include <asm/break.h>
33#include <asm/cop2.h>
32#include <asm/cpu.h> 34#include <asm/cpu.h>
33#include <asm/dsp.h> 35#include <asm/dsp.h>
34#include <asm/fpu.h> 36#include <asm/fpu.h>
@@ -79,10 +81,6 @@ extern asmlinkage void handle_reserved(void);
79extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, 81extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
80 struct mips_fpu_struct *ctx, int has_fpu); 82 struct mips_fpu_struct *ctx, int has_fpu);
81 83
82#ifdef CONFIG_CPU_CAVIUM_OCTEON
83extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
84#endif
85
86void (*board_be_init)(void); 84void (*board_be_init)(void);
87int (*board_be_handler)(struct pt_regs *regs, int is_fixup); 85int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
88void (*board_nmi_handler_setup)(void); 86void (*board_nmi_handler_setup)(void);
@@ -857,6 +855,44 @@ static void mt_ase_fp_affinity(void)
857#endif /* CONFIG_MIPS_MT_FPAFF */ 855#endif /* CONFIG_MIPS_MT_FPAFF */
858} 856}
859 857
858/*
859 * No lock; only written during early bootup by CPU 0.
860 */
861static RAW_NOTIFIER_HEAD(cu2_chain);
862
863int __ref register_cu2_notifier(struct notifier_block *nb)
864{
865 return raw_notifier_chain_register(&cu2_chain, nb);
866}
867
868int cu2_notifier_call_chain(unsigned long val, void *v)
869{
870 return raw_notifier_call_chain(&cu2_chain, val, v);
871}
872
873static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
874 void *data)
875{
876 struct pt_regs *regs = data;
877
878 switch (action) {
879 default:
880 die_if_kernel("Unhandled kernel unaligned access or invalid "
881 "instruction", regs);
882 /* Fall through */
883
884 case CU2_EXCEPTION:
885 force_sig(SIGILL, current);
886 }
887
888 return NOTIFY_OK;
889}
890
891static struct notifier_block default_cu2_notifier = {
892 .notifier_call = default_cu2_call,
893 .priority = 0x80000000, /* Run last */
894};
895
860asmlinkage void do_cpu(struct pt_regs *regs) 896asmlinkage void do_cpu(struct pt_regs *regs)
861{ 897{
862 unsigned int __user *epc; 898 unsigned int __user *epc;
@@ -920,17 +956,9 @@ asmlinkage void do_cpu(struct pt_regs *regs)
920 return; 956 return;
921 957
922 case 2: 958 case 2:
923#ifdef CONFIG_CPU_CAVIUM_OCTEON 959 raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
924 prefetch(&current->thread.cp2); 960 break;
925 local_irq_save(flags); 961
926 KSTK_STATUS(current) |= ST0_CU2;
927 status = read_c0_status();
928 write_c0_status(status | ST0_CU2);
929 octeon_cop2_restore(&(current->thread.cp2));
930 write_c0_status(status & ~ST0_CU2);
931 local_irq_restore(flags);
932 return;
933#endif
934 case 3: 962 case 3:
935 break; 963 break;
936 } 964 }
@@ -1760,4 +1788,6 @@ void __init trap_init(void)
1760 flush_tlb_handlers(); 1788 flush_tlb_handlers();
1761 1789
1762 sort_extable(__start___dbe_table, __stop___dbe_table); 1790 sort_extable(__start___dbe_table, __stop___dbe_table);
1791
1792 register_cu2_notifier(&default_cu2_notifier);
1763} 1793}