aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/amd64_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/amd64_edac.c')
-rw-r--r--drivers/edac/amd64_edac.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 0969a404f84f..533f5ff2ec33 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1645,10 +1645,11 @@ static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
1645} 1645}
1646 1646
1647/* 1647/*
1648 * This the F10h reference code from AMD to map a @sys_addr to NodeID, 1648 * For reference see "2.8.5 Routing DRAM Requests" in F10 BKDG. This code maps
1649 * CSROW, Channel. 1649 * a @sys_addr to NodeID, DCT (channel) and chip select (CSROW).
1650 * 1650 *
1651 * The @sys_addr is usually an error address received from the hardware. 1651 * The @sys_addr is usually an error address received from the hardware
1652 * (MCX_ADDR).
1652 */ 1653 */
1653static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci, 1654static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1654 struct err_regs *info, 1655 struct err_regs *info,
@@ -1661,39 +1662,34 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1661 1662
1662 csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan); 1663 csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan);
1663 1664
1664 if (csrow >= 0) { 1665 if (csrow < 0) {
1665 error_address_to_page_and_offset(sys_addr, &page, &offset); 1666 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
1667 return;
1668 }
1669
1670 error_address_to_page_and_offset(sys_addr, &page, &offset);
1666 1671
1667 syndrome = HIGH_SYNDROME(info->nbsl) << 8; 1672 syndrome = HIGH_SYNDROME(info->nbsl) << 8;
1668 syndrome |= LOW_SYNDROME(info->nbsh); 1673 syndrome |= LOW_SYNDROME(info->nbsh);
1674
1675 /*
1676 * We need the syndromes for channel detection only when we're
1677 * ganged. Otherwise @chan should already contain the channel at
1678 * this point.
1679 */
1680 if (dct_ganging_enabled(pvt) && pvt->nbcfg & K8_NBCFG_CHIPKILL)
1681 chan = get_channel_from_ecc_syndrome(mci, syndrome);
1669 1682
1683 if (chan >= 0)
1684 edac_mc_handle_ce(mci, page, offset, syndrome, csrow, chan,
1685 EDAC_MOD_STR);
1686 else
1670 /* 1687 /*
1671 * Is CHIPKILL on? If so, then we can attempt to use the 1688 * Channel unknown, report all channels on this CSROW as failed.
1672 * syndrome to isolate which channel the error was on.
1673 */ 1689 */
1674 if (pvt->nbcfg & K8_NBCFG_CHIPKILL) 1690 for (chan = 0; chan < mci->csrows[csrow].nr_channels; chan++)
1675 chan = get_channel_from_ecc_syndrome(mci, syndrome);
1676
1677 if (chan >= 0) {
1678 edac_mc_handle_ce(mci, page, offset, syndrome, 1691 edac_mc_handle_ce(mci, page, offset, syndrome,
1679 csrow, chan, EDAC_MOD_STR); 1692 csrow, chan, EDAC_MOD_STR);
1680 } else {
1681 /*
1682 * Channel unknown, report all channels on this
1683 * CSROW as failed.
1684 */
1685 for (chan = 0; chan < mci->csrows[csrow].nr_channels;
1686 chan++) {
1687 edac_mc_handle_ce(mci, page, offset,
1688 syndrome,
1689 csrow, chan,
1690 EDAC_MOD_STR);
1691 }
1692 }
1693
1694 } else {
1695 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
1696 }
1697} 1693}
1698 1694
1699/* 1695/*