cpu.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2009 Wind River Systems,
  7. * written by Ralf Baechle <ralf@linux-mips.org>
  8. */
  9. #include <linux/init.h>
  10. #include <linux/irqflags.h>
  11. #include <linux/notifier.h>
  12. #include <linux/prefetch.h>
  13. #include <linux/sched.h>
  14. #include <asm/cop2.h>
  15. #include <asm/current.h>
  16. #include <asm/mipsregs.h>
  17. #include <asm/page.h>
  18. #include <asm/octeon/octeon.h>
  19. static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
  20. void *data)
  21. {
  22. unsigned long flags;
  23. unsigned int status;
  24. switch (action) {
  25. case CU2_EXCEPTION:
  26. prefetch(&current->thread.cp2);
  27. local_irq_save(flags);
  28. KSTK_STATUS(current) |= ST0_CU2;
  29. status = read_c0_status();
  30. write_c0_status(status | ST0_CU2);
  31. octeon_cop2_restore(&(current->thread.cp2));
  32. write_c0_status(status & ~ST0_CU2);
  33. local_irq_restore(flags);
  34. return NOTIFY_BAD; /* Don't call default notifier */
  35. }
  36. return NOTIFY_OK; /* Let default notifier send signals */
  37. }
  38. static int __init cnmips_cu2_setup(void)
  39. {
  40. return cu2_notifier(cnmips_cu2_call, 0);
  41. }
  42. early_initcall(cnmips_cu2_setup);