Blame dmidecode.c

Packit Service e18529
/*
Packit Service e18529
 * DMI Decode
Packit Service e18529
 *
Packit Service e18529
 *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
Packit Service 685f37
 *   Copyright (C) 2002-2019 Jean Delvare <jdelvare@suse.de>
Packit Service e18529
 *
Packit Service e18529
 *   This program is free software; you can redistribute it and/or modify
Packit Service e18529
 *   it under the terms of the GNU General Public License as published by
Packit Service e18529
 *   the Free Software Foundation; either version 2 of the License, or
Packit Service e18529
 *   (at your option) any later version.
Packit Service e18529
 *
Packit Service e18529
 *   This program is distributed in the hope that it will be useful,
Packit Service e18529
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service e18529
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service e18529
 *   GNU General Public License for more details.
Packit Service e18529
 *
Packit Service e18529
 *   You should have received a copy of the GNU General Public License
Packit Service e18529
 *   along with this program; if not, write to the Free Software
Packit Service e18529
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
Packit Service e18529
 *
Packit Service e18529
 *   For the avoidance of doubt the "preferred form" of this code is one which
Packit Service e18529
 *   is in an open unpatent encumbered format. Where cryptographic key signing
Packit Service e18529
 *   forms part of the process of creating an executable the information
Packit Service e18529
 *   including keys needed to generate an equivalently functional executable
Packit Service e18529
 *   are deemed to be part of the source code.
Packit Service e18529
 *
Packit Service e18529
 * Unless specified otherwise, all references are aimed at the "System
Packit Service e18529
 * Management BIOS Reference Specification, Version 3.2.0" document,
Packit Service e18529
 * available from http://www.dmtf.org/standards/smbios.
Packit Service e18529
 *
Packit Service e18529
 * Note to contributors:
Packit Service e18529
 * Please reference every value you add or modify, especially if the
Packit Service e18529
 * information does not come from the above mentioned specification.
Packit Service e18529
 *
Packit Service e18529
 * Additional references:
Packit Service e18529
 *  - Intel AP-485 revision 36
Packit Service e18529
 *    "Intel Processor Identification and the CPUID Instruction"
Packit Service e18529
 *    http://www.intel.com/support/processors/sb/cs-009861.htm
Packit Service e18529
 *  - DMTF Common Information Model
Packit Service e18529
 *    CIM Schema version 2.19.1
Packit Service e18529
 *    http://www.dmtf.org/standards/cim/
Packit Service e18529
 *  - IPMI 2.0 revision 1.0
Packit Service e18529
 *    "Intelligent Platform Management Interface Specification"
Packit Service e18529
 *    http://developer.intel.com/design/servers/ipmi/spec.htm
Packit Service e18529
 *  - AMD publication #25481 revision 2.28
Packit Service e18529
 *    "CPUID Specification"
Packit Service e18529
 *    http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
Packit Service e18529
 *  - BIOS Integrity Services Application Programming Interface version 1.0
Packit Service e18529
 *    http://www.intel.com/design/archives/wfm/downloads/bisspec.htm
Packit Service e18529
 *  - DMTF DSP0239 version 1.1.0
Packit Service e18529
 *    "Management Component Transport Protocol (MCTP) IDs and Codes"
Packit Service e18529
 *    http://www.dmtf.org/standards/pmci
Packit Service e18529
 *  - "TPM Main, Part 2 TPM Structures"
Packit Service e18529
 *    Specification version 1.2, level 2, revision 116
Packit Service e18529
 *    https://trustedcomputinggroup.org/tpm-main-specification/
Packit Service e18529
 *  - "PC Client Platform TPM Profile (PTP) Specification"
Packit Service e18529
 *    Family "2.0", Level 00, Revision 00.43, January 26, 2015
Packit Service e18529
 *    https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/
Packit Service e18529
 *  - "RedFish Host Interface Specification" (DMTF DSP0270)
Packit Service e18529
 *    https://www.dmtf.org/sites/default/files/DSP0270_1.0.1.pdf
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
#include <stdio.h>
Packit Service e18529
#include <string.h>
Packit Service e18529
#include <strings.h>
Packit Service e18529
#include <stdlib.h>
Packit Service e18529
#include <unistd.h>
Packit Service e18529
#include <arpa/inet.h>
Packit Service d0f696
#include <sys/socket.h>
Packit Service e18529
Packit Service e18529
#ifdef __FreeBSD__
Packit Service e18529
#include <errno.h>
Packit Service e18529
#include <kenv.h>
Packit Service e18529
#endif
Packit Service e18529
Packit Service e18529
#include "version.h"
Packit Service e18529
#include "config.h"
Packit Service e18529
#include "types.h"
Packit Service e18529
#include "util.h"
Packit Service e18529
#include "dmidecode.h"
Packit Service e18529
#include "dmiopt.h"
Packit Service e18529
#include "dmioem.h"
Packit Service e18529
Packit Service e18529
#define out_of_spec "<OUT OF SPEC>"
Packit Service e18529
static const char *bad_index = "<BAD INDEX>";
Packit Service e18529
Packit Service e18529
#define SUPPORTED_SMBIOS_VER 0x030200
Packit Service e18529
Packit Service e18529
#define FLAG_NO_FILE_OFFSET     (1 << 0)
Packit Service e18529
#define FLAG_STOP_AT_EOT        (1 << 1)
Packit Service e18529
Packit Service e18529
#define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables"
Packit Service e18529
#define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point"
Packit Service e18529
#define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI"
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * Type-independant Stuff
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
/* Returns 1 if the buffer contains only printable ASCII characters */
Packit Service e18529
int is_printable(const u8 *data, int len)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < len; i++)
Packit Service e18529
		if (data[i] < 32 || data[i] >= 127)
Packit Service e18529
			return 0;
Packit Service e18529
Packit Service e18529
	return 1;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
const char *dmi_string(const struct dmi_header *dm, u8 s)
Packit Service e18529
{
Packit Service e18529
	char *bp = (char *)dm->data;
Packit Service e18529
	size_t i, len;
Packit Service e18529
Packit Service e18529
	if (s == 0)
Packit Service e18529
		return "Not Specified";
Packit Service e18529
Packit Service e18529
	bp += dm->length;
Packit Service e18529
	while (s > 1 && *bp)
Packit Service e18529
	{
Packit Service e18529
		bp += strlen(bp);
Packit Service e18529
		bp++;
Packit Service e18529
		s--;
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	if (!*bp)
Packit Service e18529
		return bad_index;
Packit Service e18529
Packit Service e18529
	if (!(opt.flags & FLAG_DUMP))
Packit Service e18529
	{
Packit Service e18529
		/* ASCII filtering */
Packit Service e18529
		len = strlen(bp);
Packit Service e18529
		for (i = 0; i < len; i++)
Packit Service e18529
			if (bp[i] < 32 || bp[i] == 127)
Packit Service e18529
				bp[i] = '.';
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	return bp;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_smbios_structure_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"BIOS", /* 0 */
Packit Service e18529
		"System",
Packit Service e18529
		"Base Board",
Packit Service e18529
		"Chassis",
Packit Service e18529
		"Processor",
Packit Service e18529
		"Memory Controller",
Packit Service e18529
		"Memory Module",
Packit Service e18529
		"Cache",
Packit Service e18529
		"Port Connector",
Packit Service e18529
		"System Slots",
Packit Service e18529
		"On Board Devices",
Packit Service e18529
		"OEM Strings",
Packit Service e18529
		"System Configuration Options",
Packit Service e18529
		"BIOS Language",
Packit Service e18529
		"Group Associations",
Packit Service e18529
		"System Event Log",
Packit Service e18529
		"Physical Memory Array",
Packit Service e18529
		"Memory Device",
Packit Service e18529
		"32-bit Memory Error",
Packit Service e18529
		"Memory Array Mapped Address",
Packit Service e18529
		"Memory Device Mapped Address",
Packit Service e18529
		"Built-in Pointing Device",
Packit Service e18529
		"Portable Battery",
Packit Service e18529
		"System Reset",
Packit Service e18529
		"Hardware Security",
Packit Service e18529
		"System Power Controls",
Packit Service e18529
		"Voltage Probe",
Packit Service e18529
		"Cooling Device",
Packit Service e18529
		"Temperature Probe",
Packit Service e18529
		"Electrical Current Probe",
Packit Service e18529
		"Out-of-band Remote Access",
Packit Service e18529
		"Boot Integrity Services",
Packit Service e18529
		"System Boot",
Packit Service e18529
		"64-bit Memory Error",
Packit Service e18529
		"Management Device",
Packit Service e18529
		"Management Device Component",
Packit Service e18529
		"Management Device Threshold Data",
Packit Service e18529
		"Memory Channel",
Packit Service e18529
		"IPMI Device",
Packit Service e18529
		"Power Supply",
Packit Service e18529
		"Additional Information",
Packit Service e18529
		"Onboard Device",
Packit Service e18529
		"Management Controller Host Interface",
Packit Service e18529
		"TPM Device", /* 43 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 128)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	if (code <= 43)
Packit Service e18529
		return type[code];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static int dmi_bcd_range(u8 value, u8 low, u8 high)
Packit Service e18529
{
Packit Service e18529
	if (value > 0x99 || (value & 0x0F) > 0x09)
Packit Service e18529
		return 0;
Packit Service e18529
	if (value < low || value > high)
Packit Service e18529
		return 0;
Packit Service e18529
	return 1;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_dump(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int row, i;
Packit Service e18529
	const char *s;
Packit Service e18529
Packit Service e18529
	printf("%sHeader and Data:\n", prefix);
Packit Service e18529
	for (row = 0; row < ((h->length - 1) >> 4) + 1; row++)
Packit Service e18529
	{
Packit Service e18529
		printf("%s\t", prefix);
Packit Service e18529
		for (i = 0; i < 16 && i < h->length - (row << 4); i++)
Packit Service e18529
			printf("%s%02X", i ? " " : "",
Packit Service e18529
			       (h->data)[(row << 4) + i]);
Packit Service e18529
		printf("\n");
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	if ((h->data)[h->length] || (h->data)[h->length + 1])
Packit Service e18529
	{
Packit Service e18529
		printf("%sStrings:\n", prefix);
Packit Service e18529
		i = 1;
Packit Service e18529
		while ((s = dmi_string(h, i++)) != bad_index)
Packit Service e18529
		{
Packit Service e18529
			if (opt.flags & FLAG_DUMP)
Packit Service e18529
			{
Packit Service e18529
				int j, l = strlen(s) + 1;
Packit Service e18529
				for (row = 0; row < ((l - 1) >> 4) + 1; row++)
Packit Service e18529
				{
Packit Service e18529
					printf("%s\t", prefix);
Packit Service e18529
					for (j = 0; j < 16 && j < l - (row << 4); j++)
Packit Service e18529
						printf("%s%02X", j ? " " : "",
Packit Service e18529
						       (unsigned char)s[(row << 4) + j]);
Packit Service e18529
					printf("\n");
Packit Service e18529
				}
Packit Service e18529
				/* String isn't filtered yet so do it now */
Packit Service e18529
				printf("%s\t\"", prefix);
Packit Service e18529
				while (*s)
Packit Service e18529
				{
Packit Service e18529
					if (*s < 32 || *s == 127)
Packit Service e18529
						fputc('.', stdout);
Packit Service e18529
					else
Packit Service e18529
						fputc(*s, stdout);
Packit Service e18529
					s++;
Packit Service e18529
				}
Packit Service e18529
				printf("\"\n");
Packit Service e18529
			}
Packit Service e18529
			else
Packit Service e18529
				printf("%s\t%s\n", prefix, s);
Packit Service e18529
		}
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/* shift is 0 if the value is in bytes, 1 if it is in kilobytes */
Packit Service e18529
static void dmi_print_memory_size(u64 code, int shift)
Packit Service e18529
{
Packit Service e18529
	unsigned long capacity;
Packit Service e18529
	u16 split[7];
Packit Service e18529
	static const char *unit[8] = {
Packit Service e18529
		"bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"
Packit Service e18529
	};
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * We split the overall size in powers of thousand: EB, PB, TB, GB,
Packit Service e18529
	 * MB, kB and B. In practice, it is expected that only one or two
Packit Service e18529
	 * (consecutive) of these will be non-zero.
Packit Service e18529
	 */
Packit Service e18529
	split[0] = code.l & 0x3FFUL;
Packit Service e18529
	split[1] = (code.l >> 10) & 0x3FFUL;
Packit Service e18529
	split[2] = (code.l >> 20) & 0x3FFUL;
Packit Service e18529
	split[3] = ((code.h << 2) & 0x3FCUL) | (code.l >> 30);
Packit Service e18529
	split[4] = (code.h >> 8) & 0x3FFUL;
Packit Service e18529
	split[5] = (code.h >> 18) & 0x3FFUL;
Packit Service e18529
	split[6] = code.h >> 28;
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * Now we find the highest unit with a non-zero value. If the following
Packit Service e18529
	 * is also non-zero, we use that as our base. If the following is zero,
Packit Service e18529
	 * we simply display the highest unit.
Packit Service e18529
	 */
Packit Service e18529
	for (i = 6; i > 0; i--)
Packit Service e18529
	{
Packit Service e18529
		if (split[i])
Packit Service e18529
			break;
Packit Service e18529
	}
Packit Service e18529
	if (i > 0 && split[i - 1])
Packit Service e18529
	{
Packit Service e18529
		i--;
Packit Service e18529
		capacity = split[i] + (split[i + 1] << 10);
Packit Service e18529
	}
Packit Service e18529
	else
Packit Service e18529
		capacity = split[i];
Packit Service e18529
Packit Service e18529
	printf(" %lu %s", capacity, unit[i + shift]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.1 BIOS Information (Type 0)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_bios_runtime_size(u32 code)
Packit Service e18529
{
Packit Service e18529
	if (code & 0x000003FF)
Packit Service e18529
		printf(" %u bytes", code);
Packit Service e18529
	else
Packit Service e18529
		printf(" %u kB", code >> 10);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_bios_rom_size(u8 code1, u16 code2)
Packit Service e18529
{
Packit Service e18529
	static const char *unit[4] = {
Packit Service e18529
		"MB", "GB", out_of_spec, out_of_spec
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code1 != 0xFF)
Packit Service 3dd3ee
	{
Packit Service 3dd3ee
		u64 s = { .l = (code1 + 1) << 6 };
Packit Service 3dd3ee
		dmi_print_memory_size(s, 1);
Packit Service 3dd3ee
	}
Packit Service e18529
	else
Packit Service e18529
		printf(" %u %s", code2 & 0x3FFF, unit[code2 >> 14]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_bios_characteristics(u64 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.1.1 */
Packit Service e18529
	static const char *characteristics[] = {
Packit Service e18529
		"BIOS characteristics not supported", /* 3 */
Packit Service e18529
		"ISA is supported",
Packit Service e18529
		"MCA is supported",
Packit Service e18529
		"EISA is supported",
Packit Service e18529
		"PCI is supported",
Packit Service e18529
		"PC Card (PCMCIA) is supported",
Packit Service e18529
		"PNP is supported",
Packit Service e18529
		"APM is supported",
Packit Service e18529
		"BIOS is upgradeable",
Packit Service e18529
		"BIOS shadowing is allowed",
Packit Service e18529
		"VLB is supported",
Packit Service e18529
		"ESCD support is available",
Packit Service e18529
		"Boot from CD is supported",
Packit Service e18529
		"Selectable boot is supported",
Packit Service e18529
		"BIOS ROM is socketed",
Packit Service e18529
		"Boot from PC Card (PCMCIA) is supported",
Packit Service e18529
		"EDD is supported",
Packit Service e18529
		"Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
Packit Service e18529
		"Japanese floppy for Toshiba 1.2 MB is supported (int 13h)",
Packit Service e18529
		"5.25\"/360 kB floppy services are supported (int 13h)",
Packit Service e18529
		"5.25\"/1.2 MB floppy services are supported (int 13h)",
Packit Service e18529
		"3.5\"/720 kB floppy services are supported (int 13h)",
Packit Service e18529
		"3.5\"/2.88 MB floppy services are supported (int 13h)",
Packit Service e18529
		"Print screen service is supported (int 5h)",
Packit Service e18529
		"8042 keyboard services are supported (int 9h)",
Packit Service e18529
		"Serial services are supported (int 14h)",
Packit Service e18529
		"Printer services are supported (int 17h)",
Packit Service e18529
		"CGA/mono video services are supported (int 10h)",
Packit Service e18529
		"NEC PC-98" /* 31 */
Packit Service e18529
	};
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * This isn't very clear what this bit is supposed to mean
Packit Service e18529
	 */
Packit Service e18529
	if (code.l & (1 << 3))
Packit Service e18529
	{
Packit Service e18529
		printf("%s%s\n",
Packit Service e18529
			prefix, characteristics[0]);
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	for (i = 4; i <= 31; i++)
Packit Service e18529
		if (code.l & (1 << i))
Packit Service e18529
			printf("%s%s\n",
Packit Service e18529
				prefix, characteristics[i - 3]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_bios_characteristics_x1(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.1.2.1 */
Packit Service e18529
	static const char *characteristics[] = {
Packit Service e18529
		"ACPI is supported", /* 0 */
Packit Service e18529
		"USB legacy is supported",
Packit Service e18529
		"AGP is supported",
Packit Service e18529
		"I2O boot is supported",
Packit Service e18529
		"LS-120 boot is supported",
Packit Service e18529
		"ATAPI Zip drive boot is supported",
Packit Service e18529
		"IEEE 1394 boot is supported",
Packit Service e18529
		"Smart battery is supported" /* 7 */
Packit Service e18529
	};
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i <= 7; i++)
Packit Service e18529
		if (code & (1 << i))
Packit Service e18529
			printf("%s%s\n",
Packit Service e18529
				prefix, characteristics[i]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_bios_characteristics_x2(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 37.1.2.2 */
Packit Service e18529
	static const char *characteristics[] = {
Packit Service e18529
		"BIOS boot specification is supported", /* 0 */
Packit Service e18529
		"Function key-initiated network boot is supported",
Packit Service e18529
		"Targeted content distribution is supported",
Packit Service e18529
		"UEFI is supported",
Packit Service e18529
		"System is a virtual machine" /* 4 */
Packit Service e18529
	};
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i <= 4; i++)
Packit Service e18529
		if (code & (1 << i))
Packit Service e18529
			printf("%s%s\n",
Packit Service e18529
				prefix, characteristics[i]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.2 System Information (Type 1)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_system_uuid(const u8 *p, u16 ver)
Packit Service e18529
{
Packit Service e18529
	int only0xFF = 1, only0x00 = 1;
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < 16 && (only0x00 || only0xFF); i++)
Packit Service e18529
	{
Packit Service e18529
		if (p[i] != 0x00) only0x00 = 0;
Packit Service e18529
		if (p[i] != 0xFF) only0xFF = 0;
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	if (only0xFF)
Packit Service e18529
	{
Packit Service e18529
		printf("Not Present");
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
	if (only0x00)
Packit Service e18529
	{
Packit Service e18529
		printf("Not Settable");
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * As of version 2.6 of the SMBIOS specification, the first 3
Packit Service e18529
	 * fields of the UUID are supposed to be encoded on little-endian.
Packit Service e18529
	 * The specification says that this is the defacto standard,
Packit Service e18529
	 * however I've seen systems following RFC 4122 instead and use
Packit Service e18529
	 * network byte order, so I am reluctant to apply the byte-swapping
Packit Service e18529
	 * for older versions.
Packit Service e18529
	 */
Packit Service e18529
	if (ver >= 0x0206)
Packit Service e18529
		printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Packit Service e18529
			p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
Packit Service e18529
			p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Service e18529
	else
Packit Service e18529
		printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Packit Service e18529
			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
Packit Service e18529
			p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_system_wake_up_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.2.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Reserved", /* 0x00 */
Packit Service e18529
		"Other",
Packit Service e18529
		"Unknown",
Packit Service e18529
		"APM Timer",
Packit Service e18529
		"Modem Ring",
Packit Service e18529
		"LAN Remote",
Packit Service e18529
		"Power Switch",
Packit Service e18529
		"PCI PME#",
Packit Service e18529
		"AC Power Restored" /* 0x08 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x08)
Packit Service e18529
		return type[code];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.3 Base Board Information (Type 2)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_base_board_features(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.3.1 */
Packit Service e18529
	static const char *features[] = {
Packit Service e18529
		"Board is a hosting board", /* 0 */
Packit Service e18529
		"Board requires at least one daughter board",
Packit Service e18529
		"Board is removable",
Packit Service e18529
		"Board is replaceable",
Packit Service e18529
		"Board is hot swappable" /* 4 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x1F) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 0; i <= 4; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s\n",
Packit Service e18529
					prefix, features[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_base_board_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.3.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Unknown", /* 0x01 */
Packit Service e18529
		"Other",
Packit Service e18529
		"Server Blade",
Packit Service e18529
		"Connectivity Switch",
Packit Service e18529
		"System Management Module",
Packit Service e18529
		"Processor Module",
Packit Service e18529
		"I/O Module",
Packit Service e18529
		"Memory Module",
Packit Service e18529
		"Daughter Board",
Packit Service e18529
		"Motherboard",
Packit Service e18529
		"Processor+Memory Module",
Packit Service e18529
		"Processor+I/O Module",
Packit Service e18529
		"Interconnect Board" /* 0x0D */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0D)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_base_board_handles(u8 count, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	printf("%sContained Object Handles: %u\n",
Packit Service e18529
		prefix, count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
		printf("%s\t0x%04X\n",
Packit Service e18529
			prefix, WORD(p + sizeof(u16) * i));
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.4 Chassis Information (Type 3)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_chassis_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.4.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Desktop",
Packit Service e18529
		"Low Profile Desktop",
Packit Service e18529
		"Pizza Box",
Packit Service e18529
		"Mini Tower",
Packit Service e18529
		"Tower",
Packit Service e18529
		"Portable",
Packit Service e18529
		"Laptop",
Packit Service e18529
		"Notebook",
Packit Service e18529
		"Hand Held",
Packit Service e18529
		"Docking Station",
Packit Service e18529
		"All In One",
Packit Service e18529
		"Sub Notebook",
Packit Service e18529
		"Space-saving",
Packit Service e18529
		"Lunch Box",
Packit Service e18529
		"Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */
Packit Service e18529
		"Expansion Chassis",
Packit Service e18529
		"Sub Chassis",
Packit Service e18529
		"Bus Expansion Chassis",
Packit Service e18529
		"Peripheral Chassis",
Packit Service e18529
		"RAID Chassis",
Packit Service e18529
		"Rack Mount Chassis",
Packit Service e18529
		"Sealed-case PC",
Packit Service e18529
		"Multi-system",
Packit Service e18529
		"CompactPCI",
Packit Service e18529
		"AdvancedTCA",
Packit Service e18529
		"Blade",
Packit Service e18529
		"Blade Enclosing",
Packit Service e18529
		"Tablet",
Packit Service e18529
		"Convertible",
Packit Service e18529
		"Detachable",
Packit Service e18529
		"IoT Gateway",
Packit Service e18529
		"Embedded PC",
Packit Service e18529
		"Mini PC",
Packit Service e18529
		"Stick PC" /* 0x24 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x24)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_chassis_lock(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *lock[] = {
Packit Service e18529
		"Not Present", /* 0x00 */
Packit Service e18529
		"Present" /* 0x01 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return lock[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_chassis_state(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.4.2 */
Packit Service e18529
	static const char *state[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Safe",
Packit Service e18529
		"Warning",
Packit Service e18529
		"Critical",
Packit Service e18529
		"Non-recoverable" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x06)
Packit Service e18529
		return state[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_chassis_security_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.4.3 */
Packit Service e18529
	static const char *status[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"None",
Packit Service e18529
		"External Interface Locked Out",
Packit Service e18529
		"External Interface Enabled" /* 0x05 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x05)
Packit Service e18529
		return status[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_chassis_height(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x00)
Packit Service e18529
		printf(" Unspecified");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u U", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_chassis_power_cords(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x00)
Packit Service e18529
		printf(" Unspecified");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_chassis_elements(u8 count, u8 len, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	printf("%sContained Elements: %u\n",
Packit Service e18529
		prefix, count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Service e18529
		if (len >= 0x03)
Packit Service e18529
		{
Packit Service e18529
			printf("%s\t%s (",
Packit Service e18529
				prefix, p[i * len] & 0x80 ?
Packit Service e18529
				dmi_smbios_structure_type(p[i * len] & 0x7F) :
Packit Service e18529
				dmi_base_board_type(p[i * len] & 0x7F));
Packit Service e18529
			if (p[1 + i * len] == p[2 + i * len])
Packit Service e18529
				printf("%u", p[1 + i * len]);
Packit Service e18529
			else
Packit Service e18529
				printf("%u-%u", p[1 + i * len], p[2 + i * len]);
Packit Service e18529
			printf(")\n");
Packit Service e18529
		}
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.5 Processor Information (Type 4)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_processor_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.5.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Central Processor",
Packit Service e18529
		"Math Processor",
Packit Service e18529
		"DSP Processor",
Packit Service e18529
		"Video Processor" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x06)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
Packit Service e18529
{
Packit Service e18529
	const u8 *data = h->data;
Packit Service e18529
	unsigned int i, low, high;
Packit Service e18529
	u16 code;
Packit Service e18529
Packit Service e18529
	/* 7.5.2 */
Packit Service e18529
	static struct {
Packit Service e18529
		int value;
Packit Service e18529
		const char *name;
Packit Service e18529
	} family2[] = {
Packit Service e18529
		{ 0x01, "Other" },
Packit Service e18529
		{ 0x02, "Unknown" },
Packit Service e18529
		{ 0x03, "8086" },
Packit Service e18529
		{ 0x04, "80286" },
Packit Service e18529
		{ 0x05, "80386" },
Packit Service e18529
		{ 0x06, "80486" },
Packit Service e18529
		{ 0x07, "8087" },
Packit Service e18529
		{ 0x08, "80287" },
Packit Service e18529
		{ 0x09, "80387" },
Packit Service e18529
		{ 0x0A, "80487" },
Packit Service e18529
		{ 0x0B, "Pentium" },
Packit Service e18529
		{ 0x0C, "Pentium Pro" },
Packit Service e18529
		{ 0x0D, "Pentium II" },
Packit Service e18529
		{ 0x0E, "Pentium MMX" },
Packit Service e18529
		{ 0x0F, "Celeron" },
Packit Service e18529
		{ 0x10, "Pentium II Xeon" },
Packit Service e18529
		{ 0x11, "Pentium III" },
Packit Service e18529
		{ 0x12, "M1" },
Packit Service e18529
		{ 0x13, "M2" },
Packit Service e18529
		{ 0x14, "Celeron M" },
Packit Service e18529
		{ 0x15, "Pentium 4 HT" },
Packit Service e18529
Packit Service e18529
		{ 0x18, "Duron" },
Packit Service e18529
		{ 0x19, "K5" },
Packit Service e18529
		{ 0x1A, "K6" },
Packit Service e18529
		{ 0x1B, "K6-2" },
Packit Service e18529
		{ 0x1C, "K6-3" },
Packit Service e18529
		{ 0x1D, "Athlon" },
Packit Service e18529
		{ 0x1E, "AMD29000" },
Packit Service e18529
		{ 0x1F, "K6-2+" },
Packit Service e18529
		{ 0x20, "Power PC" },
Packit Service e18529
		{ 0x21, "Power PC 601" },
Packit Service e18529
		{ 0x22, "Power PC 603" },
Packit Service e18529
		{ 0x23, "Power PC 603+" },
Packit Service e18529
		{ 0x24, "Power PC 604" },
Packit Service e18529
		{ 0x25, "Power PC 620" },
Packit Service e18529
		{ 0x26, "Power PC x704" },
Packit Service e18529
		{ 0x27, "Power PC 750" },
Packit Service e18529
		{ 0x28, "Core Duo" },
Packit Service e18529
		{ 0x29, "Core Duo Mobile" },
Packit Service e18529
		{ 0x2A, "Core Solo Mobile" },
Packit Service e18529
		{ 0x2B, "Atom" },
Packit Service e18529
		{ 0x2C, "Core M" },
Packit Service e18529
		{ 0x2D, "Core m3" },
Packit Service e18529
		{ 0x2E, "Core m5" },
Packit Service e18529
		{ 0x2F, "Core m7" },
Packit Service e18529
		{ 0x30, "Alpha" },
Packit Service e18529
		{ 0x31, "Alpha 21064" },
Packit Service e18529
		{ 0x32, "Alpha 21066" },
Packit Service e18529
		{ 0x33, "Alpha 21164" },
Packit Service e18529
		{ 0x34, "Alpha 21164PC" },
Packit Service e18529
		{ 0x35, "Alpha 21164a" },
Packit Service e18529
		{ 0x36, "Alpha 21264" },
Packit Service e18529
		{ 0x37, "Alpha 21364" },
Packit Service e18529
		{ 0x38, "Turion II Ultra Dual-Core Mobile M" },
Packit Service e18529
		{ 0x39, "Turion II Dual-Core Mobile M" },
Packit Service e18529
		{ 0x3A, "Athlon II Dual-Core M" },
Packit Service e18529
		{ 0x3B, "Opteron 6100" },
Packit Service e18529
		{ 0x3C, "Opteron 4100" },
Packit Service e18529
		{ 0x3D, "Opteron 6200" },
Packit Service e18529
		{ 0x3E, "Opteron 4200" },
Packit Service e18529
		{ 0x3F, "FX" },
Packit Service e18529
		{ 0x40, "MIPS" },
Packit Service e18529
		{ 0x41, "MIPS R4000" },
Packit Service e18529
		{ 0x42, "MIPS R4200" },
Packit Service e18529
		{ 0x43, "MIPS R4400" },
Packit Service e18529
		{ 0x44, "MIPS R4600" },
Packit Service e18529
		{ 0x45, "MIPS R10000" },
Packit Service e18529
		{ 0x46, "C-Series" },
Packit Service e18529
		{ 0x47, "E-Series" },
Packit Service e18529
		{ 0x48, "A-Series" },
Packit Service e18529
		{ 0x49, "G-Series" },
Packit Service e18529
		{ 0x4A, "Z-Series" },
Packit Service e18529
		{ 0x4B, "R-Series" },
Packit Service e18529
		{ 0x4C, "Opteron 4300" },
Packit Service e18529
		{ 0x4D, "Opteron 6300" },
Packit Service e18529
		{ 0x4E, "Opteron 3300" },
Packit Service e18529
		{ 0x4F, "FirePro" },
Packit Service e18529
		{ 0x50, "SPARC" },
Packit Service e18529
		{ 0x51, "SuperSPARC" },
Packit Service e18529
		{ 0x52, "MicroSPARC II" },
Packit Service e18529
		{ 0x53, "MicroSPARC IIep" },
Packit Service e18529
		{ 0x54, "UltraSPARC" },
Packit Service e18529
		{ 0x55, "UltraSPARC II" },
Packit Service e18529
		{ 0x56, "UltraSPARC IIi" },
Packit Service e18529
		{ 0x57, "UltraSPARC III" },
Packit Service e18529
		{ 0x58, "UltraSPARC IIIi" },
Packit Service e18529
Packit Service e18529
		{ 0x60, "68040" },
Packit Service e18529
		{ 0x61, "68xxx" },
Packit Service e18529
		{ 0x62, "68000" },
Packit Service e18529
		{ 0x63, "68010" },
Packit Service e18529
		{ 0x64, "68020" },
Packit Service e18529
		{ 0x65, "68030" },
Packit Service e18529
		{ 0x66, "Athlon X4" },
Packit Service e18529
		{ 0x67, "Opteron X1000" },
Packit Service e18529
		{ 0x68, "Opteron X2000" },
Packit Service e18529
		{ 0x69, "Opteron A-Series" },
Packit Service e18529
		{ 0x6A, "Opteron X3000" },
Packit Service e18529
		{ 0x6B, "Zen" },
Packit Service e18529
Packit Service e18529
		{ 0x70, "Hobbit" },
Packit Service e18529
Packit Service e18529
		{ 0x78, "Crusoe TM5000" },
Packit Service e18529
		{ 0x79, "Crusoe TM3000" },
Packit Service e18529
		{ 0x7A, "Efficeon TM8000" },
Packit Service e18529
Packit Service e18529
		{ 0x80, "Weitek" },
Packit Service e18529
Packit Service e18529
		{ 0x82, "Itanium" },
Packit Service e18529
		{ 0x83, "Athlon 64" },
Packit Service e18529
		{ 0x84, "Opteron" },
Packit Service e18529
		{ 0x85, "Sempron" },
Packit Service e18529
		{ 0x86, "Turion 64" },
Packit Service e18529
		{ 0x87, "Dual-Core Opteron" },
Packit Service e18529
		{ 0x88, "Athlon 64 X2" },
Packit Service e18529
		{ 0x89, "Turion 64 X2" },
Packit Service e18529
		{ 0x8A, "Quad-Core Opteron" },
Packit Service e18529
		{ 0x8B, "Third-Generation Opteron" },
Packit Service e18529
		{ 0x8C, "Phenom FX" },
Packit Service e18529
		{ 0x8D, "Phenom X4" },
Packit Service e18529
		{ 0x8E, "Phenom X2" },
Packit Service e18529
		{ 0x8F, "Athlon X2" },
Packit Service e18529
		{ 0x90, "PA-RISC" },
Packit Service e18529
		{ 0x91, "PA-RISC 8500" },
Packit Service e18529
		{ 0x92, "PA-RISC 8000" },
Packit Service e18529
		{ 0x93, "PA-RISC 7300LC" },
Packit Service e18529
		{ 0x94, "PA-RISC 7200" },
Packit Service e18529
		{ 0x95, "PA-RISC 7100LC" },
Packit Service e18529
		{ 0x96, "PA-RISC 7100" },
Packit Service e18529
Packit Service e18529
		{ 0xA0, "V30" },
Packit Service e18529
		{ 0xA1, "Quad-Core Xeon 3200" },
Packit Service e18529
		{ 0xA2, "Dual-Core Xeon 3000" },
Packit Service e18529
		{ 0xA3, "Quad-Core Xeon 5300" },
Packit Service e18529
		{ 0xA4, "Dual-Core Xeon 5100" },
Packit Service e18529
		{ 0xA5, "Dual-Core Xeon 5000" },
Packit Service e18529
		{ 0xA6, "Dual-Core Xeon LV" },
Packit Service e18529
		{ 0xA7, "Dual-Core Xeon ULV" },
Packit Service e18529
		{ 0xA8, "Dual-Core Xeon 7100" },
Packit Service e18529
		{ 0xA9, "Quad-Core Xeon 5400" },
Packit Service e18529
		{ 0xAA, "Quad-Core Xeon" },
Packit Service e18529
		{ 0xAB, "Dual-Core Xeon 5200" },
Packit Service e18529
		{ 0xAC, "Dual-Core Xeon 7200" },
Packit Service e18529
		{ 0xAD, "Quad-Core Xeon 7300" },
Packit Service e18529
		{ 0xAE, "Quad-Core Xeon 7400" },
Packit Service e18529
		{ 0xAF, "Multi-Core Xeon 7400" },
Packit Service e18529
		{ 0xB0, "Pentium III Xeon" },
Packit Service e18529
		{ 0xB1, "Pentium III Speedstep" },
Packit Service e18529
		{ 0xB2, "Pentium 4" },
Packit Service e18529
		{ 0xB3, "Xeon" },
Packit Service e18529
		{ 0xB4, "AS400" },
Packit Service e18529
		{ 0xB5, "Xeon MP" },
Packit Service e18529
		{ 0xB6, "Athlon XP" },
Packit Service e18529
		{ 0xB7, "Athlon MP" },
Packit Service e18529
		{ 0xB8, "Itanium 2" },
Packit Service e18529
		{ 0xB9, "Pentium M" },
Packit Service e18529
		{ 0xBA, "Celeron D" },
Packit Service e18529
		{ 0xBB, "Pentium D" },
Packit Service e18529
		{ 0xBC, "Pentium EE" },
Packit Service e18529
		{ 0xBD, "Core Solo" },
Packit Service e18529
		/* 0xBE handled as a special case */
Packit Service e18529
		{ 0xBF, "Core 2 Duo" },
Packit Service e18529
		{ 0xC0, "Core 2 Solo" },
Packit Service e18529
		{ 0xC1, "Core 2 Extreme" },
Packit Service e18529
		{ 0xC2, "Core 2 Quad" },
Packit Service e18529
		{ 0xC3, "Core 2 Extreme Mobile" },
Packit Service e18529
		{ 0xC4, "Core 2 Duo Mobile" },
Packit Service e18529
		{ 0xC5, "Core 2 Solo Mobile" },
Packit Service e18529
		{ 0xC6, "Core i7" },
Packit Service e18529
		{ 0xC7, "Dual-Core Celeron" },
Packit Service e18529
		{ 0xC8, "IBM390" },
Packit Service e18529
		{ 0xC9, "G4" },
Packit Service e18529
		{ 0xCA, "G5" },
Packit Service e18529
		{ 0xCB, "ESA/390 G6" },
Packit Service e18529
		{ 0xCC, "z/Architecture" },
Packit Service e18529
		{ 0xCD, "Core i5" },
Packit Service e18529
		{ 0xCE, "Core i3" },
Packit Service e18529
		{ 0xCF, "Core i9" },
Packit Service e18529
Packit Service e18529
		{ 0xD2, "C7-M" },
Packit Service e18529
		{ 0xD3, "C7-D" },
Packit Service e18529
		{ 0xD4, "C7" },
Packit Service e18529
		{ 0xD5, "Eden" },
Packit Service e18529
		{ 0xD6, "Multi-Core Xeon" },
Packit Service e18529
		{ 0xD7, "Dual-Core Xeon 3xxx" },
Packit Service e18529
		{ 0xD8, "Quad-Core Xeon 3xxx" },
Packit Service e18529
		{ 0xD9, "Nano" },
Packit Service e18529
		{ 0xDA, "Dual-Core Xeon 5xxx" },
Packit Service e18529
		{ 0xDB, "Quad-Core Xeon 5xxx" },
Packit Service e18529
Packit Service e18529
		{ 0xDD, "Dual-Core Xeon 7xxx" },
Packit Service e18529
		{ 0xDE, "Quad-Core Xeon 7xxx" },
Packit Service e18529
		{ 0xDF, "Multi-Core Xeon 7xxx" },
Packit Service e18529
		{ 0xE0, "Multi-Core Xeon 3400" },
Packit Service e18529
Packit Service e18529
		{ 0xE4, "Opteron 3000" },
Packit Service e18529
		{ 0xE5, "Sempron II" },
Packit Service e18529
		{ 0xE6, "Embedded Opteron Quad-Core" },
Packit Service e18529
		{ 0xE7, "Phenom Triple-Core" },
Packit Service e18529
		{ 0xE8, "Turion Ultra Dual-Core Mobile" },
Packit Service e18529
		{ 0xE9, "Turion Dual-Core Mobile" },
Packit Service e18529
		{ 0xEA, "Athlon Dual-Core" },
Packit Service e18529
		{ 0xEB, "Sempron SI" },
Packit Service e18529
		{ 0xEC, "Phenom II" },
Packit Service e18529
		{ 0xED, "Athlon II" },
Packit Service e18529
		{ 0xEE, "Six-Core Opteron" },
Packit Service e18529
		{ 0xEF, "Sempron M" },
Packit Service e18529
Packit Service e18529
		{ 0xFA, "i860" },
Packit Service e18529
		{ 0xFB, "i960" },
Packit Service e18529
Packit Service e18529
		{ 0x100, "ARMv7" },
Packit Service e18529
		{ 0x101, "ARMv8" },
Packit Service e18529
		{ 0x104, "SH-3" },
Packit Service e18529
		{ 0x105, "SH-4" },
Packit Service e18529
		{ 0x118, "ARM" },
Packit Service e18529
		{ 0x119, "StrongARM" },
Packit Service e18529
		{ 0x12C, "6x86" },
Packit Service e18529
		{ 0x12D, "MediaGX" },
Packit Service e18529
		{ 0x12E, "MII" },
Packit Service e18529
		{ 0x140, "WinChip" },
Packit Service e18529
		{ 0x15E, "DSP" },
Packit Service e18529
		{ 0x1F4, "Video Processor" },
Packit Service 93af92
Packit Service 93af92
		{ 0x200, "RV32" },
Packit Service 93af92
		{ 0x201, "RV64" },
Packit Service 93af92
		{ 0x202, "RV128" },
Packit Service e18529
	};
Packit Service e18529
	/*
Packit Service e18529
	 * Note to developers: when adding entries to this list, check if
Packit Service e18529
	 * function dmi_processor_id below needs updating too.
Packit Service e18529
	 */
Packit Service e18529
Packit Service e18529
	/* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */
Packit Service e18529
	if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08)
Packit Service e18529
	{
Packit Service e18529
		const char *manufacturer = dmi_string(h, data[0x07]);
Packit Service e18529
Packit Service e18529
		if (strstr(manufacturer, "Intel") != NULL
Packit Service e18529
		 || strncasecmp(manufacturer, "Intel", 5) == 0)
Packit Service e18529
			return "Pentium Pro";
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	code = (data[0x06] == 0xFE && h->length >= 0x2A) ?
Packit Service e18529
		WORD(data + 0x28) : data[0x06];
Packit Service e18529
Packit Service e18529
	/* Special case for ambiguous value 0xBE */
Packit Service e18529
	if (code == 0xBE)
Packit Service e18529
	{
Packit Service e18529
		if (h->length >= 0x08)
Packit Service e18529
		{
Packit Service e18529
			const char *manufacturer = dmi_string(h, data[0x07]);
Packit Service e18529
Packit Service e18529
			/* Best bet based on manufacturer string */
Packit Service e18529
			if (strstr(manufacturer, "Intel") != NULL
Packit Service e18529
			 || strncasecmp(manufacturer, "Intel", 5) == 0)
Packit Service e18529
				return "Core 2";
Packit Service e18529
			if (strstr(manufacturer, "AMD") != NULL
Packit Service e18529
			 || strncasecmp(manufacturer, "AMD", 3) == 0)
Packit Service e18529
				return "K7";
Packit Service e18529
		}
Packit Service e18529
Packit Service e18529
		return "Core 2 or K7";
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	/* Perform a binary search */
Packit Service e18529
	low = 0;
Packit Service e18529
	high = ARRAY_SIZE(family2) - 1;
Packit Service e18529
Packit Service e18529
	while (1)
Packit Service e18529
	{
Packit Service e18529
		i = (low + high) / 2;
Packit Service e18529
		if (family2[i].value == code)
Packit Service e18529
			return family2[i].name;
Packit Service e18529
		if (low == high) /* Not found */
Packit Service e18529
			return out_of_spec;
Packit Service e18529
Packit Service e18529
		if (code < family2[i].value)
Packit Service e18529
			high = i;
Packit Service e18529
		else
Packit Service e18529
			low = i + 1;
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_processor_id(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* Intel AP-485 revision 36, table 2-4 */
Packit Service e18529
	static const char *flags[32] = {
Packit Service e18529
		"FPU (Floating-point unit on-chip)", /* 0 */
Packit Service e18529
		"VME (Virtual mode extension)",
Packit Service e18529
		"DE (Debugging extension)",
Packit Service e18529
		"PSE (Page size extension)",
Packit Service e18529
		"TSC (Time stamp counter)",
Packit Service e18529
		"MSR (Model specific registers)",
Packit Service e18529
		"PAE (Physical address extension)",
Packit Service e18529
		"MCE (Machine check exception)",
Packit Service e18529
		"CX8 (CMPXCHG8 instruction supported)",
Packit Service e18529
		"APIC (On-chip APIC hardware supported)",
Packit Service e18529
		NULL, /* 10 */
Packit Service e18529
		"SEP (Fast system call)",
Packit Service e18529
		"MTRR (Memory type range registers)",
Packit Service e18529
		"PGE (Page global enable)",
Packit Service e18529
		"MCA (Machine check architecture)",
Packit Service e18529
		"CMOV (Conditional move instruction supported)",
Packit Service e18529
		"PAT (Page attribute table)",
Packit Service e18529
		"PSE-36 (36-bit page size extension)",
Packit Service e18529
		"PSN (Processor serial number present and enabled)",
Packit Service e18529
		"CLFSH (CLFLUSH instruction supported)",
Packit Service e18529
		NULL, /* 20 */
Packit Service e18529
		"DS (Debug store)",
Packit Service e18529
		"ACPI (ACPI supported)",
Packit Service e18529
		"MMX (MMX technology supported)",
Packit Service e18529
		"FXSR (FXSAVE and FXSTOR instructions supported)",
Packit Service e18529
		"SSE (Streaming SIMD extensions)",
Packit Service e18529
		"SSE2 (Streaming SIMD extensions 2)",
Packit Service e18529
		"SS (Self-snoop)",
Packit Service e18529
		"HTT (Multi-threading)",
Packit Service e18529
		"TM (Thermal monitor supported)",
Packit Service e18529
		NULL, /* 30 */
Packit Service e18529
		"PBE (Pending break enabled)" /* 31 */
Packit Service e18529
	};
Packit Service e18529
	const u8 *data = h->data;
Packit Service e18529
	const u8 *p = data + 0x08;
Packit Service e18529
	u32 eax, edx;
Packit Service e18529
	int sig = 0;
Packit Service e18529
	u16 type;
Packit Service e18529
Packit Service e18529
	type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
Packit Service e18529
		WORD(data + 0x28) : data[0x06];
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * This might help learn about new processors supporting the
Packit Service e18529
	 * CPUID instruction or another form of identification.
Packit Service e18529
	 */
Packit Service e18529
	printf("%sID: %02X %02X %02X %02X %02X %02X %02X %02X\n",
Packit Service e18529
		prefix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
Packit Service e18529
Packit Service e18529
	if (type == 0x05) /* 80386 */
Packit Service e18529
	{
Packit Service e18529
		u16 dx = WORD(p);
Packit Service e18529
		/*
Packit Service e18529
		 * 80386 have a different signature.
Packit Service e18529
		 */
Packit Service e18529
		printf("%sSignature: Type %u, Family %u, Major Stepping %u, Minor Stepping %u\n",
Packit Service e18529
			prefix, dx >> 12, (dx >> 8) & 0xF,
Packit Service e18529
			(dx >> 4) & 0xF, dx & 0xF);
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
	if (type == 0x06) /* 80486 */
Packit Service e18529
	{
Packit Service e18529
		u16 dx = WORD(p);
Packit Service e18529
		/*
Packit Service e18529
		 * Not all 80486 CPU support the CPUID instruction, we have to find
Packit Service e18529
		 * wether the one we have here does or not. Note that this trick
Packit Service e18529
		 * works only because we know that 80486 must be little-endian.
Packit Service e18529
		 */
Packit Service e18529
		if ((dx & 0x0F00) == 0x0400
Packit Service e18529
		 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
Packit Service e18529
		 && ((dx & 0x000F) >= 0x0003))
Packit Service e18529
			sig = 1;
Packit Service e18529
		else
Packit Service e18529
		{
Packit Service e18529
			printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n",
Packit Service e18529
				prefix, (dx >> 12) & 0x3, (dx >> 8) & 0xF,
Packit Service e18529
				(dx >> 4) & 0xF, dx & 0xF);
Packit Service e18529
			return;
Packit Service e18529
		}
Packit Service e18529
	}
Packit Service e18529
	else if ((type >= 0x100 && type <= 0x101) /* ARM */
Packit Service e18529
	      || (type >= 0x118 && type <= 0x119)) /* ARM */
Packit Service e18529
	{
Packit Service e18529
		u32 midr = DWORD(p);
Packit Service e18529
		/*
Packit Service e18529
		 * The format of this field was not defined for ARM processors
Packit Service e18529
		 * before version 3.1.0 of the SMBIOS specification, so we
Packit Service e18529
		 * silently skip it if it reads all zeroes.
Packit Service e18529
		 */
Packit Service e18529
		if (midr == 0)
Packit Service e18529
			return;
Packit Service e18529
		printf("%sSignature: Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u\n",
Packit Service e18529
			prefix, midr >> 24, (midr >> 20) & 0xF,
Packit Service e18529
			(midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
	else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
Packit Service e18529
	      || (type >= 0x28 && type <= 0x2F) /* Intel */
Packit Service e18529
	      || (type >= 0xA1 && type <= 0xB3) /* Intel */
Packit Service e18529
	      || type == 0xB5 /* Intel */
Packit Service e18529
	      || (type >= 0xB9 && type <= 0xC7) /* Intel */
Packit Service e18529
	      || (type >= 0xCD && type <= 0xCF) /* Intel */
Packit Service e18529
	      || (type >= 0xD2 && type <= 0xDB) /* VIA, Intel */
Packit Service e18529
	      || (type >= 0xDD && type <= 0xE0)) /* Intel */
Packit Service e18529
		sig = 1;
Packit Service e18529
	else if ((type >= 0x18 && type <= 0x1D) /* AMD */
Packit Service e18529
	      || type == 0x1F /* AMD */
Packit Service e18529
	      || (type >= 0x38 && type <= 0x3F) /* AMD */
Packit Service e18529
	      || (type >= 0x46 && type <= 0x4F) /* AMD */
Packit Service e18529
	      || (type >= 0x66 && type <= 0x6B) /* AMD */
Packit Service e18529
	      || (type >= 0x83 && type <= 0x8F) /* AMD */
Packit Service e18529
	      || (type >= 0xB6 && type <= 0xB7) /* AMD */
Packit Service e18529
	      || (type >= 0xE4 && type <= 0xEF)) /* AMD */
Packit Service e18529
		sig = 2;
Packit Service e18529
	else if (type == 0x01 || type == 0x02)
Packit Service e18529
	{
Packit Service e18529
		const char *version = dmi_string(h, data[0x10]);
Packit Service e18529
		/*
Packit Service e18529
		 * Some X86-class CPU have family "Other" or "Unknown". In this case,
Packit Service e18529
		 * we use the version string to determine if they are known to
Packit Service e18529
		 * support the CPUID instruction.
Packit Service e18529
		 */
Packit Service e18529
		if (strncmp(version, "Pentium III MMX", 15) == 0
Packit Service e18529
		 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
Packit Service e18529
		 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
Packit Service e18529
		 || strcmp(version, "Genuine Intel(R) CPU U1400") == 0)
Packit Service e18529
			sig = 1;
Packit Service e18529
		else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
Packit Service e18529
		      || strncmp(version, "AMD Opteron(tm)", 15) == 0
Packit Service e18529
		      || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0)
Packit Service e18529
			sig = 2;
Packit Service e18529
		else
Packit Service e18529
			return;
Packit Service e18529
	}
Packit Service e18529
	else /* neither X86 nor ARM */
Packit Service e18529
		return;
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * Extra flags are now returned in the ECX register when one calls
Packit Service e18529
	 * the CPUID instruction. Their meaning is explained in table 3-5, but
Packit Service e18529
	 * DMI doesn't support this yet.
Packit Service e18529
	 */
Packit Service e18529
	eax = DWORD(p);
Packit Service e18529
	edx = DWORD(p + 4);
Packit Service e18529
	switch (sig)
Packit Service e18529
	{
Packit Service e18529
		case 1: /* Intel */
Packit Service e18529
			printf("%sSignature: Type %u, Family %u, Model %u, Stepping %u\n",
Packit Service e18529
				prefix, (eax >> 12) & 0x3,
Packit Service e18529
				((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F),
Packit Service e18529
				((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F),
Packit Service e18529
				eax & 0xF);
Packit Service e18529
			break;
Packit Service e18529
		case 2: /* AMD, publication #25481 revision 2.28 */
Packit Service e18529
			printf("%sSignature: Family %u, Model %u, Stepping %u\n",
Packit Service e18529
				prefix,
Packit Service e18529
				((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0),
Packit Service e18529
				((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0),
Packit Service e18529
				eax & 0xF);
Packit Service e18529
			break;
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	edx = DWORD(p + 4);
Packit Service e18529
	printf("%sFlags:", prefix);
Packit Service e18529
	if ((edx & 0xBFEFFBFF) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 0; i <= 31; i++)
Packit Service e18529
			if (flags[i] != NULL && edx & (1 << i))
Packit Service e18529
				printf("%s\t%s\n", prefix, flags[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_processor_voltage(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.5.4 */
Packit Service e18529
	static const char *voltage[] = {
Packit Service e18529
		"5.0 V", /* 0 */
Packit Service e18529
		"3.3 V",
Packit Service e18529
		"2.9 V" /* 2 */
Packit Service e18529
	};
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	if (code & 0x80)
Packit Service e18529
		printf(" %.1f V", (float)(code & 0x7f) / 10);
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		for (i = 0; i <= 2; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf(" %s", voltage[i]);
Packit Service e18529
		if (code == 0x00)
Packit Service e18529
			printf(" Unknown");
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_processor_frequency(const u8 *p)
Packit Service e18529
{
Packit Service e18529
	u16 code = WORD(p);
Packit Service e18529
Packit Service e18529
	if (code)
Packit Service e18529
		printf("%u MHz", code);
Packit Service e18529
	else
Packit Service e18529
		printf("Unknown");
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/* code is assumed to be a 3-bit value */
Packit Service e18529
static const char *dmi_processor_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *status[] = {
Packit Service e18529
		"Unknown", /* 0x00 */
Packit Service e18529
		"Enabled",
Packit Service e18529
		"Disabled By User",
Packit Service e18529
		"Disabled By BIOS",
Packit Service e18529
		"Idle", /* 0x04 */
Packit Service e18529
		out_of_spec,
Packit Service e18529
		out_of_spec,
Packit Service e18529
		"Other" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return status[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_processor_upgrade(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.5.5 */
Packit Service e18529
	static const char *upgrade[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Daughter Board",
Packit Service e18529
		"ZIF Socket",
Packit Service e18529
		"Replaceable Piggy Back",
Packit Service e18529
		"None",
Packit Service e18529
		"LIF Socket",
Packit Service e18529
		"Slot 1",
Packit Service e18529
		"Slot 2",
Packit Service e18529
		"370-pin Socket",
Packit Service e18529
		"Slot A",
Packit Service e18529
		"Slot M",
Packit Service e18529
		"Socket 423",
Packit Service e18529
		"Socket A (Socket 462)",
Packit Service e18529
		"Socket 478",
Packit Service e18529
		"Socket 754",
Packit Service e18529
		"Socket 940",
Packit Service e18529
		"Socket 939",
Packit Service e18529
		"Socket mPGA604",
Packit Service e18529
		"Socket LGA771",
Packit Service e18529
		"Socket LGA775",
Packit Service e18529
		"Socket S1",
Packit Service e18529
		"Socket AM2",
Packit Service e18529
		"Socket F (1207)",
Packit Service e18529
		"Socket LGA1366",
Packit Service e18529
		"Socket G34",
Packit Service e18529
		"Socket AM3",
Packit Service e18529
		"Socket C32",
Packit Service e18529
		"Socket LGA1156",
Packit Service e18529
		"Socket LGA1567",
Packit Service e18529
		"Socket PGA988A",
Packit Service e18529
		"Socket BGA1288",
Packit Service e18529
		"Socket rPGA988B",
Packit Service e18529
		"Socket BGA1023",
Packit Service e18529
		"Socket BGA1224",
Packit Service e18529
		"Socket BGA1155",
Packit Service e18529
		"Socket LGA1356",
Packit Service e18529
		"Socket LGA2011",
Packit Service e18529
		"Socket FS1",
Packit Service e18529
		"Socket FS2",
Packit Service e18529
		"Socket FM1",
Packit Service e18529
		"Socket FM2",
Packit Service e18529
		"Socket LGA2011-3",
Packit Service e18529
		"Socket LGA1356-3",
Packit Service e18529
		"Socket LGA1150",
Packit Service e18529
		"Socket BGA1168",
Packit Service e18529
		"Socket BGA1234",
Packit Service e18529
		"Socket BGA1364",
Packit Service e18529
		"Socket AM4",
Packit Service e18529
		"Socket LGA1151",
Packit Service e18529
		"Socket BGA1356",
Packit Service e18529
		"Socket BGA1440",
Packit Service e18529
		"Socket BGA1515",
Packit Service e18529
		"Socket LGA3647-1",
Packit Service e18529
		"Socket SP3",
Packit Service e18529
		"Socket SP3r2",
Packit Service e18529
		"Socket LGA2066",
Packit Service e18529
		"Socket BGA1392",
Packit Service e18529
		"Socket BGA1510",
Packit Service e18529
		"Socket BGA1528" /* 0x3C */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x3C)
Packit Service e18529
		return upgrade[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_processor_cache(u16 code, const char *level, u16 ver)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Service e18529
	{
Packit Service e18529
		if (ver >= 0x0203)
Packit Service e18529
			printf(" Not Provided");
Packit Service e18529
		else
Packit Service e18529
			printf(" No %s Cache", level);
Packit Service e18529
	}
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%04X", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_processor_characteristics(u16 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.5.9 */
Packit Service e18529
	static const char *characteristics[] = {
Packit Service e18529
		"64-bit capable", /* 2 */
Packit Service e18529
		"Multi-Core",
Packit Service e18529
		"Hardware Thread",
Packit Service e18529
		"Execute Protection",
Packit Service e18529
		"Enhanced Virtualization",
Packit Service e18529
		"Power/Performance Control" /* 7 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x00FC) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 2; i <= 7; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s\n", prefix, characteristics[i - 2]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.6 Memory Controller Information (Type 5)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_controller_ed_method(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.6.1 */
Packit Service e18529
	static const char *method[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"None",
Packit Service e18529
		"8-bit Parity",
Packit Service e18529
		"32-bit ECC",
Packit Service e18529
		"64-bit ECC",
Packit Service e18529
		"128-bit ECC",
Packit Service e18529
		"CRC" /* 0x08 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x08)
Packit Service e18529
		return method[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_controller_ec_capabilities(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.6.2 */
Packit Service e18529
	static const char *capabilities[] = {
Packit Service e18529
		"Other", /* 0 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"None",
Packit Service e18529
		"Single-bit Error Correcting",
Packit Service e18529
		"Double-bit Error Correcting",
Packit Service e18529
		"Error Scrubbing" /* 5 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x3F) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 0; i <= 5; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s\n", prefix, capabilities[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_controller_interleave(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.6.3 */
Packit Service e18529
	static const char *interleave[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"One-way Interleave",
Packit Service e18529
		"Two-way Interleave",
Packit Service e18529
		"Four-way Interleave",
Packit Service e18529
		"Eight-way Interleave",
Packit Service e18529
		"Sixteen-way Interleave" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x07)
Packit Service e18529
		return interleave[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_controller_speeds(u16 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.6.4 */
Packit Service e18529
	const char *speeds[] = {
Packit Service e18529
		"Other", /* 0 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"70 ns",
Packit Service e18529
		"60 ns",
Packit Service e18529
		"50 ns" /* 4 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x001F) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 0; i <= 4; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s\n", prefix, speeds[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_controller_slots(u8 count, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	printf("%sAssociated Memory Slots: %u\n",
Packit Service e18529
		prefix, count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
		printf("%s\t0x%04X\n",
Packit Service e18529
			prefix, WORD(p + sizeof(u16) * i));
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.7 Memory Module Information (Type 6)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_memory_module_types(u16 code, const char *sep)
Packit Service e18529
{
Packit Service e18529
	/* 7.7.1 */
Packit Service e18529
	static const char *types[] = {
Packit Service e18529
		"Other", /* 0 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Standard",
Packit Service e18529
		"FPM",
Packit Service e18529
		"EDO",
Packit Service e18529
		"Parity",
Packit Service e18529
		"ECC",
Packit Service e18529
		"SIMM",
Packit Service e18529
		"DIMM",
Packit Service e18529
		"Burst EDO",
Packit Service e18529
		"SDRAM" /* 10 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x07FF) == 0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		for (i = 0; i <= 10; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s", sep, types[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_module_connections(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFF)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		if ((code & 0xF0) != 0xF0)
Packit Service e18529
			printf(" %u", code >> 4);
Packit Service e18529
		if ((code & 0x0F) != 0x0F)
Packit Service e18529
			printf(" %u", code & 0x0F);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_module_speed(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u ns", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_module_size(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.7.2 */
Packit Service e18529
	switch (code & 0x7F)
Packit Service e18529
	{
Packit Service e18529
		case 0x7D:
Packit Service e18529
			printf(" Not Determinable");
Packit Service e18529
			break;
Packit Service e18529
		case 0x7E:
Packit Service e18529
			printf(" Disabled");
Packit Service e18529
			break;
Packit Service e18529
		case 0x7F:
Packit Service e18529
			printf(" Not Installed");
Packit Service e18529
			return;
Packit Service e18529
		default:
Packit Service e18529
			printf(" %u MB", 1 << (code & 0x7F));
Packit Service e18529
	}
Packit Service e18529
Packit Service e18529
	if (code & 0x80)
Packit Service e18529
		printf(" (Double-bank Connection)");
Packit Service e18529
	else
Packit Service e18529
		printf(" (Single-bank Connection)");
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_module_error(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	if (code & (1 << 2))
Packit Service e18529
		printf(" See Event Log\n");
Packit Service e18529
	else
Packit Service e18529
	{	if ((code & 0x03) == 0)
Packit Service e18529
			printf(" OK\n");
Packit Service e18529
		if (code & (1 << 0))
Packit Service e18529
			printf("%sUncorrectable Errors\n", prefix);
Packit Service e18529
		if (code & (1 << 1))
Packit Service e18529
			printf("%sCorrectable Errors\n", prefix);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.8 Cache Information (Type 7)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_cache_mode(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *mode[] = {
Packit Service e18529
		"Write Through", /* 0x00 */
Packit Service e18529
		"Write Back",
Packit Service e18529
		"Varies With Memory Address",
Packit Service e18529
		"Unknown" /* 0x03 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return mode[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/* code is assumed to be a 2-bit value */
Packit Service e18529
static const char *dmi_cache_location(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *location[4] = {
Packit Service e18529
		"Internal", /* 0x00 */
Packit Service e18529
		"External",
Packit Service e18529
		out_of_spec, /* 0x02 */
Packit Service e18529
		"Unknown" /* 0x03 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return location[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_cache_size_2(u32 code)
Packit Service e18529
{
Packit Service 5f8431
	u64 size;
Packit Service 5f8431
Packit Service e18529
	if (code & 0x80000000)
Packit Service e18529
	{
Packit Service e18529
		code &= 0x7FFFFFFFLU;
Packit Service 5f8431
		size.l = code << 6;
Packit Service 5f8431
		size.h = code >> 26;
Packit Service e18529
	}
Packit Service e18529
	else
Packit Service 5f8431
	{
Packit Service 5f8431
		size.l = code;
Packit Service 5f8431
		size.h = 0;
Packit Service 5f8431
	}
Packit Service 5f8431
Packit Service 5f8431
	/* Use a more convenient unit for large cache size */
Packit Service 5f8431
	dmi_print_memory_size(size, 1);
Packit Service e18529
}
Packit Service e18529
Packit Service b2e79e
static void dmi_cache_size(u16 code)
Packit Service b2e79e
{
Packit Service b2e79e
	dmi_cache_size_2((((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU));
Packit Service b2e79e
}
Packit Service b2e79e
Packit Service e18529
static void dmi_cache_types(u16 code, const char *sep)
Packit Service e18529
{
Packit Service e18529
	/* 7.8.2 */
Packit Service e18529
	static const char *types[] = {
Packit Service e18529
		"Other", /* 0 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Non-burst",
Packit Service e18529
		"Burst",
Packit Service e18529
		"Pipeline Burst",
Packit Service e18529
		"Synchronous",
Packit Service e18529
		"Asynchronous" /* 6 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0x007F) == 0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		for (i = 0; i <= 6; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf("%s%s", sep, types[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_cache_ec_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.8.3 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"None",
Packit Service e18529
		"Parity",
Packit Service e18529
		"Single-bit ECC",
Packit Service e18529
		"Multi-bit ECC" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x06)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_cache_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.8.4 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Instruction",
Packit Service e18529
		"Data",
Packit Service e18529
		"Unified" /* 0x05 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x05)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_cache_associativity(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.8.5 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Direct Mapped",
Packit Service e18529
		"2-way Set-associative",
Packit Service e18529
		"4-way Set-associative",
Packit Service e18529
		"Fully Associative",
Packit Service e18529
		"8-way Set-associative",
Packit Service e18529
		"16-way Set-associative",
Packit Service e18529
		"12-way Set-associative",
Packit Service e18529
		"24-way Set-associative",
Packit Service e18529
		"32-way Set-associative",
Packit Service e18529
		"48-way Set-associative",
Packit Service e18529
		"64-way Set-associative",
Packit Service e18529
		"20-way Set-associative" /* 0x0E */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0E)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.9 Port Connector Information (Type 8)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_port_connector_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.9.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"None", /* 0x00 */
Packit Service e18529
		"Centronics",
Packit Service e18529
		"Mini Centronics",
Packit Service e18529
		"Proprietary",
Packit Service e18529
		"DB-25 male",
Packit Service e18529
		"DB-25 female",
Packit Service e18529
		"DB-15 male",
Packit Service e18529
		"DB-15 female",
Packit Service e18529
		"DB-9 male",
Packit Service e18529
		"DB-9 female",
Packit Service e18529
		"RJ-11",
Packit Service e18529
		"RJ-45",
Packit Service e18529
		"50 Pin MiniSCSI",
Packit Service e18529
		"Mini DIN",
Packit Service e18529
		"Micro DIN",
Packit Service e18529
		"PS/2",
Packit Service e18529
		"Infrared",
Packit Service e18529
		"HP-HIL",
Packit Service e18529
		"Access Bus (USB)",
Packit Service e18529
		"SSA SCSI",
Packit Service e18529
		"Circular DIN-8 male",
Packit Service e18529
		"Circular DIN-8 female",
Packit Service e18529
		"On Board IDE",
Packit Service e18529
		"On Board Floppy",
Packit Service e18529
		"9 Pin Dual Inline (pin 10 cut)",
Packit Service e18529
		"25 Pin Dual Inline (pin 26 cut)",
Packit Service e18529
		"50 Pin Dual Inline",
Packit Service e18529
		"68 Pin Dual Inline",
Packit Service e18529
		"On Board Sound Input From CD-ROM",
Packit Service e18529
		"Mini Centronics Type-14",
Packit Service e18529
		"Mini Centronics Type-26",
Packit Service e18529
		"Mini Jack (headphones)",
Packit Service e18529
		"BNC",
Packit Service e18529
		"IEEE 1394",
Packit Service e18529
		"SAS/SATA Plug Receptacle",
Packit Service e18529
		"USB Type-C Receptacle" /* 0x23 */
Packit Service e18529
	};
Packit Service e18529
	static const char *type_0xA0[] = {
Packit Service e18529
		"PC-98", /* 0xA0 */
Packit Service e18529
		"PC-98 Hireso",
Packit Service e18529
		"PC-H98",
Packit Service e18529
		"PC-98 Note",
Packit Service e18529
		"PC-98 Full" /* 0xA4 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x23)
Packit Service e18529
		return type[code];
Packit Service e18529
	if (code >= 0xA0 && code <= 0xA4)
Packit Service e18529
		return type_0xA0[code - 0xA0];
Packit Service e18529
	if (code == 0xFF)
Packit Service e18529
		return "Other";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_port_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.9.3 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"None", /* 0x00 */
Packit Service e18529
		"Parallel Port XT/AT Compatible",
Packit Service e18529
		"Parallel Port PS/2",
Packit Service e18529
		"Parallel Port ECP",
Packit Service e18529
		"Parallel Port EPP",
Packit Service e18529
		"Parallel Port ECP/EPP",
Packit Service e18529
		"Serial Port XT/AT Compatible",
Packit Service e18529
		"Serial Port 16450 Compatible",
Packit Service e18529
		"Serial Port 16550 Compatible",
Packit Service e18529
		"Serial Port 16550A Compatible",
Packit Service e18529
		"SCSI Port",
Packit Service e18529
		"MIDI Port",
Packit Service e18529
		"Joystick Port",
Packit Service e18529
		"Keyboard Port",
Packit Service e18529
		"Mouse Port",
Packit Service e18529
		"SSA SCSI",
Packit Service e18529
		"USB",
Packit Service e18529
		"Firewire (IEEE P1394)",
Packit Service e18529
		"PCMCIA Type I",
Packit Service e18529
		"PCMCIA Type II",
Packit Service e18529
		"PCMCIA Type III",
Packit Service e18529
		"Cardbus",
Packit Service e18529
		"Access Bus Port",
Packit Service e18529
		"SCSI II",
Packit Service e18529
		"SCSI Wide",
Packit Service e18529
		"PC-98",
Packit Service e18529
		"PC-98 Hireso",
Packit Service e18529
		"PC-H98",
Packit Service e18529
		"Video Port",
Packit Service e18529
		"Audio Port",
Packit Service e18529
		"Modem Port",
Packit Service e18529
		"Network Port",
Packit Service e18529
		"SATA",
Packit Service e18529
		"SAS" /* 0x21 */
Packit Service e18529
	};
Packit Service e18529
	static const char *type_0xA0[] = {
Packit Service e18529
		"8251 Compatible", /* 0xA0 */
Packit Service e18529
		"8251 FIFO Compatible" /* 0xA1 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x21)
Packit Service e18529
		return type[code];
Packit Service e18529
	if (code >= 0xA0 && code <= 0xA1)
Packit Service e18529
		return type_0xA0[code - 0xA0];
Packit Service e18529
	if (code == 0xFF)
Packit Service e18529
		return "Other";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.10 System Slots (Type 9)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_slot_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"ISA",
Packit Service e18529
		"MCA",
Packit Service e18529
		"EISA",
Packit Service e18529
		"PCI",
Packit Service e18529
		"PC Card (PCMCIA)",
Packit Service e18529
		"VLB",
Packit Service e18529
		"Proprietary",
Packit Service e18529
		"Processor Card",
Packit Service e18529
		"Proprietary Memory Card",
Packit Service e18529
		"I/O Riser Card",
Packit Service e18529
		"NuBus",
Packit Service e18529
		"PCI-66",
Packit Service e18529
		"AGP",
Packit Service e18529
		"AGP 2x",
Packit Service e18529
		"AGP 4x",
Packit Service e18529
		"PCI-X",
Packit Service e18529
		"AGP 8x",
Packit Service e18529
		"M.2 Socket 1-DP",
Packit Service e18529
		"M.2 Socket 1-SD",
Packit Service e18529
		"M.2 Socket 2",
Packit Service e18529
		"M.2 Socket 3",
Packit Service e18529
		"MXM Type I",
Packit Service e18529
		"MXM Type II",
Packit Service e18529
		"MXM Type III",
Packit Service e18529
		"MXM Type III-HE",
Packit Service e18529
		"MXM Type IV",
Packit Service e18529
		"MXM 3.0 Type A",
Packit Service e18529
		"MXM 3.0 Type B",
Packit Service e18529
		"PCI Express 2 SFF-8639",
Packit Service e18529
		"PCI Express 3 SFF-8639",
Packit Service e18529
		"PCI Express Mini 52-pin with bottom-side keep-outs",
Packit Service e18529
		"PCI Express Mini 52-pin without bottom-side keep-outs",
Packit Service e18529
		"PCI Express Mini 76-pin" /* 0x23 */
Packit Service e18529
	};
Packit Service 93af92
	static const char *type_0x30[] = {
Packit Service 93af92
		"CXL FLexbus 1.0" /* 0x30 */
Packit Service 93af92
	};
Packit Service e18529
	static const char *type_0xA0[] = {
Packit Service e18529
		"PC-98/C20", /* 0xA0 */
Packit Service e18529
		"PC-98/C24",
Packit Service e18529
		"PC-98/E",
Packit Service e18529
		"PC-98/Local Bus",
Packit Service e18529
		"PC-98/Card",
Packit Service e18529
		"PCI Express",
Packit Service e18529
		"PCI Express x1",
Packit Service e18529
		"PCI Express x2",
Packit Service e18529
		"PCI Express x4",
Packit Service e18529
		"PCI Express x8",
Packit Service e18529
		"PCI Express x16",
Packit Service e18529
		"PCI Express 2",
Packit Service e18529
		"PCI Express 2 x1",
Packit Service e18529
		"PCI Express 2 x2",
Packit Service e18529
		"PCI Express 2 x4",
Packit Service e18529
		"PCI Express 2 x8",
Packit Service e18529
		"PCI Express 2 x16",
Packit Service e18529
		"PCI Express 3",
Packit Service e18529
		"PCI Express 3 x1",
Packit Service e18529
		"PCI Express 3 x2",
Packit Service e18529
		"PCI Express 3 x4",
Packit Service e18529
		"PCI Express 3 x8",
Packit Service 93af92
		"PCI Express 3 x16",
Packit Service 93af92
		out_of_spec, /* 0xB7 */
Packit Service 93af92
		"PCI Express 4",
Packit Service 93af92
		"PCI Express 4 x1",
Packit Service 93af92
		"PCI Express 4 x2",
Packit Service 93af92
		"PCI Express 4 x4",
Packit Service 93af92
		"PCI Express 4 x8",
Packit Service 93af92
		"PCI Express 4 x16" /* 0xBD */
Packit Service e18529
	};
Packit Service e18529
	/*
Packit Service e18529
	 * Note to developers: when adding entries to these lists, check if
Packit Service e18529
	 * function dmi_slot_id below needs updating too.
Packit Service e18529
	 */
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x23)
Packit Service e18529
		return type[code - 0x01];
Packit Service 93af92
	if (code == 0x30)
Packit Service 93af92
		return type_0x30[code - 0x30];
Packit Service 93af92
	if (code >= 0xA0 && code <= 0xBD)
Packit Service e18529
		return type_0xA0[code - 0xA0];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_slot_bus_width(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.2 */
Packit Service e18529
	static const char *width[] = {
Packit Service e18529
		"", /* 0x01, "Other" */
Packit Service e18529
		"", /* "Unknown" */
Packit Service e18529
		"8-bit ",
Packit Service e18529
		"16-bit ",
Packit Service e18529
		"32-bit ",
Packit Service e18529
		"64-bit ",
Packit Service e18529
		"128-bit ",
Packit Service e18529
		"x1 ",
Packit Service e18529
		"x2 ",
Packit Service e18529
		"x4 ",
Packit Service e18529
		"x8 ",
Packit Service e18529
		"x12 ",
Packit Service e18529
		"x16 ",
Packit Service e18529
		"x32 " /* 0x0E */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0E)
Packit Service e18529
		return width[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_slot_current_usage(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.3 */
Packit Service e18529
	static const char *usage[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Available",
Packit Service e18529
		"In Use",
Packit Service e18529
		"Unavailable" /* 0x05 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x05)
Packit Service e18529
		return usage[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_slot_length(u8 code)
Packit Service e18529
{
Packit Service 0e1cc7
	/* 7.10.4 */
Packit Service e18529
	static const char *length[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Short",
Packit Service edd4d2
		"Long",
Packit Service edd4d2
		"2.5\" drive form factor",
Packit Service edd4d2
		"3.5\" drive form factor" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service edd4d2
	if (code >= 0x01 && code <= 0x06)
Packit Service e18529
		return length[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.5 */
Packit Service e18529
	switch (type)
Packit Service e18529
	{
Packit Service e18529
		case 0x04: /* MCA */
Packit Service e18529
			printf("%sID: %u\n", prefix, code1);
Packit Service e18529
			break;
Packit Service e18529
		case 0x05: /* EISA */
Packit Service e18529
			printf("%sID: %u\n", prefix, code1);
Packit Service e18529
			break;
Packit Service e18529
		case 0x06: /* PCI */
Packit Service e18529
		case 0x0E: /* PCI */
Packit Service e18529
		case 0x0F: /* AGP */
Packit Service e18529
		case 0x10: /* AGP */
Packit Service e18529
		case 0x11: /* AGP */
Packit Service e18529
		case 0x12: /* PCI-X */
Packit Service e18529
		case 0x13: /* AGP */
Packit Service e18529
		case 0x1F: /* PCI Express 2 */
Packit Service e18529
		case 0x20: /* PCI Express 3 */
Packit Service e18529
		case 0x21: /* PCI Express Mini */
Packit Service e18529
		case 0x22: /* PCI Express Mini */
Packit Service e18529
		case 0x23: /* PCI Express Mini */
Packit Service e18529
		case 0xA5: /* PCI Express */
Packit Service e18529
		case 0xA6: /* PCI Express */
Packit Service e18529
		case 0xA7: /* PCI Express */
Packit Service e18529
		case 0xA8: /* PCI Express */
Packit Service e18529
		case 0xA9: /* PCI Express */
Packit Service e18529
		case 0xAA: /* PCI Express */
Packit Service e18529
		case 0xAB: /* PCI Express 2 */
Packit Service e18529
		case 0xAC: /* PCI Express 2 */
Packit Service e18529
		case 0xAD: /* PCI Express 2 */
Packit Service e18529
		case 0xAE: /* PCI Express 2 */
Packit Service e18529
		case 0xAF: /* PCI Express 2 */
Packit Service e18529
		case 0xB0: /* PCI Express 2 */
Packit Service e18529
		case 0xB1: /* PCI Express 3 */
Packit Service e18529
		case 0xB2: /* PCI Express 3 */
Packit Service e18529
		case 0xB3: /* PCI Express 3 */
Packit Service e18529
		case 0xB4: /* PCI Express 3 */
Packit Service e18529
		case 0xB5: /* PCI Express 3 */
Packit Service e18529
		case 0xB6: /* PCI Express 3 */
Packit Service 93af92
		case 0xB8: /* PCI Express 4 */
Packit Service 93af92
		case 0xB9: /* PCI Express 4 */
Packit Service 93af92
		case 0xBA: /* PCI Express 4 */
Packit Service 93af92
		case 0xBB: /* PCI Express 4 */
Packit Service 93af92
		case 0xBC: /* PCI Express 4 */
Packit Service 93af92
		case 0xBD: /* PCI Express 4 */
Packit Service e18529
			printf("%sID: %u\n", prefix, code1);
Packit Service e18529
			break;
Packit Service e18529
		case 0x07: /* PCMCIA */
Packit Service e18529
			printf("%sID: Adapter %u, Socket %u\n", prefix, code1, code2);
Packit Service e18529
			break;
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_slot_characteristics(u8 code1, u8 code2, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.6 */
Packit Service e18529
	static const char *characteristics1[] = {
Packit Service e18529
		"5.0 V is provided", /* 1 */
Packit Service e18529
		"3.3 V is provided",
Packit Service e18529
		"Opening is shared",
Packit Service e18529
		"PC Card-16 is supported",
Packit Service e18529
		"Cardbus is supported",
Packit Service e18529
		"Zoom Video is supported",
Packit Service e18529
		"Modem ring resume is supported" /* 7 */
Packit Service e18529
	};
Packit Service e18529
	/* 7.10.7 */
Packit Service e18529
	static const char *characteristics2[] = {
Packit Service e18529
		"PME signal is supported", /* 0 */
Packit Service e18529
		"Hot-plug devices are supported",
Packit Service e18529
		"SMBus signal is supported",
Packit Service e18529
		"PCIe slot bifurcation is supported" /* 3 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code1 & (1 << 0))
Packit Service e18529
		printf(" Unknown\n");
Packit Service e18529
	else if ((code1 & 0xFE) == 0 && (code2 & 0x07) == 0)
Packit Service e18529
		printf(" None\n");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		printf("\n");
Packit Service e18529
		for (i = 1; i <= 7; i++)
Packit Service e18529
			if (code1 & (1 << i))
Packit Service e18529
				printf("%s%s\n", prefix, characteristics1[i - 1]);
Packit Service e18529
		for (i = 0; i <= 3; i++)
Packit Service e18529
			if (code2 & (1 << i))
Packit Service e18529
				printf("%s%s\n", prefix, characteristics2[i]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.8 */
Packit Service e18529
	if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF))
Packit Service e18529
		printf("%sBus Address: %04x:%02x:%02x.%x\n",
Packit Service e18529
		       prefix, code1, code2, code3 >> 3, code3 & 0x7);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.11 On Board Devices Information (Type 10)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_on_board_devices_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.11.1 and 7.42.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Video",
Packit Service e18529
		"SCSI Controller",
Packit Service e18529
		"Ethernet",
Packit Service e18529
		"Token Ring",
Packit Service e18529
		"Sound",
Packit Service e18529
		"PATA Controller",
Packit Service e18529
		"SATA Controller",
Packit Service e18529
		"SAS Controller" /* 0x0A */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0A)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_on_board_devices(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	u8 *p = h->data + 4;
Packit Service e18529
	u8 count = (h->length - 0x04) / 2;
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Service e18529
		if (count == 1)
Packit Service e18529
			printf("%sOn Board Device Information\n",
Packit Service e18529
				prefix);
Packit Service e18529
		else
Packit Service e18529
			printf("%sOn Board Device %d Information\n",
Packit Service e18529
				prefix, i + 1);
Packit Service e18529
		printf("%s\tType: %s\n",
Packit Service e18529
			prefix, dmi_on_board_devices_type(p[2 * i] & 0x7F));
Packit Service e18529
		printf("%s\tStatus: %s\n",
Packit Service e18529
			prefix, p[2 * i] & 0x80 ? "Enabled" : "Disabled");
Packit Service e18529
		printf("%s\tDescription: %s\n",
Packit Service e18529
			prefix, dmi_string(h, p[2 * i + 1]));
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.12 OEM Strings (Type 11)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_oem_strings(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	u8 *p = h->data + 4;
Packit Service e18529
	u8 count = p[0x00];
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 1; i <= count; i++)
Packit Service e18529
		printf("%sString %d: %s\n",
Packit Service e18529
			prefix, i, dmi_string(h, i));
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.13 System Configuration Options (Type 12)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_system_configuration_options(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	u8 *p = h->data + 4;
Packit Service e18529
	u8 count = p[0x00];
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 1; i <= count; i++)
Packit Service e18529
		printf("%sOption %d: %s\n",
Packit Service e18529
			prefix, i, dmi_string(h, i));
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.14 BIOS Language Information (Type 13)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_bios_languages(const struct dmi_header *h, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	u8 *p = h->data + 4;
Packit Service e18529
	u8 count = p[0x00];
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 1; i <= count; i++)
Packit Service e18529
		printf("%s%s\n",
Packit Service e18529
			prefix, dmi_string(h, i));
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_bios_language_format(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code & 0x01)
Packit Service e18529
		return "Abbreviated";
Packit Service e18529
	else
Packit Service e18529
		return "Long";
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.15 Group Associations (Type 14)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_group_associations_items(u8 count, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Service e18529
		printf("%s0x%04X (%s)\n",
Packit Service e18529
			prefix, WORD(p + 3 * i + 1),
Packit Service e18529
			dmi_smbios_structure_type(p[3 * i]));
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.16 System Event Log (Type 15)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_event_log_method(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *method[] = {
Packit Service e18529
		"Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */
Packit Service e18529
		"Indexed I/O, two 8-bit index ports, one 8-bit data port",
Packit Service e18529
		"Indexed I/O, one 16-bit index port, one 8-bit data port",
Packit Service e18529
		"Memory-mapped physical 32-bit address",
Packit Service e18529
		"General-purpose non-volatile data functions" /* 0x04 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x04)
Packit Service e18529
		return method[code];
Packit Service e18529
	if (code >= 0x80)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_event_log_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *valid[] = {
Packit Service e18529
		"Invalid", /* 0 */
Packit Service e18529
		"Valid" /* 1 */
Packit Service e18529
	};
Packit Service e18529
	static const char *full[] = {
Packit Service e18529
		"Not Full", /* 0 */
Packit Service e18529
		"Full" /* 1 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	printf(" %s, %s",
Packit Service e18529
		valid[(code >> 0) & 1], full[(code >> 1) & 1]);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_event_log_address(u8 method, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	/* 7.16.3 */
Packit Service e18529
	switch (method)
Packit Service e18529
	{
Packit Service e18529
		case 0x00:
Packit Service e18529
		case 0x01:
Packit Service e18529
		case 0x02:
Packit Service e18529
			printf(" Index 0x%04X, Data 0x%04X", WORD(p), WORD(p + 2));
Packit Service e18529
			break;
Packit Service e18529
		case 0x03:
Packit Service e18529
			printf(" 0x%08X", DWORD(p));
Packit Service e18529
			break;
Packit Service e18529
		case 0x04:
Packit Service e18529
			printf(" 0x%04X", WORD(p));
Packit Service e18529
			break;
Packit Service e18529
		default:
Packit Service e18529
			printf(" Unknown");
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_event_log_header_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"No Header", /* 0x00 */
Packit Service e18529
		"Type 1" /* 0x01 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x01)
Packit Service e18529
		return type[code];
Packit Service e18529
	if (code >= 0x80)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_event_log_descriptor_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.16.6.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		NULL, /* 0x00 */
Packit Service e18529
		"Single-bit ECC memory error",
Packit Service e18529
		"Multi-bit ECC memory error",
Packit Service e18529
		"Parity memory error",
Packit Service e18529
		"Bus timeout",
Packit Service e18529
		"I/O channel block",
Packit Service e18529
		"Software NMI",
Packit Service e18529
		"POST memory resize",
Packit Service e18529
		"POST error",
Packit Service e18529
		"PCI parity error",
Packit Service e18529
		"PCI system error",
Packit Service e18529
		"CPU failure",
Packit Service e18529
		"EISA failsafe timer timeout",
Packit Service e18529
		"Correctable memory log disabled",
Packit Service e18529
		"Logging disabled",
Packit Service e18529
		NULL, /* 0x0F */
Packit Service e18529
		"System limit exceeded",
Packit Service e18529
		"Asynchronous hardware timer expired",
Packit Service e18529
		"System configuration information",
Packit Service e18529
		"Hard disk information",
Packit Service e18529
		"System reconfigured",
Packit Service e18529
		"Uncorrectable CPU-complex error",
Packit Service e18529
		"Log area reset/cleared",
Packit Service e18529
		"System boot" /* 0x17 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x17 && type[code] != NULL)
Packit Service e18529
		return type[code];
Packit Service e18529
	if (code >= 0x80 && code <= 0xFE)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	if (code == 0xFF)
Packit Service e18529
		return "End of log";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_event_log_descriptor_format(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.16.6.2 */
Packit Service e18529
	static const char *format[] = {
Packit Service e18529
		"None", /* 0x00 */
Packit Service e18529
		"Handle",
Packit Service e18529
		"Multiple-event",
Packit Service e18529
		"Multiple-event handle",
Packit Service e18529
		"POST results bitmap",
Packit Service e18529
		"System management",
Packit Service e18529
		"Multiple-event system management" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x06)
Packit Service e18529
		return format[code];
Packit Service e18529
	if (code >= 0x80)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_event_log_descriptors(u8 count, u8 len, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	/* 7.16.1 */
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Service e18529
		if (len >= 0x02)
Packit Service e18529
		{
Packit Service e18529
			printf("%sDescriptor %u: %s\n",
Packit Service e18529
				prefix, i + 1, dmi_event_log_descriptor_type(p[i * len]));
Packit Service e18529
			printf("%sData Format %u: %s\n",
Packit Service e18529
				prefix, i + 1, dmi_event_log_descriptor_format(p[i * len + 1]));
Packit Service e18529
		}
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.17 Physical Memory Array (Type 16)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_array_location(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.17.1 */
Packit Service e18529
	static const char *location[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"System Board Or Motherboard",
Packit Service e18529
		"ISA Add-on Card",
Packit Service e18529
		"EISA Add-on Card",
Packit Service e18529
		"PCI Add-on Card",
Packit Service e18529
		"MCA Add-on Card",
Packit Service e18529
		"PCMCIA Add-on Card",
Packit Service e18529
		"Proprietary Add-on Card",
Packit Service e18529
		"NuBus" /* 0x0A */
Packit Service e18529
	};
Packit Service e18529
	static const char *location_0xA0[] = {
Packit Service e18529
		"PC-98/C20 Add-on Card", /* 0xA0 */
Packit Service e18529
		"PC-98/C24 Add-on Card",
Packit Service e18529
		"PC-98/E Add-on Card",
Packit Service 93af92
		"PC-98/Local Bus Add-on Card",
Packit Service 93af92
		"CXL Flexbus 1.0" /* 0xA4 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0A)
Packit Service e18529
		return location[code - 0x01];
Packit Service 93af92
	if (code >= 0xA0 && code <= 0xA4)
Packit Service e18529
		return location_0xA0[code - 0xA0];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_array_use(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.17.2 */
Packit Service e18529
	static const char *use[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"System Memory",
Packit Service e18529
		"Video Memory",
Packit Service e18529
		"Flash Memory",
Packit Service e18529
		"Non-volatile RAM",
Packit Service e18529
		"Cache Memory" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x07)
Packit Service e18529
		return use[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_array_ec_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.17.3 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"None",
Packit Service e18529
		"Parity",
Packit Service e18529
		"Single-bit ECC",
Packit Service e18529
		"Multi-bit ECC",
Packit Service e18529
		"CRC" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x07)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_array_error_handle(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFE)
Packit Service e18529
		printf(" Not Provided");
Packit Service e18529
	else if (code == 0xFFFF)
Packit Service e18529
		printf(" No Error");
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%04X", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.18 Memory Device (Type 17)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_width(u16 code)
Packit Service e18529
{
Packit Service e18529
	/*
Packit Service e18529
	 * If no memory module is present, width may be 0
Packit Service e18529
	 */
Packit Service e18529
	if (code == 0xFFFF || code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u bits", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_size(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" No Module Installed");
Packit Service e18529
	else if (code == 0xFFFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service 3dd3ee
		u64 s = { .l = code & 0x7FFF };
Packit Service 3dd3ee
		if (!(code & 0x8000))
Packit Service 3dd3ee
			s.l <<= 10;
Packit Service 3dd3ee
		dmi_print_memory_size(s, 1);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_extended_size(u32 code)
Packit Service e18529
{
Packit Service e18529
	code &= 0x7FFFFFFFUL;
Packit Service e18529
Packit Service e18529
	/*
Packit Service e18529
	 * Use the greatest unit for which the exact value can be displayed
Packit Service e18529
	 * as an integer without rounding
Packit Service e18529
	 */
Packit Service e18529
	if (code & 0x3FFUL)
Packit Service e18529
		printf(" %lu MB", (unsigned long)code);
Packit Service e18529
	else if (code & 0xFFC00UL)
Packit Service e18529
		printf(" %lu GB", (unsigned long)code >> 10);
Packit Service e18529
	else
Packit Service e18529
		printf(" %lu TB", (unsigned long)code >> 20);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_voltage_value(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_device_form_factor(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.1 */
Packit Service e18529
	static const char *form_factor[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"SIMM",
Packit Service e18529
		"SIP",
Packit Service e18529
		"Chip",
Packit Service e18529
		"DIP",
Packit Service e18529
		"ZIP",
Packit Service e18529
		"Proprietary Card",
Packit Service e18529
		"DIMM",
Packit Service e18529
		"TSOP",
Packit Service e18529
		"Row Of Chips",
Packit Service e18529
		"RIMM",
Packit Service e18529
		"SODIMM",
Packit Service e18529
		"SRIMM",
Packit Service 93af92
		"FB-DIMM",
Packit Service 93af92
		"Die" /* 0x10 */
Packit Service e18529
	};
Packit Service e18529
Packit Service 93af92
	if (code >= 0x01 && code <= 0x10)
Packit Service e18529
		return form_factor[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_set(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else if (code == 0xFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_device_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"DRAM",
Packit Service e18529
		"EDRAM",
Packit Service e18529
		"VRAM",
Packit Service e18529
		"SRAM",
Packit Service e18529
		"RAM",
Packit Service e18529
		"ROM",
Packit Service e18529
		"Flash",
Packit Service e18529
		"EEPROM",
Packit Service e18529
		"FEPROM",
Packit Service e18529
		"EPROM",
Packit Service e18529
		"CDRAM",
Packit Service e18529
		"3DRAM",
Packit Service e18529
		"SDRAM",
Packit Service e18529
		"SGRAM",
Packit Service e18529
		"RDRAM",
Packit Service e18529
		"DDR",
Packit Service e18529
		"DDR2",
Packit Service e18529
		"DDR2 FB-DIMM",
Packit Service e18529
		"Reserved",
Packit Service e18529
		"Reserved",
Packit Service e18529
		"Reserved",
Packit Service e18529
		"DDR3",
Packit Service e18529
		"FBD2",
Packit Service e18529
		"DDR4",
Packit Service e18529
		"LPDDR",
Packit Service e18529
		"LPDDR2",
Packit Service e18529
		"LPDDR3",
Packit Service 9ec2f7
		"LPDDR4",
Packit Service 93af92
		"Logical non-volatile device",
Packit Service 93af92
		"HBM",
Packit Service 93af92
		"HBM2" /* 0x21 */
Packit Service e18529
	};
Packit Service e18529
Packit Service 93af92
	if (code >= 0x01 && code <= 0x21)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_type_detail(u16 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.3 */
Packit Service e18529
	static const char *detail[] = {
Packit Service e18529
		"Other", /* 1 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Fast-paged",
Packit Service e18529
		"Static Column",
Packit Service e18529
		"Pseudo-static",
Packit Service e18529
		"RAMBus",
Packit Service e18529
		"Synchronous",
Packit Service e18529
		"CMOS",
Packit Service e18529
		"EDO",
Packit Service e18529
		"Window DRAM",
Packit Service e18529
		"Cache DRAM",
Packit Service e18529
		"Non-Volatile",
Packit Service e18529
		"Registered (Buffered)",
Packit Service e18529
		"Unbuffered (Unregistered)",
Packit Service e18529
		"LRDIMM"  /* 15 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0xFFFE) == 0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		for (i = 1; i <= 15; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf(" %s", detail[i - 1]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_device_speed(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u MT/s", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_technology(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.6 */
Packit Service e18529
	static const char * const technology[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"DRAM",
Packit Service e18529
		"NVDIMM-N",
Packit Service e18529
		"NVDIMM-F",
Packit Service e18529
		"NVDIMM-P",
Packit Service 93af92
		"Intel Optane DC persistent memory" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
	if (code >= 0x01 && code <= 0x07)
Packit Service e18529
		printf(" %s", technology[code - 0x01]);
Packit Service e18529
	else
Packit Service e18529
		printf(" %s", out_of_spec);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_operating_mode_capability(u16 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.7 */
Packit Service e18529
	static const char * const mode[] = {
Packit Service e18529
		"Other", /* 1 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Volatile memory",
Packit Service e18529
		"Byte-accessible persistent memory",
Packit Service e18529
		"Block-accessible persistent memory" /* 5 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if ((code & 0xFFFE) == 0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else {
Packit Service e18529
		int i;
Packit Service e18529
Packit Service e18529
		for (i = 1; i <= 5; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Service e18529
				printf(" %s", mode[i - 1]);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_manufacturer_id(u16 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.8 */
Packit Service e18529
	/* 7.18.10 */
Packit Service e18529
	/* LSB is 7-bit Odd Parity number of continuation codes */
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" Bank %d, Hex 0x%02X", (code & 0x7F) + 1, code >> 8);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_product_id(u16 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.9 */
Packit Service e18529
	/* 7.18.11 */
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%04X", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_size(u64 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.12 */
Packit Service e18529
	/* 7.18.13 */
Packit Service e18529
	if (code.h == 0xFFFFFFFF && code.l == 0xFFFFFFFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else if (code.h == 0x0 && code.l == 0x0)
Packit Service e18529
		printf(" None");
Packit Service e18529
	else
Packit Service e18529
		dmi_print_memory_size(code, 0);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.19 32-bit Memory Error Information (Type 18)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_error_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.19.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"OK",
Packit Service e18529
		"Bad Read",
Packit Service e18529
		"Parity Error",
Packit Service e18529
		"Single-bit Error",
Packit Service e18529
		"Double-bit Error",
Packit Service e18529
		"Multi-bit Error",
Packit Service e18529
		"Nibble Error",
Packit Service e18529
		"Checksum Error",
Packit Service e18529
		"CRC Error",
Packit Service e18529
		"Corrected Single-bit Error",
Packit Service e18529
		"Corrected Error",
Packit Service e18529
		"Uncorrectable Error" /* 0x0E */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0E)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_error_granularity(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.19.2 */
Packit Service e18529
	static const char *granularity[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Device Level",
Packit Service e18529
		"Memory Partition Level" /* 0x04 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x04)
Packit Service e18529
		return granularity[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_error_operation(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.19.3 */
Packit Service e18529
	static const char *operation[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Read",
Packit Service e18529
		"Write",
Packit Service e18529
		"Partial Write" /* 0x05 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x05)
Packit Service e18529
		return operation[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_error_syndrome(u32 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x00000000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%08X", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_32bit_memory_error_address(u32 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x80000000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%08X", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.20 Memory Array Mapped Address (Type 19)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_mapped_address_size(u32 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Invalid");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		u64 size;
Packit Service e18529
Packit Service e18529
		size.h = 0;
Packit Service e18529
		size.l = code;
Packit Service e18529
		dmi_print_memory_size(size, 1);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_mapped_address_extended_size(u64 start, u64 end)
Packit Service e18529
{
Packit Service e18529
	if (start.h == end.h && start.l == end.l)
Packit Service e18529
		printf(" Invalid");
Packit Service e18529
	else
Packit Service e18529
		dmi_print_memory_size(u64_range(start, end), 0);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.21 Memory Device Mapped Address (Type 20)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_mapped_address_row_position(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" %s", out_of_spec);
Packit Service e18529
	else if (code == 0xFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_mapped_address_interleave_position(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	if (code != 0)
Packit Service e18529
	{
Packit Service e18529
		printf("%sInterleave Position:", prefix);
Packit Service e18529
		if (code == 0xFF)
Packit Service e18529
			printf(" Unknown");
Packit Service e18529
		else
Packit Service e18529
			printf(" %u", code);
Packit Service e18529
		printf("\n");
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_mapped_address_interleaved_data_depth(u8 code, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	if (code != 0)
Packit Service e18529
	{
Packit Service e18529
		printf("%sInterleaved Data Depth:", prefix);
Packit Service e18529
		if (code == 0xFF)
Packit Service e18529
			printf(" Unknown");
Packit Service e18529
		else
Packit Service e18529
			printf(" %u", code);
Packit Service e18529
		printf("\n");
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.22 Built-in Pointing Device (Type 21)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_pointing_device_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.22.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Mouse",
Packit Service e18529
		"Track Ball",
Packit Service e18529
		"Track Point",
Packit Service e18529
		"Glide Point",
Packit Service e18529
		"Touch Pad",
Packit Service e18529
		"Touch Screen",
Packit Service e18529
		"Optical Sensor" /* 0x09 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x09)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_pointing_device_interface(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.22.2 */
Packit Service e18529
	static const char *interface[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Serial",
Packit Service e18529
		"PS/2",
Packit Service e18529
		"Infrared",
Packit Service e18529
		"HIP-HIL",
Packit Service e18529
		"Bus Mouse",
Packit Service e18529
		"ADB (Apple Desktop Bus)" /* 0x08 */
Packit Service e18529
	};
Packit Service e18529
	static const char *interface_0xA0[] = {
Packit Service e18529
		"Bus Mouse DB-9", /* 0xA0 */
Packit Service e18529
		"Bus Mouse Micro DIN",
Packit Service e18529
		"USB" /* 0xA2 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x08)
Packit Service e18529
		return interface[code - 0x01];
Packit Service e18529
	if (code >= 0xA0 && code <= 0xA2)
Packit Service e18529
		return interface_0xA0[code - 0xA0];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.23 Portable Battery (Type 22)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_battery_chemistry(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.23.1 */
Packit Service e18529
	static const char *chemistry[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Lead Acid",
Packit Service e18529
		"Nickel Cadmium",
Packit Service e18529
		"Nickel Metal Hydride",
Packit Service e18529
		"Lithium Ion",
Packit Service e18529
		"Zinc Air",
Packit Service e18529
		"Lithium Polymer" /* 0x08 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x08)
Packit Service e18529
		return chemistry[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_battery_capacity(u16 code, u8 multiplier)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u mWh", code * multiplier);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_battery_voltage(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u mV", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_battery_maximum_error(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u%%", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.24 System Reset (Type 23)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
/* code is assumed to be a 2-bit value */
Packit Service e18529
static const char *dmi_system_reset_boot_option(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *option[] = {
Packit Service e18529
		out_of_spec, /* 0x0 */
Packit Service e18529
		"Operating System", /* 0x1 */
Packit Service e18529
		"System Utilities",
Packit Service e18529
		"Do Not Reboot" /* 0x3 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return option[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_system_reset_count(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_system_reset_timer(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u min", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.25 Hardware Security (Type 24)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_hardware_security_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *status[] = {
Packit Service e18529
		"Disabled", /* 0x00 */
Packit Service e18529
		"Enabled",
Packit Service e18529
		"Not Implemented",
Packit Service e18529
		"Unknown" /* 0x03 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return status[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.26 System Power Controls (Type 25)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_power_controls_power_on(const u8 *p)
Packit Service e18529
{
Packit Service e18529
	/* 7.26.1 */
Packit Service e18529
	if (dmi_bcd_range(p[0], 0x01, 0x12))
Packit Service e18529
		printf(" %02X", p[0]);
Packit Service e18529
	else
Packit Service e18529
		printf(" *");
Packit Service e18529
	if (dmi_bcd_range(p[1], 0x01, 0x31))
Packit Service e18529
		printf("-%02X", p[1]);
Packit Service e18529
	else
Packit Service e18529
		printf("-*");
Packit Service e18529
	if (dmi_bcd_range(p[2], 0x00, 0x23))
Packit Service e18529
		printf(" %02X", p[2]);
Packit Service e18529
	else
Packit Service e18529
		printf(" *");
Packit Service e18529
	if (dmi_bcd_range(p[3], 0x00, 0x59))
Packit Service e18529
		printf(":%02X", p[3]);
Packit Service e18529
	else
Packit Service e18529
		printf(":*");
Packit Service e18529
	if (dmi_bcd_range(p[4], 0x00, 0x59))
Packit Service e18529
		printf(":%02X", p[4]);
Packit Service e18529
	else
Packit Service e18529
		printf(":*");
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.27 Voltage Probe (Type 26)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_voltage_probe_location(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.27.1 */
Packit Service e18529
	static const char *location[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Processor",
Packit Service e18529
		"Disk",
Packit Service e18529
		"Peripheral Bay",
Packit Service e18529
		"System Management Module",
Packit Service e18529
		"Motherboard",
Packit Service e18529
		"Memory Module",
Packit Service e18529
		"Processor Module",
Packit Service e18529
		"Power Unit",
Packit Service e18529
		"Add-in Card" /* 0x0B */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0B)
Packit Service e18529
		return location[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_probe_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.27.1 */
Packit Service e18529
	static const char *status[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"OK",
Packit Service e18529
		"Non-critical",
Packit Service e18529
		"Critical",
Packit Service e18529
		"Non-recoverable" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x06)
Packit Service e18529
		return status[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_voltage_probe_value(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.3f V", (float)(i16)code / 1000);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_voltage_probe_resolution(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.1f mV", (float)code / 10);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_probe_accuracy(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.2f%%", (float)code / 100);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.28 Cooling Device (Type 27)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_cooling_device_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.28.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Fan",
Packit Service e18529
		"Centrifugal Blower",
Packit Service e18529
		"Chip Fan",
Packit Service e18529
		"Cabinet Fan",
Packit Service e18529
		"Power Supply Fan",
Packit Service e18529
		"Heat Pipe",
Packit Service e18529
		"Integrated Refrigeration" /* 0x09 */
Packit Service e18529
	};
Packit Service e18529
	static const char *type_0x10[] = {
Packit Service e18529
		"Active Cooling", /* 0x10 */
Packit Service e18529
		"Passive Cooling" /* 0x11 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x09)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	if (code >= 0x10 && code <= 0x11)
Packit Service e18529
		return type_0x10[code - 0x10];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_cooling_device_speed(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown Or Non-rotating");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u rpm", code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.29 Temperature Probe (Type 28)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_temperature_probe_location(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.29.1 */
Packit Service e18529
	static const char *location[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Processor",
Packit Service e18529
		"Disk",
Packit Service e18529
		"Peripheral Bay",
Packit Service e18529
		"System Management Module",
Packit Service e18529
		"Motherboard",
Packit Service e18529
		"Memory Module",
Packit Service e18529
		"Processor Module",
Packit Service e18529
		"Power Unit",
Packit Service e18529
		"Add-in Card",
Packit Service e18529
		"Front Panel Board",
Packit Service e18529
		"Back Panel Board",
Packit Service e18529
		"Power System Board",
Packit Service e18529
		"Drive Back Plane" /* 0x0F */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0F)
Packit Service e18529
		return location[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_temperature_probe_value(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.1f deg C", (float)(i16)code / 10);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_temperature_probe_resolution(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.3f deg C", (float)code / 1000);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.30 Electrical Current Probe (Type 29)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_current_probe_value(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.3f A", (float)(i16)code / 1000);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_current_probe_resolution(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %.1f mA", (float)code / 10);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.33 System Boot Information (Type 32)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_system_boot_status(u8 code)
Packit Service e18529
{
Packit Service e18529
	static const char *status[] = {
Packit Service e18529
		"No errors detected", /* 0 */
Packit Service e18529
		"No bootable media",
Packit Service e18529
		"Operating system failed to load",
Packit Service e18529
		"Firmware-detected hardware failure",
Packit Service e18529
		"Operating system-detected hardware failure",
Packit Service e18529
		"User-requested boot",
Packit Service e18529
		"System security violation",
Packit Service e18529
		"Previously-requested image",
Packit Service e18529
		"System watchdog timer expired" /* 8 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 8)
Packit Service e18529
		return status[code];
Packit Service e18529
	if (code >= 128 && code <= 191)
Packit Service e18529
		return "OEM-specific";
Packit Service e18529
	if (code >= 192)
Packit Service e18529
		return "Product-specific";
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.34 64-bit Memory Error Information (Type 33)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_64bit_memory_error_address(u64 code)
Packit Service e18529
{
Packit Service e18529
	if (code.h == 0x80000000 && code.l == 0x00000000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" 0x%08X%08X", code.h, code.l);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.35 Management Device (Type 34)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * Several boards have a bug where some type 34 structures have their
Packit Service e18529
 * length incorrectly set to 0x10 instead of 0x0B. This causes the
Packit Service e18529
 * first 5 characters of the device name to be trimmed. It's easy to
Packit Service e18529
 * check and fix, so do it, but warn.
Packit Service e18529
 */
Packit Service e18529
static void dmi_fixup_type_34(struct dmi_header *h, int display)
Packit Service e18529
{
Packit Service e18529
	u8 *p = h->data;
Packit Service e18529
Packit Service e18529
 	/* Make sure the hidden data is ASCII only */
Packit Service e18529
	if (h->length == 0x10
Packit Service e18529
	 && is_printable(p + 0x0B, 0x10 - 0x0B))
Packit Service e18529
	{
Packit Service e18529
		if (!(opt.flags & FLAG_QUIET) && display)
Packit Service e18529
			fprintf(stderr,
Packit Service e18529
				"Invalid entry length (%u). Fixed up to %u.\n",
Packit Service e18529
				0x10, 0x0B);
Packit Service e18529
		h->length = 0x0B;
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_management_device_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.35.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"LM75",
Packit Service e18529
		"LM78",
Packit Service e18529
		"LM79",
Packit Service e18529
		"LM80",
Packit Service e18529
		"LM81",
Packit Service e18529
		"ADM9240",
Packit Service e18529
		"DS1780",
Packit Service e18529
		"MAX1617",
Packit Service e18529
		"GL518SM",
Packit Service e18529
		"W83781D",
Packit Service e18529
		"HT82H791" /* 0x0D */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x0D)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_management_device_address_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.35.2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"I/O Port",
Packit Service e18529
		"Memory",
Packit Service e18529
		"SMBus" /* 0x05 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x05)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.38 Memory Channel (Type 37)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_memory_channel_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.38.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"RamBus",
Packit Service e18529
		"SyncLink" /* 0x04 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x04)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_memory_channel_devices(u8 count, const u8 *p, const char *prefix)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 1; i <= count; i++)
Packit Service e18529
	{
Packit Service e18529
		printf("%sDevice %u Load: %u\n",
Packit Service e18529
			prefix, i, p[3 * i]);
Packit Service e18529
		if (!(opt.flags & FLAG_QUIET))
Packit Service e18529
			printf("%sDevice %u Handle: 0x%04X\n",
Packit Service e18529
				prefix, i, WORD(p + 3 * i + 1));
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.39 IPMI Device Information (Type 38)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static const char *dmi_ipmi_interface_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.39.1 and IPMI 2.0, appendix C1, table C1-2 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Unknown", /* 0x00 */
Packit Service e18529
		"KCS (Keyboard Control Style)",
Packit Service e18529
		"SMIC (Server Management Interface Chip)",
Packit Service e18529
		"BT (Block Transfer)",
Packit Service e18529
		"SSIF (SMBus System Interface)" /* 0x04 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code <= 0x04)
Packit Service e18529
		return type[code];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static void dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb)
Packit Service e18529
{
Packit Service e18529
	if (type == 0x04) /* SSIF */
Packit Service e18529
	{
Packit Service e18529
		printf("0x%02X (SMBus)", (*p) >> 1);
Packit Service e18529
	}
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		u64 address = QWORD(p);
Packit Service e18529
		printf("0x%08X%08X (%s)", address.h, (address.l & ~1) | lsb,
Packit Service e18529
			address.l & 1 ? "I/O" : "Memory-mapped");
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/* code is assumed to be a 2-bit value */
Packit Service e18529
static const char *dmi_ipmi_register_spacing(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* IPMI 2.0, appendix C1, table C1-1 */
Packit Service e18529
	static const char *spacing[] = {
Packit Service e18529
		"Successive Byte Boundaries", /* 0x00 */
Packit Service e18529
		"32-bit Boundaries",
Packit Service e18529
		"16-byte Boundaries", /* 0x02 */
Packit Service e18529
		out_of_spec /* 0x03 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	return spacing[code];
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
/*
Packit Service e18529
 * 7.40 System Power Supply (Type 39)
Packit Service e18529
 */
Packit Service e18529
Packit Service e18529
static void dmi_power_supply_power(u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Service e18529
		printf(" Unknown");
Packit Service e18529
	else
Packit Service e18529
		printf(" %u W", (unsigned int)code);
Packit Service e18529
}
Packit Service e18529
Packit Service e18529
static const char *dmi_power_supply_type(u8 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.40.1 */
Packit Service e18529
	static const char *type[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Linear",
Packit Service e18529
		"Switching",
Packit Service e18529
		"Battery",
Packit Service e18529
		"UPS",
Packit Service e18529
		"Converter",
Packit Service e18529
		"Regulator" /* 0x08 */
Packit Service e18529
	};
Packit Service e18529
Packit Service e18529
	if (code >= 0x01 && code <= 0x08)
Packit Service e18529
		return type[code - 0x01];
Packit Service e18529
	return out_of_spec;
Packit Service e18529
}