예제 #1
0
static int
amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
    nvlist_t *auth)
{
	tnode_t *chnode;
	nvlist_t *fmri;
	char *socket;
	int i, nchan;
	nvlist_t *pfmri = NULL;
	int err, nerr = 0;

	/*
	 * We will enumerate the number of channels present even if only
	 * channel A is in use (i.e., running in 64-bit mode).  Only
	 * the socket 754 package has a single channel.
	 */
	if (topo_prop_get_string(pnode, PGNAME(MCT), "socket",
	    &socket, &err) == 0 && strcmp(socket, "Socket 754") == 0)
		nchan = 1;
	else
		nchan = 2;

	topo_mod_strfree(mod, socket);

	if (topo_node_range_create(mod, pnode, name, 0, nchan - 1) < 0)
		return (-1);

	(void) topo_node_fru(pnode, &pfmri, NULL, &err);

	for (i = 0; i < nchan; i++) {
		if (mkrsrc(mod, pnode, name, i, auth, &fmri) != 0) {
			whinge(mod, &nerr, "amd_dramchan_create: mkrsrc "
			    "failed\n");
			continue;
		}

		if ((chnode = topo_node_bind(mod, pnode, name, i, fmri))
		    == NULL) {
			nvlist_free(fmri);
			whinge(mod, &nerr, "amd_dramchan_create: node bind "
			    "failed\n");
			continue;
		}

		(void) topo_node_asru_set(chnode, fmri, 0, &err);
		if (pfmri)
			(void) topo_node_fru_set(chnode, pfmri, 0, &err);

		nvlist_free(fmri);

		(void) topo_pgroup_create(chnode, &chan_pgroup, &err);

		(void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel",
		    TOPO_PROP_IMMUTABLE, i == 0 ? "A" : "B", &err);
	}
	nvlist_free(pfmri);

	return (nerr == 0 ? 0 : -1);
}
예제 #2
0
static int
amd_cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc,
    nvlist_t *auth)
{
	int i, err, nerr = 0;
	nvpair_t *nvp;
	tnode_t *csnode;
	nvlist_t *fmri, **csarr = NULL;
	uint64_t csnum;
	uint_t ncs;

	if (nvlist_lookup_nvlist_array(mc, "cslist", &csarr, &ncs) != 0)
		return (-1);

	if (ncs == 0)
		return (0);	/* no chip-selects configured on this node */

	if (topo_node_range_create(mod, pnode, name, 0, MAX_CSNUM) < 0)
		return (-1);

	for (i = 0; i < ncs; i++) {
		if (nvlist_lookup_uint64(csarr[i], "num", &csnum) != 0) {
			whinge(mod, &nerr, "amd_cs_create: cs num property "
			    "missing\n");
			continue;
		}

		if (mkrsrc(mod, pnode, name, csnum, auth, &fmri) != 0) {
			whinge(mod, &nerr, "amd_cs_create: mkrsrc failed\n");
			continue;
		}

		if ((csnode = topo_node_bind(mod, pnode, name, csnum, fmri))
		    == NULL) {
			nvlist_free(fmri);
			whinge(mod, &nerr, "amd_cs_create: node bind failed\n");
			continue;
		}

		cs_fmri[csnum] = fmri;	/* nvlist will be freed in mc_create */

		(void) topo_node_asru_set(csnode, fmri, 0, &err);

		(void) topo_node_fru_set(csnode, fmri, 0, &err);

		(void) topo_pgroup_create(csnode, &cs_pgroup, &err);

		for (nvp = nvlist_next_nvpair(csarr[i], NULL); nvp != NULL;
		    nvp = nvlist_next_nvpair(csarr[i], nvp)) {
			nerr += nvprop_add(mod, nvp, PGNAME(CS), csnode);
		}
	}

	return (nerr == 0 ? 0 : -1);
}
예제 #3
0
파일: ioboard.c 프로젝트: andreiw/polaris
static tnode_t *
iob_tnode_create(tnode_t *parent,
    const char *name, topo_instance_t i, void *priv, topo_mod_t *mod)
{
	topo_hdl_t *thp;
	nvlist_t *args, *fmri, *pfmri;
	tnode_t *ntn;
	int err;

	thp = topo_mod_handle(mod);

	if (topo_node_resource(parent, &pfmri, &err) < 0) {
		topo_mod_seterrno(mod, err);
		topo_mod_dprintf(mod,
		    "Unable to retrieve parent resource.\n");
		return (NULL);
	}
	if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) {
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		nvlist_free(pfmri);
		return (NULL);
	}
	err = nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri);
	if (err != 0) {
		nvlist_free(pfmri);
		nvlist_free(args);
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		return (NULL);
	}
	fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, i, args, &err);
	if (fmri == NULL) {
		topo_mod_dprintf(mod,
		    "Unable to make nvlist for %s bind.\n", name);
		return (NULL);
	}
	ntn = topo_node_bind(mod, parent, name, i, fmri, priv);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (NULL);
	}
	nvlist_free(fmri);
	if (topo_method_register(mod, ntn, Iob_methods) < 0) {
		topo_mod_dprintf(mod, "topo_method_register failed: %s\n",
		    topo_strerror(topo_mod_errno(mod)));
		topo_node_unbind(ntn);
		return (NULL);
	}
	return (ntn);
}
예제 #4
0
static tnode_t *
hb_tnode_create(topo_mod_t *mod, tnode_t *parent,
    const char *name, topo_instance_t i, void *priv)
{
	int err;
	nvlist_t *fmri;
	tnode_t *ntn;
	nvlist_t *auth = topo_mod_auth(mod, parent);

	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
	    NULL, auth, NULL, NULL, NULL);
	nvlist_free(auth);
	if (fmri == NULL) {
		topo_mod_dprintf(mod,
		    "Unable to make nvlist for %s bind: %s.\n",
		    name, topo_mod_errmsg(mod));
		return (NULL);
	}

	ntn = topo_node_bind(mod, parent, name, i, fmri);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (NULL);
	}
	nvlist_free(fmri);
	topo_node_setspecific(ntn, priv);

	if (topo_pgroup_create(ntn, &hb_auth_pgroup, &err) == 0) {
		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
		    FM_FMRI_AUTH_PRODUCT, &err);
		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
		    FM_FMRI_AUTH_PRODUCT_SN, &err);
		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
		    FM_FMRI_AUTH_CHASSIS, &err);
		(void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY,
		    FM_FMRI_AUTH_SERVER, &err);
	}

	if (topo_method_register(mod, ntn, Hb_methods) < 0) {
		topo_mod_dprintf(mod, "topo_method_register failed: %s\n",
		    topo_strerror(topo_mod_errno(mod)));
		topo_node_unbind(ntn);
		return (NULL);
	}
	return (ntn);
}
예제 #5
0
static tnode_t *
create_node(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth, char *name,
    topo_instance_t inst, uint16_t smbios_id)
{
	nvlist_t *fmri;
	tnode_t *cnode;

	if (mkrsrc(mod, pnode, name, inst, auth, &fmri) != 0) {
		whinge(mod, NULL, "create_node: mkrsrc failed\n");
		return (NULL);
	}

	if (FM_AWARE_SMBIOS(mod)) {
		id_t phys_cpu_smbid;
		int perr = 0;
		const char *serial = NULL;
		const char *part = NULL;
		const char *rev = NULL;

		phys_cpu_smbid = smbios_id;
		serial = chip_serial_smbios_get(mod, phys_cpu_smbid);
		part = chip_part_smbios_get(mod, phys_cpu_smbid);
		rev = chip_rev_smbios_get(mod, phys_cpu_smbid);

		perr += nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID,
		    serial);
		perr += nvlist_add_string(fmri, FM_FMRI_HC_PART,
		    part);
		perr += nvlist_add_string(fmri, FM_FMRI_HC_REVISION,
		    rev);

		if (perr != 0)
			whinge(mod, NULL,
			    "create_node: nvlist_add_string failed\n");

		topo_mod_strfree(mod, (char *)serial);
		topo_mod_strfree(mod, (char *)part);
		topo_mod_strfree(mod, (char *)rev);
	}

	cnode = topo_node_bind(mod, pnode, name, inst, fmri);

	nvlist_free(fmri);
	if (cnode == NULL) {
		whinge(mod, NULL, "create_node: node bind failed"
		    " for %s %d\n", name, (int)inst);
	}

	return (cnode);
}
예제 #6
0
static tnode_t *
niu_tnode_create(topo_mod_t *mod, tnode_t *parent,
    const char *name, topo_instance_t i, void *priv)
{
	int err;
	nvlist_t *fmri;
	tnode_t *ntn;
	nvlist_t *auth = topo_mod_auth(mod, parent);

	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i,
	    NULL, auth, NULL, NULL, NULL);
	nvlist_free(auth);

	if (fmri == NULL) {
		topo_mod_dprintf(mod,
		    "Unable to make nvlist for %s bind: %s.\n",
		    name, topo_mod_errmsg(mod));
		return (NULL);
	}

	ntn = topo_node_bind(mod, parent, name, i, fmri);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (NULL);
	}
	nvlist_free(fmri);
	topo_node_setspecific(ntn, priv);

	if (topo_pgroup_create(ntn, &io_pgroup, &err) == 0) {
		(void) devprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DEV, mod);
		(void) driverprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DRIVER,
		    mod);
		(void) moduleprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_MODULE,
		    mod);
	}
	return (ntn);
}
예제 #7
0
static tnode_t *
cpuboard_node_create(topo_mod_t *mp, tnode_t *parent, const char *name,
    int inst, void *priv)
{
	tnode_t *node;
	nvlist_t *fmri;
	nvlist_t *auth = topo_mod_auth(mp, parent);

	topo_mod_dprintf(mp, "cpuboard_node_create:\n");

	if (parent == NULL || inst < 0) {
		return (NULL);
	}

	/* Create FMRI */
	if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name,
	    inst, NULL, auth, NULL, NULL, NULL)) == NULL) {
		topo_mod_dprintf(mp, "create of tnode for %s failed: %s",
		    name, topo_strerror(topo_mod_errno(mp)));
		nvlist_free(auth);
		return (NULL);
	}
	nvlist_free(auth);

	/* Create and bind node  */
	node = topo_node_bind(mp, parent, name, inst, fmri);
	if (node == NULL) {
		nvlist_free(fmri);
		topo_mod_dprintf(mp, "unable to bind root complex: %s\n",
		    topo_strerror(topo_mod_errno(mp)));
		return (NULL); /* mod_errno already set */
	}

	nvlist_free(fmri);
	topo_node_setspecific(node, priv);

	return (node);
}
예제 #8
0
tnode_t *
x86pi_node_bind(topo_mod_t *mod, tnode_t *t_parent, x86pi_hcfmri_t *hcfmri,
    nvlist_t *fmri, int flag)
{
	int	result;
	tnode_t	*t_node;
	char	*f = "x86pi_node_bind";

	if (t_parent == NULL) {
		topo_mod_dprintf(mod,
		    "%s: NULL parent for %s node instance %d\n",
		    f, hcfmri->hc_name, hcfmri->instance);
		return (NULL);
	}

	/* Bind this node to the parent */
	t_node = topo_node_bind(mod, t_parent, hcfmri->hc_name,
	    hcfmri->instance, fmri);
	if (t_node == NULL) {
		topo_mod_dprintf(mod,
		    "%s: failed to bind %s node instance %d: %s\n",
		    f, hcfmri->hc_name, (uint32_t)hcfmri->instance,
		    topo_strerror(topo_mod_errno(mod)));
		return (NULL);
	}
	topo_mod_dprintf(mod, "%s: bound %s node instance %d type %s\n",
	    f, hcfmri->hc_name, hcfmri->instance, hcfmri->hc_name);

	/*
	 * We have bound the node.  Now decorate it with an appropriate
	 * FRU and label (which may be inherited from the parent).
	 */
	result = x86pi_set_frufmri(mod, hcfmri, t_parent, t_node, flag);
	if (result != 0) {
		/*
		 * Though we have failed to set the FRU FMRI we still continue.
		 * The module errno is set by the called routine, so we report
		 * the problem and move on.
		 */
		topo_mod_dprintf(mod,
		    "%s: failed to set FRU FMRI for %s node\n",
		    f, hcfmri->hc_name);
	}

	result = x86pi_set_label(mod, hcfmri->location, hcfmri->hc_name,
	    t_node);
	if (result != 0) {
		/*
		 * Though we have failed to set the label, we still continue.
		 * The module errno is set by the called routine, so we report
		 * the problem and move on.
		 */
		topo_mod_dprintf(mod, "%s: no label for %s node\n",
		    f, hcfmri->hc_name);
	}

	result = x86pi_set_auth(mod, hcfmri, t_parent, t_node);
	if (result != 0) {
		/*
		 * Though we have failed to set the authority, we still
		 * continue. The module errno is set by the called routine, so
		 * we report the problem and move on.
		 */
		topo_mod_dprintf(mod,
		    "%s: no authority information for %s node\n",
		    f, hcfmri->hc_name);
	}

	result = x86pi_set_system(mod, t_node);
	if (result != 0) {
		/*
		 * Though we have failed to set the system group, we still
		 * continue. The module errno is set by the called routine, so
		 * we report the problem and move on.
		 */
		topo_mod_dprintf(mod,
		    "%s: no system information for %s node\n",
		    f, hcfmri->hc_name);
	}

	return (t_node);
}
예제 #9
0
/* create the disk topo node */
static int
disk_tnode_create(topo_mod_t *mod, tnode_t *parent,
    dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval)
{
	int		len;
	nvlist_t	*fmri;
	tnode_t		*dtn;
	char		*part = NULL;
	nvlist_t	*auth;
	char		*mfg, *model, *firm, *serial;

	*rval = NULL;
	if (dnode != NULL) {
		mfg = topo_mod_clean_str(mod, dnode->ddn_mfg);
		model = topo_mod_clean_str(mod, dnode->ddn_model);
		firm = topo_mod_clean_str(mod, dnode->ddn_firm);
		serial = topo_mod_clean_str(mod, dnode->ddn_serial);
	} else {
		mfg = model = firm = serial = NULL;
	}

	/* form 'part=' of fmri as "<mfg>-<model>" */
	if (mfg != NULL && model != NULL) {
		len = strlen(mfg) + 1 + strlen(model) + 1;
		if ((part = topo_mod_alloc(mod, len)) != NULL)
			(void) snprintf(part, len, "%s-%s",
			    mfg, model);
	}

	auth = topo_mod_auth(mod, parent);
	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL,
	    auth, part ? part : model, firm, serial);
	nvlist_free(auth);

	topo_mod_strfree(mod, part);
	topo_mod_strfree(mod, mfg);
	topo_mod_strfree(mod, model);
	topo_mod_strfree(mod, firm);
	topo_mod_strfree(mod, serial);

	if (fmri == NULL) {
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "hcfmri (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		return (-1);
	}

	if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) {
		if (topo_mod_errno(mod) == EMOD_NODE_BOUND) {
			/*
			 * if disk 0 is already there then we're done
			 */
			nvlist_free(fmri);
			return (0);
		}
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "bind (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (-1);
	}
	nvlist_free(fmri);

	/* add the properties of the disk */
	if (disk_set_props(mod, parent, dtn, dnode) != 0) {
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "disk_set_props (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		topo_node_unbind(dtn);
		return (-1);
	}

	if (dnode->ddn_devid != NULL &&
	    disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) {
		topo_mod_dprintf(mod, "disk_tnode_create: failed to create "
		    "temperature sensor node on bay=%d/disk=0",
		    topo_node_instance(parent));
	}
	*rval = dtn;
	return (0);
}
예제 #10
0
void
amd_mc_create(topo_mod_t *mod,  uint16_t smbid, tnode_t *pnode,
    const char *name, nvlist_t *auth, int32_t procnodeid,
    int32_t procnodes_per_pkg, int family,
    int model, int *nerrp)
{
	tnode_t *mcnode;
	nvlist_t *rfmri, *fmri;
	nvpair_t *nvp;
	nvlist_t *mc = NULL;
	int i, err;
	int mcnum = procnodeid % procnodes_per_pkg;
	char *serial = NULL;
	char *part = NULL;
	char *rev = NULL;

	/*
	 * Return with no error for anything before AMD family 0xf - we
	 * won't generate even a generic memory topology for earlier
	 * families.
	 */
	if (family < 0xf)
		return;

	if (topo_node_lookup(pnode, name, mcnum) != NULL)
		return;

	if (FM_AWARE_SMBIOS(mod)) {
		(void) topo_node_resource(pnode, &rfmri, &err);
		(void) nvlist_lookup_string(rfmri, "serial", &serial);
		(void) nvlist_lookup_string(rfmri, "part", &part);
		(void) nvlist_lookup_string(rfmri, "revision", &rev);
	}

	if (mkrsrc(mod, pnode, name, mcnum, auth, &fmri) != 0) {
		if (FM_AWARE_SMBIOS(mod))
			nvlist_free(rfmri);
		whinge(mod, nerrp, "mc_create: mkrsrc failed\n");
		return;
	}

	if (FM_AWARE_SMBIOS(mod)) {
		(void) nvlist_add_string(fmri, "serial", serial);
		(void) nvlist_add_string(fmri, "part", part);
		(void) nvlist_add_string(fmri, "revision", rev);
		nvlist_free(rfmri);
	}

	if ((mcnode = topo_node_bind(mod, pnode, name, mcnum,
	    fmri)) == NULL) {
		nvlist_free(fmri);
		whinge(mod, nerrp, "mc_create: mc bind failed\n");
		return;
	}
	if (topo_node_fru_set(mcnode, NULL, 0, &err) < 0)
		whinge(mod, nerrp, "mc_create: topo_node_fru_set failed\n");

	if (FM_AWARE_SMBIOS(mod)) {
		if (topo_node_label_set(mcnode, NULL, &err) == -1)
			topo_mod_dprintf(mod, "Failed to set label\n");
	}

	nvlist_free(fmri);

	if (topo_pgroup_create(mcnode, &mc_pgroup, &err) < 0)
		whinge(mod, nerrp, "mc_create: topo_pgroup_create failed\n");

	if (topo_prop_set_int32(mcnode, PGNAME(MCT), MCT_PROCNODE_ID,
	    TOPO_PROP_IMMUTABLE, procnodeid, nerrp) != 0)
		whinge(mod, nerrp, "mc_create: topo_prop_set_int32 failed to"
		    "add node id\n");

	if ((mc = amd_lookup_by_mcid(mod, topo_node_instance(pnode))) == NULL) {
		/*
		 * If a memory-controller driver exists for this chip model
		 * it has not attached or has otherwise malfunctioned;
		 * alternatively no memory-controller driver exists for this
		 * (presumably newly-released) cpu model.  We fallback to
		 * creating a generic maximal topology.
		 */
		if (amd_generic_mc_create(mod, smbid, pnode, mcnode,
		    family, model, auth) != 0)
			whinge(mod, nerrp,
			    "mc_create: amd_generic_mc_create failed\n");
		return;
	}

	/*
	 * Add memory controller properties
	 */
	for (nvp = nvlist_next_nvpair(mc, NULL); nvp != NULL;
	    nvp = nvlist_next_nvpair(mc, nvp)) {
		char *name = nvpair_name(nvp);
		data_type_t type = nvpair_type(nvp);

		if (type == DATA_TYPE_NVLIST_ARRAY &&
		    (strcmp(name, "cslist") == 0 ||
		    strcmp(name, "dimmlist") == 0)) {
			continue;
		} else if (type == DATA_TYPE_UINT8 &&
		    strcmp(name, MC_NVLIST_VERSTR) == 0) {
			continue;
		} else if (type == DATA_TYPE_NVLIST &&
		    strcmp(name, "htconfig") == 0) {
			nvlist_t *htnvl;

			(void) nvpair_value_nvlist(nvp, &htnvl);
			if (amd_htconfig(mod, pnode, htnvl) != 0)
				whinge(mod, nerrp,
				    "mc_create: amd_htconfig failed\n");
		} else {
			if (nvprop_add(mod, nvp, PGNAME(MCT), mcnode) != 0)
				whinge(mod, nerrp,
				    "mc_create: nvprop_add failed\n");
		}
	}

	if (amd_dramchan_create(mod, mcnode, CHAN_NODE_NAME, auth) != 0 ||
	    amd_cs_create(mod, mcnode, CS_NODE_NAME, mc, auth) != 0 ||
	    amd_dimm_create(mod, smbid, mcnode, DIMM_NODE_NAME, mc, auth) != 0)
		whinge(mod, nerrp, "mc_create: create children failed\n");

	/*
	 * Free the fmris for the chip-selects allocated in amd_cs_create
	 */
	for (i = 0; i < MC_CHIP_NCS; i++) {
		if (cs_fmri[i] != NULL) {
			nvlist_free(cs_fmri[i]);
			cs_fmri[i] = NULL;
		}
	}

	nvlist_free(mc);
}
예제 #11
0
static int
amd_dimm_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode,
    const char *name, nvlist_t *mc, nvlist_t *auth)
{
	int i, err, nerr = 0;
	int perr = 0;
	nvpair_t *nvp;
	tnode_t *dimmnode;
	nvlist_t *fmri, **dimmarr = NULL;
	uint64_t num;
	uint_t ndimm;
	id_t smbid;
	const char *serial;
	const char *part;
	const char *rev;

	if (nvlist_lookup_nvlist_array(mc, "dimmlist", &dimmarr, &ndimm) != 0) {
		whinge(mod, NULL, "amd_dimm_create: dimmlist lookup failed\n");
		return (-1);
	}

	if (ndimm == 0)
		return (0);	/* no dimms present on this node */

	if (topo_node_range_create(mod, pnode, name, 0, MAX_DIMMNUM) < 0) {
		whinge(mod, NULL, "amd_dimm_create: range create failed\n");
		return (-1);
	}

	for (i = 0; i < ndimm; i++) {
		if (nvlist_lookup_uint64(dimmarr[i], "num", &num) != 0) {
			whinge(mod, &nerr, "amd_dimm_create: dimm num property "
			    "missing\n");
			continue;
		}

		if (mkrsrc(mod, pnode, name, num, auth, &fmri) < 0) {
			whinge(mod, &nerr, "amd_dimm_create: mkrsrc failed\n");
			continue;
		}
		if (FM_AWARE_SMBIOS(mod)) {
			smbid = memnode_to_smbiosid(mod, chip_smbid,
			    DIMM_NODE_NAME, i, NULL);
			serial = chip_serial_smbios_get(mod, smbid);
			part = chip_part_smbios_get(mod, smbid);
			rev = chip_rev_smbios_get(mod, smbid);
			perr += nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID,
			    serial);
			perr += nvlist_add_string(fmri, FM_FMRI_HC_PART,
			    part);
			perr += nvlist_add_string(fmri, FM_FMRI_HC_REVISION,
			    rev);

			if (perr != 0)
				whinge(mod, NULL, "amd_dimm_create:"
				    "nvlist_add_string failed\n");
		}

		if ((dimmnode = topo_node_bind(mod, pnode, name, num, fmri))
		    == NULL) {
			nvlist_free(fmri);
			whinge(mod, &nerr, "amd_dimm_create: node bind "
			    "failed\n");
			continue;
		}

		if (!FM_AWARE_SMBIOS(mod))
			if (topo_method_register(mod,
			    dimmnode, dimm_methods) < 0)
				whinge(mod, &nerr, "amd_dimm_create: "
				    "topo_method_register failed");

		(void) topo_pgroup_create(dimmnode, &dimm_pgroup, &err);

		if (FM_AWARE_SMBIOS(mod)) {
			char *label;

			nvlist_free(fmri);
			(void) topo_node_resource(dimmnode,
			    &fmri, &err);

			label = (char *)chip_label_smbios_get(mod,
			    pnode, smbid, NULL);
			if (topo_node_label_set(dimmnode, label,
			    &perr) == -1)
				topo_mod_dprintf(mod, "Failed"
				    "to set label\n");
			topo_mod_strfree(mod, label);

			(void) topo_prop_set_string(dimmnode, PGNAME(DIMM),
			    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE,
			    serial, &err);
			(void) topo_prop_set_string(dimmnode, PGNAME(DIMM),
			    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE,
			    part, &err);
			(void) topo_prop_set_string(dimmnode, PGNAME(DIMM),
			    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE,
			    rev, &err);
		}

		(void) topo_node_asru_set(dimmnode, fmri, 0, &err);
		(void) topo_node_fru_set(dimmnode, fmri, 0, &err);
		nvlist_free(fmri);

		for (nvp = nvlist_next_nvpair(dimmarr[i], NULL); nvp != NULL;
		    nvp = nvlist_next_nvpair(dimmarr[i], nvp)) {
			if (nvpair_type(nvp) == DATA_TYPE_UINT64_ARRAY &&
			    strcmp(nvpair_name(nvp), "csnums") == 0 ||
			    nvpair_type(nvp) == DATA_TYPE_STRING_ARRAY &&
			    strcmp(nvpair_name(nvp), "csnames") == 0)
				continue;	/* used in amd_rank_create() */

			nerr += nvprop_add(mod, nvp, PGNAME(DIMM), dimmnode);
		}

		nerr += amd_rank_create(mod, dimmnode, dimmarr[i], auth);
	}

	return (nerr == 0 ? 0 : -1);
}
예제 #12
0
int
amd_rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl,
    nvlist_t *auth)
{
	uint64_t *csnumarr;
	char **csnamearr;
	uint_t ncs, ncsname;
	tnode_t *ranknode;
	nvlist_t *fmri, *pfmri = NULL;
	uint64_t dsz, rsz;
	int nerr = 0;
	int err;
	int i;

	if (nvlist_lookup_uint64_array(dimmnvl, "csnums", &csnumarr,
	    &ncs) != 0 || nvlist_lookup_string_array(dimmnvl, "csnames",
	    &csnamearr, &ncsname) != 0 || ncs != ncsname) {
		whinge(mod, &nerr, "amd_rank_create: "
		    "csnums/csnames extraction failed\n");
		return (nerr);
	}

	if (topo_node_resource(pnode, &pfmri, &err) < 0) {
		whinge(mod, &nerr, "amd_rank_create: parent fmri lookup "
		    "failed\n");
		return (nerr);
	}

	if (topo_node_range_create(mod, pnode, RANK_NODE_NAME, 0, ncs) < 0) {
		whinge(mod, &nerr, "amd_rank_create: range create failed\n");
		nvlist_free(pfmri);
		return (nerr);
	}

	if (topo_prop_get_uint64(pnode, PGNAME(DIMM), "size", &dsz,
	    &err) == 0) {
		rsz = dsz / ncs;
	} else {
		whinge(mod, &nerr, "amd_rank_create: parent dimm has no "
		    "size\n");
		return (nerr);
	}

	for (i = 0; i < ncs; i++) {
		if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, auth, &fmri) < 0) {
			whinge(mod, &nerr, "amd_rank_create: mkrsrc failed\n");
			continue;
		}

		if ((ranknode = topo_node_bind(mod, pnode, RANK_NODE_NAME, i,
		    fmri)) == NULL) {
			nvlist_free(fmri);
			whinge(mod, &nerr, "amd_rank_create: node bind "
			    "failed\n");
			continue;
		}

		nvlist_free(fmri);
		if (FM_AWARE_SMBIOS(mod))
			(void) topo_node_fru_set(ranknode, NULL, 0, &err);
		else
			(void) topo_node_fru_set(ranknode, pfmri, 0, &err);

		/*
		 * If a rank is faulted the asru is the associated
		 * chip-select, but if a page within a rank is faulted
		 * the asru is just that page.  Hence the dual preconstructed
		 * and computed ASRU.
		 */
		if (topo_method_register(mod, ranknode, rank_methods) < 0)
			whinge(mod, &nerr, "amd_rank_create: "
			    "topo_method_register failed");

		if (! is_xpv() && topo_method_register(mod, ranknode,
		    ntv_page_retire_methods) < 0)
			whinge(mod, &nerr, "amd_rank_create: "
			    "topo_method_register failed");

		(void) topo_node_asru_set(ranknode, cs_fmri[csnumarr[i]],
		    TOPO_ASRU_COMPUTE, &err);

		(void) topo_pgroup_create(ranknode, &rank_pgroup, &err);

		(void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "size",
		    TOPO_PROP_IMMUTABLE, rsz, &err);

		(void) topo_prop_set_string(ranknode, PGNAME(RANK), "csname",
		    TOPO_PROP_IMMUTABLE, csnamearr[i], &err);

		(void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "csnum",
		    TOPO_PROP_IMMUTABLE, csnumarr[i], &err);
	}

	nvlist_free(pfmri);

	return (nerr);
}
예제 #13
0
/*ARGSUSED*/
static int
amd_generic_mc_create(topo_mod_t *mod, uint16_t smbid, tnode_t *cnode,
    tnode_t *mcnode, int family, int model, nvlist_t *auth)
{
	int chan, cs;

	/*
	 * Elsewhere we have already returned for families less than 0xf.
	 * This "generic" topology is adequate for all of family 0xf and
	 * for revisions A to E of family 0x10 (for the list of models
	 * in each revision, refer to usr/src/uts/i86pc/os/cpuid_subr.c).
	 * We cover all family 0x10 models, till model 10.
	 */
	if (family > 0x10 || (family == 0x10 && model > 10))
		return (1);

	if (topo_node_range_create(mod, mcnode, CHAN_NODE_NAME, 0,
	    MAX_CHANNUM) < 0) {
		whinge(mod, NULL, "amd_generic_mc_create: range create for "
		    "channels failed\n");
		return (-1);
	}

	for (chan = 0; chan <= MAX_CHANNUM; chan++) {
		tnode_t *chnode;
		nvlist_t *fmri;
		int err;

		if (mkrsrc(mod, mcnode, CHAN_NODE_NAME, chan, auth,
		    &fmri) != 0) {
			whinge(mod, NULL, "amd_generic_mc_create: mkrsrc "
			    "failed\n");
			return (-1);
		}

		if ((chnode = topo_node_bind(mod, mcnode, CHAN_NODE_NAME,
		    chan, fmri)) == NULL) {
			nvlist_free(fmri);
			whinge(mod, NULL, "amd_generic_mc_create: node "
			    "bind failed\n");
			return (-1);
		}

		nvlist_free(fmri);

		(void) topo_pgroup_create(chnode, &chan_pgroup, &err);

		(void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel",
		    TOPO_PROP_IMMUTABLE, chan == 0 ? "A" : "B", &err);

		if (FM_AWARE_SMBIOS(mod)) {
			if (topo_node_label_set(chnode, NULL, &err) == -1)
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "topo_node_label_set\n");
			if (topo_node_fru_set(chnode, NULL, 0, &err) != 0)
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "topo_node_fru_set failed\n");
		}

		if (topo_node_range_create(mod, chnode, CS_NODE_NAME,
		    0, MAX_CSNUM) < 0) {
			whinge(mod, NULL, "amd_generic_mc_create: "
			    "range create for cs failed\n");
			return (-1);
		}

		for (cs = 0; cs <= MAX_CSNUM; cs++) {
			tnode_t *csnode;

			if (mkrsrc(mod, chnode, CS_NODE_NAME, cs, auth,
			    &fmri) != 0) {
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "mkrsrc for cs failed\n");
				return (-1);
			}

			if ((csnode = topo_node_bind(mod, chnode, CS_NODE_NAME,
			    cs, fmri)) == NULL) {
				nvlist_free(fmri);
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "bind for cs failed\n");
				return (-1);
			}

			/*
			 * Dynamic ASRU for page faults within a chip-select.
			 * The topology does not represent pages (there are
			 * too many) so when a page is faulted we generate
			 * an ASRU to represent the individual page.
			 * If SMBIOS meets FMA needs, derive labels & serials
			 * for DIMMS and apply to chip-select nodes.
			 * If deriving from SMBIOS, skip IPMI
			 */
			if (FM_AWARE_SMBIOS(mod)) {
				if (topo_method_register(mod, csnode,
				    x86pi_gen_cs_methods) < 0)
					whinge(mod, NULL,
					    "amd_generic_mc_create: "
					    "method registration failed\n");
			} else {
				if (topo_method_register(mod, csnode,
				    gen_cs_methods) < 0)
					whinge(mod, NULL,
					    "amd_generic_mc_create: method"
					    "registration failed\n");
			}

			(void) topo_node_asru_set(csnode, fmri,
			    TOPO_ASRU_COMPUTE, &err);
			nvlist_free(fmri);

			/*
			 * If SMBIOS meets FMA needs, set DIMM as the FRU for
			 * the chip-select node. Use the channel & chip-select
			 * numbers to get the DIMM instance.
			 * Send via inst : dram channel number
			 * Receive via inst : dimm instance
			 */
			if (FM_AWARE_SMBIOS(mod)) {
				int inst;
				id_t dimm_smbid;
				const char *serial;
				const char *part;
				const char *rev;
				char *label;

				(void) topo_pgroup_create(csnode,
				    &cs_pgroup, &err);
				inst = chan;
				dimm_smbid = memnode_to_smbiosid(mod, smbid,
				    CS_NODE_NAME, cs, &inst);
				serial = chip_serial_smbios_get(mod,
				    dimm_smbid);
				part = chip_part_smbios_get(mod,
				    dimm_smbid);
				rev = chip_rev_smbios_get(mod, dimm_smbid);
				label = (char *)chip_label_smbios_get(mod,
				    chnode, dimm_smbid, NULL);

				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE,
				    serial, &err);
				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE,
				    part, &err);
				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE,
				    rev, &err);

				/*
				 * We apply DIMM labels to chip-select nodes,
				 * FRU for chip-selects should be DIMMs, and
				 * we do not derive dimm nodes for Family 0x10
				 * so FRU fmri is NULL, but FRU Labels are set,
				 * the FRU labels point to the DIMM.
				 */
				(void) topo_node_label_set(csnode, label, &err);
				topo_mod_strfree(mod, label);
			}
		}
	}

	return (0);
}
예제 #14
0
static tnode_t *
mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
    const char *name, topo_instance_t i, void *priv)
{
	nvlist_t *fmri;
	tnode_t *ntn;
	char *serial = NULL, *part = NULL;
	char *psn = NULL, *csn = NULL, *pstr = NULL;
	nvlist_t *auth = topo_mod_auth(mod, parent);

	/*
	 * Get Product Serial Number, Chassis ID, MB Serial Number and
	 * Part Number from PRI.
	 */
	(void) mb_get_pri_info(mod, &serial, &part, &csn, &psn);

	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &pstr) != 0 &&
	    csn != NULL) {
		if (nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, csn) != 0) {
			topo_mod_dprintf(mod,
			    "failed to add chassis to auth");
			nvlist_free(auth);
			return (NULL);
		}
	}

	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &pstr) != 0 &&
	    psn != NULL) {
		if (nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN, psn)
		    != 0) {
			topo_mod_dprintf(mod,
			    "failed to add product-sn to auth");
			nvlist_free(auth);
			return (NULL);
		}
	}

	fmri = topo_mod_hcfmri(mod, NULL, FM_HC_SCHEME_VERSION, name, i,
	    NULL, auth, part, NULL, serial);

	topo_mod_strfree(mod, serial);
	topo_mod_strfree(mod, part);
	topo_mod_strfree(mod, csn);
	topo_mod_strfree(mod, psn);

	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);
	}

	ntn = topo_node_bind(mod, parent, name, i, fmri);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(auth);
		nvlist_free(fmri);
		return (NULL);
	}

	mb_prop_set(ntn, auth);

	nvlist_free(auth);
	nvlist_free(fmri);

	topo_node_setspecific(ntn, priv);

	return (ntn);
}