4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
28 #include <sys/nvpair.h>
29 #include <sys/cmn_err.h>
30 #include <sys/fm/util.h>
31 #include <sys/fm/protocol.h>
32 #include <sys/smbios.h>
33 #include <sys/smbios_impl.h>
36 * Variable used to determine if the x86 generic topology enumerator will
37 * revert to legacy enumeration. I.E. Big Kill Switch... tunable via
40 int x86gentopo_legacy
= 0;
47 typedef struct bbindex
{
49 uint16_t index
[MAX_PAIRS
];
53 * the enum values come from DMTF
56 BB_BAD
= 0, /* There is no bb value 0 */
57 BB_UNKNOWN
, /* Unknown */
59 BB_BLADE
, /* Server Blade */
60 BB_CONNSW
, /* Connectivity Switch */
61 BB_SMM
, /* System Management Module */
62 BB_PROCMOD
, /* Processor Module */
63 BB_IOMOD
, /* I/O Module */
64 BB_MEMMOD
, /* Memory Module */
65 BB_DBOARD
, /* Daughter Board */
66 BB_MBOARD
, /* Motherboard */
67 BB_PROCMMOD
, /* Processor/Memory Module */
68 BB_PROCIOMOD
, /* Processor/IO Module */
69 BB_ICONNBD
/* Interconnect Board */
72 static struct bboard_type
{
77 {BB_UNKNOWN
, "unknown"},
79 {BB_BLADE
, "systemboard"},
80 {BB_CONNSW
, "connswitch"},
82 {BB_PROCMOD
, "cpuboard"},
83 {BB_IOMOD
, "ioboard"},
84 {BB_MEMMOD
, "memboard"},
85 {BB_DBOARD
, "systemboard"},
86 {BB_MBOARD
, "motherboard"},
87 {BB_PROCMMOD
, "systemboard"},
88 {BB_PROCIOMOD
, "systemboard"},
89 {BB_ICONNBD
, "systemboard"}
92 typedef struct smbs_con_ids
{
101 typedef struct smbs_cnt
{
102 int type
; /* SMBIOS stucture type */
103 int count
; /* number of table entries */
104 smbs_con_ids_t
**ids
; /* SMBIOS table entry id(s) */
108 * dynamically allocate the storage for the smbs_cnt_t
111 smb_create_strcnt(int count
)
113 smbs_cnt_t
*types
= NULL
;
116 types
= kmem_zalloc(sizeof (smbs_cnt_t
), KM_SLEEP
);
118 types
->ids
= (smbs_con_ids_t
**)kmem_zalloc(
119 count
* sizeof (smbs_con_ids_t
*), KM_SLEEP
);
121 for (i
= 0; i
< count
; i
++) {
122 types
->ids
[i
] = (smbs_con_ids_t
*)kmem_zalloc(
123 sizeof (smbs_con_ids_t
), KM_SLEEP
);
126 for (i
= 0; i
< count
; i
++) {
127 types
->ids
[i
]->cont_ids
= (uint16_t **)kmem_zalloc(
128 MAX_CONT
* sizeof (uint16_t *), KM_SLEEP
);
131 for (i
= 0; i
< count
; i
++) {
132 for (j
= 0; j
< MAX_CONT
; j
++) {
133 types
->ids
[i
]->cont_ids
[j
] = kmem_zalloc(
134 sizeof (uint16_t), KM_SLEEP
);
141 * free the smbs_cnt_t memory
144 smb_free_strcnt(smbs_cnt_t
*types
, int count
)
151 for (i
= 0; i
< count
; i
++) {
152 for (j
= 0; j
< MAX_CONT
; j
++) {
153 if (types
->ids
[i
]->cont_ids
[j
] != NULL
)
154 kmem_free(types
->ids
[i
]->cont_ids
[j
],
159 for (i
= 0; i
< count
; i
++) {
160 if (types
->ids
[i
]->cont_ids
!= NULL
)
161 kmem_free(types
->ids
[i
]->cont_ids
,
162 MAX_CONT
* sizeof (uint16_t *));
165 for (i
= 0; i
< count
; i
++) {
166 if (types
->ids
[i
] != NULL
)
167 kmem_free(types
->ids
[i
], sizeof (smbs_con_ids_t
));
170 if (types
->ids
!= NULL
)
171 kmem_free(types
->ids
, count
* sizeof (smbs_con_ids_t
*));
174 kmem_free(types
, sizeof (smbs_cnt_t
));
179 * count number of the structure type in the ksmbios
182 smb_cnttypes(smbios_hdl_t
*shp
, int type
)
184 const smb_struct_t
*sp
= shp
->sh_structs
;
185 int nstructs
= shp
->sh_nstructs
;
189 for (i
= 0, cnt
= 0; i
< nstructs
; i
++, sp
++) {
190 if (sp
->smbst_hdr
->smbh_type
== type
)
197 smb_strcnt(smbios_hdl_t
*shp
, smbs_cnt_t
*stype
)
199 const smb_struct_t
*sp
= shp
->sh_structs
;
200 int nstructs
= shp
->sh_nstructs
;
211 for (i
= 0, cnt
= 0; i
< nstructs
; i
++, sp
++) {
212 if (sp
->smbst_hdr
->smbh_type
== stype
->type
) {
213 stype
->ids
[cnt
]->id
= sp
->smbst_hdr
->smbh_hdl
;
214 stype
->ids
[cnt
]->inst
= cnt
;
215 stype
->ids
[cnt
]->visited
= 0;
216 stype
->ids
[cnt
]->cont_by_id
= -1;
217 if (stype
->type
== SMB_TYPE_BASEBOARD
) {
218 rc
= smbios_info_bboard(shp
,
219 stype
->ids
[cnt
]->id
, &bb
);
221 switch (bb
.smbb_type
) {
231 case SMB_BBT_MOTHER
:
249 stype
->ids
[cnt
]->inst
= inst
;
259 * Go through the smbios structures looking for type 2. Fill in
260 * the cont_id and cont_by_id for each type 2
264 smb_bb_contains(smbios_hdl_t
*shp
, smbs_cnt_t
*stype
)
268 const smb_struct_t
*spt
;
269 smbios_bboard_t smb_bb
;
270 uint16_t bb_id
, cont_id
;
272 id_t
*cont_hdl
= NULL
;
275 for (cnt
= 0; cnt
< stype
->count
; cnt
++) {
276 bb_id
= stype
->ids
[cnt
]->id
;
277 (void) smbios_info_bboard(shp
, stype
->ids
[cnt
]->id
, &smb_bb
);
278 cont_count
= (uint_t
)smb_bb
.smbb_contn
;
279 if (cont_count
== 0) {
283 cont_len
= sizeof (id_t
);
284 cont_hdl
= kmem_zalloc(cont_count
* cont_len
, KM_SLEEP
);
285 if (cont_hdl
== NULL
)
288 rc
= smbios_info_contains(shp
, stype
->ids
[cnt
]->id
,
289 cont_count
, cont_hdl
);
290 if (rc
> SMB_CONT_MAX
) {
291 kmem_free(cont_hdl
, cont_count
* cont_len
);
294 cont_count
= MIN(rc
, cont_count
);
297 * fill in the type 2 and type 4 ids which are
298 * contained in this type 2
301 for (j
= 0; j
< cont_count
; j
++) {
302 cont_id
= (uint16_t)cont_hdl
[j
];
303 spt
= smb_lookup_id(shp
, cont_id
);
304 if (spt
->smbst_hdr
->smbh_type
== SMB_TYPE_BASEBOARD
||
305 spt
->smbst_hdr
->smbh_type
== SMB_TYPE_PROCESSOR
) {
306 *stype
->ids
[cnt
]->cont_ids
[c
] = cont_id
;
310 if (spt
->smbst_hdr
->smbh_type
== SMB_TYPE_BASEBOARD
) {
311 for (i
= 0; i
< stype
->count
; i
++) {
312 if (stype
->ids
[i
]->id
== cont_id
) {
313 stype
->ids
[i
]->cont_by_id
=
320 stype
->ids
[cnt
]->cont_count
= c
;
321 if (cont_hdl
!= NULL
)
322 kmem_free(cont_hdl
, cont_count
* cont_len
);
327 * Verify SMBIOS structures for x86 generic topology.
329 * Return (0) on success.
332 fm_smb_check(smbios_hdl_t
*shp
)
343 uint16_t pr_id
, expr_id
;
344 uint16_t ma_id
, exma_id
;
345 uint16_t mdev_id
, exmdev_id
;
348 smbios_processor_ext_t exproc
;
349 smbios_memarray_t ma
;
350 smbios_memarray_ext_t exma
;
351 smbios_memdevice_t mdev
;
352 smbios_memdevice_ext_t exmdev
;
353 smbs_cnt_t
*bb_stype
;
354 smbs_cnt_t
*pr_stype
, *expr_stype
;
355 smbs_cnt_t
*ma_stype
, *exma_stype
;
356 smbs_cnt_t
*mdev_stype
, *exmdev_stype
;
359 * Verify the existance of the requuired extended OEM-Specific
360 * structures and they coincide with the structures they extend
361 * (e.g. the number of extended processor structures equal the
362 * number of processor structures).
364 pr_cnt
= smb_cnttypes(shp
, SMB_TYPE_PROCESSOR
);
365 expr_cnt
= smb_cnttypes(shp
, SUN_OEM_EXT_PROCESSOR
);
366 ma_cnt
= smb_cnttypes(shp
, SMB_TYPE_MEMARRAY
);
367 exma_cnt
= smb_cnttypes(shp
, SUN_OEM_EXT_MEMARRAY
);
368 mdev_cnt
= smb_cnttypes(shp
, SMB_TYPE_MEMDEVICE
);
369 exmdev_cnt
= smb_cnttypes(shp
, SUN_OEM_EXT_MEMDEVICE
);
370 if (expr_cnt
== 0 || exma_cnt
== 0 || exmdev_cnt
== 0 ||
371 expr_cnt
!= pr_cnt
|| exma_cnt
> ma_cnt
||
372 exmdev_cnt
> mdev_cnt
) {
374 cmn_err(CE_NOTE
, "!Structure mismatch: ext_proc (%d) "
375 "proc (%d) ext_ma (%d) ma (%d) ext_mdev (%d) mdev (%d)\n",
376 expr_cnt
, pr_cnt
, exma_cnt
, ma_cnt
, exmdev_cnt
,
383 * Verify the OEM-Specific structrures are correctly
384 * linked to the SMBIOS structure types they extend.
387 /* allocate processor stypes */
388 pr_stype
= smb_create_strcnt(pr_cnt
);
389 expr_stype
= smb_create_strcnt(expr_cnt
);
392 pr_stype
->type
= SMB_TYPE_PROCESSOR
;
393 smb_strcnt(shp
, pr_stype
);
394 expr_stype
->type
= SUN_OEM_EXT_PROCESSOR
;
395 smb_strcnt(shp
, expr_stype
);
397 /* verify the ext proc struct belong to the proc struct */
398 for (i
= 0; i
< pr_cnt
; i
++) {
399 pr_id
= pr_stype
->ids
[i
]->id
;
400 expr_id
= expr_stype
->ids
[i
]->id
;
401 (void) smbios_info_extprocessor(shp
, expr_id
, &exproc
);
402 if (exproc
.smbpe_processor
!= pr_id
) {
404 cmn_err(CE_NOTE
, "!Processor struct linkage (%d)", i
);
406 smb_free_strcnt(pr_stype
, pr_cnt
);
407 smb_free_strcnt(expr_stype
, expr_cnt
);
413 smb_free_strcnt(pr_stype
, pr_cnt
);
414 smb_free_strcnt(expr_stype
, expr_cnt
);
416 /* allocate memory array stypes */
417 ma_stype
= smb_create_strcnt(ma_cnt
);
418 exma_stype
= smb_create_strcnt(exma_cnt
);
419 sys_ma
= kmem_zalloc(sizeof (uint16_t) * ma_cnt
, KM_SLEEP
);
422 ma_stype
->type
= SMB_TYPE_MEMARRAY
;
423 smb_strcnt(shp
, ma_stype
);
424 exma_stype
->type
= SUN_OEM_EXT_MEMARRAY
;
425 smb_strcnt(shp
, exma_stype
);
427 /* verify linkage from ext memarray struct to memarray struct */
428 for (i
= 0; i
< ma_cnt
; i
++) {
429 sys_ma
[i
] = (uint16_t)-1;
430 ma_id
= ma_stype
->ids
[i
]->id
;
431 (void) smbios_info_memarray(shp
, ma_id
, &ma
);
432 if (ma
.smbma_use
!= SMB_MAU_SYSTEM
)
434 /* this memarray is system memory */
436 exma_id
= exma_stype
->ids
[i
]->id
;
437 (void) smbios_info_extmemarray(shp
, exma_id
, &exma
);
438 if (exma
.smbmae_ma
!= ma_id
) {
441 "!Memory Array struct linkage (%d)", i
);
443 smb_free_strcnt(ma_stype
, ma_cnt
);
444 smb_free_strcnt(exma_stype
, exma_cnt
);
445 kmem_free(sys_ma
, sizeof (uint16_t) * ma_cnt
);
451 smb_free_strcnt(ma_stype
, ma_cnt
);
452 smb_free_strcnt(exma_stype
, exma_cnt
);
454 /* allocate memory device stypes */
455 mdev_stype
= smb_create_strcnt(mdev_cnt
);
456 exmdev_stype
= smb_create_strcnt(exmdev_cnt
);
459 mdev_stype
->type
= SMB_TYPE_MEMDEVICE
;
460 smb_strcnt(shp
, mdev_stype
);
461 exmdev_stype
->type
= SUN_OEM_EXT_MEMDEVICE
;
462 smb_strcnt(shp
, exmdev_stype
);
465 for (i
= 0; i
< mdev_cnt
; i
++) {
466 mdev_id
= mdev_stype
->ids
[i
]->id
;
467 (void) smbios_info_memdevice(shp
, mdev_id
, &mdev
);
468 /* only check system memory devices */
469 for (j
= 0; j
< ma_cnt
; j
++) {
470 if (sys_ma
[j
] == mdev
.smbmd_array
)
475 exmdev_id
= exmdev_stype
->ids
[i
]->id
;
476 (void) smbios_info_extmemdevice(shp
, exmdev_id
, &exmdev
);
477 if (exmdev
.smbmdeve_md
!= mdev_id
) {
479 cmn_err(CE_NOTE
, "!Memory Device struct linkage (%d)",
482 smb_free_strcnt(mdev_stype
, mdev_cnt
);
483 smb_free_strcnt(exmdev_stype
, exmdev_cnt
);
484 kmem_free(sys_ma
, sizeof (uint16_t) * ma_cnt
);
490 smb_free_strcnt(mdev_stype
, mdev_cnt
);
491 smb_free_strcnt(exmdev_stype
, exmdev_cnt
);
492 kmem_free(sys_ma
, sizeof (uint16_t) * ma_cnt
);
495 * Verify the presece of contained handles if there are more
496 * than one Type-2 (Base Board) structures.
498 bb_cnt
= smb_cnttypes(shp
, SMB_TYPE_BASEBOARD
);
500 /* allocate base board stypes */
501 bb_stype
= smb_create_strcnt(bb_cnt
);
504 bb_stype
->type
= SMB_TYPE_BASEBOARD
;
505 smb_strcnt(shp
, bb_stype
);
507 /* verify contained handles */
508 for (i
= 0; i
< bb_cnt
; i
++) {
509 bb_id
= bb_stype
->ids
[i
]->id
;
510 (void) smbios_info_bboard(shp
, bb_id
, &bb
);
511 if (bb
.smbb_contn
== 0) {
513 cmn_err(CE_NOTE
, "!No contained hanldes (%d)",
516 smb_free_strcnt(bb_stype
, bb_cnt
);
522 smb_free_strcnt(bb_stype
, bb_cnt
);
534 const char **oem_strings
= NULL
;
535 smbs_cnt_t
*oemstypes
;
541 if (x86gentopo_legacy
== 1) {
550 /* OEM strings (Type 11) */
551 strcnt
= smb_cnttypes(shp
, SMB_TYPE_OEMSTR
);
555 oemstypes
= smb_create_strcnt(strcnt
);
556 if (oemstypes
== NULL
)
559 oemstypes
->type
= SMB_TYPE_OEMSTR
;
560 smb_strcnt(shp
, oemstypes
);
562 for (i
= 0; i
< oemstypes
->count
&& compat
== 0; i
++) {
563 id
= oemstypes
->ids
[i
]->id
;
564 cnt
= smbios_info_strtab(shp
, id
, 0, NULL
);
566 oem_strings
= kmem_zalloc(sizeof (char *) * cnt
,
568 (void) smbios_info_strtab(shp
, id
, cnt
, oem_strings
);
570 for (j
= 0; j
< cnt
; j
++) {
571 if (strncmp(oem_strings
[j
], SMB_PRMS1
,
572 strlen(SMB_PRMS1
) + 1) == 0) {
577 kmem_free(oem_strings
, sizeof (char *) * cnt
);
580 smb_free_strcnt(oemstypes
, strcnt
);
582 /* sanity check SMBIOS structures */
583 if ((compat
!= 0) && (fm_smb_check(shp
) == 0))
587 /* not compatible with x86gentopo; revert to legacy enumeration */
590 "!SMBIOS is not compatible with x86 generic topology.");
591 cmn_err(CE_NOTE
, "!Invoking legacy x86 topology enumeration.");
593 x86gentopo_legacy
= 1;
597 find_matching_apic(smbios_hdl_t
*shp
, uint16_t proc_id
, uint_t strand_apicid
)
601 smbios_processor_ext_t ep
;
605 strcnt
= smb_cnttypes(shp
, SUN_OEM_EXT_PROCESSOR
);
609 pstypes
= smb_create_strcnt(strcnt
);
613 pstypes
->type
= SUN_OEM_EXT_PROCESSOR
;
614 smb_strcnt(shp
, pstypes
);
615 for (i
= 0; i
< pstypes
->count
; i
++) {
616 ext_id
= pstypes
->ids
[i
]->id
;
617 (void) smbios_info_extprocessor(shp
, ext_id
, &ep
);
618 if (ep
.smbpe_processor
== proc_id
) {
619 for (j
= 0; j
< ep
.smbpe_n
; j
++) {
620 if (ep
.smbpe_apicid
[j
] == strand_apicid
) {
621 smb_free_strcnt(pstypes
, strcnt
);
627 smb_free_strcnt(pstypes
, strcnt
);
632 * go throught the type 2 structure contained_ids looking for
633 * the type 4 which has strand_apicid == this strand_apicid
636 find_matching_proc(smbios_hdl_t
*shp
, uint_t strand_apicid
,
637 uint16_t bb_id
, uint16_t proc_hdl
, int is_proc
)
640 const smb_struct_t
*sp
;
642 uint_t cont_count
, cont_len
;
644 id_t
*cont_hdl
= NULL
;
648 (void) smbios_info_bboard(shp
, bb_id
, &bb
);
649 cont_count
= (uint_t
)bb
.smbb_contn
;
653 cont_len
= sizeof (id_t
);
654 cont_hdl
= kmem_zalloc(cont_count
* cont_len
, KM_SLEEP
);
655 if (cont_hdl
== NULL
)
658 rc
= smbios_info_contains(shp
, bb_id
, cont_count
, cont_hdl
);
659 if (rc
> SMB_CONT_MAX
) {
660 kmem_free(cont_hdl
, cont_count
* cont_len
);
663 cont_count
= MIN(rc
, cont_count
);
665 for (n
= 0; n
< cont_count
; n
++) {
666 cont_id
= (uint16_t)cont_hdl
[n
];
667 sp
= smb_lookup_id(shp
, cont_id
);
668 if (sp
->smbst_hdr
->smbh_type
== SMB_TYPE_PROCESSOR
) {
670 if (find_matching_apic(shp
, cont_id
,
673 cont_count
* cont_len
);
677 if (cont_id
== proc_hdl
) {
679 cont_count
* cont_len
);
685 if (cont_hdl
!= NULL
)
686 kmem_free(cont_hdl
, cont_count
* cont_len
);
692 get_bboard_index(smbs_cnt_t
*bbstypes
, uint_t bb_id
, bbindex_t
*bb_idx
)
698 for (i
= 0; i
< MAX_PAIRS
; i
++)
699 tmp_idx
.index
[i
] = 0;
704 for (nb
= bbstypes
->count
-1, i
= 0; nb
>= 0; nb
--) {
705 tmp_id
= bbstypes
->ids
[nb
]->id
;
706 if (tmp_id
== curr_id
) {
707 tmp_idx
.index
[i
] = nb
;
709 curr_id
= bbstypes
->ids
[nb
]->cont_by_id
;
716 for (i
= tmp_idx
.count
- 1, j
= 0; i
>= 0; i
--) {
717 bb_idx
->index
[j
] = tmp_idx
.index
[i
];
721 bb_idx
->count
= tmp_idx
.count
;
725 get_chassis_inst(smbios_hdl_t
*shp
, uint16_t *chassis_inst
,
726 uint16_t bb_id
, int *chcnt
)
729 smbs_cnt_t
*chstypes
;
730 uint16_t chassis_id
, tmp_id
;
735 rc
= smbios_info_bboard(shp
, bb_id
, &bb
);
740 chassis_id
= bb
.smbb_chassis
;
742 ch_strcnt
= smb_cnttypes(shp
, SMB_TYPE_CHASSIS
);
747 chstypes
= smb_create_strcnt(ch_strcnt
);
748 if (chstypes
== NULL
)
751 chstypes
->type
= SMB_TYPE_CHASSIS
;
752 smb_strcnt(shp
, chstypes
);
754 for (i
= 0; i
< chstypes
->count
; i
++) {
755 tmp_id
= chstypes
->ids
[i
]->id
;
756 if (tmp_id
== chassis_id
) {
757 *chassis_inst
= chstypes
->ids
[i
]->inst
;
758 if (chstypes
->ids
[i
]->inst
!= 0)
762 smb_free_strcnt(chstypes
, ch_strcnt
);
767 smb_free_strcnt(chstypes
, ch_strcnt
);
772 smb_get_bb_fmri(smbios_hdl_t
*shp
, nvlist_t
*fmri
, uint_t parent
,
773 smbs_cnt_t
*bbstypes
)
778 nvlist_t
*pairs
[MAX_PAIRS
];
780 uint16_t chassis_inst
, mch_inst
;
787 for (n
= 0; n
< MAX_PAIRS
; n
++) {
793 get_bboard_index(bbstypes
, parent
, &bb_idx
);
795 index
= bb_idx
.index
[0];
796 bbid
= bbstypes
->ids
[index
]->id
;
798 rc
= get_chassis_inst(shp
, &chassis_inst
, bbid
, &chcnt
);
804 if ((bb_idx
.count
+ chcnt
) > MAX_PAIRS
) {
811 * create main chassis pair
813 pairs
[i
] = fm_nvlist_create(NULL
);
814 if (pairs
[i
] == NULL
) {
818 (void) snprintf(idstr
, sizeof (idstr
), "%u", mch_inst
);
819 if ((nvlist_add_string(pairs
[i
], FM_FMRI_HC_NAME
,
821 (nvlist_add_string(pairs
[i
], FM_FMRI_HC_ID
, idstr
)) != 0) {
822 fm_nvlist_destroy(pairs
[i
], FM_NVA_FREE
);
829 * create chassis pair
831 pairs
[i
] = fm_nvlist_create(NULL
);
832 if (pairs
[i
] == NULL
) {
833 for (n
= 0; n
< MAX_PAIRS
; n
++) {
834 if (pairs
[n
] != NULL
)
835 fm_nvlist_destroy(pairs
[n
], FM_NVA_FREE
);
839 (void) snprintf(idstr
, sizeof (idstr
), "%u", chassis_inst
);
840 if ((nvlist_add_string(pairs
[i
], FM_FMRI_HC_NAME
, "chassis") != 0) ||
841 (nvlist_add_string(pairs
[i
], FM_FMRI_HC_ID
, idstr
) != 0)) {
842 for (n
= 0; n
< MAX_PAIRS
; n
++) {
843 if (pairs
[n
] != NULL
)
844 fm_nvlist_destroy(pairs
[n
], FM_NVA_FREE
);
849 for (j
= 0, i
= chcnt
, cnt
= chcnt
; j
< bb_idx
.count
; j
++) {
850 index
= bb_idx
.index
[j
];
851 bbid
= bbstypes
->ids
[index
]->id
;
852 rc
= smbios_info_bboard(shp
, bbid
, &bb
);
858 pairs
[i
] = fm_nvlist_create(NULL
);
859 if (pairs
[i
] == NULL
) {
864 id
= bbstypes
->ids
[index
]->inst
;
865 (void) snprintf(idstr
, sizeof (idstr
), "%u", id
);
866 (void) strncpy(name
, bbd_type
[bb
.smbb_type
].name
,
870 if (nvlist_add_string(pairs
[i
], FM_FMRI_HC_NAME
, name
) != 0 ||
871 nvlist_add_string(pairs
[i
], FM_FMRI_HC_ID
, idstr
)
880 if (nvlist_add_nvlist_array(fmri
, FM_FMRI_HC_LIST
,
886 for (n
= 0; n
< cnt
; n
++) {
887 if (pairs
[n
] != NULL
)
888 fm_nvlist_destroy(pairs
[n
], FM_NVA_FREE
);
895 * pass in strand_apic id
896 * return chip's bboards list which has strand_apicid == passed
900 smb_bboard(uint_t strand_apicid
, uint16_t proc_hdl
, int is_proc
)
903 smbs_cnt_t
*bbstypes
;
906 nvlist_t
*fmri
= NULL
;
910 if (x86gentopo_legacy
)
919 * Type 2 structs : "base board"
921 bb_strcnt
= smb_cnttypes(shp
, SMB_TYPE_BASEBOARD
);
922 if (bb_strcnt
== 0) {
926 bbstypes
= smb_create_strcnt(bb_strcnt
);
927 if (bbstypes
== NULL
) {
931 bbstypes
->type
= SMB_TYPE_BASEBOARD
;
932 smb_strcnt(shp
, bbstypes
);
933 smb_bb_contains(shp
, bbstypes
);
935 for (nb
= 0; nb
< bbstypes
->count
; nb
++) {
936 if (bbstypes
->ids
[nb
]->visited
) {
940 bbstypes
->ids
[nb
]->visited
= 1;
941 bb_smbid
= bbstypes
->ids
[nb
]->id
;
944 * check if there is a matching processor under
945 * this board. If found, find base board(s) of this proc
946 * If proc is not in contained handle of a base board and
947 * there is only one base board in the system, treat that base
948 * board as the parent of the proc
950 if (find_matching_proc(shp
, strand_apicid
,
951 bb_smbid
, proc_hdl
, is_proc
) || (bbstypes
->count
== 1)) {
952 fmri
= fm_nvlist_create(NULL
);
954 smb_free_strcnt(bbstypes
, bb_strcnt
);
958 * find parent by walking the cont_by_id
960 rc
= smb_get_bb_fmri(shp
, fmri
, bb_smbid
, bbstypes
);
961 smb_free_strcnt(bbstypes
, bb_strcnt
);
970 smb_free_strcnt(bbstypes
, bb_strcnt
);
972 /* revert to legacy enumeration */
973 x86gentopo_legacy
= 1;
979 fm_smb_bboard(uint_t strand_apicid
)
981 return (smb_bboard(strand_apicid
, 0, PROC
));
985 fm_smb_chipinst(uint_t strand_apicid
, uint_t
*chip_inst
, uint16_t *smbiosid
)
993 if (x86gentopo_legacy
)
1001 strcnt
= smb_cnttypes(shp
, SMB_TYPE_PROCESSOR
);
1005 pstypes
= smb_create_strcnt(strcnt
);
1006 if (pstypes
== NULL
)
1009 pstypes
->type
= SMB_TYPE_PROCESSOR
;
1010 smb_strcnt(shp
, pstypes
);
1011 for (n
= 0; n
< pstypes
->count
; n
++) {
1012 proc_id
= pstypes
->ids
[n
]->id
;
1013 if (find_matching_apic(shp
, proc_id
, strand_apicid
)) {
1014 *chip_inst
= pstypes
->ids
[n
]->inst
;
1015 *smbiosid
= pstypes
->ids
[n
]->id
;
1016 smb_free_strcnt(pstypes
, strcnt
);
1020 smb_free_strcnt(pstypes
, strcnt
);
1022 /* revert to legacy enumerarion */
1023 x86gentopo_legacy
= 1;
1029 fm_smb_mc_bboards(uint_t bdf
)
1035 smbios_memarray_ext_t em
;
1036 nvlist_t
*fmri
= NULL
;
1037 smbs_cnt_t
*mastypes
;
1040 if (x86gentopo_legacy
)
1048 strcnt
= smb_cnttypes(shp
, SUN_OEM_EXT_MEMARRAY
);
1052 mastypes
= smb_create_strcnt(strcnt
);
1053 if (mastypes
== NULL
)
1056 mastypes
->type
= SUN_OEM_EXT_MEMARRAY
;
1057 smb_strcnt(shp
, mastypes
);
1058 for (i
= 0; i
< mastypes
->count
; i
++) {
1059 ext_id
= mastypes
->ids
[i
]->id
;
1060 (void) smbios_info_extmemarray(shp
, ext_id
, &em
);
1061 if (em
.smbmae_bdf
== bdf
) {
1062 fmri
= smb_bboard(0, em
.smbmae_comp
, MC
);
1063 smb_free_strcnt(mastypes
, strcnt
);
1067 smb_free_strcnt(mastypes
, strcnt
);
1069 /* revert to legacy enumerarion */
1070 x86gentopo_legacy
= 1;
1076 fm_smb_mc_chipinst(uint_t bdf
, uint_t
*chip_inst
) {
1080 smbios_memarray_ext_t em
;
1081 uint16_t ext_id
, proc_id
;
1082 smbs_cnt_t
*mastypes
;
1083 smbs_cnt_t
*pstypes
;
1084 int ma_strcnt
, p_strcnt
;
1086 if (x86gentopo_legacy
)
1094 ma_strcnt
= smb_cnttypes(shp
, SUN_OEM_EXT_MEMARRAY
);
1098 mastypes
= smb_create_strcnt(ma_strcnt
);
1099 if (mastypes
== NULL
)
1102 mastypes
->type
= SUN_OEM_EXT_MEMARRAY
;
1103 smb_strcnt(shp
, mastypes
);
1104 for (i
= 0; i
< mastypes
->count
; i
++) {
1105 ext_id
= mastypes
->ids
[i
]->id
;
1106 (void) smbios_info_extmemarray(shp
, ext_id
, &em
);
1107 if (em
.smbmae_bdf
== bdf
) {
1108 p_strcnt
= smb_cnttypes(shp
, SMB_TYPE_PROCESSOR
);
1109 if (p_strcnt
== 0) {
1110 smb_free_strcnt(mastypes
, ma_strcnt
);
1114 pstypes
= smb_create_strcnt(p_strcnt
);
1115 if (pstypes
== NULL
) {
1116 smb_free_strcnt(mastypes
, ma_strcnt
);
1120 pstypes
->type
= SMB_TYPE_PROCESSOR
;
1121 smb_strcnt(shp
, pstypes
);
1122 for (j
= 0; j
< pstypes
->count
; j
++) {
1123 proc_id
= pstypes
->ids
[j
]->id
;
1124 if (proc_id
== em
.smbmae_comp
) {
1125 *chip_inst
= pstypes
->ids
[j
]->inst
;
1126 smb_free_strcnt(mastypes
, ma_strcnt
);
1127 smb_free_strcnt(pstypes
, p_strcnt
);
1133 smb_free_strcnt(mastypes
, ma_strcnt
);
1134 smb_free_strcnt(pstypes
, p_strcnt
);
1136 /* revert to legacy enumeration */
1137 x86gentopo_legacy
= 1;