static void octeon_lmc_edac_poll(struct mem_ctl_info *mci) { union cvmx_lmcx_mem_cfg0 cfg0; bool do_clear = false; char msg[64]; cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx)); if (cfg0.s.sec_err || cfg0.s.ded_err) { union cvmx_lmcx_fadr fadr; fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx)); snprintf(msg, sizeof(msg), "DIMM %d rank %d bank %d row %d col %d", fadr.cn30xx.fdimm, fadr.cn30xx.fbunk, fadr.cn30xx.fbank, fadr.cn30xx.frow, fadr.cn30xx.fcol); } if (cfg0.s.sec_err) { edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, msg, ""); cfg0.s.sec_err = -1; /* Done, re-arm */ do_clear = true; } if (cfg0.s.ded_err) { edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, msg, ""); cfg0.s.ded_err = -1; /* Done, re-arm */ do_clear = true; } if (do_clear) cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx), cfg0.u64); }
static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci) { struct octeon_lmc_pvt *pvt = mci->pvt_info; union cvmx_lmcx_int int_reg; bool do_clear = false; char msg[64]; if (!pvt->inject) int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx)); else { int_reg.u64 = 0; if (pvt->error_type == 1) int_reg.s.sec_err = 1; if (pvt->error_type == 2) int_reg.s.ded_err = 1; } if (int_reg.s.sec_err || int_reg.s.ded_err) { union cvmx_lmcx_fadr fadr; if (likely(!pvt->inject)) fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx)); else { fadr.cn61xx.fdimm = pvt->dimm; fadr.cn61xx.fbunk = pvt->rank; fadr.cn61xx.fbank = pvt->bank; fadr.cn61xx.frow = pvt->row; fadr.cn61xx.fcol = pvt->col; } snprintf(msg, sizeof(msg), "DIMM %d rank %d bank %d row %d col %d", fadr.cn61xx.fdimm, fadr.cn61xx.fbunk, fadr.cn61xx.fbank, fadr.cn61xx.frow, fadr.cn61xx.fcol); } if (int_reg.s.sec_err) { edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, msg, ""); int_reg.s.sec_err = -1; /* Done, re-arm */ do_clear = true; } if (int_reg.s.ded_err) { edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, msg, ""); int_reg.s.ded_err = -1; /* Done, re-arm */ do_clear = true; } if (do_clear) { if (likely(!pvt->inject)) cvmx_write_csr(CVMX_LMCX_INT(mci->mc_idx), int_reg.u64); else pvt->inject = 0; } }
static ssize_t edac_fake_inject_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) { struct device *dev = file->private_data; struct mem_ctl_info *mci = to_mci(dev); static enum hw_event_mc_err_type type; u16 errcount = mci->fake_inject_count; if (!errcount) errcount = 1; type = mci->fake_inject_ue ? HW_EVENT_ERR_UNCORRECTED : HW_EVENT_ERR_CORRECTED; printk(KERN_DEBUG "Generating %d %s fake error%s to %d.%d.%d to test core handling. NOTE: this won't test the driver-specific decoding logic.\n", errcount, (type == HW_EVENT_ERR_UNCORRECTED) ? "UE" : "CE", errcount > 1 ? "s" : "", mci->fake_inject_layer[0], mci->fake_inject_layer[1], mci->fake_inject_layer[2] ); edac_mc_handle_error(type, mci, errcount, 0, 0, 0, mci->fake_inject_layer[0], mci->fake_inject_layer[1], mci->fake_inject_layer[2], "FAKE ERROR", "for EDAC testing only"); return count; }
static void i5100_handle_ue(struct mem_ctl_info *mci, int chan, unsigned bank, unsigned rank, unsigned long syndrome, unsigned cas, unsigned ras, const char *msg) { char detail[80]; /* Form out message */ snprintf(detail, sizeof(detail), "bank %u, cas %u, ras %u\n", bank, cas, ras); edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, syndrome, chan, rank, -1, msg, detail); }
static void tile_edac_check(struct mem_ctl_info *mci) { struct tile_edac_priv *priv = mci->pvt_info; struct mshim_mem_error mem_error; if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_error, sizeof(struct mshim_mem_error), MSHIM_MEM_ERROR_OFF) != sizeof(struct mshim_mem_error)) { pr_err(DRV_NAME ": MSHIM_MEM_ERROR_OFF pread failure.\n"); return; } /* Check if the current error count is different from the saved one. */ if (mem_error.sbe_count != priv->ce_count) { dev_dbg(mci->pdev, "ECC CE err on node %d\n", priv->node); priv->ce_count = mem_error.sbe_count; edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0, 0, 0, -1, mci->ctl_name, ""); } }