From: Donghyeok Choe Date: Mon, 18 Mar 2019 04:04:38 +0000 (+0900) Subject: [RAMEN9610-14210][COMMON] soc: samsung: re-engineering for exynos_err_parse X-Git-Tag: MMI-QSB30.62-17~1048 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4d27247681cf007424c11342aadd8d44a79b220e;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git [RAMEN9610-14210][COMMON] soc: samsung: re-engineering for exynos_err_parse Change-Id: Iafe6c1f2cf6ab92c3ac9086839ae10e7da04bc24 Signed-off-by: Donghyeok Choe --- diff --git a/drivers/soc/samsung/debug/exynos-helper.c b/drivers/soc/samsung/debug/exynos-helper.c index 229f67e692ea..ca287b3c3cb5 100644 --- a/drivers/soc/samsung/debug/exynos-helper.c +++ b/drivers/soc/samsung/debug/exynos-helper.c @@ -42,6 +42,195 @@ extern void (*arm_pm_restart)(enum reboot_mode str, const char *cmd); +static struct err_variant arm64_err_type_1[] = { + ERR_VAR("AV", 31, 31), + ERR_VAR("Valid", 30, 30), + ERR_VAR("UC", 29, 29), + ERR_VAR("ER", 28, 28), + ERR_VAR("OF", 27, 27), + ERR_VAR("MV", 26, 26), + ERR_VAR("CE", 25, 24), + ERR_VAR("DE", 23, 23), + ERR_VAR("PN", 22, 22), + ERR_VAR("UET", 21, 20), + ERR_VAR("RES0", 19, 16), + ERR_VAR("IERR", 15, 8), + ERR_VAR("SERR", 7, 0), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_2[] = { + ERR_VAR("Count1", 63, 56), + ERR_VAR("Count0", 55, 48), + ERR_VAR("RES1", 47, 41), + ERR_VAR("Syndrom", 40, 32), + ERR_VAR("Stype2", 31, 28), + ERR_VAR("SType1", 27, 24), + ERR_VAR("SType0", 23, 16), + ERR_VAR("Type", 15, 12), + ERR_VAR("RES0", 11, 6), + ERR_VAR("RE", 5, 5), + ERR_VAR("SynValid", 4, 4), + ERR_VAR("AddrValid", 3, 3), + ERR_VAR("UnContained", 2, 2), + ERR_VAR("UC", 1, 1), + ERR_VAR("Vaild", 0, 0), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_3[] = { + ERR_VAR("RES0", 63, 32), + ERR_VAR("A", 31, 31), + ERR_VAR("RES0", 30, 25), + ERR_VAR("RES2", 24, 16), + ERR_VAR("AEType", 15, 14), + ERR_VAR("RES1", 13, 13), + ERR_VAR("EXT", 12, 12), + ERR_VAR("AET", 11, 10), + ERR_VAR("EA", 9, 9), + ERR_VAR("EA", 8, 6), + ERR_VAR("DFSC", 5, 0), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_4[] = { + ERR_VAR("Fatal", 63, 63), + ERR_VAR("RES0", 62, 48), + ERR_VAR("Other error count", 47, 40), + ERR_VAR("Repeat error count", 39, 32), + ERR_VAR("Valid", 31, 31), + ERR_VAR("RAMID", 30, 24), + ERR_VAR("RES0", 23, 21), + ERR_VAR("CPUID", 20, 18), + ERR_VAR("RES0", 17, 12), + ERR_VAR("RAM address", 11, 0), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_TCR[] = { +// ERR_VAR("HPD1", 42, 42), +// ERR_VAR("HPD0", 41, 41), +// ERR_VAR("HD", 40, 40), +// ERR_VAR("HA", 39, 39), + ERR_VAR("TBI1", 38, 38), + ERR_VAR("TBI0", 37, 37), +// ERR_VAR("AS", 36, 36), +// ERR_VAR("IPS", 34, 32), +// ERR_VAR("TG1", 31, 30), +// ERR_VAR("SH1", 29, 28), +// ERR_VAR("ORGN1", 27, 26), +// ERR_VAR("IRGN1", 25, 24), +// ERR_VAR("EPD1", 23, 23), +// ERR_VAR("A1", 22, 22), +// ERR_VAR("T1SZ", 21, 16), +// ERR_VAR("TG0", 15, 14), +// ERR_VAR("SH0", 13, 12), +// ERR_VAR("ORGN0", 11, 10), +// ERR_VAR("IRGN0", 9, 8), +// ERR_VAR("EPD0", 7, 7), +// ERR_VAR("T1SZ", 5, 0), +// ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_VBAR[] = { + ERR_VAR("VBA[63:56]", 63, 56), + ERR_VAR("VBA[55]", 55, 55), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_L2ECTLR[] = { + ERR_VAR("L2AsyncErr", 30, 30), + ERR_VAR("END", 64, 64), +}; + +static struct err_variant arm64_err_type_L3ECTLR[] = { + ERR_VAR("L3IntrnAsyncErr", 30, 30), + ERR_VAR("ExtBusAsyncErr", 29, 29), + ERR_VAR("EnTmrIncChk", 3, 3), + ERR_VAR("ClusterQactiveCtl", 2, 0), + ERR_VAR("END", 64, 64), +}; + +enum { + FEMERR0SR = 0, + LSMERR0SR, + TBWMERR0SR, + L2MERR0SR, + L3MERR0SR, + DISR_EL1, + ERXSTATUS_EL1, + CPUMERRSR, + L2MERRSR, + TCR_EL1, + VBAR_EL1, + L2ECTLR_EL1, + L3ECTLR +}; + +static struct err_variant_data exynos_cpu_err_table[] = { + ERR_REG(arm64_err_type_2, 0, "FEMERR0SR"), + ERR_REG(arm64_err_type_2, 0, "LSMERR0SR"), + ERR_REG(arm64_err_type_2, 0, "TBWMERR0SR"), + ERR_REG(arm64_err_type_2, 0, "L2MERR0SR"), + ERR_REG(arm64_err_type_2, 0, "L3MERR0SR"), + ERR_REG(arm64_err_type_3, 31, "DISR_EL1"), + ERR_REG(arm64_err_type_1, 30, "ERXSTATUS_EL1"), + ERR_REG(arm64_err_type_4, 31, "CPUMERRSR"), + ERR_REG(arm64_err_type_4, 31, "L2MERRSR"), + ERR_REG(arm64_err_type_TCR, 0xFF, "TCR_EL1"), + ERR_REG(arm64_err_type_VBAR, 0xFF, "VBAR_EL1"), + ERR_REG(arm64_err_type_L2ECTLR, 30, "L2ECTLR_EL1"), + ERR_REG(arm64_err_type_L3ECTLR, 30, "L3ECTLR") +}; + +void exynos_err_parse(u32 reg_idx, u64 reg, struct err_variant_data *exynos_cpu_err) +{ + u8 i = 0; + u8 fld_offset, fld_end; + u64 valid; + u32 field; + const struct err_variant *variant; + + + if (exynos_cpu_err->valid_bit == 0xFF) + goto run_valid; + + valid = reg & BIT(exynos_cpu_err->valid_bit); + if (!valid) { + pr_emerg("%s valid_bit(%d) is NOT set (0x%lx)\n", + exynos_cpu_err->reg_name, exynos_cpu_err->valid_bit, valid); + return; + } + +run_valid: + variant = exynos_cpu_err->variant; + while (true) { + fld_offset = variant[i].fld_offset; + fld_end = variant[i].fld_end; + + if (fld_end > 63) + break; + + field = (reg & GENMASK_ULL(fld_end, fld_offset)) >> fld_offset; + if (field != 0) + pr_emerg("%s (%d:%d) %s 0x%lx\n", + exynos_cpu_err->reg_name, + fld_end, fld_offset, + variant[i].fld_name, field); + i++; + }; +}; + +static void exynos_cpu_err_parse(u32 reg_idx, u64 reg) +{ + if (reg_idx >= ARRAY_SIZE(exynos_cpu_err_table)) { + pr_err("%s: there is no parse data\n", __func__); + return; + } + + exynos_err_parse(reg_idx, reg, &exynos_cpu_err_table[reg_idx]); +} + static void exynos_early_panic(void *val) { exynos_bcm_dbg_stop(PANIC_HANDLE); @@ -94,7 +283,7 @@ static void exynos_save_core(void *val) { struct pt_regs *core_reg = (struct pt_regs *)val; - asm("str x0, [%0, #0]\n\t" + asm volatile ("str x0, [%0, #0]\n\t" "mov x0, %0\n\t" "str x1, [x0, #8]\n\t" "str x2, [x0, #16]\n\t" @@ -138,7 +327,7 @@ static void exynos_save_system(void *val) (struct dbg_snapshot_mmu_reg *)val; #ifdef CONFIG_ARM64 - asm("mrs x1, SCTLR_EL1\n\t" /* SCTLR_EL1 */ + asm volatile ("mrs x1, SCTLR_EL1\n\t" /* SCTLR_EL1 */ "str x1, [%0]\n\t" "mrs x1, TTBR0_EL1\n\t" /* TTBR0_EL1 */ "str x1, [%0,#8]\n\t" @@ -169,7 +358,7 @@ static void exynos_save_system(void *val) : "%x1", "memory" /* clobbered register */ ); #else - asm("mrc p15, 0, r1, c1, c0, 0\n\t" /* SCTLR */ + asm volatile ("mrc p15, 0, r1, c1, c0, 0\n\t" /* SCTLR */ "str r1, [%0]\n\t" "mrc p15, 0, r1, c2, c0, 0\n\t" /* TTBR0 */ "str r1, [%0,#4]\n\t" @@ -208,6 +397,18 @@ static void exynos_save_system(void *val) #endif } +void exynos_dump_common_cpu_reg(void) +{ + unsigned long reg1, reg2; + + asm volatile ("mrs %0, vbar_el1\n\t" + "mrs %1, tcr_el1\n" + : "=r" (reg1), "=r" (reg2)); + + exynos_cpu_err_parse(VBAR_EL1, reg1); + exynos_cpu_err_parse(TCR_EL1, reg2); +} + static void exynos_dump_info(void *val) { /* @@ -221,53 +422,6 @@ static void exynos_dump_info(void *val) switch (read_cpuid_part_number()) { case ARM_CPU_PART_MONGOOSE: case ARM_CPU_PART_MEERKAT: - asm ("mrs %0, S3_1_c15_c2_0\n\t" - "mrs %1, S3_1_c15_c2_4\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("FEMERR0SR: %016lx, FEMERR1SR: %016lx\n", reg1, reg2); - asm ("mrs %0, S3_1_c15_c2_1\n\t" - "mrs %1, S3_1_c15_c2_5\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("LSMERR0SR: %016lx, LSMERR1SR: %016lx\n", reg1, reg2); - asm ("mrs %0, S3_1_c15_c2_2\n\t" - "mrs %1, S3_1_c15_c2_6\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("TBWMERR0SR: %016lx, TBWMERR1SR: %016lx\n", reg1, reg2); - asm ("mrs %0, S3_1_c15_c2_3\n\t" - "mrs %1, S3_1_c15_c2_7\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("L2MERR0SR: %016lx, L2MERR1SR: %016lx\n", reg1, reg2); - - /* L3 MERR */ - asm ("msr S3_1_c15_c7_1, %0\n\t" - "isb\n" - :: "r" (0)); - asm ("mrs %0, S3_1_c15_c3_0\n\t" - "mrs %1, S3_1_c15_c3_4\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("BANK0 L3MERR0SR: %016lx, L3MERR1SR: %016lx\n", reg1, reg2); - asm ("msr S3_1_c15_c7_1, %0\n\t" - "isb\n" - :: "r" (1)); - asm ("mrs %0, S3_1_c15_c3_0\n\t" - "mrs %1, S3_1_c15_c3_4\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("BANK1 L3MERR0SR: %016lx, L3MERR1SR: %016lx\n", reg1, reg2); - asm ("msr S3_1_c15_c7_1, %0\n\t" - "isb\n" - :: "r" (2)); - asm ("mrs %0, S3_1_c15_c3_0\n\t" - "mrs %1, S3_1_c15_c3_4\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("BANK2 L3MERR0SR: %016lx, L3MERR1SR: %016lx\n", reg1, reg2); - asm ("msr S3_1_c15_c7_1, %0\n\t" - "isb\n" - :: "r" (3)); - asm ("mrs %0, S3_1_c15_c3_0\n\t" - "mrs %1, S3_1_c15_c3_4\n" - : "=r" (reg1), "=r" (reg2)); - pr_emerg("BANK3 L3MERR0SR: %016lx, L3MERR1SR: %016lx\n", reg1, reg2); - break; default: break; @@ -276,38 +430,56 @@ static void exynos_dump_info(void *val) switch (read_cpuid_part_number()) { case ARM_CPU_PART_CORTEX_A57: case ARM_CPU_PART_CORTEX_A53: - asm ("mrs %0, S3_1_c15_c2_2\n\t" + asm volatile ("mrs %0, S3_1_c11_c0_3\n\t" + : "=r" (reg1)); + pr_emerg("L2ECTLR_EL1: %016lx", reg1); + exynos_cpu_err_parse(L2ECTLR_EL1, reg1); + + asm volatile ("mrs %0, S3_1_c15_c2_2\n\t" "mrs %1, S3_1_c15_c2_3\n" : "=r" (reg1), "=r" (reg2)); pr_emerg("CPUMERRSR: %016lx, L2MERRSR: %016lx\n", reg1, reg2); + exynos_cpu_err_parse(CPUMERRSR, reg1); + exynos_cpu_err_parse(L2MERRSR, reg2); break; case ARM_CPU_PART_ANANKE: + case ARM_CPU_PART_CORTEX_A73: + asm volatile ("mrs %0, S3_1_c11_c0_3\n\t" + "mrs %1, S3_1_c15_c2_3\n" + : "=r" (reg1), "=r" (reg2)); + pr_emerg("L2ECTLR_EL1: %016lx, L2MERRSR: %016lx\n", reg1, reg2); + exynos_cpu_err_parse(L2ECTLR_EL1, reg1); + exynos_cpu_err_parse(L2MERRSR, reg2); + break; case ARM_CPU_PART_CORTEX_A75: - asm ("HINT #16"); - asm ("mrs %0, S3_0_c12_c1_1\n" : "=r" (reg1)); /* read DISR_EL1 */ + asm volatile ("HINT #16"); + asm volatile ("mrs %0, S3_0_c12_c1_1\n" : "=r" (reg1)); /* read DISR_EL1 */ pr_emerg("DISR_EL1: %016lx\n", reg1); + exynos_cpu_err_parse(DISR_EL1, reg1); - asm ("msr S3_0_c5_c3_1, %0\n" + asm volatile ("msr S3_0_c5_c3_1, %0\n" "isb\n" - :: "r" (0)); /* set 1st ERRSELR_EL1 */ + :: "r" (0)); /* set CPU ERRSELR_EL1 */ - asm ("mrs %0, S3_0_c5_c4_2\n" + asm volatile ("mrs %0, S3_0_c5_c4_2\n" "mrs %1, S3_0_c5_c4_3\n" "mrs %2, S3_0_c5_c5_0\n" : "=r" (reg1), "=r" (reg2), "=r" (reg3)); - pr_emerg("1st : ERXSTATUS_EL1: %016lx, ERXADDR_EL1: %016lx, " + pr_emerg("CPU : ERXSTATUS_EL1: %016lx, ERXADDR_EL1: %016lx, " "ERXMISC0_EL1: %016lx\n", reg1, reg2, reg3); + exynos_cpu_err_parse(ERXSTATUS_EL1, reg1); - asm ("msr S3_0_c5_c3_1, %0\n" + asm volatile ("msr S3_0_c5_c3_1, %0\n" "isb\n" - :: "r" (1)); /* set 2nd ERRSELR_EL1 */ + :: "r" (1)); /* set DSU ERRSELR_EL1 */ - asm ("mrs %0, S3_0_c5_c4_2\n" + asm volatile ("mrs %0, S3_0_c5_c4_2\n" "mrs %1, S3_0_c5_c4_3\n" "mrs %2, S3_0_c5_c5_0\n" : "=r" (reg1), "=r" (reg2), "=r" (reg3)); - pr_emerg("2nd : ERXSTATUS_EL1: %016lx, ERXADDR_EL1: %016lx, " + pr_emerg("DSU : ERXSTATUS_EL1: %016lx, ERXADDR_EL1: %016lx, " "ERXMISC0_EL1: %016lx\n", reg1, reg2, reg3); + exynos_cpu_err_parse(ERXSTATUS_EL1, reg1); break; default: @@ -316,11 +488,11 @@ static void exynos_dump_info(void *val) } #else unsigned long reg0; - asm ("mrc p15, 0, %0, c0, c0, 0\n": "=r" (reg0)); + asm volatile ("mrc p15, 0, %0, c0, c0, 0\n": "=r" (reg0)); if (((reg0 >> 4) & 0xFFF) == 0xC0F) { /* Only Cortex-A15 */ unsigned long reg1, reg2, reg3; - asm ("mrrc p15, 0, %0, %1, c15\n\t" + asm volatile ("mrrc p15, 0, %0, %1, c15\n\t" "mrrc p15, 1, %2, %3, c15\n" : "=r" (reg0), "=r" (reg1), "=r" (reg2), "=r" (reg3)); diff --git a/include/linux/debug-snapshot-helper.h b/include/linux/debug-snapshot-helper.h index be7c43a418c8..136d3a369f45 100644 --- a/include/linux/debug-snapshot-helper.h +++ b/include/linux/debug-snapshot-helper.h @@ -87,4 +87,35 @@ struct dbg_snapshot_mmu_reg { int POTPIDR; }; #endif + + +struct err_variant { + u8 fld_end; + u8 fld_offset; + const char *fld_name; +}; + +struct err_variant_data { + const struct err_variant *variant; + u8 valid_bit; + const char *reg_name; +}; + +#define ERR_REG(variants, valid, reg) \ + { \ + .variant = variants, \ + .valid_bit = valid, \ + .reg_name = reg, \ + } + +#define ERR_VAR(name, end, offset) \ + { \ + .fld_end = end, \ + .fld_offset = offset, \ + .fld_name = name, \ + } + + #endif + +extern void exynos_err_parse(u32 reg_idx, u64 reg, struct err_variant_data *exynos_cpu_err);