Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: traps: Ensure L1 & L2 ECC checking match for CM3 systems

On systems with CM3, we must ensure that the L1 & L2 ECC enables are set
to the same value. This is presumed by the hardware & cache corruption
can occur when it is not the case. Support enabling & disabling the L2
ECC checking on CM3 systems where this is controlled via a GCR, and
ensure that it matches the state of L1 ECC checking. Remove I6400 from
the switch statement it will no longer hit, and which was incorrect
since the L2 ECC enable bit isn't in the CP0 ErrCtl register.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14413/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Paul Burton and committed by
Ralf Baechle
35e6de38 d65e5677

+67 -3
+7
arch/mips/include/asm/mips-cm.h
··· 187 187 BUILD_CM_RW(base, MIPS_CM_GCB_OFS + 0x08) 188 188 BUILD_CM_RW(access, MIPS_CM_GCB_OFS + 0x20) 189 189 BUILD_CM_R_(rev, MIPS_CM_GCB_OFS + 0x30) 190 + BUILD_CM_RW(err_control, MIPS_CM_GCB_OFS + 0x38) 190 191 BUILD_CM_RW(error_mask, MIPS_CM_GCB_OFS + 0x40) 191 192 BUILD_CM_RW(error_cause, MIPS_CM_GCB_OFS + 0x48) 192 193 BUILD_CM_RW(error_addr, MIPS_CM_GCB_OFS + 0x50) ··· 266 265 #define CM_REV_CM2 CM_ENCODE_REV(6, 0) 267 266 #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) 268 267 #define CM_REV_CM3 CM_ENCODE_REV(8, 0) 268 + 269 + /* GCR_ERR_CONTROL register fields */ 270 + #define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF 1 271 + #define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK (_ULCAST_(0x1) << 1) 272 + #define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF 0 273 + #define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK (_ULCAST_(0x1) << 0) 269 274 270 275 /* GCR_ERROR_CAUSE register fields */ 271 276 #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27
+60 -3
arch/mips/kernel/traps.c
··· 51 51 #include <asm/idle.h> 52 52 #include <asm/mips-cm.h> 53 53 #include <asm/mips-r2-to-r6-emul.h> 54 + #include <asm/mips-cm.h> 54 55 #include <asm/mipsregs.h> 55 56 #include <asm/mipsmtregs.h> 56 57 #include <asm/module.h> ··· 1645 1644 */ 1646 1645 static inline void parity_protection_init(void) 1647 1646 { 1647 + #define ERRCTL_PE 0x80000000 1648 + #define ERRCTL_L2P 0x00800000 1649 + 1650 + if (mips_cm_revision() >= CM_REV_CM3) { 1651 + ulong gcr_ectl, cp0_ectl; 1652 + 1653 + /* 1654 + * With CM3 systems we need to ensure that the L1 & L2 1655 + * parity enables are set to the same value, since this 1656 + * is presumed by the hardware engineers. 1657 + * 1658 + * If the user disabled either of L1 or L2 ECC checking, 1659 + * disable both. 1660 + */ 1661 + l1parity &= l2parity; 1662 + l2parity &= l1parity; 1663 + 1664 + /* Probe L1 ECC support */ 1665 + cp0_ectl = read_c0_ecc(); 1666 + write_c0_ecc(cp0_ectl | ERRCTL_PE); 1667 + back_to_back_c0_hazard(); 1668 + cp0_ectl = read_c0_ecc(); 1669 + 1670 + /* Probe L2 ECC support */ 1671 + gcr_ectl = read_gcr_err_control(); 1672 + 1673 + if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) || 1674 + !(cp0_ectl & ERRCTL_PE)) { 1675 + /* 1676 + * One of L1 or L2 ECC checking isn't supported, 1677 + * so we cannot enable either. 1678 + */ 1679 + l1parity = l2parity = 0; 1680 + } 1681 + 1682 + /* Configure L1 ECC checking */ 1683 + if (l1parity) 1684 + cp0_ectl |= ERRCTL_PE; 1685 + else 1686 + cp0_ectl &= ~ERRCTL_PE; 1687 + write_c0_ecc(cp0_ectl); 1688 + back_to_back_c0_hazard(); 1689 + WARN_ON(!!(read_c0_ecc() & ERRCTL_PE) != l1parity); 1690 + 1691 + /* Configure L2 ECC checking */ 1692 + if (l2parity) 1693 + gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1694 + else 1695 + gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1696 + write_gcr_err_control(gcr_ectl); 1697 + gcr_ectl = read_gcr_err_control(); 1698 + gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1699 + WARN_ON(!!gcr_ectl != l2parity); 1700 + 1701 + pr_info("Cache parity protection %sabled\n", 1702 + l1parity ? "en" : "dis"); 1703 + return; 1704 + } 1705 + 1648 1706 switch (current_cpu_type()) { 1649 1707 case CPU_24K: 1650 1708 case CPU_34K: ··· 1714 1654 case CPU_PROAPTIV: 1715 1655 case CPU_P5600: 1716 1656 case CPU_QEMU_GENERIC: 1717 - case CPU_I6400: 1718 1657 case CPU_P6600: 1719 1658 { 1720 - #define ERRCTL_PE 0x80000000 1721 - #define ERRCTL_L2P 0x00800000 1722 1659 unsigned long errctl; 1723 1660 unsigned int l1parity_present, l2parity_present; 1724 1661