static void xgene_edac_pmd_l1_check()

in xgene_edac.c [519:657]


static void xgene_edac_pmd_l1_check(struct edac_device_ctl_info *edac_dev,
				    int cpu_idx)
{
	struct xgene_edac_pmd_ctx *ctx = edac_dev->pvt_info;
	void __iomem *pg_f;
	u32 val;

	pg_f = ctx->pmd_csr + cpu_idx * CPU_CSR_STRIDE + CPU_MEMERR_CPU_PAGE;

	val = readl(pg_f + MEMERR_CPU_ICFESR_PAGE_OFFSET);
	if (!val)
		goto chk_lsu;
	dev_err(edac_dev->dev,
		"CPU%d L1 memory error ICF 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
		MEMERR_CPU_ICFESR_ERRWAY_RD(val),
		MEMERR_CPU_ICFESR_ERRINDEX_RD(val),
		MEMERR_CPU_ICFESR_ERRINFO_RD(val));
	if (val & MEMERR_CPU_ICFESR_CERR_MASK)
		dev_err(edac_dev->dev, "One or more correctable error\n");
	if (val & MEMERR_CPU_ICFESR_MULTCERR_MASK)
		dev_err(edac_dev->dev, "Multiple correctable error\n");
	switch (MEMERR_CPU_ICFESR_ERRTYPE_RD(val)) {
	case 1:
		dev_err(edac_dev->dev, "L1 TLB multiple hit\n");
		break;
	case 2:
		dev_err(edac_dev->dev, "Way select multiple hit\n");
		break;
	case 3:
		dev_err(edac_dev->dev, "Physical tag parity error\n");
		break;
	case 4:
	case 5:
		dev_err(edac_dev->dev, "L1 data parity error\n");
		break;
	case 6:
		dev_err(edac_dev->dev, "L1 pre-decode parity error\n");
		break;
	}

	/* Clear any HW errors */
	writel(val, pg_f + MEMERR_CPU_ICFESR_PAGE_OFFSET);

	if (val & (MEMERR_CPU_ICFESR_CERR_MASK |
		   MEMERR_CPU_ICFESR_MULTCERR_MASK))
		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);

chk_lsu:
	val = readl(pg_f + MEMERR_CPU_LSUESR_PAGE_OFFSET);
	if (!val)
		goto chk_mmu;
	dev_err(edac_dev->dev,
		"CPU%d memory error LSU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
		MEMERR_CPU_LSUESR_ERRWAY_RD(val),
		MEMERR_CPU_LSUESR_ERRINDEX_RD(val),
		MEMERR_CPU_LSUESR_ERRINFO_RD(val));
	if (val & MEMERR_CPU_LSUESR_CERR_MASK)
		dev_err(edac_dev->dev, "One or more correctable error\n");
	if (val & MEMERR_CPU_LSUESR_MULTCERR_MASK)
		dev_err(edac_dev->dev, "Multiple correctable error\n");
	switch (MEMERR_CPU_LSUESR_ERRTYPE_RD(val)) {
	case 0:
		dev_err(edac_dev->dev, "Load tag error\n");
		break;
	case 1:
		dev_err(edac_dev->dev, "Load data error\n");
		break;
	case 2:
		dev_err(edac_dev->dev, "WSL multihit error\n");
		break;
	case 3:
		dev_err(edac_dev->dev, "Store tag error\n");
		break;
	case 4:
		dev_err(edac_dev->dev,
			"DTB multihit from load pipeline error\n");
		break;
	case 5:
		dev_err(edac_dev->dev,
			"DTB multihit from store pipeline error\n");
		break;
	}

	/* Clear any HW errors */
	writel(val, pg_f + MEMERR_CPU_LSUESR_PAGE_OFFSET);

	if (val & (MEMERR_CPU_LSUESR_CERR_MASK |
		   MEMERR_CPU_LSUESR_MULTCERR_MASK))
		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);

chk_mmu:
	val = readl(pg_f + MEMERR_CPU_MMUESR_PAGE_OFFSET);
	if (!val)
		return;
	dev_err(edac_dev->dev,
		"CPU%d memory error MMU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X %s\n",
		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
		MEMERR_CPU_MMUESR_ERRWAY_RD(val),
		MEMERR_CPU_MMUESR_ERRINDEX_RD(val),
		MEMERR_CPU_MMUESR_ERRINFO_RD(val),
		val & MEMERR_CPU_MMUESR_ERRREQSTR_LSU_MASK ? "LSU" : "ICF");
	if (val & MEMERR_CPU_MMUESR_CERR_MASK)
		dev_err(edac_dev->dev, "One or more correctable error\n");
	if (val & MEMERR_CPU_MMUESR_MULTCERR_MASK)
		dev_err(edac_dev->dev, "Multiple correctable error\n");
	switch (MEMERR_CPU_MMUESR_ERRTYPE_RD(val)) {
	case 0:
		dev_err(edac_dev->dev, "Stage 1 UTB hit error\n");
		break;
	case 1:
		dev_err(edac_dev->dev, "Stage 1 UTB miss error\n");
		break;
	case 2:
		dev_err(edac_dev->dev, "Stage 1 UTB allocate error\n");
		break;
	case 3:
		dev_err(edac_dev->dev, "TMO operation single bank error\n");
		break;
	case 4:
		dev_err(edac_dev->dev, "Stage 2 UTB error\n");
		break;
	case 5:
		dev_err(edac_dev->dev, "Stage 2 UTB miss error\n");
		break;
	case 6:
		dev_err(edac_dev->dev, "Stage 2 UTB allocate error\n");
		break;
	case 7:
		dev_err(edac_dev->dev, "TMO operation multiple bank error\n");
		break;
	}

	/* Clear any HW errors */
	writel(val, pg_f + MEMERR_CPU_MMUESR_PAGE_OFFSET);

	edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
}