EDAC/altera: Do less intrusive error injection

Improve the Arria10 and Stratix10 error injection routine
by reading the data and changing just 1 bit before writing
back out. Previous routine would overwrite the first bytes
to 0 then change 1 bit but this method is less intrusive.

Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: James Morse <james.morse@arm.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: https://lkml.kernel.org/r/1553635771-32693-1-git-send-email-thor.thayer@linux.intel.com
This commit is contained in:
Thor Thayer 2019-03-26 16:29:30 -05:00 committed by Borislav Petkov
parent fc00c6a416
commit 436b0a583a
2 changed files with 14 additions and 18 deletions

View File

@ -1762,28 +1762,24 @@ static ssize_t altr_edac_a10_device_trig2(struct file *file,
if (trig_type == ALTR_UE_TRIGGER_CHAR) { if (trig_type == ALTR_UE_TRIGGER_CHAR) {
writel(priv->ue_set_mask, set_addr); writel(priv->ue_set_mask, set_addr);
} else { } else {
/* Setup write of 0 to first 4 bytes */ /* Setup read/write of 4 bytes */
writel(0x0, drvdata->base + ECC_BLK_WDATA0_OFST);
writel(0x0, drvdata->base + ECC_BLK_WDATA1_OFST);
writel(0x0, drvdata->base + ECC_BLK_WDATA2_OFST);
writel(0x0, drvdata->base + ECC_BLK_WDATA3_OFST);
/* Setup write of 4 bytes */
writel(ECC_WORD_WRITE, drvdata->base + ECC_BLK_DBYTECTRL_OFST); writel(ECC_WORD_WRITE, drvdata->base + ECC_BLK_DBYTECTRL_OFST);
/* Setup Address to 0 */ /* Setup Address to 0 */
writel(0x0, drvdata->base + ECC_BLK_ADDRESS_OFST); writel(0, drvdata->base + ECC_BLK_ADDRESS_OFST);
/* Setup accctrl to write & data override */ /* Setup accctrl to read & ecc & data override */
writel(ECC_WRITE_DOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST); writel(ECC_READ_EDOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST);
/* Kick it. */
writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST);
/* Setup accctrl to read & ecc override */
writel(ECC_READ_EOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST);
/* Kick it. */ /* Kick it. */
writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST); writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST);
/* Setup write for single bit change */ /* Setup write for single bit change */
writel(0x1, drvdata->base + ECC_BLK_WDATA0_OFST); writel(readl(drvdata->base + ECC_BLK_RDATA0_OFST) ^ 0x1,
writel(0x0, drvdata->base + ECC_BLK_WDATA1_OFST); drvdata->base + ECC_BLK_WDATA0_OFST);
writel(0x0, drvdata->base + ECC_BLK_WDATA2_OFST); writel(readl(drvdata->base + ECC_BLK_RDATA1_OFST),
writel(0x0, drvdata->base + ECC_BLK_WDATA3_OFST); drvdata->base + ECC_BLK_WDATA1_OFST);
writel(readl(drvdata->base + ECC_BLK_RDATA2_OFST),
drvdata->base + ECC_BLK_WDATA2_OFST);
writel(readl(drvdata->base + ECC_BLK_RDATA3_OFST),
drvdata->base + ECC_BLK_WDATA3_OFST);
/* Copy Read ECC to Write ECC */ /* Copy Read ECC to Write ECC */
writel(readl(drvdata->base + ECC_BLK_RECC0_OFST), writel(readl(drvdata->base + ECC_BLK_RECC0_OFST),
drvdata->base + ECC_BLK_WECC0_OFST); drvdata->base + ECC_BLK_WECC0_OFST);

View File

@ -321,7 +321,7 @@ struct altr_sdram_mc_data {
#define ECC_BLK_STARTACC_OFST 0x7C #define ECC_BLK_STARTACC_OFST 0x7C
#define ECC_XACT_KICK 0x10000 #define ECC_XACT_KICK 0x10000
#define ECC_WORD_WRITE 0xF #define ECC_WORD_WRITE 0xFF
#define ECC_WRITE_DOVR 0x101 #define ECC_WRITE_DOVR 0x101
#define ECC_WRITE_EDOVR 0x103 #define ECC_WRITE_EDOVR 0x103
#define ECC_READ_EOVR 0x2 #define ECC_READ_EOVR 0x2