14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * CDDL HEADER START
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * The contents of this file are subject to the terms of the
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * Common Development and Distribution License (the "License").
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * You may not use this file except in compliance with the License.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * or http://www.opensolaris.org/os/licensing.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * See the License for the specific language governing permissions
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * and limitations under the License.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * When distributing Covered Code, include this CDDL HEADER in each
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * If applicable, add the following below this CDDL HEADER, with the
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * fields enclosed by brackets "[]" replaced with your own identifying
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * information: Portions Copyright [yyyy] [name of copyright owner]
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * CDDL HEADER END
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * Use is subject to license terms.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <stdio.h>
dd566498928f08e7c9a79797a40db893c6a4b9fbvn#include <stdlib.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <strings.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <sys/types.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <fm/topo_mod.h>
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien#include <fm/topo_hc.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <sys/fm/protocol.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <unistd.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <sys/param.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <sys/stat.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <fcntl.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#include <umem.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn#include <cpu_mdesc.h>
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * Enumerates the processing chips, or sockets, (as distinct from cores) in a
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * system. For each chip found, the necessary nodes (one or more cores, and
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * possibly a memory controller) are constructed underneath.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#define CHIP_VERSION TOPO_VERSION
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#define CPU_NODE_NAME "cpu"
14ea4bb737263733ad80a36b4f73f681c30a6b45sd#define CHIP_NODE_NAME "chip"
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeextern topo_method_t pi_cpu_methods[];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/* Forward declaration */
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_instance_t, void *, void *);
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic void chip_release(topo_mod_t *, tnode_t *);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic const topo_modops_t chip_ops =
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { chip_enum, chip_release };
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic const topo_modinfo_t chip_info =
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops };
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic const topo_pgroup_info_t chip_auth_pgroup = {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd FM_FMRI_AUTHORITY,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd TOPO_STABILITY_PRIVATE,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd TOPO_STABILITY_PRIVATE,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd 1
14ea4bb737263733ad80a36b4f73f681c30a6b45sd};
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdint
14ea4bb737263733ad80a36b4f73f681c30a6b45sd_topo_init(topo_mod_t *mod)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
dd566498928f08e7c9a79797a40db893c6a4b9fbvn md_info_t *chip;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (getenv("TOPOCHIPDBG"))
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_setdebug(mod);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "initializing chip enumerator\n");
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn if ((chip = topo_mod_zalloc(mod, sizeof (md_info_t))) == NULL)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (-1);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (cpu_mdesc_init(mod, chip) != 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "failed to get cpus from the PRI/MD\n");
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_free(mod, chip, sizeof (md_info_t));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (-1);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_setspecific(mod, (void *)chip);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "failed to register hc: "
14ea4bb737263733ad80a36b4f73f681c30a6b45sd "%s\n", topo_mod_errmsg(mod));
dd566498928f08e7c9a79797a40db893c6a4b9fbvn cpu_mdesc_fini(mod, chip);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_free(mod, chip, sizeof (md_info_t));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (-1);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "chip enumerator inited\n");
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (0);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdvoid
14ea4bb737263733ad80a36b4f73f681c30a6b45sd_topo_fini(topo_mod_t *mod)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
dd566498928f08e7c9a79797a40db893c6a4b9fbvn md_info_t *chip;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn chip = (md_info_t *)topo_mod_getspecific(mod);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn cpu_mdesc_fini(mod, chip);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_free(mod, chip, sizeof (md_info_t));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_unregister(mod);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic tnode_t *
14ea4bb737263733ad80a36b4f73f681c30a6b45sdchip_tnode_create(topo_mod_t *mod, tnode_t *parent,
ef8846857fcf954444cdc77e72249afef48377d2rb const char *name, topo_instance_t i, char *serial,
ef8846857fcf954444cdc77e72249afef48377d2rb nvlist_t *fru, char *label, void *priv)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int err;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_t *fmri;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd tnode_t *ntn;
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye char *prod = NULL, *psn = NULL, *csn = NULL, *server = NULL;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_t *auth = NULL;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_mod_nvalloc(mod, &auth, NV_UNIQUE_NAME) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn FM_FMRI_AUTH_PRODUCT, &prod, &err) == 0) {
dd566498928f08e7c9a79797a40db893c6a4b9fbvn (void) nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn prod);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_strfree(mod, prod);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn }
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye FM_FMRI_AUTH_PRODUCT_SN, &psn, &err) == 0) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye (void) nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye psn);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_mod_strfree(mod, psn);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn FM_FMRI_AUTH_SERVER, &server, &err) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) nvlist_add_string(auth, FM_FMRI_AUTH_SERVER,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn server);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_strfree(mod, server);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn FM_FMRI_AUTH_CHASSIS, &csn, &err) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn csn);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_mod_strfree(mod, csn);
dd566498928f08e7c9a79797a40db893c6a4b9fbvn }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd NULL, auth, NULL, NULL, serial);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_free(auth);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (fmri == NULL) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd "Unable to make nvlist for %s bind: %s.\n",
14ea4bb737263733ad80a36b4f73f681c30a6b45sd name, topo_mod_errmsg(mod));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd ntn = topo_node_bind(mod, parent, name, i, fmri);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (ntn == NULL) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd "topo_node_bind (%s%d/%s%d) failed: %s\n",
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_node_name(parent), topo_node_instance(parent),
14ea4bb737263733ad80a36b4f73f681c30a6b45sd name, i,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_strerror(topo_mod_errno(mod)));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_free(fmri);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_free(fmri);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_node_setspecific(ntn, priv);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_pgroup_create(ntn, &chip_auth_pgroup, &err) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd FM_FMRI_AUTH_PRODUCT, &err);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye FM_FMRI_AUTH_PRODUCT_SN, &err);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd FM_FMRI_AUTH_CHASSIS, &err);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd FM_FMRI_AUTH_SERVER, &err);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /* Inherit the Label FRU fields from the parent */
ef8846857fcf954444cdc77e72249afef48377d2rb (void) topo_node_label_set(ntn, label, &err);
ef8846857fcf954444cdc77e72249afef48377d2rb (void) topo_node_fru_set(ntn, fru, 0, &err);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye /* Register retire methods */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (topo_method_register(mod, ntn, pi_cpu_methods) < 0)
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_mod_dprintf(mod, "Unsable to register retire methods "
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye "for %s%d/%s%d: %s\n",
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_node_name(parent), topo_node_instance(parent),
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye name, i, topo_mod_errmsg(mod));
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (ntn);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic nvlist_t *
14ea4bb737263733ad80a36b4f73f681c30a6b45sdcpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int err;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_t *fmri;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd err = nvlist_add_uint8(fmri, FM_VERSION, FM_CPU_SCHEME_VERSION);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd err |= nvlist_add_uint32(fmri, FM_FMRI_CPU_ID, cpuid);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd err |= nvlist_add_uint8(fmri, FM_FMRI_CPU_MASK, cpumask);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (serial != NULL)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd err |= nvlist_add_string(fmri, FM_FMRI_CPU_SERIAL_ID, serial);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (err != 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_free(fmri);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (fmri);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*ARGSUSED*/
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic int
dd566498928f08e7c9a79797a40db893c6a4b9fbvncpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, md_info_t *chip,
13faa91230bde46da937bf33010b9accc5bdeb59sd uint64_t serial)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int i;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int min = -1;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int max = -1;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int err;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int nerr = 0;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int pid;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd char sbuf[32];
14ea4bb737263733ad80a36b4f73f681c30a6b45sd tnode_t *cnode;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_t *asru;
dd566498928f08e7c9a79797a40db893c6a4b9fbvn md_cpumap_t *mcmp;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "enumerating cpus\n");
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /*
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * find the min/max id of cpus per this cmp and create a cpu range
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
dd566498928f08e7c9a79797a40db893c6a4b9fbvn for (i = 0, mcmp = chip->cpus; i < chip->ncpus; i++, mcmp++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd if (mcmp->cpumap_serialno != serial)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd continue;
dd566498928f08e7c9a79797a40db893c6a4b9fbvn if ((min < 0) || (mcmp->cpumap_pid < min))
dd566498928f08e7c9a79797a40db893c6a4b9fbvn min = mcmp->cpumap_pid;
dd566498928f08e7c9a79797a40db893c6a4b9fbvn if ((max < 0) || (mcmp->cpumap_pid > max))
dd566498928f08e7c9a79797a40db893c6a4b9fbvn max = mcmp->cpumap_pid;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
13faa91230bde46da937bf33010b9accc5bdeb59sd if (min < 0 || max < 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_mod_dprintf(mod, "Invalid cpu range(%d,%d)\n", min, max);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (-1);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (topo_node_range_create(mod, rnode, name, 0, max+1) < 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "failed to create cpu range[0,%d]: %s\n",
1557e65f9d0c6fde875d807c12fc03ea20f50280vn max, topo_mod_errmsg(mod));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (-1);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
13faa91230bde46da937bf33010b9accc5bdeb59sd (void) snprintf(sbuf, sizeof (sbuf), "%llx", serial);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /*
13faa91230bde46da937bf33010b9accc5bdeb59sd * Create the cpu[i] nodes of a given cmp i
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
dd566498928f08e7c9a79797a40db893c6a4b9fbvn for (i = 0, mcmp = chip->cpus; i < chip->ncpus; i++, mcmp++) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
13faa91230bde46da937bf33010b9accc5bdeb59sd if (mcmp->cpumap_serialno == 0 ||
13faa91230bde46da937bf33010b9accc5bdeb59sd mcmp->cpumap_serialno != serial) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd continue;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /* physical cpuid */
dd566498928f08e7c9a79797a40db893c6a4b9fbvn pid = mcmp->cpumap_pid;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd cnode = chip_tnode_create(mod, rnode, name,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn (topo_instance_t)pid, sbuf, NULL, NULL, NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (cnode == NULL) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod,
1557e65f9d0c6fde875d807c12fc03ea20f50280vn "failed to create a cpu=%d node: %s\n",
1557e65f9d0c6fde875d807c12fc03ea20f50280vn pid, topo_mod_errmsg(mod));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nerr++;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd continue;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if ((asru = cpu_fmri_create(mod, pid, sbuf, 0)) != NULL) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_node_asru_set(cnode, asru, 0, &err);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nvlist_free(asru);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd } else {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nerr++;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (nerr != 0)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (0);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic int
70818f5837509317d1f5dac4d82d7b5a2d547c29tsiendimm_instantiate(tnode_t *parent, const char *name, topo_mod_t *mod)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (strcmp(name, CHIP) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mod,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien "Currently only know how to enumerate %s components.\n",
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien CHIP);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mod,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien "Calling dimm_enum\n");
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (topo_mod_enumerate(mod,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien parent, DIMM, DIMM, 0, 0, NULL) != 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (0);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsienstatic topo_mod_t *
70818f5837509317d1f5dac4d82d7b5a2d547c29tsiendimm_enum_load(topo_mod_t *mp)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien{
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_t *rp = NULL;
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mp, "dimm_enum_load: %s\n", CHIP);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if ((rp = topo_mod_load(mp, DIMM, TOPO_VERSION)) == NULL) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mp,
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien "%s enumerator could not load %s enum. (%d: %s)\n",
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien CHIP, DIMM, errno, strerror(errno));
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mp, "dimm_enum_load(EXIT): %s, rp=%p\n", CHIP, rp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (rp);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien}
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*ARGSUSED*/
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic int
14ea4bb737263733ad80a36b4f73f681c30a6b45sdchip_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
dd566498928f08e7c9a79797a40db893c6a4b9fbvn topo_instance_t min, topo_instance_t max, md_info_t *chip)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int nerr = 0;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd int err;
13faa91230bde46da937bf33010b9accc5bdeb59sd int i;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd char sbuf[32];
14ea4bb737263733ad80a36b4f73f681c30a6b45sd tnode_t *cnode;
ef8846857fcf954444cdc77e72249afef48377d2rb nvlist_t *fru = NULL;
ef8846857fcf954444cdc77e72249afef48377d2rb char *label = NULL;
dd566498928f08e7c9a79797a40db893c6a4b9fbvn md_proc_t *procp;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "enumerating cmp chip\n");
13faa91230bde46da937bf33010b9accc5bdeb59sd if (min < 0 || max < 0 || min > max) {
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_mod_dprintf(mod, "Invalid chip range(%d,%d)\n", min, max);
13faa91230bde46da937bf33010b9accc5bdeb59sd return (-1);
13faa91230bde46da937bf33010b9accc5bdeb59sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (dimm_enum_load(mod) == NULL)
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (-1);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /*
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * Create the chip[i] nodes, one for each CMP chip uniquely identified
14ea4bb737263733ad80a36b4f73f681c30a6b45sd * by the serial number.
14ea4bb737263733ad80a36b4f73f681c30a6b45sd */
13faa91230bde46da937bf33010b9accc5bdeb59sd for (i = min; i <= max; i++) {
13faa91230bde46da937bf33010b9accc5bdeb59sd
13faa91230bde46da937bf33010b9accc5bdeb59sd /* Skip the processors with no serial number */
13faa91230bde46da937bf33010b9accc5bdeb59sd if ((procp = cpu_find_proc(chip, i)) == NULL) {
dd566498928f08e7c9a79797a40db893c6a4b9fbvn continue;
dd566498928f08e7c9a79797a40db893c6a4b9fbvn }
13faa91230bde46da937bf33010b9accc5bdeb59sd if (procp->serialno == 0) {
13faa91230bde46da937bf33010b9accc5bdeb59sd continue;
1557e65f9d0c6fde875d807c12fc03ea20f50280vn }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
1557e65f9d0c6fde875d807c12fc03ea20f50280vn (void) snprintf(sbuf, sizeof (sbuf), "%llx", procp->serialno);
13faa91230bde46da937bf33010b9accc5bdeb59sd topo_mod_dprintf(mod, "node chip[%d], sn=%s\n", i, sbuf);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
13faa91230bde46da937bf33010b9accc5bdeb59sd cnode = chip_tnode_create(mod, rnode, name, (topo_instance_t)i,
13faa91230bde46da937bf33010b9accc5bdeb59sd sbuf, fru, label, NULL);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (cnode == NULL) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_mod_dprintf(mod, "failed to create a chip node: "
1557e65f9d0c6fde875d807c12fc03ea20f50280vn "%s\n", topo_mod_errmsg(mod));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nerr++;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd continue;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd /* Enumerate all cpu strands of this CMP chip */
13faa91230bde46da937bf33010b9accc5bdeb59sd err = cpu_create(mod, cnode, CPU_NODE_NAME, chip,
13faa91230bde46da937bf33010b9accc5bdeb59sd procp->serialno);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (err != 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd nerr++;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien /* Enumerate all DIMMs belonging to this chip */
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien if (dimm_instantiate(cnode, CHIP, mod) < 0) {
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien topo_mod_dprintf(mod, "Enumeration of dimm "
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien "failed %s\n", topo_mod_errmsg(mod));
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien return (-1);
70818f5837509317d1f5dac4d82d7b5a2d547c29tsien }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd }
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (nerr != 0)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (0);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*ARGSUSED*/
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic int
14ea4bb737263733ad80a36b4f73f681c30a6b45sdchip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
14ea4bb737263733ad80a36b4f73f681c30a6b45sd topo_instance_t min, topo_instance_t max, void *arg, void *notused)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
dd566498928f08e7c9a79797a40db893c6a4b9fbvn md_info_t *chip = (md_info_t *)arg;
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd if (strcmp(name, CHIP_NODE_NAME) == 0)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (chip_create(mod, rnode, name, min, max, chip));
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd return (0);
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}
14ea4bb737263733ad80a36b4f73f681c30a6b45sd
14ea4bb737263733ad80a36b4f73f681c30a6b45sd/*ARGSUSED*/
14ea4bb737263733ad80a36b4f73f681c30a6b45sdstatic void
14ea4bb737263733ad80a36b4f73f681c30a6b45sdchip_release(topo_mod_t *mp, tnode_t *node)
14ea4bb737263733ad80a36b4f73f681c30a6b45sd{
14ea4bb737263733ad80a36b4f73f681c30a6b45sd}