hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/soc/rockchip/rockchip_debug.c
....@@ -59,6 +59,10 @@
5959 #include <linux/irq.h>
6060 #include <linux/delay.h>
6161
62
+#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP)
63
+#include <soc/rockchip/rk_minidump.h>
64
+#endif
65
+
6266 #include "fiq_debugger/fiq_debugger_priv.h"
6367 #include "rockchip_debug.h"
6468
....@@ -85,6 +89,22 @@
8589 extern struct atomic_notifier_head hardlock_notifier_list;
8690 extern struct atomic_notifier_head rcu_stall_notifier_list;
8791
92
+static inline void rockchip_debug_serror_enable(void)
93
+{
94
+#ifdef CONFIG_ARM64
95
+ /* enable SError */
96
+ asm volatile("msr daifclr, #0x4");
97
+#endif
98
+}
99
+
100
+static inline void rockchip_debug_serror_disable(void)
101
+{
102
+#ifdef CONFIG_ARM64
103
+ /* disable SError */
104
+ asm volatile("msr daifset, #0x4");
105
+#endif
106
+}
107
+
88108 #if IS_ENABLED(CONFIG_FIQ_DEBUGGER)
89109 static int rockchip_debug_dump_edpcsr(struct fiq_debugger_output *output)
90110 {
....@@ -96,10 +116,7 @@
96116 void __iomem *base;
97117 u32 pu = 0, online = 0;
98118
99
-#ifdef CONFIG_ARM64
100
- /* disable SError */
101
- asm volatile("msr daifset, #0x4");
102
-#endif
119
+ rockchip_debug_serror_disable();
103120
104121 while (rockchip_cpu_debug[i]) {
105122 online = cpu_online(i);
....@@ -154,11 +171,7 @@
154171 printed = 0;
155172 }
156173
157
-#ifdef CONFIG_ARM64
158
- /* enable SError */
159
- asm volatile("msr daifclr, #0x4");
160
-#endif
161
-
174
+ rockchip_debug_serror_enable();
162175 return NOTIFY_OK;
163176 }
164177
....@@ -173,8 +186,7 @@
173186 void __iomem *base;
174187 u32 pu = 0, online = 0;
175188
176
- /* disable SError */
177
- asm volatile("msr daifset, #0x4");
189
+ rockchip_debug_serror_disable();
178190
179191 while (rockchip_cs_pmu[i]) {
180192 online = cpu_online(i);
....@@ -233,8 +245,7 @@
233245 prev_pc = NULL;
234246 printed = 0;
235247 }
236
- /* enable SError */
237
- asm volatile("msr daifclr, #0x4");
248
+ rockchip_debug_serror_enable();
238249 return NOTIFY_OK;
239250 }
240251 #else
....@@ -243,7 +254,6 @@
243254 return 0;
244255 }
245256 #endif
246
-
247257
248258 int rockchip_debug_dump_pcsr(struct fiq_debugger_output *output)
249259 {
....@@ -267,10 +277,7 @@
267277 void __iomem *base;
268278 u32 pu = 0;
269279
270
-#ifdef CONFIG_ARM64
271
- /* disable SError */
272
- asm volatile("msr daifset, #0x4");
273
-#endif
280
+ rockchip_debug_serror_disable();
274281
275282 /*
276283 * The panic handler will try to shut down the other CPUs.
....@@ -324,11 +331,6 @@
324331 printed = 0;
325332 }
326333
327
-#ifdef CONFIG_ARM64
328
- /* enable SError */
329
- asm volatile("msr daifclr, #0x4");
330
-#endif
331
-
332334 return NOTIFY_OK;
333335 }
334336
....@@ -344,8 +346,7 @@
344346 void __iomem *base;
345347 u32 pu = 0;
346348
347
- /* disable SError */
348
- asm volatile("msr daifset, #0x4");
349
+ rockchip_debug_serror_disable();
349350
350351 /*
351352 * The panic handler will try to shut down the other CPUs.
....@@ -403,8 +404,7 @@
403404 prev_pc = NULL;
404405 printed = 0;
405406 }
406
- /* enable SError */
407
- asm volatile("msr daifclr, #0x4");
407
+
408408 return NOTIFY_OK;
409409 }
410410 #else
....@@ -508,8 +508,73 @@
508508 rockchip_panic_notify_dump_irqs();
509509 return NOTIFY_OK;
510510 }
511
+
512
+static int rockchip_hardlock_notify(struct notifier_block *nb,
513
+ unsigned long event, void *p)
514
+{
515
+ u64 pmpcsr;
516
+ int el;
517
+ u32 pu = 0;
518
+ void *pc = NULL;
519
+ void __iomem *base;
520
+ unsigned long edpcsr;
521
+ unsigned long cpu = event;
522
+
523
+ rockchip_debug_serror_disable();
524
+
525
+ pu = (u32)readl(rockchip_cpu_debug[cpu] + EDPRSR) & EDPRSR_PU;
526
+ if (pu != EDPRSR_PU) {
527
+ pr_err("CPU%ld power down\n", cpu);
528
+ return NOTIFY_OK;
529
+ }
530
+
531
+ if (edpcsr_present) {
532
+ base = rockchip_cpu_debug[cpu];
533
+ /* Unlock EDLSR.SLK so that EDPCSRhi gets populated */
534
+ writel(EDLAR_UNLOCK, base + EDLAR);
535
+ if (sizeof(edpcsr) == 8)
536
+ edpcsr = ((u64)readl(base + EDPCSR_LO)) |
537
+ ((u64)readl(base + EDPCSR_HI) << 32);
538
+ else
539
+ edpcsr = (u32)readl(base + EDPCSR_LO);
540
+
541
+ /* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */
542
+ pc = (void *)(edpcsr & ~1);
543
+ } else {
544
+ base = rockchip_cs_pmu[cpu];
545
+ pmpcsr = ((u64)readl(base + PMPCSR_LO)) |
546
+ ((u64)readl(base + PMPCSR_HI) << 32);
547
+ el = (pmpcsr >> 61) & 0x3;
548
+ if (el == 2)
549
+ pmpcsr |= 0xff00000000000000;
550
+ else
551
+ pmpcsr &= 0x0fffffffffffffff;
552
+ /* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */
553
+ pc = (void *)(pmpcsr & ~1);
554
+ }
555
+
556
+ rockchip_debug_serror_enable();
557
+
558
+#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP)
559
+ rk_minidump_hardlock_notify(nb, event, pc);
560
+#endif
561
+
562
+#if !IS_ENABLED(CONFIG_BOOTPARAM_HARDLOCKUP_PANIC)
563
+ rockchip_panic_notify(nb, event, p);
564
+#endif
565
+ return NOTIFY_OK;
566
+}
567
+
511568 static struct notifier_block rockchip_panic_nb = {
512569 .notifier_call = rockchip_panic_notify,
570
+};
571
+
572
+static struct notifier_block rockchip_rcu_stall_nb = {
573
+ .notifier_call = rockchip_panic_notify,
574
+};
575
+
576
+static struct notifier_block rockchip_hardlock_nb = {
577
+ .notifier_call = rockchip_hardlock_notify,
513578 };
514579
515580 static const struct of_device_id rockchip_debug_dt_match[] __initconst = {
....@@ -527,7 +592,6 @@
527592 },
528593 { /* sentinel */ },
529594 };
530
-
531595
532596 static int __init rockchip_debug_init(void)
533597 {
....@@ -575,10 +639,10 @@
575639 if (IS_ENABLED(CONFIG_NO_GKI)) {
576640 if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR))
577641 atomic_notifier_chain_register(&hardlock_notifier_list,
578
- &rockchip_panic_nb);
642
+ &rockchip_hardlock_nb);
579643
580644 atomic_notifier_chain_register(&rcu_stall_notifier_list,
581
- &rockchip_panic_nb);
645
+ &rockchip_rcu_stall_nb);
582646 }
583647
584648 return 0;
....@@ -594,10 +658,10 @@
594658 if (IS_ENABLED(CONFIG_NO_GKI)) {
595659 if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR))
596660 atomic_notifier_chain_unregister(&hardlock_notifier_list,
597
- &rockchip_panic_nb);
661
+ &rockchip_hardlock_nb);
598662
599663 atomic_notifier_chain_unregister(&rcu_stall_notifier_list,
600
- &rockchip_panic_nb);
664
+ &rockchip_rcu_stall_nb);
601665 }
602666
603667 while (rockchip_cpu_debug[i])