aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2010-03-09 06:46:00 -0500
committerBorislav Petkov <borislav.petkov@amd.com>2010-08-03 10:13:31 -0400
commitad6a32e96939a0eb0eb382e7d78dbf33457aed1a (patch)
tree62824540584ff79cde370edc3730d2b592a5a0d9 /drivers/edac
parent9fe6206f400646a2322096b56c59891d530e8d51 (diff)
amd64_edac: Sanitize syndrome extraction
Remove the two syndrome extraction macros and add a single function which does the same thing but with proper typechecking. While at it, make sure to cache ECC syndrome size and dump it in debug output. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/amd64_edac.c83
-rw-r--r--drivers/edac/amd64_edac.h5
2 files changed, 55 insertions, 33 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index ac9f7985096d..e8d84f89dbcf 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -796,6 +796,11 @@ static int sys_addr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr)
796 796
797static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16); 797static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
798 798
799static u16 extract_syndrome(struct err_regs *err)
800{
801 return ((err->nbsh >> 15) & 0xff) | ((err->nbsl >> 16) & 0xff00);
802}
803
799static void amd64_cpu_display_info(struct amd64_pvt *pvt) 804static void amd64_cpu_display_info(struct amd64_pvt *pvt)
800{ 805{
801 if (boot_cpu_data.x86 == 0x11) 806 if (boot_cpu_data.x86 == 0x11)
@@ -888,6 +893,9 @@ static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
888 return; 893 return;
889 } 894 }
890 895
896 amd64_printk(KERN_INFO, "using %s syndromes.\n",
897 ((pvt->syn_type == 8) ? "x8" : "x4"));
898
891 /* Only if NOT ganged does dclr1 have valid info */ 899 /* Only if NOT ganged does dclr1 have valid info */
892 if (!dct_ganging_enabled(pvt)) 900 if (!dct_ganging_enabled(pvt))
893 amd64_dump_dramcfg_low(pvt->dclr1, 1); 901 amd64_dump_dramcfg_low(pvt->dclr1, 1);
@@ -1101,20 +1109,17 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1101} 1109}
1102 1110
1103static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, 1111static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1104 struct err_regs *info, 1112 struct err_regs *err_info, u64 sys_addr)
1105 u64 sys_addr)
1106{ 1113{
1107 struct mem_ctl_info *src_mci; 1114 struct mem_ctl_info *src_mci;
1108 unsigned short syndrome;
1109 int channel, csrow; 1115 int channel, csrow;
1110 u32 page, offset; 1116 u32 page, offset;
1117 u16 syndrome;
1111 1118
1112 /* Extract the syndrome parts and form a 16-bit syndrome */ 1119 syndrome = extract_syndrome(err_info);
1113 syndrome = HIGH_SYNDROME(info->nbsl) << 8;
1114 syndrome |= LOW_SYNDROME(info->nbsh);
1115 1120
1116 /* CHIPKILL enabled */ 1121 /* CHIPKILL enabled */
1117 if (info->nbcfg & K8_NBCFG_CHIPKILL) { 1122 if (err_info->nbcfg & K8_NBCFG_CHIPKILL) {
1118 channel = get_channel_from_ecc_syndrome(mci, syndrome); 1123 channel = get_channel_from_ecc_syndrome(mci, syndrome);
1119 if (channel < 0) { 1124 if (channel < 0) {
1120 /* 1125 /*
@@ -1123,8 +1128,8 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1123 * as suspect. 1128 * as suspect.
1124 */ 1129 */
1125 amd64_mc_printk(mci, KERN_WARNING, 1130 amd64_mc_printk(mci, KERN_WARNING,
1126 "unknown syndrome 0x%x - possible error " 1131 "unknown syndrome 0x%04x - possible "
1127 "reporting race\n", syndrome); 1132 "error reporting race\n", syndrome);
1128 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR); 1133 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
1129 return; 1134 return;
1130 } 1135 }
@@ -1654,13 +1659,13 @@ static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
1654 * (MCX_ADDR). 1659 * (MCX_ADDR).
1655 */ 1660 */
1656static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci, 1661static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1657 struct err_regs *info, 1662 struct err_regs *err_info,
1658 u64 sys_addr) 1663 u64 sys_addr)
1659{ 1664{
1660 struct amd64_pvt *pvt = mci->pvt_info; 1665 struct amd64_pvt *pvt = mci->pvt_info;
1661 u32 page, offset; 1666 u32 page, offset;
1662 unsigned short syndrome;
1663 int nid, csrow, chan = 0; 1667 int nid, csrow, chan = 0;
1668 u16 syndrome;
1664 1669
1665 csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan); 1670 csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan);
1666 1671
@@ -1671,8 +1676,7 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1671 1676
1672 error_address_to_page_and_offset(sys_addr, &page, &offset); 1677 error_address_to_page_and_offset(sys_addr, &page, &offset);
1673 1678
1674 syndrome = HIGH_SYNDROME(info->nbsl) << 8; 1679 syndrome = extract_syndrome(err_info);
1675 syndrome |= LOW_SYNDROME(info->nbsh);
1676 1680
1677 /* 1681 /*
1678 * We need the syndromes for channel detection only when we're 1682 * We need the syndromes for channel detection only when we're
@@ -1878,7 +1882,7 @@ static u16 x8_vectors[] = {
1878}; 1882};
1879 1883
1880static int decode_syndrome(u16 syndrome, u16 *vectors, int num_vecs, 1884static int decode_syndrome(u16 syndrome, u16 *vectors, int num_vecs,
1881 int v_dim) 1885 int v_dim)
1882{ 1886{
1883 unsigned int i, err_sym; 1887 unsigned int i, err_sym;
1884 1888
@@ -1955,23 +1959,23 @@ static int map_err_sym_to_channel(int err_sym, int sym_size)
1955static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome) 1959static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
1956{ 1960{
1957 struct amd64_pvt *pvt = mci->pvt_info; 1961 struct amd64_pvt *pvt = mci->pvt_info;
1958 u32 value = 0; 1962 int err_sym = -1;
1959 int err_sym = 0; 1963
1960 1964 if (pvt->syn_type == 8)
1961 if (boot_cpu_data.x86 == 0x10) { 1965 err_sym = decode_syndrome(syndrome, x8_vectors,
1962 1966 ARRAY_SIZE(x8_vectors),
1963 amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value); 1967 pvt->syn_type);
1964 1968 else if (pvt->syn_type == 4)
1965 /* F3x180[EccSymbolSize]=1 => x8 symbols */ 1969 err_sym = decode_syndrome(syndrome, x4_vectors,
1966 if (boot_cpu_data.x86_model > 7 && 1970 ARRAY_SIZE(x4_vectors),
1967 value & BIT(25)) { 1971 pvt->syn_type);
1968 err_sym = decode_syndrome(syndrome, x8_vectors, 1972 else {
1969 ARRAY_SIZE(x8_vectors), 8); 1973 amd64_printk(KERN_WARNING, "%s: Illegal syndrome type: %u\n",
1970 return map_err_sym_to_channel(err_sym, 8); 1974 __func__, pvt->syn_type);
1971 } 1975 return err_sym;
1972 } 1976 }
1973 err_sym = decode_syndrome(syndrome, x4_vectors, ARRAY_SIZE(x4_vectors), 4); 1977
1974 return map_err_sym_to_channel(err_sym, 4); 1978 return map_err_sym_to_channel(err_sym, pvt->syn_type);
1975} 1979}
1976 1980
1977/* 1981/*
@@ -2284,6 +2288,7 @@ static void amd64_free_mc_sibling_devices(struct amd64_pvt *pvt)
2284static void amd64_read_mc_registers(struct amd64_pvt *pvt) 2288static void amd64_read_mc_registers(struct amd64_pvt *pvt)
2285{ 2289{
2286 u64 msr_val; 2290 u64 msr_val;
2291 u32 tmp;
2287 int dram; 2292 int dram;
2288 2293
2289 /* 2294 /*
@@ -2349,10 +2354,22 @@ static void amd64_read_mc_registers(struct amd64_pvt *pvt)
2349 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0); 2354 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
2350 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0); 2355 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
2351 2356
2352 if (!dct_ganging_enabled(pvt) && boot_cpu_data.x86 >= 0x10) { 2357 if (boot_cpu_data.x86 >= 0x10) {
2353 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1); 2358 if (!dct_ganging_enabled(pvt)) {
2354 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1); 2359 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
2360 amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1);
2361 }
2362 amd64_read_pci_cfg(pvt->misc_f3_ctl, EXT_NB_MCA_CFG, &tmp);
2355 } 2363 }
2364
2365 if (boot_cpu_data.x86 == 0x10 &&
2366 boot_cpu_data.x86_model > 7 &&
2367 /* F3x180[EccSymbolSize]=1 => x8 symbols */
2368 tmp & BIT(25))
2369 pvt->syn_type = 8;
2370 else
2371 pvt->syn_type = 4;
2372
2356 amd64_dump_misc_regs(pvt); 2373 amd64_dump_misc_regs(pvt);
2357} 2374}
2358 2375
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 0d4bf5638243..707745b36733 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -382,6 +382,8 @@ enum {
382#define K8_NBCAP_SECDED BIT(3) 382#define K8_NBCAP_SECDED BIT(3)
383#define K8_NBCAP_DCT_DUAL BIT(0) 383#define K8_NBCAP_DCT_DUAL BIT(0)
384 384
385#define EXT_NB_MCA_CFG 0x180
386
385/* MSRs */ 387/* MSRs */
386#define K8_MSR_MCGCTL_NBE BIT(4) 388#define K8_MSR_MCGCTL_NBE BIT(4)
387 389
@@ -471,6 +473,9 @@ struct amd64_pvt {
471 u32 dram_ctl_select_high; /* DRAM Controller Select High Reg */ 473 u32 dram_ctl_select_high; /* DRAM Controller Select High Reg */
472 u32 online_spare; /* On-Line spare Reg */ 474 u32 online_spare; /* On-Line spare Reg */
473 475
476 /* x4 or x8 syndromes in use */
477 u8 syn_type;
478
474 /* temp storage for when input is received from sysfs */ 479 /* temp storage for when input is received from sysfs */
475 struct err_regs ctl_error_info; 480 struct err_regs ctl_error_info;
476 481