Mercurial > illumos > illumos-gate
changeset 3666:4c0bd30907d2
6519375 refactored the mdesc code in cpu scheme, platform-cpu.so and chip.so into a single code base
6520142 sun4v motherboard/chip enums leaking memory
6520501 libtopo exports a set of errors associated with node methods
line wrap: on
line diff
--- a/usr/src/cmd/fm/schemes/cpu/cpu.c Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/cmd/fm/schemes/cpu/cpu.c Fri Feb 16 09:49:34 2007 -0800 @@ -29,25 +29,16 @@ #include <sys/types.h> #include <sys/processor.h> #include <fm/fmd_fmri.h> +#include <fm/libtopo.h> #include <strings.h> #include <errno.h> #include <kstat.h> -#ifdef sparc -#include <cpu_mdesc.h> -#include <sys/fm/ldom.h> -#endif - /* * The scheme plugin for cpu FMRIs. */ -#ifdef sparc -cpu_t cpu; -static ldom_hdl_t *cpu_scheme_lhp; -#endif /* sparc */ - ssize_t fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { @@ -161,12 +152,7 @@ int err; uint64_t serial = 0; -#ifdef sparc - if (cpu.cpu_mdesc_cpus != NULL) - err = cpu_get_serialid_mdesc(cpuid, &serial); - else -#endif /* sparc */ - err = cpu_get_serialid_kstat(cpuid, &serial); + err = cpu_get_serialid_kstat(cpuid, &serial); (void) snprintf(serbuf, len, "%llX", (u_longlong_t)serial); return (err); @@ -175,12 +161,7 @@ static int cpu_get_serialid_V0(uint32_t cpuid, uint64_t *serialidp) { -#ifdef sparc - if (cpu.cpu_mdesc_cpus != NULL) - return (cpu_get_serialid_mdesc(cpuid, serialidp)); - else -#endif /* sparc */ - return (cpu_get_serialid_kstat(cpuid, serialidp)); + return (cpu_get_serialid_kstat(cpuid, serialidp)); } int @@ -190,12 +171,19 @@ uint32_t cpuid; uint64_t serialid; char *serstr, serbuf[21]; /* sizeof (UINT64_MAX) + '\0' */ - int rc; + int rc, err; if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); + /* + * If the cpu-scheme topology exports this method expand(), invoke it. + */ + rc = topo_fmri_expand(fmd_fmri_topology(TOPO_VERSION), nvl, &err); + if (err != ETOPO_METHOD_NOTSUP) + return (rc); + if (version == CPU_SCHEME_VERSION0) { if ((rc = nvlist_lookup_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, &serialid)) != 0) { @@ -209,32 +197,6 @@ serialid)) != 0) return (fmd_fmri_set_errno(rc)); } -#ifdef sparc - if (cpu.cpu_mdesc_cpus != NULL) { - md_cpumap_t *mcmp = cpu_find_cpumap(cpuid); - if (mcmp != NULL) { - if (strcmp(mcmp->cpumap_cpufrudn, "") == 0) { - (void) nvlist_add_string(nvl, - FM_FMRI_HC_PART, mcmp->cpumap_cpufrupn); - } else { - size_t ss = strlen(mcmp->cpumap_cpufrupn) + - strlen(mcmp->cpumap_cpufrudn) + 1; - char *sp = fmd_fmri_alloc(ss); - sp = strcpy(sp, mcmp->cpumap_cpufrupn); - sp = strncat(sp, mcmp->cpumap_cpufrudn, - strlen(mcmp->cpumap_cpufrudn) + 1); - (void) nvlist_add_string(nvl, - FM_FMRI_HC_PART, sp); - fmd_fmri_free(sp, ss); - } - (void) nvlist_add_string(nvl, - FM_FMRI_CPU_CPUFRU, mcmp->cpumap_cpufru); - nvl->nvl_nvflag = NV_UNIQUE_NAME_TYPE; - (void) nvlist_add_string(nvl, FM_FMRI_HC_SERIAL_ID, - mcmp->cpumap_cpufrusn); - } - } -#endif /* sparc */ } else if (version == CPU_SCHEME_VERSION1) { if ((rc = nvlist_lookup_string(nvl, FM_FMRI_CPU_SERIAL_ID, &serstr)) != 0) { @@ -258,7 +220,7 @@ int fmd_fmri_present(nvlist_t *nvl) { - int rc; + int rc, err; uint8_t version; uint32_t cpuid; uint64_t nvlserid, curserid; @@ -268,6 +230,13 @@ nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); + /* + * If the cpu-scheme topology exports this method present(), invoke it. + */ + rc = topo_fmri_present(fmd_fmri_topology(TOPO_VERSION), nvl, &err); + if (err != ETOPO_METHOD_NOTSUP) + return (rc); + if (version == CPU_SCHEME_VERSION0) { if (nvlist_lookup_uint64(nvl, FM_FMRI_CPU_SERIAL_ID, &nvlserid) != 0) @@ -300,6 +269,7 @@ int fmd_fmri_unusable(nvlist_t *nvl) { + int rc, err; uint8_t version; uint32_t cpuid; @@ -308,30 +278,12 @@ nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) != 0) return (fmd_fmri_set_errno(EINVAL)); -#ifdef sparc - { - int cpustatus = ldom_fmri_status(cpu_scheme_lhp, nvl); - - return (cpustatus == P_FAULTED || (cpustatus == P_OFFLINE && - ldom_major_version(cpu_scheme_lhp) == 1)); - } -#else - return (p_online(cpuid, P_STATUS) == P_FAULTED); -#endif -} + /* + * If the cpu-scheme topology exports this method unusable(), invoke it. + */ + rc = topo_fmri_unusable(fmd_fmri_topology(TOPO_VERSION), nvl, &err); + if (err != ETOPO_METHOD_NOTSUP) + return (rc); -#ifdef sparc -int -fmd_fmri_init(void) -{ - cpu_scheme_lhp = ldom_init(fmd_fmri_alloc, fmd_fmri_free); - return (cpu_mdesc_init(cpu_scheme_lhp)); + return (p_online(cpuid, P_STATUS) == P_FAULTED); } - -void -fmd_fmri_fini(void) -{ - cpu_mdesc_fini(); - ldom_fini(cpu_scheme_lhp); -} -#endif /* sparc */
--- a/usr/src/cmd/fm/schemes/cpu/sparc/Makefile Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/cmd/fm/schemes/cpu/sparc/Makefile Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -28,10 +28,9 @@ include ../../Makefile.com -SRCS = cpu.c cpu_mdesc.c +SRCS = cpu.c -CPPFLAGS += -I. -I$(ROOT)/usr/platform/sun4v/include -LDLIBS += -L$(ROOTLIB)/fm -lmdesc -lkstat -lldom +LDLIBS += -lkstat -L$(ROOTLIB)/fm -ltopo LDFLAGS += -R/usr/lib/fm include ../../Makefile.targ
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c Fri Feb 16 11:50:25 2007 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,232 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/processor.h> -#include <fm/fmd_fmri.h> -#include <sys/param.h> -#include <string.h> -#include <errno.h> -#include <cpu_mdesc.h> - -md_cpumap_t * -cpu_find_cpumap(uint32_t cpuid) { - int i; - md_cpumap_t *mcmp; - - for (i = 0, mcmp = cpu.cpu_mdesc_cpus; - i < cpu.cpu_mdesc_ncpus; i++, mcmp++) { - if (cpuid == mcmp->cpumap_pid) { - return (mcmp); - } - } - return (NULL); -} - -int -cpu_get_serialid_mdesc(uint32_t cpuid, uint64_t *serialidp) -{ - md_cpumap_t *mcmp; - if ((mcmp = cpu_find_cpumap(cpuid)) != NULL) { - *serialidp = mcmp->cpumap_serialno; - return (0); - } - return (fmd_fmri_set_errno(ENOENT)); -} - -int -cpu_mdesc_init(ldom_hdl_t *lhp) -{ - md_t *mdp; - mde_cookie_t *listp; - md_cpumap_t *mcmp; - uint64_t *bufp; - int num_nodes, idx; - ssize_t bufsiz = 0; - char *type, *cpufru, *cpufrusn, *cpufrupn, *cpufrudn; - int num_comps = 0; - uint64_t tl; - - if ((bufsiz = ldom_get_core_md(lhp, &bufp)) > 0) { - if ((mdp = md_init_intern(bufp, fmd_fmri_alloc, - fmd_fmri_free)) == NULL) { - fmd_fmri_free(bufp, (size_t)bufsiz); - return (0); - } - } else { - return (0); - } - - num_nodes = md_node_count(mdp); - listp = fmd_fmri_alloc(sizeof (mde_cookie_t) * num_nodes); - - num_comps = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, "component"), - md_find_name(mdp, "fwd"), - listp); - - if (num_comps == 0) { - cpu.cpu_mdesc_ncpus = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, "cpu"), - md_find_name(mdp, "fwd"), - listp); - - cpu.cpu_mdesc_cpus = fmd_fmri_alloc(cpu.cpu_mdesc_ncpus * - sizeof (md_cpumap_t)); - - for (idx = 0, mcmp = cpu.cpu_mdesc_cpus; - idx < cpu.cpu_mdesc_ncpus; - idx++, mcmp++) { - uint64_t tl; - - if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0) - tl = (uint64_t)-1; /* invalid value */ - mcmp->cpumap_id = tl; - - if (md_get_prop_val(mdp, listp[idx], "pid", &tl) < 0) - tl = mcmp->cpumap_id; - mcmp->cpumap_pid = tl; - - if (md_get_prop_val(mdp, listp[idx], "serial#", - &mcmp->cpumap_serialno) < 0) - mcmp->cpumap_serialno = 0; - - if (md_get_prop_str(mdp, listp[idx], "cpufru", - &cpufru) < 0) - cpufru = "mb"; - mcmp->cpumap_cpufru = fmd_fmri_strdup(cpufru); - - if (md_get_prop_str(mdp, listp[idx], "cpufru-serial#", - &cpufrusn) < 0) - cpufrusn = ""; - mcmp->cpumap_cpufrusn = fmd_fmri_strdup(cpufrusn); - - if (md_get_prop_str(mdp, listp[idx], "cpufru-part#", - &cpufrupn) < 0) - cpufrupn = ""; - mcmp->cpumap_cpufrupn = fmd_fmri_strdup(cpufrupn); - cpufrudn = ""; - mcmp->cpumap_cpufrudn = fmd_fmri_strdup(cpufrudn); - } - } else { - uint64_t procsn; - mde_cookie_t procnode = MDE_INVAL_ELEM_COOKIE; - - for (idx = 0; idx < num_comps; idx++) { - if (md_get_prop_str(mdp, listp[idx], "type", &type) < 0) - continue; - if (strcmp(type, "systemboard") == 0) { - cpufru = "MB"; - if (md_get_prop_str(mdp, listp[idx], "serial_number", - &cpufrusn) < 0) - cpufrusn = ""; - if (md_get_prop_str(mdp, listp[idx], "part_number", - &cpufrupn) < 0) - cpufrupn = ""; - if (md_get_prop_str(mdp, listp[idx], "dash_number", - &cpufrudn) < 0) - cpufrudn = ""; - break; - } - } - - for (idx = 0; idx < num_comps; idx++) { - if (md_get_prop_str(mdp, listp[idx], "type", &type) < 0) - continue; - if (strcmp(type, "processor") == 0) { - if (md_get_prop_val(mdp, listp[idx], "serial_number", - &procsn) < 0) - procsn = 0; - procnode = listp[idx]; - break; - } - } - - /* - * scan the procnode to find all strand nodes - */ - cpu.cpu_mdesc_ncpus = md_scan_dag(mdp, procnode, - md_find_name(mdp, "component"), - md_find_name(mdp, "fwd"), - listp); - - cpu.cpu_mdesc_cpus = fmd_fmri_alloc(cpu.cpu_mdesc_ncpus * - sizeof (md_cpumap_t)); - - mcmp = cpu.cpu_mdesc_cpus; - for (idx = 0; idx < cpu.cpu_mdesc_ncpus; idx++) { - if (md_get_prop_str(mdp, listp[idx], "type", &type) < 0) - continue; - if (strcmp(type, "strand") == 0) { - if (md_get_prop_val(mdp, listp[idx], "id", - &tl) < 0) - tl = (uint64_t)-1; - mcmp->cpumap_id = tl; - - mcmp->cpumap_pid = mcmp->cpumap_id; - - mcmp->cpumap_serialno = procsn; - mcmp->cpumap_cpufru = fmd_fmri_strdup(cpufru); - mcmp->cpumap_cpufrusn = - fmd_fmri_strdup(cpufrusn); - mcmp->cpumap_cpufrupn = - fmd_fmri_strdup(cpufrupn); - mcmp->cpumap_cpufrudn = - fmd_fmri_strdup(cpufrudn); - mcmp++; - } - } - - } - - fmd_fmri_free(listp, sizeof (mde_cookie_t) * num_nodes); - fmd_fmri_free(bufp, (size_t)bufsiz); - (void) md_fini(mdp); - - return (0); -} - -void -cpu_mdesc_fini(void) -{ - if (cpu.cpu_mdesc_cpus != NULL) { - int idx; - md_cpumap_t *mcmp; - for (idx = 0, mcmp = cpu.cpu_mdesc_cpus; - idx < cpu.cpu_mdesc_ncpus; - idx++, mcmp++) { - fmd_fmri_strfree(mcmp->cpumap_cpufru); - fmd_fmri_strfree(mcmp->cpumap_cpufrusn); - fmd_fmri_strfree(mcmp->cpumap_cpufrupn); - } - fmd_fmri_free(cpu.cpu_mdesc_cpus, - cpu.cpu_mdesc_ncpus * sizeof (md_cpumap_t)); - } -}
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h Fri Feb 16 11:50:25 2007 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _CPU_MDESC_H -#define _CPU_MDESC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/mdesc.h> -#include <sys/fm/ldom.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct md_cpumap { - uint32_t cpumap_id; - uint32_t cpumap_pid; - uint64_t cpumap_serialno; - char *cpumap_cpufru; - char *cpumap_cpufrusn; - char *cpumap_cpufrupn; - char *cpumap_cpufrudn; -} md_cpumap_t; - -typedef struct cpu { - md_cpumap_t *cpu_mdesc_cpus; /* ptr to array of cpu maps */ - uint32_t cpu_mdesc_ncpus; /* number of cpu maps */ -} cpu_t; - -extern cpu_t cpu; - -extern int cpu_get_serialid_mdesc(uint32_t, uint64_t *); -extern md_cpumap_t *cpu_find_cpumap(uint32_t); -extern int cpu_mdesc_init(ldom_hdl_t *lhp); -extern void cpu_mdesc_fini(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _CPU_MDESC_H */
--- a/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -29,10 +29,9 @@ include ../../Makefile.com include $(SRC)/Makefile.master.64 -SRCS = cpu.c cpu_mdesc.c -CPPFLAGS += -I../sparc -I$(ROOT)/usr/platform/sun4v/include +SRCS = cpu.c LDLIBS += -lkstat \ - -L$(ROOTLIB)/fm/$(MACH64) -lmdesc -lldom + -L$(ROOTLIB)/fm/$(MACH64) -ltopo LDFLAGS += -R/usr/lib/fm/$(MACH64) include ../../Makefile.targ
--- a/usr/src/lib/fm/topo/libtopo/Makefile.com Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/Makefile.com Fri Feb 16 09:49:34 2007 -0800 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -104,6 +104,7 @@ ../common/topo_error.c: ../common/mkerror.sh ../common/topo_error.h sh ../common/mkerror.sh liberrors < ../common/topo_error.h > $@ sh ../common/mkerror.sh properrors < ../common/libtopo.h >> $@ + sh ../common/mkerror.sh methoderrors < ../common/libtopo.h >> $@ sh ../common/mkerror.sh moderrors < ../common/topo_mod.h >> $@ include ../../../../Makefile.targ
--- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -122,6 +122,7 @@ */ extern int topo_fmri_present(topo_hdl_t *, nvlist_t *, int *); extern int topo_fmri_contains(topo_hdl_t *, nvlist_t *, nvlist_t *, int *); +extern int topo_fmri_expand(topo_hdl_t *, nvlist_t *, int *); extern int topo_fmri_unusable(topo_hdl_t *, nvlist_t *, int *); extern int topo_fmri_nvl2str(topo_hdl_t *, nvlist_t *, char **, int *); extern int topo_fmri_str2nvl(topo_hdl_t *, const char *, nvlist_t **, int *); @@ -250,6 +251,18 @@ ETOPO_PROP_END /* end of prop errno list (to ease auto-merge) */ } topo_prop_errno_t; +/* + * Similar to the above, this enum defines a set of errors associated with node + * methods. + */ +typedef enum topo_method_errno { + ETOPO_METHOD_UNKNOWN = 4000, /* unknown topo method error */ + ETOPO_METHOD_INVAL, /* invalid method registration */ + ETOPO_METHOD_NOTSUP, /* method not supported */ + ETOPO_METHOD_FAIL /* method failed */ +} topo_method_errno_t; + + extern const char *topo_strerror(int); extern void topo_debug_set(topo_hdl_t *, const char *, const char *); extern void *topo_hdl_alloc(topo_hdl_t *, size_t);
--- a/usr/src/lib/fm/topo/libtopo/common/mkerror.sh Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/mkerror.sh Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "@(#)mkerror.sh 1.1 06/02/11 SMI" @@ -34,7 +34,7 @@ if [ $1 = "liberrors" ] ; then echo "\ /*\n\ - * Copyright 2006 Sun Microsystems, Inc. All rights reserved.\n\ + * Copyright 2007 Sun Microsystems, Inc. All rights reserved.\n\ * Use is subject to license terms.\n\ */\n\ \n\ @@ -95,6 +95,22 @@ static const int _topo_nproperrstrs =\n\ sizeof (_topo_properrstrs) / sizeof (_topo_properrstrs[0]);" +elif [ $1 = "methoderrors" ] ; then + +echo "\ +\n\ +static const char *const _topo_methoderrstrs[] = {" + +pattern='^[ ]*ETOPO_METHOD_[A-Z0-9_]*.*\* \(.*\) \*.*' +replace=' "\1",' + +echo "$input" | sed -n "s/$pattern/$replace/p" || exit 1 + +echo "\ +};\n\ +\n\ +static const int _topo_nmethoderrstrs =\n\ + sizeof (_topo_methoderrstrs) / sizeof (_topo_methoderrstrs[0]);" else echo "\ @@ -144,6 +160,9 @@ else if (err >= ETOPO_PROP_UNKNOWN && (err - ETOPO_PROP_UNKNOWN) < _topo_nproperrstrs) s = _topo_properrstrs[err - ETOPO_PROP_UNKNOWN]; + else if (err >= ETOPO_METHOD_UNKNOWN && (err - ETOPO_METHOD_UNKNOWN) < + _topo_nmethoderrstrs) + s = _topo_methoderrstrs[err - ETOPO_METHOD_UNKNOWN]; else s = _topo_errstrs[0];
--- a/usr/src/lib/fm/topo/libtopo/common/topo_error.h Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/topo_error.h Fri Feb 16 09:49:34 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -85,9 +85,6 @@ ETOPO_FMRI_VERSION, /* invalid FMRI scheme version */ ETOPO_FMRI_MALFORM, /* malformed FMRI */ ETOPO_NVL_INVAL, /* invalid nvlist function argument */ - ETOPO_METHOD_INVAL, /* invalid method registration */ - ETOPO_METHOD_NOTSUP, /* method not supported */ - ETOPO_METHOD_FAIL, /* method failed */ ETOPO_FILE_NOENT, /* no topology file found */ ETOPO_PRSR_BADGRP, /* unrecognized grouping */ ETOPO_PRSR_BADNUM, /* unable to interpret attribute numerically */
--- a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c Fri Feb 16 09:49:34 2007 -0800 @@ -232,8 +232,8 @@ int topo_fmri_unusable(topo_hdl_t *thp, nvlist_t *fmri, int *err) { - int rc; char *scheme; + uint32_t unusable = 0; nvlist_t *out = NULL; tnode_t *rnode; @@ -245,11 +245,14 @@ return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_UNUSABLE, out)); - if ((rc = topo_method_invoke(rnode, TOPO_METH_UNUSABLE, - TOPO_METH_UNUSABLE_VERSION, fmri, &out, err)) < 0) + if (topo_method_invoke(rnode, TOPO_METH_UNUSABLE, + TOPO_METH_UNUSABLE_VERSION, fmri, &out, err) < 0) return (set_error(thp, *err, err, TOPO_METH_UNUSABLE, out)); - return (rc); + (void) nvlist_lookup_uint32(out, TOPO_METH_UNUSABLE_RET, &unusable); + nvlist_free(out); + + return (unusable); } int
--- a/usr/src/lib/fm/topo/libtopo/common/topo_method.h Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.h Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -42,8 +42,6 @@ #define TOPO_METH_NVL2STR "topo_nvl2str" #define TOPO_METH_STR2NVL "topo_str2nvl" #define TOPO_METH_CONTAINS "topo_contains" -#define TOPO_METH_UNUSABLE "topo_unusable" -#define TOPO_METH_EXPAND "topo_expand" #define TOPO_METH_COMPARE "topo_compare" #define TOPO_METH_FMRI_VERSION 0 @@ -52,8 +50,6 @@ #define TOPO_METH_NVL2STR_VERSION 0 #define TOPO_METH_STR2NVL_VERSION 0 #define TOPO_METH_CONTAINS_VERSION 0 -#define TOPO_METH_UNUSABLE_VERSION 0 -#define TOPO_METH_EXPAND_VERSION 0 #define TOPO_METH_COMPARE_VERSION 0 #define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor" @@ -62,8 +58,6 @@ #define TOPO_METH_NVL2STR_DESC "FMRI to string" #define TOPO_METH_STR2NVL_DESC "string to FMRI" #define TOPO_METH_CONTAINS_DESC "FMRI contains sub-FMRI" -#define TOPO_METH_UNUSABLE_DESC "FMRI is unusable" -#define TOPO_METH_EXPAND_DESC "expand FMRI" #define TOPO_METH_COMPARE_DESC "compare two FMRIs" #define TOPO_METH_FMRI_ARG_NAME "child-name"
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h Fri Feb 16 09:49:34 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -126,6 +126,17 @@ #define TOPO_METH_PRESENT_VERSION TOPO_METH_PRESENT_VERSION0 #define TOPO_METH_PRESENT_RET "present-ret" +#define TOPO_METH_UNUSABLE "topo_unusable" +#define TOPO_METH_UNUSABLE_DESC "FMRI is unusable" +#define TOPO_METH_UNUSABLE_VERSION0 0 +#define TOPO_METH_UNUSABLE_VERSION TOPO_METH_UNUSABLE_VERSION0 +#define TOPO_METH_UNUSABLE_RET "unusable-ret" + +#define TOPO_METH_EXPAND "topo_expand" +#define TOPO_METH_EXPAND_DESC "expand FMRI" +#define TOPO_METH_EXPAND_VERSION0 0 +#define TOPO_METH_EXPAND_VERSION TOPO_METH_EXPAND_VERSION0 + #define TOPO_METH_ASRU_COMPUTE "topo_asru_compute" #define TOPO_METH_ASRU_COMPUTE_VERSION 0 #define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor"
--- a/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip Fri Feb 16 09:49:34 2007 -0800 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -27,7 +27,7 @@ MODULE = chip CLASS = arch SUN4DIR = ../../sun4/$(MODULE) -MODULESRCS = chip_$(ARCH).c +MODULESRCS = $($(ARCH)_SRCS) include ../../Makefile.plugin
--- a/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile Fri Feb 16 09:49:34 2007 -0800 @@ -19,13 +19,15 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" ARCH = sun4u +sun4u_SRCS = chip_sun4u.c + include ../../sun4/chip/Makefile.chip LDLIBS += -lkstat
--- a/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile Fri Feb 16 09:49:34 2007 -0800 @@ -19,15 +19,27 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" ARCH = sun4v +PRIDIR=../platform-cpu -INCDIRS = $(ROOT)/usr/platform/sun4v/include +sun4v_SRCS = chip_sun4v.c cpu_mdesc.c + +INCDIRS = $(ROOT)/usr/platform/sun4v/include \ + $(PRIDIR) include ../../sun4/chip/Makefile.chip + LDLIBS += -lumem -lmdesc -lldom + +%.o: $(PRIDIR)/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +%.ln: $(PRIDIR)/%.c + $(LINT.c) -c $<
--- a/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c Fri Feb 16 09:49:34 2007 -0800 @@ -27,10 +27,9 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> +#include <stdlib.h> #include <strings.h> #include <sys/types.h> -#include <sys/mdesc.h> -#include <sys/fm/ldom.h> #include <fm/topo_mod.h> #include <sys/fm/protocol.h> @@ -40,7 +39,7 @@ #include <fcntl.h> #include <umem.h> -#include <stdlib.h> +#include <cpu_mdesc.h> /* @@ -53,32 +52,10 @@ #define CPU_NODE_NAME "cpu" #define CHIP_NODE_NAME "chip" -#define MD_STR_LEN 32 -#define MD_STR_CPU "cpu" -#define MD_STR_COMPONENT "component" -#define MD_STR_TYPE "type" -#define MD_STR_PROCESSOR "processor" -#define MD_STR_STRAND "strand" -#define MD_STR_SERIAL "serial_number" - -typedef struct md_cpumap { - uint32_t cpumap_id; /* virtual cpuid */ - uint32_t cpumap_pid; /* physical cpuid */ - uint64_t cpumap_serialno; /* cpu serial number */ -} md_cpumap_t; - -typedef struct chip { - uint64_t *chip_serials; /* List of cpu serial numbers */ - md_cpumap_t *chip_cpus; /* List of cpu maps */ - uint32_t chip_ncpus; /* size */ -} chip_t; - - /* Forward declaration */ static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t, void *, void *); static void chip_release(topo_mod_t *, tnode_t *); -static int cpu_mdesc_init(topo_mod_t *mod, chip_t *chip); static const topo_modops_t chip_ops = @@ -94,43 +71,33 @@ 1 }; -static void * -chip_alloc(size_t size) -{ - return (umem_alloc(size, UMEM_DEFAULT)); -} - -static void -chip_free(void *data, size_t size) -{ - umem_free(data, size); -} - int _topo_init(topo_mod_t *mod) { - chip_t *chip; + md_info_t *chip; if (getenv("TOPOCHIPDBG")) topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing chip enumerator\n"); - if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL) + if ((chip = topo_mod_zalloc(mod, sizeof (md_info_t))) == NULL) return (-1); if (cpu_mdesc_init(mod, chip) != 0) { topo_mod_dprintf(mod, "failed to get cpus from the PRI/MD\n"); - topo_mod_free(mod, chip, sizeof (chip_t)); + topo_mod_free(mod, chip, sizeof (md_info_t)); return (-1); } + topo_mod_setspecific(mod, (void *)chip); + if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register hc: " "%s\n", topo_mod_errmsg(mod)); - topo_mod_free(mod, chip, sizeof (chip_t)); + cpu_mdesc_fini(mod, chip); + topo_mod_free(mod, chip, sizeof (md_info_t)); return (-1); } - topo_mod_setspecific(mod, (void *)chip); topo_mod_dprintf(mod, "chip enumerator inited\n"); @@ -140,22 +107,15 @@ void _topo_fini(topo_mod_t *mod) { - chip_t *chip; + md_info_t *chip; - chip = (chip_t *)topo_mod_getspecific(mod); + chip = (md_info_t *)topo_mod_getspecific(mod); - if (chip->chip_serials != NULL) - topo_mod_free(mod, chip->chip_serials, - chip->chip_ncpus * sizeof (uint64_t)); + cpu_mdesc_fini(mod, chip); - if (chip->chip_cpus != NULL) - topo_mod_free(mod, chip->chip_cpus, - chip->chip_ncpus * sizeof (md_cpumap_t)); - - topo_mod_free(mod, chip, sizeof (chip_t)); + topo_mod_free(mod, chip, sizeof (md_info_t)); topo_mod_unregister(mod); - } static tnode_t * @@ -171,17 +131,23 @@ if (topo_mod_nvalloc(mod, &auth, NV_UNIQUE_NAME) == 0) { if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY, - FM_FMRI_AUTH_PRODUCT, &prod, &err) == 0) - (void) nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT, - prod); + FM_FMRI_AUTH_PRODUCT, &prod, &err) == 0) { + (void) nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT, + prod); + topo_mod_strfree(mod, prod); + } if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY, - FM_FMRI_AUTH_SERVER, &server, &err) == 0) + FM_FMRI_AUTH_SERVER, &server, &err) == 0) { (void) nvlist_add_string(auth, FM_FMRI_AUTH_SERVER, - server); + server); + topo_mod_strfree(mod, server); + } if (topo_prop_get_string(parent, FM_FMRI_AUTHORITY, - FM_FMRI_AUTH_CHASSIS, &csn, &err) == 0) + FM_FMRI_AUTH_CHASSIS, &csn, &err) == 0) { (void) nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, - csn); + csn); + topo_mod_strfree(mod, csn); + } } @@ -224,203 +190,6 @@ return (ntn); } -static int -cpu_n1_mdesc_init(topo_mod_t *mod, md_t *mdp, chip_t *chip) -{ - mde_cookie_t *listp; - md_cpumap_t *mcmp; - int i, num_nodes, idx; - - num_nodes = md_node_count(mdp); - listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes); - - chip->chip_ncpus = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, "cpu"), - md_find_name(mdp, "fwd"), - listp); - topo_mod_dprintf(mod, "Found %d cpus\n", chip->chip_ncpus); - - chip->chip_cpus = topo_mod_zalloc(mod, chip->chip_ncpus * - sizeof (md_cpumap_t)); - chip->chip_serials = topo_mod_zalloc(mod, chip->chip_ncpus * - sizeof (uint64_t)); - - for (idx = 0, mcmp = chip->chip_cpus; - idx < chip->chip_ncpus; - idx++, mcmp++) { - uint64_t tl; - - if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0) - tl = (uint64_t)-1; /* invalid value */ - mcmp->cpumap_id = tl; - - if (md_get_prop_val(mdp, listp[idx], "pid", &tl) < 0) - tl = mcmp->cpumap_id; - mcmp->cpumap_pid = tl; - - if (md_get_prop_val(mdp, listp[idx], "serial#", - &mcmp->cpumap_serialno) < 0) - mcmp->cpumap_serialno = 0; - - /* unique serial number */ - for (i = 0; i < chip->chip_ncpus && - chip->chip_serials[i] != 0; i++) { - if (mcmp->cpumap_serialno == chip->chip_serials[i]) { - break; - } - } - if (i < chip->chip_ncpus && chip->chip_serials[i] == 0) { - chip->chip_serials[i] = mcmp->cpumap_serialno; - topo_mod_dprintf(mod, "chip[%d] serial is %llx\n", i, - chip->chip_serials[i]); - } - } - - topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes); - - return (0); -} - -static int -cpu_n2_mdesc_init(topo_mod_t *mod, md_t *mdp, chip_t *chip) -{ - mde_cookie_t *list1p, *list2p; - md_cpumap_t *mcmp; - int i, j, cnt; - int nnode, ncomp, nproc, ncpu; - char *str = NULL; - uint64_t sn; - uint64_t tl; - - nnode = md_node_count(mdp); - list1p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * nnode); - - /* Count the number of processors and strands */ - ncomp = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, MD_STR_COMPONENT), - md_find_name(mdp, "fwd"), - list1p); - if (ncomp <= 0) { - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - return (-1); - } - for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) { - if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 && - str != NULL && strcmp(str, MD_STR_PROCESSOR) == 0) { - nproc++; - } - if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 && - str != NULL && strcmp(str, MD_STR_STRAND) == 0) { - ncpu++; - } - } - topo_mod_dprintf(mod, "Found %d procs and %d strands\n", nproc, ncpu); - if (ncpu <= 0 || nproc <= 0) { - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - return (-1); - } - - /* Alloc processor and strand entries */ - list2p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * 2 * ncpu); - chip->chip_ncpus = ncpu; - chip->chip_cpus = topo_mod_zalloc(mod, chip->chip_ncpus * - sizeof (md_cpumap_t)); - chip->chip_serials = topo_mod_zalloc(mod, chip->chip_ncpus * - sizeof (uint64_t)); - - /* Visit each processor node */ - mcmp = chip->chip_cpus; - for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) { - if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) < 0 || - str == NULL || strcmp(str, MD_STR_PROCESSOR)) - continue; - if (md_get_prop_val(mdp, list1p[i], MD_STR_SERIAL, &sn) < 0) { - topo_mod_dprintf(mod, - "Failed to get the serial number of proc[%d]", - nproc); - continue; - } - chip->chip_serials[nproc] = sn; - topo_mod_dprintf(mod, "proc %d : sn=%llx\n", nproc, sn); - nproc++; - - /* Get all the strands below this proc */ - cnt = md_scan_dag(mdp, - list1p[i], - md_find_name(mdp, MD_STR_COMPONENT), - md_find_name(mdp, "fwd"), - list2p); - if (cnt <= 0) { - continue; - } - for (j = 0; j < cnt && ncpu < chip->chip_ncpus; j++) { - /* Consider only the strand nodes */ - if (md_get_prop_str(mdp, list2p[j], MD_STR_TYPE, &str) - < 0 || str == NULL || strcmp(str, MD_STR_STRAND)) - continue; - - if (md_get_prop_val(mdp, list2p[j], "id", &tl) < 0) - tl = (uint64_t)-1; /* invalid value */ - mcmp->cpumap_id = tl; - - if (md_get_prop_val(mdp, list2p[j], "pid", &tl) < 0) - tl = mcmp->cpumap_id; - mcmp->cpumap_pid = tl; - - mcmp->cpumap_serialno = sn; - mcmp++; - ncpu++; - } - } - - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - topo_mod_free(mod, list2p, sizeof (mde_cookie_t) * 2*chip->chip_ncpus); - - return (0); -} - -static int -cpu_mdesc_init(topo_mod_t *mod, chip_t *chip) -{ - int rc; - md_t *mdp; - ssize_t bufsiz = 0; - uint64_t *bufp; - ldom_hdl_t *lhp; - - lhp = ldom_init(chip_alloc, chip_free); - if ((bufsiz = ldom_get_core_md(lhp, &bufp)) <= 0) { - return (-1); - } - - if ((mdp = md_init_intern(bufp, chip_alloc, chip_free)) == NULL || - md_node_count(mdp) <= 0) { - chip_free(bufp, (size_t)bufsiz); - ldom_fini(lhp); - return (-1); - } - - /* - * N1 MD contains cpu nodes while N2 MD contains component nodes - */ - if (md_find_name(mdp, MD_STR_COMPONENT) != MDE_INVAL_STR_COOKIE) { - rc = cpu_n2_mdesc_init(mod, mdp, chip); - } else if (md_find_name(mdp, MD_STR_CPU) != MDE_INVAL_STR_COOKIE) { - rc = cpu_n1_mdesc_init(mod, mdp, chip); - } else { - topo_mod_dprintf(mod, "Unsupported MD/PRI\n"); - rc = -1; - } - - chip_free(bufp, (size_t)bufsiz); - (void) md_fini(mdp); - ldom_fini(lhp); - - return (rc); -} - static nvlist_t * cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask) { @@ -446,7 +215,7 @@ /*ARGSUSED*/ static int -cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip, +cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, md_info_t *chip, int chipidx) { int i; @@ -458,20 +227,22 @@ char sbuf[32]; tnode_t *cnode; nvlist_t *asru; + md_cpumap_t *mcmp; + md_proc_t *procp; topo_mod_dprintf(mod, "enumerating cpus\n"); /* * find the min/max id of cpus per this cmp and create a cpu range */ - for (i = 0; i < chip->chip_ncpus; i++) { - if (chip->chip_cpus[i].cpumap_serialno != - chip->chip_serials[chipidx]) + procp = chip->procs + chipidx; + for (i = 0, mcmp = chip->cpus; i < chip->ncpus; i++, mcmp++) { + if (mcmp->cpumap_serialno != procp->serialno) continue; - if ((min < 0) || (chip->chip_cpus[i].cpumap_pid < min)) - min = chip->chip_cpus[i].cpumap_pid; - if ((max < 0) || (chip->chip_cpus[i].cpumap_pid > max)) - max = chip->chip_cpus[i].cpumap_pid; + if ((min < 0) || (mcmp->cpumap_pid < min)) + min = mcmp->cpumap_pid; + if ((max < 0) || (mcmp->cpumap_pid > max)) + max = mcmp->cpumap_pid; } if (min < 0 || max < 0) return (-1); @@ -482,21 +253,19 @@ return (-1); } - (void) snprintf(sbuf, sizeof (sbuf), "%llx", - chip->chip_serials[chipidx]); + (void) snprintf(sbuf, sizeof (sbuf), "%llx", procp->serialno); /* * Create the cpu[i] nodes of a given cmp chipidx */ - for (i = 0; i < chip->chip_ncpus; i++) { + for (i = 0, mcmp = chip->cpus; i < chip->ncpus; i++, mcmp++) { - if (chip->chip_cpus[i].cpumap_serialno != - chip->chip_serials[chipidx]) { + if (mcmp->cpumap_serialno != procp->serialno) { continue; } /* physical cpuid */ - pid = chip->chip_cpus[i].cpumap_pid; + pid = mcmp->cpumap_pid; cnode = chip_tnode_create(mod, rnode, name, (topo_instance_t)pid, sbuf, NULL, NULL, NULL); @@ -525,7 +294,7 @@ /*ARGSUSED*/ static int chip_create(topo_mod_t *mod, tnode_t *rnode, const char *name, - topo_instance_t min, topo_instance_t max, chip_t *chip) + topo_instance_t min, topo_instance_t max, md_info_t *chip) { int nerr = 0; int err; @@ -534,11 +303,13 @@ tnode_t *cnode; nvlist_t *fru = NULL; char *label = NULL; + md_proc_t *procp; topo_mod_dprintf(mod, "enumerating cmp chip\n"); - for (chipidx = 0; chipidx < chip->chip_ncpus && - chip->chip_serials[chipidx] != 0; chipidx++); + /* Create the range of chip nodes */ + for (chipidx = 0, procp = chip->procs; chipidx < chip->nprocs && + procp->serialno != 0; chipidx++, procp++); topo_node_range_destroy(rnode, name); if (topo_node_range_create(mod, rnode, name, 0, chipidx+1) < 0) { topo_mod_dprintf(mod, "failed to create chip range[0,%d]: %s\n", @@ -550,11 +321,14 @@ * Create the chip[i] nodes, one for each CMP chip uniquely identified * by the serial number. */ - for (chipidx = 0; chipidx < chip->chip_ncpus && - chip->chip_serials[chipidx] != 0; chipidx++) { + for (chipidx = 0, procp = chip->procs; chipidx < chip->nprocs; + chipidx++, procp++) { + if (procp->serialno == 0) { + continue; + } (void) snprintf(sbuf, sizeof (sbuf), "%llx", - chip->chip_serials[chipidx]); + procp->serialno); topo_mod_dprintf(mod, "enumerating chip [%s]\n", sbuf); @@ -586,7 +360,7 @@ chip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name, topo_instance_t min, topo_instance_t max, void *arg, void *notused) { - chip_t *chip = (chip_t *)arg; + md_info_t *chip = (md_info_t *)arg; if (strcmp(name, CHIP_NODE_NAME) == 0) return (chip_create(mod, rnode, name, min, max, chip));
--- a/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c Fri Feb 16 09:49:34 2007 -0800 @@ -119,8 +119,7 @@ } static int -mb_get_pri_info(topo_mod_t *mod, ldom_hdl_t *lhp, - char **serialp, char **partp, char **csnp) +mb_get_pri_info(topo_mod_t *mod, char **serialp, char **partp, char **csnp) { char isa[MAXNAMELEN]; md_t *mdp; @@ -130,26 +129,35 @@ int nfrus, num_nodes, i; char *pstr = NULL; char *sn, *pn, *dn, *csn; + ldom_hdl_t *lhp; + + lhp = ldom_init(mb_topo_alloc, mb_topo_free); + if (lhp == NULL) { + topo_mod_dprintf(mod, "ldom_init failed\n"); + return (-1); + } (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN); - if (strcmp(isa, "sun4v") != 0) { topo_mod_dprintf(mod, "not sun4v architecture%s\n", isa); + ldom_fini(lhp); return (-1); } if ((bufsize = ldom_get_core_md(lhp, &bufp)) < 1) { topo_mod_dprintf(mod, "ldom_get_core_md error, bufsize=%d\n", bufsize); + ldom_fini(lhp); return (-1); } topo_mod_dprintf(mod, "pri bufsize=%d\n", bufsize); if ((mdp = md_init_intern(bufp, mb_topo_alloc, mb_topo_free)) == NULL || (num_nodes = md_node_count(mdp)) < 1) { - mb_topo_free(bufp, bufsize); topo_mod_dprintf(mod, "md_init_intern error\n"); + mb_topo_free(bufp, (size_t)bufsize); + ldom_fini(lhp); return (-1); } topo_mod_dprintf(mod, "num_nodes=%d\n", num_nodes); @@ -157,6 +165,9 @@ if ((listp = (mde_cookie_t *)mb_topo_alloc( sizeof (mde_cookie_t) * num_nodes)) == NULL) { topo_mod_dprintf(mod, "alloc listp error\n"); + mb_topo_free(bufp, (size_t)bufsize); + (void) md_fini(mdp); + ldom_fini(lhp); return (-1); } @@ -165,6 +176,10 @@ md_find_name(mdp, "fwd"), listp); if (nfrus <= 0) { topo_mod_dprintf(mod, "error: nfrus=%d\n", nfrus); + mb_topo_free(listp, sizeof (mde_cookie_t) * num_nodes); + mb_topo_free(bufp, (size_t)bufsize); + (void) md_fini(mdp); + ldom_fini(lhp); return (-1); } topo_mod_dprintf(mod, "nfrus=%d\n", nfrus); @@ -192,17 +207,19 @@ } *serialp = topo_mod_strdup(mod, sn); - *partp = topo_mod_alloc(mod, (strlen(dn) - + strlen(pn) + 1)); - (void) strcpy(*partp, pn); - if (dn != NULL) - (void) strcat(*partp, dn); + + i = (pn ? strlen(pn) : 0) + (dn ? strlen(dn) : 0) + 1; + pstr = mb_topo_alloc(i); + (void) snprintf(pstr, i, "%s%s", pn ? pn : "", dn ? dn : ""); + *partp = topo_mod_strdup(mod, pstr); + mb_topo_free(pstr, i); *csnp = topo_mod_strdup(mod, csn); mb_topo_free(listp, sizeof (mde_cookie_t) * num_nodes); mb_topo_free(bufp, (size_t)bufsize); (void) md_fini(mdp); + ldom_fini(lhp); return (0); } @@ -249,13 +266,10 @@ tnode_t *ntn; char *serial = NULL, *part = NULL; char *csn = NULL, *pstr = NULL; - ldom_hdl_t *motherboard_lhp; nvlist_t *auth = topo_mod_auth(mod, parent); - motherboard_lhp = ldom_init(mb_topo_alloc, mb_topo_free); - /* Get Chassis ID, MB Serial Number and Part Number from PRI */ - (void) mb_get_pri_info(mod, motherboard_lhp, &serial, &part, &csn); + (void) mb_get_pri_info(mod, &serial, &part, &csn); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &pstr) != 0 && csn != NULL) @@ -267,12 +281,12 @@ topo_mod_strfree(mod, serial); topo_mod_strfree(mod, part); topo_mod_strfree(mod, csn); - ldom_fini(motherboard_lhp); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); + nvlist_free(auth); return (NULL); } @@ -283,6 +297,7 @@ topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); + nvlist_free(auth); nvlist_free(fmri); return (NULL); }
--- a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile Fri Feb 16 09:49:34 2007 -0800 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -28,7 +28,7 @@ ARCH = sun4v CLASS = arch -MODULESRCS = cpu.c +MODULESRCS = cpu.c cpu_mdesc.c include ../../Makefile.plugin
--- a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c Fri Feb 16 11:50:25 2007 -0800 +++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c Fri Feb 16 09:49:34 2007 -0800 @@ -26,49 +26,36 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include <stdio.h> #include <strings.h> #include <umem.h> -#include <sys/types.h> -#include <sys/mdesc.h> +#include <fm/topo_mod.h> #include <sys/fm/ldom.h> -#include <fm/topo_mod.h> #include <sys/fm/protocol.h> +#include <cpu_mdesc.h> + /* - * Enumerates the cpu strands in a system. For each strand found, the - * necessary cpu-schemed nodes are constructed underneath. + * This enumerator creates cpu-schemed nodes for each strand found in the + * sun4v Physical Rource Inventory (PRI). + * Each node export three methods present(), expand() and unusable(). + * */ #define PLATFORM_CPU_NAME "platform-cpu" #define PLATFORM_CPU_VERSION TOPO_VERSION #define CPU_NODE_NAME "cpu" -#define MD_STR_CPU "cpu" -#define MD_STR_COMPONENT "component" -#define MD_STR_TYPE "type" -#define MD_STR_PROCESSOR "processor" -#define MD_STR_STRAND "strand" -#define MD_STR_SERIAL "serial_number" - -typedef struct md_cpumap { - uint32_t cpumap_id; /* virtual cpuid */ - uint32_t cpumap_pid; /* physical cpuid */ - uint64_t cpumap_serialno; /* cpu serial number */ -} md_cpumap_t; - -typedef struct chip { - md_cpumap_t *chip_cpus; /* List of cpu maps */ - uint32_t chip_ncpus; /* size */ -} chip_t; - /* Forward declaration */ static int cpu_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t, void *, void *); static void cpu_release(topo_mod_t *, tnode_t *); -static int cpu_mdesc_init(topo_mod_t *mod, chip_t *chip); - +static int cpu_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, + nvlist_t **); +static int cpu_expand(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, + nvlist_t **); +static int cpu_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, + nvlist_t **); static const topo_modops_t cpu_ops = { cpu_enum, cpu_release }; @@ -76,6 +63,15 @@ { PLATFORM_CPU_NAME, FM_FMRI_SCHEME_CPU, PLATFORM_CPU_VERSION, &cpu_ops }; +static const topo_method_t cpu_methods[] = { + { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC, + TOPO_METH_PRESENT_VERSION, TOPO_STABILITY_INTERNAL, cpu_present }, + { TOPO_METH_EXPAND, TOPO_METH_EXPAND_DESC, + TOPO_METH_EXPAND_VERSION, TOPO_STABILITY_INTERNAL, cpu_expand }, + { TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC, + TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL, cpu_unusable }, + { NULL } +}; static void * cpu_alloc(size_t size) @@ -92,29 +88,31 @@ int _topo_init(topo_mod_t *mod) { - chip_t *chip; + md_info_t *chip; if (getenv("TOPOPLATFORMCPUDBG")) topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing %s enumerator\n", PLATFORM_CPU_NAME); - if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL) + if ((chip = topo_mod_zalloc(mod, sizeof (md_info_t))) == NULL) return (-1); if (cpu_mdesc_init(mod, chip) != 0) { topo_mod_dprintf(mod, "failed to get cpus from the PRI/MD\n"); - topo_mod_free(mod, chip, sizeof (chip_t)); + topo_mod_free(mod, chip, sizeof (md_info_t)); return (-1); } + topo_mod_setspecific(mod, (void *)chip); + if (topo_mod_register(mod, &cpu_info, TOPO_VERSION) != 0) { - topo_mod_dprintf(mod, "failed to register hc: " - "%s\n", topo_mod_errmsg(mod)); - topo_mod_free(mod, chip, sizeof (chip_t)); + topo_mod_dprintf(mod, "failed to register %s: %s\n", + PLATFORM_CPU_NAME, topo_mod_errmsg(mod)); + cpu_mdesc_fini(mod, chip); + topo_mod_free(mod, chip, sizeof (md_info_t)); return (-1); } - topo_mod_setspecific(mod, (void *)chip); topo_mod_dprintf(mod, "%s enumerator inited\n", PLATFORM_CPU_NAME); @@ -124,196 +122,158 @@ void _topo_fini(topo_mod_t *mod) { - chip_t *chip; + md_info_t *chip; - chip = (chip_t *)topo_mod_getspecific(mod); + chip = (md_info_t *)topo_mod_getspecific(mod); - if (chip->chip_cpus != NULL) - topo_mod_free(mod, chip->chip_cpus, - chip->chip_ncpus * sizeof (md_cpumap_t)); + cpu_mdesc_fini(mod, chip); - topo_mod_free(mod, chip, sizeof (chip_t)); + topo_mod_free(mod, chip, sizeof (md_info_t)); topo_mod_unregister(mod); } +/*ARGSUSED*/ static int -cpu_n1_mdesc_init(topo_mod_t *mod, md_t *mdp, chip_t *chip) +cpu_present(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) { - mde_cookie_t *listp; + uint8_t version; + uint32_t cpuid; + uint64_t nvlserid; + uint32_t present = 0; md_cpumap_t *mcmp; - int num_nodes, idx; - - num_nodes = md_node_count(mdp); - listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes); - - chip->chip_ncpus = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, "cpu"), - md_find_name(mdp, "fwd"), - listp); - topo_mod_dprintf(mod, "Found %d cpus\n", chip->chip_ncpus); + md_info_t *chip = (md_info_t *)topo_mod_getspecific(mod); - chip->chip_cpus = topo_mod_zalloc(mod, chip->chip_ncpus * - sizeof (md_cpumap_t)); - - for (idx = 0, mcmp = chip->chip_cpus; - idx < chip->chip_ncpus; - idx++, mcmp++) { - uint64_t tl; - - if (md_get_prop_val(mdp, listp[idx], "id", &tl) < 0) - tl = (uint64_t)-1; /* invalid value */ - mcmp->cpumap_id = tl; - - if (md_get_prop_val(mdp, listp[idx], "pid", &tl) < 0) - tl = mcmp->cpumap_id; - mcmp->cpumap_pid = tl; - - if (md_get_prop_val(mdp, listp[idx], "serial#", - &mcmp->cpumap_serialno) < 0) - mcmp->cpumap_serialno = 0; + /* + * Support only cpu scheme version 0 + */ + if (nvlist_lookup_uint8(in, FM_VERSION, &version) != 0 || + version > CPU_SCHEME_VERSION0 || + nvlist_lookup_uint32(in, FM_FMRI_CPU_ID, &cpuid) != 0 || + nvlist_lookup_uint64(in, FM_FMRI_CPU_SERIAL_ID, &nvlserid) != 0) { + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } - topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes); + /* Find the cpuid entry */ + if ((mcmp = cpu_find_cpumap(chip, cpuid)) != NULL) { + present = nvlserid == mcmp->cpumap_serialno; + } + + /* return the present status */ + if (topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) != 0) + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + if (nvlist_add_uint32(*out, TOPO_METH_PRESENT_RET, present) != 0) { + nvlist_free(*out); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } return (0); } +/*ARGSUSED*/ static int -cpu_n2_mdesc_init(topo_mod_t *mod, md_t *mdp, chip_t *chip) +cpu_expand(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) { - mde_cookie_t *list1p, *list2p; + int rc; + uint8_t version; + uint32_t cpuid; + uint64_t nvlserid; md_cpumap_t *mcmp; - int i, j; - int nnode, ncomp, nproc, ncpu; - char *str = NULL; - uint64_t sn; - - nnode = md_node_count(mdp); - list1p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * nnode); + md_info_t *chip = (md_info_t *)topo_mod_getspecific(mod); - /* Count the number of strands */ - ncomp = md_scan_dag(mdp, - MDE_INVAL_ELEM_COOKIE, - md_find_name(mdp, MD_STR_COMPONENT), - md_find_name(mdp, "fwd"), - list1p); - if (ncomp <= 0) { - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - return (-1); - } - for (i = 0, ncpu = 0; i < ncomp; i++) { - if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 && - str && strcmp(str, MD_STR_STRAND) == 0) { - ncpu++; - } - } - topo_mod_dprintf(mod, "Found %d strands\n", ncpu); - if (ncpu == 0) { - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - return (-1); + if (nvlist_lookup_uint8(in, FM_VERSION, &version) != 0 || + version > FM_CPU_SCHEME_VERSION || + nvlist_lookup_uint32(in, FM_FMRI_CPU_ID, &cpuid) != 0) { + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } - /* Alloc strand entries */ - list2p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * 2 * ncpu); - chip->chip_ncpus = ncpu; - chip->chip_cpus = topo_mod_zalloc(mod, ncpu * sizeof (md_cpumap_t)); - - /* Visit each processor node */ - mcmp = chip->chip_cpus; - for (i = 0, nproc = 0; i < ncomp; i++) { - if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) < 0 || - str == NULL || strcmp(str, MD_STR_PROCESSOR)) - continue; - if (md_get_prop_val(mdp, list1p[i], MD_STR_SERIAL, &sn) < 0) { - topo_mod_dprintf(mod, - "Failed to get the serial number of proc[%d]\n", - nproc); - continue; + if ((rc = nvlist_lookup_uint64(in, FM_FMRI_CPU_SERIAL_ID, + &nvlserid)) != 0) { + if (rc != ENOENT) { + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } - nproc++; - - /* Get all the strands below this proc */ - ncpu = md_scan_dag(mdp, - list1p[i], - md_find_name(mdp, MD_STR_COMPONENT), - md_find_name(mdp, "fwd"), - list2p); - topo_mod_dprintf(mod, "proc[%llx]: Found %d components\n", - sn, ncpu); - if (ncpu <= 0) { - continue; + /* Find the cpuid entry */ + if ((mcmp = cpu_find_cpumap(chip, cpuid)) == NULL) { + return (-1); } - for (j = 0; j < ncpu; j++) { - uint64_t tl; - - /* Consider only the strand nodes */ - if (md_get_prop_str(mdp, list2p[j], MD_STR_TYPE, &str) - < 0 || str == NULL || strcmp(str, MD_STR_STRAND)) - continue; - - if (md_get_prop_val(mdp, list2p[j], "id", &tl) < 0) - tl = (uint64_t)-1; /* invalid value */ - mcmp->cpumap_id = tl; - - if (md_get_prop_val(mdp, list2p[j], "pid", &tl) < 0) - tl = mcmp->cpumap_id; - mcmp->cpumap_pid = tl; - - mcmp->cpumap_serialno = sn; - mcmp++; + if ((rc = nvlist_add_uint64(in, FM_FMRI_CPU_SERIAL_ID, + mcmp->cpumap_serialno)) != 0) { + return (topo_mod_seterrno(mod, rc)); } } + topo_mod_dprintf(mod, "nvlserid=%llX\n", nvlserid); + if (mcmp != NULL && + mcmp->cpumap_chipidx >= 0 && + mcmp->cpumap_chipidx < chip->nprocs && + chip->procs && + chip->procs[mcmp->cpumap_chipidx].fru) { + int len; + char *str; + md_fru_t *frup = chip->procs[mcmp->cpumap_chipidx].fru; - topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); - topo_mod_free(mod, list2p, sizeof (mde_cookie_t) * 2*chip->chip_ncpus); + /* part number + dash number */ + len = (frup->part ? strlen(frup->part) : 0) + + (frup->dash ? strlen(frup->dash) : 0) + 1; + str = cpu_alloc(len); + (void) snprintf(str, len, "%s%s", + frup->part ? frup->part : MD_STR_BLANK, + frup->dash ? frup->dash : MD_STR_BLANK); + (void) nvlist_add_string(in, FM_FMRI_HC_PART, str); + cpu_free(str, len); + + /* fru name */ + (void) nvlist_add_string(in, FM_FMRI_CPU_CPUFRU, + frup->nac ? frup->nac : MD_STR_BLANK); + + /* fru serial */ + in->nvl_nvflag = NV_UNIQUE_NAME_TYPE; + (void) nvlist_add_string(in, FM_FMRI_HC_SERIAL_ID, + frup->serial ? frup->serial : MD_STR_BLANK); + } return (0); } +/*ARGSUSED*/ static int -cpu_mdesc_init(topo_mod_t *mod, chip_t *chip) +cpu_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) { int rc = -1; - md_t *mdp; - ssize_t bufsiz = 0; - uint64_t *bufp; + uint8_t version; + int status; + uint32_t cpuid; ldom_hdl_t *lhp; - /* get the PRI/MD */ - lhp = ldom_init(cpu_alloc, cpu_free); - if ((lhp == NULL) || (bufsiz = ldom_get_core_md(lhp, &bufp)) <= 0) { - topo_mod_dprintf(mod, "failed to get the PRI/MD\n"); - return (-1); + if (nvlist_lookup_uint8(in, FM_VERSION, &version) != 0 || + version > FM_CPU_SCHEME_VERSION || + nvlist_lookup_uint32(in, FM_FMRI_CPU_ID, &cpuid) != 0) { + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } - if ((mdp = md_init_intern(bufp, cpu_alloc, cpu_free)) == NULL || - md_node_count(mdp) <= 0) { - cpu_free(bufp, (size_t)bufsiz); - ldom_fini(lhp); - return (-1); + lhp = ldom_init(cpu_alloc, cpu_free); + if (lhp == NULL) { + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + status = ldom_fmri_status(lhp, in); + rc = (status == P_FAULTED || + (status == P_OFFLINE && ldom_major_version(lhp) == 1)); + ldom_fini(lhp); + + /* return the unusable status */ + if (topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) != 0) + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + if (nvlist_add_uint32(*out, TOPO_METH_UNUSABLE_RET, rc) != 0) { + nvlist_free(*out); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } - /* - * N1 MD contains cpu nodes while N2 MD contains component nodes. - */ - if (md_find_name(mdp, MD_STR_COMPONENT) != MDE_INVAL_STR_COOKIE) { - rc = cpu_n2_mdesc_init(mod, mdp, chip); - } else if (md_find_name(mdp, MD_STR_CPU) != MDE_INVAL_STR_COOKIE) { - rc = cpu_n1_mdesc_init(mod, mdp, chip); - } else { - topo_mod_dprintf(mod, "Unsupported PRI/MD\n"); - rc = -1; - } + return (0); +} - cpu_free(bufp, (size_t)bufsiz); - (void) md_fini(mdp); - ldom_fini(lhp); - - return (rc); -} static nvlist_t * cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask) @@ -372,7 +332,7 @@ /*ARGSUSED*/ static int -cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip) +cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, md_info_t *chip) { int i; int min = -1; @@ -387,11 +347,11 @@ /* * find the min/max id of cpus per this cmp and create a cpu range */ - for (i = 0; i < chip->chip_ncpus; i++) { - if ((min < 0) || (chip->chip_cpus[i].cpumap_pid < min)) - min = chip->chip_cpus[i].cpumap_pid; - if ((max < 0) || (chip->chip_cpus[i].cpumap_pid > max)) - max = chip->chip_cpus[i].cpumap_pid; + for (i = 0; i < chip->ncpus; i++) { + if ((min < 0) || (chip->cpus[i].cpumap_pid < min)) + min = chip->cpus[i].cpumap_pid; + if ((max < 0) || (chip->cpus[i].cpumap_pid > max)) + max = chip->cpus[i].cpumap_pid; } if (min < 0 || max < 0) return (-1); @@ -405,13 +365,13 @@ /* * Create the cpu nodes */ - for (i = 0; i < chip->chip_ncpus; i++) { + for (i = 0; i < chip->ncpus; i++) { (void) snprintf(sbuf, sizeof (sbuf), "%llx", - chip->chip_cpus[i].cpumap_serialno); + chip->cpus[i].cpumap_serialno); /* physical cpuid */ - pid = chip->chip_cpus[i].cpumap_pid; + pid = chip->cpus[i].cpumap_pid; cnode = cpu_tnode_create(mod, rnode, name, (topo_instance_t)pid, sbuf, NULL); if (cnode == NULL) { @@ -436,14 +396,22 @@ topo_instance_t min, topo_instance_t max, void *arg, void *notused) { topo_mod_dprintf(mod, "%s enumerating %s\n", PLATFORM_CPU_NAME, name); + + if (topo_method_register(mod, rnode, cpu_methods) < 0) { + topo_mod_dprintf(mod, "topo_method_register failed: %s\n", + topo_strerror(topo_mod_errno(mod))); + return (-1); + } + if (strcmp(name, CPU_NODE_NAME) == 0) - return (cpu_create(mod, rnode, name, (chip_t *)arg)); + return (cpu_create(mod, rnode, name, (md_info_t *)arg)); return (0); } /*ARGSUSED*/ static void -cpu_release(topo_mod_t *mp, tnode_t *node) +cpu_release(topo_mod_t *mod, tnode_t *node) { + topo_method_unregister_all(mod, node); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c Fri Feb 16 09:49:34 2007 -0800 @@ -0,0 +1,356 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <string.h> +#include <umem.h> +#include <sys/mdesc.h> +#include <sys/fm/ldom.h> + +#include <cpu_mdesc.h> + +static void * +cpu_alloc(size_t size) +{ + return (umem_alloc(size, UMEM_DEFAULT)); +} + +static void +cpu_free(void *data, size_t size) +{ + umem_free(data, size); +} + +md_cpumap_t * +cpu_find_cpumap(md_info_t *chip, uint32_t cpuid) { + int i; + md_cpumap_t *mcmp; + + for (i = 0, mcmp = chip->cpus; i < chip->ncpus; i++, mcmp++) { + if (cpuid == mcmp->cpumap_pid) { + return (mcmp); + } + } + return (NULL); +} + +int +cpu_get_serialid_mdesc(md_info_t *chip, uint32_t cpuid, uint64_t *serialidp) +{ + md_cpumap_t *mcmp; + if ((mcmp = cpu_find_cpumap(chip, cpuid)) != NULL) { + *serialidp = mcmp->cpumap_serialno; + return (0); + } + return (-1); +} + +static int +cpu_n1_mdesc_init(topo_mod_t *mod, md_t *mdp, md_info_t *chip) +{ + mde_cookie_t *listp; + md_cpumap_t *mcmp; + int i, num_nodes, idx; + uint64_t x; + + num_nodes = md_node_count(mdp); + listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes); + + chip->ncpus = md_scan_dag(mdp, + MDE_INVAL_ELEM_COOKIE, + md_find_name(mdp, "cpu"), + md_find_name(mdp, "fwd"), + listp); + topo_mod_dprintf(mod, "Found %d cpus\n", chip->ncpus); + + chip->cpus = topo_mod_zalloc(mod, chip->ncpus * sizeof (md_cpumap_t)); + chip->nprocs = chip->ncpus; + chip->procs = topo_mod_zalloc(mod, chip->nprocs * sizeof (md_proc_t)); + + for (idx = 0, mcmp = chip->cpus; idx < chip->ncpus; idx++, mcmp++) { + if (md_get_prop_val(mdp, listp[idx], MD_STR_ID, &x) < 0) + x = (uint64_t)-1; /* invalid value */ + mcmp->cpumap_id = x; + + if (md_get_prop_val(mdp, listp[idx], MD_STR_PID, &x) < 0) + x = mcmp->cpumap_id; + mcmp->cpumap_pid = x; + + if (md_get_prop_val(mdp, listp[idx], MD_STR_CPU_SERIAL, + &mcmp->cpumap_serialno) < 0) + mcmp->cpumap_serialno = 0; + + /* + * This PRI/MD has no indentity info. of the FRU. + * Find if there is already an existing processor entry + */ + for (i = 0; i < chip->nprocs && + chip->procs[i].serialno != 0; i++) { + if (mcmp->cpumap_serialno == chip->procs[i].serialno) { + break; + } + } + if (i < chip->nprocs) { + mcmp->cpumap_chipidx = i; + if (chip->procs[i].serialno == 0) { + chip->procs[i].serialno = mcmp->cpumap_serialno; + topo_mod_dprintf(mod, + "chip[%d] serial is %llx\n", + i, chip->procs[i].serialno); + } + } + + } + + topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes); + + return (0); +} + +static int +cpu_n2_mdesc_init(topo_mod_t *mod, md_t *mdp, md_info_t *chip) +{ + mde_cookie_t *list1p, *list2p; + md_cpumap_t *mcmp; + md_proc_t *procp; + md_fru_t *frup; + int i, j, cnt; + int nnode, ncomp, nproc, ncpu; + char *str = NULL; + uint64_t x, sn; + + nnode = md_node_count(mdp); + list1p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * nnode); + + /* Count the number of processors and strands */ + ncomp = md_scan_dag(mdp, + MDE_INVAL_ELEM_COOKIE, + md_find_name(mdp, MD_STR_COMPONENT), + md_find_name(mdp, "fwd"), + list1p); + if (ncomp <= 0) { + topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); + return (-1); + } + for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) { + if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 && + str != NULL && strcmp(str, MD_STR_PROCESSOR) == 0) { + nproc++; + } + if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 && + str && strcmp(str, MD_STR_STRAND) == 0) { + ncpu++; + } + } + topo_mod_dprintf(mod, "Found %d procs and %d strands\n", nproc, ncpu); + if (nproc == 0 || ncpu == 0) { + topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); + return (-1); + } + + /* Alloc processors and strand entries */ + list2p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * 2 * ncpu); + chip->nprocs = nproc; + chip->procs = topo_mod_zalloc(mod, nproc * sizeof (md_proc_t)); + chip->ncpus = ncpu; + chip->cpus = topo_mod_zalloc(mod, ncpu * sizeof (md_cpumap_t)); + + /* Visit each processor node */ + procp = chip->procs; + mcmp = chip->cpus; + for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) { + if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) < 0 || + str == NULL || strcmp(str, MD_STR_PROCESSOR)) + continue; + if (md_get_prop_val(mdp, list1p[i], MD_STR_SERIAL, &sn) < 0) { + topo_mod_dprintf(mod, + "Failed to get the serial number of proc[%d]\n", + nproc); + continue; + } + procp->serialno = sn; + topo_mod_dprintf(mod, "proc %d : sn=%llx\n", nproc, sn); + nproc++; + + /* Get all the strands below this proc */ + cnt = md_scan_dag(mdp, + list1p[i], + md_find_name(mdp, MD_STR_COMPONENT), + md_find_name(mdp, "fwd"), + list2p); + topo_mod_dprintf(mod, "proc[%llx]: Found %d fwd components\n", + sn, cnt); + if (cnt <= 0) { + procp++; + continue; + } + for (j = 0; j < cnt; j++) { + /* Consider only the strand nodes */ + if (md_get_prop_str(mdp, list2p[j], MD_STR_TYPE, &str) + < 0 || str == NULL || strcmp(str, MD_STR_STRAND)) + continue; + + ncpu++; + if (md_get_prop_val(mdp, list2p[j], MD_STR_ID, &x) < 0) + x = (uint64_t)-1; /* invalid value */ + mcmp->cpumap_id = x; + + if (md_get_prop_val(mdp, list2p[j], MD_STR_PID, &x) < 0) + x = mcmp->cpumap_id; + mcmp->cpumap_pid = x; + + mcmp->cpumap_serialno = sn; + mcmp->cpumap_chipidx = nproc - 1; + mcmp++; + } + + /* + * To get the fru of this proc, follow the back arc up to + * find the first node whose fru field is set + */ + cnt = md_scan_dag(mdp, + list1p[i], + md_find_name(mdp, MD_STR_COMPONENT), + md_find_name(mdp, "back"), + list2p); + topo_mod_dprintf(mod, "proc[%d]: Found %d back components\n", + nproc-1, cnt); + if (cnt <= 0) { + procp++; + continue; + } + for (j = 0; j < cnt; j++) { + /* test the fru field which must be positive number */ + if ((md_get_prop_val(mdp, list2p[j], MD_STR_FRU, &x) + == 0) && x > 0) + break; + } + if (j < cnt) { + /* Found the FRU node, get the fru identity */ + topo_mod_dprintf(mod, "proc[%d] sn=%llx has a fru %d\n", + nproc-1, procp->serialno, j); + frup = topo_mod_zalloc(mod, sizeof (md_fru_t)); + procp->fru = frup; + if (!md_get_prop_str(mdp, list2p[j], MD_STR_NAC, &str)) + frup->nac = topo_mod_strdup(mod, str); + else + frup->nac = topo_mod_strdup(mod, MD_FRU_DEF); + if (!md_get_prop_str(mdp, list2p[j], MD_STR_PART, &str)) + frup->part = topo_mod_strdup(mod, str); + if (!md_get_prop_str(mdp, list2p[j], MD_STR_SERIAL, + &str)) + frup->serial = topo_mod_strdup(mod, str); + if (!md_get_prop_str(mdp, list2p[j], MD_STR_DASH, &str)) + frup->dash = topo_mod_strdup(mod, str); + } else { + topo_mod_dprintf(mod, "proc[%d] sn=%llx has no fru\n", + i, procp->serialno); + } + procp++; + } /* for i */ + + topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode); + topo_mod_free(mod, list2p, sizeof (mde_cookie_t) * 2*chip->ncpus); + + return (0); +} + +/* + * Extract from the PRI the processor, strand and their fru identity + */ +int +cpu_mdesc_init(topo_mod_t *mod, md_info_t *chip) +{ + int rc = -1; + md_t *mdp; + ssize_t bufsiz = 0; + uint64_t *bufp; + ldom_hdl_t *lhp; + + /* get the PRI/MD */ + if ((lhp = ldom_init(cpu_alloc, cpu_free)) == NULL) { + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + if ((bufsiz = ldom_get_core_md(lhp, &bufp)) <= 0) { + topo_mod_dprintf(mod, "failed to get the PRI/MD\n"); + ldom_fini(lhp); + return (-1); + } + + if ((mdp = md_init_intern(bufp, cpu_alloc, cpu_free)) == NULL || + md_node_count(mdp) <= 0) { + cpu_free(bufp, (size_t)bufsiz); + ldom_fini(lhp); + return (-1); + } + + /* + * N1 MD contains cpu nodes while N2 MD contains component nodes. + */ + if (md_find_name(mdp, MD_STR_COMPONENT) != MDE_INVAL_STR_COOKIE) { + rc = cpu_n2_mdesc_init(mod, mdp, chip); + } else if (md_find_name(mdp, MD_STR_CPU) != MDE_INVAL_STR_COOKIE) { + rc = cpu_n1_mdesc_init(mod, mdp, chip); + } else { + topo_mod_dprintf(mod, "Unsupported PRI/MD\n"); + rc = -1; + } + + cpu_free(bufp, (size_t)bufsiz); + (void) md_fini(mdp); + ldom_fini(lhp); + + return (rc); +} + +void +cpu_mdesc_fini(topo_mod_t *mod, md_info_t *chip) +{ + int i; + md_proc_t *procp; + md_fru_t *frup; + + if (chip->cpus != NULL) + topo_mod_free(mod, chip->cpus, + chip->ncpus * sizeof (md_cpumap_t)); + + if (chip->procs != NULL) { + procp = chip->procs; + for (i = 0; i < chip->nprocs; i++) { + if ((frup = procp->fru) != NULL) { + topo_mod_strfree(mod, frup->nac); + topo_mod_strfree(mod, frup->serial); + topo_mod_strfree(mod, frup->part); + topo_mod_strfree(mod, frup->dash); + topo_mod_free(mod, frup, sizeof (md_fru_t)); + } + procp++; + } + topo_mod_free(mod, chip->procs, + chip->nprocs * sizeof (md_proc_t)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h Fri Feb 16 09:49:34 2007 -0800 @@ -0,0 +1,96 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _CPU_MDESC_H +#define _CPU_MDESC_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <fm/topo_mod.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Node/Field names in the PRI/MD + */ +#define MD_STR_ID "id" +#define MD_STR_PID "pid" +#define MD_STR_CPU_SERIAL "serial#" +#define MD_STR_CPU "cpu" +#define MD_STR_COMPONENT "component" +#define MD_STR_TYPE "type" +#define MD_STR_PROCESSOR "processor" +#define MD_STR_STRAND "strand" +#define MD_STR_FRU "fru" +#define MD_STR_NAC "nac" +#define MD_STR_SERIAL "serial_number" +#define MD_STR_PART "part_number" +#define MD_STR_DASH "dash_number" + +#define MD_FRU_DEF "MB" +#define MD_STR_BLANK "" + +typedef struct md_cpumap { + uint32_t cpumap_id; /* virtual cpuid */ + uint32_t cpumap_pid; /* physical cpuid */ + uint64_t cpumap_serialno; /* cpu serial number */ + int cpumap_chipidx; /* chip idx */ +} md_cpumap_t; + +typedef struct md_fru { + char *nac; /* FRU or nac */ + char *serial; /* FRU serial */ + char *part; /* FRU part number */ + char *dash; /* FRU dash */ +} md_fru_t; + +typedef struct md_proc { + uint64_t serialno; /* processor serial number */ + md_fru_t *fru; /* FRU info */ +} md_proc_t; + +typedef struct md_info { + md_proc_t *procs; /* list of processors */ + uint32_t nprocs; /* size */ + md_cpumap_t *cpus; /* List of cpu maps */ + uint32_t ncpus; /* size */ +} md_info_t; + + +extern int cpu_mdesc_init(topo_mod_t *mod, md_info_t *chip); +extern void cpu_mdesc_fini(topo_mod_t *mod, md_info_t *chip); + +extern int cpu_get_serialid_mdesc(md_info_t *chip, uint32_t cpuid, + uint64_t *serialno); +extern md_cpumap_t *cpu_find_cpumap(md_info_t *chip, uint32_t cpuid); + +#ifdef __cplusplus +} +#endif + +#endif /* _CPU_MDESC_H */