Commit 276b824c authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

i7core_edac: some fixes at error injection code

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 17cb7b0c
...@@ -32,9 +32,6 @@ ...@@ -32,9 +32,6 @@
#include "edac_core.h" #include "edac_core.h"
/* To use the new pci_[read/write]_config_qword instead of two dword */
#define USE_QWORD 0
/* /*
* Alter this version for the module when modifications are made * Alter this version for the module when modifications are made
*/ */
...@@ -473,7 +470,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) ...@@ -473,7 +470,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket)
"x%x x 0x%x\n", "x%x x 0x%x\n",
numdimms(pvt->info.max_dod), numdimms(pvt->info.max_dod),
numrank(pvt->info.max_dod >> 2), numrank(pvt->info.max_dod >> 2),
numbank(pvt->info.max_dod >> 4)); numbank(pvt->info.max_dod >> 4),
numrow(pvt->info.max_dod >> 6), numrow(pvt->info.max_dod >> 6),
numcol(pvt->info.max_dod >> 9)); numcol(pvt->info.max_dod >> 9));
...@@ -646,7 +643,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, ...@@ -646,7 +643,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci,
int rc; int rc;
rc = strict_strtoul(data, 10, &value); rc = strict_strtoul(data, 10, &value);
if ((rc < 0) || (value > pvt->sockets)) if ((rc < 0) || (value >= pvt->sockets))
return 0; return 0;
pvt->inject.section = (u32) value; pvt->inject.section = (u32) value;
...@@ -803,7 +800,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, ...@@ -803,7 +800,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
else else
return cmd - data; return cmd - data;
} else if (!strcasecmp(cmd, "dimm")) { } else if (!strcasecmp(cmd, "dimm")) {
if (value < 4) if (value < 3)
pvt->inject.dimm = value; pvt->inject.dimm = value;
else else
return cmd - data; return cmd - data;
...@@ -813,7 +810,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, ...@@ -813,7 +810,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
else else
return cmd - data; return cmd - data;
} else if (!strcasecmp(cmd, "bank")) { } else if (!strcasecmp(cmd, "bank")) {
if (value < 4) if (value < 32)
pvt->inject.bank = value; pvt->inject.bank = value;
else else
return cmd - data; return cmd - data;
...@@ -870,6 +867,28 @@ static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci, ...@@ -870,6 +867,28 @@ static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
channel, dimm, bank, rank, page, col); channel, dimm, bank, rank, page, col);
} }
static int write_and_test(struct pci_dev *dev, int where, u32 val)
{
u32 read;
int count;
for (count = 0; count < 10; count++) {
if (count)
msleep (100);
pci_write_config_dword(dev, where, val);
pci_read_config_dword(dev, where, &read);
if (read == val)
return 0;
}
debugf0("Error Injection Register 0x%02x: Tried to write 0x%08x, "
"but read: 0x%08x\n", where, val, read);
return -EINVAL;
}
/* /*
* This routine prepares the Memory Controller for error injection. * This routine prepares the Memory Controller for error injection.
* The error will be injected when some process tries to write to the * The error will be injected when some process tries to write to the
...@@ -949,70 +968,49 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, ...@@ -949,70 +968,49 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
else else
mask |= (pvt->inject.col & 0x3fffL); mask |= (pvt->inject.col & 0x3fffL);
/* Unlock writes to registers */ /*
* bit 0: REPEAT_EN
* bits 1-2: MASK_HALF_CACHELINE
* bit 3: INJECT_ECC
* bit 4: INJECT_ADDR_PARITY
*/
injectmask = (pvt->inject.type & 1) |
(pvt->inject.section & 0x3) << 1 |
(pvt->inject.type & 0x6) << (3 - 1);
/* Unlock writes to registers - this register is write only */
pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket],
MC_CFG_CONTROL, 0x2); MC_CFG_CONTROL, 0x2);
msleep(100);
#if 0
/* Zeroes error count registers */ /* Zeroes error count registers */
pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
MC_TEST_ERR_RCV1, 0); MC_TEST_ERR_RCV1, 0);
pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
MC_TEST_ERR_RCV0, 0); MC_TEST_ERR_RCV0, 0);
pvt->ce_count_available[pvt->inject.socket] = 0; pvt->ce_count_available[pvt->inject.socket] = 0;
#endif
write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
#if USE_QWORD
pci_write_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH, mask); MC_CHANNEL_ADDR_MATCH, mask);
#else write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH, mask);
pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
#endif
#if 1 write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
#if USE_QWORD
u64 rdmask;
pci_read_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH, &rdmask);
debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
mask, rdmask);
#else
u32 rdmask1, rdmask2;
pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH, &rdmask1);
pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n",
mask, rdmask1, rdmask2);
#endif
#endif
pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ERROR_MASK, injectmask);
/* /*
* bit 0: REPEAT_EN * This is something undocumented, based on my tests
* bits 1-2: MASK_HALF_CACHELINE * Without writing 8 to this register, errors aren't injected. Not sure
* bit 3: INJECT_ECC * why.
* bit 4: INJECT_ADDR_PARITY
*/ */
pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket],
MC_CFG_CONTROL, 8);
injectmask = (pvt->inject.type & 1) |
(pvt->inject.section & 0x3) << 1 |
(pvt->inject.type & 0x6) << (3 - 1);
pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
MC_CHANNEL_ERROR_MASK, injectmask);
#if 0
/* lock writes to registers */
pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0);
#endif
debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
" inject 0x%08x\n", " inject 0x%08x\n",
mask, pvt->inject.eccmask, injectmask); mask, pvt->inject.eccmask, injectmask);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment