17aec1d6eScindi /*
27aec1d6eScindi  * CDDL HEADER START
37aec1d6eScindi  *
47aec1d6eScindi  * The contents of this file are subject to the terms of the
57aec1d6eScindi  * Common Development and Distribution License (the "License").
67aec1d6eScindi  * You may not use this file except in compliance with the License.
77aec1d6eScindi  *
87aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
107aec1d6eScindi  * See the License for the specific language governing permissions
117aec1d6eScindi  * and limitations under the License.
127aec1d6eScindi  *
137aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
147aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
167aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
177aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
187aec1d6eScindi  *
197aec1d6eScindi  * CDDL HEADER END
207aec1d6eScindi  */
217aec1d6eScindi 
227aec1d6eScindi /*
23c93c462eSCheng Sean Ye  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247aec1d6eScindi  * Use is subject to license terms.
25f2dbfd32SRobert Mustacchi  * Copyright 2019, Joyent, Inc.
26*d0caeb89SRobert Mustacchi  * Copyright 2020 Oxide Computer Company
277aec1d6eScindi  */
287aec1d6eScindi 
297aec1d6eScindi #include <unistd.h>
30e4b86885SCheng Sean Ye #include <fcntl.h>
317aec1d6eScindi #include <stdio.h>
327aec1d6eScindi #include <stdlib.h>
338a40a695Sgavinm #include <stdarg.h>
347aec1d6eScindi #include <string.h>
357aec1d6eScindi #include <strings.h>
367aec1d6eScindi #include <limits.h>
377aec1d6eScindi #include <alloca.h>
387aec1d6eScindi #include <kstat.h>
397aec1d6eScindi #include <errno.h>
407aec1d6eScindi #include <libnvpair.h>
417aec1d6eScindi #include <sys/types.h>
427aec1d6eScindi #include <sys/bitmap.h>
437aec1d6eScindi #include <sys/processor.h>
447aec1d6eScindi #include <sys/param.h>
457aec1d6eScindi #include <sys/fm/protocol.h>
467aec1d6eScindi #include <sys/systeminfo.h>
477aec1d6eScindi #include <sys/mc.h>
488a40a695Sgavinm #include <sys/mc_amd.h>
4920c794b3Sgavinm #include <sys/mc_intel.h>
50e4b86885SCheng Sean Ye #include <sys/devfm.h>
51e4b86885SCheng Sean Ye #include <fm/fmd_agent.h>
527aec1d6eScindi #include <fm/topo_mod.h>
537aec1d6eScindi 
547aec1d6eScindi #include "chip.h"
557aec1d6eScindi 
56bac58072Sgavinm #define	MAX_DIMMNUM	7
57bac58072Sgavinm #define	MAX_CSNUM	7
58bac58072Sgavinm 
597aec1d6eScindi /*
607aec1d6eScindi  * Enumerates the processing chips, or sockets, (as distinct from cores) in a
617aec1d6eScindi  * system.  For each chip found, the necessary nodes (one or more cores, and
627aec1d6eScindi  * possibly a memory controller) are constructed underneath.
637aec1d6eScindi  */
647aec1d6eScindi 
6520c794b3Sgavinm static int chip_enum(topo_mod_t *, tnode_t *, const char *,
6620c794b3Sgavinm     topo_instance_t, topo_instance_t, void *, void *);
678a40a695Sgavinm 
680eb822a1Scindi static const topo_modops_t chip_ops =
690eb822a1Scindi 	{ chip_enum, NULL};
700eb822a1Scindi static const topo_modinfo_t chip_info =
719dd0f810Scindi 	{ CHIP_NODE_NAME, FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops };
720eb822a1Scindi 
730eb822a1Scindi static const topo_pgroup_info_t chip_pgroup =
749dd0f810Scindi 	{ PGNAME(CHIP), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
75e4b86885SCheng Sean Ye 
76e4b86885SCheng Sean Ye static const topo_pgroup_info_t core_pgroup =
77e4b86885SCheng Sean Ye 	{ PGNAME(CORE), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
78e4b86885SCheng Sean Ye 
79e4b86885SCheng Sean Ye static const topo_pgroup_info_t strand_pgroup =
80e4b86885SCheng Sean Ye 	{ PGNAME(STRAND), TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 };
818a40a695Sgavinm 
8220c794b3Sgavinm static const topo_method_t chip_methods[] = {
834557a2a1Srobj 	{ SIMPLE_CHIP_LBL, "Property method", 0,
844557a2a1Srobj 	    TOPO_STABILITY_INTERNAL, simple_chip_label},
854557a2a1Srobj 	{ G4_CHIP_LBL, "Property method", 0,
864557a2a1Srobj 	    TOPO_STABILITY_INTERNAL, g4_chip_label},
872cb5535aSrobj 	{ A4FPLUS_CHIP_LBL, "Property method", 0,
882cb5535aSrobj 	    TOPO_STABILITY_INTERNAL, a4fplus_chip_label},
8964d1d4abSAdrian Frost 	{ FSB2_CHIP_LBL, "Property method", 0,
9064d1d4abSAdrian Frost 	    TOPO_STABILITY_INTERNAL, fsb2_chip_label},
912a613b59SRobert Mustacchi 	{ TOPO_METH_REPLACED, TOPO_METH_REPLACED_DESC,
922a613b59SRobert Mustacchi 	    TOPO_METH_REPLACED_VERSION, TOPO_STABILITY_INTERNAL,
932a613b59SRobert Mustacchi 	    chip_fmri_replaced },
944557a2a1Srobj 	{ NULL }
954557a2a1Srobj };
964557a2a1Srobj 
97e4b86885SCheng Sean Ye static const topo_method_t strands_retire_methods[] = {
98e4b86885SCheng Sean Ye 	{ TOPO_METH_RETIRE, TOPO_METH_RETIRE_DESC,
99e4b86885SCheng Sean Ye 	    TOPO_METH_RETIRE_VERSION, TOPO_STABILITY_INTERNAL,
100e4b86885SCheng Sean Ye 	    retire_strands },
101e4b86885SCheng Sean Ye 	{ TOPO_METH_UNRETIRE, TOPO_METH_UNRETIRE_DESC,
102e4b86885SCheng Sean Ye 	    TOPO_METH_UNRETIRE_VERSION, TOPO_STABILITY_INTERNAL,
103e4b86885SCheng Sean Ye 	    unretire_strands },
104e4b86885SCheng Sean Ye 	{ TOPO_METH_SERVICE_STATE, TOPO_METH_SERVICE_STATE_DESC,
105e4b86885SCheng Sean Ye 	    TOPO_METH_SERVICE_STATE_VERSION, TOPO_STABILITY_INTERNAL,
106e4b86885SCheng Sean Ye 	    service_state_strands },
107e4b86885SCheng Sean Ye 	{ TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC,
108e4b86885SCheng Sean Ye 	    TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL,
109e4b86885SCheng Sean Ye 	    unusable_strands },
110e4b86885SCheng Sean Ye 	{ NULL }
111e4b86885SCheng Sean Ye };
112e4b86885SCheng Sean Ye 
1137aec1d6eScindi int
_topo_init(topo_mod_t * mod)1147aec1d6eScindi _topo_init(topo_mod_t *mod)
1157aec1d6eScindi {
1160eb822a1Scindi 	if (getenv("TOPOCHIPDBG"))
1170eb822a1Scindi 		topo_mod_setdebug(mod);
1187aec1d6eScindi 	topo_mod_dprintf(mod, "initializing chip enumerator\n");
1197aec1d6eScindi 
1200eb822a1Scindi 	if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) {
1218a40a695Sgavinm 		whinge(mod, NULL, "failed to register hc: "
1227aec1d6eScindi 		    "%s\n", topo_mod_errmsg(mod));
1237aec1d6eScindi 		return (-1); /* mod errno set */
1247aec1d6eScindi 	}
1257aec1d6eScindi 
1267aec1d6eScindi 	return (0);
1277aec1d6eScindi }
1287aec1d6eScindi 
1297aec1d6eScindi void
_topo_fini(topo_mod_t * mod)1307aec1d6eScindi _topo_fini(topo_mod_t *mod)
1317aec1d6eScindi {
1327aec1d6eScindi 	topo_mod_unregister(mod);
1337aec1d6eScindi }
1347aec1d6eScindi 
135e4b86885SCheng Sean Ye boolean_t
is_xpv(void)136e4b86885SCheng Sean Ye is_xpv(void)
137e3d60c9bSAdrian Frost {
138e4b86885SCheng Sean Ye 	static int r = -1;
139e4b86885SCheng Sean Ye 	char platform[MAXNAMELEN];
140e3d60c9bSAdrian Frost 
141e4b86885SCheng Sean Ye 	if (r != -1)
142e4b86885SCheng Sean Ye 		return (r == 0);
143e3d60c9bSAdrian Frost 
144e4b86885SCheng Sean Ye 	(void) sysinfo(SI_PLATFORM, platform, sizeof (platform));
145e4b86885SCheng Sean Ye 	r = strcmp(platform, "i86xpv");
146e4b86885SCheng Sean Ye 	return (r == 0);
147e4b86885SCheng Sean Ye }
148e3d60c9bSAdrian Frost 
149e4b86885SCheng Sean Ye static tnode_t *
create_node(topo_mod_t * mod,tnode_t * pnode,nvlist_t * auth,char * name,topo_instance_t inst,nvlist_t * cpu,uint16_t smbios_id)150e4b86885SCheng Sean Ye create_node(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth, char *name,
1512a613b59SRobert Mustacchi     topo_instance_t inst, nvlist_t *cpu, uint16_t smbios_id)
152e4b86885SCheng Sean Ye {
153e4b86885SCheng Sean Ye 	nvlist_t *fmri;
154e4b86885SCheng Sean Ye 	tnode_t *cnode;
155e3d60c9bSAdrian Frost 
156e4b86885SCheng Sean Ye 	if (mkrsrc(mod, pnode, name, inst, auth, &fmri) != 0) {
157e4b86885SCheng Sean Ye 		whinge(mod, NULL, "create_node: mkrsrc failed\n");
158e4b86885SCheng Sean Ye 		return (NULL);
159e3d60c9bSAdrian Frost 	}
160074bb90dSTom Pothier 
161074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
162074bb90dSTom Pothier 		id_t phys_cpu_smbid;
163074bb90dSTom Pothier 		int perr = 0;
164074bb90dSTom Pothier 		const char *serial = NULL;
165074bb90dSTom Pothier 		const char *part = NULL;
166074bb90dSTom Pothier 		const char *rev = NULL;
167074bb90dSTom Pothier 
168074bb90dSTom Pothier 		phys_cpu_smbid = smbios_id;
169074bb90dSTom Pothier 		serial = chip_serial_smbios_get(mod, phys_cpu_smbid);
170074bb90dSTom Pothier 		part = chip_part_smbios_get(mod, phys_cpu_smbid);
171074bb90dSTom Pothier 		rev = chip_rev_smbios_get(mod, phys_cpu_smbid);
172074bb90dSTom Pothier 
173074bb90dSTom Pothier 		perr += nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID,
174074bb90dSTom Pothier 		    serial);
175074bb90dSTom Pothier 		perr += nvlist_add_string(fmri, FM_FMRI_HC_PART,
176074bb90dSTom Pothier 		    part);
177074bb90dSTom Pothier 		perr += nvlist_add_string(fmri, FM_FMRI_HC_REVISION,
178074bb90dSTom Pothier 		    rev);
179074bb90dSTom Pothier 
180074bb90dSTom Pothier 		if (perr != 0)
181074bb90dSTom Pothier 			whinge(mod, NULL,
182074bb90dSTom Pothier 			    "create_node: nvlist_add_string failed\n");
183074bb90dSTom Pothier 
184074bb90dSTom Pothier 		topo_mod_strfree(mod, (char *)serial);
185074bb90dSTom Pothier 		topo_mod_strfree(mod, (char *)part);
186074bb90dSTom Pothier 		topo_mod_strfree(mod, (char *)rev);
1872a613b59SRobert Mustacchi 	} else {
1882a613b59SRobert Mustacchi 		char *serial = NULL;
1892a613b59SRobert Mustacchi 
1902a613b59SRobert Mustacchi 		if (nvlist_lookup_string(cpu, FM_PHYSCPU_INFO_CHIP_IDENTSTR,
1912a613b59SRobert Mustacchi 		    &serial) == 0) {
1922a613b59SRobert Mustacchi 			if (nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID,
1932a613b59SRobert Mustacchi 			    serial) != 0) {
1942a613b59SRobert Mustacchi 				whinge(mod, NULL,
1952a613b59SRobert Mustacchi 				    "create_node: nvlist_add_string failed\n");
1962a613b59SRobert Mustacchi 			}
1972a613b59SRobert Mustacchi 		}
198074bb90dSTom Pothier 	}
199074bb90dSTom Pothier 
200e4b86885SCheng Sean Ye 	cnode = topo_node_bind(mod, pnode, name, inst, fmri);
201074bb90dSTom Pothier 
202e4b86885SCheng Sean Ye 	nvlist_free(fmri);
203074bb90dSTom Pothier 	if (cnode == NULL) {
204074bb90dSTom Pothier 		whinge(mod, NULL, "create_node: node bind failed"
205074bb90dSTom Pothier 		    " for %s %d\n", name, (int)inst);
206074bb90dSTom Pothier 	}
207e3d60c9bSAdrian Frost 
208e4b86885SCheng Sean Ye 	return (cnode);
209e3d60c9bSAdrian Frost }
210e3d60c9bSAdrian Frost 
211e3d60c9bSAdrian Frost static int
create_strand(topo_mod_t * mod,tnode_t * pnode,nvlist_t * cpu,nvlist_t * auth,uint16_t chip_smbiosid)212074bb90dSTom Pothier create_strand(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu,
213074bb90dSTom Pothier     nvlist_t *auth, uint16_t chip_smbiosid)
214e3d60c9bSAdrian Frost {
215e4b86885SCheng Sean Ye 	tnode_t *strand;
216e4b86885SCheng Sean Ye 	int32_t strandid, cpuid;
217074bb90dSTom Pothier 	int err, perr, nerr = 0;
218e4b86885SCheng Sean Ye 	nvlist_t *fmri;
219074bb90dSTom Pothier 	char *serial = NULL;
220074bb90dSTom Pothier 	char *part = NULL;
221074bb90dSTom Pothier 	char *rev = NULL;
222e3d60c9bSAdrian Frost 
223e4b86885SCheng Sean Ye 	if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_STRAND_ID,
224e4b86885SCheng Sean Ye 	    &strandid)) != 0) {
225e4b86885SCheng Sean Ye 		whinge(mod, NULL, "create_strand: lookup strand_id failed: "
226e4b86885SCheng Sean Ye 		    "%s\n", strerror(err));
227e3d60c9bSAdrian Frost 		return (-1);
228e4b86885SCheng Sean Ye 	}
229e3d60c9bSAdrian Frost 
230e4b86885SCheng Sean Ye 	if ((strand = topo_node_lookup(pnode, STRAND_NODE_NAME, strandid))
231e4b86885SCheng Sean Ye 	    != NULL) {
232e4b86885SCheng Sean Ye 		whinge(mod, NULL, "create_strand: duplicate tuple found\n");
233e4b86885SCheng Sean Ye 		return (-1);
234e4b86885SCheng Sean Ye 	}
235e3d60c9bSAdrian Frost 
236e4b86885SCheng Sean Ye 	if ((strand = create_node(mod, pnode, auth, STRAND_NODE_NAME,
2372a613b59SRobert Mustacchi 	    strandid, cpu, chip_smbiosid)) == NULL)
238e4b86885SCheng Sean Ye 		return (-1);
239e3d60c9bSAdrian Frost 
240e4b86885SCheng Sean Ye 	/*
241e4b86885SCheng Sean Ye 	 * Inherit FRU from core node, in native use cpu scheme ASRU,
242e4b86885SCheng Sean Ye 	 * in xpv, use hc scheme ASRU.
243e4b86885SCheng Sean Ye 	 */
244074bb90dSTom Pothier 	(void) topo_node_fru_set(strand, NULL, 0, &perr);
245074bb90dSTom Pothier 	/*
246074bb90dSTom Pothier 	 * From the inherited FRU, extract the Serial
247074bb90dSTom Pothier 	 * number(if SMBIOS donates) and set it in the ASRU
248074bb90dSTom Pothier 	 */
249074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
250074bb90dSTom Pothier 		char *val = NULL;
251074bb90dSTom Pothier 
252074bb90dSTom Pothier 		if (topo_prop_get_fmri(strand, TOPO_PGROUP_PROTOCOL,
253074bb90dSTom Pothier 		    TOPO_PROP_RESOURCE, &fmri, &err) != 0)
254074bb90dSTom Pothier 			whinge(mod, NULL,
255074bb90dSTom Pothier 			    "create_strand: topo_prop_get_fmri failed\n");
256074bb90dSTom Pothier 		if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &val) != 0)
257074bb90dSTom Pothier 			whinge(mod, NULL,
258074bb90dSTom Pothier 			    "create_strand: nvlist_lookup_string failed: \n");
259074bb90dSTom Pothier 		else
260074bb90dSTom Pothier 			serial = topo_mod_strdup(mod, val);
261074bb90dSTom Pothier 		nvlist_free(fmri);
262074bb90dSTom Pothier 	}
263e4b86885SCheng Sean Ye 	if (is_xpv()) {
264e4b86885SCheng Sean Ye 		if (topo_node_resource(strand, &fmri, &err) == -1) {
265e4b86885SCheng Sean Ye 			whinge(mod, &nerr, "create_strand: "
266e4b86885SCheng Sean Ye 			    "topo_node_resource failed\n");
267e4b86885SCheng Sean Ye 		} else {
268074bb90dSTom Pothier 			if (FM_AWARE_SMBIOS(mod))
269074bb90dSTom Pothier 				(void) nvlist_add_string(fmri,
270074bb90dSTom Pothier 				    FM_FMRI_HC_SERIAL_ID, serial);
271e4b86885SCheng Sean Ye 			(void) topo_node_asru_set(strand, fmri, 0, &err);
272e3d60c9bSAdrian Frost 			nvlist_free(fmri);
273e3d60c9bSAdrian Frost 		}
274e4b86885SCheng Sean Ye 	} else {
275e4b86885SCheng Sean Ye 		if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) {
276e4b86885SCheng Sean Ye 			whinge(mod, &nerr, "create_strand: lookup cpuid "
277e4b86885SCheng Sean Ye 			    "failed\n");
278e4b86885SCheng Sean Ye 		} else {
279074bb90dSTom Pothier 			if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0))
280e4b86885SCheng Sean Ye 			    != NULL) {
281e4b86885SCheng Sean Ye 				(void) topo_node_asru_set(strand, fmri,
282e4b86885SCheng Sean Ye 				    0, &err);
283e4b86885SCheng Sean Ye 				nvlist_free(fmri);
284e4b86885SCheng Sean Ye 			} else {
285e4b86885SCheng Sean Ye 				whinge(mod, &nerr, "create_strand: "
286e4b86885SCheng Sean Ye 				    "cpu_fmri_create() failed\n");
287e4b86885SCheng Sean Ye 			}
288e4b86885SCheng Sean Ye 		}
289e4b86885SCheng Sean Ye 	}
290e3d60c9bSAdrian Frost 
291e4b86885SCheng Sean Ye 	if (topo_method_register(mod, strand, strands_retire_methods) < 0)
292e4b86885SCheng Sean Ye 		whinge(mod, &nerr, "create_strand: "
293e4b86885SCheng Sean Ye 		    "topo_method_register failed\n");
294e3d60c9bSAdrian Frost 
295e4b86885SCheng Sean Ye 	(void) topo_pgroup_create(strand, &strand_pgroup, &err);
296e4b86885SCheng Sean Ye 	nerr -= add_nvlist_longprops(mod, strand, cpu, PGNAME(STRAND), NULL,
2978031591dSSrihari Venkatesan 	    STRAND_CHIP_ID, STRAND_PROCNODE_ID, STRAND_CORE_ID, STRAND_CPU_ID,
2988031591dSSrihari Venkatesan 	    NULL);
299e3d60c9bSAdrian Frost 
300074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
301074bb90dSTom Pothier 		(void) topo_node_label_set(strand, NULL, &perr);
302074bb90dSTom Pothier 
303074bb90dSTom Pothier 		if (topo_node_resource(strand, &fmri, &perr) != 0) {
304074bb90dSTom Pothier 			whinge(mod, &nerr, "create_strand: "
305074bb90dSTom Pothier 			    "topo_node_resource failed\n");
306074bb90dSTom Pothier 			perr = 0;
307074bb90dSTom Pothier 		}
308074bb90dSTom Pothier 
309074bb90dSTom Pothier 		perr += nvlist_lookup_string(fmri,
310074bb90dSTom Pothier 		    FM_FMRI_HC_PART, &part);
311074bb90dSTom Pothier 		perr += nvlist_lookup_string(fmri,
312074bb90dSTom Pothier 		    FM_FMRI_HC_REVISION, &rev);
313074bb90dSTom Pothier 
314074bb90dSTom Pothier 		if (perr != 0) {
315074bb90dSTom Pothier 			whinge(mod, NULL,
316074bb90dSTom Pothier 			    "create_strand: nvlist_lookup_string failed\n");
317074bb90dSTom Pothier 			perr = 0;
318074bb90dSTom Pothier 		}
319074bb90dSTom Pothier 
320074bb90dSTom Pothier 		perr += topo_prop_set_string(strand, PGNAME(STRAND),
321074bb90dSTom Pothier 		    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr);
322074bb90dSTom Pothier 		perr += topo_prop_set_string(strand, PGNAME(STRAND),
323074bb90dSTom Pothier 		    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr);
324074bb90dSTom Pothier 		perr += topo_prop_set_string(strand, PGNAME(STRAND),
325074bb90dSTom Pothier 		    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr);
326074bb90dSTom Pothier 
327074bb90dSTom Pothier 		if (perr != 0)
328074bb90dSTom Pothier 			whinge(mod, NULL, "create_strand: topo_prop_set_string"
329074bb90dSTom Pothier 			    "failed\n");
330074bb90dSTom Pothier 
331074bb90dSTom Pothier 		nvlist_free(fmri);
332074bb90dSTom Pothier 		topo_mod_strfree(mod, serial);
333074bb90dSTom Pothier 	}
334074bb90dSTom Pothier 
335e4b86885SCheng Sean Ye 	return (err == 0 && nerr == 0 ? 0 : -1);
336e3d60c9bSAdrian Frost }
337e3d60c9bSAdrian Frost 
3387aec1d6eScindi static int
create_core(topo_mod_t * mod,tnode_t * pnode,nvlist_t * cpu,nvlist_t * auth,uint16_t chip_smbiosid)339074bb90dSTom Pothier create_core(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu,
340074bb90dSTom Pothier     nvlist_t *auth, uint16_t chip_smbiosid)
3417aec1d6eScindi {
342e4b86885SCheng Sean Ye 	tnode_t *core;
343e4b86885SCheng Sean Ye 	int32_t coreid, cpuid;
344074bb90dSTom Pothier 	int err, perr, nerr = 0;
345e4b86885SCheng Sean Ye 	nvlist_t *fmri;
346074bb90dSTom Pothier 	char *serial = NULL;
347074bb90dSTom Pothier 	char *part = NULL;
348074bb90dSTom Pothier 	char *rev = NULL;
3497aec1d6eScindi 
350e4b86885SCheng Sean Ye 	if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_CORE_ID, &coreid))
351e4b86885SCheng Sean Ye 	    != 0) {
352e4b86885SCheng Sean Ye 		whinge(mod, NULL, "create_core: lookup core_id failed: %s\n",
353e4b86885SCheng Sean Ye 		    strerror(err));
3547aec1d6eScindi 		return (-1);
355e4b86885SCheng Sean Ye 	}
356e4b86885SCheng Sean Ye 	if ((core = topo_node_lookup(pnode, CORE_NODE_NAME, coreid)) == NULL) {
357e4b86885SCheng Sean Ye 		if ((core = create_node(mod, pnode, auth, CORE_NODE_NAME,
3582a613b59SRobert Mustacchi 		    coreid, cpu, chip_smbiosid)) == NULL)
359e4b86885SCheng Sean Ye 			return (-1);
3607aec1d6eScindi 
3618a40a695Sgavinm 		/*
362e4b86885SCheng Sean Ye 		 * Inherit FRU from the chip node, for native, we use hc
363e4b86885SCheng Sean Ye 		 * scheme ASRU for the core node.
3648a40a695Sgavinm 		 */
365074bb90dSTom Pothier 		(void) topo_node_fru_set(core, NULL, 0, &perr);
366074bb90dSTom Pothier 		/*
367074bb90dSTom Pothier 		 * From the inherited FRU, extract the Serial
368074bb90dSTom Pothier 		 * number if SMBIOS donates and set it in the ASRU
369074bb90dSTom Pothier 		 */
370074bb90dSTom Pothier 		if (FM_AWARE_SMBIOS(mod)) {
371074bb90dSTom Pothier 			char *val = NULL;
372074bb90dSTom Pothier 
373074bb90dSTom Pothier 			if (topo_node_resource(core, &fmri, &err) != 0)
374074bb90dSTom Pothier 				whinge(mod, NULL,
375074bb90dSTom Pothier 				    "create_core: topo_prop_get_fmri failed\n");
376074bb90dSTom Pothier 			if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID,
377074bb90dSTom Pothier 			    &val) != 0)
378074bb90dSTom Pothier 				whinge(mod, NULL, "create_core:"
379074bb90dSTom Pothier 				    "nvlist_lookup_string failed\n");
380074bb90dSTom Pothier 			else
381074bb90dSTom Pothier 				serial = topo_mod_strdup(mod, val);
382074bb90dSTom Pothier 			nvlist_free(fmri);
383074bb90dSTom Pothier 		}
384e4b86885SCheng Sean Ye 		if (is_xpv()) {
385e4b86885SCheng Sean Ye 			if (topo_node_resource(core, &fmri, &err) == -1) {
386e4b86885SCheng Sean Ye 				whinge(mod, &nerr, "create_core: "
387e4b86885SCheng Sean Ye 				    "topo_node_resource failed\n");
388e4b86885SCheng Sean Ye 			} else {
389074bb90dSTom Pothier 				if (FM_AWARE_SMBIOS(mod))
390074bb90dSTom Pothier 					(void) nvlist_add_string(fmri,
391074bb90dSTom Pothier 					    FM_FMRI_HC_SERIAL_ID, serial);
392e4b86885SCheng Sean Ye 				(void) topo_node_asru_set(core, fmri, 0, &err);
393e4b86885SCheng Sean Ye 				nvlist_free(fmri);
394e4b86885SCheng Sean Ye 			}
3957aec1d6eScindi 		}
396e4b86885SCheng Sean Ye 		if (topo_method_register(mod, core, strands_retire_methods) < 0)
397e4b86885SCheng Sean Ye 			whinge(mod, &nerr, "create_core: "
398e4b86885SCheng Sean Ye 			    "topo_method_register failed\n");
399e4b86885SCheng Sean Ye 
400e4b86885SCheng Sean Ye 		(void) topo_pgroup_create(core, &core_pgroup, &err);
4018031591dSSrihari Venkatesan 		nerr -= add_nvlist_longprops(mod, core, cpu, PGNAME(CORE), NULL,
4028031591dSSrihari Venkatesan 		    CORE_CHIP_ID, CORE_PROCNODE_ID, NULL);
4037aec1d6eScindi 
404e4b86885SCheng Sean Ye 		if (topo_node_range_create(mod, core, STRAND_NODE_NAME,
405e4b86885SCheng Sean Ye 		    0, 255) != 0)
406e4b86885SCheng Sean Ye 			return (-1);
407f2dbfd32SRobert Mustacchi 
408f2dbfd32SRobert Mustacchi 		/*
409f2dbfd32SRobert Mustacchi 		 * Creating a temperature sensor may fail because the sensor
410f2dbfd32SRobert Mustacchi 		 * doesn't exist or due to internal reasons. At the moment, we
411f2dbfd32SRobert Mustacchi 		 * swallow any such errors that occur.
412f2dbfd32SRobert Mustacchi 		 */
413f2dbfd32SRobert Mustacchi 		(void) chip_create_core_temp_sensor(mod, core);
414e4b86885SCheng Sean Ye 	}
4158a40a695Sgavinm 
416074bb90dSTom Pothier 	if (!is_xpv()) {
4178a40a695Sgavinm 		/*
418e4b86885SCheng Sean Ye 		 * In native mode, we're in favor of cpu scheme ASRU for
419e4b86885SCheng Sean Ye 		 * printing reason.  More work needs to be done to support
420e4b86885SCheng Sean Ye 		 * multi-strand cpu: the ASRU will be a list of cpuid then.
4218a40a695Sgavinm 		 */
422e4b86885SCheng Sean Ye 		if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) {
423e4b86885SCheng Sean Ye 			whinge(mod, &nerr, "create_core: lookup cpuid "
4248a40a695Sgavinm 			    "failed\n");
425e4b86885SCheng Sean Ye 		} else {
426074bb90dSTom Pothier 			if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0))
427e4b86885SCheng Sean Ye 			    != NULL) {
428e4b86885SCheng Sean Ye 				(void) topo_node_asru_set(core, fmri, 0, &err);
429e4b86885SCheng Sean Ye 				nvlist_free(fmri);
430e4b86885SCheng Sean Ye 			} else {
431e4b86885SCheng Sean Ye 				whinge(mod, &nerr, "create_core: "
432e4b86885SCheng Sean Ye 				    "cpu_fmri_create() failed\n");
433e4b86885SCheng Sean Ye 			}
4347aec1d6eScindi 		}
4357aec1d6eScindi 	}
4367aec1d6eScindi 
437074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
438074bb90dSTom Pothier 		(void) topo_node_label_set(core, NULL, &perr);
439074bb90dSTom Pothier 
440074bb90dSTom Pothier 		if (topo_node_resource(core, &fmri, &perr) != 0) {
441074bb90dSTom Pothier 			whinge(mod, &nerr, "create_core: "
442074bb90dSTom Pothier 			    "topo_node_resource failed\n");
443074bb90dSTom Pothier 			perr = 0;
444074bb90dSTom Pothier 		}
445074bb90dSTom Pothier 
446074bb90dSTom Pothier 		perr += nvlist_lookup_string(fmri,
447074bb90dSTom Pothier 		    FM_FMRI_HC_PART, &part);
448074bb90dSTom Pothier 		perr += nvlist_lookup_string(fmri,
449074bb90dSTom Pothier 		    FM_FMRI_HC_REVISION, &rev);
450074bb90dSTom Pothier 
451074bb90dSTom Pothier 		if (perr != 0) {
452074bb90dSTom Pothier 			whinge(mod, NULL,
453074bb90dSTom Pothier 			    "create_core: nvlist_lookup_string failed\n");
454074bb90dSTom Pothier 			perr = 0;
455074bb90dSTom Pothier 		}
456074bb90dSTom Pothier 
457074bb90dSTom Pothier 		perr += topo_prop_set_string(core, PGNAME(CORE),
458074bb90dSTom Pothier 		    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr);
459074bb90dSTom Pothier 		perr += topo_prop_set_string(core, PGNAME(CORE),
460074bb90dSTom Pothier 		    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr);
461074bb90dSTom Pothier 		perr += topo_prop_set_string(core, PGNAME(CORE),
462074bb90dSTom Pothier 		    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr);
463074bb90dSTom Pothier 
464074bb90dSTom Pothier 		if (perr != 0)
465074bb90dSTom Pothier 			whinge(mod, NULL, "create_core: topo_prop_set_string"
466074bb90dSTom Pothier 			    "failed\n");
467074bb90dSTom Pothier 
468074bb90dSTom Pothier 		nvlist_free(fmri);
469074bb90dSTom Pothier 		topo_mod_strfree(mod, serial);
470074bb90dSTom Pothier 	}
471074bb90dSTom Pothier 
472074bb90dSTom Pothier 	err = create_strand(mod, core, cpu, auth, chip_smbiosid);
473e4b86885SCheng Sean Ye 
474e4b86885SCheng Sean Ye 	return (err == 0 && nerr == 0 ? 0 : -1);
4757aec1d6eScindi }
4767aec1d6eScindi 
4777aec1d6eScindi static int
create_chip(topo_mod_t * mod,tnode_t * pnode,topo_instance_t min,topo_instance_t max,nvlist_t * cpu,nvlist_t * auth,int mc_offchip,kstat_ctl_t * kc)478e4b86885SCheng Sean Ye create_chip(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min,
479e4b86885SCheng Sean Ye     topo_instance_t max, nvlist_t *cpu, nvlist_t *auth,
480c26bf377SRob Johnston     int mc_offchip, kstat_ctl_t *kc)
4817aec1d6eScindi {
482e4b86885SCheng Sean Ye 	tnode_t *chip;
483e4b86885SCheng Sean Ye 	nvlist_t *fmri = NULL;
484074bb90dSTom Pothier 	int err, perr, nerr = 0;
4858031591dSSrihari Venkatesan 	int32_t chipid, procnodeid, procnodes_per_pkg;
486*d0caeb89SRobert Mustacchi 	const char *vendor;
487*d0caeb89SRobert Mustacchi 	char *brand, *socket;
4888031591dSSrihari Venkatesan 	int32_t family, model;
489c93c462eSCheng Sean Ye 	boolean_t create_mc = B_FALSE;
490074bb90dSTom Pothier 	uint16_t smbios_id;
4917aec1d6eScindi 
492074bb90dSTom Pothier 	/*
493074bb90dSTom Pothier 	 * /dev/fm will export the chipid based on SMBIOS' ordering
494074bb90dSTom Pothier 	 * of Type-4 structures, if SMBIOS meets FMA needs
495074bb90dSTom Pothier 	 */
4968031591dSSrihari Venkatesan 	err = nvlist_lookup_pairs(cpu, 0,
4978031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_CHIP_ID, DATA_TYPE_INT32, &chipid,
4988031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_NPROCNODES, DATA_TYPE_INT32, &procnodes_per_pkg,
4998031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_PROCNODE_ID, DATA_TYPE_INT32, &procnodeid,
5008031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_VENDOR_ID, DATA_TYPE_STRING, &vendor,
5018031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_FAMILY, DATA_TYPE_INT32, &family,
5028031591dSSrihari Venkatesan 	    FM_PHYSCPU_INFO_MODEL, DATA_TYPE_INT32, &model,
5038031591dSSrihari Venkatesan 	    NULL);
5048031591dSSrihari Venkatesan 
5058031591dSSrihari Venkatesan 	if (err) {
5068031591dSSrihari Venkatesan 		whinge(mod, NULL, "create_chip: lookup failed: %s\n",
507e4b86885SCheng Sean Ye 		    strerror(err));
508e4b86885SCheng Sean Ye 		return (-1);
5097aec1d6eScindi 	}
5107aec1d6eScindi 
511e4b86885SCheng Sean Ye 	if (chipid < min || chipid > max)
512e4b86885SCheng Sean Ye 		return (-1);
5137aec1d6eScindi 
514074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
515074bb90dSTom Pothier 		if ((err = nvlist_lookup_uint16(cpu,
516074bb90dSTom Pothier 		    FM_PHYSCPU_INFO_SMBIOS_ID, &smbios_id)) != 0) {
517074bb90dSTom Pothier 			whinge(mod, NULL,
518074bb90dSTom Pothier 			    "create_chip: lookup smbios_id failed"
519074bb90dSTom Pothier 			    ": enumerating x86pi & chip topology, but"
520074bb90dSTom Pothier 			    " no Chip properties from SMBIOS"
521074bb90dSTom Pothier 			    " - err msg : %s\n", strerror(err));
522074bb90dSTom Pothier 			/*
523074bb90dSTom Pothier 			 * Lets reset the module specific
524074bb90dSTom Pothier 			 * data to NULL, overriding any
525074bb90dSTom Pothier 			 * SMBIOS capability encoded earlier.
526074bb90dSTom Pothier 			 * This will fail all subsequent
527074bb90dSTom Pothier 			 * FM_AWARE_SMBIOS checks.
528074bb90dSTom Pothier 			 */
529074bb90dSTom Pothier 			topo_mod_setspecific(mod, NULL);
530074bb90dSTom Pothier 		}
531074bb90dSTom Pothier 	}
532074bb90dSTom Pothier 
533e4b86885SCheng Sean Ye 	if ((chip = topo_node_lookup(pnode, CHIP_NODE_NAME, chipid)) == NULL) {
534e4b86885SCheng Sean Ye 		if ((chip = create_node(mod, pnode, auth, CHIP_NODE_NAME,
5352a613b59SRobert Mustacchi 		    chipid, cpu, smbios_id)) == NULL)
536e4b86885SCheng Sean Ye 			return (-1);
537074bb90dSTom Pothier 		/*
538074bb90dSTom Pothier 		 * Do not register XML map methods if SMBIOS can provide
539074bb90dSTom Pothier 		 * serial, part, revision & label
540074bb90dSTom Pothier 		 */
541074bb90dSTom Pothier 		if (!FM_AWARE_SMBIOS(mod)) {
542074bb90dSTom Pothier 			if (topo_method_register(mod, chip, chip_methods) < 0)
543074bb90dSTom Pothier 				whinge(mod, &nerr, "create_chip: "
544074bb90dSTom Pothier 				    "topo_method_register failed\n");
5457aec1d6eScindi 		}
5467aec1d6eScindi 
547e4b86885SCheng Sean Ye 		(void) topo_pgroup_create(chip, &chip_pgroup, &err);
548e4b86885SCheng Sean Ye 		nerr -= add_nvlist_strprop(mod, chip, cpu, PGNAME(CHIP),
5498031591dSSrihari Venkatesan 		    CHIP_VENDOR_ID, NULL);
550e4b86885SCheng Sean Ye 		nerr -= add_nvlist_longprops(mod, chip, cpu, PGNAME(CHIP),
5518031591dSSrihari Venkatesan 		    NULL, CHIP_FAMILY, CHIP_MODEL, CHIP_STEPPING, NULL);
5524557a2a1Srobj 
553c26bf377SRob Johnston 		/*
554*d0caeb89SRobert Mustacchi 		 * Attempt to lookup the processor brand and socket string in
555*d0caeb89SRobert Mustacchi 		 * kstats and add it as a prop, if found.
556c26bf377SRob Johnston 		 */
557*d0caeb89SRobert Mustacchi 		brand = socket = NULL;
558*d0caeb89SRobert Mustacchi 		get_chip_kstat_strs(mod, kc, chipid, &brand, &socket);
559c26bf377SRob Johnston 		if (brand != NULL && topo_prop_set_string(chip, PGNAME(CHIP),
560c26bf377SRob Johnston 		    CHIP_BRAND, TOPO_PROP_IMMUTABLE, brand, &perr) != 0) {
561c26bf377SRob Johnston 			whinge(mod, &nerr, "failed to set prop %s/%s",
562c26bf377SRob Johnston 			    PGNAME(CHIP), CHIP_BRAND);
563c26bf377SRob Johnston 		}
564*d0caeb89SRobert Mustacchi 		topo_mod_strfree(mod, brand);
565*d0caeb89SRobert Mustacchi 
566*d0caeb89SRobert Mustacchi 		if (socket != NULL && topo_prop_set_string(chip, PGNAME(CHIP),
567*d0caeb89SRobert Mustacchi 		    CHIP_SOCKET, TOPO_PROP_IMMUTABLE, socket, &perr) != 0) {
568*d0caeb89SRobert Mustacchi 			whinge(mod, &nerr, "failed to set prop %s/%s",
569*d0caeb89SRobert Mustacchi 			    PGNAME(CHIP), CHIP_SOCKET);
570*d0caeb89SRobert Mustacchi 		}
571*d0caeb89SRobert Mustacchi 		topo_mod_strfree(mod, socket);
572c26bf377SRob Johnston 
573074bb90dSTom Pothier 		if (FM_AWARE_SMBIOS(mod)) {
574074bb90dSTom Pothier 			int fru = 0;
575074bb90dSTom Pothier 			char *serial = NULL;
576074bb90dSTom Pothier 			char *part = NULL;
577074bb90dSTom Pothier 			char *rev = NULL;
578074bb90dSTom Pothier 			char *label;
579074bb90dSTom Pothier 
580074bb90dSTom Pothier 			fru = chip_fru_smbios_get(mod, smbios_id);
581074bb90dSTom Pothier 			/*
582074bb90dSTom Pothier 			 * Chip is not a FRU, set the FRU fmri of parent node
583074bb90dSTom Pothier 			 */
584074bb90dSTom Pothier 			if (topo_node_resource(chip, &fmri, &perr) != 0)
585074bb90dSTom Pothier 				whinge(mod, &nerr, "create_chip: "
586074bb90dSTom Pothier 				    "topo_node_resource failed\n");
587074bb90dSTom Pothier 			if (!fru) {
588074bb90dSTom Pothier 				(void) topo_node_fru_set(chip, NULL, 0, &perr);
589074bb90dSTom Pothier 				label = NULL;
590074bb90dSTom Pothier 			} else {
591074bb90dSTom Pothier 				label = (char *)chip_label_smbios_get(mod,
592074bb90dSTom Pothier 				    pnode, smbios_id, NULL);
593074bb90dSTom Pothier 
594074bb90dSTom Pothier 				if (topo_node_fru_set(chip, fmri, 0, &perr)
595074bb90dSTom Pothier 				    != 0) {
596074bb90dSTom Pothier 					whinge(mod, NULL, "create_chip: "
597074bb90dSTom Pothier 					    "topo_node_fru_set failed\n");
598074bb90dSTom Pothier 					perr = 0;
599074bb90dSTom Pothier 				}
600074bb90dSTom Pothier 			}
601074bb90dSTom Pothier 
602074bb90dSTom Pothier 			perr += nvlist_lookup_string(fmri,
603074bb90dSTom Pothier 			    FM_FMRI_HC_SERIAL_ID, &serial);
604074bb90dSTom Pothier 			perr += nvlist_lookup_string(fmri,
605074bb90dSTom Pothier 			    FM_FMRI_HC_PART, &part);
606074bb90dSTom Pothier 			perr += nvlist_lookup_string(fmri,
607074bb90dSTom Pothier 			    FM_FMRI_HC_REVISION, &rev);
608074bb90dSTom Pothier 
609074bb90dSTom Pothier 			if (perr != 0) {
610074bb90dSTom Pothier 				whinge(mod, NULL,
611074bb90dSTom Pothier 				    "create_chip: nvlist_lookup_string"
612074bb90dSTom Pothier 				    "failed\n");
613074bb90dSTom Pothier 				perr = 0;
614074bb90dSTom Pothier 			}
615074bb90dSTom Pothier 
616074bb90dSTom Pothier 			perr += topo_prop_set_string(chip, PGNAME(CHIP),
617074bb90dSTom Pothier 			    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE,
618074bb90dSTom Pothier 			    serial, &perr);
619074bb90dSTom Pothier 			perr += topo_prop_set_string(chip, PGNAME(CHIP),
620074bb90dSTom Pothier 			    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE,
621074bb90dSTom Pothier 			    part, &perr);
622074bb90dSTom Pothier 			perr += topo_prop_set_string(chip, PGNAME(CHIP),
623074bb90dSTom Pothier 			    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE,
624074bb90dSTom Pothier 			    rev, &perr);
625074bb90dSTom Pothier 
626074bb90dSTom Pothier 			if (perr != 0)
627074bb90dSTom Pothier 				whinge(mod, NULL,
628074bb90dSTom Pothier 				    "create_chip: topo_prop_set_string"
629074bb90dSTom Pothier 				    "failed\n");
630074bb90dSTom Pothier 
631074bb90dSTom Pothier 			nvlist_free(fmri);
632074bb90dSTom Pothier 
633074bb90dSTom Pothier 			if (topo_node_label_set(chip, label, &perr)
634074bb90dSTom Pothier 			    == -1) {
635074bb90dSTom Pothier 				whinge(mod, NULL, "create_chip: "
636074bb90dSTom Pothier 				    "topo_node_label_set failed\n");
637074bb90dSTom Pothier 			}
638074bb90dSTom Pothier 			topo_mod_strfree(mod, label);
639074bb90dSTom Pothier 
640074bb90dSTom Pothier 		} else {
641074bb90dSTom Pothier 			if (topo_node_resource(chip, &fmri, &err) == -1) {
642074bb90dSTom Pothier 				whinge(mod, &nerr, "create_chip: "
643074bb90dSTom Pothier 				    "topo_node_resource failed\n");
644074bb90dSTom Pothier 			} else {
645074bb90dSTom Pothier 				(void) topo_node_fru_set(chip, fmri, 0, &perr);
646074bb90dSTom Pothier 				nvlist_free(fmri);
647074bb90dSTom Pothier 			}
648074bb90dSTom Pothier 		}
649074bb90dSTom Pothier 
650e4b86885SCheng Sean Ye 		if (topo_method_register(mod, chip, strands_retire_methods) < 0)
651e4b86885SCheng Sean Ye 			whinge(mod, &nerr, "create_chip: "
652e4b86885SCheng Sean Ye 			    "topo_method_register failed\n");
6537aec1d6eScindi 
6548031591dSSrihari Venkatesan 		if (topo_node_range_create(mod, chip, CORE_NODE_NAME, 0, 255))
655e4b86885SCheng Sean Ye 			return (-1);
656c93c462eSCheng Sean Ye 
6578031591dSSrihari Venkatesan 		if (strcmp(vendor, "AuthenticAMD") == 0) {
6588031591dSSrihari Venkatesan 			if (topo_node_range_create(mod, chip, MCT_NODE_NAME,
6598031591dSSrihari Venkatesan 			    0, 255))
6608031591dSSrihari Venkatesan 				return (-1);
6618031591dSSrihari Venkatesan 		}
6628031591dSSrihari Venkatesan 
663c93c462eSCheng Sean Ye 		create_mc = B_TRUE;
664f2dbfd32SRobert Mustacchi 
665f2dbfd32SRobert Mustacchi 		/*
666f2dbfd32SRobert Mustacchi 		 * Creating a temperature sensor may fail because the sensor
667f2dbfd32SRobert Mustacchi 		 * doesn't exist or due to internal reasons. At the moment, we
668f2dbfd32SRobert Mustacchi 		 * swallow any such errors that occur.
669f2dbfd32SRobert Mustacchi 		 */
670f2dbfd32SRobert Mustacchi 		(void) chip_create_chip_temp_sensor(mod, chip);
671e4b86885SCheng Sean Ye 	}
6727aec1d6eScindi 
673074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod)) {
674074bb90dSTom Pothier 		int status = 0;
675074bb90dSTom Pothier 		/*
676074bb90dSTom Pothier 		 * STATUS
677074bb90dSTom Pothier 		 * CPU Socket Populated
678074bb90dSTom Pothier 		 * CPU Socket Unpopulated
679074bb90dSTom Pothier 		 * Populated : Enabled
680074bb90dSTom Pothier 		 * Populated : Disabled by BIOS (Setup)
681074bb90dSTom Pothier 		 * Populated : Disabled by BIOS (Error)
682074bb90dSTom Pothier 		 * Populated : Idle
683074bb90dSTom Pothier 		 *
684074bb90dSTom Pothier 		 * Enumerate core & strand only for Populated : Enabled
685074bb90dSTom Pothier 		 * Enumerate Off-Chip Memory Controller only for
686074bb90dSTom Pothier 		 * Populated : Enabled
687074bb90dSTom Pothier 		 */
688074bb90dSTom Pothier 
689074bb90dSTom Pothier 		status = chip_status_smbios_get(mod, (id_t)smbios_id);
690074bb90dSTom Pothier 		if (!status) {
691074bb90dSTom Pothier 			whinge(mod, NULL, "create_chip: "
692074bb90dSTom Pothier 			    "CPU Socket is not populated or is disabled\n");
693074bb90dSTom Pothier 			return (0);
694074bb90dSTom Pothier 		}
695074bb90dSTom Pothier 	}
696074bb90dSTom Pothier 
697074bb90dSTom Pothier 	err = create_core(mod, chip, cpu, auth, smbios_id);
6989dd0f810Scindi 
699e4b86885SCheng Sean Ye 	/*
700e4b86885SCheng Sean Ye 	 * Create memory-controller node under a chip for architectures
701e4b86885SCheng Sean Ye 	 * that may have on-chip memory-controller(s).
702074bb90dSTom Pothier 	 * If SMBIOS meets FMA needs, when Multi-Chip-Module is
703074bb90dSTom Pothier 	 * addressed, mc instances should be derived from SMBIOS
704e4b86885SCheng Sean Ye 	 */
7058031591dSSrihari Venkatesan 	if (strcmp(vendor, "AuthenticAMD") == 0) {
7068031591dSSrihari Venkatesan 		amd_mc_create(mod, smbios_id, chip, MCT_NODE_NAME, auth,
7078031591dSSrihari Venkatesan 		    procnodeid, procnodes_per_pkg, family, model, &nerr);
7088031591dSSrihari Venkatesan 	} else if (create_mc && !mc_offchip)
7098031591dSSrihari Venkatesan 		onchip_mc_create(mod, smbios_id, chip, MCT_NODE_NAME, auth);
7107aec1d6eScindi 
711e4b86885SCheng Sean Ye 	return (err == 0 && nerr == 0 ? 0 : -1);
712e4b86885SCheng Sean Ye }
713e3d60c9bSAdrian Frost 
714e4b86885SCheng Sean Ye /*ARGSUSED*/
715e4b86885SCheng Sean Ye static int
create_chips(topo_mod_t * mod,tnode_t * pnode,const char * name,topo_instance_t min,topo_instance_t max,void * arg,nvlist_t * auth,int mc_offchip)716e4b86885SCheng Sean Ye create_chips(topo_mod_t *mod, tnode_t *pnode, const char *name,
717e4b86885SCheng Sean Ye     topo_instance_t min, topo_instance_t max, void *arg, nvlist_t *auth,
718e4b86885SCheng Sean Ye     int mc_offchip)
719e4b86885SCheng Sean Ye {
720e4b86885SCheng Sean Ye 	fmd_agent_hdl_t *hdl;
721e4b86885SCheng Sean Ye 	nvlist_t **cpus;
722e4b86885SCheng Sean Ye 	int nerr = 0;
723e4b86885SCheng Sean Ye 	uint_t i, ncpu;
724c26bf377SRob Johnston 	kstat_ctl_t *kc;
72520c794b3Sgavinm 
726e4b86885SCheng Sean Ye 	if (strcmp(name, CHIP_NODE_NAME) != 0)
727e4b86885SCheng Sean Ye 		return (0);
728e4b86885SCheng Sean Ye 
729e4b86885SCheng Sean Ye 	if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL)
730e4b86885SCheng Sean Ye 		return (-1);
731e4b86885SCheng Sean Ye 	if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) {
732e4b86885SCheng Sean Ye 		whinge(mod, NULL, "create_chip: fmd_agent_physcpu_info "
733e4b86885SCheng Sean Ye 		    "failed: %s\n", fmd_agent_errmsg(hdl));
734e4b86885SCheng Sean Ye 		fmd_agent_close(hdl);
735e4b86885SCheng Sean Ye 		return (-1);
7367aec1d6eScindi 	}
737e4b86885SCheng Sean Ye 	fmd_agent_close(hdl);
7387aec1d6eScindi 
739c26bf377SRob Johnston 	if ((kc = kstat_open()) == NULL) {
740c26bf377SRob Johnston 		whinge(mod, NULL, "kstat_open() failed");
741c26bf377SRob Johnston 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
742c26bf377SRob Johnston 	}
743c26bf377SRob Johnston 
744e4b86885SCheng Sean Ye 	for (i = 0; i < ncpu; i++) {
745e4b86885SCheng Sean Ye 		nerr -= create_chip(mod, pnode, min, max, cpus[i], auth,
746c26bf377SRob Johnston 		    mc_offchip, kc);
747e4b86885SCheng Sean Ye 		nvlist_free(cpus[i]);
748e4b86885SCheng Sean Ye 	}
749c26bf377SRob Johnston 	(void) kstat_close(kc);
750e4b86885SCheng Sean Ye 	umem_free(cpus, sizeof (nvlist_t *) * ncpu);
7517aec1d6eScindi 
7528a40a695Sgavinm 	if (nerr == 0) {
7538a40a695Sgavinm 		return (0);
7548a40a695Sgavinm 	} else {
7557aec1d6eScindi 		(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
7568a40a695Sgavinm 		return (-1);
7578a40a695Sgavinm 	}
7587aec1d6eScindi }
7597aec1d6eScindi 
7600eb822a1Scindi /*ARGSUSED*/
7617aec1d6eScindi static int
chip_enum(topo_mod_t * mod,tnode_t * pnode,const char * name,topo_instance_t min,topo_instance_t max,void * arg,void * smbios_enabled)7627aec1d6eScindi chip_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
763074bb90dSTom Pothier     topo_instance_t min, topo_instance_t max, void *arg, void *smbios_enabled)
7647aec1d6eScindi {
7650eb822a1Scindi 	int rv = 0;
7660eb822a1Scindi 	nvlist_t *auth = NULL;
767e3d60c9bSAdrian Frost 	int offchip_mc;
768e4b86885SCheng Sean Ye 	char buf[BUFSIZ];
769e4b86885SCheng Sean Ye 	const char *dom0 = "control_d";
770e4b86885SCheng Sean Ye 
771e4b86885SCheng Sean Ye 	/*
772e4b86885SCheng Sean Ye 	 * Create nothing if we're running in domU.
773e4b86885SCheng Sean Ye 	 */
774e4b86885SCheng Sean Ye 	if (sysinfo(SI_PLATFORM, buf, sizeof (buf)) == -1)
775e4b86885SCheng Sean Ye 		return (-1);
776e4b86885SCheng Sean Ye 
777e4b86885SCheng Sean Ye 	if (strncmp(buf, "i86pc", sizeof (buf)) != 0 &&
778e4b86885SCheng Sean Ye 	    strncmp(buf, "i86xpv", sizeof (buf)) != 0)
779e4b86885SCheng Sean Ye 		return (0);
780e4b86885SCheng Sean Ye 
781e4b86885SCheng Sean Ye 	if (strncmp(buf, "i86xpv", sizeof (buf)) == 0) {
782e4b86885SCheng Sean Ye 		int fd = open("/dev/xen/domcaps", O_RDONLY);
783e4b86885SCheng Sean Ye 
784e4b86885SCheng Sean Ye 		if (fd != -1) {
785e4b86885SCheng Sean Ye 			if (read(fd, buf, sizeof (buf)) <= 0 ||
786e4b86885SCheng Sean Ye 			    strncmp(buf, dom0, strlen(dom0)) != 0) {
787e4b86885SCheng Sean Ye 				(void) close(fd);
788e4b86885SCheng Sean Ye 				return (0);
789e4b86885SCheng Sean Ye 			}
790e4b86885SCheng Sean Ye 			(void) close(fd);
791e4b86885SCheng Sean Ye 		}
792e4b86885SCheng Sean Ye 	}
7930eb822a1Scindi 
794074bb90dSTom Pothier 	/*
795074bb90dSTom Pothier 	 * Set Chip Enumerator Module's private data with the value passed by
796074bb90dSTom Pothier 	 * x86pi Enumerator, defining SMBIOS capabilities
797074bb90dSTom Pothier 	 */
798074bb90dSTom Pothier 	topo_mod_setspecific(mod, smbios_enabled);
799074bb90dSTom Pothier 
800074bb90dSTom Pothier 	if (FM_AWARE_SMBIOS(mod))
801074bb90dSTom Pothier 		if (init_chip_smbios(mod) != 0) {
802074bb90dSTom Pothier 			whinge(mod, NULL,
803074bb90dSTom Pothier 			    "init_chip_smbios() failed, "
804074bb90dSTom Pothier 			    " enumerating x86pi & chip topology, but no"
805074bb90dSTom Pothier 			    " CPU & Memory properties will be"
806074bb90dSTom Pothier 			    " derived from SMBIOS\n");
807074bb90dSTom Pothier 			/*
808074bb90dSTom Pothier 			 * Lets reset the module specific
809074bb90dSTom Pothier 			 * data to NULL, overriding any
810074bb90dSTom Pothier 			 * SMBIOS capability encoded earlier.
811074bb90dSTom Pothier 			 * This will fail all subsequent
812074bb90dSTom Pothier 			 * FM_AWARE_SMBIOS checks.
813074bb90dSTom Pothier 			 */
814074bb90dSTom Pothier 			topo_mod_setspecific(mod, NULL);
815074bb90dSTom Pothier 		}
816074bb90dSTom Pothier 
8170eb822a1Scindi 	auth = topo_mod_auth(mod, pnode);
8187aec1d6eScindi 
819e3d60c9bSAdrian Frost 	offchip_mc = mc_offchip_open();
8209dd0f810Scindi 	if (strcmp(name, CHIP_NODE_NAME) == 0)
821e4b86885SCheng Sean Ye 		rv = create_chips(mod, pnode, name, min, max, NULL, auth,
822e3d60c9bSAdrian Frost 		    offchip_mc);
8237aec1d6eScindi 
824e3d60c9bSAdrian Frost 	if (offchip_mc)
82520c794b3Sgavinm 		(void) mc_offchip_create(mod, pnode, "memory-controller", auth);
82620c794b3Sgavinm 
8270eb822a1Scindi 	nvlist_free(auth);
8280eb822a1Scindi 
8290eb822a1Scindi 	return (rv);
8307aec1d6eScindi }
831