7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER START
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * The contents of this file are subject to the terms of the
7bebe46c240b554f47faeed19186123896281967jc * Common Development and Distribution License (the "License").
7bebe46c240b554f47faeed19186123896281967jc * You may not use this file except in compliance with the License.
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7bebe46c240b554f47faeed19186123896281967jc * or http://www.opensolaris.org/os/licensing.
7bebe46c240b554f47faeed19186123896281967jc * See the License for the specific language governing permissions
7bebe46c240b554f47faeed19186123896281967jc * and limitations under the License.
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * When distributing Covered Code, include this CDDL HEADER in each
7bebe46c240b554f47faeed19186123896281967jc * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7bebe46c240b554f47faeed19186123896281967jc * If applicable, add the following below this CDDL HEADER, with the
7bebe46c240b554f47faeed19186123896281967jc * fields enclosed by brackets "[]" replaced with your own identifying
7bebe46c240b554f47faeed19186123896281967jc * information: Portions Copyright [yyyy] [name of copyright owner]
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER END
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc/*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7bebe46c240b554f47faeed19186123896281967jc * Use is subject to license terms.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * Support routines for managing per-Lxcache state.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#include <sys/types.h>
7bebe46c240b554f47faeed19186123896281967jc#include <errno.h>
7bebe46c240b554f47faeed19186123896281967jc#include <strings.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/stat.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fcntl.h>
7bebe46c240b554f47faeed19186123896281967jc#include <unistd.h>
7bebe46c240b554f47faeed19186123896281967jc#include <stropts.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fm/fmd_api.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/fm/protocol.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/fm/cpu/UltraSPARC-III.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/cpuvar.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_Lxcache.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_mem.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_cpu.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_state.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd.h>
7bebe46c240b554f47faeed19186123896281967jc#define _KERNEL
7bebe46c240b554f47faeed19186123896281967jc#include <sys/cheetahregs.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/mem_cache.h>
7bebe46c240b554f47faeed19186123896281967jc#undef _KERNEL
7bebe46c240b554f47faeed19186123896281967jc#include <sys/errclassify.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/fm/io/sun4upci.h>
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#include <fmd_adm.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fmd_adm_impl.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fmd_rpc_adm.h>
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define PN_CACHE_ERRORS (CMD_ERRCL_UCC | CMD_ERRCL_WDC | \
7bebe46c240b554f47faeed19186123896281967jc CMD_ERRCL_CPC | CMD_ERRCL_EDC | \
7bebe46c240b554f47faeed19186123896281967jc CMD_ERRCL_L3_UCC | CMD_ERRCL_L3_CPC |\
7bebe46c240b554f47faeed19186123896281967jc CMD_ERRCL_L3_WDC | CMD_ERRCL_L3_EDC)
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/* Note that these are the same for panther L2 and L3 (see prm) */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define LX_INDEX_MASK PN_L2_INDEX_MASK
7bebe46c240b554f47faeed19186123896281967jc#define LX_INDEX_SHIFT 6
7bebe46c240b554f47faeed19186123896281967jc#define PN_ECSTATE_NA 5
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_ECSTATE_INV 0
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_L3_INDEX_MASK PN_L3_TAG_RD_MASK
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic const errdata_t l3errdata =
7bebe46c240b554f47faeed19186123896281967jc { &cmd.cmd_l3data_serd, "l3cachedata", CMD_PTR_LxCACHE_CASE };
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic const errdata_t l2errdata =
7bebe46c240b554f47faeed19186123896281967jc { &cmd.cmd_l2data_serd, "l2cachedata", CMD_PTR_LxCACHE_CASE };
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* Macro for putting 64-bit onto stack as two 32-bit ints */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PRTF_64_TO_32(x) (uint32_t)((x)>>32), (uint32_t)(x)
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define LX_PA_MASK2_32BIT_CORRECT 16
7bebe46c240b554f47faeed19186123896281967jc#define LX_PA_MASK3_32BIT_CORRECT 24
7bebe46c240b554f47faeed19186123896281967jc#define LX_PA_MASK2 0x7fffff8
7bebe46c240b554f47faeed19186123896281967jc#define LX_PA_MASK3 0x7ffff8
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define MAX_RETRIES_FOR_ECC_MATCH 3
7bebe46c240b554f47faeed19186123896281967jc#define PN_TAG_ECC_MASK 0x7fc0
7bebe46c240b554f47faeed19186123896281967jc#define PN_L2_PTAG_SHIFT 19
7bebe46c240b554f47faeed19186123896281967jc#define PN_L3_PTAG_SHIFT 24
7bebe46c240b554f47faeed19186123896281967jc#define L2_PTAG_MASK 0xffffff
7bebe46c240b554f47faeed19186123896281967jc#define L3_PTAG_MASK 0xfffff
7bebe46c240b554f47faeed19186123896281967jc#define BIT_MASK 0x7f
7bebe46c240b554f47faeed19186123896281967jc#define MSB_BIT 0x8000
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define SET_MSB_BIT 0x8000
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define CLEAR_MSB_BIT 0x7fff
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_LX_TAG_ECC_START_BIT 6
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_LX_TAG_ECC_END_BIT 14
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_LX_STATE_END_BIT 2
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define PN_LX_NUM_OF_BITS_IN_ECC 9
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define LX_NWAYS 4
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcint test_mode = 0; /* should be 0 in production version. */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define FM_EREPORT_RECHECK_OF_TAGS "recheck_tags"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define RETRIES_TO_BE_DONE_WHEN_SYND_IS_ZERO 3
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianuint32_t cmd_Lxcache_recheck_tags_delay
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian [RETRIES_TO_BE_DONE_WHEN_SYND_IS_ZERO + 1] = {0, 1, 2, 4};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * e (for ecctable) maps single bit positions (0-127, or 0-0x7F) to the
7bebe46c240b554f47faeed19186123896281967jc * corresponding ECC syndromes for an error in that position.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jcint e[] = {
7bebe46c240b554f47faeed19186123896281967jc /* From Table P-4, JPS1 US-III Supplement */
7bebe46c240b554f47faeed19186123896281967jc /* 0 1 2 3 4 5 6 7 */
7bebe46c240b554f47faeed19186123896281967jc/* 00 */ 0x03B, 0x127, 0x067, 0x097, 0x10F, 0x08F, 0x04F, 0x02C,
7bebe46c240b554f47faeed19186123896281967jc/* 08 */ 0x147, 0x0C7, 0x02F, 0x01C, 0x117, 0x032, 0x08A, 0x04A,
7bebe46c240b554f47faeed19186123896281967jc/* 10 */ 0x01F, 0x086, 0x046, 0x026, 0x09B, 0x08C, 0x0C1, 0x0A1,
7bebe46c240b554f47faeed19186123896281967jc/* 18 */ 0x01A, 0x016, 0x061, 0x091, 0x052, 0x00E, 0x109, 0x029,
7bebe46c240b554f47faeed19186123896281967jc/* 20 */ 0x02A, 0x019, 0x105, 0x085, 0x045, 0x025, 0x015, 0x103,
7bebe46c240b554f47faeed19186123896281967jc/* 28 */ 0x031, 0x00D, 0x083, 0x043, 0x051, 0x089, 0x023, 0x007,
7bebe46c240b554f47faeed19186123896281967jc/* 30 */ 0x0B9, 0x049, 0x013, 0x0A7, 0x057, 0x00B, 0x07A, 0x187,
7bebe46c240b554f47faeed19186123896281967jc/* 38 */ 0x0F8, 0x11B, 0x079, 0x034, 0x178, 0x1D8, 0x05B, 0x04C,
7bebe46c240b554f47faeed19186123896281967jc/* 40 */ 0x064, 0x1B4, 0x037, 0x03D, 0x058, 0x13C, 0x1B1, 0x03E,
7bebe46c240b554f47faeed19186123896281967jc/* 48 */ 0x1C3, 0x0BC, 0x1A0, 0x1D4, 0x1CA, 0x190, 0x124, 0x13A,
7bebe46c240b554f47faeed19186123896281967jc/* 50 */ 0x1C0, 0x188, 0x122, 0x114, 0x184, 0x182, 0x160, 0x118,
7bebe46c240b554f47faeed19186123896281967jc/* 58 */ 0x181, 0x150, 0x148, 0x144, 0x142, 0x141, 0x130, 0x0A8,
7bebe46c240b554f47faeed19186123896281967jc/* 60 */ 0x128, 0x121, 0x0E0, 0x094, 0x112, 0x10C, 0x0D0, 0x0B0,
7bebe46c240b554f47faeed19186123896281967jc/* 68 */ 0x10A, 0x106, 0x062, 0x1B2, 0x0C8, 0x0C4, 0x0C2, 0x1F0,
7bebe46c240b554f47faeed19186123896281967jc/* 70 */ 0x0A4, 0x0A2, 0x098, 0x1D1, 0x070, 0x1E8, 0x1C6, 0x1C5,
7bebe46c240b554f47faeed19186123896281967jc/* 78 */ 0x068, 0x1E4, 0x1E2, 0x1E1, 0x1D2, 0x1CC, 0x1C9, 0x1B8,
7bebe46c240b554f47faeed19186123896281967jc /* Now we have the check bits */
7bebe46c240b554f47faeed19186123896281967jc /* C0 C1 C2 C3 C4 C5 C6 C7 C8 */
7bebe46c240b554f47faeed19186123896281967jc 0x001, 0x002, 0x004, 0x008, 0x010, 0x020, 0x040, 0x080, 0x100,
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define NBITS (sizeof (e)/sizeof (e[0]))
7bebe46c240b554f47faeed19186123896281967jc#define NDATABITS (128)
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * This table is used to determine which bit(s) is(are) bad when an ECC
7bebe46c240b554f47faeed19186123896281967jc * error occurs. The array is indexed by an 9-bit syndrome. The entries
7bebe46c240b554f47faeed19186123896281967jc * of this array have the following semantics:
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * 00-127 The number of the bad bit, when only one bit is bad.
7bebe46c240b554f47faeed19186123896281967jc * 128 ECC bit C0 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 129 ECC bit C1 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 130 ECC bit C2 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 131 ECC bit C3 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 132 ECC bit C4 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 133 ECC bit C5 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 134 ECC bit C6 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 135 ECC bit C7 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 136 ECC bit C8 is bad.
7bebe46c240b554f47faeed19186123896281967jc * 137-143 reserved for Mtag Data and ECC.
7bebe46c240b554f47faeed19186123896281967jc * 144(M2) Two bits are bad within a nibble.
7bebe46c240b554f47faeed19186123896281967jc * 145(M3) Three bits are bad within a nibble.
7bebe46c240b554f47faeed19186123896281967jc * 146(M3) Four bits are bad within a nibble.
7bebe46c240b554f47faeed19186123896281967jc * 147(M) Multiple bits (5 or more) are bad.
7bebe46c240b554f47faeed19186123896281967jc * 148 NO bits are bad.
7bebe46c240b554f47faeed19186123896281967jc * Based on "Cheetah Programmer's Reference Manual" rev 1.1, Tables 11-4,11-5.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define C0 128
7bebe46c240b554f47faeed19186123896281967jc#define C1 129
7bebe46c240b554f47faeed19186123896281967jc#define C2 130
7bebe46c240b554f47faeed19186123896281967jc#define C3 131
7bebe46c240b554f47faeed19186123896281967jc#define C4 132
7bebe46c240b554f47faeed19186123896281967jc#define C5 133
7bebe46c240b554f47faeed19186123896281967jc#define C6 134
7bebe46c240b554f47faeed19186123896281967jc#define C7 135
7bebe46c240b554f47faeed19186123896281967jc#define C8 136
7bebe46c240b554f47faeed19186123896281967jc#define MT0 137 /* Mtag Data bit 0 */
7bebe46c240b554f47faeed19186123896281967jc#define MT1 138
7bebe46c240b554f47faeed19186123896281967jc#define MT2 139
7bebe46c240b554f47faeed19186123896281967jc#define MTC0 140 /* Mtag Check bit 0 */
7bebe46c240b554f47faeed19186123896281967jc#define MTC1 141
7bebe46c240b554f47faeed19186123896281967jc#define MTC2 142
7bebe46c240b554f47faeed19186123896281967jc#define MTC3 143
7bebe46c240b554f47faeed19186123896281967jc#define M2 144
7bebe46c240b554f47faeed19186123896281967jc#define M3 145
7bebe46c240b554f47faeed19186123896281967jc#define M4 146
7bebe46c240b554f47faeed19186123896281967jc#define M 147
7bebe46c240b554f47faeed19186123896281967jc#define NA 148
7bebe46c240b554f47faeed19186123896281967jc#if defined(JALAPENO) || defined(SERRANO)
7bebe46c240b554f47faeed19186123896281967jc#define S003 149 /* Syndrome 0x003 => likely from CPU/EDU:ST/FRU/BP */
7bebe46c240b554f47faeed19186123896281967jc#define S003MEM 150 /* Syndrome 0x003 => likely from WDU/WBP */
7bebe46c240b554f47faeed19186123896281967jc#define SLAST S003MEM /* last special syndrome */
7bebe46c240b554f47faeed19186123896281967jc#else /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jc#define S003 149 /* Syndrome 0x003 => likely from EDU:ST */
7bebe46c240b554f47faeed19186123896281967jc#define S071 150 /* Syndrome 0x071 => likely from WDU/CPU */
7bebe46c240b554f47faeed19186123896281967jc#define S11C 151 /* Syndrome 0x11c => likely from BERR/DBERR */
7bebe46c240b554f47faeed19186123896281967jc#define SLAST S11C /* last special syndrome */
7bebe46c240b554f47faeed19186123896281967jc#endif /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jc#if defined(JALAPENO) || defined(SERRANO)
7bebe46c240b554f47faeed19186123896281967jc#define BPAR0 152 /* syndrom 152 through 167 for bus parity */
7bebe46c240b554f47faeed19186123896281967jc#define BPAR15 167
7bebe46c240b554f47faeed19186123896281967jc#endif /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic uint8_t ecc_syndrome_tab[] =
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jcNA, C0, C1, S003, C2, M2, M3, 47, C3, M2, M2, 53, M2, 41, 29, M,
7bebe46c240b554f47faeed19186123896281967jcC4, M, M, 50, M2, 38, 25, M2, M2, 33, 24, M2, 11, M, M2, 16,
7bebe46c240b554f47faeed19186123896281967jcC5, M, M, 46, M2, 37, 19, M2, M, 31, 32, M, 7, M2, M2, 10,
7bebe46c240b554f47faeed19186123896281967jcM2, 40, 13, M2, 59, M, M2, 66, M, M2, M2, 0, M2, 67, 71, M,
7bebe46c240b554f47faeed19186123896281967jcC6, M, M, 43, M, 36, 18, M, M2, 49, 15, M, 63, M2, M2, 6,
7bebe46c240b554f47faeed19186123896281967jcM2, 44, 28, M2, M, M2, M2, 52, 68, M2, M2, 62, M2, M3, M3, M4,
7bebe46c240b554f47faeed19186123896281967jcM2, 26, 106, M2, 64, M, M2, 2, 120, M, M2, M3, M, M3, M3, M4,
7bebe46c240b554f47faeed19186123896281967jc#if defined(JALAPENO) || defined(SERRANO)
7bebe46c240b554f47faeed19186123896281967jc116, M2, M2, M3, M2, M3, M, M4, M2, 58, 54, M2, M, M4, M4, M3,
7bebe46c240b554f47faeed19186123896281967jc#else /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jc116, S071, M2, M3, M2, M3, M, M4, M2, 58, 54, M2, M, M4, M4, M3,
7bebe46c240b554f47faeed19186123896281967jc#endif /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jcC7, M2, M, 42, M, 35, 17, M2, M, 45, 14, M2, 21, M2, M2, 5,
7bebe46c240b554f47faeed19186123896281967jcM, 27, M, M, 99, M, M, 3, 114, M2, M2, 20, M2, M3, M3, M,
7bebe46c240b554f47faeed19186123896281967jcM2, 23, 113, M2, 112, M2, M, 51, 95, M, M2, M3, M2, M3, M3, M2,
7bebe46c240b554f47faeed19186123896281967jc103, M, M2, M3, M2, M3, M3, M4, M2, 48, M, M, 73, M2, M, M3,
7bebe46c240b554f47faeed19186123896281967jcM2, 22, 110, M2, 109, M2, M, 9, 108, M2, M, M3, M2, M3, M3, M,
7bebe46c240b554f47faeed19186123896281967jc102, M2, M, M, M2, M3, M3, M, M2, M3, M3, M2, M, M4, M, M3,
7bebe46c240b554f47faeed19186123896281967jc98, M, M2, M3, M2, M, M3, M4, M2, M3, M3, M4, M3, M, M, M,
7bebe46c240b554f47faeed19186123896281967jcM2, M3, M3, M, M3, M, M, M, 56, M4, M, M3, M4, M, M, M,
7bebe46c240b554f47faeed19186123896281967jcC8, M, M2, 39, M, 34, 105, M2, M, 30, 104, M, 101, M, M, 4,
7bebe46c240b554f47faeed19186123896281967jc#if defined(JALAPENO) || defined(SERRANO)
7bebe46c240b554f47faeed19186123896281967jcM, M, 100, M, 83, M, M2, 12, 87, M, M, 57, M2, M, M3, M,
7bebe46c240b554f47faeed19186123896281967jc#else /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jcM, M, 100, M, 83, M, M2, 12, 87, M, M, 57, S11C, M, M3, M,
7bebe46c240b554f47faeed19186123896281967jc#endif /* JALAPENO || SERRANO */
7bebe46c240b554f47faeed19186123896281967jcM2, 97, 82, M2, 78, M2, M2, 1, 96, M, M, M, M, M, M3, M2,
7bebe46c240b554f47faeed19186123896281967jc94, M, M2, M3, M2, M, M3, M, M2, M, 79, M, 69, M, M4, M,
7bebe46c240b554f47faeed19186123896281967jcM2, 93, 92, M, 91, M, M2, 8, 90, M2, M2, M, M, M, M, M4,
7bebe46c240b554f47faeed19186123896281967jc89, M, M, M3, M2, M3, M3, M, M, M, M3, M2, M3, M2, M, M3,
7bebe46c240b554f47faeed19186123896281967jc86, M, M2, M3, M2, M, M3, M, M2, M, M3, M, M3, M, M, M3,
7bebe46c240b554f47faeed19186123896281967jcM, M, M3, M2, M3, M2, M4, M, 60, M, M2, M3, M4, M, M, M2,
7bebe46c240b554f47faeed19186123896281967jcM2, 88, 85, M2, 84, M, M2, 55, 81, M2, M2, M3, M2, M3, M3, M4,
7bebe46c240b554f47faeed19186123896281967jc77, M, M, M, M2, M3, M, M, M2, M3, M3, M4, M3, M2, M, M,
7bebe46c240b554f47faeed19186123896281967jc74, M, M2, M3, M, M, M3, M, M, M, M3, M, M3, M, M4, M3,
7bebe46c240b554f47faeed19186123896281967jcM2, 70, 107, M4, 65, M2, M2, M, 127, M, M, M, M2, M3, M3, M,
7bebe46c240b554f47faeed19186123896281967jc80, M2, M2, 72, M, 119, 118, M, M2, 126, 76, M, 125, M, M4, M3,
7bebe46c240b554f47faeed19186123896281967jcM2, 115, 124, M, 75, M, M, M3, 61, M, M4, M, M4, M, M, M,
7bebe46c240b554f47faeed19186123896281967jcM, 123, 122, M4, 121, M4, M, M3, 117, M2, M2, M3, M4, M3, M, M,
7bebe46c240b554f47faeed19186123896281967jc111, M, M, M, M4, M3, M3, M, M, M, M3, M, M3, M2, M, M
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define ESYND_TBL_SIZE (sizeof (ecc_syndrome_tab) / sizeof (uint8_t))
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianint8_t L2TAG_bit_to_way_map[128] = {
7bebe46c240b554f47faeed19186123896281967jc/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
7bebe46c240b554f47faeed19186123896281967jc/* 1 */ 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 0,
7bebe46c240b554f47faeed19186123896281967jc/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7bebe46c240b554f47faeed19186123896281967jc/* 3 */ 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 4 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 5 */-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1,
7bebe46c240b554f47faeed19186123896281967jc/* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7bebe46c240b554f47faeed19186123896281967jc/* 7 */ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 8 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1,
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcuint8_t L2TAG_bit_to_way_bit[128] = {
7bebe46c240b554f47faeed19186123896281967jc/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
7bebe46c240b554f47faeed19186123896281967jc/* 1 */ 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 19, 20, 21, 22,
7bebe46c240b554f47faeed19186123896281967jc/* 2 */23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
7bebe46c240b554f47faeed19186123896281967jc/* 3 */39, 40, 41, 42, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
7bebe46c240b554f47faeed19186123896281967jc/* 4 */31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, C0, C0, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc/* 5 */C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, 19, 20, 21, 22,
7bebe46c240b554f47faeed19186123896281967jc/* 6 */23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
7bebe46c240b554f47faeed19186123896281967jc/* 7 */39, 40, 41, 42, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
7bebe46c240b554f47faeed19186123896281967jc/* 8 */31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, C0, C0, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianint8_t L3TAG_bit_to_way_map[128] = {
7bebe46c240b554f47faeed19186123896281967jc/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
7bebe46c240b554f47faeed19186123896281967jc/* 1 */ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
7bebe46c240b554f47faeed19186123896281967jc/* 2 */ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 3 */ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -1, -1,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 4 */-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7bebe46c240b554f47faeed19186123896281967jc/* 5 */ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
7bebe46c240b554f47faeed19186123896281967jc/* 6 */ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 7 */ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, -1, -1,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* 8 */-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcuint8_t L3TAG_bit_to_way_bit[128] = {
7bebe46c240b554f47faeed19186123896281967jc/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
7bebe46c240b554f47faeed19186123896281967jc/* 1 */ 0, 0, 1, 1, 2, 2, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
7bebe46c240b554f47faeed19186123896281967jc/* 2 */29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36,
7bebe46c240b554f47faeed19186123896281967jc/* 3 */37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc/* 4 */C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc/* 5 */ 0, 0, 1, 1, 2, 2, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
7bebe46c240b554f47faeed19186123896281967jc/* 6 */29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36,
7bebe46c240b554f47faeed19186123896281967jc/* 7 */37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc/* 8 */C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0,
7bebe46c240b554f47faeed19186123896281967jc};
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcuint16_t
7bebe46c240b554f47faeed19186123896281967jccalcecc(uint64_t chi, uint64_t clo)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int i;
7bebe46c240b554f47faeed19186123896281967jc uint64_t syndrome = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < (NDATABITS/2); i++) {
7bebe46c240b554f47faeed19186123896281967jc syndrome ^= ((chi & 1) ? e[(NDATABITS/2) + i] : 0) ^
7bebe46c240b554f47faeed19186123896281967jc ((clo & 1) ? e[i] : 0);
7bebe46c240b554f47faeed19186123896281967jc chi >>= 1;
7bebe46c240b554f47faeed19186123896281967jc clo >>= 1;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (uint16_t)(syndrome);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianuint64_t
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancalcsynd(uint64_t chi, uint64_t clo, uint64_t ecc)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (calcecc(chi, clo) ^ ecc);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
7bebe46c240b554f47faeed19186123896281967jcstatic uint8_t
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniantag_bit_to_way_bit(cmd_ptrsubtype_t pstype, int16_t tag_bit)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t way_bit = C0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc way_bit = L2TAG_bit_to_way_bit[tag_bit];
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc way_bit = L3TAG_bit_to_way_bit[tag_bit];
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (way_bit);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int8_t
7bebe46c240b554f47faeed19186123896281967jcbit_to_way(cmd_ptrsubtype_t pstype, uint32_t bit)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int8_t way = -1;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc way = L2TAG_bit_to_way_map[bit & BIT_MASK];
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc way = L3TAG_bit_to_way_map[bit & BIT_MASK];
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (way);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int32_t
7bebe46c240b554f47faeed19186123896281967jcget_index(cmd_ptrsubtype_t pstype, uint64_t tag_afar)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index = -1;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index = (int32_t)((tag_afar & PN_L2_INDEX_MASK)
7bebe46c240b554f47faeed19186123896281967jc >> PN_CACHE_LINE_SHIFT);
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index = (int32_t)((tag_afar & PN_L3_TAG_RD_MASK)
7bebe46c240b554f47faeed19186123896281967jc >> PN_CACHE_LINE_SHIFT);
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (index);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianget_retired_ways(uint64_t *tag_data)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int i, retired_ways;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_ways = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (i = 0; i < PN_CACHE_NWAYS; i++) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((tag_data[i] & CH_ECSTATE_MASK) ==
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian PN_ECSTATE_NA)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_ways++;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (retired_ways);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
7bebe46c240b554f47faeed19186123896281967jcstatic cmd_evdisp_t
7bebe46c240b554f47faeed19186123896281967jcextract_data_from_ereport_payload(fmd_hdl_t *hdl, nvlist_t *nvl,
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu,
7bebe46c240b554f47faeed19186123896281967jc cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc uint64_t *afarp, uint64_t *tag_data,
7bebe46c240b554f47faeed19186123896281967jc const char *fltnm)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc ch_ec_data_t *ec_data;
7bebe46c240b554f47faeed19186123896281967jc char *payload_namep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int tag_afar_status;
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_afar;
7bebe46c240b554f47faeed19186123896281967jc int i;
7bebe46c240b554f47faeed19186123896281967jc uint_t sz;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t recheck_of_tags;
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_afar_status = cmd_afar_valid(hdl, nvl, 0, &tag_afar);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (tag_afar_status == -1) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id = %d Invalid afar status in nvlist\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc *afarp = tag_afar;
7bebe46c240b554f47faeed19186123896281967jc index = get_index(pstype, tag_afar);
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc payload_namep = FM_EREPORT_PAYLOAD_NAME_L2_DATA;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc payload_namep = FM_EREPORT_PAYLOAD_NAME_L3_DATA;
7bebe46c240b554f47faeed19186123896281967jc break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian default:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_int32(nvl, FM_EREPORT_RECHECK_OF_TAGS,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &recheck_of_tags) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian recheck_of_tags = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((recheck_of_tags) || (test_mode))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (get_tagdata(cpu, pstype, index, tag_data));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint64_array(nvl, payload_namep,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (uint64_t **)&ec_data, &sz) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d index = %d could not find %s"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " in nvlist\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index, payload_namep);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d Reading tag data through"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " mem_cache driver.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
7bebe46c240b554f47faeed19186123896281967jc return (get_tagdata(cpu, pstype, index,
7bebe46c240b554f47faeed19186123896281967jc tag_data));
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
7bebe46c240b554f47faeed19186123896281967jc tag_data[i] = ec_data[i].ec_tag;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic void
7bebe46c240b554f47faeed19186123896281967jcprint_ecc(fmd_hdl_t *hdl, cmd_cpu_t *cpu, const char *fltnm, uint64_t *tag_data)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int i;
7bebe46c240b554f47faeed19186123896281967jc uint16_t tag_ecc[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_ecc[i] =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ((tag_data[i] & PN_TAG_ECC_MASK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian >> PN_LX_TAG_ECC_START_BIT);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d ecc[0] = 0x%03x ecc[1] = 0x%03x"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " ecc[2] = 0x%03x ecc[3] = 0x%03x\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, tag_ecc[0], tag_ecc[1], tag_ecc[2],
7bebe46c240b554f47faeed19186123896281967jc tag_ecc[3]);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic int
7bebe46c240b554f47faeed19186123896281967jcmatching_ecc(uint64_t *tag_data)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int i;
7bebe46c240b554f47faeed19186123896281967jc uint16_t tag_ecc[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_ecc[i] =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ((tag_data[i] & PN_TAG_ECC_MASK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian >> PN_LX_TAG_ECC_START_BIT);
7bebe46c240b554f47faeed19186123896281967jc if (tag_ecc[i] != tag_ecc[0]) {
7bebe46c240b554f47faeed19186123896281967jc return (1);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (0);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic void
7bebe46c240b554f47faeed19186123896281967jcgen_data_for_ecc(uint64_t *tag_data, uint64_t *data_for_ecc_gen,
7bebe46c240b554f47faeed19186123896281967jc cmd_ptrsubtype_t pstype)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc uint64_t ptag[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc uint8_t state[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc int i;
7bebe46c240b554f47faeed19186123896281967jc uint16_t tag_ecc[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc uint8_t bit_position;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
7bebe46c240b554f47faeed19186123896281967jc state[i] = tag_data[i] & CH_ECSTATE_MASK;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_ecc[i] =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ((tag_data[i] & PN_TAG_ECC_MASK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian >> PN_LX_TAG_ECC_START_BIT);
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc ptag[i] = (tag_data[i] >> PN_L2_PTAG_SHIFT) &
7bebe46c240b554f47faeed19186123896281967jc L2_PTAG_MASK;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc ptag[i] = (tag_data[i] >> PN_L3_PTAG_SHIFT) &
7bebe46c240b554f47faeed19186123896281967jc L3_PTAG_MASK;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * We now assemble the 128 bit data swizzling the Physical tags
7bebe46c240b554f47faeed19186123896281967jc * and states we obtained for all the 4 ways.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] = 0; /* high order 64 bits */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] = 0; /* low order 64 bits */
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] = state[0]; /* way 0 state */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (state[1] << 3); /* way 1 state */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (state[2] << 6); /* way 2 state */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (state[3] << 9); /* way 3 state */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |= (ptag[0] << 12); /* way 0 ptag */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |= (ptag[2] << 36); /* way 2 ptag */
7bebe46c240b554f47faeed19186123896281967jc /* bits 63:60 of low order 64 bits are 0s */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * We now start with hig order 64 bits.
7bebe46c240b554f47faeed19186123896281967jc * the low 12 bits are 0s
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |= (ptag[1] << 12); /* way 1 ptag */
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |= (ptag[3] << 36); /* way 3 ptag */
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc bit_position = 0;
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Swizzle state bits for way 1 and way 3
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < 3; i++) {
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (((state[1] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (((state[3] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Swizzle physical tag bits for way 1 and way 3
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < 20; i++) {
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (((ptag[1] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[1] |=
7bebe46c240b554f47faeed19186123896281967jc (((ptag[3] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * start the high order 64 bits.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc bit_position = 0;
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Swizzle state bits for way 0 and way 2
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < 3; i++) {
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |=
7bebe46c240b554f47faeed19186123896281967jc (((state[0] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |=
7bebe46c240b554f47faeed19186123896281967jc (((state[2] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Swizzle physical tag bits for way 0 and way 2
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < 20; i++) {
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |=
7bebe46c240b554f47faeed19186123896281967jc (((ptag[0] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc data_for_ecc_gen[0] |=
7bebe46c240b554f47faeed19186123896281967jc (((ptag[2] >> i) & 1) << bit_position);
7bebe46c240b554f47faeed19186123896281967jc bit_position++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic uint16_t
7bebe46c240b554f47faeed19186123896281967jccompute_syndrome(uint64_t *tag_data, cmd_ptrsubtype_t pstype)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_synd;
7bebe46c240b554f47faeed19186123896281967jc uint64_t data_for_ecc_gen[2];
7bebe46c240b554f47faeed19186123896281967jc uint16_t tag_ecc;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc gen_data_for_ecc(tag_data, data_for_ecc_gen, pstype);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_ecc = ((tag_data[0] & PN_TAG_ECC_MASK) >> PN_LX_TAG_ECC_START_BIT);
7bebe46c240b554f47faeed19186123896281967jc tag_synd = calcsynd(data_for_ecc_gen[0], data_for_ecc_gen[1],
7bebe46c240b554f47faeed19186123896281967jc (uint64_t)tag_ecc);
7bebe46c240b554f47faeed19186123896281967jc return (tag_synd);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int16_t
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianfind_bit_stickiness(uint64_t *tag_data, int8_t way, int16_t bit)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int16_t sticky_bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian sticky_bit = bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((tag_data[way] & ((uint64_t)1 << bit)) != 0)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian sticky_bit |= MSB_BIT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (sticky_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic cmd_Lxcache_t *
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_create_and_destroy_Lxcache(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *Lxcache)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fltnm;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *new_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm = cmd_type_to_str(Lxcache->Lxcache_type);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We first create a new Lxcache and add the event ep
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that is in Lxcache to the new case we create.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we then destroy the Lxcache that has the event ep in its SERD engine.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian new_Lxcache = cmd_Lxcache_create(hdl, Lxcache->xr, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu->cpu_asru_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_type,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index, Lxcache->Lxcache_way, Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (new_Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:Failed to create a Lxcache for"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " index %d way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_way, Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (NULL);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) cmd_create_case_for_Lxcache(hdl, cpu, new_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (new_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianint
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_retire_as_reason(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *Lxcache, const char *fltnm, int32_t reason)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian boolean_t ret;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint_t certainty;
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (reason == CMD_LXSUSPECT_0_TAG) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * clear MSB bit to retire as SUSPECT_0_TAG
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to update the Lxcache asru to reflect
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the change in bit value.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_bit &= CLEAR_MSB_BIT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian errno = nvlist_add_uint16(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_asru_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian FM_FMRI_CPU_CACHE_BIT,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (errno) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: failed to update",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " CACHE_BIT in asru.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (reason == CMD_LXCONVICTED)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian certainty = HUNDRED_PERCENT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian else
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian certainty = SUSPECT_PERCENT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = cmd_Lxcache_retire(hdl, cpu, Lxcache, fltnm, certainty);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (reason == CMD_LXSUSPECT_0_TAG)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_bit |= SET_MSB_BIT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ret == B_FALSE)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_reason = reason;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Update the persistence storage of
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Lxcache.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:reason = %s flags = %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_reason_to_str(Lxcache->Lxcache_reason),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_flags_to_str(Lxcache->Lxcache_flags));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_write(hdl, Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianint
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianretire_lowest_retirable_way_as_suspect(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *anonymous_Lxcache, const char *fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * This routine is called only when handling anonymous TAG or DATA
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * errors. When we exit this routine we would have destroyed the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * anonymous_Lxcache structure that was passed to us and created
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * a new Lxcache if we were successful in determining a way to retire.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int8_t lowest_retirable_way, ways_retired;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t reason;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t type;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *new_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ways_retired = get_index_retired_ways(cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_type,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired == -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Couldn't determine how many ways have been retired at this
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * index. Destroy the anonymous_Lxcache and return failure.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Before retiring a way check if we have already
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired 3 ways for this index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * For TAG errors we will not perform this check because
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we could reretire cachlines retired for DATA errors.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The get_lowest_retirable_way() will ensure that we do
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * not end up retiring all 4 ways.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (!IS_TAG(anonymous_Lxcache->Lxcache_type)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired >= 3) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: num of ways retired for index %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " is %d will fault the CPU\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_index, ways_retired);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian type = anonymous_Lxcache->Lxcache_type;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * destroy the anonymous_Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, type, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * No ways have been retired as "SUSPECT" for this bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to retire the lowest unretired way as suspect.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id %d Checking for the lowest retirable"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way at index %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, anonymous_Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian lowest_retirable_way = cmd_Lxcache_get_lowest_retirable_way(cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_index, anonymous_Lxcache->Lxcache_type);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (lowest_retirable_way != -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id %d lowest retirable way is %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, lowest_retirable_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_way = lowest_retirable_way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian new_Lxcache = cmd_create_and_destroy_Lxcache(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((new_Lxcache == NULL) ||
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (new_Lxcache->Lxcache_case.cc_cp == NULL)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (IS_TAG(new_Lxcache->Lxcache_type))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian reason = CMD_LXSUSPECT_0_TAG;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian else
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian reason = CMD_LXSUSPECT_DATA;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_Lxcache_retire_as_reason(hdl, cpu, new_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, reason));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d we are unable to determine which"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way is faulty at cache index %d."
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " Will retire the CPU.\nRecommended-Action:"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " Service action required\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, anonymous_Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian type = anonymous_Lxcache->Lxcache_type;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * destroy the anonymous_Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, type, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianint
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianunretire_suspect_and_retire_next_retirable_way(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *suspect_Lxcache, cmd_Lxcache_t *anonymous_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int8_t retired_way, next_retirable_way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t retired_index;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t retired_type;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t reason;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *new_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * This routine is called only when handling anonymous TAG or DATA
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * errors. When we exit this routine we would have destroyed the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * anonymous_Lxcache structure that was passed to us.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d found index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " bit %d retired as %s. Will unretire this now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, suspect_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way, suspect_Lxcache->Lxcache_bit,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_reason_to_str(suspect_Lxcache->Lxcache_reason));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Save the way because we will destroy the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * suspect_Lxcache after we successfully unretire it.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_way = suspect_Lxcache->Lxcache_way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_index = suspect_Lxcache->Lxcache_index;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_type = suspect_Lxcache->Lxcache_type;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretire the retired_way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache_unretire(hdl, cpu, suspect_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian == B_TRUE) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_reason =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian CMD_LXFUNCTIONING;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " successfully unretired. Will"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " destroy this Lxcache now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, suspect_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, suspect_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * destroy the anonymous_Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the next retirable way
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian next_retirable_way = cmd_Lxcache_get_next_retirable_way(cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_type, retired_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (next_retirable_way == -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * There is no retirable way that is next to the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * one we just retired. We need to offline the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * CPU since we are unable to determine which
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * way is reporting the errors.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d we are unable to determine"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " which way is faulty at cache index %d."
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " It is likely that we have a leaky bit"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " that gets corrected.\n Will retire"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " the CPU.\nRecommended-Action: Service"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " action required\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, retired_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * destroy the anonymous_Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, retired_type, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d found way %d at index %d to"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retire as SUSPECT_0/SUSPECT_DATA\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, next_retirable_way, retired_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to create a new Lxcache struture.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The existing Lxcache is for anonymous way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_way = next_retirable_way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian new_Lxcache = cmd_create_and_destroy_Lxcache(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((new_Lxcache == NULL) ||
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (new_Lxcache->Lxcache_case.cc_cp == NULL)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (IS_TAG(new_Lxcache->Lxcache_type))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian reason = CMD_LXSUSPECT_0_TAG;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian else
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian reason = CMD_LXSUSPECT_DATA;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_Lxcache_retire_as_reason(hdl, cpu, new_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, reason));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianvoid
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianfind_and_destroy_anonymous_Lxcache(fmd_hdl_t *hdl, cmd_cpu_t *cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_ptrsubtype_t pstype, int32_t index)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *anonymous_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fltnm;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm = cmd_type_to_str(pstype);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_lookup_by_type_index_way_bit(cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian pstype, index, -1, -1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (anonymous_Lxcache != NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id = %d index = %d We are destroying the"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " anonymous Lxcache now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Free the resources allocated to handle
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * recheck_of_tags. Delete the Lxcache.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianvoid
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramaniancmd_Lxcache_anonymous_tag_error_timeout(fmd_hdl_t *hdl, id_t id)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *class;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We search thru the entire Lxcache structures to find
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * a matching id.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache = cmd_Lxcache_lookup_by_timeout_id(id);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "Could not find Lxcache for timeout_id 0x%x\n", id);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:anonymous_tag_error_timeout:index = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_type_to_str(Lxcache->Lxcache_type),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Set timeout_id to -1 to indicate that we have processed the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * timeout.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian switch (Lxcache->Lxcache_type) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_PTR_CPU_L2TAG:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian class = "ereport.cpu.ultraSPARC-IVplus.thce";
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) cmd_txce(hdl, Lxcache->Lxcache_ep,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian class, Lxcache->Lxcache_clcode);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_PTR_CPU_L3TAG:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian class = "ereport.cpu.ultraSPARC-IVplus.l3-thce";
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) cmd_l3_thce(hdl, Lxcache->Lxcache_ep,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian class, Lxcache->Lxcache_clcode);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian default:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "Unexpected pstype 0x%x found in"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " anonymous_tag_error_timeout: index = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_type,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jccmd_evdisp_t
7bebe46c240b554f47faeed19186123896281967jccmd_us4plus_tag_err(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *serdn, const char *serdt,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian const char *fltnm, cmd_errcl_t clcode)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_afar;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int8_t way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int16_t tag_bit, bit, sticky_bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *Lxcache, *suspect_Lxcache, *retired_Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *anonymous_Lxcache;
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_synd;
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_data[PN_CACHE_NWAYS];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t state;
7bebe46c240b554f47faeed19186123896281967jc int ways_retired, ret;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int retries_for_ecc_match;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t recheck_of_tags;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int way_already_retired = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * We now extract physical tags and states
7bebe46c240b554f47faeed19186123896281967jc * and also look for matching ECC on all 4 ways.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc ret = extract_data_from_ereport_payload(hdl, nvl, cpu, pstype,
7bebe46c240b554f47faeed19186123896281967jc &tag_afar, tag_data, fltnm);
7bebe46c240b554f47faeed19186123896281967jc if (ret != 0)
7bebe46c240b554f47faeed19186123896281967jc return (ret);
7bebe46c240b554f47faeed19186123896281967jc index = get_index(pstype, tag_afar);
7bebe46c240b554f47faeed19186123896281967jc retries_for_ecc_match = 0;
7bebe46c240b554f47faeed19186123896281967jc while (matching_ecc(tag_data) != 0) {
7bebe46c240b554f47faeed19186123896281967jc if (retries_for_ecc_match >= MAX_RETRIES_FOR_ECC_MATCH)
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc print_ecc(hdl, cpu, fltnm, tag_data);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id = %d index = %d ECCs don't match.\n"
7bebe46c240b554f47faeed19186123896281967jc "Reading tag info again.\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, index);
7bebe46c240b554f47faeed19186123896281967jc (void) get_tagdata(cpu, pstype, index, tag_data);
7bebe46c240b554f47faeed19186123896281967jc retries_for_ecc_match++;
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ways_retired = get_retired_ways(tag_data);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: found %d ways retired at the index %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, ways_retired, index);
7bebe46c240b554f47faeed19186123896281967jc tag_synd = compute_syndrome(tag_data, pstype);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = nvlist_lookup_int32(nvl, FM_EREPORT_RECHECK_OF_TAGS,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &recheck_of_tags);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ret != CMD_EVD_OK) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "ret value = %d for nvlist_lookup of recheck_of_tags\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian recheck_of_tags = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc if (tag_synd == 0) {
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * The bit has been corrected by writeback, we will
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * first check if we are processing the re-check of tags
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that we scheduled thru the timeout call.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * if so we will exit if we reached the max retries.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Else we start a timeout and exit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We will create a Lxcache structure for this index with way
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * as -1 and bit as -1. We will also keep a count of
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * attempts we made to check the tag data at this index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian *
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache = cmd_Lxcache_lookup_by_type_index_way_bit(cpu, pstype,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (recheck_of_tags) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We are processing the re-read of tags scheduled by
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * timeout. Exit if retry limit has been
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * reached. Else start another timeout.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * This shouldn't happen.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d failed to lookup"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " index = %d way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d index = %d syndrome"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " computed is 0 in attempt #%d.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_retry_count >=
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian RETRIES_TO_BE_DONE_WHEN_SYND_IS_ZERO) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We free only the nvl list here.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * anonymous SERD engine will be freed
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * when the Lxcache gets destroyed.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need the anonymous SERD engine still
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * because it has the event ep.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * reset or destroy of SERD engine frees the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * event ep.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_nvl != NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian nvlist_free(Lxcache->Lxcache_nvl);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_nvl = NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Max retry count reached. Giving up.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id = -1;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian goto process_after_finding_way_bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count++;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_timer_install(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void *)CMD_TIMERTYPE_ANONYMOUS_TAG_ERROR,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian NULL,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache_recheck_tags_delay[
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count] * NANOSEC));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Check if we already have a Lxcache structure
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * with anonymous way and bit created.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache = cmd_Lxcache_create(hdl, 0, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu->cpu_asru_nvl, pstype, index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Failed to create Lxcache"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " for index=%d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_timeout_id != -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We have another syndrome = 0 condition while we are
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * still in the process of retrying for the previous
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * condition.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d index = %d We have another"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " syndrome = 0 condition while we have already"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " scheduled a timeout. We will ignore this"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " event.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d index = %d syndrome computed is 0."
7bebe46c240b554f47faeed19186123896281967jc "Looks like the bit got corrected."
7bebe46c240b554f47faeed19186123896281967jc " Will check later to see if it is OK.\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, index);
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to store the following arguments passed to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * this function(tag_error_handler) so that we can
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * invoke this function from timeout routine.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian *
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * nvl, ep, clcode
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_nvl == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_dup(nvl, &Lxcache->Lxcache_nvl, 0) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Failed to duplicate nvl"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " for index=%d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_add_int32(Lxcache->Lxcache_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian FM_EREPORT_RECHECK_OF_TAGS, 1) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Failed to add"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " RECHECK_OF_TAGS in nvl for index=%d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We are called with CMP_CPU_LEVEL_CORE masked out
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * from cmd_txce(), cmd_l3_thce() routines.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to set CMD_CPU_LEVEL_CORE because we want to handle
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * both the cores on the Chip as one single cpu_id.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_clcode = (clcode | CMD_CPU_LEVEL_CORE);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_ep == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_ep = ep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we need to preserve the event ep so that it does
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * not get destroyed when we return from this call.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We do that by adding the event ep to the SERD engine.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The SERD engine we create is different from the one
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we create when we handle the actual event at label
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * process_after_finding_way_bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_serdnm =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_anonymous_serdnm_create(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu->cpu_cpuid, pstype, index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (!fmd_serd_exists(hdl, Lxcache->Lxcache_serdnm)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_serd_create(hdl, Lxcache->Lxcache_serdnm,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_prop_get_int32(hdl, serdn),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_prop_get_int64(hdl, serdt));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id %d: created a SERD engine"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) fmd_serd_record(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_serdnm,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ep);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count++;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_timeout_id =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_timer_install(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void *)CMD_TIMERTYPE_ANONYMOUS_TAG_ERROR, NULL,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (cmd_Lxcache_recheck_tags_delay[
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_retry_count] * NANOSEC));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
7bebe46c240b554f47faeed19186123896281967jc } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * tag_synd != 0
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * determine way and bit
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian tag_bit = ecc_syndrome_tab[tag_synd & 0x1ff];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d index = %d tag_bit %03d is faulty.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index, tag_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((tag_bit > C8)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "%s: cpu_id = %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " Unexpected MTAG or Multiple bit error detected\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu, pstype,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((tag_bit >= C0) && (tag_bit <= C8)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * ECC bit is corrupted.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Need to offline the CPU
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit = (tag_bit - C0) + PN_LX_TAG_ECC_START_BIT;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way = 0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d ECC bit is faulty.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit = tag_bit_to_way_bit(pstype, tag_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way = bit_to_way(pstype, tag_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (way < 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id = %d %d bit indicted is a"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " meta bit !!\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian pstype,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } /* end of tag_synd != 0 */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianprocess_after_finding_way_bit:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((Lxcache = cmd_Lxcache_lookup_by_type_index_way_bit(cpu, pstype,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index, way,
7bebe46c240b554f47faeed19186123896281967jc bit)) != NULL &&
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_case.cc_cp != NULL &&
7bebe46c240b554f47faeed19186123896281967jc fmd_case_solved(hdl, Lxcache->Lxcache_case.cc_cp)) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu %d: the case for %s is already solved.\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, Lxcache->Lxcache_bufname);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu, pstype, index);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_REDUND);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (Lxcache == NULL)
7bebe46c240b554f47faeed19186123896281967jc Lxcache = cmd_Lxcache_create(hdl, 0, cpu, cpu->cpu_asru_nvl,
7bebe46c240b554f47faeed19186123896281967jc pstype, index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu %d: Failed to create Lxcache for index %d",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way %d bit %d\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, index, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu, pstype, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_create_case_for_Lxcache(hdl, cpu, Lxcache) == B_FALSE) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu, pstype, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc if (Lxcache->Lxcache_case.cc_serdnm == NULL) {
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_case.cc_serdnm = cmd_Lxcache_serdnm_create(hdl,
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, pstype, index,
7bebe46c240b554f47faeed19186123896281967jc way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (!fmd_serd_exists(hdl, Lxcache->Lxcache_case.cc_serdnm)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_serd_create(hdl, Lxcache->Lxcache_case.cc_serdnm,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_prop_get_int32(hdl, serdn),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_prop_get_int64(hdl, serdt));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id %d: created a SERD engine %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: Checking if the SERD engine %s has fired.\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, Lxcache->Lxcache_case.cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) fmd_serd_record(hdl, Lxcache->Lxcache_case.cc_serdnm, ep);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (way >= 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Now that we have recorded the event ep we can do the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * necessary cleanup of resources allocated for recheck of tags.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian find_and_destroy_anonymous_Lxcache(hdl, cpu, pstype, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (fmd_serd_fired(hdl, Lxcache->Lxcache_case.cc_serdnm) ==
7bebe46c240b554f47faeed19186123896281967jc FMD_B_FALSE)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "\n%s: cpu_id = %d creating fault %s\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, Lxcache->Lxcache_case.cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc fmd_case_add_serd(hdl, Lxcache->Lxcache_case.cc_cp,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_case.cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc fmd_serd_reset(hdl, Lxcache->Lxcache_case.cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (way == -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The assignment below is to make the code easier to maintain.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to destroy the anonymous_Lxcache after we have
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * identifed a way to retire. If we cannot detrmine a way to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire we will destrory the anonymous_Lxcache and fault the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * cpu.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache = Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Anonymous TAG way retirement.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if a way at this index has already been retired as
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * "suspect-1", unretire that way, and retire the next
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretired way as "suspect-0", using a pattern of all zeros
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * for the PA bits.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if a way at this index has already been retired as
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * "suspect-0", re-retire that way as "suspect-1", using a
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * pattern of all ones for the PA bits.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if no ways have been retired as "suspect" for this index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the lowest unretired way as "suspect-0" for this
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * bit, using a pattern of all zeros for the PA bits.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if there is no next retirable way, fault the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache = cmd_Lxcache_lookup_by_type_index_bit_reason(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, pstype, index, bit, CMD_LXSUSPECT_1_TAG);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_ep = ep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = unretire_suspect_and_retire_next_retirable_way(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian hdl, cpu, suspect_Lxcache, anonymous_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (ret);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } /* end SUSPECT_1_TAG */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache = cmd_Lxcache_lookup_by_type_index_bit_reason(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, pstype, index, bit, CMD_LXSUSPECT_0_TAG);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d found index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " bit %d retired as SUSPECT_0_TAG. Will"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " re-retire this now as SUSPECT_1_TAG.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * destroy the anonymous_Lxcache
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, anonymous_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_ep = ep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to update the FM_FMRI_CPU_CACHE_BIT entry
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * in the Lxcache_asru_nvl. This entry was last updated
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * when the cacheline was retired as SUSPECT_0.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Therefore the MSB of FM_FMRI_CPU_CACHE_BIT entry
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * value will be reset. To retire cacheline as
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * SUSPECT_1 the MSB has to be set.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian errno = nvlist_add_uint16(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_asru_nvl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian FM_FMRI_CPU_CACHE_BIT,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (errno) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: failed to update",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " CACHE_BIT in asru.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_Lxcache_retire_as_reason(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache, fltnm, CMD_LXSUSPECT_1_TAG));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } /* end of SUSPECT_0_TAG */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * No ways have been retired as "SUSPECT_x" for this bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to retire the lowest unretired way as suspect.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = retire_lowest_retirable_way_as_suspect(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (ret);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } /* End of Anonymous TAG retirement */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Identified bit and way has fired.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - Destroy any anonymous SERD engine at that index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - If the bad bit is an ECC bit, fault the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - If the way was already convicted due to tag errors, fault the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - If the bad bit is a state bit, then:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if the stable value of the bad bit will hold the NA encoding,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the containing way as "convicted".
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if the stable value of the bad bit will not hold the NA
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * encoding, fault the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy_anonymous_serd_engines(hdl, cpu, pstype, index, -1);
7bebe46c240b554f47faeed19186123896281967jc sticky_bit = find_bit_stickiness(tag_data, way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((bit >= PN_LX_TAG_ECC_START_BIT) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (bit <= PN_LX_TAG_ECC_END_BIT)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d Bad ECC bit %d at cache index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " detected. Will offline the CPU.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, bit, index, way);
7bebe46c240b554f47faeed19186123896281967jc cmd_fault_the_cpu(hdl, cpu, pstype, fltnm);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Check if a STATE bit is faulty.
7bebe46c240b554f47faeed19186123896281967jc * If so we need to ensure that we will be able to
7bebe46c240b554f47faeed19186123896281967jc * make the way NA, else fault the CPU.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (bit <= PN_LX_STATE_END_BIT) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
7bebe46c240b554f47faeed19186123896281967jc "%s cpu_id = %d: STATE bit %d is faulty.\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, bit);
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * If the stable value of bit will hold the NA encoding
7bebe46c240b554f47faeed19186123896281967jc * retire the containing way Else fault the cpu.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian state = tag_data[way] & CH_ECSTATE_MASK;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((state & (1 << bit)) != (PN_ECSTATE_NA & (1 << bit))) {
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The stable value of the bad bit will not hold the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * NA encoding. will fault the CPU.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d STATE bit %d is faulty at"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cache index %d way %d. STATE = 0x%x\n"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " The bad bit will not hold the encoding we need"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " to mark the cacheline as retired, so will offline"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " the CPU.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, bit, index, way, state);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, pstype, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Check if we are getting fault on a way that is already retired.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * if the way was already convicted due to tag errors, fault the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Note that the way could have previously been retired due to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * data errors. This is okay; we just re-retire it due to tag errors,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * so that we can write the offending tag bit to a stable value.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((tag_data[way] & CH_ECSTATE_MASK) == PN_ECSTATE_NA) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Looking for CONVICTED TAG fault first.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If found retire the CPU.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_Lxcache = cmd_Lxcache_lookup_by_type_index_way_reason(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, pstype, index, way, CMD_LXCONVICTED);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (retired_Lxcache) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: The cache index %d way %d previously"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retired for %s fault at bit %d is reporting"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " fault. Will fault the CPU\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index, way,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_type_to_str(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_Lxcache->Lxcache_type),
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian retired_Lxcache->Lxcache_bit);
7bebe46c240b554f47faeed19186123896281967jc cmd_fault_the_cpu(hdl, cpu, pstype, fltnm);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way_already_retired = 1;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If any way(Including the current way) at this index is retired as
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * "suspect" due to tag errors, unretire it. (If that suspect way
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * really was bad, it will start producing errors again and will
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * eventually be retired again.)
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache = cmd_Lxcache_lookup_by_type_index_bit_reason(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, pstype, index, -1,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (CMD_LXSUSPECT_0_TAG | CMD_LXSUSPECT_1_TAG));
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d found index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " bit %d retired as SUSPECT_x. Will"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " unretire this now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way, -1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretire the suspect_x retired_way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache_unretire(hdl, cpu, suspect_Lxcache, fltnm)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian == B_TRUE) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_reason =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian CMD_LXFUNCTIONING;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " successfully unretired. Will"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " destroy this Lxcache now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, suspect_Lxcache);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We are unable to unretire the previously retired
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * SUSPECT way at the fault index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If the previously retired way is same as the way
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we are attempting to retire then return failure.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache->Lxcache_way ==
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_way)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ways_retired = get_index_retired_ways(cpu, pstype, index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired == -1)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Before retiring a way check if we have already
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired 3 ways for this index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If the way was already retired due to DATA error or
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * SUSPECT_X TAG error then we skip the check.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (!way_already_retired) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired >= 3) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: num of ways retired for index %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " is %d will fault the CPU\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fltnm, cpu->cpu_cpuid, index, ways_retired);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, pstype, fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: num of ways retired for index %d is %d\n",
7bebe46c240b554f47faeed19186123896281967jc fltnm, cpu->cpu_cpuid, index, ways_retired);
7bebe46c240b554f47faeed19186123896281967jc if ((errno = nvlist_add_uint16(Lxcache->Lxcache_asru_nvl,
7bebe46c240b554f47faeed19186123896281967jc FM_FMRI_CPU_CACHE_BIT,
7bebe46c240b554f47faeed19186123896281967jc sticky_bit)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = fmd_nvl_fmri_expand(hdl, Lxcache->Lxcache_asru_nvl)) != 0)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to build Lxcache fmri");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_ep = ep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (cmd_Lxcache_retire_as_reason(hdl, cpu, Lxcache, fltnm,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian CMD_LXCONVICTED));
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic boolean_t
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianpn_there_is_a_matching_synd(fmd_hdl_t *hdl, cmd_xr_t *xr)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int ec_data_idx, i;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int8_t way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint64_t ec_tag, data_hi, data_lo;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int ecc, calc_synd;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ec_data_elm_t *ecdptr = NULL;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint8_t state;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ch_ec_data_t *ecp;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ecp = (ch_ec_data_t *)(xr->xr_cache_data);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (way = 0; way < xr->xr_num_ways; way++, ecp++) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ec_tag = ecp->ec_tag;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * skip Retired and Invalid ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian state = ec_tag & CH_ECSTATE_MASK;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((state == PN_ECSTATE_NA) ||
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (state == CH_ECSTATE_INV))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian continue;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Each 16 bytes of data are protected by 9-bit ECC field.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian for (i = 0; i < (CH_ECACHE_SUBBLK_SIZE/16); i++) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ec_data_idx = (i/2);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ecdptr = &ecp->ec_data[ec_data_idx];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((i & 1) == 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ecc = (ecdptr->ec_eccd >> 9) & 0x1ff;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian data_hi = ecdptr->ec_d8[0];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian data_lo = ecdptr->ec_d8[1];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ecc = ecdptr->ec_eccd & 0x1ff;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian data_hi = ecdptr->ec_d8[2];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian data_lo = ecdptr->ec_d8[3];
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian calc_synd = calcsynd(data_hi, data_lo, ecc);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((calc_synd != 0) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (xr->xr_synd == calc_synd)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (xr->xr_num_ways == 1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\ncomputed syndrome matches with the reported syndrome"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " 0x%x index = %d way = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_synd, xr->xr_error_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way);
7bebe46c240b554f47faeed19186123896281967jc } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\ncomputed syndrome matches with"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " the reported syndrome"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " 0x%x index = %d way = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_synd, xr->xr_error_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = way;
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (B_TRUE);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (B_FALSE);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian/* add to cheetahregs.h */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#define CH_ECSTATE_NA 5
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianstatic int32_t
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanianpn_extract_index(int32_t type, uint64_t afar)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int32_t index = -1;
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian switch (type) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_PTR_CPU_L2DATA:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index = (int32_t)((afar & PN_L2_INDEX_MASK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian >> PN_CACHE_LINE_SHIFT);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_PTR_CPU_L3DATA:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian index = (int32_t)((afar & PN_L3_INDEX_MASK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian >> PN_CACHE_LINE_SHIFT);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (index);
7bebe46c240b554f47faeed19186123896281967jc}
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * cmd_cache_ce_panther
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * This routine handles L2 and L3 cachedata errors for the Panther.
7bebe46c240b554f47faeed19186123896281967jc * It's called when the train processing for L2 and L3 correctable
7bebe46c240b554f47faeed19186123896281967jc * data errors are about to issue a fault.
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * This routine retrieves payload information gathered during the XR
7bebe46c240b554f47faeed19186123896281967jc * processing and generates a unique SERD engine and cache data
7bebe46c240b554f47faeed19186123896281967jc * associated with the CPU if one does not exist.
7bebe46c240b554f47faeed19186123896281967jc * If the SERD fires for the given engine it will initiate a cache
7bebe46c240b554f47faeed19186123896281967jc * line fault if the way is not anonomyous.
7bebe46c240b554f47faeed19186123896281967jc * If the way is anonomyous, it will attempt to choose a way for the
7bebe46c240b554f47faeed19186123896281967jc * given index to fault. If the maximum for the index has not been
7bebe46c240b554f47faeed19186123896281967jc * reached, it will attempt to unretire a different way previously retired
7bebe46c240b554f47faeed19186123896281967jc * under suspicion for the index prior to faulting
7bebe46c240b554f47faeed19186123896281967jc * the selected way.
7bebe46c240b554f47faeed19186123896281967jc * The routine will also fault the CPU if the maximum number of
7bebe46c240b554f47faeed19186123896281967jc * retired ways for the CPU has been exceeded based on the category.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc/*ARGSUSED*/
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jccmd_cache_ce_panther(fmd_hdl_t *hdl, fmd_event_t *ep, cmd_xr_t *xr)
7bebe46c240b554f47faeed19186123896281967jc{
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_t *suspect_Lxcache, *Lxcache, *anonymous_Lxcache;
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu = xr->xr_cpu;
7bebe46c240b554f47faeed19186123896281967jc cmd_case_t *cpu_cc;
7bebe46c240b554f47faeed19186123896281967jc cmd_ptrsubtype_t type;
7bebe46c240b554f47faeed19186123896281967jc const errdata_t *cache_ed;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint16_t offset;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int16_t bit;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int ways_retired;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int ret;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The caller of this routine cmd_xxc_hdlr() expects us to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * return CMD_EVD_OK for success and CMD_EVD_BAD for failures.
7bebe46c240b554f47faeed19186123896281967jc * If this is not a Panther or one of the Panther specific
7bebe46c240b554f47faeed19186123896281967jc * errors that we handle here, then exit
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cpu->cpu_pers.cpup_type != CPU_ULTRASPARC_IVplus)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (!(xr->xr_clcode & (int)PN_CACHE_ERRORS))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /* Set up Cache specific structs */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (CMD_ERRCL_ISL2XXCU(xr->xr_clcode)) {
7bebe46c240b554f47faeed19186123896281967jc type = CMD_PTR_CPU_L2DATA;
7bebe46c240b554f47faeed19186123896281967jc cpu_cc = &cpu->cpu_l2data;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed = &l2errdata;
7bebe46c240b554f47faeed19186123896281967jc } else {
7bebe46c240b554f47faeed19186123896281967jc type = CMD_PTR_CPU_L3DATA;
7bebe46c240b554f47faeed19186123896281967jc cpu_cc = &cpu->cpu_l3data;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed = &l3errdata;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /* Ensure that our case is not solved */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (cpu->cpu_faulting || (cpu_cc->cc_cp != NULL &&
7bebe46c240b554f47faeed19186123896281967jc fmd_case_solved(hdl, cpu_cc->cc_cp)))
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "Processing Panther %s Error\n",
7bebe46c240b554f47faeed19186123896281967jc cache_ed->ed_fltnm);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /* L3 errors arrive as mem scheme errors - convert to CPU */
7bebe46c240b554f47faeed19186123896281967jc if (type == CMD_PTR_CPU_L3DATA) {
7bebe46c240b554f47faeed19186123896281967jc cmd_fmri_init(hdl, &xr->xr_rsrc,
7bebe46c240b554f47faeed19186123896281967jc xr->xr_detector_nvlist, "%s_rsrc",
7bebe46c240b554f47faeed19186123896281967jc fmd_case_uuid(hdl, xr->xr_case));
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit = (uint8_t)ecc_syndrome_tab[xr->xr_synd];
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian offset = (uint16_t)xr->xr_afar & 0x3f;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (bit > C8) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "xxC/LDxC dropped due to syndrome\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (bit < C0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Data bit. Set bit in the range 0-511
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit += ((3 - (offset/16)) * 128);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * ECC bit. Set bit in the range 512-547
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit -= C0;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit += 512 + ((3 - (offset/16)) * PN_LX_NUM_OF_BITS_IN_ECC);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_index = pn_extract_index(type, xr->xr_afar);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (xr->xr_error_index == 0xffffffff) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "xxC/LDxC dropped due to index\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "cpu_id: %d, syndrome: 0x%x, afar: 0x%llx\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_cpuid, xr->xr_synd, xr->xr_afar);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "index: 0x%x(%d) bit: %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_index, xr->xr_error_index, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The payload information for the DATA errors are assembled
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * after first looking for a valid line that matches the fault AFAR.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If no match is found all 4 ways are logged and xr_num_ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * will be 4. If a matching way is found only that entry is logged
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * and xr_num_ways is set as 1.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The xr_error_way is set as -1 when xr_num_ways is 4, else
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * xr_error_way is set to the matching way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * what we do below is to force the xr_error_way to -1 for WDC/CPC
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * errors.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * For UCC and EDC errors the xr_error_way will be set correctly.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian switch (xr->xr_clcode) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_WDC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_L3_WDC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * WDC is a disrupting trap, and invalidates and
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * overwrites the problematic way. Any match is due to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * a refetch of the AFAR, which could have been to any
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * way. So these are treated as "anonymous".
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "WDC fault detected\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = (uint32_t)CMD_ANON_WAY;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_CPC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_L3_CPC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * CPC is a disrupting trap, but since it happens due to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * a snoop, the problematic way could become invalid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * overwritten by a different cache line, and then the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * AFAR accessed and pulled into a different way,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * causing a false positive match. So it's best to not
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * look for a matching way and just ascribe these to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the "anonymous" way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "CPC fault detected\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = (uint32_t)CMD_ANON_WAY;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_UCC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_L3_UCC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * UCC is a precise trap, so, absent activity from the
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * other core, the tag address values read by the TL=1
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * trap handler are likely to be the same as those at
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * the time of the trap.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * (A snoop from another CPU might cause a change in
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * state from valid to invalid, but the tag address
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * won't change.) If we find a matching valid tag,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that identifies the way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "UCC fault detected\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "# of ways collected are %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_num_ways);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: error way = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_EDC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian case CMD_ERRCL_L3_EDC:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * EDC is a disrupting trap, but again if a matching
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * valid way is found, it is likely to be the correct
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "EDC fault detected\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "# of ways collected are %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_num_ways);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: error way = %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian break;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian default:
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "Unexpected fault detected\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = (uint32_t)CMD_ANON_WAY;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((type == CMD_PTR_CPU_L2DATA) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (xr->xr_cache_data != NULL) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (!pn_there_is_a_matching_synd(hdl, xr))) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "No matching syndrome\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache = cmd_Lxcache_lookup_by_type_index_way_bit(xr->xr_cpu, type,
7bebe46c240b554f47faeed19186123896281967jc xr->xr_error_index, xr->xr_error_way, bit);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: creating a case for index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " bit %d\n",
7bebe46c240b554f47faeed19186123896281967jc cache_ed->ed_fltnm, xr->xr_cpuid,
7bebe46c240b554f47faeed19186123896281967jc xr->xr_error_index, xr->xr_error_way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache = cmd_Lxcache_create(hdl, xr, xr->xr_cpu,
7bebe46c240b554f47faeed19186123896281967jc xr->xr_cpu->cpu_asru_nvl,
7bebe46c240b554f47faeed19186123896281967jc type, xr->xr_error_index,
7bebe46c240b554f47faeed19186123896281967jc xr->xr_error_way, bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d:Failed to create a Lxcache for"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " index %d way %d bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_way, Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_create_case_for_Lxcache(hdl, cpu, Lxcache) == B_FALSE)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (Lxcache->Lxcache_case.cc_serdnm == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm =
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_serdnm_create(hdl, xr->xr_cpuid,
7bebe46c240b554f47faeed19186123896281967jc type, xr->xr_error_index, xr->xr_error_way, bit);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (!fmd_serd_exists(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm)) {
7bebe46c240b554f47faeed19186123896281967jc fmd_serd_create(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm,
7bebe46c240b554f47faeed19186123896281967jc cache_ed->ed_serd->cs_n,
7bebe46c240b554f47faeed19186123896281967jc cache_ed->ed_serd->cs_t);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu_id %d: created a SERD engine %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /* Ensure that our case is not solved */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if ((Lxcache->Lxcache_case.cc_cp != NULL) &&
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_case_solved(hdl, Lxcache->Lxcache_case.cc_cp)) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu %d: the case for %s is already solved.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_bufname);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_REDUND);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d: checking if SERD engine %s has fired.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, xr->xr_cpuid, Lxcache->Lxcache_case.cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (fmd_serd_record(hdl, Lxcache->Lxcache_case.cc_serdnm, ep)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian == FMD_B_FALSE)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK); /* serd engine hasn't fired yet */
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "\n%s: cpu_id = %d creating fault %s\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_case_add_serd(hdl, Lxcache->Lxcache_case.cc_cp,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_case.cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_serd_reset(hdl, Lxcache->Lxcache_case.cc_serdnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Find out if there is a way at the fault index/bit that was retired
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * as suspect. We need this information for both anonymous way and
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * identified way handling. We store this info in suspect_Lxcache.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d checking if there is a way at"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " index %d retired as suspect due to bit %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index, Lxcache->Lxcache_bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache = cmd_Lxcache_lookup_by_type_index_bit_reason(
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, type, Lxcache->Lxcache_index, Lxcache->Lxcache_bit,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian CMD_LXSUSPECT_DATA);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (xr->xr_error_way != (uint32_t)CMD_ANON_WAY) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * IDENTIFIED WAY DATA error handling.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian *
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If there is a way at that index retired as suspect due
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * to that bit, unretire it.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the identified way, and mark the way as "convicted"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * for this bit. Destroy any anonymous SERD engine named by
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that index and bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache != NULL) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s:cpu_id %d found index %d way %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " bit %d retired on suspicion. Will"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " unretire this now.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_way,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_bit);
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * unretire the retired_way.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cmd_Lxcache_unretire(hdl, cpu, suspect_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm) == B_TRUE) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian suspect_Lxcache->Lxcache_reason =
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian CMD_LXFUNCTIONING;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy(hdl, cpu, suspect_Lxcache);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We proceed to retire the identified way even if
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we are unable to unretire the suspect way.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We will not end up retiring all 4 ways because
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * we check the actual number of ways retired
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * at this index by reading the info from processor
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * directly. The call to get_index_retired_ways() does
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Before retiring a way check if we have already
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retired 3 ways for this index.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ways_retired = get_index_retired_ways(cpu, type,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired == -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: We are unable to determine how many"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " ways are retired at this index. We will not be"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " retiring the identified cacheline at index %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " way %d\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index, Lxcache->Lxcache_way);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_BAD);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ways_retired >= 3) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "\n%s: cpu %d: num of ways retired for index %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " is %d. Will fault the CPU\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, cpu->cpu_cpuid,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index, ways_retired);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_fault_the_cpu(hdl, cpu, type, cache_ed->ed_fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the cache line
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = cmd_Lxcache_retire_as_reason(hdl, cpu, Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm, CMD_LXCONVICTED);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (ret != CMD_EVD_OK)
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (ret);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * anonymous serd engines for DATA faults will have valid bit
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * but way as -1.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cmd_Lxcache_destroy_anonymous_serd_engines(hdl, cpu, type,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian Lxcache->Lxcache_index,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian bit);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMD_EVD_OK);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } /* end of IDENTIFIED WAY error handling */
7bebe46c240b554f47faeed19186123896281967jc /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * ANONYMOUS WAY DATA error handling.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian *
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if a way at this index has already been retired as "suspect"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * for this bit, unretire that way, and retire the next retirable
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * way as "suspect" for this bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if no ways have been retired as "suspect" for this bit,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire the lowest unretired way as "suspect" for this bit.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * - if there is no next retirable way, fault the CPU.
7bebe46c240b554f47faeed19186123896281967jc */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The assignment below is to make the code easier to maintain.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * We need to destroy the anonymous_Lxcache after we have
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * identifed a way to retire. If we cannot detrmine a way to
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * retire we will destrory the anonymous_Lxcache and fault the cpu.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache = Lxcache;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache->Lxcache_ep = ep;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (suspect_Lxcache != NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = unretire_suspect_and_retire_next_retirable_way(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpu, suspect_Lxcache, anonymous_Lxcache,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cache_ed->ed_fltnm);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian } else {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = retire_lowest_retirable_way_as_suspect(hdl, cpu,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian anonymous_Lxcache, cache_ed->ed_fltnm);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (ret);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/* ARGSUSED */
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jccmd_xr_pn_cache_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr,
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu, cmd_errcl_t clcode)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc struct ch_ec_data *data_ptr;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint64_t *cache_data = NULL;
7bebe46c240b554f47faeed19186123896281967jc uint_t sz;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (cpu->cpu_pers.cpup_type != CPU_ULTRASPARC_IVplus)
7bebe46c240b554f47faeed19186123896281967jc return (0);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_nvlist(nvl, FM_EREPORT_DETECTOR,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &xr->xr_detector_nvlist) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "look up for FM_EREPORT_DETECTOR failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_AFSR,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &xr->xr_afsr) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "look up for FM_EREPORT_PAYLOAD_NAME_AFSR failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /* check clcode for l2/l3 first */
7bebe46c240b554f47faeed19186123896281967jc if (CMD_ERRCL_ISL3XXCU(clcode)) {
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint8(nvl, FM_EREPORT_PAYLOAD_NAME_L3_WAYS,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &xr->xr_num_ways) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "look up for FM_EREPORT_PAYLOAD_NAME_L3_WAYS failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint64_array(nvl,
7bebe46c240b554f47faeed19186123896281967jc FM_EREPORT_PAYLOAD_NAME_L3_DATA, (uint64_t **)&cache_data,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &sz) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "look up for FM_EREPORT_PAYLOAD_NAME_L3_DATA failed\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc } else {
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint8(nvl, FM_EREPORT_PAYLOAD_NAME_L2_WAYS,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &xr->xr_num_ways) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "look up for FM_EREPORT_PAYLOAD_NAME_L2_WAYS failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint64_array(nvl,
7bebe46c240b554f47faeed19186123896281967jc FM_EREPORT_PAYLOAD_NAME_L2_DATA, (uint64_t **)&cache_data,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian &sz) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "look up for FM_EREPORT_PAYLOAD_NAME_L2_DATA failed\n");
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (xr->xr_num_ways > PN_CACHE_NWAYS) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "xr_num_ways > PN_CACHE_WAYS\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc xr->xr_cache_data = cache_data;
7bebe46c240b554f47faeed19186123896281967jc data_ptr = (struct ch_ec_data *)cache_data;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (cache_data == NULL) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = (uint32_t)CMD_ANON_WAY;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (0);
7bebe46c240b554f47faeed19186123896281967jc }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Our error handler checks for a matching valid way
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * If there is a match, there is only 1 data set, the set
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * associated with the cache-line/way that was "valid"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Otherwise, it stores all of the ways
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_tag = data_ptr[0].ec_tag;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian xr->xr_error_way = (uint32_t)data_ptr[0].ec_way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian
7bebe46c240b554f47faeed19186123896281967jc /* If there is more than 1 way structure, set way to Anonymous */
7bebe46c240b554f47faeed19186123896281967jc if (xr->xr_num_ways > 1)
7bebe46c240b554f47faeed19186123896281967jc xr->xr_error_way = (uint32_t)CMD_ANON_WAY;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (0);
7bebe46c240b554f47faeed19186123896281967jc}