nmi_debug.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (C) 2007 Atmel Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/kdebug.h>
  10. #include <linux/notifier.h>
  11. #include <linux/sched.h>
  12. #include <linux/sched/debug.h>
  13. #include <asm/irq.h>
  14. enum nmi_action {
  15. NMI_SHOW_STATE = 1 << 0,
  16. NMI_SHOW_REGS = 1 << 1,
  17. NMI_DIE = 1 << 2,
  18. NMI_DEBOUNCE = 1 << 3,
  19. };
  20. static unsigned long nmi_actions;
  21. static int nmi_debug_notify(struct notifier_block *self,
  22. unsigned long val, void *data)
  23. {
  24. struct die_args *args = data;
  25. if (likely(val != DIE_NMI))
  26. return NOTIFY_DONE;
  27. if (nmi_actions & NMI_SHOW_STATE)
  28. show_state();
  29. if (nmi_actions & NMI_SHOW_REGS)
  30. show_regs(args->regs);
  31. if (nmi_actions & NMI_DEBOUNCE)
  32. mdelay(10);
  33. if (nmi_actions & NMI_DIE)
  34. return NOTIFY_BAD;
  35. return NOTIFY_OK;
  36. }
  37. static struct notifier_block nmi_debug_nb = {
  38. .notifier_call = nmi_debug_notify,
  39. };
  40. static int __init nmi_debug_setup(char *str)
  41. {
  42. char *p, *sep;
  43. register_die_notifier(&nmi_debug_nb);
  44. if (nmi_enable()) {
  45. printk(KERN_WARNING "Unable to enable NMI.\n");
  46. return 0;
  47. }
  48. if (*str != '=')
  49. return 0;
  50. for (p = str + 1; *p; p = sep + 1) {
  51. sep = strchr(p, ',');
  52. if (sep)
  53. *sep = 0;
  54. if (strcmp(p, "state") == 0)
  55. nmi_actions |= NMI_SHOW_STATE;
  56. else if (strcmp(p, "regs") == 0)
  57. nmi_actions |= NMI_SHOW_REGS;
  58. else if (strcmp(p, "debounce") == 0)
  59. nmi_actions |= NMI_DEBOUNCE;
  60. else if (strcmp(p, "die") == 0)
  61. nmi_actions |= NMI_DIE;
  62. else
  63. printk(KERN_WARNING "NMI: Unrecognized action `%s'\n",
  64. p);
  65. if (!sep)
  66. break;
  67. }
  68. return 0;
  69. }
  70. __setup("nmi_debug", nmi_debug_setup);