From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/soc/rockchip/rockchip_debug.c | 128 ++++++++++++++++++++++++++++++++---------- 1 files changed, 96 insertions(+), 32 deletions(-) diff --git a/kernel/drivers/soc/rockchip/rockchip_debug.c b/kernel/drivers/soc/rockchip/rockchip_debug.c index 60edc6a..2f9eac2 100644 --- a/kernel/drivers/soc/rockchip/rockchip_debug.c +++ b/kernel/drivers/soc/rockchip/rockchip_debug.c @@ -59,6 +59,10 @@ #include <linux/irq.h> #include <linux/delay.h> +#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP) +#include <soc/rockchip/rk_minidump.h> +#endif + #include "fiq_debugger/fiq_debugger_priv.h" #include "rockchip_debug.h" @@ -85,6 +89,22 @@ extern struct atomic_notifier_head hardlock_notifier_list; extern struct atomic_notifier_head rcu_stall_notifier_list; +static inline void rockchip_debug_serror_enable(void) +{ +#ifdef CONFIG_ARM64 + /* enable SError */ + asm volatile("msr daifclr, #0x4"); +#endif +} + +static inline void rockchip_debug_serror_disable(void) +{ +#ifdef CONFIG_ARM64 + /* disable SError */ + asm volatile("msr daifset, #0x4"); +#endif +} + #if IS_ENABLED(CONFIG_FIQ_DEBUGGER) static int rockchip_debug_dump_edpcsr(struct fiq_debugger_output *output) { @@ -96,10 +116,7 @@ void __iomem *base; u32 pu = 0, online = 0; -#ifdef CONFIG_ARM64 - /* disable SError */ - asm volatile("msr daifset, #0x4"); -#endif + rockchip_debug_serror_disable(); while (rockchip_cpu_debug[i]) { online = cpu_online(i); @@ -154,11 +171,7 @@ printed = 0; } -#ifdef CONFIG_ARM64 - /* enable SError */ - asm volatile("msr daifclr, #0x4"); -#endif - + rockchip_debug_serror_enable(); return NOTIFY_OK; } @@ -173,8 +186,7 @@ void __iomem *base; u32 pu = 0, online = 0; - /* disable SError */ - asm volatile("msr daifset, #0x4"); + rockchip_debug_serror_disable(); while (rockchip_cs_pmu[i]) { online = cpu_online(i); @@ -233,8 +245,7 @@ prev_pc = NULL; printed = 0; } - /* enable SError */ - asm volatile("msr daifclr, #0x4"); + rockchip_debug_serror_enable(); return NOTIFY_OK; } #else @@ -243,7 +254,6 @@ return 0; } #endif - int rockchip_debug_dump_pcsr(struct fiq_debugger_output *output) { @@ -267,10 +277,7 @@ void __iomem *base; u32 pu = 0; -#ifdef CONFIG_ARM64 - /* disable SError */ - asm volatile("msr daifset, #0x4"); -#endif + rockchip_debug_serror_disable(); /* * The panic handler will try to shut down the other CPUs. @@ -324,11 +331,6 @@ printed = 0; } -#ifdef CONFIG_ARM64 - /* enable SError */ - asm volatile("msr daifclr, #0x4"); -#endif - return NOTIFY_OK; } @@ -344,8 +346,7 @@ void __iomem *base; u32 pu = 0; - /* disable SError */ - asm volatile("msr daifset, #0x4"); + rockchip_debug_serror_disable(); /* * The panic handler will try to shut down the other CPUs. @@ -403,8 +404,7 @@ prev_pc = NULL; printed = 0; } - /* enable SError */ - asm volatile("msr daifclr, #0x4"); + return NOTIFY_OK; } #else @@ -508,8 +508,73 @@ rockchip_panic_notify_dump_irqs(); return NOTIFY_OK; } + +static int rockchip_hardlock_notify(struct notifier_block *nb, + unsigned long event, void *p) +{ + u64 pmpcsr; + int el; + u32 pu = 0; + void *pc = NULL; + void __iomem *base; + unsigned long edpcsr; + unsigned long cpu = event; + + rockchip_debug_serror_disable(); + + pu = (u32)readl(rockchip_cpu_debug[cpu] + EDPRSR) & EDPRSR_PU; + if (pu != EDPRSR_PU) { + pr_err("CPU%ld power down\n", cpu); + return NOTIFY_OK; + } + + if (edpcsr_present) { + base = rockchip_cpu_debug[cpu]; + /* Unlock EDLSR.SLK so that EDPCSRhi gets populated */ + writel(EDLAR_UNLOCK, base + EDLAR); + if (sizeof(edpcsr) == 8) + edpcsr = ((u64)readl(base + EDPCSR_LO)) | + ((u64)readl(base + EDPCSR_HI) << 32); + else + edpcsr = (u32)readl(base + EDPCSR_LO); + + /* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */ + pc = (void *)(edpcsr & ~1); + } else { + base = rockchip_cs_pmu[cpu]; + pmpcsr = ((u64)readl(base + PMPCSR_LO)) | + ((u64)readl(base + PMPCSR_HI) << 32); + el = (pmpcsr >> 61) & 0x3; + if (el == 2) + pmpcsr |= 0xff00000000000000; + else + pmpcsr &= 0x0fffffffffffffff; + /* NOTE: no offset on ARMv8; see DBGDEVID1.PCSROffset */ + pc = (void *)(pmpcsr & ~1); + } + + rockchip_debug_serror_enable(); + +#if IS_ENABLED(CONFIG_ROCKCHIP_MINIDUMP) + rk_minidump_hardlock_notify(nb, event, pc); +#endif + +#if !IS_ENABLED(CONFIG_BOOTPARAM_HARDLOCKUP_PANIC) + rockchip_panic_notify(nb, event, p); +#endif + return NOTIFY_OK; +} + static struct notifier_block rockchip_panic_nb = { .notifier_call = rockchip_panic_notify, +}; + +static struct notifier_block rockchip_rcu_stall_nb = { + .notifier_call = rockchip_panic_notify, +}; + +static struct notifier_block rockchip_hardlock_nb = { + .notifier_call = rockchip_hardlock_notify, }; static const struct of_device_id rockchip_debug_dt_match[] __initconst = { @@ -527,7 +592,6 @@ }, { /* sentinel */ }, }; - static int __init rockchip_debug_init(void) { @@ -575,10 +639,10 @@ if (IS_ENABLED(CONFIG_NO_GKI)) { if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR)) atomic_notifier_chain_register(&hardlock_notifier_list, - &rockchip_panic_nb); + &rockchip_hardlock_nb); atomic_notifier_chain_register(&rcu_stall_notifier_list, - &rockchip_panic_nb); + &rockchip_rcu_stall_nb); } return 0; @@ -594,10 +658,10 @@ if (IS_ENABLED(CONFIG_NO_GKI)) { if (IS_ENABLED(CONFIG_HARDLOCKUP_DETECTOR)) atomic_notifier_chain_unregister(&hardlock_notifier_list, - &rockchip_panic_nb); + &rockchip_hardlock_nb); atomic_notifier_chain_unregister(&rcu_stall_notifier_list, - &rockchip_panic_nb); + &rockchip_rcu_stall_nb); } while (rockchip_cpu_debug[i]) -- Gitblit v1.6.2