aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-22 20:45:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:44:54 -0400
commit276b824c3095b09e8cb76f5709f56e9c6818ae85 (patch)
tree8902c16854157bcecbcfc230e1d21ee935697d98 /drivers/edac
parent17cb7b0cf78c14913c5410eff2ce03e1d9c8d958 (diff)
i7core_edac: some fixes at error injection code
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7core_edac.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 86af14840b88..72859e87aeb2 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -32,9 +32,6 @@
32 32
33#include "edac_core.h" 33#include "edac_core.h"
34 34
35/* To use the new pci_[read/write]_config_qword instead of two dword */
36#define USE_QWORD 0
37
38/* 35/*
39 * Alter this version for the module when modifications are made 36 * Alter this version for the module when modifications are made
40 */ 37 */
@@ -473,7 +470,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket)
473 "x%x x 0x%x\n", 470 "x%x x 0x%x\n",
474 numdimms(pvt->info.max_dod), 471 numdimms(pvt->info.max_dod),
475 numrank(pvt->info.max_dod >> 2), 472 numrank(pvt->info.max_dod >> 2),
476 numbank(pvt->info.max_dod >> 4)); 473 numbank(pvt->info.max_dod >> 4),
477 numrow(pvt->info.max_dod >> 6), 474 numrow(pvt->info.max_dod >> 6),
478 numcol(pvt->info.max_dod >> 9)); 475 numcol(pvt->info.max_dod >> 9));
479 476
@@ -646,7 +643,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci,
646 int rc; 643 int rc;
647 644
648 rc = strict_strtoul(data, 10, &value); 645 rc = strict_strtoul(data, 10, &value);
649 if ((rc < 0) || (value > pvt->sockets)) 646 if ((rc < 0) || (value >= pvt->sockets))
650 return 0; 647 return 0;
651 648
652 pvt->inject.section = (u32) value; 649 pvt->inject.section = (u32) value;
@@ -803,7 +800,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
803 else 800 else
804 return cmd - data; 801 return cmd - data;
805 } else if (!strcasecmp(cmd, "dimm")) { 802 } else if (!strcasecmp(cmd, "dimm")) {
806 if (value < 4) 803 if (value < 3)
807 pvt->inject.dimm = value; 804 pvt->inject.dimm = value;
808 else 805 else
809 return cmd - data; 806 return cmd - data;
@@ -813,7 +810,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
813 else 810 else
814 return cmd - data; 811 return cmd - data;
815 } else if (!strcasecmp(cmd, "bank")) { 812 } else if (!strcasecmp(cmd, "bank")) {
816 if (value < 4) 813 if (value < 32)
817 pvt->inject.bank = value; 814 pvt->inject.bank = value;
818 else 815 else
819 return cmd - data; 816 return cmd - data;
@@ -870,6 +867,28 @@ static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
870 channel, dimm, bank, rank, page, col); 867 channel, dimm, bank, rank, page, col);
871} 868}
872 869
870static int write_and_test(struct pci_dev *dev, int where, u32 val)
871{
872 u32 read;
873 int count;
874
875 for (count = 0; count < 10; count++) {
876 if (count)
877 msleep (100);
878 pci_write_config_dword(dev, where, val);
879 pci_read_config_dword(dev, where, &read);
880
881 if (read == val)
882 return 0;
883 }
884
885 debugf0("Error Injection Register 0x%02x: Tried to write 0x%08x, "
886 "but read: 0x%08x\n", where, val, read);
887
888 return -EINVAL;
889}
890
891
873/* 892/*
874 * This routine prepares the Memory Controller for error injection. 893 * This routine prepares the Memory Controller for error injection.
875 * The error will be injected when some process tries to write to the 894 * 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 else 968 else
950 mask |= (pvt->inject.col & 0x3fffL); 969 mask |= (pvt->inject.col & 0x3fffL);
951 970
952 /* Unlock writes to registers */ 971 /*
972 * bit 0: REPEAT_EN
973 * bits 1-2: MASK_HALF_CACHELINE
974 * bit 3: INJECT_ECC
975 * bit 4: INJECT_ADDR_PARITY
976 */
977
978 injectmask = (pvt->inject.type & 1) |
979 (pvt->inject.section & 0x3) << 1 |
980 (pvt->inject.type & 0x6) << (3 - 1);
981
982 /* Unlock writes to registers - this register is write only */
953 pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], 983 pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket],
954 MC_CFG_CONTROL, 0x2); 984 MC_CFG_CONTROL, 0x2);
955 msleep(100);
956 985
986#if 0
957 /* Zeroes error count registers */ 987 /* Zeroes error count registers */
958 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], 988 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
959 MC_TEST_ERR_RCV1, 0); 989 MC_TEST_ERR_RCV1, 0);
960 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], 990 pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4],
961 MC_TEST_ERR_RCV0, 0); 991 MC_TEST_ERR_RCV0, 0);
962 pvt->ce_count_available[pvt->inject.socket] = 0; 992 pvt->ce_count_available[pvt->inject.socket] = 0;
993#endif
963 994
964 995 write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
965#if USE_QWORD
966 pci_write_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
967 MC_CHANNEL_ADDR_MATCH, mask); 996 MC_CHANNEL_ADDR_MATCH, mask);
968#else 997 write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
969 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
970 MC_CHANNEL_ADDR_MATCH, mask);
971 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
972 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); 998 MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
973#endif
974 999
975#if 1 1000 write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
976#if USE_QWORD
977 u64 rdmask;
978 pci_read_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
979 MC_CHANNEL_ADDR_MATCH, &rdmask);
980 debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
981 mask, rdmask);
982#else
983 u32 rdmask1, rdmask2;
984
985 pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
986 MC_CHANNEL_ADDR_MATCH, &rdmask1);
987 pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
988 MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
989
990 debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n",
991 mask, rdmask1, rdmask2);
992#endif
993#endif
994
995 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
996 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); 1001 MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
997 1002
1003 write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
1004 MC_CHANNEL_ERROR_MASK, injectmask);
1005
998 /* 1006 /*
999 * bit 0: REPEAT_EN 1007 * This is something undocumented, based on my tests
1000 * bits 1-2: MASK_HALF_CACHELINE 1008 * Without writing 8 to this register, errors aren't injected. Not sure
1001 * bit 3: INJECT_ECC 1009 * why.
1002 * bit 4: INJECT_ADDR_PARITY
1003 */ 1010 */
1011 pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket],
1012 MC_CFG_CONTROL, 8);
1004 1013
1005 injectmask = (pvt->inject.type & 1) |
1006 (pvt->inject.section & 0x3) << 1 |
1007 (pvt->inject.type & 0x6) << (3 - 1);
1008
1009 pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0],
1010 MC_CHANNEL_ERROR_MASK, injectmask);
1011
1012#if 0
1013 /* lock writes to registers */
1014 pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0);
1015#endif
1016 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," 1014 debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
1017 " inject 0x%08x\n", 1015 " inject 0x%08x\n",
1018 mask, pvt->inject.eccmask, injectmask); 1016 mask, pvt->inject.eccmask, injectmask);