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

📄 dmidecode.c

📁 读取bios DMI信息
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 3.3.5.2 */
	static struct {
		int value;
		const char *name;
	} family2[] = {
		{ 0x01, "Other" },
		{ 0x02, "Unknown" },
		{ 0x03, "8086" },
		{ 0x04, "80286" },
		{ 0x05, "80386" },
		{ 0x06, "80486" },
		{ 0x07, "8087" },
		{ 0x08, "80287" },
		{ 0x09, "80387" },
		{ 0x0A, "80487" },
		{ 0x0B, "Pentium" },
		{ 0x0C, "Pentium Pro" },
		{ 0x0D, "Pentium II" },
		{ 0x0E, "Pentium MMX" },
		{ 0x0F, "Celeron" },
		{ 0x10, "Pentium II Xeon" },
		{ 0x11, "Pentium III" },
		{ 0x12, "M1" },
		{ 0x13, "M2" },
		{ 0x14, "Celeron M" }, /* From CIM_Processor.Family */
		{ 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */

		{ 0x18, "Duron" },
		{ 0x19, "K5" },
		{ 0x1A, "K6" },
		{ 0x1B, "K6-2" },
		{ 0x1C, "K6-3" },
		{ 0x1D, "Athlon" },
		{ 0x1E, "AMD29000" },
		{ 0x1F, "K6-2+" },
		{ 0x20, "Power PC" },
		{ 0x21, "Power PC 601" },
		{ 0x22, "Power PC 603" },
		{ 0x23, "Power PC 603+" },
		{ 0x24, "Power PC 604" },
		{ 0x25, "Power PC 620" },
		{ 0x26, "Power PC x704" },
		{ 0x27, "Power PC 750" },
		{ 0x28, "Core Duo" }, /* From CIM_Processor.Family */
		{ 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */
		{ 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */
		{ 0x2B, "Atom" }, /* From CIM_Processor.Family */

		{ 0x30, "Alpha" },
		{ 0x31, "Alpha 21064" },
		{ 0x32, "Alpha 21066" },
		{ 0x33, "Alpha 21164" },
		{ 0x34, "Alpha 21164PC" },
		{ 0x35, "Alpha 21164a" },
		{ 0x36, "Alpha 21264" },
		{ 0x37, "Alpha 21364" },

		{ 0x40, "MIPS" },
		{ 0x41, "MIPS R4000" },
		{ 0x42, "MIPS R4200" },
		{ 0x43, "MIPS R4400" },
		{ 0x44, "MIPS R4600" },
		{ 0x45, "MIPS R10000" },

		{ 0x50, "SPARC" },
		{ 0x51, "SuperSPARC" },
		{ 0x52, "MicroSPARC II" },
		{ 0x53, "MicroSPARC IIep" },
		{ 0x54, "UltraSPARC" },
		{ 0x55, "UltraSPARC II" },
		{ 0x56, "UltraSPARC IIi" },
		{ 0x57, "UltraSPARC III" },
		{ 0x58, "UltraSPARC IIIi" },

		{ 0x60, "68040" },
		{ 0x61, "68xxx" },
		{ 0x62, "68000" },
		{ 0x63, "68010" },
		{ 0x64, "68020" },
		{ 0x65, "68030" },

		{ 0x70, "Hobbit" },

		{ 0x78, "Crusoe TM5000" },
		{ 0x79, "Crusoe TM3000" },
		{ 0x7A, "Efficeon TM8000" },

		{ 0x80, "Weitek" },

		{ 0x82, "Itanium" },
		{ 0x83, "Athlon 64" },
		{ 0x84, "Opteron" },
		{ 0x85, "Sempron" },
		{ 0x86, "Turion 64" },
		{ 0x87, "Dual-Core Opteron" },
		{ 0x88, "Athlon 64 X2" },
		{ 0x89, "Turion 64 X2" },
		{ 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */
		{ 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */
		{ 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */
		{ 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */
		{ 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */
		{ 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */
		{ 0x90, "PA-RISC" },
		{ 0x91, "PA-RISC 8500" },
		{ 0x92, "PA-RISC 8000" },
		{ 0x93, "PA-RISC 7300LC" },
		{ 0x94, "PA-RISC 7200" },
		{ 0x95, "PA-RISC 7100LC" },
		{ 0x96, "PA-RISC 7100" },

		{ 0xA0, "V30" },
		{ 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */
		{ 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */
		{ 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */
		{ 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */
		{ 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */
		{ 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */
		{ 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */
		{ 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */
		{ 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */
		{ 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */

		{ 0xB0, "Pentium III Xeon" },
		{ 0xB1, "Pentium III Speedstep" },
		{ 0xB2, "Pentium 4" },
		{ 0xB3, "Xeon" },
		{ 0xB4, "AS400" },
		{ 0xB5, "Xeon MP" },
		{ 0xB6, "Athlon XP" },
		{ 0xB7, "Athlon MP" },
		{ 0xB8, "Itanium 2" },
		{ 0xB9, "Pentium M" },
		{ 0xBA, "Celeron D" },
		{ 0xBB, "Pentium D" },
		{ 0xBC, "Pentium EE" },
		{ 0xBD, "Core Solo" },
		/* 0xBE handled as a special case */
		{ 0xBF, "Core 2 Duo" },
		{ 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */
		{ 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */
		{ 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */
		{ 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */
		{ 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */
		{ 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */

		{ 0xC8, "IBM390" },
		{ 0xC9, "G4" },
		{ 0xCA, "G5" },
		{ 0xCB, "ESA/390 G6" },
		{ 0xCC, "z/Architectur" },

		{ 0xD2, "C7-M" },
		{ 0xD3, "C7-D" },
		{ 0xD4, "C7" },
		{ 0xD5, "Eden" },

		{ 0xE6, "Embedded Opteron Quad-Core" }, /* From CIM_Processor.Family */
		{ 0xE7, "Phenom Triple-Core" }, /* From CIM_Processor.Family */
		{ 0xE8, "Turion Ultra Dual-Core Mobile" }, /* From CIM_Processor.Family */
		{ 0xE9, "Turion Dual-Core Mobile" }, /* From CIM_Processor.Family */
		{ 0xEA, "Athlon Dual-Core" }, /* From CIM_Processor.Family */
		{ 0xEB, "Sempron SI" }, /* From CIM_Processor.Family */

		{ 0xFA, "i860" },
		{ 0xFB, "i960" },

		{ 0x104, "SH-3" },
		{ 0x105, "SH-4" },
		{ 0x118, "ARM" },
		{ 0x119, "StrongARM" },
		{ 0x12C, "6x86" },
		{ 0x12D, "MediaGX" },
		{ 0x12E, "MII" },
		{ 0x140, "WinChip" },
		{ 0x15E, "DSP" },
		{ 0x1F4, "Video Processor" },
	};

	code = (data[0x06] == 0xFE && h->length >= 0x2A) ?
		WORD(data + 0x28) : data[0x06];

	/* Special case for ambiguous value 0xBE */
	if (code == 0xBE)
	{
		const char *manufacturer = dmi_string(h, data[0x07]);

		/* Best bet based on manufacturer string */
		if (strstr(manufacturer, "Intel") != NULL
		 || strncasecmp(manufacturer, "Intel", 5) == 0)
			return "Core 2";
		if (strstr(manufacturer, "AMD") != NULL
		 || strncasecmp(manufacturer, "AMD", 3) == 0)
			return "K7";
		return "Core 2 or K7";
	}

	/* Perform a binary search */
	low = 0;
	high = ARRAY_SIZE(family2) - 1;

	while (1)
	{
		i = (low + high) / 2;
		if (family2[i].value == code)
			return family2[i].name;
		if (low == high) /* Not found */
			return out_of_spec;

		if (code < family2[i].value)
			high = i;
		else
			low = i + 1;
	}
}

static void dmi_processor_id(u8 type, const u8 *p, const char *version, const char *prefix)
{
	/* Intel AP-485 revision 32, table 3-4 */
	static const char *flags[32] = {
		"FPU (Floating-point unit on-chip)", /* 0 */
		"VME (Virtual mode extension)",
		"DE (Debugging extension)",
		"PSE (Page size extension)",
		"TSC (Time stamp counter)",
		"MSR (Model specific registers)",
		"PAE (Physical address extension)",
		"MCE (Machine check exception)",
		"CX8 (CMPXCHG8 instruction supported)",
		"APIC (On-chip APIC hardware supported)",
		NULL, /* 10 */
		"SEP (Fast system call)",
		"MTRR (Memory type range registers)",
		"PGE (Page global enable)",
		"MCA (Machine check architecture)",
		"CMOV (Conditional move instruction supported)",
		"PAT (Page attribute table)",
		"PSE-36 (36-bit page size extension)",
		"PSN (Processor serial number present and enabled)",
		"CLFSH (CLFLUSH instruction supported)",
		NULL, /* 20 */
		"DS (Debug store)",
		"ACPI (ACPI supported)",
		"MMX (MMX technology supported)",
		"FXSR (Fast floating-point save and restore)",
		"SSE (Streaming SIMD extensions)",
		"SSE2 (Streaming SIMD extensions 2)",
		"SS (Self-snoop)",
		"HTT (Hyper-threading technology)",
		"TM (Thermal monitor supported)",
		"IA64 (IA64 capabilities)",
		"PBE (Pending break enabled)" /* 31 */
	};
	/*
	 * Extra flags are now returned in the ECX register when one calls
	 * the CPUID instruction. Their meaning is explained in table 3-5, but
	 * DMI doesn't support this yet.
	 */
	u32 eax, edx;
	int sig = 0;

	/*
	 * This might help learn about new processors supporting the
	 * CPUID instruction or another form of identification.
	 */
	printf("%sID: %02X %02X %02X %02X %02X %02X %02X %02X\n",
		prefix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);

	if (type == 0x05) /* 80386 */
	{
		u16 dx = WORD(p);
		/*
		 * 80386 have a different signature.
		 */
		printf("%sSignature: Type %u, Family %u, Major Stepping %u, Minor Stepping %u\n",
			prefix, dx >> 12, (dx >> 8) & 0xF,
			(dx >> 4) & 0xF, dx & 0xF);
		return;
	}
	if (type == 0x06) /* 80486 */
	{
		u16 dx = WORD(p);
		/*
		 * Not all 80486 CPU support the CPUID instruction, we have to find
		 * wether the one we have here does or not. Note that this trick
		 * works only because we know that 80486 must be little-endian.
		 */
		if ((dx & 0x0F00) == 0x0400
		 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
		 && ((dx & 0x000F) >= 0x0003))
			sig = 1;
		else
		{
			printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n",
				prefix, (dx >> 12) & 0x3, (dx >> 8) & 0xF,
				(dx >> 4) & 0xF, dx & 0xF);
			return;
		}
	}
	else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
	      || (type >= 0x28 && type <= 0x2B) /* Intel */
	      || (type >= 0xA1 && type <= 0xAA) /* Intel */
	      || (type >= 0xB0 && type <= 0xB3) /* Intel */
	      || type == 0xB5 /* Intel */
	      || (type >= 0xB9 && type <= 0xC5) /* Intel */
	      || (type >= 0xD2 && type <= 0xD5)) /* VIA */
		sig = 1;
	else if ((type >= 0x18 && type <= 0x1D) /* AMD */
	      || type == 0x1F /* AMD */
	      || (type >= 0x83 && type <= 0x8F) /* AMD */
	      || (type >= 0xB6 && type <= 0xB7) /* AMD */
	      || (type >= 0xE6 && type <= 0xEB)) /* AMD */
		sig = 2;
	else if (type == 0x01 || type == 0x02)
	{
		/*
		 * Some X86-class CPU have family "Other" or "Unknown". In this case,
		 * we use the version string to determine if they are known to
		 * support the CPUID instruction.
		 */
		if (strncmp(version, "Pentium III MMX", 15) == 0
		 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
		 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
		 || strcmp(version, "Genuine Intel(R) CPU U1400") == 0)
			sig = 1;
		else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
		      || strncmp(version, "AMD Opteron(tm)", 15) == 0
		      || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0)
			sig = 2;
		else
			return;
	}
	else /* not X86-class */
		return;

	eax = DWORD(p);
	edx = DWORD(p + 4);
	switch (sig)
	{
		case 1: /* Intel */
			printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n",
				prefix, (eax >> 12) & 0x3,
				((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F),
				((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F),
				eax & 0xF);
			break;
		case 2: /* AMD, publication #25481 revision 2.28 */
			printf("%sSignature: Family %u, Model %u, Stepping %u\n",
				prefix,
				((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0),
				((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0),
				eax&0xF);
			break;
	}

	edx = DWORD(p + 4);
	printf("%sFlags:", prefix);
	if ((edx & 0xFFEFFBFF) == 0)
		printf(" None\n");
	else
	{
		int i;

		printf("\n");
		for (i = 0; i <= 31; i++)
			if (flags[i] != NULL && edx & (1 << i))
				printf("%s\t%s\n", prefix, flags[i]);
	}
}

static void dmi_processor_voltage(u8 code)
{
	/* 3.3.5.4 */
	static const char *voltage[] = {
		"5.0 V", /* 0 */
		"3.3 V",
		"2.9 V" /* 2 */
	};
	int i;

	if (code & 0x80)
		printf(" %.1f V", (float)(code & 0x7f) / 10);
	else
	{
		for (i = 0; i <= 2; i++)
			if (code & (1 << i))
				printf(" %s", voltage[i]);
		if (code == 0x00)
			printf(" Unknown");
	}
}

static void dmi_processor_frequency(const u8 *p)
{
	u16 code = WORD(p);

	if (code)
		printf("%u MHz", code);
	else
		printf("Unknown");
}

/* code is assumed to be a 3-bit value */
static const char *dmi_processor_status(u8 code)
{
	static const char *status[] = {
		"Unknown", /* 0x00 */
		"Enabled",
		"Disabled By User",
		"Disabled By BIOS",
		"Idle", /* 0x04 */
		out_of_spec,
		out_of_spec,
		"Other" /* 0x07 */
	};

	return status[code];
}

static const char *dmi_processor_upgrade(u8 code)
{
	/* 3.3.5.5 */
	static const char *upgrade[] = {
		"Other", /* 0x01 */
		"Unknown",
		"Daughter Board",
		"ZIF Socket",
		"Replaceable Piggy Back",
		"None",
		"LIF Socket",
		"Slot 1",
		"Slot 2",
		"370-pin Socket",
		"Slot A",
		"Slot M",
		"Socket 423",
		"Socket A (Socket 462)",
		"Socket 478",
		"Socket 754",
		"Socket 940",
		"Socket 939",
		"Socket mPGA604",
		"Socket LGA771",
		"Socket LGA775",
		"Socket S1",
		"Socket AM2",
		"Socket F (1207)" /* 0x18 */
	};

	if (code >= 0x01 && code <= 0x18)
		return upgrade[code - 0x01];
	return out_of_spec;
}

static void dmi_processor_cache(u16 code, const char *level, u16 ver)
{
	if (code == 0xFFFF)
	{
		if (ver >= 0x0203)
			printf(" Not Provided");
		else
			printf(" No %s Cache", level);
	}
	else
		printf(" 0x%04X", code);
}

static void dmi_processor_characteristics(u16 code, const char *prefix)
{
	/* 3.3.5.9 */
	static const char *characteristics[] = {
		"64-bit capable" /* 2 */
	};

	if ((code & 0x0004) == 0)
		printf(" None\n");
	else
	{
		int i;

		printf("\n");
		for (i = 2; i <= 2; i++)
			if (code & (1 << i))
				printf("%s%s\n", prefix, characteristics[i - 2]);
	}
}

/*
 * 3.3.6 Memory Controller Information (Type 5)
 */

static const char *dmi_memory_controller_ed_method(u8 code)
{
	/* 3.3.6.1 */
	static const char *method[] = {
		"Other", /* 0x01 */
		"Unknown",
		"None",
		"8-bit Parity",
		"32-bit ECC",
		"64-bit ECC",
		"128-bit ECC",
		"CRC" /* 0x08 */
	};

	if (code >= 0x01 && code <= 0x08)
		return method[code - 0x01];
	return out_of_spec;
}

static void dmi_memory_controller_ec_capabilities(u8 code, const char *prefix)
{
	/* 3.3.6.2 */
	static const char *capabilities[] = {
		"Other", /* 0 */
		"Unknown",
		"None",
		"Single-bit Error Correcting",
		"Double-bit Error Correcting",
		"Error Scrubbing" /* 5 */
	};

	if ((code & 0x3F) == 0)
		printf(" None\n");
	else
	{
		int i;

		printf("\n");
		for (i = 0; i <= 5; i++)
			if (code & (1 << i))
				printf("%s%s\n", prefix, capabilities[i]);
	}
}

static const char *dmi_memory_controller_interleave(u8 code)
{
	/* 3.3.6.3 */
	static const char *interleave[] = {
		"Other", /* 0x01 */
		"Unknown",
		"One-way Interleave",
		"Two-way Interleave",
		"Four-way Interleave",
		"Eight-way Interleave",
		"Sixteen-way Interleave" /* 0x07 */
	};

	if (code >= 0x01 && code <= 0x07)
		return interleave[code - 0x01];
	return out_of_spec;
}

static void dmi_memory_controller_speeds(u16 code, const char *prefix)
{
	/* 3.3.6.4 */
	const char *speeds[] = {
		"Other", /* 0 */
		"Unknown",
		"70 ns",
		"60 ns",
		"50 ns" /* 4 */
	};

	if ((code & 0x001F) == 0)
		printf(" None\n");
	else
	{
		int i;

		printf("\n");
		for (i = 0; i <= 4; i++)
			if (code & (1 << i))
				printf("%s%s\n", prefix, speeds[i]);
	}
}

static void dmi_memory_controller_slots(u8 count, const u8 *p, const char *prefix)
{
	int i;

	printf("%sAssociated Memory Slots: %u\n",
		prefix, count);
	for (i = 0; i < count; i++)
		printf("%s\t0x%04X\n",
			prefix, WORD(p + sizeof(u16) * i));
}

/*
 * 3.3.7 Memory Module Information (Type 6)
 */

static void dmi_memory_module_types(u16 code, const char *sep)
{
	/* 3.3.7.1 */
	static const char *types[] = {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -