.. | .. |
---|
59 | 59 | #include <linux/irq.h> |
---|
60 | 60 | #include <linux/delay.h> |
---|
61 | 61 | |
---|
| 62 | +#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP) |
---|
| 63 | +#include <soc/rockchip/rk_minidump.h> |
---|
| 64 | +#endif |
---|
| 65 | + |
---|
62 | 66 | #include "fiq_debugger/fiq_debugger_priv.h" |
---|
63 | 67 | #include "rockchip_debug.h" |
---|
64 | 68 | |
---|
.. | .. |
---|
85 | 89 | extern struct atomic_notifier_head hardlock_notifier_list; |
---|
86 | 90 | extern struct atomic_notifier_head rcu_stall_notifier_list; |
---|
87 | 91 | |
---|
| 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 | + |
---|
88 | 108 | #if IS_ENABLED(CONFIG_FIQ_DEBUGGER) |
---|
89 | 109 | static int rockchip_debug_dump_edpcsr(struct fiq_debugger_output *output) |
---|
90 | 110 | { |
---|
.. | .. |
---|
96 | 116 | void __iomem *base; |
---|
97 | 117 | u32 pu = 0, online = 0; |
---|
98 | 118 | |
---|
99 | | -#ifdef CONFIG_ARM64 |
---|
100 | | - /* disable SError */ |
---|
101 | | - asm volatile("msr daifset, #0x4"); |
---|
102 | | -#endif |
---|
| 119 | + rockchip_debug_serror_disable(); |
---|
103 | 120 | |
---|
104 | 121 | while (rockchip_cpu_debug[i]) { |
---|
105 | 122 | online = cpu_online(i); |
---|
.. | .. |
---|
154 | 171 | printed = 0; |
---|
155 | 172 | } |
---|
156 | 173 | |
---|
157 | | -#ifdef CONFIG_ARM64 |
---|
158 | | - /* enable SError */ |
---|
159 | | - asm volatile("msr daifclr, #0x4"); |
---|
160 | | -#endif |
---|
161 | | - |
---|
| 174 | + rockchip_debug_serror_enable(); |
---|
162 | 175 | return NOTIFY_OK; |
---|
163 | 176 | } |
---|
164 | 177 | |
---|
.. | .. |
---|
173 | 186 | void __iomem *base; |
---|
174 | 187 | u32 pu = 0, online = 0; |
---|
175 | 188 | |
---|
176 | | - /* disable SError */ |
---|
177 | | - asm volatile("msr daifset, #0x4"); |
---|
| 189 | + rockchip_debug_serror_disable(); |
---|
178 | 190 | |
---|
179 | 191 | while (rockchip_cs_pmu[i]) { |
---|
180 | 192 | online = cpu_online(i); |
---|
.. | .. |
---|
233 | 245 | prev_pc = NULL; |
---|
234 | 246 | printed = 0; |
---|
235 | 247 | } |
---|
236 | | - /* enable SError */ |
---|
237 | | - asm volatile("msr daifclr, #0x4"); |
---|
| 248 | + rockchip_debug_serror_enable(); |
---|
238 | 249 | return NOTIFY_OK; |
---|
239 | 250 | } |
---|
240 | 251 | #else |
---|
.. | .. |
---|
243 | 254 | return 0; |
---|
244 | 255 | } |
---|
245 | 256 | #endif |
---|
246 | | - |
---|
247 | 257 | |
---|
248 | 258 | int rockchip_debug_dump_pcsr(struct fiq_debugger_output *output) |
---|
249 | 259 | { |
---|
.. | .. |
---|
267 | 277 | void __iomem *base; |
---|
268 | 278 | u32 pu = 0; |
---|
269 | 279 | |
---|
270 | | -#ifdef CONFIG_ARM64 |
---|
271 | | - /* disable SError */ |
---|
272 | | - asm volatile("msr daifset, #0x4"); |
---|
273 | | -#endif |
---|
| 280 | + rockchip_debug_serror_disable(); |
---|
274 | 281 | |
---|
275 | 282 | /* |
---|
276 | 283 | * The panic handler will try to shut down the other CPUs. |
---|
.. | .. |
---|
324 | 331 | printed = 0; |
---|
325 | 332 | } |
---|
326 | 333 | |
---|
327 | | -#ifdef CONFIG_ARM64 |
---|
328 | | - /* enable SError */ |
---|
329 | | - asm volatile("msr daifclr, #0x4"); |
---|
330 | | -#endif |
---|
331 | | - |
---|
332 | 334 | return NOTIFY_OK; |
---|
333 | 335 | } |
---|
334 | 336 | |
---|
.. | .. |
---|
344 | 346 | void __iomem *base; |
---|
345 | 347 | u32 pu = 0; |
---|
346 | 348 | |
---|
347 | | - /* disable SError */ |
---|
348 | | - asm volatile("msr daifset, #0x4"); |
---|
| 349 | + rockchip_debug_serror_disable(); |
---|
349 | 350 | |
---|
350 | 351 | /* |
---|
351 | 352 | * The panic handler will try to shut down the other CPUs. |
---|
.. | .. |
---|
403 | 404 | prev_pc = NULL; |
---|
404 | 405 | printed = 0; |
---|
405 | 406 | } |
---|
406 | | - /* enable SError */ |
---|
407 | | - asm volatile("msr daifclr, #0x4"); |
---|
| 407 | + |
---|
408 | 408 | return NOTIFY_OK; |
---|
409 | 409 | } |
---|
410 | 410 | #else |
---|
.. | .. |
---|
508 | 508 | rockchip_panic_notify_dump_irqs(); |
---|
509 | 509 | return NOTIFY_OK; |
---|
510 | 510 | } |
---|
| 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 | + |
---|
511 | 568 | static struct notifier_block rockchip_panic_nb = { |
---|
512 | 569 | .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, |
---|
513 | 578 | }; |
---|
514 | 579 | |
---|
515 | 580 | static const struct of_device_id rockchip_debug_dt_match[] __initconst = { |
---|
.. | .. |
---|
527 | 592 | }, |
---|
528 | 593 | { /* sentinel */ }, |
---|
529 | 594 | }; |
---|
530 | | - |
---|
531 | 595 | |
---|
532 | 596 | static int __init rockchip_debug_init(void) |
---|
533 | 597 | { |
---|
.. | .. |
---|
575 | 639 | if (IS_ENABLED(CONFIG_NO_GKI)) { |
---|
576 | 640 | if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR)) |
---|
577 | 641 | atomic_notifier_chain_register(&hardlock_notifier_list, |
---|
578 | | - &rockchip_panic_nb); |
---|
| 642 | + &rockchip_hardlock_nb); |
---|
579 | 643 | |
---|
580 | 644 | atomic_notifier_chain_register(&rcu_stall_notifier_list, |
---|
581 | | - &rockchip_panic_nb); |
---|
| 645 | + &rockchip_rcu_stall_nb); |
---|
582 | 646 | } |
---|
583 | 647 | |
---|
584 | 648 | return 0; |
---|
.. | .. |
---|
594 | 658 | if (IS_ENABLED(CONFIG_NO_GKI)) { |
---|
595 | 659 | if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR)) |
---|
596 | 660 | atomic_notifier_chain_unregister(&hardlock_notifier_list, |
---|
597 | | - &rockchip_panic_nb); |
---|
| 661 | + &rockchip_hardlock_nb); |
---|
598 | 662 | |
---|
599 | 663 | atomic_notifier_chain_unregister(&rcu_stall_notifier_list, |
---|
600 | | - &rockchip_panic_nb); |
---|
| 664 | + &rockchip_rcu_stall_nb); |
---|
601 | 665 | } |
---|
602 | 666 | |
---|
603 | 667 | while (rockchip_cpu_debug[i]) |
---|