smbios.c revision 84ab085a13f931bc78e7415e7ce921dbaa14fcb3
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* x86 System Management BIOS prtdiag
*
* Most modern x86 systems support a System Management BIOS, which is a memory
* buffer filled in by the BIOS at boot time that describes the hardware. This
* data format is described by DMTF specification DSP0134 (see http://dmtf.org)
* This file implements a rudimentary prtdiag(1M) display using the SMBIOS.
*
* NOTE: It is important to understand that x86 hardware varies extremely
* widely and that the DMTF SMBIOS specification leaves way too much latitude
* for implementors, and provides no standardized validation mechanism. As
* such, it is not uncommon to find out-of-spec SMBIOSes or fields that
* contain strange and possibly even incorrect information. As such, this
* file should not be extended to report every SMBIOS tidbit or structure in
* the spec unless we have good reason to believe it tends to be reliable.
*
* Similarly, the prtdiag(1M) utility itself should not be used to spit out
* every possible bit of x86 configuration data from every possible source;
* otherwise this code will become an unmaintainable and untestable disaster.
* Extensions to prtdiag should prefer to use more stable kernel mechanisms
* that actually discover the true hardware when such subsystems are available,
* and should generally limit themselves to commonly needed h/w data. As such,
* extensions to x86 prtdiag should focus on integration with the device tree.
*
* The prtdiag(1M) utility is for service personnel and system administrators:
* it is not your personal ACPI disassembler or CPUID decoder ring. The
* complete SMBIOS data is available from smbdump(1), and other specialized
* tools can be created to display the state of other x86 features, especially
* when that information is more for kernel developers than box administrators.
*/
#include <smbios.h>
#include <alloca.h>
#include <locale.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
/*ARGSUSED*/
static int
{
const char *v;
char *s;
size_t n;
/*
* Obtaining a decent string for the type of processor is
* messy: the BIOS has hopefully filled in the SMBIOS record.
* If so, strip trailing spaces and \r (seen in some BIOSes).
* If not, fall back to the family name for p.smbp_family.
*/
v = s = alloca(n + 1);
if (s[n - 1] == '\r')
s[--n] = '\0';
while (n != 0 && isspace(s[n - 1]))
s[--n] = '\0';
} else if ((v = smbios_processor_family_desc(
p.smbp_family)) == NULL) {
v = gettext("Unknown");
}
}
return (0);
}
/*
* NOTE: It would be very convenient to print the DIMM size in do_memdevs.
* Unfortunately, SMBIOS can only be relied upon to tell us whether a DIMM is
* present or not (smbmd_size == 0). Some BIOSes do fill in an accurate size
* for DIMMs, whereas others fill in the maximum size, and still others insert
* a wrong value. Sizes will need to wait for x86 memory controller interfaces
* or integration with IPMI, which can actually read the true DIMM SPD data.
*/
/*ARGSUSED*/
static int
{
char buf[8];
else
t ? t : gettext("Unknown"),
}
return (0);
}
/*ARGSUSED*/
static int
{
int i, argc;
for (i = 0; i < argc; i++)
}
return (0);
}
/*ARGSUSED*/
static int
{
const char *t = smbios_slot_type_desc(s.smbl_type);
const char *u = smbios_slot_usage_desc(s.smbl_usage);
}
return (0);
}
/*ARGSUSED*/
int
{
const char *s;
int err;
gettext("%s: failed to open SMBIOS: %s\n"),
return (1);
}
} else {
gettext("%s: failed to get system info: %s\n"),
}
} else {
gettext("%s: failed to get bios info: %s\n"),
}
s = gettext("Unknown");
}
"\n==== Processor Sockets ====================================\n"));
"\n-------------------------------- --------------------------\n"));
"\n==== Memory Device Sockets ================================\n"));
"Type", "Status", "Set", "Device Locator", "Bank Locator");
"\n------- ------ --- ------------------- --------------------\n"));
"\n==== On-Board Devices =====================================\n"));
"\n==== Upgradeable Slots ====================================\n"));
"ID", "Status", "Type", "Description");
"\n--- --------- ---------------- ----------------------------\n"));
return (0);
}