toc.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/kgdb.h>
  4. #include <linux/printk.h>
  5. #include <linux/sched/debug.h>
  6. #include <linux/delay.h>
  7. #include <linux/reboot.h>
  8. #include <asm/pdc.h>
  9. #include <asm/pdc_chassis.h>
  10. #include <asm/ldcw.h>
  11. #include <asm/processor.h>
  12. static unsigned int __aligned(16) toc_lock = 1;
  13. DEFINE_PER_CPU_PAGE_ALIGNED(char [16384], toc_stack) __visible;
  14. static void toc20_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_20 *toc)
  15. {
  16. int i;
  17. regs->gr[0] = (unsigned long)toc->cr[22];
  18. for (i = 1; i < 32; i++)
  19. regs->gr[i] = (unsigned long)toc->gr[i];
  20. for (i = 0; i < 8; i++)
  21. regs->sr[i] = (unsigned long)toc->sr[i];
  22. regs->iasq[0] = (unsigned long)toc->cr[17];
  23. regs->iasq[1] = (unsigned long)toc->iasq_back;
  24. regs->iaoq[0] = (unsigned long)toc->cr[18];
  25. regs->iaoq[1] = (unsigned long)toc->iaoq_back;
  26. regs->sar = (unsigned long)toc->cr[11];
  27. regs->iir = (unsigned long)toc->cr[19];
  28. regs->isr = (unsigned long)toc->cr[20];
  29. regs->ior = (unsigned long)toc->cr[21];
  30. }
  31. static void toc11_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_11 *toc)
  32. {
  33. int i;
  34. regs->gr[0] = toc->cr[22];
  35. for (i = 1; i < 32; i++)
  36. regs->gr[i] = toc->gr[i];
  37. for (i = 0; i < 8; i++)
  38. regs->sr[i] = toc->sr[i];
  39. regs->iasq[0] = toc->cr[17];
  40. regs->iasq[1] = toc->iasq_back;
  41. regs->iaoq[0] = toc->cr[18];
  42. regs->iaoq[1] = toc->iaoq_back;
  43. regs->sar = toc->cr[11];
  44. regs->iir = toc->cr[19];
  45. regs->isr = toc->cr[20];
  46. regs->ior = toc->cr[21];
  47. }
  48. void notrace __noreturn __cold toc_intr(struct pt_regs *regs)
  49. {
  50. struct pdc_toc_pim_20 pim_data20;
  51. struct pdc_toc_pim_11 pim_data11;
  52. /* verify we wrote regs to the correct stack */
  53. BUG_ON(regs != (struct pt_regs *)&per_cpu(toc_stack, raw_smp_processor_id()));
  54. if (boot_cpu_data.cpu_type >= pcxu) {
  55. if (pdc_pim_toc20(&pim_data20))
  56. panic("Failed to get PIM data");
  57. toc20_to_pt_regs(regs, &pim_data20);
  58. } else {
  59. if (pdc_pim_toc11(&pim_data11))
  60. panic("Failed to get PIM data");
  61. toc11_to_pt_regs(regs, &pim_data11);
  62. }
  63. #ifdef CONFIG_KGDB
  64. nmi_enter();
  65. if (atomic_read(&kgdb_active) != -1)
  66. kgdb_nmicallback(raw_smp_processor_id(), regs);
  67. kgdb_handle_exception(9, SIGTRAP, 0, regs);
  68. #endif
  69. /* serialize output, otherwise all CPUs write backtrace at once */
  70. while (__ldcw(&toc_lock) == 0)
  71. ; /* wait */
  72. show_regs(regs);
  73. toc_lock = 1; /* release lock for next CPU */
  74. if (raw_smp_processor_id() != 0)
  75. while (1) ; /* all but monarch CPU will wait endless. */
  76. /* give other CPUs time to show their backtrace */
  77. mdelay(2000);
  78. machine_restart("TOC");
  79. /* should never reach this */
  80. panic("TOC");
  81. }
  82. static __init int setup_toc(void)
  83. {
  84. unsigned int csum = 0;
  85. unsigned long toc_code = (unsigned long)dereference_function_descriptor(toc_handler);
  86. int i;
  87. PAGE0->vec_toc = __pa(toc_code) & 0xffffffff;
  88. #ifdef CONFIG_64BIT
  89. PAGE0->vec_toc_hi = __pa(toc_code) >> 32;
  90. #endif
  91. PAGE0->vec_toclen = toc_handler_size;
  92. for (i = 0; i < toc_handler_size/4; i++)
  93. csum += ((u32 *)toc_code)[i];
  94. toc_handler_csum = -csum;
  95. pr_info("TOC handler registered\n");
  96. return 0;
  97. }
  98. early_initcall(setup_toc);