265 lines
5.9 KiB
C
265 lines
5.9 KiB
C
/* ----------------------------------------------------------------------- *
|
|
*
|
|
* Pportions of this file taken from the dmidecode project
|
|
*
|
|
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
|
* Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* For the avoidance of doubt the "preferred form" of this code is one which
|
|
* is in an open unpatent encumbered format. Where cryptographic key signing
|
|
* forms part of the process of creating an executable the information
|
|
* including keys needed to generate an equivalently functional executable
|
|
* are deemed to be part of the source code.
|
|
*/
|
|
|
|
#include <dmi/dmi.h>
|
|
#include <stdio.h>
|
|
|
|
void dmi_memory_array_error_handle(uint16_t code, char *array)
|
|
{
|
|
if (code == 0xFFFE)
|
|
sprintf(array, "%s", "Not Provided");
|
|
else if (code == 0xFFFF)
|
|
sprintf(array, "%s", "No Error");
|
|
else
|
|
sprintf(array, "0x%04X", code);
|
|
}
|
|
|
|
void dmi_memory_device_width(uint16_t code, char *width)
|
|
{
|
|
/*
|
|
* 3.3.18 Memory Device (Type 17)
|
|
* If no memory module is present, width may be 0
|
|
*/
|
|
if (code == 0xFFFF || code == 0)
|
|
sprintf(width, "%s", "Unknown");
|
|
else
|
|
sprintf(width, "%u bits", code);
|
|
}
|
|
|
|
void dmi_memory_device_size(uint16_t code, char *size)
|
|
{
|
|
if (code == 0)
|
|
sprintf(size, "%s", "Free");
|
|
else if (code == 0xFFFF)
|
|
sprintf(size, "%s", "Unknown");
|
|
else {
|
|
if (code & 0x8000)
|
|
sprintf(size, "%u kB", code & 0x7FFF);
|
|
else
|
|
sprintf(size, "%u MB", code);
|
|
}
|
|
}
|
|
|
|
const char *dmi_memory_device_form_factor(uint8_t code)
|
|
{
|
|
/* 3.3.18.1 */
|
|
static const char *form_factor[] = {
|
|
"Other", /* 0x01 */
|
|
"Unknown",
|
|
"SIMM",
|
|
"SIP",
|
|
"Chip",
|
|
"DIP",
|
|
"ZIP",
|
|
"Proprietary Card",
|
|
"DIMM",
|
|
"TSOP",
|
|
"Row Of Chips",
|
|
"RIMM",
|
|
"SODIMM",
|
|
"SRIMM",
|
|
"FB-DIMM" /* 0x0F */
|
|
};
|
|
|
|
if (code >= 0x01 && code <= 0x0F)
|
|
return form_factor[code - 0x01];
|
|
return out_of_spec;
|
|
}
|
|
|
|
void dmi_memory_device_set(uint8_t code, char *set)
|
|
{
|
|
if (code == 0)
|
|
sprintf(set, "%s", "None");
|
|
else if (code == 0xFF)
|
|
sprintf(set, "%s", "Unknown");
|
|
else
|
|
sprintf(set, "%u", code);
|
|
}
|
|
|
|
const char *dmi_memory_device_type(uint8_t code)
|
|
{
|
|
/* 3.3.18.2 */
|
|
static const char *type[] = {
|
|
"Other", /* 0x01 */
|
|
"Unknown",
|
|
"DRAM",
|
|
"EDRAM",
|
|
"VRAM",
|
|
"SRAM",
|
|
"RAM",
|
|
"ROM",
|
|
"Flash",
|
|
"EEPROM",
|
|
"FEPROM",
|
|
"EPROM",
|
|
"CDRAM",
|
|
"3DRAM",
|
|
"SDRAM",
|
|
"SGRAM",
|
|
"RDRAM",
|
|
"DDR",
|
|
"DDR2",
|
|
"DDR2 FB-DIMM", /* 0x14 */
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
"DDR3", /* 0x18 */
|
|
"FBD2" /* 0x19 */
|
|
};
|
|
|
|
if (code >= 0x01 && code <= 0x19)
|
|
return type[code - 0x01];
|
|
return out_of_spec;
|
|
}
|
|
|
|
void dmi_memory_device_type_detail(uint16_t code, char *type_detail, int sizeof_type_detail)
|
|
{
|
|
/* 3.3.18.3 */
|
|
static const char *detail[] = {
|
|
"Other", /* 1 */
|
|
"Unknown",
|
|
"Fast-paged",
|
|
"Static Column",
|
|
"Pseudo-static",
|
|
"RAMBus",
|
|
"Synchronous",
|
|
"CMOS",
|
|
"EDO",
|
|
"Window DRAM",
|
|
"Cache DRAM",
|
|
"Non-Volatile" /* 12 */
|
|
};
|
|
|
|
if ((code & 0x1FFE) == 0)
|
|
sprintf(type_detail, "%s", "None");
|
|
else {
|
|
int i;
|
|
|
|
for (i = 1; i <= 12; i++)
|
|
if (code & (1 << i))
|
|
snprintf(type_detail, sizeof_type_detail, "%s", detail[i - 1]);
|
|
}
|
|
}
|
|
|
|
void dmi_memory_device_speed(uint16_t code, char *speed)
|
|
{
|
|
if (code == 0)
|
|
sprintf(speed, "%s", "Unknown");
|
|
else
|
|
sprintf(speed, "%u MHz", code);
|
|
}
|
|
|
|
/*
|
|
* 3.3.7 Memory Module Information (Type 6)
|
|
*/
|
|
|
|
void dmi_memory_module_types(uint16_t code, const char *sep, char *type, int sizeof_type)
|
|
{
|
|
/* 3.3.7.1 */
|
|
static const char *types[] = {
|
|
"Other", /* 0 */
|
|
"Unknown",
|
|
"Standard",
|
|
"FPM",
|
|
"EDO",
|
|
"Parity",
|
|
"ECC",
|
|
"SIMM",
|
|
"DIMM",
|
|
"Burst EDO",
|
|
"SDRAM" /* 10 */
|
|
};
|
|
|
|
if ((code & 0x07FF) == 0)
|
|
sprintf(type, "%s", "None");
|
|
else {
|
|
int i;
|
|
|
|
for (i = 0; i <= 10; i++)
|
|
if (code & (1 << i))
|
|
snprintf(type, sizeof_type, "%s%s%s", type, sep, types[i]);
|
|
}
|
|
}
|
|
|
|
void dmi_memory_module_connections(uint8_t code, char *connection, int sizeof_connection)
|
|
{
|
|
if (code == 0xFF)
|
|
sprintf(connection, "%s", "None");
|
|
else {
|
|
if ((code & 0xF0) != 0xF0)
|
|
sprintf(connection, "%u ", code >> 4);
|
|
if ((code & 0x0F) != 0x0F)
|
|
snprintf(connection, sizeof_connection, "%s%u", connection, code & 0x0F);
|
|
}
|
|
}
|
|
|
|
void dmi_memory_module_speed(uint8_t code, char *speed)
|
|
{
|
|
if (code == 0)
|
|
sprintf(speed, "%s", "Unknown");
|
|
else
|
|
sprintf(speed, "%u ns", code);
|
|
}
|
|
|
|
void dmi_memory_module_size(uint8_t code, char *size, int sizeof_size)
|
|
{
|
|
/* 3.3.7.2 */
|
|
switch (code & 0x7F) {
|
|
case 0x7D:
|
|
sprintf(size, "%s", "Not Determinable");
|
|
break;
|
|
case 0x7E:
|
|
sprintf(size, "%s", "Disabled");
|
|
break;
|
|
case 0x7F:
|
|
sprintf(size, "%s", "Not Installed");
|
|
return;
|
|
default:
|
|
sprintf(size, "%u MB", 1 << (code & 0x7F));
|
|
}
|
|
|
|
if (code & 0x80)
|
|
snprintf(size, sizeof_size, "%s %s", size, "(Double-bank Connection)");
|
|
else
|
|
snprintf(size, sizeof_size, "%s %s", size, "(Single-bank Connection)");
|
|
}
|
|
|
|
void dmi_memory_module_error(uint8_t code, const char *prefix, char *error)
|
|
{
|
|
if (code & (1 << 2))
|
|
sprintf(error, "%s", "See Event Log\n");
|
|
else {
|
|
if ((code & 0x03) == 0)
|
|
sprintf(error, "%s", "OK\n");
|
|
if (code & (1 << 0))
|
|
sprintf(error, "%sUncorrectable Errors\n", prefix);
|
|
if (code & (1 << 1))
|
|
sprintf(error, "%sCorrectable Errors\n", prefix);
|
|
}
|
|
}
|