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 /* 2211ccb6bfSTom Pothier * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23074bb90dSTom Pothier * Use is subject to license terms. 24074bb90dSTom Pothier */ 25074bb90dSTom Pothier 26074bb90dSTom Pothier #include <sys/types.h> 27074bb90dSTom Pothier #include <sys/time.h> 28074bb90dSTom Pothier #include <sys/nvpair.h> 29074bb90dSTom Pothier #include <sys/cmn_err.h> 30074bb90dSTom Pothier #include <sys/fm/util.h> 31074bb90dSTom Pothier #include <sys/fm/protocol.h> 32074bb90dSTom Pothier #include <sys/smbios.h> 33074bb90dSTom Pothier #include <sys/smbios_impl.h> 34074bb90dSTom Pothier 35074bb90dSTom Pothier /* 36074bb90dSTom Pothier * Variable used to determine if the x86 generic topology enumerator will 37074bb90dSTom Pothier * revert to legacy enumeration. I.E. Big Kill Switch... tunable via 38074bb90dSTom Pothier * /etc/system 39074bb90dSTom Pothier */ 40074bb90dSTom Pothier int x86gentopo_legacy = 0; 41074bb90dSTom Pothier 42074bb90dSTom Pothier #define MC 0 43074bb90dSTom Pothier #define PROC 1 44074bb90dSTom Pothier #define MAX_PAIRS 20 45074bb90dSTom Pothier #define MAX_CONT 40 46074bb90dSTom Pothier 47074bb90dSTom Pothier typedef struct bbindex { 48074bb90dSTom Pothier int count; 49074bb90dSTom Pothier uint16_t index[MAX_PAIRS]; 50074bb90dSTom Pothier } bbindex_t; 51074bb90dSTom Pothier 52074bb90dSTom Pothier /* 53074bb90dSTom Pothier * the enum values come from DMTF 54074bb90dSTom Pothier */ 55074bb90dSTom Pothier typedef enum baseb { 56074bb90dSTom Pothier BB_BAD = 0, /* There is no bb value 0 */ 57074bb90dSTom Pothier BB_UNKNOWN, /* Unknown */ 58074bb90dSTom Pothier BB_OTHER, /* Other */ 59074bb90dSTom Pothier BB_BLADE, /* Server Blade */ 60074bb90dSTom Pothier BB_CONNSW, /* Connectivity Switch */ 61074bb90dSTom Pothier BB_SMM, /* System Management Module */ 62074bb90dSTom Pothier BB_PROCMOD, /* Processor Module */ 63074bb90dSTom Pothier BB_IOMOD, /* I/O Module */ 64074bb90dSTom Pothier BB_MEMMOD, /* Memory Module */ 65074bb90dSTom Pothier BB_DBOARD, /* Daughter Board */ 66074bb90dSTom Pothier BB_MBOARD, /* Motherboard */ 67074bb90dSTom Pothier BB_PROCMMOD, /* Processor/Memory Module */ 68074bb90dSTom Pothier BB_PROCIOMOD, /* Processor/IO Module */ 69074bb90dSTom Pothier BB_ICONNBD /* Interconnect Board */ 70074bb90dSTom Pothier } bbd_t; 71074bb90dSTom Pothier 72074bb90dSTom Pothier static struct bboard_type { 73074bb90dSTom Pothier bbd_t baseb; 74074bb90dSTom Pothier const char *name; 75074bb90dSTom Pothier } bbd_type[] = { 76074bb90dSTom Pothier {BB_BAD, NULL}, 77074bb90dSTom Pothier {BB_UNKNOWN, "unknown"}, 78074bb90dSTom Pothier {BB_OTHER, "other"}, 79074bb90dSTom Pothier {BB_BLADE, "systemboard"}, 80074bb90dSTom Pothier {BB_CONNSW, "connswitch"}, 81074bb90dSTom Pothier {BB_SMM, "smmodule"}, 82074bb90dSTom Pothier {BB_PROCMOD, "cpuboard"}, 83074bb90dSTom Pothier {BB_IOMOD, "ioboard"}, 84074bb90dSTom Pothier {BB_MEMMOD, "memboard"}, 85074bb90dSTom Pothier {BB_DBOARD, "systemboard"}, 86074bb90dSTom Pothier {BB_MBOARD, "motherboard"}, 87074bb90dSTom Pothier {BB_PROCMMOD, "systemboard"}, 88074bb90dSTom Pothier {BB_PROCIOMOD, "systemboard"}, 89074bb90dSTom Pothier {BB_ICONNBD, "systemboard"} 90074bb90dSTom Pothier }; 91074bb90dSTom Pothier 92074bb90dSTom Pothier typedef struct smbs_con_ids { 93074bb90dSTom Pothier int id; 94074bb90dSTom Pothier int inst; 95074bb90dSTom Pothier int cont_count; 96074bb90dSTom Pothier uint16_t **cont_ids; 97074bb90dSTom Pothier int cont_by_id; 98074bb90dSTom Pothier int visited; 99074bb90dSTom Pothier } smbs_con_ids_t; 100074bb90dSTom Pothier 101074bb90dSTom Pothier typedef struct smbs_cnt { 102074bb90dSTom Pothier int type; /* SMBIOS stucture type */ 103074bb90dSTom Pothier int count; /* number of table entries */ 104074bb90dSTom Pothier smbs_con_ids_t **ids; /* SMBIOS table entry id(s) */ 105074bb90dSTom Pothier } smbs_cnt_t; 106074bb90dSTom Pothier 107074bb90dSTom Pothier /* 108074bb90dSTom Pothier * dynamically allocate the storage for the smbs_cnt_t 109074bb90dSTom Pothier */ 110074bb90dSTom Pothier static smbs_cnt_t * 111074bb90dSTom Pothier smb_create_strcnt(int count) 112074bb90dSTom Pothier { 113074bb90dSTom Pothier smbs_cnt_t *types = NULL; 114074bb90dSTom Pothier int i, j; 115074bb90dSTom Pothier 116074bb90dSTom Pothier types = kmem_zalloc(sizeof (smbs_cnt_t), KM_SLEEP); 117074bb90dSTom Pothier 118074bb90dSTom Pothier types->ids = (smbs_con_ids_t **)kmem_zalloc( 119074bb90dSTom Pothier count * sizeof (smbs_con_ids_t *), KM_SLEEP); 120074bb90dSTom Pothier 121074bb90dSTom Pothier for (i = 0; i < count; i++) { 122074bb90dSTom Pothier types->ids[i] = (smbs_con_ids_t *)kmem_zalloc( 123074bb90dSTom Pothier sizeof (smbs_con_ids_t), KM_SLEEP); 124074bb90dSTom Pothier } 125074bb90dSTom Pothier 126074bb90dSTom Pothier for (i = 0; i < count; i++) { 127074bb90dSTom Pothier types->ids[i]->cont_ids = (uint16_t **)kmem_zalloc( 128074bb90dSTom Pothier MAX_CONT * sizeof (uint16_t *), KM_SLEEP); 129074bb90dSTom Pothier } 130074bb90dSTom Pothier 131074bb90dSTom Pothier for (i = 0; i < count; i++) { 132074bb90dSTom Pothier for (j = 0; j < MAX_CONT; j++) { 133074bb90dSTom Pothier types->ids[i]->cont_ids[j] = (uint16_t *)kmem_zalloc( 134074bb90dSTom Pothier sizeof (uint16_t), KM_SLEEP); 135074bb90dSTom Pothier } 136074bb90dSTom Pothier } 137074bb90dSTom Pothier return (types); 138074bb90dSTom Pothier } 139074bb90dSTom Pothier 140074bb90dSTom Pothier /* 141074bb90dSTom Pothier * free the smbs_cnt_t memory 142074bb90dSTom Pothier */ 143074bb90dSTom Pothier static void 144074bb90dSTom Pothier smb_free_strcnt(smbs_cnt_t *types, int count) 145074bb90dSTom Pothier { 146074bb90dSTom Pothier int i, j; 147074bb90dSTom Pothier 148074bb90dSTom Pothier if (types == NULL) 149074bb90dSTom Pothier return; 150074bb90dSTom Pothier 151074bb90dSTom Pothier for (i = 0; i < count; i++) { 152074bb90dSTom Pothier for (j = 0; j < MAX_CONT; j++) { 153074bb90dSTom Pothier if (types->ids[i]->cont_ids[j] != NULL) 154074bb90dSTom Pothier kmem_free(types->ids[i]->cont_ids[j], 155074bb90dSTom Pothier sizeof (uint16_t)); 156074bb90dSTom Pothier } 157074bb90dSTom Pothier } 158074bb90dSTom Pothier 159074bb90dSTom Pothier for (i = 0; i < count; i++) { 160074bb90dSTom Pothier if (types->ids[i]->cont_ids != NULL) 161074bb90dSTom Pothier kmem_free(types->ids[i]->cont_ids, 162074bb90dSTom Pothier MAX_CONT * sizeof (uint16_t *)); 163074bb90dSTom Pothier } 164074bb90dSTom Pothier 165074bb90dSTom Pothier for (i = 0; i < count; i++) { 166074bb90dSTom Pothier if (types->ids[i] != NULL) 167074bb90dSTom Pothier kmem_free(types->ids[i], sizeof (smbs_con_ids_t)); 168074bb90dSTom Pothier } 169074bb90dSTom Pothier 170074bb90dSTom Pothier if (types->ids != NULL) 171074bb90dSTom Pothier kmem_free(types->ids, count * sizeof (smbs_con_ids_t *)); 172074bb90dSTom Pothier 173074bb90dSTom Pothier if (types != NULL) 174074bb90dSTom Pothier kmem_free(types, sizeof (smbs_cnt_t)); 175074bb90dSTom Pothier 176074bb90dSTom Pothier } 177074bb90dSTom Pothier 178074bb90dSTom Pothier /* 179074bb90dSTom Pothier * count number of the structure type in the ksmbios 180074bb90dSTom Pothier */ 181074bb90dSTom Pothier static int 182074bb90dSTom Pothier smb_cnttypes(smbios_hdl_t *shp, int type) 183074bb90dSTom Pothier { 184074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 185074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 186074bb90dSTom Pothier int i; 187074bb90dSTom Pothier int cnt = 0; 188074bb90dSTom Pothier 189074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 190074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == type) 191074bb90dSTom Pothier cnt++; 192074bb90dSTom Pothier } 193074bb90dSTom Pothier return (cnt); 194074bb90dSTom Pothier } 195074bb90dSTom Pothier 196074bb90dSTom Pothier static void 197074bb90dSTom Pothier smb_strcnt(smbios_hdl_t *shp, smbs_cnt_t *stype) 198074bb90dSTom Pothier { 199074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 200074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 201074bb90dSTom Pothier smbios_bboard_t bb; 202074bb90dSTom Pothier int i, cnt; 203074bb90dSTom Pothier int mb_cnt = 0; 204074bb90dSTom Pothier int cpub_cnt = 0; 205074bb90dSTom Pothier int sysb_cnt = 0; 206074bb90dSTom Pothier int memb_cnt = 0; 207074bb90dSTom Pothier int iob_cnt = 0; 208074bb90dSTom Pothier int inst = 0; 209074bb90dSTom Pothier int rc = 0; 210074bb90dSTom Pothier 211074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 212074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == stype->type) { 213074bb90dSTom Pothier stype->ids[cnt]->id = sp->smbst_hdr->smbh_hdl; 214074bb90dSTom Pothier stype->ids[cnt]->inst = cnt; 215074bb90dSTom Pothier stype->ids[cnt]->visited = 0; 216074bb90dSTom Pothier stype->ids[cnt]->cont_by_id = -1; 217074bb90dSTom Pothier if (stype->type == SMB_TYPE_BASEBOARD) { 218074bb90dSTom Pothier rc = smbios_info_bboard(shp, 219074bb90dSTom Pothier stype->ids[cnt]->id, &bb); 220074bb90dSTom Pothier if (rc == 0) { 221074bb90dSTom Pothier switch (bb.smbb_type) { 222074bb90dSTom Pothier case SMB_BBT_PROC : 223074bb90dSTom Pothier inst = cpub_cnt++; 224074bb90dSTom Pothier break; 225074bb90dSTom Pothier case SMB_BBT_IO : 226074bb90dSTom Pothier inst = iob_cnt++; 227074bb90dSTom Pothier break; 228074bb90dSTom Pothier case SMB_BBT_MEM : 229074bb90dSTom Pothier inst = memb_cnt++; 230074bb90dSTom Pothier break; 231074bb90dSTom Pothier case SMB_BBT_MOTHER : 232074bb90dSTom Pothier inst = mb_cnt++; 233074bb90dSTom Pothier break; 234074bb90dSTom Pothier default: 235074bb90dSTom Pothier /* 236074bb90dSTom Pothier * SMB_BBT_UNKNOWN 237074bb90dSTom Pothier * SMB_BBT_OTHER 238074bb90dSTom Pothier * SMB_BBT_SBLADE 239074bb90dSTom Pothier * SMB_BBT_CSWITCH 240074bb90dSTom Pothier * SMB_BBT_SMM 241074bb90dSTom Pothier * SMB_BBT_DAUGHTER 242074bb90dSTom Pothier * SMB_BBT_PROCMEM 243074bb90dSTom Pothier * SMB_BBT_PROCIO 244074bb90dSTom Pothier * SMB_BBT_INTER 245074bb90dSTom Pothier */ 246074bb90dSTom Pothier inst = sysb_cnt++; 247074bb90dSTom Pothier break; 248074bb90dSTom Pothier } 249074bb90dSTom Pothier stype->ids[cnt]->inst = inst; 250074bb90dSTom Pothier } 251074bb90dSTom Pothier } 252074bb90dSTom Pothier cnt++; 253074bb90dSTom Pothier } 254074bb90dSTom Pothier } 255074bb90dSTom Pothier stype->count = cnt; 256074bb90dSTom Pothier } 257074bb90dSTom Pothier 258074bb90dSTom Pothier /* 259074bb90dSTom Pothier * Go through the smbios structures looking for type 2. Fill in 260074bb90dSTom Pothier * the cont_id and cont_by_id for each type 2 261074bb90dSTom Pothier * 262074bb90dSTom Pothier */ 263074bb90dSTom Pothier static void 264074bb90dSTom Pothier smb_bb_contains(smbios_hdl_t *shp, smbs_cnt_t *stype) 265074bb90dSTom Pothier { 266074bb90dSTom Pothier int i, j, cnt, c; 267074bb90dSTom Pothier uint_t cont_count; 268074bb90dSTom Pothier const smb_struct_t *spt; 269074bb90dSTom Pothier smbios_bboard_t smb_bb; 270074bb90dSTom Pothier uint16_t bb_id, cont_id; 271074bb90dSTom Pothier uint_t cont_len; 272074bb90dSTom Pothier id_t *cont_hdl = NULL; 273074bb90dSTom Pothier int rc; 274074bb90dSTom Pothier 275074bb90dSTom Pothier for (cnt = 0; cnt < stype->count; cnt++) { 276074bb90dSTom Pothier bb_id = stype->ids[cnt]->id; 277074bb90dSTom Pothier (void) smbios_info_bboard(shp, stype->ids[cnt]->id, &smb_bb); 278074bb90dSTom Pothier cont_count = (uint_t)smb_bb.smbb_contn; 279074bb90dSTom Pothier if (cont_count == 0) { 280074bb90dSTom Pothier continue; 281074bb90dSTom Pothier } 282074bb90dSTom Pothier 283074bb90dSTom Pothier cont_len = sizeof (id_t); 284074bb90dSTom Pothier cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP); 285074bb90dSTom Pothier if (cont_hdl == NULL) 286074bb90dSTom Pothier continue; 287074bb90dSTom Pothier 288074bb90dSTom Pothier rc = smbios_info_contains(shp, stype->ids[cnt]->id, 289074bb90dSTom Pothier cont_count, cont_hdl); 290074bb90dSTom Pothier if (rc > SMB_CONT_MAX) { 291074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 292074bb90dSTom Pothier continue; 293074bb90dSTom Pothier } 294074bb90dSTom Pothier cont_count = MIN(rc, cont_count); 295074bb90dSTom Pothier 296074bb90dSTom Pothier /* 297074bb90dSTom Pothier * fill in the type 2 and type 4 ids which are 298074bb90dSTom Pothier * contained in this type 2 299074bb90dSTom Pothier */ 300074bb90dSTom Pothier c = 0; 301074bb90dSTom Pothier for (j = 0; j < cont_count; j++) { 302074bb90dSTom Pothier cont_id = (uint16_t)cont_hdl[j]; 303074bb90dSTom Pothier spt = smb_lookup_id(shp, cont_id); 304074bb90dSTom Pothier if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD || 305074bb90dSTom Pothier spt->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) { 306074bb90dSTom Pothier *stype->ids[cnt]->cont_ids[c] = cont_id; 307074bb90dSTom Pothier c++; 308074bb90dSTom Pothier } 309074bb90dSTom Pothier 310074bb90dSTom Pothier if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD) { 311074bb90dSTom Pothier for (i = 0; i < stype->count; i++) { 312074bb90dSTom Pothier if (stype->ids[i]->id == cont_id) { 313074bb90dSTom Pothier stype->ids[i]->cont_by_id = 314074bb90dSTom Pothier bb_id; 315074bb90dSTom Pothier } 316074bb90dSTom Pothier } 317074bb90dSTom Pothier } 318074bb90dSTom Pothier 319074bb90dSTom Pothier } 320074bb90dSTom Pothier stype->ids[cnt]->cont_count = c; 321074bb90dSTom Pothier if (cont_hdl != NULL) 322074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 323074bb90dSTom Pothier } 324074bb90dSTom Pothier } 325074bb90dSTom Pothier 326074bb90dSTom Pothier /* 327074bb90dSTom Pothier * Verify SMBIOS structures for x86 generic topology. 328074bb90dSTom Pothier * 329074bb90dSTom Pothier * Return (0) on success. 330074bb90dSTom Pothier */ 331074bb90dSTom Pothier static int 332074bb90dSTom Pothier fm_smb_check(smbios_hdl_t *shp) 333074bb90dSTom Pothier { 33411ccb6bfSTom Pothier int i, j; 335074bb90dSTom Pothier int bb_cnt = 0; 336074bb90dSTom Pothier int pr_cnt = 0; 337074bb90dSTom Pothier int expr_cnt = 0; 338074bb90dSTom Pothier int ma_cnt = 0; 339074bb90dSTom Pothier int exma_cnt = 0; 340074bb90dSTom Pothier int mdev_cnt = 0; 341074bb90dSTom Pothier int exmdev_cnt = 0; 342074bb90dSTom Pothier uint16_t bb_id; 343074bb90dSTom Pothier uint16_t pr_id, expr_id; 344074bb90dSTom Pothier uint16_t ma_id, exma_id; 345074bb90dSTom Pothier uint16_t mdev_id, exmdev_id; 34611ccb6bfSTom Pothier uint16_t *sys_ma; 347074bb90dSTom Pothier smbios_bboard_t bb; 348074bb90dSTom Pothier smbios_processor_ext_t exproc; 34911ccb6bfSTom Pothier smbios_memarray_t ma; 350074bb90dSTom Pothier smbios_memarray_ext_t exma; 35111ccb6bfSTom Pothier smbios_memdevice_t mdev; 352074bb90dSTom Pothier smbios_memdevice_ext_t exmdev; 353074bb90dSTom Pothier smbs_cnt_t *bb_stype; 354074bb90dSTom Pothier smbs_cnt_t *pr_stype, *expr_stype; 355074bb90dSTom Pothier smbs_cnt_t *ma_stype, *exma_stype; 356074bb90dSTom Pothier smbs_cnt_t *mdev_stype, *exmdev_stype; 357074bb90dSTom Pothier 358074bb90dSTom Pothier /* 359074bb90dSTom Pothier * Verify the existance of the requuired extended OEM-Specific 360074bb90dSTom Pothier * structures and they coincide with the structures they extend 361074bb90dSTom Pothier * (e.g. the number of extended processor structures equal the 362074bb90dSTom Pothier * number of processor structures). 363074bb90dSTom Pothier */ 364074bb90dSTom Pothier pr_cnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 365074bb90dSTom Pothier expr_cnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR); 366074bb90dSTom Pothier ma_cnt = smb_cnttypes(shp, SMB_TYPE_MEMARRAY); 367074bb90dSTom Pothier exma_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 368074bb90dSTom Pothier mdev_cnt = smb_cnttypes(shp, SMB_TYPE_MEMDEVICE); 369074bb90dSTom Pothier exmdev_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMDEVICE); 370074bb90dSTom Pothier if (expr_cnt == 0 || exma_cnt == 0 || exmdev_cnt == 0 || 37111ccb6bfSTom Pothier expr_cnt != pr_cnt || exma_cnt > ma_cnt || 37211ccb6bfSTom Pothier exmdev_cnt > mdev_cnt) { 373074bb90dSTom Pothier #ifdef DEBUG 3747991dd24STom Pothier cmn_err(CE_NOTE, "!Structure mismatch: ext_proc (%d) " 375074bb90dSTom Pothier "proc (%d) ext_ma (%d) ma (%d) ext_mdev (%d) mdev (%d)\n", 376074bb90dSTom Pothier expr_cnt, pr_cnt, exma_cnt, ma_cnt, exmdev_cnt, 377074bb90dSTom Pothier mdev_cnt); 378074bb90dSTom Pothier #endif /* DEBUG */ 379074bb90dSTom Pothier return (-1); 380074bb90dSTom Pothier } 381074bb90dSTom Pothier 382074bb90dSTom Pothier /* 383074bb90dSTom Pothier * Verify the OEM-Specific structrures are correctly 384074bb90dSTom Pothier * linked to the SMBIOS structure types they extend. 385074bb90dSTom Pothier */ 386074bb90dSTom Pothier 387074bb90dSTom Pothier /* allocate processor stypes */ 388074bb90dSTom Pothier pr_stype = smb_create_strcnt(pr_cnt); 389074bb90dSTom Pothier expr_stype = smb_create_strcnt(expr_cnt); 390074bb90dSTom Pothier 391074bb90dSTom Pothier /* fill in stypes */ 392074bb90dSTom Pothier pr_stype->type = SMB_TYPE_PROCESSOR; 393074bb90dSTom Pothier smb_strcnt(shp, pr_stype); 394074bb90dSTom Pothier expr_stype->type = SUN_OEM_EXT_PROCESSOR; 395074bb90dSTom Pothier smb_strcnt(shp, expr_stype); 396074bb90dSTom Pothier 397074bb90dSTom Pothier /* verify the ext proc struct belong to the proc struct */ 398074bb90dSTom Pothier for (i = 0; i < pr_cnt; i++) { 399074bb90dSTom Pothier pr_id = pr_stype->ids[i]->id; 400074bb90dSTom Pothier expr_id = expr_stype->ids[i]->id; 401074bb90dSTom Pothier (void) smbios_info_extprocessor(shp, expr_id, &exproc); 402074bb90dSTom Pothier if (exproc.smbpe_processor != pr_id) { 403074bb90dSTom Pothier #ifdef DEBUG 4047991dd24STom Pothier cmn_err(CE_NOTE, "!Processor struct linkage (%d)", i); 405074bb90dSTom Pothier #endif /* DEBUG */ 406074bb90dSTom Pothier smb_free_strcnt(pr_stype, pr_cnt); 407074bb90dSTom Pothier smb_free_strcnt(expr_stype, expr_cnt); 408074bb90dSTom Pothier return (-1); 409074bb90dSTom Pothier } 410074bb90dSTom Pothier } 411074bb90dSTom Pothier 412074bb90dSTom Pothier /* free stypes */ 413074bb90dSTom Pothier smb_free_strcnt(pr_stype, pr_cnt); 414074bb90dSTom Pothier smb_free_strcnt(expr_stype, expr_cnt); 415074bb90dSTom Pothier 416074bb90dSTom Pothier /* allocate memory array stypes */ 417074bb90dSTom Pothier ma_stype = smb_create_strcnt(ma_cnt); 418074bb90dSTom Pothier exma_stype = smb_create_strcnt(exma_cnt); 41911ccb6bfSTom Pothier sys_ma = kmem_zalloc(sizeof (uint16_t) * ma_cnt, KM_SLEEP); 420074bb90dSTom Pothier 421074bb90dSTom Pothier /* fill in stypes */ 422074bb90dSTom Pothier ma_stype->type = SMB_TYPE_MEMARRAY; 423074bb90dSTom Pothier smb_strcnt(shp, ma_stype); 424074bb90dSTom Pothier exma_stype->type = SUN_OEM_EXT_MEMARRAY; 425074bb90dSTom Pothier smb_strcnt(shp, exma_stype); 426074bb90dSTom Pothier 427074bb90dSTom Pothier /* verify linkage from ext memarray struct to memarray struct */ 428074bb90dSTom Pothier for (i = 0; i < ma_cnt; i++) { 42911ccb6bfSTom Pothier sys_ma[i] = (uint16_t)-1; 430074bb90dSTom Pothier ma_id = ma_stype->ids[i]->id; 43111ccb6bfSTom Pothier (void) smbios_info_memarray(shp, ma_id, &ma); 43211ccb6bfSTom Pothier if (ma.smbma_use != SMB_MAU_SYSTEM) 43311ccb6bfSTom Pothier continue; 43411ccb6bfSTom Pothier /* this memarray is system memory */ 43511ccb6bfSTom Pothier sys_ma[i] = ma_id; 436074bb90dSTom Pothier exma_id = exma_stype->ids[i]->id; 437074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, exma_id, &exma); 438074bb90dSTom Pothier if (exma.smbmae_ma != ma_id) { 439074bb90dSTom Pothier #ifdef DEBUG 4407991dd24STom Pothier cmn_err(CE_NOTE, 4417991dd24STom Pothier "!Memory Array struct linkage (%d)", i); 442074bb90dSTom Pothier #endif /* DEBUG */ 443074bb90dSTom Pothier smb_free_strcnt(ma_stype, ma_cnt); 444074bb90dSTom Pothier smb_free_strcnt(exma_stype, exma_cnt); 44511ccb6bfSTom Pothier kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt); 446074bb90dSTom Pothier return (-1); 447074bb90dSTom Pothier } 448074bb90dSTom Pothier } 449074bb90dSTom Pothier 450074bb90dSTom Pothier /* free stypes */ 451074bb90dSTom Pothier smb_free_strcnt(ma_stype, ma_cnt); 452074bb90dSTom Pothier smb_free_strcnt(exma_stype, exma_cnt); 453074bb90dSTom Pothier 454074bb90dSTom Pothier /* allocate memory device stypes */ 455074bb90dSTom Pothier mdev_stype = smb_create_strcnt(mdev_cnt); 456074bb90dSTom Pothier exmdev_stype = smb_create_strcnt(exmdev_cnt); 457074bb90dSTom Pothier 458074bb90dSTom Pothier /* fill in stypes */ 459074bb90dSTom Pothier mdev_stype->type = SMB_TYPE_MEMDEVICE; 460074bb90dSTom Pothier smb_strcnt(shp, mdev_stype); 461074bb90dSTom Pothier exmdev_stype->type = SUN_OEM_EXT_MEMDEVICE; 462074bb90dSTom Pothier smb_strcnt(shp, exmdev_stype); 463074bb90dSTom Pothier 464074bb90dSTom Pothier /* verify linkage */ 465074bb90dSTom Pothier for (i = 0; i < mdev_cnt; i++) { 466074bb90dSTom Pothier mdev_id = mdev_stype->ids[i]->id; 46711ccb6bfSTom Pothier (void) smbios_info_memdevice(shp, mdev_id, &mdev); 46811ccb6bfSTom Pothier /* only check system memory devices */ 46911ccb6bfSTom Pothier for (j = 0; j < ma_cnt; j++) { 47011ccb6bfSTom Pothier if (sys_ma[j] == mdev.smbmd_array) 47111ccb6bfSTom Pothier break; 47211ccb6bfSTom Pothier } 47311ccb6bfSTom Pothier if (j == ma_cnt) 47411ccb6bfSTom Pothier continue; 475074bb90dSTom Pothier exmdev_id = exmdev_stype->ids[i]->id; 476074bb90dSTom Pothier (void) smbios_info_extmemdevice(shp, exmdev_id, &exmdev); 477074bb90dSTom Pothier if (exmdev.smbmdeve_md != mdev_id) { 478074bb90dSTom Pothier #ifdef DEBUG 4797991dd24STom Pothier cmn_err(CE_NOTE, "!Memory Device struct linkage (%d)", 480074bb90dSTom Pothier i); 481074bb90dSTom Pothier #endif /* DEBUG */ 482074bb90dSTom Pothier smb_free_strcnt(mdev_stype, mdev_cnt); 483074bb90dSTom Pothier smb_free_strcnt(exmdev_stype, exmdev_cnt); 48411ccb6bfSTom Pothier kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt); 485074bb90dSTom Pothier return (-1); 486074bb90dSTom Pothier } 487074bb90dSTom Pothier } 488074bb90dSTom Pothier 489074bb90dSTom Pothier /* free stypes */ 490074bb90dSTom Pothier smb_free_strcnt(mdev_stype, mdev_cnt); 491074bb90dSTom Pothier smb_free_strcnt(exmdev_stype, exmdev_cnt); 49211ccb6bfSTom Pothier kmem_free(sys_ma, sizeof (uint16_t) * ma_cnt); 493074bb90dSTom Pothier 494074bb90dSTom Pothier /* 495074bb90dSTom Pothier * Verify the presece of contained handles if there are more 496074bb90dSTom Pothier * than one Type-2 (Base Board) structures. 497074bb90dSTom Pothier */ 498074bb90dSTom Pothier bb_cnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD); 499074bb90dSTom Pothier if (bb_cnt > 1) { 500074bb90dSTom Pothier /* allocate base board stypes */ 501074bb90dSTom Pothier bb_stype = smb_create_strcnt(bb_cnt); 502074bb90dSTom Pothier 503074bb90dSTom Pothier /* fill in stypes */ 504074bb90dSTom Pothier bb_stype->type = SMB_TYPE_BASEBOARD; 505074bb90dSTom Pothier smb_strcnt(shp, bb_stype); 506074bb90dSTom Pothier 507074bb90dSTom Pothier /* verify contained handles */ 508074bb90dSTom Pothier for (i = 0; i < bb_cnt; i++) { 509074bb90dSTom Pothier bb_id = bb_stype->ids[i]->id; 510074bb90dSTom Pothier (void) smbios_info_bboard(shp, bb_id, &bb); 511074bb90dSTom Pothier if (bb.smbb_contn == 0) { 512074bb90dSTom Pothier #ifdef DEBUG 5137991dd24STom Pothier cmn_err(CE_NOTE, "!No contained hanldes (%d)", 514074bb90dSTom Pothier i); 515074bb90dSTom Pothier #endif /* DEBUG */ 516074bb90dSTom Pothier smb_free_strcnt(bb_stype, bb_cnt); 517074bb90dSTom Pothier return (-1); 518074bb90dSTom Pothier } 519074bb90dSTom Pothier } 520074bb90dSTom Pothier 521074bb90dSTom Pothier /* free stypes */ 522074bb90dSTom Pothier smb_free_strcnt(bb_stype, bb_cnt); 523074bb90dSTom Pothier } 524074bb90dSTom Pothier 525074bb90dSTom Pothier return (0); 526074bb90dSTom Pothier } 527074bb90dSTom Pothier 528074bb90dSTom Pothier void 529074bb90dSTom Pothier fm_smb_fmacompat() 530074bb90dSTom Pothier { 531074bb90dSTom Pothier int i, j; 532074bb90dSTom Pothier int id; 533074bb90dSTom Pothier int cnt; 534074bb90dSTom Pothier const char **oem_strings = NULL; 535074bb90dSTom Pothier smbs_cnt_t *oemstypes; 536074bb90dSTom Pothier smbios_hdl_t *shp; 537074bb90dSTom Pothier int strcnt; 538074bb90dSTom Pothier int compat = 0; 539074bb90dSTom Pothier 540074bb90dSTom Pothier /* check for BKS */ 541074bb90dSTom Pothier if (x86gentopo_legacy == 1) { 542074bb90dSTom Pothier return; 543074bb90dSTom Pothier } 544074bb90dSTom Pothier 545074bb90dSTom Pothier shp = ksmbios; 546074bb90dSTom Pothier if (shp == NULL) { 547074bb90dSTom Pothier goto bad; 548074bb90dSTom Pothier } 549074bb90dSTom Pothier 550074bb90dSTom Pothier /* OEM strings (Type 11) */ 551074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SMB_TYPE_OEMSTR); 552074bb90dSTom Pothier if (strcnt == 0) 553074bb90dSTom Pothier goto bad; 554074bb90dSTom Pothier 555074bb90dSTom Pothier oemstypes = smb_create_strcnt(strcnt); 556074bb90dSTom Pothier if (oemstypes == NULL) 557074bb90dSTom Pothier goto bad; 558074bb90dSTom Pothier 559074bb90dSTom Pothier oemstypes->type = SMB_TYPE_OEMSTR; 560074bb90dSTom Pothier smb_strcnt(shp, oemstypes); 561074bb90dSTom Pothier 562*9f67f65cSJens Rosenboom for (i = 0; i < oemstypes->count && compat == 0; i++) { 563074bb90dSTom Pothier id = oemstypes->ids[i]->id; 564074bb90dSTom Pothier cnt = smbios_info_strtab(shp, id, 0, NULL); 565074bb90dSTom Pothier if (cnt > 0) { 566074bb90dSTom Pothier oem_strings = kmem_zalloc(sizeof (char *) * cnt, 567074bb90dSTom Pothier KM_SLEEP); 568074bb90dSTom Pothier (void) smbios_info_strtab(shp, id, cnt, oem_strings); 569074bb90dSTom Pothier 570074bb90dSTom Pothier for (j = 0; j < cnt; j++) { 571074bb90dSTom Pothier if (strncmp(oem_strings[j], SMB_PRMS1, 572074bb90dSTom Pothier strlen(SMB_PRMS1) + 1) == 0) { 573074bb90dSTom Pothier compat = 1; 574074bb90dSTom Pothier break; 575074bb90dSTom Pothier } 576074bb90dSTom Pothier } 577074bb90dSTom Pothier kmem_free(oem_strings, sizeof (char *) * cnt); 578074bb90dSTom Pothier } 579*9f67f65cSJens Rosenboom } 580*9f67f65cSJens Rosenboom smb_free_strcnt(oemstypes, strcnt); 581074bb90dSTom Pothier 582074bb90dSTom Pothier /* sanity check SMBIOS structures */ 583*9f67f65cSJens Rosenboom if ((compat != 0) && (fm_smb_check(shp) == 0)) 584074bb90dSTom Pothier return; 585074bb90dSTom Pothier 586074bb90dSTom Pothier bad: 587074bb90dSTom Pothier /* not compatible with x86gentopo; revert to legacy enumeration */ 588074bb90dSTom Pothier #ifdef DEBUG 5897991dd24STom Pothier cmn_err(CE_NOTE, 5907991dd24STom Pothier "!SMBIOS is not compatible with x86 generic topology."); 5917991dd24STom Pothier cmn_err(CE_NOTE, "!Invoking legacy x86 topology enumeration."); 592074bb90dSTom Pothier #endif /* DEBUG */ 593074bb90dSTom Pothier x86gentopo_legacy = 1; 594074bb90dSTom Pothier } 595074bb90dSTom Pothier 596074bb90dSTom Pothier static int 597074bb90dSTom Pothier find_matching_apic(smbios_hdl_t *shp, uint16_t proc_id, uint_t strand_apicid) 598074bb90dSTom Pothier { 599074bb90dSTom Pothier uint16_t ext_id; 600074bb90dSTom Pothier int i, j; 601074bb90dSTom Pothier smbios_processor_ext_t ep; 602074bb90dSTom Pothier smbs_cnt_t *pstypes; 603074bb90dSTom Pothier int strcnt; 604074bb90dSTom Pothier 605074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR); 606074bb90dSTom Pothier if (strcnt == 0) 607074bb90dSTom Pothier return (0); 608074bb90dSTom Pothier 609074bb90dSTom Pothier pstypes = smb_create_strcnt(strcnt); 610074bb90dSTom Pothier if (pstypes == NULL) 611074bb90dSTom Pothier return (0); 612074bb90dSTom Pothier 613074bb90dSTom Pothier pstypes->type = SUN_OEM_EXT_PROCESSOR; 614074bb90dSTom Pothier smb_strcnt(shp, pstypes); 615074bb90dSTom Pothier for (i = 0; i < pstypes->count; i++) { 616074bb90dSTom Pothier ext_id = pstypes->ids[i]->id; 617074bb90dSTom Pothier (void) smbios_info_extprocessor(shp, ext_id, &ep); 618074bb90dSTom Pothier if (ep.smbpe_processor == proc_id) { 619074bb90dSTom Pothier for (j = 0; j < ep.smbpe_n; j++) { 620074bb90dSTom Pothier if (ep.smbpe_apicid[j] == strand_apicid) { 621074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 622074bb90dSTom Pothier return (1); 623074bb90dSTom Pothier } 624074bb90dSTom Pothier } 625074bb90dSTom Pothier } 626074bb90dSTom Pothier } 627074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 628074bb90dSTom Pothier return (0); 629074bb90dSTom Pothier } 630074bb90dSTom Pothier 631074bb90dSTom Pothier /* 632074bb90dSTom Pothier * go throught the type 2 structure contained_ids looking for 633074bb90dSTom Pothier * the type 4 which has strand_apicid == this strand_apicid 634074bb90dSTom Pothier */ 635074bb90dSTom Pothier static int 636074bb90dSTom Pothier find_matching_proc(smbios_hdl_t *shp, uint_t strand_apicid, 637074bb90dSTom Pothier uint16_t bb_id, uint16_t proc_hdl, int is_proc) 638074bb90dSTom Pothier { 639074bb90dSTom Pothier int n; 640074bb90dSTom Pothier const smb_struct_t *sp; 641074bb90dSTom Pothier smbios_bboard_t bb; 642074bb90dSTom Pothier uint_t cont_count, cont_len; 643074bb90dSTom Pothier uint16_t cont_id; 644074bb90dSTom Pothier id_t *cont_hdl = NULL; 645074bb90dSTom Pothier int rc; 646074bb90dSTom Pothier 647074bb90dSTom Pothier 648074bb90dSTom Pothier (void) smbios_info_bboard(shp, bb_id, &bb); 649074bb90dSTom Pothier cont_count = (uint_t)bb.smbb_contn; 650074bb90dSTom Pothier if (cont_count == 0) 651074bb90dSTom Pothier return (0); 652074bb90dSTom Pothier 653074bb90dSTom Pothier cont_len = sizeof (id_t); 654074bb90dSTom Pothier cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP); 655074bb90dSTom Pothier if (cont_hdl == NULL) 656074bb90dSTom Pothier return (0); 657074bb90dSTom Pothier 658074bb90dSTom Pothier rc = smbios_info_contains(shp, bb_id, cont_count, cont_hdl); 659074bb90dSTom Pothier if (rc > SMB_CONT_MAX) { 660074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 661074bb90dSTom Pothier return (0); 662074bb90dSTom Pothier } 663074bb90dSTom Pothier cont_count = MIN(rc, cont_count); 664074bb90dSTom Pothier 665074bb90dSTom Pothier for (n = 0; n < cont_count; n++) { 666074bb90dSTom Pothier cont_id = (uint16_t)cont_hdl[n]; 667074bb90dSTom Pothier sp = smb_lookup_id(shp, cont_id); 668074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) { 669074bb90dSTom Pothier if (is_proc) { 670074bb90dSTom Pothier if (find_matching_apic(shp, cont_id, 671074bb90dSTom Pothier strand_apicid)) { 672074bb90dSTom Pothier kmem_free(cont_hdl, 673074bb90dSTom Pothier cont_count * cont_len); 674074bb90dSTom Pothier return (1); 675074bb90dSTom Pothier } 676074bb90dSTom Pothier } else { 677074bb90dSTom Pothier if (cont_id == proc_hdl) { 678074bb90dSTom Pothier kmem_free(cont_hdl, 679074bb90dSTom Pothier cont_count * cont_len); 680074bb90dSTom Pothier return (1); 681074bb90dSTom Pothier } 682074bb90dSTom Pothier } 683074bb90dSTom Pothier } 684074bb90dSTom Pothier } 685074bb90dSTom Pothier if (cont_hdl != NULL) 686074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 687074bb90dSTom Pothier 688074bb90dSTom Pothier return (0); 689074bb90dSTom Pothier } 690074bb90dSTom Pothier 691074bb90dSTom Pothier void 692074bb90dSTom Pothier get_bboard_index(smbs_cnt_t *bbstypes, uint_t bb_id, bbindex_t *bb_idx) 693074bb90dSTom Pothier { 694074bb90dSTom Pothier int curr_id, tmp_id; 695074bb90dSTom Pothier int i, j, nb; 696074bb90dSTom Pothier bbindex_t tmp_idx; 697074bb90dSTom Pothier 698074bb90dSTom Pothier for (i = 0; i < MAX_PAIRS; i++) 699074bb90dSTom Pothier tmp_idx.index[i] = 0; 700074bb90dSTom Pothier 701074bb90dSTom Pothier tmp_idx.count = 0; 702074bb90dSTom Pothier 703074bb90dSTom Pothier curr_id = bb_id; 704074bb90dSTom Pothier for (nb = bbstypes->count-1, i = 0; nb >= 0; nb--) { 705074bb90dSTom Pothier tmp_id = bbstypes->ids[nb]->id; 706074bb90dSTom Pothier if (tmp_id == curr_id) { 707074bb90dSTom Pothier tmp_idx.index[i] = nb; 708074bb90dSTom Pothier tmp_idx.count++; 709074bb90dSTom Pothier curr_id = bbstypes->ids[nb]->cont_by_id; 710074bb90dSTom Pothier if (curr_id == -1) 711074bb90dSTom Pothier break; 712074bb90dSTom Pothier i++; 713074bb90dSTom Pothier } 714074bb90dSTom Pothier } 715074bb90dSTom Pothier 716074bb90dSTom Pothier for (i = tmp_idx.count - 1, j = 0; i >= 0; i--) { 717074bb90dSTom Pothier bb_idx->index[j] = tmp_idx.index[i]; 718074bb90dSTom Pothier j++; 719074bb90dSTom Pothier } 720074bb90dSTom Pothier 721074bb90dSTom Pothier bb_idx->count = tmp_idx.count; 722074bb90dSTom Pothier } 723074bb90dSTom Pothier 724074bb90dSTom Pothier int 725074bb90dSTom Pothier get_chassis_inst(smbios_hdl_t *shp, uint16_t *chassis_inst, 726074bb90dSTom Pothier uint16_t bb_id, int *chcnt) 727074bb90dSTom Pothier { 728074bb90dSTom Pothier int ch_strcnt; 729074bb90dSTom Pothier smbs_cnt_t *chstypes; 730074bb90dSTom Pothier uint16_t chassis_id, tmp_id; 731074bb90dSTom Pothier smbios_bboard_t bb; 732074bb90dSTom Pothier int rc = 0; 733074bb90dSTom Pothier int i; 734074bb90dSTom Pothier 735074bb90dSTom Pothier rc = smbios_info_bboard(shp, bb_id, &bb); 736074bb90dSTom Pothier if (rc != 0) { 737074bb90dSTom Pothier return (-1); 738074bb90dSTom Pothier } 739074bb90dSTom Pothier 740074bb90dSTom Pothier chassis_id = bb.smbb_chassis; 741074bb90dSTom Pothier 742074bb90dSTom Pothier ch_strcnt = smb_cnttypes(shp, SMB_TYPE_CHASSIS); 743074bb90dSTom Pothier 744074bb90dSTom Pothier if (ch_strcnt == 0) 745074bb90dSTom Pothier return (-1); 746074bb90dSTom Pothier 747074bb90dSTom Pothier chstypes = smb_create_strcnt(ch_strcnt); 748074bb90dSTom Pothier if (chstypes == NULL) 749074bb90dSTom Pothier return (-1); 750074bb90dSTom Pothier 751074bb90dSTom Pothier chstypes->type = SMB_TYPE_CHASSIS; 752074bb90dSTom Pothier smb_strcnt(shp, chstypes); 753074bb90dSTom Pothier 754074bb90dSTom Pothier for (i = 0; i < chstypes->count; i++) { 755074bb90dSTom Pothier tmp_id = chstypes->ids[i]->id; 756074bb90dSTom Pothier if (tmp_id == chassis_id) { 757074bb90dSTom Pothier *chassis_inst = chstypes->ids[i]->inst; 758074bb90dSTom Pothier if (chstypes->ids[i]->inst != 0) 759074bb90dSTom Pothier *chcnt = 2; 760074bb90dSTom Pothier else 761074bb90dSTom Pothier *chcnt = 1; 762074bb90dSTom Pothier smb_free_strcnt(chstypes, ch_strcnt); 763074bb90dSTom Pothier return (0); 764074bb90dSTom Pothier } 765074bb90dSTom Pothier } 766074bb90dSTom Pothier 767074bb90dSTom Pothier smb_free_strcnt(chstypes, ch_strcnt); 768074bb90dSTom Pothier return (-1); 769074bb90dSTom Pothier } 770074bb90dSTom Pothier 771074bb90dSTom Pothier int 772074bb90dSTom Pothier smb_get_bb_fmri(smbios_hdl_t *shp, nvlist_t *fmri, uint_t parent, 773074bb90dSTom Pothier smbs_cnt_t *bbstypes) 774074bb90dSTom Pothier { 775074bb90dSTom Pothier int rc = 0; 776074bb90dSTom Pothier int i, j, n, cnt; 777074bb90dSTom Pothier int id, index; 778074bb90dSTom Pothier nvlist_t *pairs[MAX_PAIRS]; 779074bb90dSTom Pothier smbios_bboard_t bb; 780074bb90dSTom Pothier uint16_t chassis_inst, mch_inst; 781074bb90dSTom Pothier char name[40]; 782074bb90dSTom Pothier char idstr[11]; 783074bb90dSTom Pothier bbindex_t bb_idx; 784074bb90dSTom Pothier uint16_t bbid; 785074bb90dSTom Pothier int chcnt = 0; 786074bb90dSTom Pothier 787074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 788074bb90dSTom Pothier bb_idx.index[n] = 0; 789074bb90dSTom Pothier pairs[n] = NULL; 790074bb90dSTom Pothier } 791074bb90dSTom Pothier bb_idx.count = 0; 792074bb90dSTom Pothier 793074bb90dSTom Pothier get_bboard_index(bbstypes, parent, &bb_idx); 794074bb90dSTom Pothier 795074bb90dSTom Pothier index = bb_idx.index[0]; 796074bb90dSTom Pothier bbid = bbstypes->ids[index]->id; 797074bb90dSTom Pothier 798074bb90dSTom Pothier rc = get_chassis_inst(shp, &chassis_inst, bbid, &chcnt); 799074bb90dSTom Pothier 800074bb90dSTom Pothier if (rc != 0) { 801074bb90dSTom Pothier return (rc); 802074bb90dSTom Pothier } 803074bb90dSTom Pothier 804074bb90dSTom Pothier if ((bb_idx.count + chcnt) > MAX_PAIRS) { 805074bb90dSTom Pothier return (-1); 806074bb90dSTom Pothier } 807074bb90dSTom Pothier 808074bb90dSTom Pothier i = 0; 809074bb90dSTom Pothier if (chcnt > 1) { 810074bb90dSTom Pothier /* 811074bb90dSTom Pothier * create main chassis pair 812074bb90dSTom Pothier */ 813074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 814074bb90dSTom Pothier if (pairs[i] == NULL) { 815074bb90dSTom Pothier return (-1); 816074bb90dSTom Pothier } 817074bb90dSTom Pothier mch_inst = 0; 818074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", mch_inst); 819074bb90dSTom Pothier if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, 820074bb90dSTom Pothier "chassis") != 0) || 821074bb90dSTom Pothier (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr)) != 0) { 822074bb90dSTom Pothier fm_nvlist_destroy(pairs[i], FM_NVA_FREE); 823074bb90dSTom Pothier return (-1); 824074bb90dSTom Pothier } 825074bb90dSTom Pothier i++; 826074bb90dSTom Pothier } 827074bb90dSTom Pothier 828074bb90dSTom Pothier /* 829074bb90dSTom Pothier * create chassis pair 830074bb90dSTom Pothier */ 831074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 832074bb90dSTom Pothier if (pairs[i] == NULL) { 833074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 834074bb90dSTom Pothier if (pairs[n] != NULL) 835074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 836074bb90dSTom Pothier } 837074bb90dSTom Pothier return (-1); 838074bb90dSTom Pothier } 839074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", chassis_inst); 840074bb90dSTom Pothier if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, "chassis") != 0) || 841074bb90dSTom Pothier (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) != 0)) { 842074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 843074bb90dSTom Pothier if (pairs[n] != NULL) 844074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 845074bb90dSTom Pothier } 846074bb90dSTom Pothier return (-1); 847074bb90dSTom Pothier } 848074bb90dSTom Pothier 849074bb90dSTom Pothier for (j = 0, i = chcnt, cnt = chcnt; j < bb_idx.count; j++) { 850074bb90dSTom Pothier index = bb_idx.index[j]; 851074bb90dSTom Pothier bbid = bbstypes->ids[index]->id; 852074bb90dSTom Pothier rc = smbios_info_bboard(shp, bbid, &bb); 853074bb90dSTom Pothier if (rc != 0) { 854074bb90dSTom Pothier rc = -1; 855074bb90dSTom Pothier break; 856074bb90dSTom Pothier } 857074bb90dSTom Pothier 858074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 859074bb90dSTom Pothier if (pairs[i] == NULL) { 860074bb90dSTom Pothier rc = -1; 861074bb90dSTom Pothier break; 862074bb90dSTom Pothier } 863074bb90dSTom Pothier 864074bb90dSTom Pothier id = bbstypes->ids[index]->inst; 865074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", id); 866074bb90dSTom Pothier (void) strncpy(name, bbd_type[bb.smbb_type].name, 867074bb90dSTom Pothier sizeof (name)); 868074bb90dSTom Pothier cnt++; 869074bb90dSTom Pothier 870074bb90dSTom Pothier if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name) != 0 || 871074bb90dSTom Pothier nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) 872074bb90dSTom Pothier != 0) { 873074bb90dSTom Pothier rc = -1; 874074bb90dSTom Pothier break; 875074bb90dSTom Pothier } 876074bb90dSTom Pothier i++; 877074bb90dSTom Pothier } 878074bb90dSTom Pothier 879074bb90dSTom Pothier if (rc != -1) { 880074bb90dSTom Pothier if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, 881074bb90dSTom Pothier pairs, cnt) != 0) { 882074bb90dSTom Pothier rc = -1; 883074bb90dSTom Pothier } 884074bb90dSTom Pothier } 885074bb90dSTom Pothier 886074bb90dSTom Pothier for (n = 0; n < cnt; n++) { 887074bb90dSTom Pothier if (pairs[n] != NULL) 888074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 889074bb90dSTom Pothier } 890074bb90dSTom Pothier 891074bb90dSTom Pothier return (rc); 892074bb90dSTom Pothier } 893074bb90dSTom Pothier 894074bb90dSTom Pothier /* 895074bb90dSTom Pothier * pass in strand_apic id 896074bb90dSTom Pothier * return chip's bboards list which has strand_apicid == passed 897074bb90dSTom Pothier * in strand_apic id 898074bb90dSTom Pothier */ 899074bb90dSTom Pothier static nvlist_t * 900074bb90dSTom Pothier smb_bboard(uint_t strand_apicid, uint16_t proc_hdl, int is_proc) 901074bb90dSTom Pothier { 902074bb90dSTom Pothier smbios_hdl_t *shp; 903074bb90dSTom Pothier smbs_cnt_t *bbstypes; 904074bb90dSTom Pothier int nb; 905074bb90dSTom Pothier int bb_smbid; 906074bb90dSTom Pothier nvlist_t *fmri = NULL; 907074bb90dSTom Pothier int rc = 0; 908074bb90dSTom Pothier int bb_strcnt; 909074bb90dSTom Pothier 910074bb90dSTom Pothier if (x86gentopo_legacy) 911074bb90dSTom Pothier return (NULL); 912074bb90dSTom Pothier 913074bb90dSTom Pothier shp = ksmbios; 914074bb90dSTom Pothier if (shp == NULL) { 915074bb90dSTom Pothier goto bad; 916074bb90dSTom Pothier } 917074bb90dSTom Pothier 918074bb90dSTom Pothier /* 919074bb90dSTom Pothier * Type 2 structs : "base board" 920074bb90dSTom Pothier */ 921074bb90dSTom Pothier bb_strcnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD); 922074bb90dSTom Pothier if (bb_strcnt == 0) { 923074bb90dSTom Pothier goto bad; 924074bb90dSTom Pothier } 925074bb90dSTom Pothier 926074bb90dSTom Pothier bbstypes = smb_create_strcnt(bb_strcnt); 927074bb90dSTom Pothier if (bbstypes == NULL) { 928074bb90dSTom Pothier goto bad; 929074bb90dSTom Pothier } 930074bb90dSTom Pothier 931074bb90dSTom Pothier bbstypes->type = SMB_TYPE_BASEBOARD; 932074bb90dSTom Pothier smb_strcnt(shp, bbstypes); 933074bb90dSTom Pothier smb_bb_contains(shp, bbstypes); 934074bb90dSTom Pothier 935074bb90dSTom Pothier for (nb = 0; nb < bbstypes->count; nb++) { 936074bb90dSTom Pothier if (bbstypes->ids[nb]->visited) { 937074bb90dSTom Pothier continue; 938074bb90dSTom Pothier } 939074bb90dSTom Pothier 940074bb90dSTom Pothier bbstypes->ids[nb]->visited = 1; 941074bb90dSTom Pothier bb_smbid = bbstypes->ids[nb]->id; 942074bb90dSTom Pothier 943074bb90dSTom Pothier /* 944074bb90dSTom Pothier * check if there is a matching processor under 945074bb90dSTom Pothier * this board. If found, find base board(s) of this proc 946074bb90dSTom Pothier * If proc is not in contained handle of a base board and 947074bb90dSTom Pothier * there is only one base board in the system, treat that base 948074bb90dSTom Pothier * board as the parent of the proc 949074bb90dSTom Pothier */ 950074bb90dSTom Pothier if (find_matching_proc(shp, strand_apicid, 951074bb90dSTom Pothier bb_smbid, proc_hdl, is_proc) || (bbstypes->count == 1)) { 952074bb90dSTom Pothier fmri = fm_nvlist_create(NULL); 953074bb90dSTom Pothier if (fmri == NULL) { 954074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 955074bb90dSTom Pothier goto bad; 956074bb90dSTom Pothier } 957074bb90dSTom Pothier /* 958074bb90dSTom Pothier * find parent by walking the cont_by_id 959074bb90dSTom Pothier */ 960074bb90dSTom Pothier rc = smb_get_bb_fmri(shp, fmri, bb_smbid, bbstypes); 961074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 962074bb90dSTom Pothier if (rc == 0) { 963074bb90dSTom Pothier return (fmri); 964074bb90dSTom Pothier } else 965074bb90dSTom Pothier goto bad; 966074bb90dSTom Pothier } 967074bb90dSTom Pothier 968074bb90dSTom Pothier } 969074bb90dSTom Pothier 970074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 971074bb90dSTom Pothier bad: 972074bb90dSTom Pothier /* revert to legacy enumeration */ 973074bb90dSTom Pothier x86gentopo_legacy = 1; 974074bb90dSTom Pothier 975074bb90dSTom Pothier return (NULL); 976074bb90dSTom Pothier } 977074bb90dSTom Pothier 978074bb90dSTom Pothier nvlist_t * 979074bb90dSTom Pothier fm_smb_bboard(uint_t strand_apicid) 980074bb90dSTom Pothier { 981074bb90dSTom Pothier return (smb_bboard(strand_apicid, 0, PROC)); 982074bb90dSTom Pothier } 983074bb90dSTom Pothier 984074bb90dSTom Pothier int 985074bb90dSTom Pothier fm_smb_chipinst(uint_t strand_apicid, uint_t *chip_inst, uint16_t *smbiosid) 986074bb90dSTom Pothier { 987074bb90dSTom Pothier int n; 988074bb90dSTom Pothier smbios_hdl_t *shp; 989074bb90dSTom Pothier uint16_t proc_id; 990074bb90dSTom Pothier smbs_cnt_t *pstypes; 991074bb90dSTom Pothier int strcnt; 992074bb90dSTom Pothier 993074bb90dSTom Pothier if (x86gentopo_legacy) 994074bb90dSTom Pothier return (-1); 995074bb90dSTom Pothier 996074bb90dSTom Pothier shp = ksmbios; 997074bb90dSTom Pothier if (shp == NULL) { 998074bb90dSTom Pothier goto bad; 999074bb90dSTom Pothier } 1000074bb90dSTom Pothier 1001074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 1002074bb90dSTom Pothier if (strcnt == 0) 1003074bb90dSTom Pothier goto bad; 1004074bb90dSTom Pothier 1005074bb90dSTom Pothier pstypes = smb_create_strcnt(strcnt); 1006074bb90dSTom Pothier if (pstypes == NULL) 1007074bb90dSTom Pothier goto bad; 1008074bb90dSTom Pothier 1009074bb90dSTom Pothier pstypes->type = SMB_TYPE_PROCESSOR; 1010074bb90dSTom Pothier smb_strcnt(shp, pstypes); 1011074bb90dSTom Pothier for (n = 0; n < pstypes->count; n++) { 1012074bb90dSTom Pothier proc_id = pstypes->ids[n]->id; 1013074bb90dSTom Pothier if (find_matching_apic(shp, proc_id, strand_apicid)) { 1014074bb90dSTom Pothier *chip_inst = pstypes->ids[n]->inst; 1015074bb90dSTom Pothier *smbiosid = pstypes->ids[n]->id; 1016074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 1017074bb90dSTom Pothier return (0); 1018074bb90dSTom Pothier } 1019074bb90dSTom Pothier } 1020074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 1021074bb90dSTom Pothier bad: 1022074bb90dSTom Pothier /* revert to legacy enumerarion */ 1023074bb90dSTom Pothier x86gentopo_legacy = 1; 1024074bb90dSTom Pothier 1025074bb90dSTom Pothier return (-1); 1026074bb90dSTom Pothier } 1027074bb90dSTom Pothier 1028074bb90dSTom Pothier nvlist_t * 1029074bb90dSTom Pothier fm_smb_mc_bboards(uint_t bdf) 1030074bb90dSTom Pothier { 1031074bb90dSTom Pothier 1032074bb90dSTom Pothier int i; 1033074bb90dSTom Pothier smbios_hdl_t *shp; 1034074bb90dSTom Pothier uint16_t ext_id; 1035074bb90dSTom Pothier smbios_memarray_ext_t em; 1036074bb90dSTom Pothier nvlist_t *fmri = NULL; 1037074bb90dSTom Pothier smbs_cnt_t *mastypes; 1038074bb90dSTom Pothier int strcnt; 1039074bb90dSTom Pothier 1040074bb90dSTom Pothier if (x86gentopo_legacy) 1041074bb90dSTom Pothier return (NULL); 1042074bb90dSTom Pothier 1043074bb90dSTom Pothier shp = ksmbios; 1044074bb90dSTom Pothier if (shp == NULL) { 1045074bb90dSTom Pothier goto bad; 1046074bb90dSTom Pothier } 1047074bb90dSTom Pothier 1048074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 1049074bb90dSTom Pothier if (strcnt == 0) 1050074bb90dSTom Pothier goto bad; 1051074bb90dSTom Pothier 1052074bb90dSTom Pothier mastypes = smb_create_strcnt(strcnt); 1053074bb90dSTom Pothier if (mastypes == NULL) 1054074bb90dSTom Pothier goto bad; 1055074bb90dSTom Pothier 1056074bb90dSTom Pothier mastypes->type = SUN_OEM_EXT_MEMARRAY; 1057074bb90dSTom Pothier smb_strcnt(shp, mastypes); 1058074bb90dSTom Pothier for (i = 0; i < mastypes->count; i++) { 1059074bb90dSTom Pothier ext_id = mastypes->ids[i]->id; 1060074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, ext_id, &em); 1061074bb90dSTom Pothier if (em.smbmae_bdf == bdf) { 1062074bb90dSTom Pothier fmri = smb_bboard(0, em.smbmae_comp, MC); 1063074bb90dSTom Pothier smb_free_strcnt(mastypes, strcnt); 1064074bb90dSTom Pothier return (fmri); 1065074bb90dSTom Pothier } 1066074bb90dSTom Pothier } 1067074bb90dSTom Pothier smb_free_strcnt(mastypes, strcnt); 1068074bb90dSTom Pothier bad: 1069074bb90dSTom Pothier /* revert to legacy enumerarion */ 1070074bb90dSTom Pothier x86gentopo_legacy = 1; 1071074bb90dSTom Pothier 1072074bb90dSTom Pothier return (NULL); 1073074bb90dSTom Pothier } 1074074bb90dSTom Pothier 1075074bb90dSTom Pothier int 1076074bb90dSTom Pothier fm_smb_mc_chipinst(uint_t bdf, uint_t *chip_inst) { 1077074bb90dSTom Pothier 1078074bb90dSTom Pothier int i, j; 1079074bb90dSTom Pothier smbios_hdl_t *shp; 1080074bb90dSTom Pothier smbios_memarray_ext_t em; 1081074bb90dSTom Pothier uint16_t ext_id, proc_id; 1082074bb90dSTom Pothier smbs_cnt_t *mastypes; 1083074bb90dSTom Pothier smbs_cnt_t *pstypes; 1084074bb90dSTom Pothier int ma_strcnt, p_strcnt; 1085074bb90dSTom Pothier 1086074bb90dSTom Pothier if (x86gentopo_legacy) 1087074bb90dSTom Pothier return (-1); 1088074bb90dSTom Pothier 1089074bb90dSTom Pothier shp = ksmbios; 1090074bb90dSTom Pothier if (shp == NULL) { 1091074bb90dSTom Pothier goto bad; 1092074bb90dSTom Pothier } 1093074bb90dSTom Pothier 1094074bb90dSTom Pothier ma_strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 1095074bb90dSTom Pothier if (ma_strcnt == 0) 1096074bb90dSTom Pothier goto bad; 1097074bb90dSTom Pothier 1098074bb90dSTom Pothier mastypes = smb_create_strcnt(ma_strcnt); 1099074bb90dSTom Pothier if (mastypes == NULL) 1100074bb90dSTom Pothier goto bad; 1101074bb90dSTom Pothier 1102074bb90dSTom Pothier mastypes->type = SUN_OEM_EXT_MEMARRAY; 1103074bb90dSTom Pothier smb_strcnt(shp, mastypes); 1104074bb90dSTom Pothier for (i = 0; i < mastypes->count; i++) { 1105074bb90dSTom Pothier ext_id = mastypes->ids[i]->id; 1106074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, ext_id, &em); 1107074bb90dSTom Pothier if (em.smbmae_bdf == bdf) { 1108074bb90dSTom Pothier p_strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 1109074bb90dSTom Pothier if (p_strcnt == 0) { 1110074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1111074bb90dSTom Pothier goto bad; 1112074bb90dSTom Pothier } 1113074bb90dSTom Pothier 1114074bb90dSTom Pothier pstypes = smb_create_strcnt(p_strcnt); 1115074bb90dSTom Pothier if (pstypes == NULL) { 1116074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1117074bb90dSTom Pothier goto bad; 1118074bb90dSTom Pothier } 1119074bb90dSTom Pothier 1120074bb90dSTom Pothier pstypes->type = SMB_TYPE_PROCESSOR; 1121074bb90dSTom Pothier smb_strcnt(shp, pstypes); 1122074bb90dSTom Pothier for (j = 0; j < pstypes->count; j++) { 1123074bb90dSTom Pothier proc_id = pstypes->ids[j]->id; 1124074bb90dSTom Pothier if (proc_id == em.smbmae_comp) { 1125074bb90dSTom Pothier *chip_inst = pstypes->ids[j]->inst; 1126074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1127074bb90dSTom Pothier smb_free_strcnt(pstypes, p_strcnt); 1128074bb90dSTom Pothier return (0); 1129074bb90dSTom Pothier } 1130074bb90dSTom Pothier } 1131074bb90dSTom Pothier } 1132074bb90dSTom Pothier } 1133074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1134074bb90dSTom Pothier smb_free_strcnt(pstypes, p_strcnt); 1135074bb90dSTom Pothier bad: 1136074bb90dSTom Pothier /* revert to legacy enumeration */ 1137074bb90dSTom Pothier x86gentopo_legacy = 1; 1138074bb90dSTom Pothier 1139074bb90dSTom Pothier return (-1); 1140074bb90dSTom Pothier } 1141