x86pi.c revision 05ead181677a01a3a118f8b89ce79361113e34cf
/*
* 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
*/
/*
*/
/*
* x86 Generic FMA Topology Enumerator
*/
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>
#include <fm/topo_mod.h>
#include <sys/systeminfo.h>
#include <sys/smbios_impl.h>
#include <x86pi_impl.h>
/*
* Entry point called by libtopo when enumeration is required
*/
/*
* Declare the operations vector and information structure used during
* module registration
*/
static topo_modops_t x86pi_ops =
{ x86pi_enum, NULL };
static topo_modinfo_t x86pi_modinfo =
/*
* Used to pass SMBIOS' FM compatibility to the
* chip enumerator
*/
int x86pi_smbios = 0;
/*
* Called by libtopo when the topo module is loaded.
*/
int
{
int result;
char isa[MAXNAMELEN];
/* Debugging is requested for this module */
}
if (version != TOPO_VERSION) {
version);
return (-1);
}
/* Verify that this is a i86pc architecture machine */
return (-1);
}
if (result < 0) {
/* module errno already set */
return (-1);
}
return (0);
}
/*
* Clean up any data used by the module before it is unloaded.
*/
void
{
/* Unregister from libtopo */
}
/*
* Enumeration entry point for the x86 Generic topology enumerator
*/
/* ARGSUSED */
static int
{
int result;
/* Begin enumeration */
/*
* Let's do some enumeration.
*/
if (result != 0) {
return (-1);
}
/* Complete enumeration */
/* All done */
return (result);
}
static int
{
int rv;
int complvl = 0;
char *f = "x86pi_enum_start";
/*
* Verify BIOS compliance.
*/
} else {
}
if (complvl == X86PI_NONE) {
/* fall back to legacy enumeration */
"%s: Calling legacy enumeration\n", f);
"i86pc-legacy", FM_FMRI_SCHEME_HC));
}
if (x86pi_hbr_enum_init(mod) < 0) {
return (-1);
}
/*
* Create the topology.
*/
fac_done = 0;
if (rv != 0) {
return (-1);
}
if (fac_done == 0) {
}
/* All done */
return (rv);
}
/*
* Create the i86pc topology
*
* walk them creating the topo.
*
*
* Main Chassis
* Motherboard
* Memory Controllers/Memory Devices (DIMMs)
* PCIE HostBrige
* PCIE Root Complex
*
*/
static int
{
int rv;
int notvisited;
int ch_inst = 0;
int disk_inst = 0;
char *f = "x86pi_enum_gentopo";
return (-1);
}
/*
* "Chassis'"
*/
/* Type 3 structs */
/*
* Expect SMBIOS to set the first Chassis Structure to be the
*/
if (nch == 0)
else {
if (motherchassis_node != NULL)
else
}
if (chassis_node == NULL) {
"%s: Failed to create chassis %d\n", f, nch);
continue;
}
/* count SMBIOS extended port connector structures */
/*
* enumerate direct attached SATA disks if we found a
* SUN_OEM_EXT_PORT record.
*/
if (rv != 0) {
"%s: Failed to create %s range: %s\n",
continue;
}
} else {
"Skipping disk bay enumeration\n");
}
&export) != 0) {
"smbios_info_export failed: id = %d\n",
continue;
}
continue;
/*
* x86pi_gen_bay:
* create "bay" node
* call "disk" enum passing in "bay" node
*/
if (rv != 0)
"Failed to create disk %d\n", i);
disk_inst++;
}
}
/*
* "Base Board"
*/
/* Type 2 structs */
}
min = 0;
nbb = 0;
do {
/*
* We have reached end of the array due to the
* parent-child relationship, without visiting all
* baseboards! so re-iterate..
* (or)
* All baseboards are visited and their contained
* processors are enumerated
* More baseboards pending a visit
*/
nbb = 0;
break;
nbb++;
continue;
}
/*
* Get the Top-most Parent Baseboard, irrespective
* of its index in the array of Type-2s
* If this Baseboard has no Baseboard parents
* place it under the chassis that contains it
*/
"Failed to get BaseBoard node (%d): parent\n",
nbb);
return (-1);
}
for (int i = 0; i < bb_count; i++) {
if (bb_smbid ==
visited = 1;
notvisited--;
break;
}
}
} else {
notvisited--;
}
if (basebd_node == NULL) {
"Failed to create BaseBoard node (%d)\n", nbb);
nbb++;
continue;
}
/*
* Look for contained handles here and if there are
* make sure the chip handle below is part of it.
*/
if (ncmp > 0) {
/* make sure the chip enum is loaded */
"%s: Failed to load %s module: %s\n", f,
} else {
/* create node range */
"%s: chip range %d to %d\n",
if (rv != 0) {
"%s: Failed to create node range: "
"%s\n", f,
} else {
/* call the chip enumerator */
" chip enum\n", f);
rv =
&x86pi_smbios);
if (rv != 0)
"enumeration failed: \n",
f, CHIP);
}
}
}
/* enumerate the hostbridge node */
0, 255);
if (rv != 0) {
"%s: Failed to create %s range: %s\n",
continue;
}
&hbr) != 0) {
"smbios_info_pciexrc failed: "
continue;
}
continue;
if (rv != 0)
"couldn't create hostbridge=%d\n", hbri);
hbri++;
}
nbb++;
} while (notvisited);
return (0);
}