summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorvn83148 <none@none>2007-02-19 20:47:33 -0800
committervn83148 <none@none>2007-02-19 20:47:33 -0800
commitdd566498928f08e7c9a79797a40db893c6a4b9fb (patch)
tree60c74a7043ebc3e743792e7151b6ba4ee960430a /usr/src
parentb577246e49ecc1edb9eb452aae13264729bacb51 (diff)
downloadillumos-gate-dd566498928f08e7c9a79797a40db893c6a4b9fb.tar.gz
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 --HG-- rename : usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c => usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c rename : usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h => usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fm/schemes/cpu/amd64/Makefile7
-rw-r--r--usr/src/cmd/fm/schemes/cpu/cpu.c100
-rw-r--r--usr/src/cmd/fm/schemes/cpu/i386/Makefile6
-rw-r--r--usr/src/cmd/fm/schemes/cpu/sparc/Makefile8
-rw-r--r--usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c232
-rw-r--r--usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h66
-rw-r--r--usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile7
-rw-r--r--usr/src/lib/fm/topo/libtopo/Makefile.com3
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/libtopo.h15
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/mkerror.sh23
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_error.h5
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_fmri.c11
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_method.h8
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_mod.h13
-rw-r--r--usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip4
-rw-r--r--usr/src/lib/fm/topo/modules/sun4u/chip/Makefile4
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/chip/Makefile15
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c330
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c43
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile4
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c348
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c356
-rw-r--r--usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h96
23 files changed, 811 insertions, 893 deletions
diff --git a/usr/src/cmd/fm/schemes/cpu/amd64/Makefile b/usr/src/cmd/fm/schemes/cpu/amd64/Makefile
index 320bdf8e60..257526a284 100644
--- a/usr/src/cmd/fm/schemes/cpu/amd64/Makefile
+++ b/usr/src/cmd/fm/schemes/cpu/amd64/Makefile
@@ -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"
@@ -30,7 +30,10 @@ include ../../Makefile.com
include $(SRC)/Makefile.master.64
SRCS = cpu.c
-LDFLAGS += -lkstat
+LDFLAGS += -lkstat \
+ -L$(ROOTLIB)/fm/$(MACH64) -ltopo
+LDFLAGS += -R/usr/lib/fm/$(MACH64)
+
include ../../Makefile.targ
diff --git a/usr/src/cmd/fm/schemes/cpu/cpu.c b/usr/src/cmd/fm/schemes/cpu/cpu.c
index 8bd3e85031..6f767a5d3e 100644
--- a/usr/src/cmd/fm/schemes/cpu/cpu.c
+++ b/usr/src/cmd/fm/schemes/cpu/cpu.c
@@ -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 @@ cpu_get_serialid_V1(uint32_t cpuid, char *serbuf, size_t len)
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 @@ cpu_get_serialid_V1(uint32_t cpuid, char *serbuf, size_t len)
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 @@ fmd_fmri_expand(nvlist_t *nvl)
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 @@ fmd_fmri_expand(nvlist_t *nvl)
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 @@ fmd_fmri_expand(nvlist_t *nvl)
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 @@ fmd_fmri_present(nvlist_t *nvl)
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 @@ fmd_fmri_present(nvlist_t *nvl)
int
fmd_fmri_unusable(nvlist_t *nvl)
{
+ int rc, err;
uint8_t version;
uint32_t cpuid;
@@ -308,30 +278,12 @@ fmd_fmri_unusable(nvlist_t *nvl)
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);
+ /*
+ * 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);
- return (cpustatus == P_FAULTED || (cpustatus == P_OFFLINE &&
- ldom_major_version(cpu_scheme_lhp) == 1));
- }
-#else
return (p_online(cpuid, P_STATUS) == P_FAULTED);
-#endif
-}
-
-#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));
-}
-
-void
-fmd_fmri_fini(void)
-{
- cpu_mdesc_fini();
- ldom_fini(cpu_scheme_lhp);
}
-#endif /* sparc */
diff --git a/usr/src/cmd/fm/schemes/cpu/i386/Makefile b/usr/src/cmd/fm/schemes/cpu/i386/Makefile
index e592391fad..59a8be49ae 100644
--- a/usr/src/cmd/fm/schemes/cpu/i386/Makefile
+++ b/usr/src/cmd/fm/schemes/cpu/i386/Makefile
@@ -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,7 +29,9 @@
include ../../Makefile.com
SRCS = cpu.c
-LDLIBS += -lkstat
+LDLIBS += -lkstat \
+ -L$(ROOTLIB)/fm -ltopo
+LDFLAGS += -R/usr/lib/fm
include ../../Makefile.targ
diff --git a/usr/src/cmd/fm/schemes/cpu/sparc/Makefile b/usr/src/cmd/fm/schemes/cpu/sparc/Makefile
index b7a4c88f7a..faa1f86434 100644
--- a/usr/src/cmd/fm/schemes/cpu/sparc/Makefile
+++ b/usr/src/cmd/fm/schemes/cpu/sparc/Makefile
@@ -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,10 @@
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
diff --git a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c b/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c
deleted file mode 100644
index 8eb8b285e8..0000000000
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.c
+++ /dev/null
@@ -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));
- }
-}
diff --git a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h b/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h
deleted file mode 100644
index bca4fc4575..0000000000
--- a/usr/src/cmd/fm/schemes/cpu/sparc/cpu_mdesc.h
+++ /dev/null
@@ -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 */
diff --git a/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile b/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile
index 3d0bffa850..cfb2d7dc5e 100644
--- a/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile
+++ b/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile
@@ -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
diff --git a/usr/src/lib/fm/topo/libtopo/Makefile.com b/usr/src/lib/fm/topo/libtopo/Makefile.com
index b4c89f2556..f0abd475e3 100644
--- a/usr/src/lib/fm/topo/libtopo/Makefile.com
+++ b/usr/src/lib/fm/topo/libtopo/Makefile.com
@@ -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 @@ pics/%.o: ../$(MACH)/%.c
../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
diff --git a/usr/src/lib/fm/topo/libtopo/common/libtopo.h b/usr/src/lib/fm/topo/libtopo/common/libtopo.h
index 82d702b8be..be196cfa9f 100644
--- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h
+++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h
@@ -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 void topo_walk_fini(topo_walk_t *);
*/
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 @@ typedef enum topo_prop_errno {
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);
diff --git a/usr/src/lib/fm/topo/libtopo/common/mkerror.sh b/usr/src/lib/fm/topo/libtopo/common/mkerror.sh
index 583cb7f5f0..3a0e5672dc 100644
--- a/usr/src/lib/fm/topo/libtopo/common/mkerror.sh
+++ b/usr/src/lib/fm/topo/libtopo/common/mkerror.sh
@@ -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 @@ input="`cat`"
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 @@ echo "\
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 @@ topo_strerror(int err)
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];
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_error.h b/usr/src/lib/fm/topo/libtopo/common/topo_error.h
index 4b747397d2..ad264adbea 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_error.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_error.h
@@ -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 @@ typedef enum topo_errno {
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 */
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c
index 673046bb7a..fb01929752 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c
@@ -232,8 +232,8 @@ topo_fmri_contains(topo_hdl_t *thp, nvlist_t *fmri, nvlist_t *subfmri, int *err)
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 @@ topo_fmri_unusable(topo_hdl_t *thp, nvlist_t *fmri, int *err)
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
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_method.h b/usr/src/lib/fm/topo/libtopo/common/topo_method.h
index df004ccec4..b7953d0146 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_method.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.h
@@ -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 @@ extern "C" {
#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 @@ extern "C" {
#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 @@ extern "C" {
#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"
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
index 62d3f22b7b..e496094b6f 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h
@@ -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 @@ extern nvlist_t *topo_mod_auth(topo_mod_t *, tnode_t *);
#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"
diff --git a/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip b/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip
index a0b27630fd..b8bf7c87d9 100644
--- a/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip
+++ b/usr/src/lib/fm/topo/modules/sun4/chip/Makefile.chip
@@ -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
diff --git a/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile b/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile
index 14c7f030fa..ded8670afc 100644
--- a/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile
+++ b/usr/src/lib/fm/topo/modules/sun4u/chip/Makefile
@@ -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
diff --git a/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile b/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile
index d554b36890..f98a9ce166 100644
--- a/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile
+++ b/usr/src/lib/fm/topo/modules/sun4v/chip/Makefile
@@ -19,15 +19,26 @@
# 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 $<
diff --git a/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c
index 24381f6a86..ae1db76895 100644
--- a/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c
+++ b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c
@@ -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 @@ static const topo_pgroup_info_t chip_auth_pgroup = {
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 @@ _topo_init(topo_mod_t *mod)
void
_topo_fini(topo_mod_t *mod)
{
- chip_t *chip;
-
- chip = (chip_t *)topo_mod_getspecific(mod);
+ md_info_t *chip;
- if (chip->chip_serials != NULL)
- topo_mod_free(mod, chip->chip_serials,
- chip->chip_ncpus * sizeof (uint64_t));
+ 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);
-
}
static tnode_t *
@@ -171,17 +131,23 @@ chip_tnode_create(topo_mod_t *mod, tnode_t *parent,
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 @@ chip_tnode_create(topo_mod_t *mod, tnode_t *parent,
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 @@ cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask)
/*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 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip,
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 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip,
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 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip,
/*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 @@ chip_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
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 @@ chip_create(topo_mod_t *mod, tnode_t *rnode, const char *name,
* 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 @@ static int
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));
diff --git a/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c b/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c
index 1adeb04009..932ddabeb3 100644
--- a/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c
+++ b/usr/src/lib/fm/topo/modules/sun4v/motherboard/motherboard.c
@@ -119,8 +119,7 @@ mb_topo_free(void *data, size_t size)
}
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 @@ mb_get_pri_info(topo_mod_t *mod, ldom_hdl_t *lhp,
int nfrus, num_nodes, i;
char *pstr = NULL;
char *sn, *pn, *dn, *csn;
+ ldom_hdl_t *lhp;
- (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN);
+ 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 @@ mb_get_pri_info(topo_mod_t *mod, ldom_hdl_t *lhp,
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 @@ mb_get_pri_info(topo_mod_t *mod, ldom_hdl_t *lhp,
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 @@ mb_get_pri_info(topo_mod_t *mod, ldom_hdl_t *lhp,
}
*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 @@ mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
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 @@ mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
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 @@ mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
topo_node_name(parent), topo_node_instance(parent),
name, i,
topo_strerror(topo_mod_errno(mod)));
+ nvlist_free(auth);
nvlist_free(fmri);
return (NULL);
}
diff --git a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile
index c18b4bf1b8..ca0a62b72b 100644
--- a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/Makefile
@@ -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 @@ MODULE = platform-cpu
ARCH = sun4v
CLASS = arch
-MODULESRCS = cpu.c
+MODULESRCS = cpu.c cpu_mdesc.c
include ../../Makefile.plugin
diff --git a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c
index 2cf44105e1..df7e3bb2be 100644
--- a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu.c
@@ -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 <sys/fm/ldom.h>
#include <fm/topo_mod.h>
+#include <sys/fm/ldom.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 @@ static const topo_modinfo_t cpu_info =
{ 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 @@ cpu_free(void *data, size_t size)
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,197 +122,159 @@ _topo_init(topo_mod_t *mod)
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;
+ /*
+ * 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));
+ }
- if (md_get_prop_val(mdp, listp[idx], "serial#",
- &mcmp->cpumap_serialno) < 0)
- mcmp->cpumap_serialno = 0;
+ /* Find the cpuid entry */
+ if ((mcmp = cpu_find_cpumap(chip, cpuid)) != NULL) {
+ present = nvlserid == mcmp->cpumap_serialno;
}
- topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes);
+ /* 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);
-
- /* 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);
- }
+ md_info_t *chip = (md_info_t *)topo_mod_getspecific(mod);
- /* 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));
+ 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));
+ }
- /* 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_free(mod, list1p, sizeof (mde_cookie_t) * nnode);
- topo_mod_free(mod, list2p, sizeof (mde_cookie_t) * 2*chip->chip_ncpus);
+ 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;
+
+ /* 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);
- /*
- * 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 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));
}
- cpu_free(bufp, (size_t)bufsiz);
- (void) md_fini(mdp);
- ldom_fini(lhp);
-
- return (rc);
+ return (0);
}
+
static nvlist_t *
cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *serial, uint8_t cpumask)
{
@@ -372,7 +332,7 @@ cpu_tnode_create(topo_mod_t *mod, tnode_t *parent,
/*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 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip)
/*
* 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 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, chip_t *chip)
/*
* 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 @@ cpu_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
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);
}
diff --git a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c
new file mode 100644
index 0000000000..c41e3aac76
--- /dev/null
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.c
@@ -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));
+ }
+}
diff --git a/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h
new file mode 100644
index 0000000000..e4feabdb09
--- /dev/null
+++ b/usr/src/lib/fm/topo/modules/sun4v/platform-cpu/cpu_mdesc.h
@@ -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 */