summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/cfgadm_plugins/ccid/common/cfga_ccid.c7
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c206
-rw-r--r--usr/src/lib/libcmdutils/common/nicenum.c10
-rw-r--r--usr/src/lib/libdemangle/common/demangle-sys.h3
-rw-r--r--usr/src/lib/libdemangle/common/demangle.c40
-rw-r--r--usr/src/lib/libdemangle/common/mapfile-vers2
6 files changed, 220 insertions, 48 deletions
diff --git a/usr/src/lib/cfgadm_plugins/ccid/common/cfga_ccid.c b/usr/src/lib/cfgadm_plugins/ccid/common/cfga_ccid.c
index 4ce28c2aec..3a44580306 100644
--- a/usr/src/lib/cfgadm_plugins/ccid/common/cfga_ccid.c
+++ b/usr/src/lib/cfgadm_plugins/ccid/common/cfga_ccid.c
@@ -376,10 +376,9 @@ cfga_list_ext(const char *ap, struct cfga_list_data **ap_list, int *nlist,
}
/*
- * XXX We should probably have a way to indicate that there's an error
- * when the ICC is basically foobar'd. We should also allow the status
- * ioctl to know that the slot is resetting or something else is going
- * on I guess.
+ * We should probably have a way to indicate that there's an error when
+ * the ICC is basically foobar'd. We should also allow the status ioctl
+ * to know that the slot is resetting or something else is going on.
*/
if ((ucs.ucs_class.ccd_dwFeatures &
(CCID_CLASS_F_SHORT_APDU_XCHG | CCID_CLASS_F_EXT_APDU_XCHG)) == 0) {
diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c
index 4c5da1e8cb..df6e2b6f95 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_intel.c
@@ -73,6 +73,8 @@
#define DIMM_HDRL "hdrl-enabled"
#define DIMM_HDRL_PARITY "hdrl-parity"
#define DIMM_3DRANK "3d-subranks"
+#define RANK_STATUS "dimm-rank-status"
+#define RANK_SIZE "dimm-rank-size"
static const topo_pgroup_info_t dimm_channel_pgroup =
{ PGNAME(CHAN), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
@@ -156,7 +158,7 @@ mc_add_ranks(topo_mod_t *mod, tnode_t *dnode, nvlist_t *auth, int dimm,
(void) topo_node_fru_set(rnode, NULL, 0, &err);
if (topo_method_register(mod, rnode, rank_methods) < 0)
- whinge(mod, &err, "rank_create: "
+ whinge(mod, &err, "mc_add_ranks: "
"topo_method_register failed");
if (! is_xpv() && topo_method_register(mod, rnode,
@@ -455,6 +457,102 @@ mc_nb_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
}
static int
+mc_rank_create_v1(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth,
+ nvlist_t *dimm_nvl, uint64_t rsize, uint32_t id)
+{
+ nvlist_t *fmri;
+ tnode_t *rank;
+ int err;
+ boolean_t *disabled;
+ uint_t ndisabled;
+ const char *status;
+
+ fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION, RANK, id,
+ NULL, auth, NULL, NULL, NULL);
+ if (fmri == NULL) {
+ whinge(mod, NULL, "mc_rank_create_v1: topo_mod_hcfmri "
+ "failed\n");
+ return (-1);
+ }
+
+ if ((rank = topo_node_bind(mod, pnode, RANK, id, fmri)) == NULL) {
+ whinge(mod, NULL, "mc_rank_create_v1: node bind failed for "
+ "DIMM\n");
+ nvlist_free(fmri);
+ return (-1);
+ }
+
+ if (topo_method_register(mod, rank, rank_methods) < 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: topo_method_register "
+ "failed for rank_methods: %d", topo_mod_errno(mod));
+ }
+
+ if (!is_xpv() && topo_method_register(mod, rank,
+ ntv_page_retire_methods) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: topo_method_register "
+ "failed for page retire: %d", topo_mod_errno(mod));
+ }
+
+ if (topo_node_asru_set(rank, fmri, TOPO_ASRU_COMPUTE, &err) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: failed to set asru: %d",
+ err);
+ nvlist_free(fmri);
+ return (topo_mod_seterrno(mod, err));
+ }
+
+ if (topo_node_fru_set(rank, NULL, 0, &err) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: fru set failed: "
+ "%d\n", err);
+ nvlist_free(fmri);
+ return (topo_mod_seterrno(mod, err));
+ }
+ nvlist_free(fmri);
+
+ if (topo_pgroup_create(rank, &rank_pgroup, &err) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: failed to create "
+ "property group: %d\n", err);
+ return (topo_mod_seterrno(mod, err));
+ }
+
+ /*
+ * The traditional northbridge driver broke down each rank into the
+ * interleave targets that led to it. At this time, the imc driver (the
+ * only v1 provider) does not supply that information and therefore we
+ * cannot set that. Instead we just set basic properties on this, the
+ * size of the rank and whether or not it is disabled.
+ */
+ if (rsize != 0 && topo_prop_set_uint64(rank, PGNAME(RANK), RANK_SIZE,
+ TOPO_PROP_IMMUTABLE, rsize, &err) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: failed to set %s "
+ "property: %d", RANK_SIZE, err);
+ return (topo_mod_seterrno(mod, err));
+ }
+
+ if (nvlist_lookup_boolean_array(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_RDIS,
+ &disabled, &ndisabled) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: Couldn't find disabled "
+ "ranks array");
+ return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
+ }
+
+ if (id >= ndisabled) {
+ whinge(mod, NULL, "mc_rank_create_v1: Found rank %u with id "
+ "larger than supported by hardware", id);
+ return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
+ }
+
+ status = disabled[id] ? "disabled" : "enabled";
+ if (topo_prop_set_string(rank, PGNAME(RANK), RANK_STATUS,
+ TOPO_PROP_IMMUTABLE, status, &err) != 0) {
+ whinge(mod, NULL, "mc_rank_create_v1: failed to set %s "
+ "property: %d", RANK_STATUS, err);
+ return (topo_mod_seterrno(mod, err));
+ }
+
+ return (0);
+}
+
+static int
mc_dimm_create_v1(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth,
nvlist_t *dimm_nvl, uint_t id)
{
@@ -462,8 +560,8 @@ mc_dimm_create_v1(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth,
tnode_t *dimm;
nvlist_t *fmri;
boolean_t present;
- uint64_t size, density;
- uint32_t cols, rows, width, ranks, banks;
+ uint64_t size, density, rsize;
+ uint32_t cols, rows, width, ranks, banks, i;
/*
* First, figure out if this DIMM is present. If not, we don't bother
@@ -510,8 +608,10 @@ mc_dimm_create_v1(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth,
&size) == 0) {
char buf[64];
const char *suffix;
+ uint64_t tsize;
ret |= topo_prop_set_uint64(dimm, PGNAME(DIMM), DIMM_SIZE,
TOPO_PROP_IMMUTABLE, size, &err);
+ tsize = size;
/*
* We must manually cons up a dimm-size property which is the
@@ -520,68 +620,115 @@ mc_dimm_create_v1(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth,
* controller drivers did this in the driver, but we instead opt
* to do so in user land.
*/
- if (size >= (1ULL << 40)) {
- size /= (1ULL << 40);
+ if (tsize >= (1ULL << 40)) {
+ tsize /= (1ULL << 40);
suffix = "T";
- } else if (size >= (1ULL << 30)) {
- size /= (1ULL << 30);
+ } else if (tsize >= (1ULL << 30)) {
+ tsize /= (1ULL << 30);
suffix = "G";
- } else if (size >= (1ULL << 20)) {
- size /= (1ULL << 20);
+ } else if (tsize >= (1ULL << 20)) {
+ tsize /= (1ULL << 20);
suffix = "M";
} else {
suffix = NULL;
}
if (suffix != NULL) {
- if (snprintf(buf, sizeof (buf), "%"PRIu64"%s", size,
+ if (snprintf(buf, sizeof (buf), "%"PRIu64"%s", tsize,
suffix) >= sizeof (buf)) {
whinge(mod, NULL, "failed to construct DIMM "
"size due to buffer overflow");
return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
}
- ret |= topo_prop_set_string(dimm, PGNAME(DIMM),
+ ret = topo_prop_set_string(dimm, PGNAME(DIMM),
DIMM_STRING_SIZE, TOPO_PROP_IMMUTABLE, buf, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
+ } else {
+ size = 0;
}
if (nvlist_lookup_uint32(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_NCOLS,
&cols) == 0) {
- ret |= topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_COL,
+ ret = topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_COL,
TOPO_PROP_IMMUTABLE, cols, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_uint32(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_NROWS,
&rows) == 0) {
- ret |= topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_ROW,
+ ret = topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_ROW,
TOPO_PROP_IMMUTABLE, rows, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_uint64(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_DENSITY,
&density) == 0) {
- ret |= topo_prop_set_uint64(dimm, PGNAME(DIMM), DIMM_DENSITY,
+ ret = topo_prop_set_uint64(dimm, PGNAME(DIMM), DIMM_DENSITY,
TOPO_PROP_IMMUTABLE, density, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_uint32(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_WIDTH,
&width) == 0) {
- ret |= topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_WIDTH,
+ ret = topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_WIDTH,
TOPO_PROP_IMMUTABLE, width, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_uint32(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_BANKS,
&banks) == 0) {
- ret |= topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_BANKS,
+ ret = topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_BANKS,
TOPO_PROP_IMMUTABLE, banks, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
+ } else {
+ banks = 0;
}
if (nvlist_lookup_uint32(dimm_nvl, MCINTEL_NVLIST_V1_DIMM_RANKS,
&ranks) == 0) {
- ret |= topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_RANKS,
+ ret = topo_prop_set_uint32(dimm, PGNAME(DIMM), DIMM_RANKS,
TOPO_PROP_IMMUTABLE, ranks, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
+ }
+
+ if (ret != 0) {
+ return (-1);
+ }
+
+ if (topo_node_range_create(mod, dimm, RANK, 0, ranks - 1) < 0) {
+ whinge(mod, NULL, "mc_dimm_create_v1: rank node range "
+ "create failed\n");
+ return (-1);
+ }
+
+ rsize = 0;
+ if (size != 0 && banks != 0) {
+ rsize = size / banks;
}
- return (ret != 0 ? -1 : 0);
+ for (i = 0; i < ranks; i++) {
+ if (mc_rank_create_v1(mod, dimm, auth, dimm_nvl, rsize, i) !=
+ 0) {
+ return (-1);
+ }
+ }
+
+ return (0);
}
static int
@@ -657,12 +804,12 @@ mc_imc_create_v1(topo_mod_t *mod, tnode_t *pnode, const char *name,
uint_t nchans, i;
if (mkrsrc(mod, pnode, name, id, auth, &fmri) != 0) {
- whinge(mod, NULL, "mc_nb_create_v1: mkrsrc failed\n");
+ whinge(mod, NULL, "mc_imc_create_v1: mkrsrc failed\n");
return (-1);
}
if ((mcnode = topo_node_bind(mod, pnode, name, id, fmri)) == NULL) {
- whinge(mod, NULL, "mc_nb_create_v1: node bind failed"
+ whinge(mod, NULL, "mc_imc_create_v1: node bind failed"
" for memory-controller\n");
nvlist_free(fmri);
return (-1);
@@ -670,13 +817,13 @@ mc_imc_create_v1(topo_mod_t *mod, tnode_t *pnode, const char *name,
nvlist_free(fmri);
if (topo_node_fru_set(mcnode, NULL, 0, &err) != 0) {
- whinge(mod, NULL, "mc_nb_create_v1: fru set failed: "
+ whinge(mod, NULL, "mc_imc_create_v1: fru set failed: "
"%d\n", err);
return (topo_mod_seterrno(mod, err));
}
if (topo_pgroup_create(mcnode, &mc_pgroup, &err) != 0) {
- whinge(mod, NULL, "mc_nb_create_v1: failed to create "
+ whinge(mod, NULL, "mc_imc_create_v1: failed to create "
"property group: %d\n", err);
return (topo_mod_seterrno(mod, err));
}
@@ -689,14 +836,20 @@ mc_imc_create_v1(topo_mod_t *mod, tnode_t *pnode, const char *name,
if (nvlist_lookup_boolean_value(mc_nvl, MCINTEL_NVLIST_V1_MC_ECC,
&ecc) == 0) {
const char *pval = ecc ? "enabled" : "disabled";
- ret |= topo_prop_set_string(mcnode, PGNAME(MCT), MC_PROP_ECC,
+ ret = topo_prop_set_string(mcnode, PGNAME(MCT), MC_PROP_ECC,
TOPO_PROP_IMMUTABLE, pval, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_string(mc_nvl, MCINTEL_NVLIST_V1_MC_POLICY,
&page) == 0) {
- ret |= topo_prop_set_string(mcnode, PGNAME(MCT), MC_PROP_POLICY,
+ ret = topo_prop_set_string(mcnode, PGNAME(MCT), MC_PROP_POLICY,
TOPO_PROP_IMMUTABLE, page, &err);
+ if (ret != 0) {
+ return (topo_mod_seterrno(mod, err));
+ }
}
if (nvlist_lookup_string(mc_nvl, MCINTEL_NVLIST_V1_MC_CHAN_MODE,
@@ -704,9 +857,6 @@ mc_imc_create_v1(topo_mod_t *mod, tnode_t *pnode, const char *name,
cmode = NULL;
}
- if (ret != 0)
- return (-1);
-
if (nvlist_lookup_nvlist_array(mc_nvl, MCINTEL_NVLIST_V1_MC_CHANNELS,
&channels, &nchans) != 0) {
whinge(mod, NULL, "mc_imc_create_v1: missing channels entry");
@@ -746,7 +896,7 @@ mc_nb_create_v1(topo_mod_t *mod, tnode_t *pnode, const char *name,
if (topo_node_range_create(mod, pnode, name, 0, nmc - 1) < 0) {
whinge(mod, NULL,
- "mc_nb_create: node range create failed\n");
+ "mc_nb_create_v1: node range create failed\n");
return (-1);
}
diff --git a/usr/src/lib/libcmdutils/common/nicenum.c b/usr/src/lib/libcmdutils/common/nicenum.c
index 9b9a8fcd5e..a9161c422c 100644
--- a/usr/src/lib/libcmdutils/common/nicenum.c
+++ b/usr/src/lib/libcmdutils/common/nicenum.c
@@ -45,13 +45,11 @@ nicenum_scale(uint64_t n, size_t units, char *buf, size_t buflen,
uint64_t divisor = 1;
int index = 0;
int rc = 0;
- int spclen = 0;
- char *spc = "";
+ const char *spc = "";
char u;
if (flags & NN_UNIT_SPACE) {
spc = " ";
- spclen = 1;
}
if (units == 0)
@@ -92,7 +90,7 @@ nicenum_scale(uint64_t n, size_t units, char *buf, size_t buflen,
u = " KMGTPE"[index];
if (index == 0) {
- rc = snprintf(buf, buflen, "%llu", n);
+ rc = snprintf(buf, buflen, "%llu%s", n, spc);
} else if (n % divisor == 0) {
/*
* If this is an even multiple of the base, always display
@@ -102,7 +100,7 @@ nicenum_scale(uint64_t n, size_t units, char *buf, size_t buflen,
} else {
/*
* We want to choose a precision that reflects the best choice
- * for fitting in 5 characters. This can get rather tricky
+ * for fitting in the buffer. This can get rather tricky
* when we have numbers that are very close to an order of
* magnitude. For example, when displaying 10239 (which is
* really 9.999K), we want only a single place of precision
@@ -113,7 +111,7 @@ nicenum_scale(uint64_t n, size_t units, char *buf, size_t buflen,
int i;
for (i = 2; i >= 0; i--) {
if ((rc = snprintf(buf, buflen, "%.*f%s%c", i,
- (double)n / divisor, spc, u)) <= 5 + spclen)
+ (double)n / divisor, spc, u)) <= (buflen - 1))
break;
}
}
diff --git a/usr/src/lib/libdemangle/common/demangle-sys.h b/usr/src/lib/libdemangle/common/demangle-sys.h
index 05776ee5ee..3452d39667 100644
--- a/usr/src/lib/libdemangle/common/demangle-sys.h
+++ b/usr/src/lib/libdemangle/common/demangle-sys.h
@@ -11,7 +11,7 @@
/*
* Copyright 2017 Jason King
- * Copyright 2018, Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
#ifndef _DEMANGLE_SYS_H
@@ -34,6 +34,7 @@ typedef struct sysdem_alloc_s {
void (*free)(void *, size_t);
} sysdem_ops_t;
+boolean_t sysdem_parse_lang(const char *, sysdem_lang_t *);
char *sysdemangle(const char *, sysdem_lang_t, sysdem_ops_t *);
#ifdef __cplusplus
diff --git a/usr/src/lib/libdemangle/common/demangle.c b/usr/src/lib/libdemangle/common/demangle.c
index 4f8e9ad678..b6db356416 100644
--- a/usr/src/lib/libdemangle/common/demangle.c
+++ b/usr/src/lib/libdemangle/common/demangle.c
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <sys/ctype.h>
#include <sys/debug.h>
+#include <sys/sysmacros.h>
#include <stdarg.h>
#include "demangle-sys.h"
#include "demangle_int.h"
@@ -31,19 +32,40 @@ static pthread_once_t debug_once = PTHREAD_ONCE_INIT;
volatile boolean_t demangle_debug;
FILE *debugf = stderr;
+static struct {
+ const char *str;
+ sysdem_lang_t lang;
+} lang_tbl[] = {
+ { "auto", SYSDEM_LANG_AUTO },
+ { "c++", SYSDEM_LANG_CPP },
+ { "rust", SYSDEM_LANG_RUST },
+};
+
static const char *
langstr(sysdem_lang_t lang)
{
- switch (lang) {
- case SYSDEM_LANG_AUTO:
- return ("auto");
- case SYSDEM_LANG_CPP:
- return ("c++");
- case SYSDEM_LANG_RUST:
- return ("rust");
- default:
- return ("invalid");
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(lang_tbl); i++) {
+ if (lang == lang_tbl[i].lang)
+ return (lang_tbl[i].str);
}
+ return ("invalid");
+}
+
+boolean_t
+sysdem_parse_lang(const char *str, sysdem_lang_t *langp)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(lang_tbl); i++) {
+ if (strcmp(str, lang_tbl[i].str) == 0) {
+ *langp = lang_tbl[i].lang;
+ return (B_TRUE);
+ }
+ }
+
+ return (B_FALSE);
}
static sysdem_lang_t
diff --git a/usr/src/lib/libdemangle/common/mapfile-vers b/usr/src/lib/libdemangle/common/mapfile-vers
index 48c11ef0d7..2207547185 100644
--- a/usr/src/lib/libdemangle/common/mapfile-vers
+++ b/usr/src/lib/libdemangle/common/mapfile-vers
@@ -11,6 +11,7 @@
#
# Copyright 2017 Jason King
+# Copyright 2019 Joyent, Inc.
#
#
@@ -30,6 +31,7 @@ $mapfile_version 2
SYMBOL_VERSION ILLUMOSprivate {
global:
+ sysdem_parse_lang;
sysdemangle;
local:
*;