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