📄 dmidecode.c
字号:
}
static void dmi_battery_maximum_error(u8 code)
{
if (code == 0xFF)
printf(" Unknown");
else
printf(" %u%%", code);
}
/*
* 3.3.24 System Reset (Type 23)
*/
/* code is assumed to be a 2-bit value */
static const char *dmi_system_reset_boot_option(u8 code)
{
static const char *option[] = {
out_of_spec, /* 0x0 */
"Operating System", /* 0x1 */
"System Utilities",
"Do Not Reboot" /* 0x3 */
};
return option[code];
}
static void dmi_system_reset_count(u16 code)
{
if (code == 0xFFFF)
printf(" Unknown");
else
printf(" %u", code);
}
static void dmi_system_reset_timer(u16 code)
{
if (code == 0xFFFF)
printf(" Unknown");
else
printf(" %u min", code);
}
/*
* 3.3.25 Hardware Security (Type 24)
*/
static const char *dmi_hardware_security_status(u8 code)
{
static const char *status[] = {
"Disabled", /* 0x00 */
"Enabled",
"Not Implemented",
"Unknown" /* 0x03 */
};
return status[code];
}
/*
* 3.3.26 System Power Controls (Type 25)
*/
static void dmi_power_controls_power_on(const u8 *p)
{
/* 3.3.26.1 */
if (dmi_bcd_range(p[0], 0x01, 0x12))
printf(" %02X", p[0]);
else
printf(" *");
if (dmi_bcd_range(p[1], 0x01, 0x31))
printf("-%02X", p[1]);
else
printf("-*");
if (dmi_bcd_range(p[2], 0x00, 0x23))
printf(" %02X", p[2]);
else
printf(" *");
if (dmi_bcd_range(p[3], 0x00, 0x59))
printf(":%02X", p[3]);
else
printf(":*");
if (dmi_bcd_range(p[4], 0x00, 0x59))
printf(":%02X", p[4]);
else
printf(":*");
}
/*
* 3.3.27 Voltage Probe (Type 26)
*/
static const char *dmi_voltage_probe_location(u8 code)
{
/* 3.3.27.1 */
static const char *location[] = {
"Other", /* 0x01 */
"Unknown",
"Processor",
"Disk",
"Peripheral Bay",
"System Management Module",
"Motherboard",
"Memory Module",
"Processor Module",
"Power Unit",
"Add-in Card" /* 0x0B */
};
if (code >= 0x01 && code <= 0x0B)
return location[code - 0x01];
return out_of_spec;
}
static const char *dmi_probe_status(u8 code)
{
/* 3.3.27.1 */
static const char *status[] = {
"Other", /* 0x01 */
"Unknown",
"OK",
"Non-critical",
"Critical",
"Non-recoverable" /* 0x06 */
};
if (code >= 0x01 && code <= 0x06)
return status[code - 0x01];
return out_of_spec;
}
static void dmi_voltage_probe_value(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.3f V", (float)(i16)code / 1000);
}
static void dmi_voltage_probe_resolution(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.1f mV", (float)code / 10);
}
static void dmi_probe_accuracy(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.2f%%", (float)code / 100);
}
/*
* 3.3.28 Cooling Device (Type 27)
*/
static const char *dmi_cooling_device_type(u8 code)
{
/* 3.3.28.1 */
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"Fan",
"Centrifugal Blower",
"Chip Fan",
"Cabinet Fan",
"Power Supply Fan",
"Heat Pipe",
"Integrated Refrigeration" /* 0x09 */
};
static const char *type_0x10[] = {
"Active Cooling", /* 0x10 */
"Passive Cooling" /* 0x11 */
};
if (code >= 0x01 && code <= 0x09)
return type[code - 0x01];
if (code >= 0x10 && code <= 0x11)
return type_0x10[code - 0x10];
return out_of_spec;
}
static void dmi_cooling_device_speed(u16 code)
{
if (code == 0x8000)
printf(" Unknown Or Non-rotating");
else
printf(" %u rpm", code);
}
/*
* 3.3.29 Temperature Probe (Type 28)
*/
static const char *dmi_temperature_probe_location(u8 code)
{
/* 3.3.29.1 */
static const char *location[] = {
"Other", /* 0x01 */
"Unknown",
"Processor",
"Disk",
"Peripheral Bay",
"System Management Module",
"Motherboard",
"Memory Module",
"Processor Module",
"Power Unit",
"Add-in Card",
"Front Panel Board",
"Back Panel Board",
"Power System Board",
"Drive Back Plane" /* 0x0F */
};
if (code >= 0x01 && code <= 0x0F)
return location[code - 0x01];
return out_of_spec;
}
static void dmi_temperature_probe_value(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.1f deg C", (float)(i16)code / 10);
}
static void dmi_temperature_probe_resolution(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.3f deg C", (float)code / 1000);
}
/*
* 3.3.30 Electrical Current Probe (Type 29)
*/
static void dmi_current_probe_value(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.3f A", (float)(i16)code / 1000);
}
static void dmi_current_probe_resolution(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.1f mA", (float)code / 10);
}
/*
* 3.3.33 System Boot Information (Type 32)
*/
static const char *dmi_system_boot_status(u8 code)
{
static const char *status[] = {
"No errors detected", /* 0 */
"No bootable media",
"Operating system failed to load",
"Firmware-detected hardware failure",
"Operating system-detected hardware failure",
"User-requested boot",
"System security violation",
"Previously-requested image",
"System watchdog timer expired" /* 8 */
};
if (code <= 8)
return status[code];
if (code >= 128 && code <= 191)
return "OEM-specific";
if (code >= 192)
return "Product-specific";
return out_of_spec;
}
/*
* 3.3.34 64-bit Memory Error Information (Type 33)
*/
static void dmi_64bit_memory_error_address(u64 code)
{
if (code.h == 0x80000000 && code.l == 0x00000000)
printf(" Unknown");
else
printf(" 0x%08X%08X", code.h, code.l);
}
/*
* 3.3.35 Management Device (Type 34)
*/
static const char *dmi_management_device_type(u8 code)
{
/* 3.3.35.1 */
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"LM75",
"LM78",
"LM79",
"LM80",
"LM81",
"ADM9240",
"DS1780",
"MAX1617",
"GL518SM",
"W83781D",
"HT82H791" /* 0x0D */
};
if (code >= 0x01 && code <= 0x0D)
return type[code - 0x01];
return out_of_spec;
}
static const char *dmi_management_device_address_type(u8 code)
{
/* 3.3.35.2 */
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"I/O Port",
"Memory",
"SMBus" /* 0x05 */
};
if (code >= 0x01 && code <= 0x05)
return type[code - 0x01];
return out_of_spec;
}
/*
* 3.3.38 Memory Channel (Type 37)
*/
static const char *dmi_memory_channel_type(u8 code)
{
/* 3.3.38.1 */
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"RamBus",
"SyncLink" /* 0x04 */
};
if (code >= 0x01 && code <= 0x04)
return type[code - 0x01];
return out_of_spec;
}
static void dmi_memory_channel_devices(u8 count, const u8 *p, const char *prefix)
{
int i;
for (i = 1; i <= count; i++)
{
printf("%sDevice %u Load: %u\n",
prefix, i, p[3 * i]);
if (!(opt.flags & FLAG_QUIET))
printf("%sDevice %u Handle: 0x%04X\n",
prefix, i, WORD(p + 3 * i + 1));
}
}
/*
* 3.3.39 IPMI Device Information (Type 38)
*/
static const char *dmi_ipmi_interface_type(u8 code)
{
/* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */
static const char *type[] = {
"Unknown", /* 0x00 */
"KCS (Keyboard Control Style)",
"SMIC (Server Management Interface Chip)",
"BT (Block Transfer)",
"SSIF (SMBus System Interface)" /* 0x04 */
};
if (code <= 0x04)
return type[code];
return out_of_spec;
}
static void dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb)
{
if (type == 0x04) /* SSIF */
{
printf("0x%02X (SMBus)", (*p) >> 1);
}
else
{
u64 address = QWORD(p);
printf("0x%08X%08X (%s)", address.h, (address.l & ~1) | lsb,
address.l & 1 ? "I/O" : "Memory-mapped");
}
}
/* code is assumed to be a 2-bit value */
static const char *dmi_ipmi_register_spacing(u8 code)
{
/* IPMI 2.0, appendix C1, table C1-1 */
static const char *spacing[] = {
"Successive Byte Boundaries", /* 0x00 */
"32-bit Boundaries",
"16-byte Boundaries", /* 0x02 */
out_of_spec /* 0x03 */
};
return spacing[code];
}
/*
* 3.3.40 System Power Supply (Type 39)
*/
static void dmi_power_supply_power(u16 code)
{
if (code == 0x8000)
printf(" Unknown");
else
printf(" %.3f W", (float)code / 1000);
}
static const char *dmi_power_supply_type(u8 code)
{
/* 3.3.40.1 */
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"Linear",
"Switching",
"Battery",
"UPS",
"Converter",
"Regulator" /* 0x08 */
};
if (code >= 0x01 && code <= 0x08)
return type[code - 0x01];
return out_of_spec;
}
static const char *dmi_power_supply_status(u8 code)
{
/* 3.3.40.1 */
static const char *status[] = {
"Other", /* 0x01 */
"Unknown",
"OK",
"Non-critical",
"Critical" /* 0x05 */
};
if (code >= 0x01 && code <= 0x05)
return status[code - 0x01];
return out_of_spec;
}
static const char *dmi_power_supply_range_switching(u8 code)
{
/* 3.3.40.1 */
static const char *switching[] = {
"Other", /* 0x01 */
"Unknown",
"Manual",
"Auto-switch",
"Wide Range",
"N/A" /* 0x06 */
};
if (code >= 0x01 && code <= 0x06)
return switching[code - 0x01];
return out_of_spec;
}
/*
* 3.3.41 Additional Information (Type 40)
*
* Proper support of this entry type would require redesigning a large part of
* the code, so I am waiting to see actual implementations of it to decide
* whether it's worth the effort.
*/
static void dmi_additional_info(const struct dmi_header *h, const char *prefix)
{
u8 *p = h->data + 4;
u8 count = *p++;
u8 length;
int i, offset = 5;
for (i = 0; i < count; i++)
{
printf("%sAdditional Information %d\n", prefix, i + 1);
/* Check for short entries */
if (h->length < offset + 1) break;
length = p[0x00];
if (length < 0x05 || h->length < offset + length) break;
printf("%s\tReferenced Handle: 0x%04x\n",
prefix, WORD(p + 0x01));
printf("%s\tReferenced Offset: 0x%02x\n",
prefix, p[0x03]);
printf("%s\tString: %s\n",
prefix, dmi_string(h, p[0x04]));
printf("%s\tValue: ", prefix);
switch (length - 0x05)
{
case 1:
printf("0x%02x", p[0x05]);
break;
case 2:
printf("0x%04x", WORD(p + 0x05));
break;
case 4:
printf("0x%08x", DWORD(p + 0x05));
break;
default:
printf("Unexpected size");
break;
}
printf("\n");
p += length;
offset += length;
}
}
/*
* Main
*/
static void dmi_decode(const struct dmi_header *h, u16 ver)
{
const u8 *data = h->data;
/*
* Note: DMI types 37, 39 and 40 are untested
*/
switch (h->type)
{
case 0: /* 3.3.1 BIOS Information */
printf("BIOS Information\n");
if (h->length < 0x12) break;
printf("\tVendor: %s\n",
dmi_string(h, data[0x04]));
printf("\tVersion: %s\n",
dmi_string(h, data[0x05]));
printf("\tRelease Date: %s\n",
dmi_string(h, data[0x08]));
/*
* On IA-64, the BIOS base address will read 0 because
* there is no BIOS. Skip the base address and the
* runtime size in this case.
*/
if (WORD(data + 0x06) != 0)
{
printf("\tAddress: 0x%04X0\n",
WORD(data + 0x06));
printf("\tRuntime Size:");
dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4);
printf("\n");
}
printf("\tROM Size: %u kB\n",
(data[0x09] + 1) << 6);
printf("\tCharacteristics:\n");
dmi_bios_characteristics(QWORD(data + 0x0A), "\t\t");
if (h->length < 0x13) break;
dmi_bios_characteristics_x1(data[0x12], "\t\t");
if (h->length < 0x14) break;
dmi_bios_characteristics_x2(data[0x13], "\t\t");
if (h->length < 0x18) break;
if (data[0x14] != 0xFF && data[0x15] != 0xFF)
printf("\tBIOS Revision: %u.%u\n",
data[0x14], data[0x15]);
if (data[0x16] != 0xFF && data[0x17] != 0xFF)
printf("\tFirmware Revision: %u.%u\n",
data[0x16], data[0x17]);
break;
case 1: /* 3.3.2 Sy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -