1074bb90dSTom Pothier /*
2074bb90dSTom Pothier * CDDL HEADER START
3074bb90dSTom Pothier *
4074bb90dSTom Pothier * The contents of this file are subject to the terms of the
5074bb90dSTom Pothier * Common Development and Distribution License (the "License").
6074bb90dSTom Pothier * You may not use this file except in compliance with the License.
7074bb90dSTom Pothier *
8074bb90dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9074bb90dSTom Pothier * or http://www.opensolaris.org/os/licensing.
10074bb90dSTom Pothier * See the License for the specific language governing permissions
11074bb90dSTom Pothier * and limitations under the License.
12074bb90dSTom Pothier *
13074bb90dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each
14074bb90dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15074bb90dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the
16074bb90dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying
17074bb90dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner]
18074bb90dSTom Pothier *
19074bb90dSTom Pothier * CDDL HEADER END
20074bb90dSTom Pothier */
21074bb90dSTom Pothier
22074bb90dSTom Pothier /*
23efd31e1dSTrang Do * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24074bb90dSTom Pothier */
25074bb90dSTom Pothier
26074bb90dSTom Pothier #include <unistd.h>
27074bb90dSTom Pothier #include <ctype.h>
28074bb90dSTom Pothier #include <strings.h>
29074bb90dSTom Pothier #include <sys/types.h>
30074bb90dSTom Pothier #include <sys/devfm.h>
31074bb90dSTom Pothier #include <libnvpair.h>
32074bb90dSTom Pothier #include <sys/smbios.h>
33074bb90dSTom Pothier #include <fm/topo_mod.h>
34074bb90dSTom Pothier #include <sys/fm/protocol.h>
35074bb90dSTom Pothier #include <sys/smbios_impl.h>
36074bb90dSTom Pothier
37074bb90dSTom Pothier #include "chip.h"
38074bb90dSTom Pothier
39074bb90dSTom Pothier #define CPU_SLOTS 64
40074bb90dSTom Pothier #define DIMM_SLOTS 512
41074bb90dSTom Pothier #define MC_INSTANCES 128
42074bb90dSTom Pothier
43074bb90dSTom Pothier #define MAXNAMELEN 256
44074bb90dSTom Pothier #define LABEL 1
45074bb90dSTom Pothier
46074bb90dSTom Pothier #define SKIP_CS 9999
47074bb90dSTom Pothier
48074bb90dSTom Pothier
49074bb90dSTom Pothier typedef struct cpu_smbios {
50074bb90dSTom Pothier id_t cpu_id;
51074bb90dSTom Pothier uint8_t status;
52074bb90dSTom Pothier uint8_t fru;
53074bb90dSTom Pothier }csmb_t;
54074bb90dSTom Pothier
55074bb90dSTom Pothier typedef struct dimm_smbios {
56074bb90dSTom Pothier id_t dimm_id;
57074bb90dSTom Pothier id_t extdimm_id;
58074bb90dSTom Pothier const char *bankloc;
59074bb90dSTom Pothier }dsmb_t;
60074bb90dSTom Pothier
61074bb90dSTom Pothier typedef struct mct_smbios {
62074bb90dSTom Pothier id_t extmct_id;
63074bb90dSTom Pothier id_t mct_id;
64074bb90dSTom Pothier id_t p_id;
65074bb90dSTom Pothier }msmb_t;
66074bb90dSTom Pothier
67074bb90dSTom Pothier csmb_t cpusmb[CPU_SLOTS];
68074bb90dSTom Pothier dsmb_t dimmsmb[DIMM_SLOTS];
69074bb90dSTom Pothier msmb_t mctsmb[MC_INSTANCES];
70074bb90dSTom Pothier
71074bb90dSTom Pothier static int ncpu_ids = 0;
72074bb90dSTom Pothier static int bb_count = 0;
73074bb90dSTom Pothier static int ndimm_ids, nmct_ids = 0;
74074bb90dSTom Pothier
75074bb90dSTom Pothier static int fill_chip_smbios = 0;
76074bb90dSTom Pothier typedef int smbios_rec_f(topo_mod_t *, const smbios_struct_t *);
77074bb90dSTom Pothier
78074bb90dSTom Pothier static smbios_struct_t *
smb_export(const smb_struct_t * stp,smbios_struct_t * sp)79074bb90dSTom Pothier smb_export(const smb_struct_t *stp, smbios_struct_t *sp)
80074bb90dSTom Pothier {
81074bb90dSTom Pothier const smb_header_t *hdr;
82074bb90dSTom Pothier
83074bb90dSTom Pothier if (stp == NULL)
84074bb90dSTom Pothier return (NULL);
85074bb90dSTom Pothier
86074bb90dSTom Pothier hdr = stp->smbst_hdr;
87074bb90dSTom Pothier sp->smbstr_id = hdr->smbh_hdl;
88074bb90dSTom Pothier sp->smbstr_type = hdr->smbh_type;
89074bb90dSTom Pothier sp->smbstr_data = hdr;
90074bb90dSTom Pothier sp->smbstr_size = (size_t)(stp->smbst_end - (uchar_t *)hdr);
91074bb90dSTom Pothier
92074bb90dSTom Pothier return (sp);
93074bb90dSTom Pothier }
94074bb90dSTom Pothier
95074bb90dSTom Pothier static int
extdimmslot_to_dimmslot(topo_mod_t * mod,id_t chip_smbid,int channum,int csnum)96efd31e1dSTrang Do extdimmslot_to_dimmslot(topo_mod_t *mod, id_t chip_smbid, int channum,
97efd31e1dSTrang Do int csnum)
98074bb90dSTom Pothier {
99074bb90dSTom Pothier smbios_memdevice_ext_t emd;
100074bb90dSTom Pothier smbios_memdevice_t md;
101*679a141eSToomas Soome int i, j;
102074bb90dSTom Pothier int match = 0;
103efd31e1dSTrang Do smbios_hdl_t *shp;
104efd31e1dSTrang Do
105efd31e1dSTrang Do shp = topo_mod_smbios(mod);
106efd31e1dSTrang Do if (shp == NULL)
107efd31e1dSTrang Do return (-1);
108074bb90dSTom Pothier
109074bb90dSTom Pothier if (chip_smbid == IGNORE_ID && bb_count <= 1 && nmct_ids <= 1) {
110074bb90dSTom Pothier for (i = 0; i < ndimm_ids; i++) {
111*679a141eSToomas Soome if (smbios_info_extmemdevice(shp, dimmsmb[i].extdimm_id,
112*679a141eSToomas Soome &emd) != 0) {
113*679a141eSToomas Soome continue;
114*679a141eSToomas Soome }
115*679a141eSToomas Soome
116074bb90dSTom Pothier if (emd.smbmdeve_drch == channum) {
117*679a141eSToomas Soome uint_t ncs;
118*679a141eSToomas Soome uint8_t *cs;
119*679a141eSToomas Soome
120*679a141eSToomas Soome if (csnum == SKIP_CS) {
121074bb90dSTom Pothier return (emd.smbmdeve_md);
122*679a141eSToomas Soome }
123*679a141eSToomas Soome
124*679a141eSToomas Soome if (smbios_info_extmemdevice_cs(shp,
125*679a141eSToomas Soome dimmsmb[i].extdimm_id, &ncs, &cs) != 0) {
126*679a141eSToomas Soome continue;
127*679a141eSToomas Soome }
128*679a141eSToomas Soome
129*679a141eSToomas Soome for (uint_t k = 0; k < ncs; k++) {
130*679a141eSToomas Soome if (cs[k] != csnum) {
131*679a141eSToomas Soome continue;
132*679a141eSToomas Soome }
133*679a141eSToomas Soome
134*679a141eSToomas Soome smbios_info_extmemdevice_cs_free(shp,
135*679a141eSToomas Soome ncs, cs);
136*679a141eSToomas Soome return (emd.smbmdeve_md);
137*679a141eSToomas Soome }
138*679a141eSToomas Soome
139*679a141eSToomas Soome smbios_info_extmemdevice_cs_free(shp, ncs, cs);
140074bb90dSTom Pothier }
141074bb90dSTom Pothier }
142074bb90dSTom Pothier }
143074bb90dSTom Pothier
144074bb90dSTom Pothier for (j = 0; j < nmct_ids; j++) {
145074bb90dSTom Pothier if (mctsmb[j].p_id == chip_smbid) {
146074bb90dSTom Pothier for (i = 0; i < ndimm_ids; i++) {
147*679a141eSToomas Soome if (smbios_info_extmemdevice(shp,
148*679a141eSToomas Soome dimmsmb[i].extdimm_id, &emd) != 0) {
149*679a141eSToomas Soome continue;
150*679a141eSToomas Soome }
151*679a141eSToomas Soome
152074bb90dSTom Pothier (void) smbios_info_memdevice(shp,
153074bb90dSTom Pothier emd.smbmdeve_md, &md);
154074bb90dSTom Pothier if (md.smbmd_array == mctsmb[j].mct_id &&
155074bb90dSTom Pothier emd.smbmdeve_drch == channum) {
156074bb90dSTom Pothier match = 1;
157074bb90dSTom Pothier break;
158074bb90dSTom Pothier }
159074bb90dSTom Pothier }
160074bb90dSTom Pothier if (match) {
161*679a141eSToomas Soome uint_t ncs;
162*679a141eSToomas Soome uint8_t *cs;
163*679a141eSToomas Soome
164*679a141eSToomas Soome if (csnum == SKIP_CS) {
165*679a141eSToomas Soome return (emd.smbmdeve_md);
166*679a141eSToomas Soome }
167*679a141eSToomas Soome
168*679a141eSToomas Soome if (smbios_info_extmemdevice_cs(shp,
169*679a141eSToomas Soome dimmsmb[i].extdimm_id, &ncs, &cs) != 0) {
170*679a141eSToomas Soome continue;
171*679a141eSToomas Soome }
172*679a141eSToomas Soome
173*679a141eSToomas Soome for (uint_t k = 0; k < ncs; k++) {
174*679a141eSToomas Soome if (cs[k] != csnum) {
175*679a141eSToomas Soome continue;
176*679a141eSToomas Soome }
177*679a141eSToomas Soome
178*679a141eSToomas Soome smbios_info_extmemdevice_cs_free(shp,
179*679a141eSToomas Soome ncs, cs);
180074bb90dSTom Pothier return (emd.smbmdeve_md);
181*679a141eSToomas Soome }
182*679a141eSToomas Soome smbios_info_extmemdevice_cs_free(shp, ncs, cs);
183074bb90dSTom Pothier }
184074bb90dSTom Pothier }
185074bb90dSTom Pothier }
186074bb90dSTom Pothier
187074bb90dSTom Pothier return (-1);
188074bb90dSTom Pothier }
189074bb90dSTom Pothier
190074bb90dSTom Pothier id_t
memnode_to_smbiosid(topo_mod_t * mod,uint16_t chip_smbid,const char * name,uint64_t nodeid,void * data)191efd31e1dSTrang Do memnode_to_smbiosid(topo_mod_t *mod, uint16_t chip_smbid, const char *name,
192efd31e1dSTrang Do uint64_t nodeid, void *data)
193074bb90dSTom Pothier {
194074bb90dSTom Pothier
195074bb90dSTom Pothier if (strcmp(name, CS_NODE_NAME) == 0) {
196074bb90dSTom Pothier int channum, csnum;
197074bb90dSTom Pothier id_t dimmslot = -1;
198074bb90dSTom Pothier
199074bb90dSTom Pothier if (data == NULL)
200074bb90dSTom Pothier return (-1);
201074bb90dSTom Pothier channum = *(int *)data;
202074bb90dSTom Pothier csnum = nodeid;
203074bb90dSTom Pothier /*
204074bb90dSTom Pothier * Set the DIMM Slot label to the Chip Select Node
205074bb90dSTom Pothier * Set the "data" to carry the DIMM instance
206074bb90dSTom Pothier */
207efd31e1dSTrang Do dimmslot = extdimmslot_to_dimmslot(mod, chip_smbid, channum,
208efd31e1dSTrang Do csnum);
209074bb90dSTom Pothier if (dimmslot != -1 && dimmsmb[0].dimm_id != 0)
210074bb90dSTom Pothier *((id_t *)data) = dimmslot % (dimmsmb[0].dimm_id);
211074bb90dSTom Pothier else
212074bb90dSTom Pothier *((id_t *)data) = -1;
213074bb90dSTom Pothier
214074bb90dSTom Pothier return (dimmslot);
215074bb90dSTom Pothier
216074bb90dSTom Pothier } else if (strcmp(name, DIMM_NODE_NAME) == 0) {
217074bb90dSTom Pothier static int dimmnum = 0;
218074bb90dSTom Pothier
219074bb90dSTom Pothier /*
220074bb90dSTom Pothier * On certain Intel Chips, topology does not have
221074bb90dSTom Pothier * chip-select nodes, it has the below layout
222074bb90dSTom Pothier * chip/memory-controller/dram-channel/dimm
223074bb90dSTom Pothier * so we check if channel instance is passed
224074bb90dSTom Pothier * and get the SMBIOS ID based on the channel
225074bb90dSTom Pothier */
226074bb90dSTom Pothier if (data != NULL) {
227074bb90dSTom Pothier int channum;
228074bb90dSTom Pothier id_t dimmslot = -1;
229074bb90dSTom Pothier
230074bb90dSTom Pothier channum = *(int *)data;
231efd31e1dSTrang Do dimmslot = extdimmslot_to_dimmslot(mod, chip_smbid,
232074bb90dSTom Pothier channum, SKIP_CS);
233074bb90dSTom Pothier
234074bb90dSTom Pothier return (dimmslot);
235074bb90dSTom Pothier }
236074bb90dSTom Pothier dimmnum = nodeid;
237074bb90dSTom Pothier return (dimmsmb[dimmnum].dimm_id);
238074bb90dSTom Pothier }
239074bb90dSTom Pothier
240074bb90dSTom Pothier return (-1);
241074bb90dSTom Pothier }
242074bb90dSTom Pothier
243074bb90dSTom Pothier
244074bb90dSTom Pothier int
chip_get_smbstruct(topo_mod_t * mod,const smbios_struct_t * sp)245074bb90dSTom Pothier chip_get_smbstruct(topo_mod_t *mod, const smbios_struct_t *sp)
246074bb90dSTom Pothier {
247074bb90dSTom Pothier smbios_processor_t p;
248074bb90dSTom Pothier smbios_memdevice_t md;
249074bb90dSTom Pothier smbios_processor_ext_t extp;
250074bb90dSTom Pothier smbios_memarray_ext_t extma;
251bb1fad37SSrihari Venkatesan smbios_memdevice_ext_t extmd;
252bb1fad37SSrihari Venkatesan int ext_match = 0;
253efd31e1dSTrang Do smbios_hdl_t *shp;
254efd31e1dSTrang Do
255efd31e1dSTrang Do shp = topo_mod_smbios(mod);
256efd31e1dSTrang Do if (shp == NULL)
257efd31e1dSTrang Do return (-1);
258074bb90dSTom Pothier
259074bb90dSTom Pothier switch (sp->smbstr_type) {
260074bb90dSTom Pothier case SMB_TYPE_BASEBOARD:
261074bb90dSTom Pothier bb_count++;
262074bb90dSTom Pothier break;
263074bb90dSTom Pothier case SMB_TYPE_MEMARRAY:
264074bb90dSTom Pothier mctsmb[nmct_ids].mct_id = sp->smbstr_id;
265bb1fad37SSrihari Venkatesan nmct_ids++;
266074bb90dSTom Pothier break;
267074bb90dSTom Pothier case SUN_OEM_EXT_MEMARRAY:
268074bb90dSTom Pothier if (shp != NULL) {
269074bb90dSTom Pothier if (smbios_info_extmemarray(shp,
270074bb90dSTom Pothier sp->smbstr_id, &extma) != 0) {
271074bb90dSTom Pothier topo_mod_dprintf(mod, "chip_get_smbstruct : "
272074bb90dSTom Pothier "smbios_info_extmemarray()"
273074bb90dSTom Pothier "failed\n");
274074bb90dSTom Pothier return (-1);
275074bb90dSTom Pothier }
276074bb90dSTom Pothier } else
277074bb90dSTom Pothier return (-1);
278bb1fad37SSrihari Venkatesan for (int i = 0; i < nmct_ids; i++) {
279bb1fad37SSrihari Venkatesan if (extma.smbmae_ma == mctsmb[i].mct_id) {
280bb1fad37SSrihari Venkatesan mctsmb[i].extmct_id = sp->smbstr_id;
281bb1fad37SSrihari Venkatesan mctsmb[i].p_id = extma.smbmae_comp;
282bb1fad37SSrihari Venkatesan ext_match = 1;
283bb1fad37SSrihari Venkatesan break;
284bb1fad37SSrihari Venkatesan }
285bb1fad37SSrihari Venkatesan }
286bb1fad37SSrihari Venkatesan if (!ext_match) {
287bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_get_smbstruct : "
288bb1fad37SSrihari Venkatesan "EXT_MEMARRAY-MEMARRAY records are mismatched\n");
289bb1fad37SSrihari Venkatesan ext_match = 0;
290074bb90dSTom Pothier return (-1);
291bb1fad37SSrihari Venkatesan }
292074bb90dSTom Pothier break;
293074bb90dSTom Pothier case SMB_TYPE_MEMDEVICE:
294074bb90dSTom Pothier dimmsmb[ndimm_ids].dimm_id = sp->smbstr_id;
295074bb90dSTom Pothier if (shp != NULL) {
296074bb90dSTom Pothier if (smbios_info_memdevice(shp,
297074bb90dSTom Pothier sp->smbstr_id, &md) != 0)
298074bb90dSTom Pothier return (-1);
299074bb90dSTom Pothier } else
300074bb90dSTom Pothier return (-1);
301074bb90dSTom Pothier dimmsmb[ndimm_ids].bankloc = md.smbmd_bloc;
302bb1fad37SSrihari Venkatesan ndimm_ids++;
303074bb90dSTom Pothier break;
304074bb90dSTom Pothier /*
305074bb90dSTom Pothier * Every SMB_TYPE_MEMDEVICE SHOULD have a
306074bb90dSTom Pothier * corresponding SUN_OEM_EXT_MEMDEVICE
307074bb90dSTom Pothier */
308074bb90dSTom Pothier case SUN_OEM_EXT_MEMDEVICE:
309bb1fad37SSrihari Venkatesan if (smbios_info_extmemdevice(shp,
310bb1fad37SSrihari Venkatesan sp->smbstr_id, &extmd) != 0) {
311bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_get_smbstruct : "
312bb1fad37SSrihari Venkatesan "smbios_info_extmemdevice()"
313bb1fad37SSrihari Venkatesan "failed\n");
314bb1fad37SSrihari Venkatesan return (-1);
315bb1fad37SSrihari Venkatesan }
316bb1fad37SSrihari Venkatesan for (int i = 0; i < ndimm_ids; i++) {
317bb1fad37SSrihari Venkatesan if (extmd.smbmdeve_md == dimmsmb[i].dimm_id) {
318bb1fad37SSrihari Venkatesan dimmsmb[i].extdimm_id = sp->smbstr_id;
319bb1fad37SSrihari Venkatesan ext_match = 1;
320bb1fad37SSrihari Venkatesan break;
321bb1fad37SSrihari Venkatesan }
322bb1fad37SSrihari Venkatesan }
323bb1fad37SSrihari Venkatesan if (!ext_match) {
324bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_get_smbstruct : "
325bb1fad37SSrihari Venkatesan "EXT_MEMDEVICE-MEMDEVICE records are mismatched\n");
326bb1fad37SSrihari Venkatesan ext_match = 0;
327bb1fad37SSrihari Venkatesan return (-1);
328bb1fad37SSrihari Venkatesan }
329074bb90dSTom Pothier break;
330074bb90dSTom Pothier case SMB_TYPE_PROCESSOR:
331074bb90dSTom Pothier cpusmb[ncpu_ids].cpu_id = sp->smbstr_id;
332074bb90dSTom Pothier if (shp != NULL) {
333074bb90dSTom Pothier if (smbios_info_processor(shp,
334074bb90dSTom Pothier sp->smbstr_id, &p) != 0) {
335074bb90dSTom Pothier topo_mod_dprintf(mod, "chip_get_smbstruct : "
336074bb90dSTom Pothier "smbios_info_processor()"
337074bb90dSTom Pothier "failed\n");
338074bb90dSTom Pothier return (-1);
339074bb90dSTom Pothier }
340074bb90dSTom Pothier }
341074bb90dSTom Pothier cpusmb[ncpu_ids].status = p.smbp_status;
342bb1fad37SSrihari Venkatesan ncpu_ids++;
343074bb90dSTom Pothier break;
344074bb90dSTom Pothier /*
345074bb90dSTom Pothier * Every SMB_TYPE_PROCESSOR SHOULD have a
346074bb90dSTom Pothier * corresponding SUN_OEM_EXT_PROCESSOR
347074bb90dSTom Pothier */
348074bb90dSTom Pothier case SUN_OEM_EXT_PROCESSOR:
349074bb90dSTom Pothier if (smbios_info_extprocessor(shp,
350074bb90dSTom Pothier sp->smbstr_id, &extp) != 0) {
351074bb90dSTom Pothier topo_mod_dprintf(mod, "chip_get_smbstruct : "
352074bb90dSTom Pothier "smbios_info_extprocessor()"
353074bb90dSTom Pothier "failed\n");
354074bb90dSTom Pothier return (-1);
355074bb90dSTom Pothier }
356bb1fad37SSrihari Venkatesan for (int i = 0; i < ncpu_ids; i++) {
357bb1fad37SSrihari Venkatesan if (extp.smbpe_processor == cpusmb[i].cpu_id) {
358bb1fad37SSrihari Venkatesan cpusmb[i].fru = extp.smbpe_fru;
359bb1fad37SSrihari Venkatesan ext_match = 1;
360bb1fad37SSrihari Venkatesan break;
361bb1fad37SSrihari Venkatesan }
362bb1fad37SSrihari Venkatesan }
363bb1fad37SSrihari Venkatesan if (!ext_match) {
364bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_get_smbstruct : "
365bb1fad37SSrihari Venkatesan "EXT_PROCESSOR-PROCESSOR records are mismatched\n");
366bb1fad37SSrihari Venkatesan ext_match = 0;
367bb1fad37SSrihari Venkatesan return (-1);
368bb1fad37SSrihari Venkatesan }
369074bb90dSTom Pothier break;
370074bb90dSTom Pothier }
371074bb90dSTom Pothier return (0);
372074bb90dSTom Pothier }
373074bb90dSTom Pothier
374074bb90dSTom Pothier static int
chip_smbios_iterate(topo_mod_t * mod,smbios_rec_f * func_iter)375074bb90dSTom Pothier chip_smbios_iterate(topo_mod_t *mod, smbios_rec_f *func_iter)
376074bb90dSTom Pothier {
377efd31e1dSTrang Do const smb_struct_t *sp;
378074bb90dSTom Pothier smbios_struct_t s;
379074bb90dSTom Pothier int i, rv = 0;
380efd31e1dSTrang Do smbios_hdl_t *shp;
381074bb90dSTom Pothier
382efd31e1dSTrang Do shp = topo_mod_smbios(mod);
383efd31e1dSTrang Do if (shp == NULL)
384efd31e1dSTrang Do return (rv);
385efd31e1dSTrang Do
386efd31e1dSTrang Do sp = shp->sh_structs;
387074bb90dSTom Pothier for (i = 0; i < shp->sh_nstructs; i++, sp++) {
388074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type != SMB_TYPE_INACTIVE &&
389074bb90dSTom Pothier (rv = func_iter(mod, smb_export(sp, &s))) != 0)
390074bb90dSTom Pothier break;
391074bb90dSTom Pothier }
392074bb90dSTom Pothier return (rv);
393074bb90dSTom Pothier }
394074bb90dSTom Pothier
395074bb90dSTom Pothier int
init_chip_smbios(topo_mod_t * mod)396074bb90dSTom Pothier init_chip_smbios(topo_mod_t *mod)
397074bb90dSTom Pothier {
398074bb90dSTom Pothier if (!fill_chip_smbios) {
399074bb90dSTom Pothier if (chip_smbios_iterate(mod, chip_get_smbstruct) == -1)
400074bb90dSTom Pothier return (-1);
401074bb90dSTom Pothier fill_chip_smbios = 1;
402074bb90dSTom Pothier }
403074bb90dSTom Pothier
404074bb90dSTom Pothier return (0);
405074bb90dSTom Pothier }
406074bb90dSTom Pothier
407074bb90dSTom Pothier int
chip_status_smbios_get(topo_mod_t * mod,id_t smb_id)408074bb90dSTom Pothier chip_status_smbios_get(topo_mod_t *mod, id_t smb_id)
409074bb90dSTom Pothier {
410074bb90dSTom Pothier /*
411074bb90dSTom Pothier * Type-4 Socket Status bit definitions per SMBIOS Version 2.6
412074bb90dSTom Pothier *
413074bb90dSTom Pothier * STATUS
414074bb90dSTom Pothier * CPU Socket Populated
415074bb90dSTom Pothier * CPU Socket Unpopulated
416074bb90dSTom Pothier * Populated : Enabled
417074bb90dSTom Pothier * Populated : Disabled by BIOS (Setup)
418074bb90dSTom Pothier * Populated : Disabled by BIOS (Error)
419074bb90dSTom Pothier * Populated : Idle
420074bb90dSTom Pothier */
421074bb90dSTom Pothier uint8_t enabled = 0x01;
422074bb90dSTom Pothier uint8_t populated = 0x40;
423074bb90dSTom Pothier
424074bb90dSTom Pothier for (int i = 0; i < ncpu_ids; i++) {
425074bb90dSTom Pothier if (smb_id == cpusmb[i].cpu_id) {
426074bb90dSTom Pothier if (cpusmb[i].status == (enabled | populated))
427074bb90dSTom Pothier return (1);
428074bb90dSTom Pothier }
429074bb90dSTom Pothier }
430074bb90dSTom Pothier
431bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_status_smbios_get() failed"
4326597d6fcSRobert Mustacchi " considering that Type 4 ID : %ld is disabled", smb_id);
433074bb90dSTom Pothier return (0);
434074bb90dSTom Pothier }
435074bb90dSTom Pothier
436074bb90dSTom Pothier int
chip_fru_smbios_get(topo_mod_t * mod,id_t smb_id)437074bb90dSTom Pothier chip_fru_smbios_get(topo_mod_t *mod, id_t smb_id)
438074bb90dSTom Pothier {
439074bb90dSTom Pothier /*
440074bb90dSTom Pothier * smbios_processor_ext_t->smbpe_fru : if set to 1
441074bb90dSTom Pothier * processor is a FRU
442074bb90dSTom Pothier */
443074bb90dSTom Pothier uint8_t fru = 1;
444074bb90dSTom Pothier
445074bb90dSTom Pothier for (int i = 0; i < ncpu_ids; i++) {
446074bb90dSTom Pothier if (smb_id == cpusmb[i].cpu_id) {
447074bb90dSTom Pothier if (cpusmb[i].fru == fru)
448074bb90dSTom Pothier return (1);
449074bb90dSTom Pothier else
450074bb90dSTom Pothier return (0);
451074bb90dSTom Pothier }
452074bb90dSTom Pothier }
453074bb90dSTom Pothier
454bb1fad37SSrihari Venkatesan topo_mod_dprintf(mod, "chip_fru_smbios_get() failed"
4556597d6fcSRobert Mustacchi " considering that Type 4 ID : %ld is not a FRU", smb_id);
456074bb90dSTom Pothier return (0);
457074bb90dSTom Pothier }
458074bb90dSTom Pothier
459074bb90dSTom Pothier /*
460074bb90dSTom Pothier * This could be defined as topo_mod_strlen()
461074bb90dSTom Pothier */
462074bb90dSTom Pothier size_t
chip_strlen(const char * str)463074bb90dSTom Pothier chip_strlen(const char *str)
464074bb90dSTom Pothier {
465074bb90dSTom Pothier int len = 0;
466074bb90dSTom Pothier
467074bb90dSTom Pothier if (str != NULL)
468074bb90dSTom Pothier len = strlen(str);
469074bb90dSTom Pothier
470074bb90dSTom Pothier return (len);
471074bb90dSTom Pothier }
472074bb90dSTom Pothier
473074bb90dSTom Pothier /*
474074bb90dSTom Pothier * We clean Serials, Revisions, Part No. strings, to
475074bb90dSTom Pothier * avoid getting lost when fmd synthesizes these
476074bb90dSTom Pothier * strings. :, =, /, ' ' characters are replaced
477074bb90dSTom Pothier * with character '-' any non-printable characters
478074bb90dSTom Pothier * as seen with !isprint() is also replaced with '-'
479074bb90dSTom Pothier * Labels are checked only for non-printable characters.
480074bb90dSTom Pothier */
481074bb90dSTom Pothier static const char *
chip_cleanup_smbios_str(topo_mod_t * mod,const char * begin,int str_type)482074bb90dSTom Pothier chip_cleanup_smbios_str(topo_mod_t *mod, const char *begin, int str_type)
483074bb90dSTom Pothier {
484074bb90dSTom Pothier char buf[MAXNAMELEN];
485074bb90dSTom Pothier const char *end, *cp;
486074bb90dSTom Pothier char *pp;
487074bb90dSTom Pothier char c;
488074bb90dSTom Pothier int i;
489074bb90dSTom Pothier
490074bb90dSTom Pothier end = begin + strlen(begin);
491074bb90dSTom Pothier
492074bb90dSTom Pothier while (begin < end && isspace(*begin))
493074bb90dSTom Pothier begin++;
494074bb90dSTom Pothier while (begin < end && isspace(*(end - 1)))
495074bb90dSTom Pothier end--;
496074bb90dSTom Pothier
497074bb90dSTom Pothier if (begin >= end)
498074bb90dSTom Pothier return (NULL);
499074bb90dSTom Pothier
500074bb90dSTom Pothier cp = begin;
501074bb90dSTom Pothier for (i = 0; i < MAXNAMELEN - 1; i++) {
502074bb90dSTom Pothier if (cp >= end)
503074bb90dSTom Pothier break;
504074bb90dSTom Pothier c = *cp;
505074bb90dSTom Pothier if (str_type == LABEL) {
506074bb90dSTom Pothier if (!isprint(c))
507074bb90dSTom Pothier buf[i] = '-';
508074bb90dSTom Pothier else
509074bb90dSTom Pothier buf[i] = c;
510074bb90dSTom Pothier } else {
511074bb90dSTom Pothier if (c == ':' || c == '=' || c == '/' ||
512074bb90dSTom Pothier isspace(c) || !isprint(c))
513074bb90dSTom Pothier buf[i] = '-';
514074bb90dSTom Pothier else
515074bb90dSTom Pothier buf[i] = c;
516074bb90dSTom Pothier }
517074bb90dSTom Pothier cp++;
518074bb90dSTom Pothier }
519074bb90dSTom Pothier buf[i] = 0;
520074bb90dSTom Pothier
521074bb90dSTom Pothier pp = topo_mod_strdup(mod, buf);
522074bb90dSTom Pothier
523074bb90dSTom Pothier if (str_type == LABEL)
524074bb90dSTom Pothier topo_mod_strfree(mod, (char *)begin);
525074bb90dSTom Pothier
526074bb90dSTom Pothier return (pp);
527074bb90dSTom Pothier }
528074bb90dSTom Pothier
529074bb90dSTom Pothier const char *
chip_label_smbios_get(topo_mod_t * mod,tnode_t * pnode,id_t smb_id,char * ksmbios_label)530074bb90dSTom Pothier chip_label_smbios_get(topo_mod_t *mod, tnode_t *pnode, id_t smb_id,
531074bb90dSTom Pothier char *ksmbios_label)
532074bb90dSTom Pothier {
533074bb90dSTom Pothier smbios_info_t c;
534074bb90dSTom Pothier char *label = NULL;
535074bb90dSTom Pothier char *buf = NULL;
536074bb90dSTom Pothier const char *lsmbios_label = NULL;
537074bb90dSTom Pothier int bufsz = 0;
538074bb90dSTom Pothier char *delim = NULL, *blank = " ";
539074bb90dSTom Pothier const char *dimm_bank = NULL;
540074bb90dSTom Pothier const char *clean_label = NULL;
541074bb90dSTom Pothier int err;
542efd31e1dSTrang Do smbios_hdl_t *shp;
543074bb90dSTom Pothier
544efd31e1dSTrang Do shp = topo_mod_smbios(mod);
545074bb90dSTom Pothier if (shp != NULL) {
546074bb90dSTom Pothier /*
547074bb90dSTom Pothier * Get Parent FRU's label
548074bb90dSTom Pothier */
549074bb90dSTom Pothier if (topo_prop_get_string(pnode, TOPO_PGROUP_PROTOCOL,
550074bb90dSTom Pothier TOPO_PROP_LABEL, &label, &err) == -1)
551074bb90dSTom Pothier topo_mod_dprintf(mod, "Failed to get"
552074bb90dSTom Pothier " Label of Parent Node error : %d\n", err);
553074bb90dSTom Pothier
554074bb90dSTom Pothier if (label != NULL)
555074bb90dSTom Pothier label = (char *)chip_cleanup_smbios_str(mod,
556074bb90dSTom Pothier label, LABEL);
557074bb90dSTom Pothier
558074bb90dSTom Pothier /*
559074bb90dSTom Pothier * On Intel the driver gets the label from ksmbios
560074bb90dSTom Pothier * so we check if we already have it, if not we
561074bb90dSTom Pothier * get it from libsmbios
562074bb90dSTom Pothier */
563074bb90dSTom Pothier if (ksmbios_label == NULL && smb_id != -1) {
564074bb90dSTom Pothier if (smbios_info_common(shp, smb_id, &c) != SMB_ERR) {
565074bb90dSTom Pothier for (int i = 0; i < ndimm_ids; i++) {
566074bb90dSTom Pothier if (smb_id == dimmsmb[i].dimm_id) {
567074bb90dSTom Pothier dimm_bank = dimmsmb[i].bankloc;
568074bb90dSTom Pothier break;
569074bb90dSTom Pothier }
570074bb90dSTom Pothier }
571074bb90dSTom Pothier if (dimm_bank != NULL) {
572074bb90dSTom Pothier bufsz += chip_strlen(blank) +
573074bb90dSTom Pothier chip_strlen(dimm_bank);
574074bb90dSTom Pothier }
575074bb90dSTom Pothier lsmbios_label = c.smbi_location;
576074bb90dSTom Pothier }
577074bb90dSTom Pothier } else
578074bb90dSTom Pothier lsmbios_label = ksmbios_label;
579074bb90dSTom Pothier
580074bb90dSTom Pothier if (label != NULL && lsmbios_label != NULL)
581074bb90dSTom Pothier delim = "/";
582074bb90dSTom Pothier
583074bb90dSTom Pothier bufsz += chip_strlen(label) + chip_strlen(delim) +
584074bb90dSTom Pothier chip_strlen(lsmbios_label) + 1;
585074bb90dSTom Pothier
586074bb90dSTom Pothier buf = topo_mod_alloc(mod, bufsz);
587074bb90dSTom Pothier
588074bb90dSTom Pothier if (buf != NULL) {
589074bb90dSTom Pothier if (label != NULL) {
590074bb90dSTom Pothier (void) strlcpy(buf, label, bufsz);
591074bb90dSTom Pothier if (lsmbios_label != NULL) {
592074bb90dSTom Pothier (void) strlcat(buf, delim, bufsz);
593074bb90dSTom Pothier /*
594074bb90dSTom Pothier * If we are working on a DIMM
595074bb90dSTom Pothier * and we are deriving from libsmbios
596074bb90dSTom Pothier * smbi_location has the Device Locator.
597074bb90dSTom Pothier * add the Device Locator
598074bb90dSTom Pothier * add Bank Locator latter
599074bb90dSTom Pothier */
600074bb90dSTom Pothier (void) strlcat(buf, lsmbios_label,
601074bb90dSTom Pothier bufsz);
602074bb90dSTom Pothier }
603074bb90dSTom Pothier } else if (lsmbios_label != NULL)
604074bb90dSTom Pothier (void) strlcpy(buf, lsmbios_label,
605074bb90dSTom Pothier bufsz);
606074bb90dSTom Pothier
607074bb90dSTom Pothier if (dimm_bank != NULL) {
608074bb90dSTom Pothier (void) strlcat(buf, blank, bufsz);
609074bb90dSTom Pothier (void) strlcat(buf, dimm_bank, bufsz);
610074bb90dSTom Pothier }
611074bb90dSTom Pothier }
612074bb90dSTom Pothier
613074bb90dSTom Pothier clean_label = chip_cleanup_smbios_str(mod, buf, LABEL);
614074bb90dSTom Pothier topo_mod_strfree(mod, label);
615074bb90dSTom Pothier
616074bb90dSTom Pothier return (clean_label);
617074bb90dSTom Pothier }
618074bb90dSTom Pothier
619074bb90dSTom Pothier topo_mod_dprintf(mod, "Failed to get Label\n");
620074bb90dSTom Pothier return (NULL);
621074bb90dSTom Pothier }
622074bb90dSTom Pothier
623074bb90dSTom Pothier
624074bb90dSTom Pothier const char *
chip_serial_smbios_get(topo_mod_t * mod,id_t smb_id)625074bb90dSTom Pothier chip_serial_smbios_get(topo_mod_t *mod, id_t smb_id)
626074bb90dSTom Pothier {
627074bb90dSTom Pothier smbios_info_t c;
628074bb90dSTom Pothier const char *clean_serial = NULL;
629efd31e1dSTrang Do smbios_hdl_t *shp;
630074bb90dSTom Pothier
631efd31e1dSTrang Do shp = topo_mod_smbios(mod);
632074bb90dSTom Pothier if (shp != NULL && smb_id != -1)
633074bb90dSTom Pothier if (smbios_info_common(shp, smb_id, &c) != SMB_ERR) {
634074bb90dSTom Pothier clean_serial = chip_cleanup_smbios_str(mod,
635074bb90dSTom Pothier c.smbi_serial, 0);
636074bb90dSTom Pothier return (clean_serial);
637074bb90dSTom Pothier }
638074bb90dSTom Pothier
639074bb90dSTom Pothier topo_mod_dprintf(mod, "Failed to get Serial \n");
640074bb90dSTom Pothier return (NULL);
641074bb90dSTom Pothier }
642074bb90dSTom Pothier
643074bb90dSTom Pothier
644074bb90dSTom Pothier const char *
chip_part_smbios_get(topo_mod_t * mod,id_t smb_id)645074bb90dSTom Pothier chip_part_smbios_get(topo_mod_t *mod, id_t smb_id)
646074bb90dSTom Pothier {
647074bb90dSTom Pothier smbios_info_t c;
648074bb90dSTom Pothier const char *clean_part = NULL;
649efd31e1dSTrang Do smbios_hdl_t *shp;
650074bb90dSTom Pothier
651efd31e1dSTrang Do shp = topo_mod_smbios(mod);
652074bb90dSTom Pothier if (shp != NULL && smb_id != -1)
653074bb90dSTom Pothier if (smbios_info_common(shp, smb_id, &c) != SMB_ERR) {
654074bb90dSTom Pothier clean_part = chip_cleanup_smbios_str(mod,
655074bb90dSTom Pothier c.smbi_part, 0);
656074bb90dSTom Pothier return (clean_part);
657074bb90dSTom Pothier }
658074bb90dSTom Pothier
659074bb90dSTom Pothier topo_mod_dprintf(mod, "Failed to get Part\n");
660074bb90dSTom Pothier return (NULL);
661074bb90dSTom Pothier }
662074bb90dSTom Pothier
663074bb90dSTom Pothier const char *
chip_rev_smbios_get(topo_mod_t * mod,id_t smb_id)664074bb90dSTom Pothier chip_rev_smbios_get(topo_mod_t *mod, id_t smb_id)
665074bb90dSTom Pothier {
666074bb90dSTom Pothier smbios_info_t c;
667074bb90dSTom Pothier const char *clean_rev = NULL;
668efd31e1dSTrang Do smbios_hdl_t *shp;
669074bb90dSTom Pothier
670efd31e1dSTrang Do shp = topo_mod_smbios(mod);
671074bb90dSTom Pothier if (shp != NULL && smb_id != -1)
672074bb90dSTom Pothier if (smbios_info_common(shp, smb_id, &c) != SMB_ERR) {
673074bb90dSTom Pothier clean_rev = chip_cleanup_smbios_str(mod,
674074bb90dSTom Pothier c.smbi_version, 0);
675074bb90dSTom Pothier return (clean_rev);
676074bb90dSTom Pothier }
677074bb90dSTom Pothier
678074bb90dSTom Pothier topo_mod_dprintf(mod, "Failed to get Revision\n");
679074bb90dSTom Pothier return (NULL);
680074bb90dSTom Pothier }
681