/*
* 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 <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <alloca.h>
#include <kstat.h>
#include <errno.h>
#include <libnvpair.h>
#include <sys/processor.h>
#include <sys/systeminfo.h>
#include <sys/mc_intel.h>
#include <fm/fmd_agent.h>
#include <fm/topo_mod.h>
#include "chip.h"
/*
* Enumerates the processing chips, or sockets, (as distinct from cores) in a
* system. For each chip found, the necessary nodes (one or more cores, and
* possibly a memory controller) are constructed underneath.
*/
topo_instance_t, topo_instance_t, void *, void *);
{ SIMPLE_CHIP_LBL, "Property method", 0,
{ G4_CHIP_LBL, "Property method", 0,
{ A4FPLUS_CHIP_LBL, "Property method", 0,
{ FSB2_CHIP_LBL, "Property method", 0,
{ NULL }
};
{ NULL }
};
int
{
if (getenv("TOPOCHIPDBG"))
return (-1); /* mod errno set */
}
return (0);
}
void
{
}
is_xpv(void)
{
static int r = -1;
if (r != -1)
return (r == 0);
return (r == 0);
}
static tnode_t *
{
return (NULL);
}
if (FM_AWARE_SMBIOS(mod)) {
int perr = 0;
serial);
part);
rev);
if (perr != 0)
"create_node: nvlist_add_string failed\n");
}
}
return (cnode);
}
static int
{
&strandid)) != 0) {
return (-1);
}
!= NULL) {
return (-1);
}
return (-1);
/*
* Inherit FRU from core node, in native use cpu scheme ASRU,
* in xpv, use hc scheme ASRU.
*/
/*
* From the inherited FRU, extract the Serial
* number(if SMBIOS donates) and set it in the ASRU
*/
if (FM_AWARE_SMBIOS(mod)) {
"create_strand: topo_prop_get_fmri failed\n");
"create_strand: nvlist_lookup_string failed: \n");
else
}
if (is_xpv()) {
"topo_node_resource failed\n");
} else {
if (FM_AWARE_SMBIOS(mod))
(void) nvlist_add_string(fmri,
}
} else {
"failed\n");
} else {
!= NULL) {
0, &err);
} else {
"cpu_fmri_create() failed\n");
}
}
}
"topo_method_register failed\n");
NULL);
if (FM_AWARE_SMBIOS(mod)) {
"topo_node_resource failed\n");
perr = 0;
}
FM_FMRI_HC_PART, &part);
if (perr != 0) {
"create_strand: nvlist_lookup_string failed\n");
perr = 0;
}
if (perr != 0)
"failed\n");
}
}
static int
{
!= 0) {
return (-1);
}
return (-1);
/*
* Inherit FRU from the chip node, for native, we use hc
* scheme ASRU for the core node.
*/
/*
* From the inherited FRU, extract the Serial
* number if SMBIOS donates and set it in the ASRU
*/
if (FM_AWARE_SMBIOS(mod)) {
"create_core: topo_prop_get_fmri failed\n");
&val) != 0)
"nvlist_lookup_string failed\n");
else
}
if (is_xpv()) {
"topo_node_resource failed\n");
} else {
if (FM_AWARE_SMBIOS(mod))
(void) nvlist_add_string(fmri,
}
}
"topo_method_register failed\n");
0, 255) != 0)
return (-1);
}
if (!is_xpv()) {
/*
* In native mode, we're in favor of cpu scheme ASRU for
* printing reason. More work needs to be done to support
* multi-strand cpu: the ASRU will be a list of cpuid then.
*/
"failed\n");
} else {
!= NULL) {
} else {
"cpu_fmri_create() failed\n");
}
}
}
if (FM_AWARE_SMBIOS(mod)) {
"topo_node_resource failed\n");
perr = 0;
}
FM_FMRI_HC_PART, &part);
if (perr != 0) {
"create_core: nvlist_lookup_string failed\n");
perr = 0;
}
if (perr != 0)
"failed\n");
}
}
static int
int mc_offchip)
{
const char *vendor;
/*
* of Type-4 structures, if SMBIOS meets FMA needs
*/
NULL);
if (err) {
return (-1);
}
return (-1);
if (FM_AWARE_SMBIOS(mod)) {
FM_PHYSCPU_INFO_SMBIOS_ID, &smbios_id)) != 0) {
"create_chip: lookup smbios_id failed"
": enumerating x86pi & chip topology, but"
" no Chip properties from SMBIOS"
/*
* Lets reset the module specific
* data to NULL, overriding any
* SMBIOS capability encoded earlier.
* This will fail all subsequent
* FM_AWARE_SMBIOS checks.
*/
}
}
return (-1);
/*
* Do not register XML map methods if SMBIOS can provide
* serial, part, revision & label
*/
if (!FM_AWARE_SMBIOS(mod)) {
"topo_method_register failed\n");
}
if (FM_AWARE_SMBIOS(mod)) {
int fru = 0;
char *label;
/*
* Chip is not a FRU, set the FRU fmri of parent node
*/
"topo_node_resource failed\n");
if (!fru) {
} else {
!= 0) {
"topo_node_fru_set failed\n");
perr = 0;
}
}
FM_FMRI_HC_PART, &part);
if (perr != 0) {
"create_chip: nvlist_lookup_string"
"failed\n");
perr = 0;
}
if (perr != 0)
"create_chip: topo_prop_set_string"
"failed\n");
== -1) {
"topo_node_label_set failed\n");
}
} else {
"topo_node_resource failed\n");
} else {
}
}
"topo_method_register failed\n");
return (-1);
0, 255))
return (-1);
}
}
if (FM_AWARE_SMBIOS(mod)) {
int status = 0;
/*
* STATUS
* CPU Socket Populated
* CPU Socket Unpopulated
* Populated : Enabled
* Populated : Disabled by BIOS (Setup)
* Populated : Disabled by BIOS (Error)
* Populated : Idle
*
* Enumerate core & strand only for Populated : Enabled
* Enumerate Off-Chip Memory Controller only for
* Populated : Enabled
*/
if (!status) {
"CPU Socket is not populated or is disabled\n");
return (0);
}
}
/*
* Create memory-controller node under a chip for architectures
* that may have on-chip memory-controller(s).
* If SMBIOS meets FMA needs, when Multi-Chip-Module is
* addressed, mc instances should be derived from SMBIOS
*/
} else if (create_mc && !mc_offchip)
}
/*ARGSUSED*/
static int
int mc_offchip)
{
int nerr = 0;
return (0);
return (-1);
return (-1);
}
for (i = 0; i < ncpu; i++) {
nvlist_free(cpus[i]);
}
if (nerr == 0) {
return (0);
} else {
return (-1);
}
}
/*ARGSUSED*/
static int
{
int rv = 0;
int offchip_mc;
/*
* Create nothing if we're running in domU.
*/
return (-1);
return (0);
if (fd != -1) {
return (0);
}
}
}
/*
* Set Chip Enumerator Module's private data with the value passed by
* x86pi Enumerator, defining SMBIOS capabilities
*/
if (FM_AWARE_SMBIOS(mod))
if (init_chip_smbios(mod) != 0) {
"init_chip_smbios() failed, "
" enumerating x86pi & chip topology, but no"
" CPU & Memory properties will be"
" derived from SMBIOS\n");
/*
* Lets reset the module specific
* data to NULL, overriding any
* SMBIOS capability encoded earlier.
* This will fail all subsequent
* FM_AWARE_SMBIOS checks.
*/
}
if (offchip_mc)
return (rv);
}