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