0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/irqflags.h>
0011 #include <linux/notifier.h>
0012 #include <linux/prefetch.h>
0013 #include <linux/ptrace.h>
0014 #include <linux/sched.h>
0015 #include <linux/sched/task_stack.h>
0016
0017 #include <asm/cop2.h>
0018 #include <asm/current.h>
0019 #include <asm/mipsregs.h>
0020 #include <asm/page.h>
0021 #include <asm/octeon/octeon.h>
0022
0023 static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
0024 void *data)
0025 {
0026 unsigned long flags;
0027 unsigned int status;
0028
0029 switch (action) {
0030 case CU2_EXCEPTION:
0031 prefetch(¤t->thread.cp2);
0032 local_irq_save(flags);
0033 KSTK_STATUS(current) |= ST0_CU2;
0034 status = read_c0_status();
0035 write_c0_status(status | ST0_CU2);
0036 octeon_cop2_restore(&(current->thread.cp2));
0037 write_c0_status(status & ~ST0_CU2);
0038 local_irq_restore(flags);
0039
0040 return NOTIFY_BAD;
0041 }
0042
0043 return NOTIFY_OK;
0044 }
0045
0046 static int __init cnmips_cu2_setup(void)
0047 {
0048 return cu2_notifier(cnmips_cu2_call, 0);
0049 }
0050 early_initcall(cnmips_cu2_setup);