fmsmb.c revision 7991dd244dd6e9bd35355640fc39c8fe3300c4fb
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/smbios_impl.h>
/*
* Variable used to determine if the x86 generic topology enumerator will
* revert to legacy enumeration. I.E. Big Kill Switch... tunable via
*/
int x86gentopo_legacy = 0;
#define MC 0
#define PROC 1
#define MAX_PAIRS 20
#define MAX_CONT 40
typedef struct bbindex {
int count;
} bbindex_t;
/*
* the enum values come from DMTF
*/
typedef enum baseb {
BB_BAD = 0, /* There is no bb value 0 */
BB_UNKNOWN, /* Unknown */
BB_OTHER, /* Other */
BB_BLADE, /* Server Blade */
BB_CONNSW, /* Connectivity Switch */
BB_SMM, /* System Management Module */
BB_PROCMOD, /* Processor Module */
BB_IOMOD, /* I/O Module */
BB_MEMMOD, /* Memory Module */
BB_DBOARD, /* Daughter Board */
BB_MBOARD, /* Motherboard */
BB_PROCMMOD, /* Processor/Memory Module */
BB_PROCIOMOD, /* Processor/IO Module */
BB_ICONNBD /* Interconnect Board */
} bbd_t;
static struct bboard_type {
const char *name;
} bbd_type[] = {
{BB_UNKNOWN, "unknown"},
{BB_OTHER, "other"},
{BB_BLADE, "systemboard"},
{BB_CONNSW, "connswitch"},
{BB_SMM, "smmodule"},
{BB_PROCMOD, "cpuboard"},
{BB_IOMOD, "ioboard"},
{BB_MEMMOD, "memboard"},
{BB_DBOARD, "systemboard"},
{BB_MBOARD, "motherboard"},
{BB_PROCMMOD, "systemboard"},
{BB_PROCIOMOD, "systemboard"},
{BB_ICONNBD, "systemboard"}
};
typedef struct smbs_con_ids {
int id;
int inst;
int cont_count;
int cont_by_id;
int visited;
typedef struct smbs_cnt {
int type; /* SMBIOS stucture type */
int count; /* number of table entries */
} smbs_cnt_t;
/*
* dynamically allocate the storage for the smbs_cnt_t
*/
static smbs_cnt_t *
smb_create_strcnt(int count)
{
int i, j;
for (i = 0; i < count; i++) {
sizeof (smbs_con_ids_t), KM_SLEEP);
}
for (i = 0; i < count; i++) {
}
for (i = 0; i < count; i++) {
for (j = 0; j < MAX_CONT; j++) {
}
}
return (types);
}
/*
* free the smbs_cnt_t memory
*/
static void
{
int i, j;
return;
for (i = 0; i < count; i++) {
for (j = 0; j < MAX_CONT; j++) {
sizeof (uint16_t));
}
}
for (i = 0; i < count; i++) {
}
for (i = 0; i < count; i++) {
}
}
/*
* count number of the structure type in the ksmbios
*/
static int
{
int i;
int cnt = 0;
cnt++;
}
return (cnt);
}
static void
{
int i, cnt;
int mb_cnt = 0;
int cpub_cnt = 0;
int sysb_cnt = 0;
int memb_cnt = 0;
int iob_cnt = 0;
int inst = 0;
int rc = 0;
if (rc == 0) {
case SMB_BBT_PROC :
break;
case SMB_BBT_IO :
break;
case SMB_BBT_MEM :
break;
case SMB_BBT_MOTHER :
break;
default:
/*
* SMB_BBT_UNKNOWN
* SMB_BBT_OTHER
* SMB_BBT_SBLADE
* SMB_BBT_CSWITCH
* SMB_BBT_SMM
* SMB_BBT_DAUGHTER
* SMB_BBT_PROCMEM
* SMB_BBT_PROCIO
* SMB_BBT_INTER
*/
break;
}
}
}
cnt++;
}
}
}
/*
* Go through the smbios structures looking for type 2. Fill in
* the cont_id and cont_by_id for each type 2
*
*/
static void
{
int i, j, cnt, c;
const smb_struct_t *spt;
int rc;
if (cont_count == 0) {
continue;
}
continue;
if (rc > SMB_CONT_MAX) {
continue;
}
/*
* fill in the type 2 and type 4 ids which are
* contained in this type 2
*/
c = 0;
for (j = 0; j < cont_count; j++) {
c++;
}
}
}
}
}
}
}
/*
* Verify SMBIOS structures for x86 generic topology.
*
* Return (0) on success.
*/
static int
{
int i;
int bb_cnt = 0;
int pr_cnt = 0;
int expr_cnt = 0;
int ma_cnt = 0;
int exma_cnt = 0;
int mdev_cnt = 0;
int exmdev_cnt = 0;
/*
* Verify the existance of the requuired extended OEM-Specific
* structures and they coincide with the structures they extend
* (e.g. the number of extended processor structures equal the
* number of processor structures).
*/
exmdev_cnt != mdev_cnt) {
#ifdef DEBUG
"proc (%d) ext_ma (%d) ma (%d) ext_mdev (%d) mdev (%d)\n",
mdev_cnt);
#endif /* DEBUG */
return (-1);
}
/*
* Verify the OEM-Specific structrures are correctly
* linked to the SMBIOS structure types they extend.
*/
/* allocate processor stypes */
/* fill in stypes */
/* verify the ext proc struct belong to the proc struct */
for (i = 0; i < pr_cnt; i++) {
#ifdef DEBUG
#endif /* DEBUG */
return (-1);
}
}
/* free stypes */
/* allocate memory array stypes */
/* fill in stypes */
/* verify linkage from ext memarray struct to memarray struct */
for (i = 0; i < ma_cnt; i++) {
#ifdef DEBUG
"!Memory Array struct linkage (%d)", i);
#endif /* DEBUG */
return (-1);
}
}
/* free stypes */
/* allocate memory device stypes */
/* fill in stypes */
/* verify linkage */
for (i = 0; i < mdev_cnt; i++) {
#ifdef DEBUG
i);
#endif /* DEBUG */
return (-1);
}
}
/* free stypes */
/*
* Verify the presece of contained handles if there are more
* than one Type-2 (Base Board) structures.
*/
if (bb_cnt > 1) {
/* allocate base board stypes */
/* fill in stypes */
/* verify contained handles */
for (i = 0; i < bb_cnt; i++) {
if (bb.smbb_contn == 0) {
#ifdef DEBUG
i);
#endif /* DEBUG */
return (-1);
}
}
/* free stypes */
}
return (0);
}
void
{
int i, j;
int id;
int cnt;
const char **oem_strings = NULL;
int strcnt;
int compat = 0;
/* check for BKS */
if (x86gentopo_legacy == 1) {
return;
}
goto bad;
}
/* OEM strings (Type 11) */
if (strcnt == 0)
goto bad;
goto bad;
if (cnt > 0) {
KM_SLEEP);
for (j = 0; j < cnt; j++) {
sizeof (char *) * cnt);
compat = 1;
break;
}
}
}
}
if (compat == 0) {
/* didn't find x86pi magic cookie */
if (oem_strings != NULL)
goto bad;
}
/* sanity check SMBIOS structures */
if (fm_smb_check(shp) == 0)
return;
bad:
/* not compatible with x86gentopo; revert to legacy enumeration */
#ifdef DEBUG
"!SMBIOS is not compatible with x86 generic topology.");
#endif /* DEBUG */
x86gentopo_legacy = 1;
}
static int
{
int i, j;
int strcnt;
if (strcnt == 0)
return (0);
return (0);
return (1);
}
}
}
}
return (0);
}
/*
* go throught the type 2 structure contained_ids looking for
* the type 4 which has strand_apicid == this strand_apicid
*/
static int
{
int n;
const smb_struct_t *sp;
int rc;
if (cont_count == 0)
return (0);
return (0);
if (rc > SMB_CONT_MAX) {
return (0);
}
for (n = 0; n < cont_count; n++) {
if (is_proc) {
strand_apicid)) {
cont_count * cont_len);
return (1);
}
} else {
cont_count * cont_len);
return (1);
}
}
}
}
return (0);
}
void
{
int i, j, nb;
for (i = 0; i < MAX_PAIRS; i++)
if (curr_id == -1)
break;
i++;
}
}
j++;
}
}
int
{
int ch_strcnt;
int rc = 0;
int i;
if (rc != 0) {
return (-1);
}
if (ch_strcnt == 0)
return (-1);
return (-1);
if (tmp_id == chassis_id) {
*chcnt = 2;
else
*chcnt = 1;
return (0);
}
}
return (-1);
}
int
{
int rc = 0;
int i, j, n, cnt;
char name[40];
char idstr[11];
int chcnt = 0;
for (n = 0; n < MAX_PAIRS; n++) {
}
if (rc != 0) {
return (rc);
}
return (-1);
}
i = 0;
if (chcnt > 1) {
/*
* create main chassis pair
*/
return (-1);
}
mch_inst = 0;
"chassis") != 0) ||
return (-1);
}
i++;
}
/*
* create chassis pair
*/
for (n = 0; n < MAX_PAIRS; n++) {
}
return (-1);
}
for (n = 0; n < MAX_PAIRS; n++) {
}
return (-1);
}
if (rc != 0) {
rc = -1;
break;
}
rc = -1;
break;
}
sizeof (name));
cnt++;
!= 0) {
rc = -1;
break;
}
i++;
}
if (rc != -1) {
rc = -1;
}
}
for (n = 0; n < cnt; n++) {
}
return (rc);
}
/*
* pass in strand_apic id
* return chip's bboards list which has strand_apicid == passed
* in strand_apic id
*/
static nvlist_t *
{
int nb;
int bb_smbid;
int rc = 0;
int bb_strcnt;
if (x86gentopo_legacy)
return (NULL);
goto bad;
}
/*
* Type 2 structs : "base board"
*/
if (bb_strcnt == 0) {
goto bad;
}
goto bad;
}
continue;
}
/*
* check if there is a matching processor under
* this board. If found, find base board(s) of this proc
* If proc is not in contained handle of a base board and
* there is only one base board in the system, treat that base
* board as the parent of the proc
*/
goto bad;
}
/*
* find parent by walking the cont_by_id
*/
if (rc == 0) {
return (fmri);
} else
goto bad;
}
}
bad:
/* revert to legacy enumeration */
x86gentopo_legacy = 1;
return (NULL);
}
nvlist_t *
{
}
int
{
int n;
int strcnt;
if (x86gentopo_legacy)
return (-1);
goto bad;
}
if (strcnt == 0)
goto bad;
goto bad;
return (0);
}
}
bad:
/* revert to legacy enumerarion */
x86gentopo_legacy = 1;
return (-1);
}
nvlist_t *
{
int i;
int strcnt;
if (x86gentopo_legacy)
return (NULL);
goto bad;
}
if (strcnt == 0)
goto bad;
goto bad;
return (fmri);
}
}
bad:
/* revert to legacy enumerarion */
x86gentopo_legacy = 1;
return (NULL);
}
int
int i, j;
if (x86gentopo_legacy)
return (-1);
goto bad;
}
if (ma_strcnt == 0)
goto bad;
goto bad;
if (p_strcnt == 0) {
goto bad;
}
goto bad;
}
return (0);
}
}
}
}
bad:
/* revert to legacy enumeration */
x86gentopo_legacy = 1;
return (-1);
}