1*074bb90dSTom Pothier /* 2*074bb90dSTom Pothier * CDDL HEADER START 3*074bb90dSTom Pothier * 4*074bb90dSTom Pothier * The contents of this file are subject to the terms of the 5*074bb90dSTom Pothier * Common Development and Distribution License (the "License"). 6*074bb90dSTom Pothier * You may not use this file except in compliance with the License. 7*074bb90dSTom Pothier * 8*074bb90dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*074bb90dSTom Pothier * or http://www.opensolaris.org/os/licensing. 10*074bb90dSTom Pothier * See the License for the specific language governing permissions 11*074bb90dSTom Pothier * and limitations under the License. 12*074bb90dSTom Pothier * 13*074bb90dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each 14*074bb90dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*074bb90dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the 16*074bb90dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying 17*074bb90dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner] 18*074bb90dSTom Pothier * 19*074bb90dSTom Pothier * CDDL HEADER END 20*074bb90dSTom Pothier */ 21*074bb90dSTom Pothier /* 22*074bb90dSTom Pothier * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*074bb90dSTom Pothier * Use is subject to license terms. 24*074bb90dSTom Pothier */ 25*074bb90dSTom Pothier 26*074bb90dSTom Pothier #include <sys/types.h> 27*074bb90dSTom Pothier #include <sys/time.h> 28*074bb90dSTom Pothier #include <sys/nvpair.h> 29*074bb90dSTom Pothier #include <sys/cmn_err.h> 30*074bb90dSTom Pothier #include <sys/fm/util.h> 31*074bb90dSTom Pothier #include <sys/fm/protocol.h> 32*074bb90dSTom Pothier #include <sys/smbios.h> 33*074bb90dSTom Pothier #include <sys/smbios_impl.h> 34*074bb90dSTom Pothier 35*074bb90dSTom Pothier /* 36*074bb90dSTom Pothier * Variable used to determine if the x86 generic topology enumerator will 37*074bb90dSTom Pothier * revert to legacy enumeration. I.E. Big Kill Switch... tunable via 38*074bb90dSTom Pothier * /etc/system 39*074bb90dSTom Pothier */ 40*074bb90dSTom Pothier int x86gentopo_legacy = 0; 41*074bb90dSTom Pothier 42*074bb90dSTom Pothier #define MC 0 43*074bb90dSTom Pothier #define PROC 1 44*074bb90dSTom Pothier #define MAX_PAIRS 20 45*074bb90dSTom Pothier #define MAX_CONT 40 46*074bb90dSTom Pothier 47*074bb90dSTom Pothier typedef struct bbindex { 48*074bb90dSTom Pothier int count; 49*074bb90dSTom Pothier uint16_t index[MAX_PAIRS]; 50*074bb90dSTom Pothier } bbindex_t; 51*074bb90dSTom Pothier 52*074bb90dSTom Pothier /* 53*074bb90dSTom Pothier * the enum values come from DMTF 54*074bb90dSTom Pothier */ 55*074bb90dSTom Pothier typedef enum baseb { 56*074bb90dSTom Pothier BB_BAD = 0, /* There is no bb value 0 */ 57*074bb90dSTom Pothier BB_UNKNOWN, /* Unknown */ 58*074bb90dSTom Pothier BB_OTHER, /* Other */ 59*074bb90dSTom Pothier BB_BLADE, /* Server Blade */ 60*074bb90dSTom Pothier BB_CONNSW, /* Connectivity Switch */ 61*074bb90dSTom Pothier BB_SMM, /* System Management Module */ 62*074bb90dSTom Pothier BB_PROCMOD, /* Processor Module */ 63*074bb90dSTom Pothier BB_IOMOD, /* I/O Module */ 64*074bb90dSTom Pothier BB_MEMMOD, /* Memory Module */ 65*074bb90dSTom Pothier BB_DBOARD, /* Daughter Board */ 66*074bb90dSTom Pothier BB_MBOARD, /* Motherboard */ 67*074bb90dSTom Pothier BB_PROCMMOD, /* Processor/Memory Module */ 68*074bb90dSTom Pothier BB_PROCIOMOD, /* Processor/IO Module */ 69*074bb90dSTom Pothier BB_ICONNBD /* Interconnect Board */ 70*074bb90dSTom Pothier } bbd_t; 71*074bb90dSTom Pothier 72*074bb90dSTom Pothier static struct bboard_type { 73*074bb90dSTom Pothier bbd_t baseb; 74*074bb90dSTom Pothier const char *name; 75*074bb90dSTom Pothier } bbd_type[] = { 76*074bb90dSTom Pothier {BB_BAD, NULL}, 77*074bb90dSTom Pothier {BB_UNKNOWN, "unknown"}, 78*074bb90dSTom Pothier {BB_OTHER, "other"}, 79*074bb90dSTom Pothier {BB_BLADE, "systemboard"}, 80*074bb90dSTom Pothier {BB_CONNSW, "connswitch"}, 81*074bb90dSTom Pothier {BB_SMM, "smmodule"}, 82*074bb90dSTom Pothier {BB_PROCMOD, "cpuboard"}, 83*074bb90dSTom Pothier {BB_IOMOD, "ioboard"}, 84*074bb90dSTom Pothier {BB_MEMMOD, "memboard"}, 85*074bb90dSTom Pothier {BB_DBOARD, "systemboard"}, 86*074bb90dSTom Pothier {BB_MBOARD, "motherboard"}, 87*074bb90dSTom Pothier {BB_PROCMMOD, "systemboard"}, 88*074bb90dSTom Pothier {BB_PROCIOMOD, "systemboard"}, 89*074bb90dSTom Pothier {BB_ICONNBD, "systemboard"} 90*074bb90dSTom Pothier }; 91*074bb90dSTom Pothier 92*074bb90dSTom Pothier typedef struct smbs_con_ids { 93*074bb90dSTom Pothier int id; 94*074bb90dSTom Pothier int inst; 95*074bb90dSTom Pothier int cont_count; 96*074bb90dSTom Pothier uint16_t **cont_ids; 97*074bb90dSTom Pothier int cont_by_id; 98*074bb90dSTom Pothier int visited; 99*074bb90dSTom Pothier } smbs_con_ids_t; 100*074bb90dSTom Pothier 101*074bb90dSTom Pothier typedef struct smbs_cnt { 102*074bb90dSTom Pothier int type; /* SMBIOS stucture type */ 103*074bb90dSTom Pothier int count; /* number of table entries */ 104*074bb90dSTom Pothier smbs_con_ids_t **ids; /* SMBIOS table entry id(s) */ 105*074bb90dSTom Pothier } smbs_cnt_t; 106*074bb90dSTom Pothier 107*074bb90dSTom Pothier /* 108*074bb90dSTom Pothier * dynamically allocate the storage for the smbs_cnt_t 109*074bb90dSTom Pothier */ 110*074bb90dSTom Pothier static smbs_cnt_t * 111*074bb90dSTom Pothier smb_create_strcnt(int count) 112*074bb90dSTom Pothier { 113*074bb90dSTom Pothier smbs_cnt_t *types = NULL; 114*074bb90dSTom Pothier int i, j; 115*074bb90dSTom Pothier 116*074bb90dSTom Pothier types = kmem_zalloc(sizeof (smbs_cnt_t), KM_SLEEP); 117*074bb90dSTom Pothier 118*074bb90dSTom Pothier types->ids = (smbs_con_ids_t **)kmem_zalloc( 119*074bb90dSTom Pothier count * sizeof (smbs_con_ids_t *), KM_SLEEP); 120*074bb90dSTom Pothier 121*074bb90dSTom Pothier for (i = 0; i < count; i++) { 122*074bb90dSTom Pothier types->ids[i] = (smbs_con_ids_t *)kmem_zalloc( 123*074bb90dSTom Pothier sizeof (smbs_con_ids_t), KM_SLEEP); 124*074bb90dSTom Pothier } 125*074bb90dSTom Pothier 126*074bb90dSTom Pothier for (i = 0; i < count; i++) { 127*074bb90dSTom Pothier types->ids[i]->cont_ids = (uint16_t **)kmem_zalloc( 128*074bb90dSTom Pothier MAX_CONT * sizeof (uint16_t *), KM_SLEEP); 129*074bb90dSTom Pothier } 130*074bb90dSTom Pothier 131*074bb90dSTom Pothier for (i = 0; i < count; i++) { 132*074bb90dSTom Pothier for (j = 0; j < MAX_CONT; j++) { 133*074bb90dSTom Pothier types->ids[i]->cont_ids[j] = (uint16_t *)kmem_zalloc( 134*074bb90dSTom Pothier sizeof (uint16_t), KM_SLEEP); 135*074bb90dSTom Pothier } 136*074bb90dSTom Pothier } 137*074bb90dSTom Pothier return (types); 138*074bb90dSTom Pothier } 139*074bb90dSTom Pothier 140*074bb90dSTom Pothier /* 141*074bb90dSTom Pothier * free the smbs_cnt_t memory 142*074bb90dSTom Pothier */ 143*074bb90dSTom Pothier static void 144*074bb90dSTom Pothier smb_free_strcnt(smbs_cnt_t *types, int count) 145*074bb90dSTom Pothier { 146*074bb90dSTom Pothier int i, j; 147*074bb90dSTom Pothier 148*074bb90dSTom Pothier if (types == NULL) 149*074bb90dSTom Pothier return; 150*074bb90dSTom Pothier 151*074bb90dSTom Pothier for (i = 0; i < count; i++) { 152*074bb90dSTom Pothier for (j = 0; j < MAX_CONT; j++) { 153*074bb90dSTom Pothier if (types->ids[i]->cont_ids[j] != NULL) 154*074bb90dSTom Pothier kmem_free(types->ids[i]->cont_ids[j], 155*074bb90dSTom Pothier sizeof (uint16_t)); 156*074bb90dSTom Pothier } 157*074bb90dSTom Pothier } 158*074bb90dSTom Pothier 159*074bb90dSTom Pothier for (i = 0; i < count; i++) { 160*074bb90dSTom Pothier if (types->ids[i]->cont_ids != NULL) 161*074bb90dSTom Pothier kmem_free(types->ids[i]->cont_ids, 162*074bb90dSTom Pothier MAX_CONT * sizeof (uint16_t *)); 163*074bb90dSTom Pothier } 164*074bb90dSTom Pothier 165*074bb90dSTom Pothier for (i = 0; i < count; i++) { 166*074bb90dSTom Pothier if (types->ids[i] != NULL) 167*074bb90dSTom Pothier kmem_free(types->ids[i], sizeof (smbs_con_ids_t)); 168*074bb90dSTom Pothier } 169*074bb90dSTom Pothier 170*074bb90dSTom Pothier if (types->ids != NULL) 171*074bb90dSTom Pothier kmem_free(types->ids, count * sizeof (smbs_con_ids_t *)); 172*074bb90dSTom Pothier 173*074bb90dSTom Pothier if (types != NULL) 174*074bb90dSTom Pothier kmem_free(types, sizeof (smbs_cnt_t)); 175*074bb90dSTom Pothier 176*074bb90dSTom Pothier } 177*074bb90dSTom Pothier 178*074bb90dSTom Pothier /* 179*074bb90dSTom Pothier * count number of the structure type in the ksmbios 180*074bb90dSTom Pothier */ 181*074bb90dSTom Pothier static int 182*074bb90dSTom Pothier smb_cnttypes(smbios_hdl_t *shp, int type) 183*074bb90dSTom Pothier { 184*074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 185*074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 186*074bb90dSTom Pothier int i; 187*074bb90dSTom Pothier int cnt = 0; 188*074bb90dSTom Pothier 189*074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 190*074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == type) 191*074bb90dSTom Pothier cnt++; 192*074bb90dSTom Pothier } 193*074bb90dSTom Pothier return (cnt); 194*074bb90dSTom Pothier } 195*074bb90dSTom Pothier 196*074bb90dSTom Pothier static void 197*074bb90dSTom Pothier smb_strcnt(smbios_hdl_t *shp, smbs_cnt_t *stype) 198*074bb90dSTom Pothier { 199*074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 200*074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 201*074bb90dSTom Pothier smbios_bboard_t bb; 202*074bb90dSTom Pothier int i, cnt; 203*074bb90dSTom Pothier int mb_cnt = 0; 204*074bb90dSTom Pothier int cpub_cnt = 0; 205*074bb90dSTom Pothier int sysb_cnt = 0; 206*074bb90dSTom Pothier int memb_cnt = 0; 207*074bb90dSTom Pothier int iob_cnt = 0; 208*074bb90dSTom Pothier int inst = 0; 209*074bb90dSTom Pothier int rc = 0; 210*074bb90dSTom Pothier 211*074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 212*074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == stype->type) { 213*074bb90dSTom Pothier stype->ids[cnt]->id = sp->smbst_hdr->smbh_hdl; 214*074bb90dSTom Pothier stype->ids[cnt]->inst = cnt; 215*074bb90dSTom Pothier stype->ids[cnt]->visited = 0; 216*074bb90dSTom Pothier stype->ids[cnt]->cont_by_id = -1; 217*074bb90dSTom Pothier if (stype->type == SMB_TYPE_BASEBOARD) { 218*074bb90dSTom Pothier rc = smbios_info_bboard(shp, 219*074bb90dSTom Pothier stype->ids[cnt]->id, &bb); 220*074bb90dSTom Pothier if (rc == 0) { 221*074bb90dSTom Pothier switch (bb.smbb_type) { 222*074bb90dSTom Pothier case SMB_BBT_PROC : 223*074bb90dSTom Pothier inst = cpub_cnt++; 224*074bb90dSTom Pothier break; 225*074bb90dSTom Pothier case SMB_BBT_IO : 226*074bb90dSTom Pothier inst = iob_cnt++; 227*074bb90dSTom Pothier break; 228*074bb90dSTom Pothier case SMB_BBT_MEM : 229*074bb90dSTom Pothier inst = memb_cnt++; 230*074bb90dSTom Pothier break; 231*074bb90dSTom Pothier case SMB_BBT_MOTHER : 232*074bb90dSTom Pothier inst = mb_cnt++; 233*074bb90dSTom Pothier break; 234*074bb90dSTom Pothier default: 235*074bb90dSTom Pothier /* 236*074bb90dSTom Pothier * SMB_BBT_UNKNOWN 237*074bb90dSTom Pothier * SMB_BBT_OTHER 238*074bb90dSTom Pothier * SMB_BBT_SBLADE 239*074bb90dSTom Pothier * SMB_BBT_CSWITCH 240*074bb90dSTom Pothier * SMB_BBT_SMM 241*074bb90dSTom Pothier * SMB_BBT_DAUGHTER 242*074bb90dSTom Pothier * SMB_BBT_PROCMEM 243*074bb90dSTom Pothier * SMB_BBT_PROCIO 244*074bb90dSTom Pothier * SMB_BBT_INTER 245*074bb90dSTom Pothier */ 246*074bb90dSTom Pothier inst = sysb_cnt++; 247*074bb90dSTom Pothier break; 248*074bb90dSTom Pothier } 249*074bb90dSTom Pothier stype->ids[cnt]->inst = inst; 250*074bb90dSTom Pothier } 251*074bb90dSTom Pothier } 252*074bb90dSTom Pothier cnt++; 253*074bb90dSTom Pothier } 254*074bb90dSTom Pothier } 255*074bb90dSTom Pothier stype->count = cnt; 256*074bb90dSTom Pothier } 257*074bb90dSTom Pothier 258*074bb90dSTom Pothier /* 259*074bb90dSTom Pothier * Go through the smbios structures looking for type 2. Fill in 260*074bb90dSTom Pothier * the cont_id and cont_by_id for each type 2 261*074bb90dSTom Pothier * 262*074bb90dSTom Pothier */ 263*074bb90dSTom Pothier static void 264*074bb90dSTom Pothier smb_bb_contains(smbios_hdl_t *shp, smbs_cnt_t *stype) 265*074bb90dSTom Pothier { 266*074bb90dSTom Pothier int i, j, cnt, c; 267*074bb90dSTom Pothier uint_t cont_count; 268*074bb90dSTom Pothier const smb_struct_t *spt; 269*074bb90dSTom Pothier smbios_bboard_t smb_bb; 270*074bb90dSTom Pothier uint16_t bb_id, cont_id; 271*074bb90dSTom Pothier uint_t cont_len; 272*074bb90dSTom Pothier id_t *cont_hdl = NULL; 273*074bb90dSTom Pothier int rc; 274*074bb90dSTom Pothier 275*074bb90dSTom Pothier for (cnt = 0; cnt < stype->count; cnt++) { 276*074bb90dSTom Pothier bb_id = stype->ids[cnt]->id; 277*074bb90dSTom Pothier (void) smbios_info_bboard(shp, stype->ids[cnt]->id, &smb_bb); 278*074bb90dSTom Pothier cont_count = (uint_t)smb_bb.smbb_contn; 279*074bb90dSTom Pothier if (cont_count == 0) { 280*074bb90dSTom Pothier continue; 281*074bb90dSTom Pothier } 282*074bb90dSTom Pothier 283*074bb90dSTom Pothier cont_len = sizeof (id_t); 284*074bb90dSTom Pothier cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP); 285*074bb90dSTom Pothier if (cont_hdl == NULL) 286*074bb90dSTom Pothier continue; 287*074bb90dSTom Pothier 288*074bb90dSTom Pothier rc = smbios_info_contains(shp, stype->ids[cnt]->id, 289*074bb90dSTom Pothier cont_count, cont_hdl); 290*074bb90dSTom Pothier if (rc > SMB_CONT_MAX) { 291*074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 292*074bb90dSTom Pothier continue; 293*074bb90dSTom Pothier } 294*074bb90dSTom Pothier cont_count = MIN(rc, cont_count); 295*074bb90dSTom Pothier 296*074bb90dSTom Pothier /* 297*074bb90dSTom Pothier * fill in the type 2 and type 4 ids which are 298*074bb90dSTom Pothier * contained in this type 2 299*074bb90dSTom Pothier */ 300*074bb90dSTom Pothier c = 0; 301*074bb90dSTom Pothier for (j = 0; j < cont_count; j++) { 302*074bb90dSTom Pothier cont_id = (uint16_t)cont_hdl[j]; 303*074bb90dSTom Pothier spt = smb_lookup_id(shp, cont_id); 304*074bb90dSTom Pothier if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD || 305*074bb90dSTom Pothier spt->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) { 306*074bb90dSTom Pothier *stype->ids[cnt]->cont_ids[c] = cont_id; 307*074bb90dSTom Pothier c++; 308*074bb90dSTom Pothier } 309*074bb90dSTom Pothier 310*074bb90dSTom Pothier if (spt->smbst_hdr->smbh_type == SMB_TYPE_BASEBOARD) { 311*074bb90dSTom Pothier for (i = 0; i < stype->count; i++) { 312*074bb90dSTom Pothier if (stype->ids[i]->id == cont_id) { 313*074bb90dSTom Pothier stype->ids[i]->cont_by_id = 314*074bb90dSTom Pothier bb_id; 315*074bb90dSTom Pothier } 316*074bb90dSTom Pothier } 317*074bb90dSTom Pothier } 318*074bb90dSTom Pothier 319*074bb90dSTom Pothier } 320*074bb90dSTom Pothier stype->ids[cnt]->cont_count = c; 321*074bb90dSTom Pothier if (cont_hdl != NULL) 322*074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 323*074bb90dSTom Pothier } 324*074bb90dSTom Pothier } 325*074bb90dSTom Pothier 326*074bb90dSTom Pothier /* 327*074bb90dSTom Pothier * Verify SMBIOS structures for x86 generic topology. 328*074bb90dSTom Pothier * 329*074bb90dSTom Pothier * Return (0) on success. 330*074bb90dSTom Pothier */ 331*074bb90dSTom Pothier static int 332*074bb90dSTom Pothier fm_smb_check(smbios_hdl_t *shp) 333*074bb90dSTom Pothier { 334*074bb90dSTom Pothier int i; 335*074bb90dSTom Pothier int bb_cnt = 0; 336*074bb90dSTom Pothier int pr_cnt = 0; 337*074bb90dSTom Pothier int expr_cnt = 0; 338*074bb90dSTom Pothier int ma_cnt = 0; 339*074bb90dSTom Pothier int exma_cnt = 0; 340*074bb90dSTom Pothier int mdev_cnt = 0; 341*074bb90dSTom Pothier int exmdev_cnt = 0; 342*074bb90dSTom Pothier uint16_t bb_id; 343*074bb90dSTom Pothier uint16_t pr_id, expr_id; 344*074bb90dSTom Pothier uint16_t ma_id, exma_id; 345*074bb90dSTom Pothier uint16_t mdev_id, exmdev_id; 346*074bb90dSTom Pothier smbios_bboard_t bb; 347*074bb90dSTom Pothier smbios_processor_ext_t exproc; 348*074bb90dSTom Pothier smbios_memarray_ext_t exma; 349*074bb90dSTom Pothier smbios_memdevice_ext_t exmdev; 350*074bb90dSTom Pothier smbs_cnt_t *bb_stype; 351*074bb90dSTom Pothier smbs_cnt_t *pr_stype, *expr_stype; 352*074bb90dSTom Pothier smbs_cnt_t *ma_stype, *exma_stype; 353*074bb90dSTom Pothier smbs_cnt_t *mdev_stype, *exmdev_stype; 354*074bb90dSTom Pothier 355*074bb90dSTom Pothier /* 356*074bb90dSTom Pothier * Verify the existance of the requuired extended OEM-Specific 357*074bb90dSTom Pothier * structures and they coincide with the structures they extend 358*074bb90dSTom Pothier * (e.g. the number of extended processor structures equal the 359*074bb90dSTom Pothier * number of processor structures). 360*074bb90dSTom Pothier */ 361*074bb90dSTom Pothier pr_cnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 362*074bb90dSTom Pothier expr_cnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR); 363*074bb90dSTom Pothier ma_cnt = smb_cnttypes(shp, SMB_TYPE_MEMARRAY); 364*074bb90dSTom Pothier exma_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 365*074bb90dSTom Pothier mdev_cnt = smb_cnttypes(shp, SMB_TYPE_MEMDEVICE); 366*074bb90dSTom Pothier exmdev_cnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMDEVICE); 367*074bb90dSTom Pothier if (expr_cnt == 0 || exma_cnt == 0 || exmdev_cnt == 0 || 368*074bb90dSTom Pothier expr_cnt != pr_cnt || exma_cnt != ma_cnt || 369*074bb90dSTom Pothier exmdev_cnt != mdev_cnt) { 370*074bb90dSTom Pothier #ifdef DEBUG 371*074bb90dSTom Pothier cmn_err(CE_NOTE, "Structure mismatch: ext_proc (%d) " 372*074bb90dSTom Pothier "proc (%d) ext_ma (%d) ma (%d) ext_mdev (%d) mdev (%d)\n", 373*074bb90dSTom Pothier expr_cnt, pr_cnt, exma_cnt, ma_cnt, exmdev_cnt, 374*074bb90dSTom Pothier mdev_cnt); 375*074bb90dSTom Pothier #endif /* DEBUG */ 376*074bb90dSTom Pothier return (-1); 377*074bb90dSTom Pothier } 378*074bb90dSTom Pothier 379*074bb90dSTom Pothier /* 380*074bb90dSTom Pothier * Verify the OEM-Specific structrures are correctly 381*074bb90dSTom Pothier * linked to the SMBIOS structure types they extend. 382*074bb90dSTom Pothier */ 383*074bb90dSTom Pothier 384*074bb90dSTom Pothier /* allocate processor stypes */ 385*074bb90dSTom Pothier pr_stype = smb_create_strcnt(pr_cnt); 386*074bb90dSTom Pothier expr_stype = smb_create_strcnt(expr_cnt); 387*074bb90dSTom Pothier 388*074bb90dSTom Pothier /* fill in stypes */ 389*074bb90dSTom Pothier pr_stype->type = SMB_TYPE_PROCESSOR; 390*074bb90dSTom Pothier smb_strcnt(shp, pr_stype); 391*074bb90dSTom Pothier expr_stype->type = SUN_OEM_EXT_PROCESSOR; 392*074bb90dSTom Pothier smb_strcnt(shp, expr_stype); 393*074bb90dSTom Pothier 394*074bb90dSTom Pothier /* verify the ext proc struct belong to the proc struct */ 395*074bb90dSTom Pothier for (i = 0; i < pr_cnt; i++) { 396*074bb90dSTom Pothier pr_id = pr_stype->ids[i]->id; 397*074bb90dSTom Pothier expr_id = expr_stype->ids[i]->id; 398*074bb90dSTom Pothier (void) smbios_info_extprocessor(shp, expr_id, &exproc); 399*074bb90dSTom Pothier if (exproc.smbpe_processor != pr_id) { 400*074bb90dSTom Pothier #ifdef DEBUG 401*074bb90dSTom Pothier cmn_err(CE_NOTE, "Processor struct linkage (%d)", i); 402*074bb90dSTom Pothier #endif /* DEBUG */ 403*074bb90dSTom Pothier smb_free_strcnt(pr_stype, pr_cnt); 404*074bb90dSTom Pothier smb_free_strcnt(expr_stype, expr_cnt); 405*074bb90dSTom Pothier return (-1); 406*074bb90dSTom Pothier } 407*074bb90dSTom Pothier } 408*074bb90dSTom Pothier 409*074bb90dSTom Pothier /* free stypes */ 410*074bb90dSTom Pothier smb_free_strcnt(pr_stype, pr_cnt); 411*074bb90dSTom Pothier smb_free_strcnt(expr_stype, expr_cnt); 412*074bb90dSTom Pothier 413*074bb90dSTom Pothier /* allocate memory array stypes */ 414*074bb90dSTom Pothier ma_stype = smb_create_strcnt(ma_cnt); 415*074bb90dSTom Pothier exma_stype = smb_create_strcnt(exma_cnt); 416*074bb90dSTom Pothier 417*074bb90dSTom Pothier /* fill in stypes */ 418*074bb90dSTom Pothier ma_stype->type = SMB_TYPE_MEMARRAY; 419*074bb90dSTom Pothier smb_strcnt(shp, ma_stype); 420*074bb90dSTom Pothier exma_stype->type = SUN_OEM_EXT_MEMARRAY; 421*074bb90dSTom Pothier smb_strcnt(shp, exma_stype); 422*074bb90dSTom Pothier 423*074bb90dSTom Pothier /* verify linkage from ext memarray struct to memarray struct */ 424*074bb90dSTom Pothier for (i = 0; i < ma_cnt; i++) { 425*074bb90dSTom Pothier ma_id = ma_stype->ids[i]->id; 426*074bb90dSTom Pothier exma_id = exma_stype->ids[i]->id; 427*074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, exma_id, &exma); 428*074bb90dSTom Pothier if (exma.smbmae_ma != ma_id) { 429*074bb90dSTom Pothier #ifdef DEBUG 430*074bb90dSTom Pothier cmn_err(CE_NOTE, "Memory Array struct linkage (%d)", i); 431*074bb90dSTom Pothier #endif /* DEBUG */ 432*074bb90dSTom Pothier smb_free_strcnt(ma_stype, ma_cnt); 433*074bb90dSTom Pothier smb_free_strcnt(exma_stype, exma_cnt); 434*074bb90dSTom Pothier return (-1); 435*074bb90dSTom Pothier } 436*074bb90dSTom Pothier } 437*074bb90dSTom Pothier 438*074bb90dSTom Pothier /* free stypes */ 439*074bb90dSTom Pothier smb_free_strcnt(ma_stype, ma_cnt); 440*074bb90dSTom Pothier smb_free_strcnt(exma_stype, exma_cnt); 441*074bb90dSTom Pothier 442*074bb90dSTom Pothier /* allocate memory device stypes */ 443*074bb90dSTom Pothier mdev_stype = smb_create_strcnt(mdev_cnt); 444*074bb90dSTom Pothier exmdev_stype = smb_create_strcnt(exmdev_cnt); 445*074bb90dSTom Pothier 446*074bb90dSTom Pothier /* fill in stypes */ 447*074bb90dSTom Pothier mdev_stype->type = SMB_TYPE_MEMDEVICE; 448*074bb90dSTom Pothier smb_strcnt(shp, mdev_stype); 449*074bb90dSTom Pothier exmdev_stype->type = SUN_OEM_EXT_MEMDEVICE; 450*074bb90dSTom Pothier smb_strcnt(shp, exmdev_stype); 451*074bb90dSTom Pothier 452*074bb90dSTom Pothier /* verify linkage */ 453*074bb90dSTom Pothier for (i = 0; i < mdev_cnt; i++) { 454*074bb90dSTom Pothier mdev_id = mdev_stype->ids[i]->id; 455*074bb90dSTom Pothier exmdev_id = exmdev_stype->ids[i]->id; 456*074bb90dSTom Pothier (void) smbios_info_extmemdevice(shp, exmdev_id, &exmdev); 457*074bb90dSTom Pothier if (exmdev.smbmdeve_md != mdev_id) { 458*074bb90dSTom Pothier #ifdef DEBUG 459*074bb90dSTom Pothier cmn_err(CE_NOTE, "Memory Device struct linkage (%d)", 460*074bb90dSTom Pothier i); 461*074bb90dSTom Pothier #endif /* DEBUG */ 462*074bb90dSTom Pothier smb_free_strcnt(mdev_stype, mdev_cnt); 463*074bb90dSTom Pothier smb_free_strcnt(exmdev_stype, exmdev_cnt); 464*074bb90dSTom Pothier return (-1); 465*074bb90dSTom Pothier } 466*074bb90dSTom Pothier } 467*074bb90dSTom Pothier 468*074bb90dSTom Pothier /* free stypes */ 469*074bb90dSTom Pothier smb_free_strcnt(mdev_stype, mdev_cnt); 470*074bb90dSTom Pothier smb_free_strcnt(exmdev_stype, exmdev_cnt); 471*074bb90dSTom Pothier 472*074bb90dSTom Pothier /* 473*074bb90dSTom Pothier * Verify the presece of contained handles if there are more 474*074bb90dSTom Pothier * than one Type-2 (Base Board) structures. 475*074bb90dSTom Pothier */ 476*074bb90dSTom Pothier bb_cnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD); 477*074bb90dSTom Pothier if (bb_cnt > 1) { 478*074bb90dSTom Pothier /* allocate base board stypes */ 479*074bb90dSTom Pothier bb_stype = smb_create_strcnt(bb_cnt); 480*074bb90dSTom Pothier 481*074bb90dSTom Pothier /* fill in stypes */ 482*074bb90dSTom Pothier bb_stype->type = SMB_TYPE_BASEBOARD; 483*074bb90dSTom Pothier smb_strcnt(shp, bb_stype); 484*074bb90dSTom Pothier 485*074bb90dSTom Pothier /* verify contained handles */ 486*074bb90dSTom Pothier for (i = 0; i < bb_cnt; i++) { 487*074bb90dSTom Pothier bb_id = bb_stype->ids[i]->id; 488*074bb90dSTom Pothier (void) smbios_info_bboard(shp, bb_id, &bb); 489*074bb90dSTom Pothier if (bb.smbb_contn == 0) { 490*074bb90dSTom Pothier #ifdef DEBUG 491*074bb90dSTom Pothier cmn_err(CE_NOTE, "No contained hanldes (%d)", 492*074bb90dSTom Pothier i); 493*074bb90dSTom Pothier #endif /* DEBUG */ 494*074bb90dSTom Pothier smb_free_strcnt(bb_stype, bb_cnt); 495*074bb90dSTom Pothier return (-1); 496*074bb90dSTom Pothier } 497*074bb90dSTom Pothier } 498*074bb90dSTom Pothier 499*074bb90dSTom Pothier /* free stypes */ 500*074bb90dSTom Pothier smb_free_strcnt(bb_stype, bb_cnt); 501*074bb90dSTom Pothier } 502*074bb90dSTom Pothier 503*074bb90dSTom Pothier return (0); 504*074bb90dSTom Pothier } 505*074bb90dSTom Pothier 506*074bb90dSTom Pothier void 507*074bb90dSTom Pothier fm_smb_fmacompat() 508*074bb90dSTom Pothier { 509*074bb90dSTom Pothier int i, j; 510*074bb90dSTom Pothier int id; 511*074bb90dSTom Pothier int cnt; 512*074bb90dSTom Pothier const char **oem_strings = NULL; 513*074bb90dSTom Pothier smbs_cnt_t *oemstypes; 514*074bb90dSTom Pothier smbios_hdl_t *shp; 515*074bb90dSTom Pothier int strcnt; 516*074bb90dSTom Pothier int compat = 0; 517*074bb90dSTom Pothier 518*074bb90dSTom Pothier /* check for BKS */ 519*074bb90dSTom Pothier if (x86gentopo_legacy == 1) { 520*074bb90dSTom Pothier #ifdef DEBUG 521*074bb90dSTom Pothier cmn_err(CE_NOTE, "forced legacy x86 topology enumeration"); 522*074bb90dSTom Pothier #endif /* DEBUG */ 523*074bb90dSTom Pothier return; 524*074bb90dSTom Pothier } 525*074bb90dSTom Pothier 526*074bb90dSTom Pothier shp = ksmbios; 527*074bb90dSTom Pothier if (shp == NULL) { 528*074bb90dSTom Pothier goto bad; 529*074bb90dSTom Pothier } 530*074bb90dSTom Pothier 531*074bb90dSTom Pothier /* OEM strings (Type 11) */ 532*074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SMB_TYPE_OEMSTR); 533*074bb90dSTom Pothier if (strcnt == 0) 534*074bb90dSTom Pothier goto bad; 535*074bb90dSTom Pothier 536*074bb90dSTom Pothier oemstypes = smb_create_strcnt(strcnt); 537*074bb90dSTom Pothier if (oemstypes == NULL) 538*074bb90dSTom Pothier goto bad; 539*074bb90dSTom Pothier 540*074bb90dSTom Pothier oemstypes->type = SMB_TYPE_OEMSTR; 541*074bb90dSTom Pothier smb_strcnt(shp, oemstypes); 542*074bb90dSTom Pothier 543*074bb90dSTom Pothier for (i = 0; i < oemstypes->count; i++) { 544*074bb90dSTom Pothier id = oemstypes->ids[i]->id; 545*074bb90dSTom Pothier cnt = smbios_info_strtab(shp, id, 0, NULL); 546*074bb90dSTom Pothier if (cnt > 0) { 547*074bb90dSTom Pothier oem_strings = kmem_zalloc(sizeof (char *) * cnt, 548*074bb90dSTom Pothier KM_SLEEP); 549*074bb90dSTom Pothier (void) smbios_info_strtab(shp, id, cnt, oem_strings); 550*074bb90dSTom Pothier 551*074bb90dSTom Pothier for (j = 0; j < cnt; j++) { 552*074bb90dSTom Pothier if (strncmp(oem_strings[j], SMB_PRMS1, 553*074bb90dSTom Pothier strlen(SMB_PRMS1) + 1) == 0) { 554*074bb90dSTom Pothier kmem_free(oem_strings, 555*074bb90dSTom Pothier sizeof (char *) * cnt); 556*074bb90dSTom Pothier smb_free_strcnt(oemstypes, strcnt); 557*074bb90dSTom Pothier compat = 1; 558*074bb90dSTom Pothier break; 559*074bb90dSTom Pothier } 560*074bb90dSTom Pothier } 561*074bb90dSTom Pothier } 562*074bb90dSTom Pothier } 563*074bb90dSTom Pothier 564*074bb90dSTom Pothier if (compat == 0) { 565*074bb90dSTom Pothier /* didn't find x86pi magic cookie */ 566*074bb90dSTom Pothier if (oem_strings != NULL) 567*074bb90dSTom Pothier kmem_free(oem_strings, sizeof (char *) * cnt); 568*074bb90dSTom Pothier smb_free_strcnt(oemstypes, strcnt); 569*074bb90dSTom Pothier goto bad; 570*074bb90dSTom Pothier } 571*074bb90dSTom Pothier 572*074bb90dSTom Pothier /* sanity check SMBIOS structures */ 573*074bb90dSTom Pothier if (fm_smb_check(shp) == 0) 574*074bb90dSTom Pothier return; 575*074bb90dSTom Pothier 576*074bb90dSTom Pothier bad: 577*074bb90dSTom Pothier /* not compatible with x86gentopo; revert to legacy enumeration */ 578*074bb90dSTom Pothier #ifdef DEBUG 579*074bb90dSTom Pothier cmn_err(CE_NOTE, "SMBIOS is not compatible with x86 generic topology."); 580*074bb90dSTom Pothier cmn_err(CE_NOTE, "Invoking legacy x86 topology enumeration."); 581*074bb90dSTom Pothier #endif /* DEBUG */ 582*074bb90dSTom Pothier x86gentopo_legacy = 1; 583*074bb90dSTom Pothier } 584*074bb90dSTom Pothier 585*074bb90dSTom Pothier static int 586*074bb90dSTom Pothier find_matching_apic(smbios_hdl_t *shp, uint16_t proc_id, uint_t strand_apicid) 587*074bb90dSTom Pothier { 588*074bb90dSTom Pothier uint16_t ext_id; 589*074bb90dSTom Pothier int i, j; 590*074bb90dSTom Pothier smbios_processor_ext_t ep; 591*074bb90dSTom Pothier smbs_cnt_t *pstypes; 592*074bb90dSTom Pothier int strcnt; 593*074bb90dSTom Pothier 594*074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SUN_OEM_EXT_PROCESSOR); 595*074bb90dSTom Pothier if (strcnt == 0) 596*074bb90dSTom Pothier return (0); 597*074bb90dSTom Pothier 598*074bb90dSTom Pothier pstypes = smb_create_strcnt(strcnt); 599*074bb90dSTom Pothier if (pstypes == NULL) 600*074bb90dSTom Pothier return (0); 601*074bb90dSTom Pothier 602*074bb90dSTom Pothier pstypes->type = SUN_OEM_EXT_PROCESSOR; 603*074bb90dSTom Pothier smb_strcnt(shp, pstypes); 604*074bb90dSTom Pothier for (i = 0; i < pstypes->count; i++) { 605*074bb90dSTom Pothier ext_id = pstypes->ids[i]->id; 606*074bb90dSTom Pothier (void) smbios_info_extprocessor(shp, ext_id, &ep); 607*074bb90dSTom Pothier if (ep.smbpe_processor == proc_id) { 608*074bb90dSTom Pothier for (j = 0; j < ep.smbpe_n; j++) { 609*074bb90dSTom Pothier if (ep.smbpe_apicid[j] == strand_apicid) { 610*074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 611*074bb90dSTom Pothier return (1); 612*074bb90dSTom Pothier } 613*074bb90dSTom Pothier } 614*074bb90dSTom Pothier } 615*074bb90dSTom Pothier } 616*074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 617*074bb90dSTom Pothier return (0); 618*074bb90dSTom Pothier } 619*074bb90dSTom Pothier 620*074bb90dSTom Pothier /* 621*074bb90dSTom Pothier * go throught the type 2 structure contained_ids looking for 622*074bb90dSTom Pothier * the type 4 which has strand_apicid == this strand_apicid 623*074bb90dSTom Pothier */ 624*074bb90dSTom Pothier static int 625*074bb90dSTom Pothier find_matching_proc(smbios_hdl_t *shp, uint_t strand_apicid, 626*074bb90dSTom Pothier uint16_t bb_id, uint16_t proc_hdl, int is_proc) 627*074bb90dSTom Pothier { 628*074bb90dSTom Pothier int n; 629*074bb90dSTom Pothier const smb_struct_t *sp; 630*074bb90dSTom Pothier smbios_bboard_t bb; 631*074bb90dSTom Pothier uint_t cont_count, cont_len; 632*074bb90dSTom Pothier uint16_t cont_id; 633*074bb90dSTom Pothier id_t *cont_hdl = NULL; 634*074bb90dSTom Pothier int rc; 635*074bb90dSTom Pothier 636*074bb90dSTom Pothier 637*074bb90dSTom Pothier (void) smbios_info_bboard(shp, bb_id, &bb); 638*074bb90dSTom Pothier cont_count = (uint_t)bb.smbb_contn; 639*074bb90dSTom Pothier if (cont_count == 0) 640*074bb90dSTom Pothier return (0); 641*074bb90dSTom Pothier 642*074bb90dSTom Pothier cont_len = sizeof (id_t); 643*074bb90dSTom Pothier cont_hdl = kmem_zalloc(cont_count * cont_len, KM_SLEEP); 644*074bb90dSTom Pothier if (cont_hdl == NULL) 645*074bb90dSTom Pothier return (0); 646*074bb90dSTom Pothier 647*074bb90dSTom Pothier rc = smbios_info_contains(shp, bb_id, cont_count, cont_hdl); 648*074bb90dSTom Pothier if (rc > SMB_CONT_MAX) { 649*074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 650*074bb90dSTom Pothier return (0); 651*074bb90dSTom Pothier } 652*074bb90dSTom Pothier cont_count = MIN(rc, cont_count); 653*074bb90dSTom Pothier 654*074bb90dSTom Pothier for (n = 0; n < cont_count; n++) { 655*074bb90dSTom Pothier cont_id = (uint16_t)cont_hdl[n]; 656*074bb90dSTom Pothier sp = smb_lookup_id(shp, cont_id); 657*074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == SMB_TYPE_PROCESSOR) { 658*074bb90dSTom Pothier if (is_proc) { 659*074bb90dSTom Pothier if (find_matching_apic(shp, cont_id, 660*074bb90dSTom Pothier strand_apicid)) { 661*074bb90dSTom Pothier kmem_free(cont_hdl, 662*074bb90dSTom Pothier cont_count * cont_len); 663*074bb90dSTom Pothier return (1); 664*074bb90dSTom Pothier } 665*074bb90dSTom Pothier } else { 666*074bb90dSTom Pothier if (cont_id == proc_hdl) { 667*074bb90dSTom Pothier kmem_free(cont_hdl, 668*074bb90dSTom Pothier cont_count * cont_len); 669*074bb90dSTom Pothier return (1); 670*074bb90dSTom Pothier } 671*074bb90dSTom Pothier } 672*074bb90dSTom Pothier } 673*074bb90dSTom Pothier } 674*074bb90dSTom Pothier if (cont_hdl != NULL) 675*074bb90dSTom Pothier kmem_free(cont_hdl, cont_count * cont_len); 676*074bb90dSTom Pothier 677*074bb90dSTom Pothier return (0); 678*074bb90dSTom Pothier } 679*074bb90dSTom Pothier 680*074bb90dSTom Pothier void 681*074bb90dSTom Pothier get_bboard_index(smbs_cnt_t *bbstypes, uint_t bb_id, bbindex_t *bb_idx) 682*074bb90dSTom Pothier { 683*074bb90dSTom Pothier int curr_id, tmp_id; 684*074bb90dSTom Pothier int i, j, nb; 685*074bb90dSTom Pothier bbindex_t tmp_idx; 686*074bb90dSTom Pothier 687*074bb90dSTom Pothier for (i = 0; i < MAX_PAIRS; i++) 688*074bb90dSTom Pothier tmp_idx.index[i] = 0; 689*074bb90dSTom Pothier 690*074bb90dSTom Pothier tmp_idx.count = 0; 691*074bb90dSTom Pothier 692*074bb90dSTom Pothier curr_id = bb_id; 693*074bb90dSTom Pothier for (nb = bbstypes->count-1, i = 0; nb >= 0; nb--) { 694*074bb90dSTom Pothier tmp_id = bbstypes->ids[nb]->id; 695*074bb90dSTom Pothier if (tmp_id == curr_id) { 696*074bb90dSTom Pothier tmp_idx.index[i] = nb; 697*074bb90dSTom Pothier tmp_idx.count++; 698*074bb90dSTom Pothier curr_id = bbstypes->ids[nb]->cont_by_id; 699*074bb90dSTom Pothier if (curr_id == -1) 700*074bb90dSTom Pothier break; 701*074bb90dSTom Pothier i++; 702*074bb90dSTom Pothier } 703*074bb90dSTom Pothier } 704*074bb90dSTom Pothier 705*074bb90dSTom Pothier for (i = tmp_idx.count - 1, j = 0; i >= 0; i--) { 706*074bb90dSTom Pothier bb_idx->index[j] = tmp_idx.index[i]; 707*074bb90dSTom Pothier j++; 708*074bb90dSTom Pothier } 709*074bb90dSTom Pothier 710*074bb90dSTom Pothier bb_idx->count = tmp_idx.count; 711*074bb90dSTom Pothier } 712*074bb90dSTom Pothier 713*074bb90dSTom Pothier int 714*074bb90dSTom Pothier get_chassis_inst(smbios_hdl_t *shp, uint16_t *chassis_inst, 715*074bb90dSTom Pothier uint16_t bb_id, int *chcnt) 716*074bb90dSTom Pothier { 717*074bb90dSTom Pothier int ch_strcnt; 718*074bb90dSTom Pothier smbs_cnt_t *chstypes; 719*074bb90dSTom Pothier uint16_t chassis_id, tmp_id; 720*074bb90dSTom Pothier smbios_bboard_t bb; 721*074bb90dSTom Pothier int rc = 0; 722*074bb90dSTom Pothier int i; 723*074bb90dSTom Pothier 724*074bb90dSTom Pothier rc = smbios_info_bboard(shp, bb_id, &bb); 725*074bb90dSTom Pothier if (rc != 0) { 726*074bb90dSTom Pothier return (-1); 727*074bb90dSTom Pothier } 728*074bb90dSTom Pothier 729*074bb90dSTom Pothier chassis_id = bb.smbb_chassis; 730*074bb90dSTom Pothier 731*074bb90dSTom Pothier ch_strcnt = smb_cnttypes(shp, SMB_TYPE_CHASSIS); 732*074bb90dSTom Pothier 733*074bb90dSTom Pothier if (ch_strcnt == 0) 734*074bb90dSTom Pothier return (-1); 735*074bb90dSTom Pothier 736*074bb90dSTom Pothier chstypes = smb_create_strcnt(ch_strcnt); 737*074bb90dSTom Pothier if (chstypes == NULL) 738*074bb90dSTom Pothier return (-1); 739*074bb90dSTom Pothier 740*074bb90dSTom Pothier chstypes->type = SMB_TYPE_CHASSIS; 741*074bb90dSTom Pothier smb_strcnt(shp, chstypes); 742*074bb90dSTom Pothier 743*074bb90dSTom Pothier for (i = 0; i < chstypes->count; i++) { 744*074bb90dSTom Pothier tmp_id = chstypes->ids[i]->id; 745*074bb90dSTom Pothier if (tmp_id == chassis_id) { 746*074bb90dSTom Pothier *chassis_inst = chstypes->ids[i]->inst; 747*074bb90dSTom Pothier if (chstypes->ids[i]->inst != 0) 748*074bb90dSTom Pothier *chcnt = 2; 749*074bb90dSTom Pothier else 750*074bb90dSTom Pothier *chcnt = 1; 751*074bb90dSTom Pothier smb_free_strcnt(chstypes, ch_strcnt); 752*074bb90dSTom Pothier return (0); 753*074bb90dSTom Pothier } 754*074bb90dSTom Pothier } 755*074bb90dSTom Pothier 756*074bb90dSTom Pothier smb_free_strcnt(chstypes, ch_strcnt); 757*074bb90dSTom Pothier return (-1); 758*074bb90dSTom Pothier } 759*074bb90dSTom Pothier 760*074bb90dSTom Pothier int 761*074bb90dSTom Pothier smb_get_bb_fmri(smbios_hdl_t *shp, nvlist_t *fmri, uint_t parent, 762*074bb90dSTom Pothier smbs_cnt_t *bbstypes) 763*074bb90dSTom Pothier { 764*074bb90dSTom Pothier int rc = 0; 765*074bb90dSTom Pothier int i, j, n, cnt; 766*074bb90dSTom Pothier int id, index; 767*074bb90dSTom Pothier nvlist_t *pairs[MAX_PAIRS]; 768*074bb90dSTom Pothier smbios_bboard_t bb; 769*074bb90dSTom Pothier uint16_t chassis_inst, mch_inst; 770*074bb90dSTom Pothier char name[40]; 771*074bb90dSTom Pothier char idstr[11]; 772*074bb90dSTom Pothier bbindex_t bb_idx; 773*074bb90dSTom Pothier uint16_t bbid; 774*074bb90dSTom Pothier int chcnt = 0; 775*074bb90dSTom Pothier 776*074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 777*074bb90dSTom Pothier bb_idx.index[n] = 0; 778*074bb90dSTom Pothier pairs[n] = NULL; 779*074bb90dSTom Pothier } 780*074bb90dSTom Pothier bb_idx.count = 0; 781*074bb90dSTom Pothier 782*074bb90dSTom Pothier get_bboard_index(bbstypes, parent, &bb_idx); 783*074bb90dSTom Pothier 784*074bb90dSTom Pothier index = bb_idx.index[0]; 785*074bb90dSTom Pothier bbid = bbstypes->ids[index]->id; 786*074bb90dSTom Pothier 787*074bb90dSTom Pothier rc = get_chassis_inst(shp, &chassis_inst, bbid, &chcnt); 788*074bb90dSTom Pothier 789*074bb90dSTom Pothier if (rc != 0) { 790*074bb90dSTom Pothier return (rc); 791*074bb90dSTom Pothier } 792*074bb90dSTom Pothier 793*074bb90dSTom Pothier if ((bb_idx.count + chcnt) > MAX_PAIRS) { 794*074bb90dSTom Pothier return (-1); 795*074bb90dSTom Pothier } 796*074bb90dSTom Pothier 797*074bb90dSTom Pothier i = 0; 798*074bb90dSTom Pothier if (chcnt > 1) { 799*074bb90dSTom Pothier /* 800*074bb90dSTom Pothier * create main chassis pair 801*074bb90dSTom Pothier */ 802*074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 803*074bb90dSTom Pothier if (pairs[i] == NULL) { 804*074bb90dSTom Pothier return (-1); 805*074bb90dSTom Pothier } 806*074bb90dSTom Pothier mch_inst = 0; 807*074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", mch_inst); 808*074bb90dSTom Pothier if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, 809*074bb90dSTom Pothier "chassis") != 0) || 810*074bb90dSTom Pothier (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr)) != 0) { 811*074bb90dSTom Pothier fm_nvlist_destroy(pairs[i], FM_NVA_FREE); 812*074bb90dSTom Pothier return (-1); 813*074bb90dSTom Pothier } 814*074bb90dSTom Pothier i++; 815*074bb90dSTom Pothier } 816*074bb90dSTom Pothier 817*074bb90dSTom Pothier /* 818*074bb90dSTom Pothier * create chassis pair 819*074bb90dSTom Pothier */ 820*074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 821*074bb90dSTom Pothier if (pairs[i] == NULL) { 822*074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 823*074bb90dSTom Pothier if (pairs[n] != NULL) 824*074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 825*074bb90dSTom Pothier } 826*074bb90dSTom Pothier return (-1); 827*074bb90dSTom Pothier } 828*074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", chassis_inst); 829*074bb90dSTom Pothier if ((nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, "chassis") != 0) || 830*074bb90dSTom Pothier (nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) != 0)) { 831*074bb90dSTom Pothier for (n = 0; n < MAX_PAIRS; n++) { 832*074bb90dSTom Pothier if (pairs[n] != NULL) 833*074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 834*074bb90dSTom Pothier } 835*074bb90dSTom Pothier return (-1); 836*074bb90dSTom Pothier } 837*074bb90dSTom Pothier 838*074bb90dSTom Pothier for (j = 0, i = chcnt, cnt = chcnt; j < bb_idx.count; j++) { 839*074bb90dSTom Pothier index = bb_idx.index[j]; 840*074bb90dSTom Pothier bbid = bbstypes->ids[index]->id; 841*074bb90dSTom Pothier rc = smbios_info_bboard(shp, bbid, &bb); 842*074bb90dSTom Pothier if (rc != 0) { 843*074bb90dSTom Pothier rc = -1; 844*074bb90dSTom Pothier break; 845*074bb90dSTom Pothier } 846*074bb90dSTom Pothier 847*074bb90dSTom Pothier pairs[i] = fm_nvlist_create(NULL); 848*074bb90dSTom Pothier if (pairs[i] == NULL) { 849*074bb90dSTom Pothier rc = -1; 850*074bb90dSTom Pothier break; 851*074bb90dSTom Pothier } 852*074bb90dSTom Pothier 853*074bb90dSTom Pothier id = bbstypes->ids[index]->inst; 854*074bb90dSTom Pothier (void) snprintf(idstr, sizeof (idstr), "%u", id); 855*074bb90dSTom Pothier (void) strncpy(name, bbd_type[bb.smbb_type].name, 856*074bb90dSTom Pothier sizeof (name)); 857*074bb90dSTom Pothier cnt++; 858*074bb90dSTom Pothier 859*074bb90dSTom Pothier if (nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name) != 0 || 860*074bb90dSTom Pothier nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr) 861*074bb90dSTom Pothier != 0) { 862*074bb90dSTom Pothier rc = -1; 863*074bb90dSTom Pothier break; 864*074bb90dSTom Pothier } 865*074bb90dSTom Pothier i++; 866*074bb90dSTom Pothier } 867*074bb90dSTom Pothier 868*074bb90dSTom Pothier if (rc != -1) { 869*074bb90dSTom Pothier if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, 870*074bb90dSTom Pothier pairs, cnt) != 0) { 871*074bb90dSTom Pothier rc = -1; 872*074bb90dSTom Pothier } 873*074bb90dSTom Pothier } 874*074bb90dSTom Pothier 875*074bb90dSTom Pothier for (n = 0; n < cnt; n++) { 876*074bb90dSTom Pothier if (pairs[n] != NULL) 877*074bb90dSTom Pothier fm_nvlist_destroy(pairs[n], FM_NVA_FREE); 878*074bb90dSTom Pothier } 879*074bb90dSTom Pothier 880*074bb90dSTom Pothier return (rc); 881*074bb90dSTom Pothier } 882*074bb90dSTom Pothier 883*074bb90dSTom Pothier /* 884*074bb90dSTom Pothier * pass in strand_apic id 885*074bb90dSTom Pothier * return chip's bboards list which has strand_apicid == passed 886*074bb90dSTom Pothier * in strand_apic id 887*074bb90dSTom Pothier */ 888*074bb90dSTom Pothier static nvlist_t * 889*074bb90dSTom Pothier smb_bboard(uint_t strand_apicid, uint16_t proc_hdl, int is_proc) 890*074bb90dSTom Pothier { 891*074bb90dSTom Pothier smbios_hdl_t *shp; 892*074bb90dSTom Pothier smbs_cnt_t *bbstypes; 893*074bb90dSTom Pothier int nb; 894*074bb90dSTom Pothier int bb_smbid; 895*074bb90dSTom Pothier nvlist_t *fmri = NULL; 896*074bb90dSTom Pothier int rc = 0; 897*074bb90dSTom Pothier int bb_strcnt; 898*074bb90dSTom Pothier 899*074bb90dSTom Pothier if (x86gentopo_legacy) 900*074bb90dSTom Pothier return (NULL); 901*074bb90dSTom Pothier 902*074bb90dSTom Pothier shp = ksmbios; 903*074bb90dSTom Pothier if (shp == NULL) { 904*074bb90dSTom Pothier goto bad; 905*074bb90dSTom Pothier } 906*074bb90dSTom Pothier 907*074bb90dSTom Pothier /* 908*074bb90dSTom Pothier * Type 2 structs : "base board" 909*074bb90dSTom Pothier */ 910*074bb90dSTom Pothier bb_strcnt = smb_cnttypes(shp, SMB_TYPE_BASEBOARD); 911*074bb90dSTom Pothier if (bb_strcnt == 0) { 912*074bb90dSTom Pothier goto bad; 913*074bb90dSTom Pothier } 914*074bb90dSTom Pothier 915*074bb90dSTom Pothier bbstypes = smb_create_strcnt(bb_strcnt); 916*074bb90dSTom Pothier if (bbstypes == NULL) { 917*074bb90dSTom Pothier goto bad; 918*074bb90dSTom Pothier } 919*074bb90dSTom Pothier 920*074bb90dSTom Pothier bbstypes->type = SMB_TYPE_BASEBOARD; 921*074bb90dSTom Pothier smb_strcnt(shp, bbstypes); 922*074bb90dSTom Pothier smb_bb_contains(shp, bbstypes); 923*074bb90dSTom Pothier 924*074bb90dSTom Pothier for (nb = 0; nb < bbstypes->count; nb++) { 925*074bb90dSTom Pothier if (bbstypes->ids[nb]->visited) { 926*074bb90dSTom Pothier continue; 927*074bb90dSTom Pothier } 928*074bb90dSTom Pothier 929*074bb90dSTom Pothier bbstypes->ids[nb]->visited = 1; 930*074bb90dSTom Pothier bb_smbid = bbstypes->ids[nb]->id; 931*074bb90dSTom Pothier 932*074bb90dSTom Pothier /* 933*074bb90dSTom Pothier * check if there is a matching processor under 934*074bb90dSTom Pothier * this board. If found, find base board(s) of this proc 935*074bb90dSTom Pothier * If proc is not in contained handle of a base board and 936*074bb90dSTom Pothier * there is only one base board in the system, treat that base 937*074bb90dSTom Pothier * board as the parent of the proc 938*074bb90dSTom Pothier */ 939*074bb90dSTom Pothier if (find_matching_proc(shp, strand_apicid, 940*074bb90dSTom Pothier bb_smbid, proc_hdl, is_proc) || (bbstypes->count == 1)) { 941*074bb90dSTom Pothier fmri = fm_nvlist_create(NULL); 942*074bb90dSTom Pothier if (fmri == NULL) { 943*074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 944*074bb90dSTom Pothier goto bad; 945*074bb90dSTom Pothier } 946*074bb90dSTom Pothier /* 947*074bb90dSTom Pothier * find parent by walking the cont_by_id 948*074bb90dSTom Pothier */ 949*074bb90dSTom Pothier rc = smb_get_bb_fmri(shp, fmri, bb_smbid, bbstypes); 950*074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 951*074bb90dSTom Pothier if (rc == 0) { 952*074bb90dSTom Pothier return (fmri); 953*074bb90dSTom Pothier } else 954*074bb90dSTom Pothier goto bad; 955*074bb90dSTom Pothier } 956*074bb90dSTom Pothier 957*074bb90dSTom Pothier } 958*074bb90dSTom Pothier 959*074bb90dSTom Pothier smb_free_strcnt(bbstypes, bb_strcnt); 960*074bb90dSTom Pothier bad: 961*074bb90dSTom Pothier /* revert to legacy enumeration */ 962*074bb90dSTom Pothier x86gentopo_legacy = 1; 963*074bb90dSTom Pothier 964*074bb90dSTom Pothier return (NULL); 965*074bb90dSTom Pothier } 966*074bb90dSTom Pothier 967*074bb90dSTom Pothier nvlist_t * 968*074bb90dSTom Pothier fm_smb_bboard(uint_t strand_apicid) 969*074bb90dSTom Pothier { 970*074bb90dSTom Pothier return (smb_bboard(strand_apicid, 0, PROC)); 971*074bb90dSTom Pothier } 972*074bb90dSTom Pothier 973*074bb90dSTom Pothier int 974*074bb90dSTom Pothier fm_smb_chipinst(uint_t strand_apicid, uint_t *chip_inst, uint16_t *smbiosid) 975*074bb90dSTom Pothier { 976*074bb90dSTom Pothier int n; 977*074bb90dSTom Pothier smbios_hdl_t *shp; 978*074bb90dSTom Pothier uint16_t proc_id; 979*074bb90dSTom Pothier smbs_cnt_t *pstypes; 980*074bb90dSTom Pothier int strcnt; 981*074bb90dSTom Pothier 982*074bb90dSTom Pothier if (x86gentopo_legacy) 983*074bb90dSTom Pothier return (-1); 984*074bb90dSTom Pothier 985*074bb90dSTom Pothier shp = ksmbios; 986*074bb90dSTom Pothier if (shp == NULL) { 987*074bb90dSTom Pothier goto bad; 988*074bb90dSTom Pothier } 989*074bb90dSTom Pothier 990*074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 991*074bb90dSTom Pothier if (strcnt == 0) 992*074bb90dSTom Pothier goto bad; 993*074bb90dSTom Pothier 994*074bb90dSTom Pothier pstypes = smb_create_strcnt(strcnt); 995*074bb90dSTom Pothier if (pstypes == NULL) 996*074bb90dSTom Pothier goto bad; 997*074bb90dSTom Pothier 998*074bb90dSTom Pothier pstypes->type = SMB_TYPE_PROCESSOR; 999*074bb90dSTom Pothier smb_strcnt(shp, pstypes); 1000*074bb90dSTom Pothier for (n = 0; n < pstypes->count; n++) { 1001*074bb90dSTom Pothier proc_id = pstypes->ids[n]->id; 1002*074bb90dSTom Pothier if (find_matching_apic(shp, proc_id, strand_apicid)) { 1003*074bb90dSTom Pothier *chip_inst = pstypes->ids[n]->inst; 1004*074bb90dSTom Pothier *smbiosid = pstypes->ids[n]->id; 1005*074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 1006*074bb90dSTom Pothier return (0); 1007*074bb90dSTom Pothier } 1008*074bb90dSTom Pothier } 1009*074bb90dSTom Pothier smb_free_strcnt(pstypes, strcnt); 1010*074bb90dSTom Pothier bad: 1011*074bb90dSTom Pothier /* revert to legacy enumerarion */ 1012*074bb90dSTom Pothier x86gentopo_legacy = 1; 1013*074bb90dSTom Pothier 1014*074bb90dSTom Pothier return (-1); 1015*074bb90dSTom Pothier } 1016*074bb90dSTom Pothier 1017*074bb90dSTom Pothier nvlist_t * 1018*074bb90dSTom Pothier fm_smb_mc_bboards(uint_t bdf) 1019*074bb90dSTom Pothier { 1020*074bb90dSTom Pothier 1021*074bb90dSTom Pothier int i; 1022*074bb90dSTom Pothier smbios_hdl_t *shp; 1023*074bb90dSTom Pothier uint16_t ext_id; 1024*074bb90dSTom Pothier smbios_memarray_ext_t em; 1025*074bb90dSTom Pothier nvlist_t *fmri = NULL; 1026*074bb90dSTom Pothier smbs_cnt_t *mastypes; 1027*074bb90dSTom Pothier int strcnt; 1028*074bb90dSTom Pothier 1029*074bb90dSTom Pothier if (x86gentopo_legacy) 1030*074bb90dSTom Pothier return (NULL); 1031*074bb90dSTom Pothier 1032*074bb90dSTom Pothier shp = ksmbios; 1033*074bb90dSTom Pothier if (shp == NULL) { 1034*074bb90dSTom Pothier goto bad; 1035*074bb90dSTom Pothier } 1036*074bb90dSTom Pothier 1037*074bb90dSTom Pothier strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 1038*074bb90dSTom Pothier if (strcnt == 0) 1039*074bb90dSTom Pothier goto bad; 1040*074bb90dSTom Pothier 1041*074bb90dSTom Pothier mastypes = smb_create_strcnt(strcnt); 1042*074bb90dSTom Pothier if (mastypes == NULL) 1043*074bb90dSTom Pothier goto bad; 1044*074bb90dSTom Pothier 1045*074bb90dSTom Pothier mastypes->type = SUN_OEM_EXT_MEMARRAY; 1046*074bb90dSTom Pothier smb_strcnt(shp, mastypes); 1047*074bb90dSTom Pothier for (i = 0; i < mastypes->count; i++) { 1048*074bb90dSTom Pothier ext_id = mastypes->ids[i]->id; 1049*074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, ext_id, &em); 1050*074bb90dSTom Pothier if (em.smbmae_bdf == bdf) { 1051*074bb90dSTom Pothier fmri = smb_bboard(0, em.smbmae_comp, MC); 1052*074bb90dSTom Pothier smb_free_strcnt(mastypes, strcnt); 1053*074bb90dSTom Pothier return (fmri); 1054*074bb90dSTom Pothier } 1055*074bb90dSTom Pothier } 1056*074bb90dSTom Pothier smb_free_strcnt(mastypes, strcnt); 1057*074bb90dSTom Pothier bad: 1058*074bb90dSTom Pothier /* revert to legacy enumerarion */ 1059*074bb90dSTom Pothier x86gentopo_legacy = 1; 1060*074bb90dSTom Pothier 1061*074bb90dSTom Pothier return (NULL); 1062*074bb90dSTom Pothier } 1063*074bb90dSTom Pothier 1064*074bb90dSTom Pothier int 1065*074bb90dSTom Pothier fm_smb_mc_chipinst(uint_t bdf, uint_t *chip_inst) { 1066*074bb90dSTom Pothier 1067*074bb90dSTom Pothier int i, j; 1068*074bb90dSTom Pothier smbios_hdl_t *shp; 1069*074bb90dSTom Pothier smbios_memarray_ext_t em; 1070*074bb90dSTom Pothier uint16_t ext_id, proc_id; 1071*074bb90dSTom Pothier smbs_cnt_t *mastypes; 1072*074bb90dSTom Pothier smbs_cnt_t *pstypes; 1073*074bb90dSTom Pothier int ma_strcnt, p_strcnt; 1074*074bb90dSTom Pothier 1075*074bb90dSTom Pothier if (x86gentopo_legacy) 1076*074bb90dSTom Pothier return (-1); 1077*074bb90dSTom Pothier 1078*074bb90dSTom Pothier shp = ksmbios; 1079*074bb90dSTom Pothier if (shp == NULL) { 1080*074bb90dSTom Pothier goto bad; 1081*074bb90dSTom Pothier } 1082*074bb90dSTom Pothier 1083*074bb90dSTom Pothier ma_strcnt = smb_cnttypes(shp, SUN_OEM_EXT_MEMARRAY); 1084*074bb90dSTom Pothier if (ma_strcnt == 0) 1085*074bb90dSTom Pothier goto bad; 1086*074bb90dSTom Pothier 1087*074bb90dSTom Pothier mastypes = smb_create_strcnt(ma_strcnt); 1088*074bb90dSTom Pothier if (mastypes == NULL) 1089*074bb90dSTom Pothier goto bad; 1090*074bb90dSTom Pothier 1091*074bb90dSTom Pothier mastypes->type = SUN_OEM_EXT_MEMARRAY; 1092*074bb90dSTom Pothier smb_strcnt(shp, mastypes); 1093*074bb90dSTom Pothier for (i = 0; i < mastypes->count; i++) { 1094*074bb90dSTom Pothier ext_id = mastypes->ids[i]->id; 1095*074bb90dSTom Pothier (void) smbios_info_extmemarray(shp, ext_id, &em); 1096*074bb90dSTom Pothier if (em.smbmae_bdf == bdf) { 1097*074bb90dSTom Pothier p_strcnt = smb_cnttypes(shp, SMB_TYPE_PROCESSOR); 1098*074bb90dSTom Pothier if (p_strcnt == 0) { 1099*074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1100*074bb90dSTom Pothier goto bad; 1101*074bb90dSTom Pothier } 1102*074bb90dSTom Pothier 1103*074bb90dSTom Pothier pstypes = smb_create_strcnt(p_strcnt); 1104*074bb90dSTom Pothier if (pstypes == NULL) { 1105*074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1106*074bb90dSTom Pothier goto bad; 1107*074bb90dSTom Pothier } 1108*074bb90dSTom Pothier 1109*074bb90dSTom Pothier pstypes->type = SMB_TYPE_PROCESSOR; 1110*074bb90dSTom Pothier smb_strcnt(shp, pstypes); 1111*074bb90dSTom Pothier for (j = 0; j < pstypes->count; j++) { 1112*074bb90dSTom Pothier proc_id = pstypes->ids[j]->id; 1113*074bb90dSTom Pothier if (proc_id == em.smbmae_comp) { 1114*074bb90dSTom Pothier *chip_inst = pstypes->ids[j]->inst; 1115*074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1116*074bb90dSTom Pothier smb_free_strcnt(pstypes, p_strcnt); 1117*074bb90dSTom Pothier return (0); 1118*074bb90dSTom Pothier } 1119*074bb90dSTom Pothier } 1120*074bb90dSTom Pothier } 1121*074bb90dSTom Pothier } 1122*074bb90dSTom Pothier smb_free_strcnt(mastypes, ma_strcnt); 1123*074bb90dSTom Pothier smb_free_strcnt(pstypes, p_strcnt); 1124*074bb90dSTom Pothier bad: 1125*074bb90dSTom Pothier /* revert to legacy enumeration */ 1126*074bb90dSTom Pothier x86gentopo_legacy = 1; 1127*074bb90dSTom Pothier 1128*074bb90dSTom Pothier return (-1); 1129*074bb90dSTom Pothier } 1130