cmd_Lxcache.c revision d69c2551e89e9440043ac6ff5739b58746286f33
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/*
7bebe46c240b554f47faeed19186123896281967jc * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7bebe46c240b554f47faeed19186123896281967jc * Use is subject to license terms.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#pragma ident "%Z%%M% %I% %E% SMI"
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * Support routines for managing per-Lxcache state.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_Lxcache.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_mem.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd_cpu.h>
7bebe46c240b554f47faeed19186123896281967jc#include <cmd.h>
7bebe46c240b554f47faeed19186123896281967jc#include <errno.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fcntl.h>
7bebe46c240b554f47faeed19186123896281967jc#include <unistd.h>
7bebe46c240b554f47faeed19186123896281967jc#include <stdio.h>
7bebe46c240b554f47faeed19186123896281967jc#include <strings.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fm/fmd_api.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/fm/protocol.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/cheetahregs.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/mem_cache.h>
d69c2551e89e9440043ac6ff5739b58746286f33jc#include <fmd_adm.h>
d69c2551e89e9440043ac6ff5739b58746286f33jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define PN_ECSTATE_NA 5
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * These values are our threshold values for SERDing CPU's based on the
7bebe46c240b554f47faeed19186123896281967jc * the # of times we have retired a cache line for each category.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#define CMD_CPU_SERD_AGG_1 64
7bebe46c240b554f47faeed19186123896281967jc#define CMD_CPU_SERD_AGG_2 64
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic void
7bebe46c240b554f47faeed19186123896281967jcLxcache_write(fmd_hdl_t *hdl, cmd_Lxcache_t *Lxcache)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc fmd_buf_write(hdl, NULL, Lxcache->Lxcache_bufname, Lxcache,
7bebe46c240b554f47faeed19186123896281967jc sizeof (cmd_Lxcache_pers_t));
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
d69c2551e89e9440043ac6ff5739b58746286f33jcchar *
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_type_to_str(cmd_ptrsubtype_t pstype)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc switch (pstype) {
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l2data");
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l3data");
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l2tag");
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("l3tag");
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc default:
d69c2551e89e9440043ac6ff5739b58746286f33jc return ("unknown");
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc}
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_free(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache,
7bebe46c240b554f47faeed19186123896281967jc int destroy)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_case_t *cc = &Lxcache->Lxcache_case;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "Entering cmd_Lxcache_free for %s destroy = %d\n",
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_bufname, destroy);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (cc->cc_cp != NULL)
7bebe46c240b554f47faeed19186123896281967jc cmd_case_fini(hdl, cc->cc_cp, destroy);
7bebe46c240b554f47faeed19186123896281967jc if (cc->cc_serdnm != NULL) {
7bebe46c240b554f47faeed19186123896281967jc if (fmd_serd_exists(hdl, cc->cc_serdnm) && destroy) {
7bebe46c240b554f47faeed19186123896281967jc fmd_serd_destroy(hdl, cc->cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_strfree(hdl, cc->cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc cc->cc_serdnm = NULL;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (destroy)
7bebe46c240b554f47faeed19186123896281967jc fmd_buf_destroy(hdl, NULL, Lxcache->Lxcache_bufname);
7bebe46c240b554f47faeed19186123896281967jc cmd_fmri_fini(hdl, &Lxcache->Lxcache_asru, destroy);
7bebe46c240b554f47faeed19186123896281967jc cmd_list_delete(&cpu->cpu_Lxcaches, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_free(hdl, Lxcache, sizeof (cmd_Lxcache_t));
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_destroy(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_free(hdl, cpu, Lxcache, FMD_B_TRUE);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic cmd_Lxcache_t *
7bebe46c240b554f47faeed19186123896281967jcLxcache_lookup_by_type_index_way_bit(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc uint32_t index, uint32_t way, uint16_t bit)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches); Lxcache != NULL;
7bebe46c240b554f47faeed19186123896281967jc Lxcache = cmd_list_next(Lxcache)) {
7bebe46c240b554f47faeed19186123896281967jc if ((Lxcache->Lxcache_type == pstype) &&
7bebe46c240b554f47faeed19186123896281967jc (Lxcache->Lxcache_index == index) &&
7bebe46c240b554f47faeed19186123896281967jc (Lxcache->Lxcache_way == way) &&
7bebe46c240b554f47faeed19186123896281967jc (Lxcache->Lxcache_bit == bit))
7bebe46c240b554f47faeed19186123896281967jc return (Lxcache);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (NULL);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_t *
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_create(fmd_hdl_t *hdl, cmd_xr_t *xr, cmd_cpu_t *cpu,
7bebe46c240b554f47faeed19186123896281967jc nvlist_t *modasru, cmd_ptrsubtype_t pstype, uint32_t index,
7bebe46c240b554f47faeed19186123896281967jc uint32_t way, uint16_t bit)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc nvlist_t *asru;
7bebe46c240b554f47faeed19186123896281967jc const char *pstype_name;
7bebe46c240b554f47faeed19186123896281967jc uint8_t fmri_Lxcache_type;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
7bebe46c240b554f47faeed19186123896281967jc "creating new Lxcache for cachetype=%d index=%lx way=%lx bit=%x\n",
7bebe46c240b554f47faeed19186123896281967jc pstype, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc CMD_CPU_STAT_BUMP(cpu, Lxcache_creat);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc Lxcache = fmd_hdl_zalloc(hdl, sizeof (cmd_Lxcache_t), FMD_SLEEP);
7bebe46c240b554f47faeed19186123896281967jc (void) strncpy(Lxcache->Lxcache_cpu_bufname,
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_bufname, CMD_BUFNMLEN);
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_nodetype = CMD_NT_LxCACHE;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_version = CMD_LxCACHE_VERSION;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_type = pstype;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_index = index;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_way = way;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_bit = bit;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_reason = CMD_LXFUNCTIONING;
7bebe46c240b554f47faeed19186123896281967jc Lxcache->xr = xr;
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2DATA:
7bebe46c240b554f47faeed19186123896281967jc pstype_name = "l2data";
7bebe46c240b554f47faeed19186123896281967jc fmri_Lxcache_type = FM_FMRI_CPU_CACHE_TYPE_L2;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3DATA:
7bebe46c240b554f47faeed19186123896281967jc pstype_name = "l3data";
7bebe46c240b554f47faeed19186123896281967jc fmri_Lxcache_type = FM_FMRI_CPU_CACHE_TYPE_L3;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc pstype_name = "l2tag";
7bebe46c240b554f47faeed19186123896281967jc fmri_Lxcache_type = FM_FMRI_CPU_CACHE_TYPE_L2;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc pstype_name = "l3tag";
7bebe46c240b554f47faeed19186123896281967jc fmri_Lxcache_type = FM_FMRI_CPU_CACHE_TYPE_L3;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc default:
7bebe46c240b554f47faeed19186123896281967jc pstype_name = "unknown";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_bufname(Lxcache->Lxcache_bufname, sizeof (Lxcache->Lxcache_bufname),
7bebe46c240b554f47faeed19186123896281967jc "Lxcache_%s_%04d_%08d_%02d_%03d", pstype_name, cpu->cpu_cpuid,
7bebe46c240b554f47faeed19186123896281967jc index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc if ((errno = nvlist_dup(modasru, &asru, 0)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = nvlist_add_uint32(asru, FM_FMRI_CPU_CACHE_INDEX,
7bebe46c240b554f47faeed19186123896281967jc index)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = nvlist_add_uint32(asru, FM_FMRI_CPU_CACHE_WAY,
7bebe46c240b554f47faeed19186123896281967jc way)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = nvlist_add_uint16(asru, FM_FMRI_CPU_CACHE_BIT,
7bebe46c240b554f47faeed19186123896281967jc bit)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = nvlist_add_uint8(asru, FM_FMRI_CPU_CACHE_TYPE,
7bebe46c240b554f47faeed19186123896281967jc fmri_Lxcache_type)) != 0 ||
7bebe46c240b554f47faeed19186123896281967jc (errno = fmd_nvl_fmri_expand(hdl, asru)) != 0)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to build Lxcache fmri");
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_fmri_init(hdl, &Lxcache->Lxcache_asru, asru,
7bebe46c240b554f47faeed19186123896281967jc "%s_asru_%08x_%02x_%04x", pstype_name, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc nvlist_free(asru);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_list_append(&cpu->cpu_Lxcaches, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc Lxcache_write(hdl, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (Lxcache);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_t *
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_lookup_by_index_way(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc uint32_t index, uint32_t way)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *cache;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
7bebe46c240b554f47faeed19186123896281967jc cache = cmd_list_next(cache)) {
7bebe46c240b554f47faeed19186123896281967jc if ((cache->Lxcache_index == index) &&
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_way == way) &&
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_type == pstype)) {
7bebe46c240b554f47faeed19186123896281967jc return (cache);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (NULL);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_t *
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_lookup(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype, uint32_t index,
7bebe46c240b554f47faeed19186123896281967jc uint32_t way, uint16_t bit)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (Lxcache_lookup_by_type_index_way_bit(cpu, pstype, index, way,
7bebe46c240b554f47faeed19186123896281967jc bit));
7bebe46c240b554f47faeed19186123896281967jc}
d69c2551e89e9440043ac6ff5739b58746286f33jcssize_t
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_fmri_nvl2str(fmd_hdl_t *hdl, nvlist_t *nvl, char *buf, size_t buflen)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc uint8_t type;
d69c2551e89e9440043ac6ff5739b58746286f33jc uint32_t cpuid, index, way;
d69c2551e89e9440043ac6ff5739b58746286f33jc char *serstr = NULL;
d69c2551e89e9440043ac6ff5739b58746286f33jc char missing_list[128];
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc missing_list[0] = 0;
d69c2551e89e9440043ac6ff5739b58746286f33jc if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0)
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) strcat(missing_list, FM_FMRI_CPU_ID);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &serstr) != 0)
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) strcat(missing_list, FM_FMRI_CPU_SERIAL_ID);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_CACHE_INDEX, &index) != 0)
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) strcat(missing_list, FM_FMRI_CPU_CACHE_INDEX);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_CACHE_WAY, &way) != 0)
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) strcat(missing_list, FM_FMRI_CPU_CACHE_WAY);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (nvlist_lookup_uint8(nvl, FM_FMRI_CPU_CACHE_TYPE, &type) != 0)
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) strcat(missing_list, FM_FMRI_CPU_CACHE_TYPE);
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc if (strlen(missing_list) != 0) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\ncmd_fmri_nvl2str: missing %s in fmri\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc missing_list);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (-1);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc return (snprintf(buf, buflen,
d69c2551e89e9440043ac6ff5739b58746286f33jc "cpu:///%s=%u/%s=%s/%s=%u/%s=%u/%s=%d",
d69c2551e89e9440043ac6ff5739b58746286f33jc FM_FMRI_CPU_ID, cpuid,
d69c2551e89e9440043ac6ff5739b58746286f33jc FM_FMRI_CPU_SERIAL_ID, serstr,
d69c2551e89e9440043ac6ff5739b58746286f33jc FM_FMRI_CPU_CACHE_INDEX, index,
d69c2551e89e9440043ac6ff5739b58746286f33jc FM_FMRI_CPU_CACHE_WAY, way,
d69c2551e89e9440043ac6ff5739b58746286f33jc FM_FMRI_CPU_CACHE_TYPE, type));
d69c2551e89e9440043ac6ff5739b58746286f33jc}
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jcstatic int
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_repair_fmri(fmd_hdl_t *hdl, char *buf)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_adm_t *ap;
d69c2551e89e9440043ac6ff5739b58746286f33jc int err;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc if ((ap = fmd_adm_open(NULL, FMD_ADM_PROGRAM,
d69c2551e89e9440043ac6ff5739b58746286f33jc FMD_ADM_VERSION)) == NULL) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl, "Could not contact fmadm to unretire\n");
d69c2551e89e9440043ac6ff5739b58746286f33jc return (-1);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
7bebe46c240b554f47faeed19186123896281967jc
d69c2551e89e9440043ac6ff5739b58746286f33jc err = fmd_adm_rsrc_repair(ap, buf);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (err)
d69c2551e89e9440043ac6ff5739b58746286f33jc err = -1;
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_adm_close(ap);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (err);
d69c2551e89e9440043ac6ff5739b58746286f33jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcstatic cmd_Lxcache_t *
7bebe46c240b554f47faeed19186123896281967jcLxcache_wrapv1(fmd_hdl_t *hdl, cmd_Lxcache_pers_t *pers, size_t psz)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (psz != sizeof (cmd_Lxcache_pers_t)) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "size of state doesn't match size of "
7bebe46c240b554f47faeed19186123896281967jc "version 1 state (%u bytes).\n",
7bebe46c240b554f47faeed19186123896281967jc sizeof (cmd_Lxcache_pers_t));
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc Lxcache = fmd_hdl_zalloc(hdl, sizeof (cmd_Lxcache_t), FMD_SLEEP);
7bebe46c240b554f47faeed19186123896281967jc bcopy(pers, Lxcache, sizeof (cmd_Lxcache_pers_t));
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_free(hdl, pers, psz);
7bebe46c240b554f47faeed19186123896281967jc return (Lxcache);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid *
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *recovered_Lxcache;
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu;
7bebe46c240b554f47faeed19186123896281967jc size_t Lxcachesz;
7bebe46c240b554f47faeed19186123896281967jc char *serdnm;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * We need to first extract the cpu name by reading directly
7bebe46c240b554f47faeed19186123896281967jc * from fmd buffers in order to begin our search for Lxcache in
7bebe46c240b554f47faeed19186123896281967jc * the appropriate cpu list.
7bebe46c240b554f47faeed19186123896281967jc * After we identify the cpu list using buf name we could look
7bebe46c240b554f47faeed19186123896281967jc * in cpu list for our Lxcache states.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "restoring Lxcache from %s\n", ptr->ptr_name);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if ((Lxcachesz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "Lxcache referenced by case %s does "
7bebe46c240b554f47faeed19186123896281967jc "not exist in saved state\n",
7bebe46c240b554f47faeed19186123896281967jc fmd_case_uuid(hdl, cp));
7bebe46c240b554f47faeed19186123896281967jc } else if (Lxcachesz != sizeof (cmd_Lxcache_pers_t)) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "Lxcache buffer referenced by case %s "
7bebe46c240b554f47faeed19186123896281967jc "is %d bytes. Expected size is %d bytes\n",
7bebe46c240b554f47faeed19186123896281967jc fmd_case_uuid(hdl, cp), Lxcachesz,
7bebe46c240b554f47faeed19186123896281967jc sizeof (cmd_Lxcache_pers_t));
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if ((Lxcache = cmd_buf_read(hdl, NULL, ptr->ptr_name,
7bebe46c240b554f47faeed19186123896281967jc Lxcachesz)) == NULL) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to read Lxcache buf %s",
7bebe46c240b554f47faeed19186123896281967jc ptr->ptr_name);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "found %d in version field\n",
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_version);
7bebe46c240b554f47faeed19186123896281967jc cpu = cmd_restore_cpu_only(hdl, cp, Lxcache->Lxcache_cpu_bufname);
7bebe46c240b554f47faeed19186123896281967jc recovered_Lxcache = Lxcache; /* save the recovered Lxcache */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches); Lxcache != NULL;
7bebe46c240b554f47faeed19186123896281967jc Lxcache = cmd_list_next(Lxcache)) {
7bebe46c240b554f47faeed19186123896281967jc if (strcmp(Lxcache->Lxcache_bufname, ptr->ptr_name) == 0)
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (Lxcache == NULL) {
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc switch (recovered_Lxcache->Lxcache_version) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_LxCACHE_VERSION_1:
7bebe46c240b554f47faeed19186123896281967jc Lxcache = Lxcache_wrapv1(hdl,
7bebe46c240b554f47faeed19186123896281967jc (cmd_Lxcache_pers_t *)recovered_Lxcache,
7bebe46c240b554f47faeed19186123896281967jc Lxcachesz);
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc default:
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "unknown version (found %d) "
7bebe46c240b554f47faeed19186123896281967jc "for Lxcache state referenced by case %s.\n",
7bebe46c240b554f47faeed19186123896281967jc recovered_Lxcache->Lxcache_version,
7bebe46c240b554f47faeed19186123896281967jc fmd_case_uuid(hdl, cp));
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_fmri_restore(hdl, &Lxcache->Lxcache_asru);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_list_append(&cpu->cpu_Lxcaches, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc serdnm = cmd_Lxcache_serdnm_create(hdl, cpu->cpu_cpuid,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_type, Lxcache->Lxcache_index,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_way, Lxcache->Lxcache_bit);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
7bebe46c240b554f47faeed19186123896281967jc "cpu_id %d: serdname for the case is %s\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, serdnm);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl,
7bebe46c240b554f47faeed19186123896281967jc "cpu_id %d: restoring the case for index %d way %d bit %d\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, Lxcache->Lxcache_index,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_way, Lxcache->Lxcache_bit);
7bebe46c240b554f47faeed19186123896281967jc cmd_case_restore(hdl, &Lxcache->Lxcache_case, cp, serdnm);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc return (Lxcache);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/*ARGSUSED*/
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_validate(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache, *next;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
7bebe46c240b554f47faeed19186123896281967jc Lxcache != NULL; Lxcache = next) {
7bebe46c240b554f47faeed19186123896281967jc next = cmd_list_next(Lxcache);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (fmd_nvl_fmri_unusable(hdl, Lxcache->Lxcache_asru_nvl)) {
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_destroy(hdl, cpu, Lxcache);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_dirty(fmd_hdl_t *hdl, cmd_Lxcache_t *Lxcache)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc if (fmd_buf_size(hdl, NULL, Lxcache->Lxcache_bufname) !=
7bebe46c240b554f47faeed19186123896281967jc sizeof (cmd_Lxcache_pers_t))
7bebe46c240b554f47faeed19186123896281967jc fmd_buf_destroy(hdl, NULL, Lxcache->Lxcache_bufname);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /* No need to rewrite the FMRIs in the Lxcache - they don't change */
7bebe46c240b554f47faeed19186123896281967jc fmd_buf_write(hdl, NULL,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_bufname, &Lxcache->Lxcache_pers,
7bebe46c240b554f47faeed19186123896281967jc sizeof (cmd_Lxcache_pers_t));
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_fini(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc while ((Lxcache = cmd_list_next(&cpu->cpu_Lxcaches)) != NULL)
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_free(hdl, cpu, Lxcache, FMD_B_FALSE);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jcchar *
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_serdnm_create(fmd_hdl_t *hdl, uint32_t cpu_id,
7bebe46c240b554f47faeed19186123896281967jc cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc uint32_t index, uint32_t way, uint16_t bit)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc const char *fmt = "cpu_%d:%s_%08d_%02d_%03d_serd";
7bebe46c240b554f47faeed19186123896281967jc const char *serdbase;
7bebe46c240b554f47faeed19186123896281967jc size_t sz;
7bebe46c240b554f47faeed19186123896281967jc char *nm;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2DATA:
7bebe46c240b554f47faeed19186123896281967jc serdbase = "l2data";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3DATA:
7bebe46c240b554f47faeed19186123896281967jc serdbase = "l3data";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc serdbase = "l2tag";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc serdbase = "l3tag";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc default:
7bebe46c240b554f47faeed19186123896281967jc serdbase = "unknown";
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc sz = (snprintf(NULL, 0, fmt, cpu_id, serdbase, index, way, bit) + 1);
7bebe46c240b554f47faeed19186123896281967jc nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
7bebe46c240b554f47faeed19186123896281967jc (void) snprintf(nm, sz, fmt, cpu_id, serdbase, index, way, bit);
7bebe46c240b554f47faeed19186123896281967jc return (nm);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * Count the number of SERD type 2 ways retired for a given cpu
7bebe46c240b554f47faeed19186123896281967jc * These are defined to be L3 Cache data retirements
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcuint32_t
7bebe46c240b554f47faeed19186123896281967jccmd_Lx_index_count_type2_ways(cmd_cpu_t *cpu)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *cache = NULL;
7bebe46c240b554f47faeed19186123896281967jc uint32_t ret_count = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
7bebe46c240b554f47faeed19186123896281967jc cache = cmd_list_next(cache)) {
7bebe46c240b554f47faeed19186123896281967jc if (((cache->Lxcache_reason == CMD_LXCONVICTED) ||
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_reason == CMD_LXSUSPICOUS)) &&
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_type == CMD_PTR_CPU_L3DATA)) {
7bebe46c240b554f47faeed19186123896281967jc ret_count++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (ret_count);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * Count the number of SERD type 1 ways retired for a given cpu
7bebe46c240b554f47faeed19186123896281967jc * These are defined to be L2 Data, tag and L3 Tag retirements
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcuint32_t
7bebe46c240b554f47faeed19186123896281967jccmd_Lx_index_count_type1_ways(cmd_cpu_t *cpu)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *cache = NULL;
7bebe46c240b554f47faeed19186123896281967jc uint32_t ret_count = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (cache = cmd_list_next(&cpu->cpu_Lxcaches); cache != NULL;
7bebe46c240b554f47faeed19186123896281967jc cache = cmd_list_next(cache)) {
7bebe46c240b554f47faeed19186123896281967jc if (((cache->Lxcache_reason == CMD_LXCONVICTED) ||
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_reason == CMD_LXSUSPICOUS)) &&
7bebe46c240b554f47faeed19186123896281967jc ((cache->Lxcache_type == CMD_PTR_CPU_L2DATA) ||
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_type == CMD_PTR_CPU_L2TAG) ||
7bebe46c240b554f47faeed19186123896281967jc (cache->Lxcache_type == CMD_PTR_CPU_L3TAG))) {
7bebe46c240b554f47faeed19186123896281967jc ret_count++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (ret_count);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_fault_the_cpu(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc const char *fltnm)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc fmd_case_t *cp;
7bebe46c240b554f47faeed19186123896281967jc const char *uuid;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cp = cmd_case_create(hdl, &cpu->cpu_header, pstype,
7bebe46c240b554f47faeed19186123896281967jc &uuid);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if ((errno = fmd_nvl_fmri_expand(hdl, cpu->cpu_asru_nvl)) != 0)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to build CPU fmri");
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_create_faultlist(hdl, cp, cpu, fltnm, NULL, 100);
7bebe46c240b554f47faeed19186123896281967jc fmd_case_solve(hdl, cp);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_fault(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache,
7bebe46c240b554f47faeed19186123896281967jc const char *type, nvlist_t *rsrc, uint_t cert)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc char fltnm[64];
7bebe46c240b554f47faeed19186123896281967jc nvlist_t *flt;
7bebe46c240b554f47faeed19186123896281967jc int cpu_retired_1, cpu_retired_2;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc (void) snprintf(fltnm, sizeof (fltnm), "fault.cpu.%s.%s-line",
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_type2name(hdl, cpu->cpu_type), type);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (Lxcache->Lxcache_flags & CMD_LxCACHE_F_FAULTING) {
7bebe46c240b554f47faeed19186123896281967jc return;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_flags |= CMD_LxCACHE_F_FAULTING;
7bebe46c240b554f47faeed19186123896281967jc flt = fmd_nvl_create_fault(hdl, fltnm, cert,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_asru.fmri_nvl, cpu->cpu_fru_nvl, rsrc);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_add_boolean_value(flt, FM_SUSPECT_MESSAGE, B_FALSE) != 0)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to add no-message member to fault");
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fmd_case_add_suspect(hdl, Lxcache->Lxcache_case.cc_cp, flt);
7bebe46c240b554f47faeed19186123896281967jc fmd_case_solve(hdl, Lxcache->Lxcache_case.cc_cp);
7bebe46c240b554f47faeed19186123896281967jc
d69c2551e89e9440043ac6ff5739b58746286f33jc if (Lxcache->Lxcache_retired_fmri[0] == 0) {
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_fmri_nvl2str(hdl, Lxcache->Lxcache_asru.fmri_nvl,
d69c2551e89e9440043ac6ff5739b58746286f33jc Lxcache->Lxcache_retired_fmri,
d69c2551e89e9440043ac6ff5739b58746286f33jc sizeof (Lxcache->Lxcache_retired_fmri)) == -1)
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu_id %d: Failed to save the"
d69c2551e89e9440043ac6ff5739b58746286f33jc " retired fmri string\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid);
d69c2551e89e9440043ac6ff5739b58746286f33jc else
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu_id %d:Saved the retired fmri string %s\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid,
d69c2551e89e9440043ac6ff5739b58746286f33jc Lxcache->Lxcache_retired_fmri);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
7bebe46c240b554f47faeed19186123896281967jc /* Retrieve the number of retired ways for each category */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cpu_retired_1 = cmd_Lx_index_count_type1_ways(cpu);
7bebe46c240b554f47faeed19186123896281967jc cpu_retired_2 = cmd_Lx_index_count_type2_ways(cpu);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "CPU %d retired Type 1 way count is: %d\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, cpu_retired_1);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "CPU %d retired Type 2 way count is: %d\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, cpu_retired_2);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if ((cpu_retired_1 > CMD_CPU_SERD_AGG_1) ||
7bebe46c240b554f47faeed19186123896281967jc (cpu_retired_2 > CMD_CPU_SERD_AGG_2) &&
7bebe46c240b554f47faeed19186123896281967jc (cpu->cpu_faulting != FMD_B_TRUE)) {
7bebe46c240b554f47faeed19186123896281967jc cmd_fault_the_cpu(hdl, cpu, Lxcache->Lxcache_type,
7bebe46c240b554f47faeed19186123896281967jc type);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_close(fmd_hdl_t *hdl, void *arg)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu;
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_t *Lxcache;
7bebe46c240b554f47faeed19186123896281967jc cmd_case_t *cc;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc Lxcache = (cmd_Lxcache_t *)arg;
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "closing Lxcache for %s\n",
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_bufname);
7bebe46c240b554f47faeed19186123896281967jc cc = &Lxcache->Lxcache_case;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
7bebe46c240b554f47faeed19186123896281967jc cpu = cmd_list_next(cpu)) {
7bebe46c240b554f47faeed19186123896281967jc if (strcmp(cpu->cpu_bufname,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_cpu_bufname) == 0)
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc if (cpu == NULL)
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_abort(hdl, "failed to find the cpu %s for %s\n",
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_cpu_bufname,
7bebe46c240b554f47faeed19186123896281967jc Lxcache->Lxcache_bufname);
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * We will destroy the case and serd engine.
7bebe46c240b554f47faeed19186123896281967jc * The rest will be destroyed when we retire the CPU
7bebe46c240b554f47faeed19186123896281967jc * until then we keep the Lxcache strutures alive.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (cc->cc_cp != NULL) {
7bebe46c240b554f47faeed19186123896281967jc cmd_case_fini(hdl, cc->cc_cp, FMD_B_TRUE);
7bebe46c240b554f47faeed19186123896281967jc cc->cc_cp = NULL;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc if (cc->cc_serdnm != NULL) {
7bebe46c240b554f47faeed19186123896281967jc if (fmd_serd_exists(hdl, cc->cc_serdnm))
7bebe46c240b554f47faeed19186123896281967jc fmd_serd_destroy(hdl, cc->cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_strfree(hdl, cc->cc_serdnm);
7bebe46c240b554f47faeed19186123896281967jc cc->cc_serdnm = NULL;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcvoid
7bebe46c240b554f47faeed19186123896281967jccmd_Lxcache_gc(fmd_hdl_t *hdl)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc cmd_cpu_t *cpu;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
7bebe46c240b554f47faeed19186123896281967jc cpu = cmd_list_next(cpu))
7bebe46c240b554f47faeed19186123896281967jc cmd_Lxcache_validate(hdl, cpu);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jccmd_evdisp_t
7bebe46c240b554f47faeed19186123896281967jcget_tagdata(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype,
7bebe46c240b554f47faeed19186123896281967jc uint32_t index, uint64_t *tag_data)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int fd;
7bebe46c240b554f47faeed19186123896281967jc cache_info_t cache_info;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fd = open(mem_cache_device, O_RDONLY);
7bebe46c240b554f47faeed19186123896281967jc if (fd == -1) {
7bebe46c240b554f47faeed19186123896281967jc (void) printf(
7bebe46c240b554f47faeed19186123896281967jc "cpu_id = %d could not open %s to read tag info.\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, mem_cache_device);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2DATA:
7bebe46c240b554f47faeed19186123896281967jc cache_info.cache = L2_CACHE_TAG;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3DATA:
7bebe46c240b554f47faeed19186123896281967jc cache_info.cache = L3_CACHE_TAG;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc cache_info.cpu_id = cpu->cpu_cpuid;
7bebe46c240b554f47faeed19186123896281967jc cache_info.index = index;
7bebe46c240b554f47faeed19186123896281967jc cache_info.datap = tag_data;
7bebe46c240b554f47faeed19186123896281967jc cache_info.way = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (test_mode) {
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (ioctl(fd, MEM_CACHE_READ_ERROR_INJECTED_TAGS, &cache_info)
7bebe46c240b554f47faeed19186123896281967jc == -1) {
7bebe46c240b554f47faeed19186123896281967jc (void) printf("cpu_id = %d ioctl"
7bebe46c240b554f47faeed19186123896281967jc " MEM_CACHE_READ_ERROR_INJECTED_TAGS failed"
7bebe46c240b554f47faeed19186123896281967jc " errno = %d\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, errno);
7bebe46c240b554f47faeed19186123896281967jc (void) close(fd);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc } else {
7bebe46c240b554f47faeed19186123896281967jc if (ioctl(fd, MEM_CACHE_READ_TAGS, &cache_info)
7bebe46c240b554f47faeed19186123896281967jc == -1) {
7bebe46c240b554f47faeed19186123896281967jc (void) printf("cpu_id = %d ioctl"
7bebe46c240b554f47faeed19186123896281967jc " MEM_CACHE_READ_TAGS failed"
7bebe46c240b554f47faeed19186123896281967jc " errno = %d\n",
7bebe46c240b554f47faeed19186123896281967jc cpu->cpu_cpuid, errno);
7bebe46c240b554f47faeed19186123896281967jc (void) close(fd);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_BAD);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc (void) close(fd);
7bebe46c240b554f47faeed19186123896281967jc return (CMD_EVD_OK);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jcget_cpu_retired_ways(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int index, index_size, i, retired_ways, fd;
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_data[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc cache_info_t cache_info;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fd = open(mem_cache_device, O_RDWR);
7bebe46c240b554f47faeed19186123896281967jc if (fd == -1) {
7bebe46c240b554f47faeed19186123896281967jc (void) printf("Error in opening file %s,Errno = %d\n",
7bebe46c240b554f47faeed19186123896281967jc mem_cache_device, errno);
7bebe46c240b554f47faeed19186123896281967jc return (-1);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc cache_info.cpu_id = cpu->cpu_cpuid;
7bebe46c240b554f47faeed19186123896281967jc switch (pstype) {
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2TAG:
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L2DATA:
7bebe46c240b554f47faeed19186123896281967jc index_size = (PN_L2_SET_SIZE/PN_L2_LINESIZE);
7bebe46c240b554f47faeed19186123896281967jc cache_info.cache = L2_CACHE_TAG;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3TAG:
7bebe46c240b554f47faeed19186123896281967jc case CMD_PTR_CPU_L3DATA:
7bebe46c240b554f47faeed19186123896281967jc index_size = (PN_L3_SET_SIZE/PN_L3_LINESIZE);
7bebe46c240b554f47faeed19186123896281967jc cache_info.cache = L3_CACHE_TAG;
7bebe46c240b554f47faeed19186123896281967jc break;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc retired_ways = 0;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc for (index = 0; index < index_size; index++) {
7bebe46c240b554f47faeed19186123896281967jc cache_info.index = index;
7bebe46c240b554f47faeed19186123896281967jc cache_info.way = 0;
7bebe46c240b554f47faeed19186123896281967jc cache_info.datap = &tag_data;
7bebe46c240b554f47faeed19186123896281967jc if (ioctl(fd, MEM_CACHE_READ_TAGS, &cache_info) == -1) {
7bebe46c240b554f47faeed19186123896281967jc (void) printf("index = %d :", index);
7bebe46c240b554f47faeed19186123896281967jc perror("ioctl MEM_CACHE_READ_TAGS failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (-1);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
7bebe46c240b554f47faeed19186123896281967jc if ((tag_data[i] & CH_ECSTATE_MASK) ==
7bebe46c240b554f47faeed19186123896281967jc PN_ECSTATE_NA)
7bebe46c240b554f47faeed19186123896281967jc retired_ways++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (retired_ways);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jcget_index_retired_ways(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype, uint32_t index)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc int i, retired_ways;
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_data[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (get_tagdata(cpu, pstype, index, tag_data) != 0) {
7bebe46c240b554f47faeed19186123896281967jc return (-1);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc retired_ways = 0;
7bebe46c240b554f47faeed19186123896281967jc for (i = 0; i < PN_CACHE_NWAYS; i++) {
7bebe46c240b554f47faeed19186123896281967jc if ((tag_data[i] & CH_ECSTATE_MASK) ==
7bebe46c240b554f47faeed19186123896281967jc PN_ECSTATE_NA)
7bebe46c240b554f47faeed19186123896281967jc retired_ways++;
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (retired_ways);
7bebe46c240b554f47faeed19186123896281967jc}
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jcis_index_way_retired(cmd_cpu_t *cpu, cmd_ptrsubtype_t pstype, uint32_t index,
7bebe46c240b554f47faeed19186123896281967jc uint32_t way)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc uint64_t tag_data[PN_CACHE_NWAYS];
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (get_tagdata(cpu, pstype, index, tag_data) != 0) {
7bebe46c240b554f47faeed19186123896281967jc return (-1);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc if ((tag_data[way] & CH_ECSTATE_MASK) == PN_ECSTATE_NA)
7bebe46c240b554f47faeed19186123896281967jc return (1);
7bebe46c240b554f47faeed19186123896281967jc return (0);
7bebe46c240b554f47faeed19186123896281967jc}
d69c2551e89e9440043ac6ff5739b58746286f33jcint
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_cache_way_retire(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc char *fltnm;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info_t cache_info;
d69c2551e89e9440043ac6ff5739b58746286f33jc int ret, fd;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm = cmd_type_to_str(Lxcache->Lxcache_type);
d69c2551e89e9440043ac6ff5739b58746286f33jc fd = open(mem_cache_device, O_RDWR);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (fd == -1) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d open of %s failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid, mem_cache_device);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cpu_id = cpu->cpu_cpuid;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.way = Lxcache->Lxcache_way;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.bit = Lxcache->Lxcache_bit;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.index = Lxcache->Lxcache_index;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc switch (Lxcache->Lxcache_type) {
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L2_CACHE_TAG;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L2_CACHE_DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L3_CACHE_TAG;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L3_CACHE_DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu %d: Retiring index %d, way %d bit %d\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid, cache_info.index, cache_info.way,
d69c2551e89e9440043ac6ff5739b58746286f33jc (int16_t)cache_info.bit);
d69c2551e89e9440043ac6ff5739b58746286f33jc ret = ioctl(fd, MEM_CACHE_RETIRE, &cache_info);
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) close(fd);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (ret == -1) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d MEM_CACHE_RETIRE ioctl failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_TRUE);
d69c2551e89e9440043ac6ff5739b58746286f33jc}
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jcboolean_t
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_cache_way_unretire(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *Lxcache)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc char *fltnm;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info_t cache_info;
d69c2551e89e9440043ac6ff5739b58746286f33jc int ret, fd;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm = cmd_type_to_str(Lxcache->Lxcache_type);
d69c2551e89e9440043ac6ff5739b58746286f33jc fd = open(mem_cache_device, O_RDWR);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (fd == -1) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d open of %s failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid, mem_cache_device);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cpu_id = cpu->cpu_cpuid;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.way = Lxcache->Lxcache_way;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.bit = Lxcache->Lxcache_bit;
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.index = Lxcache->Lxcache_index;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc switch (Lxcache->Lxcache_type) {
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L2_CACHE_TAG;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L2DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L2_CACHE_DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3TAG:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L3_CACHE_TAG;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc case CMD_PTR_CPU_L3DATA:
d69c2551e89e9440043ac6ff5739b58746286f33jc cache_info.cache = L3_CACHE_DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc break;
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpu %d: Unretiring index %d, way %d bit %d\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid, cache_info.index, cache_info.way,
d69c2551e89e9440043ac6ff5739b58746286f33jc (int16_t)cache_info.bit);
d69c2551e89e9440043ac6ff5739b58746286f33jc ret = ioctl(fd, MEM_CACHE_UNRETIRE, &cache_info);
d69c2551e89e9440043ac6ff5739b58746286f33jc (void) close(fd);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (ret == -1) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "fltnm:cpu_id %d MEM_CACHE_UNRETIRE ioctl failed\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid);
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_TRUE);
d69c2551e89e9440043ac6ff5739b58746286f33jc}
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jcstatic cmd_Lxcache_t *
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_Lxcache_lookup_by_type_index_way_flags(cmd_cpu_t *cpu,
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_ptrsubtype_t type, uint32_t index, int8_t way, int32_t flags)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache_t *cmd_Lxcache;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc for (cmd_Lxcache = cmd_list_next(&cpu->cpu_Lxcaches);
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache != NULL;
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache = cmd_list_next(cmd_Lxcache)) {
d69c2551e89e9440043ac6ff5739b58746286f33jc if ((cmd_Lxcache->Lxcache_index == index) &&
d69c2551e89e9440043ac6ff5739b58746286f33jc (cmd_Lxcache->Lxcache_way == way) &&
d69c2551e89e9440043ac6ff5739b58746286f33jc (cmd_Lxcache->Lxcache_type == type) &&
d69c2551e89e9440043ac6ff5739b58746286f33jc (cmd_Lxcache->Lxcache_flags & flags))
d69c2551e89e9440043ac6ff5739b58746286f33jc return (cmd_Lxcache);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc return (NULL);
d69c2551e89e9440043ac6ff5739b58746286f33jc}
d69c2551e89e9440043ac6ff5739b58746286f33jcboolean_t
d69c2551e89e9440043ac6ff5739b58746286f33jccmd_Lxcache_unretire(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_Lxcache_t *cmd_Lxcache,
d69c2551e89e9440043ac6ff5739b58746286f33jc const char *fltnm)
d69c2551e89e9440043ac6ff5739b58746286f33jc{
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_ptrsubtype_t data_type;
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache_t *retired_Lxcache;
d69c2551e89e9440043ac6ff5739b58746286f33jc
d69c2551e89e9440043ac6ff5739b58746286f33jc /*
d69c2551e89e9440043ac6ff5739b58746286f33jc * If we are unretiring a cacheline retired due to suspected TAG
d69c2551e89e9440043ac6ff5739b58746286f33jc * fault, then we must first check if we are using a cacheline
d69c2551e89e9440043ac6ff5739b58746286f33jc * that was retired earlier for DATA fault.
d69c2551e89e9440043ac6ff5739b58746286f33jc * If so we will not unretire the cacheline.
d69c2551e89e9440043ac6ff5739b58746286f33jc * We will change the flags to reflect the current condition.
d69c2551e89e9440043ac6ff5739b58746286f33jc * We will return success, though.
d69c2551e89e9440043ac6ff5739b58746286f33jc */
d69c2551e89e9440043ac6ff5739b58746286f33jc if ((cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L2TAG) ||
d69c2551e89e9440043ac6ff5739b58746286f33jc (cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L3TAG)) {
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L2TAG)
d69c2551e89e9440043ac6ff5739b58746286f33jc data_type = CMD_PTR_CPU_L2DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_Lxcache->Lxcache_type == CMD_PTR_CPU_L3TAG)
d69c2551e89e9440043ac6ff5739b58746286f33jc data_type = CMD_PTR_CPU_L3DATA;
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d checking if there is a %s"
d69c2551e89e9440043ac6ff5739b58746286f33jc " cacheline re-retired at this index %d and way %d\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid, cmd_type_to_str(data_type),
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_index, cmd_Lxcache->Lxcache_way);
d69c2551e89e9440043ac6ff5739b58746286f33jc retired_Lxcache = cmd_Lxcache_lookup_by_type_index_way_flags(
d69c2551e89e9440043ac6ff5739b58746286f33jc cpu, data_type, cmd_Lxcache->Lxcache_index,
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_way, CMD_LxCACHE_F_RERETIRED);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (retired_Lxcache) {
d69c2551e89e9440043ac6ff5739b58746286f33jc retired_Lxcache->Lxcache_flags = CMD_LxCACHE_F_RETIRED;
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_flags = CMD_LxCACHE_F_UNRETIRED;
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_TRUE);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_cache_way_unretire(hdl, cpu, cmd_Lxcache) == B_FALSE)
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_flags = CMD_LxCACHE_F_UNRETIRED;
d69c2551e89e9440043ac6ff5739b58746286f33jc /*
d69c2551e89e9440043ac6ff5739b58746286f33jc * We have unretired the cacheline. We need to inform the fmd
d69c2551e89e9440043ac6ff5739b58746286f33jc * that we have repaired the faulty fmri that we retired earlier.
d69c2551e89e9440043ac6ff5739b58746286f33jc * The cpumem agent will not unretire cacheline in response to
d69c2551e89e9440043ac6ff5739b58746286f33jc * the list.repair events it receives.
d69c2551e89e9440043ac6ff5739b58746286f33jc */
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_Lxcache->Lxcache_retired_fmri[0] != 0) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d Repairing the retired fmri %s",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid,
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_retired_fmri);
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_repair_fmri(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_retired_fmri) != 0) {
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d Failed to repair"
d69c2551e89e9440043ac6ff5739b58746286f33jc " retired fmri.",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid);
d69c2551e89e9440043ac6ff5739b58746286f33jc /*
d69c2551e89e9440043ac6ff5739b58746286f33jc * We need to retire the cacheline that we just
d69c2551e89e9440043ac6ff5739b58746286f33jc * unretired.
d69c2551e89e9440043ac6ff5739b58746286f33jc */
d69c2551e89e9440043ac6ff5739b58746286f33jc if (cmd_cache_way_retire(hdl, cpu, cmd_Lxcache)
d69c2551e89e9440043ac6ff5739b58746286f33jc == B_FALSE) {
d69c2551e89e9440043ac6ff5739b58746286f33jc /*
d69c2551e89e9440043ac6ff5739b58746286f33jc * A hopeless situation.
d69c2551e89e9440043ac6ff5739b58746286f33jc * cannot maintain consistency of cacheline
d69c2551e89e9440043ac6ff5739b58746286f33jc * sate between fmd and DE.
d69c2551e89e9440043ac6ff5739b58746286f33jc * Aborting the DE.
d69c2551e89e9440043ac6ff5739b58746286f33jc */
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_abort(hdl,
d69c2551e89e9440043ac6ff5739b58746286f33jc "\n%s:cpuid %d We are unable to repair"
d69c2551e89e9440043ac6ff5739b58746286f33jc " the fmri we just unretired and are"
d69c2551e89e9440043ac6ff5739b58746286f33jc " unable to restore the DE and fmd to"
d69c2551e89e9440043ac6ff5739b58746286f33jc " a sane state.\n",
d69c2551e89e9440043ac6ff5739b58746286f33jc fltnm, cpu->cpu_cpuid);
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_FALSE);
d69c2551e89e9440043ac6ff5739b58746286f33jc } else {
d69c2551e89e9440043ac6ff5739b58746286f33jc cmd_Lxcache->Lxcache_retired_fmri[0] = 0;
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc }
d69c2551e89e9440043ac6ff5739b58746286f33jc return (B_TRUE);
d69c2551e89e9440043ac6ff5739b58746286f33jc}