⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmidecode.c

📁 读取bios DMI信息
💻 C
📖 第 1 页 / 共 5 页
字号:
}

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 + -