1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport/*
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * CDDL HEADER START
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * The contents of this file are subject to the terms of the
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * Common Development and Distribution License (the "License").
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * You may not use this file except in compliance with the License.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * or http://www.opensolaris.org/os/licensing.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * See the License for the specific language governing permissions
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * and limitations under the License.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * When distributing Covered Code, include this CDDL HEADER in each
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * If applicable, add the following below this CDDL HEADER, with the
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * fields enclosed by brackets "[]" replaced with your own identifying
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * information: Portions Copyright [yyyy] [name of copyright owner]
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * CDDL HEADER END
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport */
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport/*
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * Use is subject to license terms.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport */
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport/*
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport * Support routines for managing state related to memory modules.
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport */
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <gmem_mem.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <gmem_dimm.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <gmem.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <assert.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <errno.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <strings.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <ctype.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <fcntl.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <unistd.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <fm/fmd_api.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <sys/fm/protocol.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <sys/mem.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport#include <sys/nvpair.h>
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportchar *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mem_serdnm_create(fmd_hdl_t *hdl, const char *serdbase, const char *serial)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport const char *fmt = "%s_%s_serd";
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport size_t sz = snprintf(NULL, 0, fmt, serdbase, serial) + 1;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport char *nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) snprintf(nm, sz, fmt, serdbase, serial);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (nm);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportchar *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_page_serdnm_create(fmd_hdl_t *hdl, const char *serdbase,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint64_t phys_addr)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport const char *fmt = "%s_%llXserd";
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport size_t sz = snprintf(NULL, 0, fmt, serdbase, phys_addr) + 1;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport char *nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) snprintf(nm, sz, fmt, serdbase, phys_addr);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (nm);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportchar *
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mq_serdnm_create(fmd_hdl_t *hdl, const char *serdbase,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint64_t phys_addr, uint16_t cw, uint16_t pos)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport const char *fmt = "%s_%llX_%x_%x_serd";
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport size_t sz = snprintf(NULL, 0, fmt, serdbase, phys_addr, cw, pos) + 1;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport char *nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) snprintf(nm, sz, fmt, serdbase, phys_addr, cw, pos);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (nm);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportuint32_t
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_get_serd_filter_ratio(nvlist_t *nvl)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint32_t filter_ratio = 0;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint32_t erpt_ratio;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (gmem.gm_filter_ratio == 0) {
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (nvlist_lookup_uint32(nvl,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport GMEM_ERPT_PAYLOAD_FILTER_RATIO, &erpt_ratio) == 0)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport filter_ratio = erpt_ratio;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport } else
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport filter_ratio = gmem.gm_filter_ratio;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (filter_ratio);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportvoid
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_page_serd_create(fmd_hdl_t *hdl, gmem_page_t *page, nvlist_t *nvl)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint32_t erpt_serdn, serd_n;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint64_t erpt_serdt, serd_t;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport serd_n = gmem.gm_ce_n;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport serd_t = gmem.gm_ce_t;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (serd_n == DEFAULT_SERDN && serd_t == DEFAULT_SERDT) {
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (nvlist_lookup_uint32(nvl, GMEM_ERPT_PAYLOAD_SERDN,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport &erpt_serdn) == 0)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport serd_n = erpt_serdn;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (nvlist_lookup_uint64(nvl, GMEM_ERPT_PAYLOAD_SERDT,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport &erpt_serdt) == 0)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport serd_t = erpt_serdt;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport }
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport page->page_case.cc_serdnm = gmem_page_serdnm_create(hdl, "page",
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport page->page_physbase);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport fmd_serd_create(hdl, page->page_case.cc_serdnm, serd_n, serd_t);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportint
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_serd_record(fmd_hdl_t *hdl, const char *serdbaser, uint32_t ratio,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport fmd_event_t *ep)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport int i, rc;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (ratio == 0)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (fmd_serd_record(hdl, serdbaser, ep));
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport for (i = 0; i < ratio; i++) {
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport rc = fmd_serd_record(hdl, serdbaser, ep);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport if (rc != FMD_B_FALSE)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport break;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport }
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport return (rc);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportvoid
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mem_case_restore(fmd_hdl_t *hdl, gmem_case_t *cc, fmd_case_t *cp,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport const char *serdbase, const char *serial)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport gmem_case_restore(hdl, cc, cp, gmem_mem_serdnm_create(hdl, serdbase,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport serial));
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportvoid
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mem_retirestat_create(fmd_hdl_t *hdl, fmd_stat_t *st, const char *serial,
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport uint64_t value, const char *prefix)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) snprintf(st->fmds_name, sizeof (st->fmds_name), "%s%s",
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport prefix, serial);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) snprintf(st->fmds_desc, sizeof (st->fmds_desc),
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport "retirements for %s%s", prefix, serial);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport st->fmds_type = FMD_TYPE_UINT64;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport st->fmds_value.ui64 = value;
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, 1, st);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportvoid
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mem_gc(fmd_hdl_t *hdl)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport gmem_dimm_gc(hdl);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportvoid
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenportgmem_mem_fini(fmd_hdl_t *hdl)
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport{
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport gmem_dimm_fini(hdl);
1529f529004c61fcfd0d95ab79b0f257d6ad4451Scott Davenport}