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 Bot e9532b
 *   Copyright (C) 2002-2020 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 Bot 1d6d0f
#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 Bot 613a53
#include "dmioutput.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 Bot fd6691
/* Replace non-ASCII characters with dots */
Packit Bot fd6691
static void ascii_filter(char *bp, size_t len)
Packit Service 0d123c
{
Packit Bot fd6691
	size_t i;
Packit Bot a901f8
Packit Bot fd6691
	for (i = 0; i < len; i++)
Packit Bot fd6691
		if (bp[i] < 32 || bp[i] == 127)
Packit Bot fd6691
			bp[i] = '.';
Packit Bot fd6691
}
Packit Bot fd6691
Packit Bot fd6691
static char *_dmi_string(const struct dmi_header *dm, u8 s, int filter)
Packit Bot fd6691
{
Packit Bot fd6691
	char *bp = (char *)dm->data;
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 Bot fd6691
		return NULL;
Packit Service 622062
Packit Bot fd6691
	if (filter)
Packit Bot fd6691
		ascii_filter(bp, strlen(bp));
Packit Bot fd6691
Packit Bot fd6691
	return bp;
Packit Bot fd6691
}
Packit Bot fd6691
Packit Bot fd6691
const char *dmi_string(const struct dmi_header *dm, u8 s)
Packit Bot fd6691
{
Packit Bot fd6691
	char *bp;
Packit Bot fd6691
Packit Bot fd6691
	if (s == 0)
Packit Bot fd6691
		return "Not Specified";
Packit Bot fd6691
Packit Bot fd6691
	bp = _dmi_string(dm, s, 1);
Packit Bot fd6691
	if (bp == NULL)
Packit Bot fd6691
		return bad_index;
Packit Bot a901f8
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 Bot bc323c
static void dmi_dump(const struct dmi_header *h)
Packit Service e18529
{
Packit Bot bc323c
	static char raw_data[48];
Packit Service e18529
	int row, i;
Packit Bot bc323c
	unsigned int off;
Packit Bot fd6691
	char *s;
Packit Service e18529
Packit Bot bc323c
	pr_list_start("Header and Data", NULL);
Packit Service e18529
	for (row = 0; row < ((h->length - 1) >> 4) + 1; row++)
Packit Service e18529
	{
Packit Bot bc323c
		off = 0;
Packit Service e18529
		for (i = 0; i < 16 && i < h->length - (row << 4); i++)
Packit Bot bc323c
			off += sprintf(raw_data + off, i ? " %02X" : "%02X",
Packit Service e18529
			       (h->data)[(row << 4) + i]);
Packit Bot bc323c
		pr_list_item(raw_data);
Packit Service e18529
	}
Packit Bot bc323c
	pr_list_end();
Packit Service e18529
Packit Service e18529
	if ((h->data)[h->length] || (h->data)[h->length + 1])
Packit Service e18529
	{
Packit Bot bc323c
		pr_list_start("Strings", NULL);
Packit Service e18529
		i = 1;
Packit Bot fd6691
		while ((s = _dmi_string(h, i++, !(opt.flags & FLAG_DUMP))))
Packit Service e18529
		{
Packit Service e18529
			if (opt.flags & FLAG_DUMP)
Packit Service e18529
			{
Packit Service e18529
				int j, l = strlen(s) + 1;
Packit Bot bc323c
Packit Service e18529
				for (row = 0; row < ((l - 1) >> 4) + 1; row++)
Packit Service e18529
				{
Packit Bot c70073
					off = 0;
Packit Service e18529
					for (j = 0; j < 16 && j < l - (row << 4); j++)
Packit Bot bc323c
						off += sprintf(raw_data + off,
Packit Bot bc323c
						       j ? " %02X" : "%02X",
Packit Service e18529
						       (unsigned char)s[(row << 4) + j]);
Packit Bot bc323c
					pr_list_item(raw_data);
Packit Service e18529
				}
Packit Service e18529
				/* String isn't filtered yet so do it now */
Packit Bot fd6691
				ascii_filter(s, l - 1);
Packit Service e18529
			}
Packit Bot bc323c
			pr_list_item("%s", s);
Packit Service e18529
		}
Packit Bot bc323c
		pr_list_end();
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 Bot 986715
static void dmi_print_memory_size(const char *attr, 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 Bot 986715
	pr_attr(attr, "%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 Bot 986715
	const char *format;
Packit Bot 986715
Packit Service e18529
	if (code & 0x000003FF)
Packit Bot 986715
	{
Packit Bot 986715
		format = "%u bytes";
Packit Bot 986715
	}
Packit Service e18529
	else
Packit Bot 986715
	{
Packit Bot 986715
		format = "%u kB";
Packit Bot 986715
		code >>= 10;
Packit Bot 986715
	}
Packit Bot 986715
Packit Bot 986715
	pr_attr("Runtime Size", format, code);
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 Bot 0941f5
	{
Packit Bot 0941f5
		u64 s = { .l = (code1 + 1) << 6 };
Packit Bot 986715
		dmi_print_memory_size("ROM Size", s, 1);
Packit Bot 0941f5
	}
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("ROM Size", "%u %s", code2 & 0x3FFF, unit[code2 >> 14]);
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_bios_characteristics(u64 code)
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 Bot 962e8c
		pr_list_item("%s", 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 Bot 962e8c
			pr_list_item("%s", characteristics[i - 3]);
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_bios_characteristics_x1(u8 code)
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 Bot 962e8c
			pr_list_item("%s", characteristics[i]);
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_bios_characteristics_x2(u8 code)
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 Bot 962e8c
			pr_list_item("%s", 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 Bot 19ab97
static void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...),
Packit Bot 19ab97
			    const char *attr, 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 Bot 19ab97
		if (print_cb)
Packit Bot 19ab97
			print_cb(attr, "Not Present");
Packit Bot 986715
		else
Packit Bot 986715
			printf("Not Present\n");
Packit Service e18529
		return;
Packit Service e18529
	}
Packit Service e18529
	if (only0x00)
Packit Service e18529
	{
Packit Bot 19ab97
		if (print_cb)
Packit Bot 19ab97
			print_cb(attr, "Not Settable");
Packit Bot 986715
		else
Packit Bot 986715
			printf("Not Settable\n");
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 Bot 986715
	{
Packit Bot 19ab97
		if (print_cb)
Packit Bot 19ab97
			print_cb(attr,
Packit Bot 986715
				"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Packit Bot 986715
				p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
Packit Bot 986715
				p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Bot 986715
		else
Packit Bot 986715
			printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
Packit Bot 986715
				p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
Packit Bot 986715
				p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Bot 986715
	}
Packit Service e18529
	else
Packit Bot 986715
	{
Packit Bot 19ab97
		if (print_cb)
Packit Bot 19ab97
			print_cb(attr,
Packit Bot 986715
				"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
Packit Bot 986715
				p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
Packit Bot 986715
				p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Bot 986715
		else
Packit Bot 986715
			printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
Packit Bot 986715
				p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
Packit Bot 986715
				p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
Packit Bot 986715
	}
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 Bot 962e8c
static void dmi_base_board_features(u8 code)
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 Bot 962e8c
		pr_list_start("Features", "%s", "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start("Features", NULL);
Packit Service e18529
		for (i = 0; i <= 4; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", features[i]);
Packit Service e18529
	}
Packit Bot 962e8c
	pr_list_end();
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 Bot 962e8c
static void dmi_base_board_handles(u8 count, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Bot 962e8c
	pr_list_start("Contained Object Handles", "%u", count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Bot 962e8c
		pr_list_item("0x%04X", WORD(p + sizeof(u16) * i));
Packit Bot 962e8c
	pr_list_end();
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 Bot 986715
		pr_attr("Height", "Unspecified");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Height", "%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 Bot 986715
		pr_attr("Number Of Power Cords", "Unspecified");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Number Of Power Cords", "%u", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_chassis_elements(u8 count, u8 len, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Bot 962e8c
	pr_list_start("Contained Elements", "%u", count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Service e18529
		if (len >= 0x03)
Packit Service e18529
		{
Packit Bot 962e8c
			const char *type;
Packit Bot 962e8c
Packit Bot 962e8c
			type = (p[i * len] & 0x80) ?
Packit Service e18529
				dmi_smbios_structure_type(p[i * len] & 0x7F) :
Packit Bot 962e8c
				dmi_base_board_type(p[i * len] & 0x7F);
Packit Bot 962e8c
Packit Service e18529
			if (p[1 + i * len] == p[2 + i * len])
Packit Bot 962e8c
				pr_list_item("%s (%u)", type, p[1 + i * len]);
Packit Service e18529
			else
Packit Bot 962e8c
				pr_list_item("%s (%u-%u)", type, p[1 + i * len],
Packit Bot 962e8c
					     p[2 + i * len]);
Packit Service e18529
		}
Packit Service e18529
	}
Packit Bot 962e8c
	pr_list_end();
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 Bot 29be0b
Packit Bot 29be0b
		{ 0x200, "RV32" },
Packit Bot 29be0b
		{ 0x201, "RV64" },
Packit Bot 29be0b
		{ 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 Bot 962e8c
static void dmi_processor_id(const struct dmi_header *h)
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 Bot 986715
	pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X",
Packit Bot 986715
		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 Bot 986715
		pr_attr("Signature",
Packit Bot 986715
			"Type %u, Family %u, Major Stepping %u, Minor Stepping %u",
Packit Bot 986715
			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 Bot 986715
			pr_attr("Signature",
Packit Bot 986715
				"Type %u, Family %u, Model %u, Stepping %u",
Packit Bot 986715
				(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 Bot 986715
		pr_attr("Signature",
Packit Bot 986715
			"Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u",
Packit Bot 986715
			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 Bot 986715
			pr_attr("Signature",
Packit Bot 986715
				"Type %u, Family %u, Model %u, Stepping %u",
Packit Bot 986715
				(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 Bot 986715
			pr_attr("Signature", "Family %u, Model %u, Stepping %u",
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
	if ((edx & 0xBFEFFBFF) == 0)
Packit Bot 962e8c
		pr_list_start("Flags", "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start("Flags", NULL);
Packit Service e18529
		for (i = 0; i <= 31; i++)
Packit Service e18529
			if (flags[i] != NULL && edx & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", flags[i]);
Packit Service e18529
	}
Packit Bot 962e8c
	pr_list_end();
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_processor_voltage(const char *attr, 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 Bot 986715
		pr_attr(attr, "%.1f V", (float)(code & 0x7f) / 10);
Packit Bot 7fae18
	else if ((code & 0x07) == 0x00)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Bot 986715
		char voltage_str[18];
Packit Bot 986715
		int off = 0;
Packit Bot 986715
Packit Service e18529
		for (i = 0; i <= 2; i++)
Packit Bot 986715
		{
Packit Service e18529
			if (code & (1 << i))
Packit Bot 986715
			{
Packit Bot 986715
				/* Insert space if not the first value */
Packit Bot 986715
				off += sprintf(voltage_str + off,
Packit Bot 986715
					       off ? " %s" :"%s",
Packit Bot 986715
					       voltage[i]);
Packit Bot 986715
			}
Packit Bot 986715
		}
Packit Bot 986715
		if (off)
Packit Bot 986715
			pr_attr(attr, voltage_str);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_processor_frequency(const char *attr, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	u16 code = WORD(p);
Packit Service e18529
Packit Service e18529
	if (code)
Packit Bot 986715
	{
Packit Bot 986715
		if (attr)
Packit Bot 986715
			pr_attr(attr, "%u MHz", code);
Packit Bot 986715
		else
Packit Bot 986715
			printf("%u MHz\n", code);
Packit Bot 986715
	}
Packit Service e18529
	else
Packit Bot 986715
	{
Packit Bot 986715
		if (attr)
Packit Bot 986715
			pr_attr(attr, "Unknown");
Packit Bot 986715
		else
Packit Bot 986715
			printf("Unknown\n");
Packit Bot 986715
	}
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 Bot 986715
static void dmi_processor_cache(const char *attr, u16 code, const char *level,
Packit Bot 986715
				u16 ver)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Service e18529
	{
Packit Service e18529
		if (ver >= 0x0203)
Packit Bot 986715
			pr_attr(attr, "Not Provided");
Packit Service e18529
		else
Packit Bot 986715
			pr_attr(attr, "No %s Cache", level);
Packit Service e18529
	}
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "0x%04X", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_processor_characteristics(const char *attr, u16 code)
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 Bot 962e8c
		pr_attr(attr, "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 2; i <= 7; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", characteristics[i - 2]);
Packit Bot 962e8c
		pr_list_end();
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 Bot 962e8c
static void dmi_memory_controller_ec_capabilities(const char *attr, u8 code)
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 Bot 962e8c
		pr_attr(attr, "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 0; i <= 5; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", capabilities[i]);
Packit Bot 962e8c
		pr_list_end();
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 Bot 962e8c
static void dmi_memory_controller_speeds(const char *attr, u16 code)
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 Bot 962e8c
		pr_attr(attr, "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 0; i <= 4; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", speeds[i]);
Packit Bot 962e8c
		pr_list_end();
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_memory_controller_slots(u8 count, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Bot 962e8c
	pr_list_start("Associated Memory Slots", "%u", count);
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Bot 962e8c
		pr_list_item("0x%04X", WORD(p + sizeof(u16) * i));
Packit Bot 962e8c
	pr_list_end();
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 Bot 962e8c
static void dmi_memory_module_types(const char *attr, u16 code, int flat)
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 Bot 962e8c
		pr_attr(attr, "None");
Packit Bot 962e8c
	else if (flat)
Packit Bot 962e8c
	{
Packit Bot 962e8c
		char type_str[68];
Packit Bot 962e8c
		int i, off = 0;
Packit Bot 962e8c
Packit Bot 962e8c
		for (i = 0; i <= 10; i++)
Packit Bot 962e8c
		{
Packit Bot 962e8c
			if (code & (1 << i))
Packit Bot 962e8c
			{
Packit Bot 962e8c
				/* Insert space if not the first value */
Packit Bot 962e8c
				off += sprintf(type_str + off,
Packit Bot 962e8c
					       off ? " %s" :"%s",
Packit Bot 962e8c
					       types[i]);
Packit Bot 962e8c
			}
Packit Bot 962e8c
		}
Packit Bot 962e8c
		if (off)
Packit Bot 962e8c
			pr_attr(attr, type_str);
Packit Bot 962e8c
	}
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 0; i <= 10; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", types[i]);
Packit Bot 962e8c
		pr_list_end();
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 Bot 986715
		pr_attr("Bank Connections", "None");
Packit Bot 986715
	else if ((code & 0xF0) == 0xF0)
Packit Bot 986715
		pr_attr("Bank Connections", "%u", code & 0x0F);
Packit Bot 986715
	else if ((code & 0x0F) == 0x0F)
Packit Bot 986715
		pr_attr("Bank Connections", "%u", code >> 4);
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Bank Connections", "%u %u", code >> 4, code & 0x0F);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_module_speed(const char *attr, u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%u ns", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_module_size(const char *attr, u8 code)
Packit Service e18529
{
Packit Bot 986715
	const char *connection;
Packit Bot 986715
Packit Service e18529
	/* 7.7.2 */
Packit Bot 986715
	if (code & 0x80)
Packit Bot 986715
		connection = " (Double-bank Connection)";
Packit Bot 986715
	else
Packit Bot 986715
		connection = " (Single-bank Connection)";
Packit Bot 986715
Packit Service e18529
	switch (code & 0x7F)
Packit Service e18529
	{
Packit Service e18529
		case 0x7D:
Packit Bot 986715
			pr_attr(attr, "Not Determinable%s", connection);
Packit Service e18529
			break;
Packit Service e18529
		case 0x7E:
Packit Bot 986715
			pr_attr(attr, "Disabled%s", connection);
Packit Service e18529
			break;
Packit Service e18529
		case 0x7F:
Packit Bot 986715
			pr_attr(attr, "Not Installed");
Packit Service e18529
			return;
Packit Service e18529
		default:
Packit Bot 986715
			pr_attr(attr, "%u MB%s", 1 << (code & 0x7F),
Packit Bot 986715
				connection);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 6a1afb
static void dmi_memory_module_error(u8 code)
Packit Service e18529
{
Packit Bot 6a1afb
	static const char *status[] = {
Packit Bot 6a1afb
		"OK", /* 0x00 */
Packit Bot 6a1afb
		"Uncorrectable Errors",
Packit Bot 6a1afb
		"Correctable Errors",
Packit Bot 6a1afb
		"Correctable and Uncorrectable Errors" /* 0x03 */
Packit Bot 6a1afb
	};
Packit Bot 6a1afb
Packit Service e18529
	if (code & (1 << 2))
Packit Bot 986715
		pr_attr("Error Status", "See Event Log");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Error Status", "%s", status[code & 0x03]);
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 Bot 986715
static void dmi_cache_size_2(const char *attr, u32 code)
Packit Bot a901f8
{
Packit Bot 95dedf
	u64 size;
Packit Bot 95dedf
Packit Service e18529
	if (code & 0x80000000)
Packit Service e18529
	{
Packit Service e18529
		code &= 0x7FFFFFFFLU;
Packit Bot 95dedf
		size.l = code << 6;
Packit Bot 95dedf
		size.h = code >> 26;
Packit Service e18529
	}
Packit Service e18529
	else
Packit Bot 95dedf
	{
Packit Bot 95dedf
		size.l = code;
Packit Bot 95dedf
		size.h = 0;
Packit Bot 95dedf
	}
Packit Bot 95dedf
Packit Bot 95dedf
	/* Use a more convenient unit for large cache size */
Packit Bot 986715
	dmi_print_memory_size(attr, size, 1);
Packit Service 2d7cf6
}
Packit Service 2d7cf6
Packit Bot 986715
static void dmi_cache_size(const char *attr, u16 code)
Packit Bot 05d0af
{
Packit Bot 986715
	dmi_cache_size_2(attr,
Packit Bot 986715
			 (((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU));
Packit Bot 05d0af
}
Packit Bot 05d0af
Packit Bot 962e8c
static void dmi_cache_types(const char *attr, u16 code, int flat)
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 Bot 962e8c
		pr_attr(attr, "None");
Packit Bot 962e8c
	else if (flat)
Packit Bot 962e8c
	{
Packit Bot 962e8c
		char type_str[70];
Packit Bot 962e8c
		int i, off = 0;
Packit Bot 962e8c
Packit Bot 962e8c
		for (i = 0; i <= 6; i++)
Packit Bot 962e8c
		{
Packit Bot 962e8c
			if (code & (1 << i))
Packit Bot 962e8c
			{
Packit Bot 962e8c
				/* Insert space if not the first value */
Packit Bot 962e8c
				off += sprintf(type_str + off,
Packit Bot 962e8c
					       off ? " %s" :"%s",
Packit Bot 962e8c
					       types[i]);
Packit Bot 962e8c
			}
Packit Bot 962e8c
		}
Packit Bot 962e8c
		if (off)
Packit Bot 962e8c
			pr_attr(attr, type_str);
Packit Bot 962e8c
	}
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 0; i <= 6; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", types[i]);
Packit Bot 962e8c
		pr_list_end();
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 Bot 08cac1
		"PCI Express 2 SFF-8639 (U.2)",
Packit Bot 08cac1
		"PCI Express 3 SFF-8639 (U.2)",
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 Bot 727187
		"PCI Express Mini 76-pin",
Packit Bot 08cac1
		"PCI Express 4 SFF-8639 (U.2)",
Packit Bot 08cac1
		"PCI Express 5 SFF-8639 (U.2)",
Packit Bot 08cac1
		"OCP NIC 3.0 Small Form Factor (SFF)",
Packit Bot 08cac1
		"OCP NIC 3.0 Large Form Factor (LFF)",
Packit Bot 08cac1
		"OCP NIC Prior to 3.0" /* 0x28 */
Packit Service 0bfd26
	};
Packit Bot 29be0b
	static const char *type_0x30[] = {
Packit Bot 29be0b
		"CXL FLexbus 1.0" /* 0x30 */
Packit Bot 29be0b
	};
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 Bot 29be0b
		"PCI Express 3 x16",
Packit Bot 29be0b
		out_of_spec, /* 0xB7 */
Packit Bot 29be0b
		"PCI Express 4",
Packit Bot 29be0b
		"PCI Express 4 x1",
Packit Bot 29be0b
		"PCI Express 4 x2",
Packit Bot 29be0b
		"PCI Express 4 x4",
Packit Bot 29be0b
		"PCI Express 4 x8",
Packit Bot 08cac1
		"PCI Express 4 x16",
Packit Bot 08cac1
		"PCI Express 5",
Packit Bot 08cac1
		"PCI Express 5 x1",
Packit Bot 08cac1
		"PCI Express 5 x2",
Packit Bot 08cac1
		"PCI Express 5 x4",
Packit Bot 08cac1
		"PCI Express 5 x8",
Packit Bot 08cac1
		"PCI Express 5 x16",
Packit Bot 08cac1
		"PCI Express 6+",
Packit Bot 08cac1
		"EDSFF E1",
Packit Bot 08cac1
		"EDSFF E3" /* 0xC6 */
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 Bot 08cac1
	if (code >= 0x01 && code <= 0x28)
Packit Service e18529
		return type[code - 0x01];
Packit Bot 29be0b
	if (code == 0x30)
Packit Bot 29be0b
		return type_0x30[code - 0x30];
Packit Bot 08cac1
	if (code >= 0xA0 && code <= 0xC6)
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 Bot eaf1d8
	/* 7.10.4 */
Packit Service e18529
	static const char *length[] = {
Packit Service e18529
		"Other", /* 0x01 */
Packit Service e18529
		"Unknown",
Packit Service e18529
		"Short",
Packit Bot b718c0
		"Long",
Packit Bot b718c0
		"2.5\" drive form factor",
Packit Bot b718c0
		"3.5\" drive form factor" /* 0x06 */
Packit Service e18529
	};
Packit Service e18529
Packit Bot b718c0
	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 Bot 986715
static void dmi_slot_id(u8 code1, u8 code2, u8 type)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.5 */
Packit Service e18529
	switch (type)
Packit Service e18529
	{
Packit Service e18529
		case 0x04: /* MCA */
Packit Bot 986715
			pr_attr("ID", "%u", code1);
Packit Service e18529
			break;
Packit Service e18529
		case 0x05: /* EISA */
Packit Bot 986715
			pr_attr("ID", "%u", 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 Bot 29be0b
		case 0xB8: /* PCI Express 4 */
Packit Bot 29be0b
		case 0xB9: /* PCI Express 4 */
Packit Bot 29be0b
		case 0xBA: /* PCI Express 4 */
Packit Bot 29be0b
		case 0xBB: /* PCI Express 4 */
Packit Bot 29be0b
		case 0xBC: /* PCI Express 4 */
Packit Bot 29be0b
		case 0xBD: /* PCI Express 4 */
Packit Bot 986715
			pr_attr("ID", "%u", code1);
Packit Service e18529
			break;
Packit Service e18529
		case 0x07: /* PCMCIA */
Packit Bot 986715
			pr_attr("ID", "Adapter %u, Socket %u", code1, code2);
Packit Service e18529
			break;
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 962e8c
static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2)
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 Bot 962e8c
		pr_attr(attr, "Unknown");
Packit Service e18529
	else if ((code1 & 0xFE) == 0 && (code2 & 0x07) == 0)
Packit Bot 962e8c
		pr_attr(attr, "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Service e18529
		int i;
Packit Service e18529
Packit Bot 962e8c
		pr_list_start(attr, NULL);
Packit Service e18529
		for (i = 1; i <= 7; i++)
Packit Service e18529
			if (code1 & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", characteristics1[i - 1]);
Packit Service e18529
		for (i = 0; i <= 3; i++)
Packit Service e18529
			if (code2 & (1 << i))
Packit Bot 962e8c
				pr_list_item("%s", characteristics2[i]);
Packit Bot 962e8c
		pr_list_end();
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3)
Packit Service e18529
{
Packit Service e18529
	/* 7.10.8 */
Packit Service e18529
	if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF))
Packit Bot 986715
		pr_attr("Bus Address", "%04x:%02x:%02x.%x",
Packit Bot 986715
			code1, code2, code3 >> 3, code3 & 0x7);
Packit Service 568207
}
Packit Service 568207
Packit Bot 986715
static void dmi_slot_peers(u8 n, const u8 *data)
Packit Bot b710f4
{
Packit Bot 986715
	char attr[16];
Packit Bot b710f4
	int i;
Packit Bot b710f4
Packit Bot b710f4
	for (i = 1; i <= n; i++, data += 5)
Packit Bot 986715
	{
Packit Bot 986715
		sprintf(attr, "Peer Device %hu", i);
Packit Bot 986715
		pr_attr(attr, "%04x:%02x:%02x.%x (Width %u)",
Packit Bot 986715
			WORD(data), data[2], data[3] >> 3, data[3] & 0x07,
Packit Bot 986715
			data[4]);
Packit Bot 986715
	}
Packit Bot b710f4
}
Packit Bot b710f4
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 Bot 986715
static void dmi_on_board_devices(const struct dmi_header *h)
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 Bot beb2d7
			pr_handle_name("On Board Device Information");
Packit Service e18529
		else
Packit Bot beb2d7
			pr_handle_name("On Board Device %d Information",
Packit Bot beb2d7
				       i + 1);
Packit Bot 986715
		pr_attr("Type", "%s",
Packit Bot 986715
			dmi_on_board_devices_type(p[2 * i] & 0x7F));
Packit Bot 986715
		pr_attr("Status", "%s",
Packit Bot 986715
			p[2 * i] & 0x80 ? "Enabled" : "Disabled");
Packit Bot 986715
		pr_attr("Description", "%s", 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 Bot 986715
static void dmi_oem_strings(const struct dmi_header *h)
Packit Service e18529
{
Packit Bot 986715
	char attr[11];
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 Bot 986715
	{
Packit Bot 986715
		sprintf(attr, "String %hu", i);
Packit Bot 986715
		pr_attr(attr, "%s",dmi_string(h, i));
Packit Bot 986715
	}
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 Bot 986715
static void dmi_system_configuration_options(const struct dmi_header *h)
Packit Service e18529
{
Packit Bot 986715
	char attr[11];
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 Bot 986715
	{
Packit Bot 986715
		sprintf(attr, "Option %hu", i);
Packit Bot 986715
		pr_attr(attr, "%s",dmi_string(h, i));
Packit Bot 986715
	}
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 Bot 962e8c
static void dmi_bios_languages(const struct dmi_header *h)
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 Bot 962e8c
		pr_list_item("%s", 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 Bot 962e8c
static void dmi_group_associations_items(u8 count, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	int i;
Packit Service e18529
Packit Service e18529
	for (i = 0; i < count; i++)
Packit Service e18529
	{
Packit Bot 962e8c
		pr_list_item("0x%04X (%s)",
Packit Bot 962e8c
			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 Bot 986715
	pr_attr("Status", "%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 Bot 986715
			pr_attr("Access Address", "Index 0x%04X, Data 0x%04X",
Packit Bot 986715
				WORD(p), WORD(p + 2));
Packit Service e18529
			break;
Packit Service e18529
		case 0x03:
Packit Bot 986715
			pr_attr("Access Address", "0x%08X", DWORD(p));
Packit Service e18529
			break;
Packit Service e18529
		case 0x04:
Packit Bot 986715
			pr_attr("Access Address", "0x%04X", WORD(p));
Packit Service e18529
			break;
Packit Service e18529
		default:
Packit Bot 986715
			pr_attr("Access Address", "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 Bot 986715
static void dmi_event_log_descriptors(u8 count, u8 len, const u8 *p)
Packit Service e18529
{
Packit Service e18529
	/* 7.16.1 */
Packit Bot 986715
	char attr[16];
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 Bot 986715
			sprintf(attr, "Descriptor %hu", i + 1);
Packit Bot 986715
			pr_attr(attr, "%s",
Packit Bot 986715
				dmi_event_log_descriptor_type(p[i * len]));
Packit Bot 986715
			sprintf(attr, "Data Format %hu", i + 1);
Packit Bot 986715
			pr_attr(attr, "%s",
Packit Bot 986715
				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 Bot 29be0b
		"PC-98/Local Bus Add-on Card",
Packit Bot 29be0b
		"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 Bot 29be0b
	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 Bot 986715
		pr_attr("Error Information Handle", "Not Provided");
Packit Service e18529
	else if (code == 0xFFFF)
Packit Bot 986715
		pr_attr("Error Information Handle", "No Error");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Error Information Handle", "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 Bot 986715
static void dmi_memory_device_width(const char *attr, 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 Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%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 Bot 986715
		pr_attr("Size", "No Module Installed");
Packit Service e18529
	else if (code == 0xFFFF)
Packit Bot 986715
		pr_attr("Size", "Unknown");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Bot 0941f5
		u64 s = { .l = code & 0x7FFF };
Packit Bot 0941f5
		if (!(code & 0x8000))
Packit Bot 0941f5
			s.l <<= 10;
Packit Bot 986715
		dmi_print_memory_size("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 Bot 986715
		pr_attr("Size", "%lu MB", (unsigned long)code);
Packit Service e18529
	else if (code & 0xFFC00UL)
Packit Bot 986715
		pr_attr("Size", "%lu GB", (unsigned long)code >> 10);
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Size", "%lu TB", (unsigned long)code >> 20);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_voltage_value(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, code % 100 ? "%g V" : "%.1f V",
Packit Bot 986715
			(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 Bot 29be0b
		"FB-DIMM",
Packit Bot 29be0b
		"Die" /* 0x10 */
Packit Service e18529
	};
Packit Service e18529
Packit Bot 29be0b
	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 Bot 986715
		pr_attr("Set", "None");
Packit Service e18529
	else if (code == 0xFF)
Packit Bot 986715
		pr_attr("Set", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Set", "%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 Bot 0c6c89
		"LPDDR4",
Packit Bot 29be0b
		"Logical non-volatile device",
Packit Bot 29be0b
		"HBM",
Packit Bot 29be0b
		"HBM2" /* 0x21 */
Packit Service e18529
	};
Packit Service e18529
Packit Bot 29be0b
	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 Bot 986715
	char list[172];		/* Update length if you touch the array above */
Packit Service e18529
Packit Service e18529
	if ((code & 0xFFFE) == 0)
Packit Bot 986715
		pr_attr("Type Detail", "None");
Packit Service e18529
	else
Packit Service e18529
	{
Packit Bot 986715
		int i, off = 0;
Packit Service e18529
Packit Bot 986715
		list[0] = '\0';
Packit Service e18529
		for (i = 1; i <= 15; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 986715
				off += sprintf(list + off, off ? " %s" : "%s",
Packit Bot 986715
					       detail[i - 1]);
Packit Bot 986715
		pr_attr("Type Detail", list);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_device_speed(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%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 Bot 29be0b
		"Intel Optane DC persistent memory" /* 0x07 */
Packit Service e18529
	};
Packit Service e18529
	if (code >= 0x01 && code <= 0x07)
Packit Bot 986715
		pr_attr("Memory Technology", "%s", technology[code - 0x01]);
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Memory Technology", "%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 Bot 986715
	char list[99];		/* Update length if you touch the array above */
Packit Service e18529
Packit Service e18529
	if ((code & 0xFFFE) == 0)
Packit Bot 986715
		pr_attr("Memory Operating Mode Capability", "None");
Packit Service e18529
	else {
Packit Bot 986715
		int i, off = 0;
Packit Service e18529
Packit Bot 986715
		list[0] = '\0';
Packit Service e18529
		for (i = 1; i <= 5; i++)
Packit Service e18529
			if (code & (1 << i))
Packit Bot 986715
				off += sprintf(list + off, off ? " %s" : "%s",
Packit Bot 986715
					       mode[i - 1]);
Packit Bot 986715
		pr_attr("Memory Operating Mode Capability", list);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_manufacturer_id(const char *attr, 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 Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "Bank %d, Hex 0x%02X",
Packit Bot 986715
			(code & 0x7F) + 1, code >> 8);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_product_id(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	/* 7.18.9 */
Packit Service e18529
	/* 7.18.11 */
Packit Service e18529
	if (code == 0)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "0x%04X", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_memory_size(const char *attr, 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 Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else if (code.h == 0x0 && code.l == 0x0)
Packit Bot 986715
		pr_attr(attr, "None");
Packit Service e18529
	else
Packit Bot 986715
		dmi_print_memory_size(attr, 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 Bot 986715
		pr_attr("Vendor Syndrome", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Vendor Syndrome", "0x%08X", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_32bit_memory_error_address(const char *attr, u32 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x80000000)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "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 Bot 986715
		pr_attr("Range Size", "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 Bot 986715
		dmi_print_memory_size("Range 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 Bot 986715
		pr_attr("Range Size", "Invalid");
Packit Service e18529
	else
Packit Bot 986715
		dmi_print_memory_size("Range 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 Bot 986715
		pr_attr("Partition Row Position", "%s", out_of_spec);
Packit Service e18529
	else if (code == 0xFF)
Packit Bot 986715
		pr_attr("Partition Row Position", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Partition Row Position", "%u", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_mapped_address_interleave_position(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code != 0)
Packit Service e18529
	{
Packit Service e18529
		if (code == 0xFF)
Packit Bot 986715
			pr_attr("Interleave Position", "Unknown");
Packit Service e18529
		else
Packit Bot 986715
			pr_attr("Interleave Position", "%u", code);
Packit Service e18529
	}
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_mapped_address_interleaved_data_depth(u8 code)
Packit Service e18529
{
Packit Service e18529
	if (code != 0)
Packit Service e18529
	{
Packit Service e18529
		if (code == 0xFF)
Packit Bot 986715
			pr_attr("Interleaved Data Depth", "Unknown");
Packit Service e18529
		else
Packit Bot 986715
			pr_attr("Interleaved Data Depth", "%u", code);
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 Bot 986715
		pr_attr("Design Capacity", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Design Capacity", "%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 Bot 986715
		pr_attr("Design Voltage", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Design Voltage", "%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 Bot 986715
		pr_attr("Maximum Error", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Maximum Error", "%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 Bot 986715
static void dmi_system_reset_count(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%u", code);
Packit Service e18529
}
Packit Service e18529
Packit Bot 986715
static void dmi_system_reset_timer(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0xFFFF)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%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 Bot 986715
	char time[15];
Packit Bot 986715
	int off = 0;
Packit Bot 986715
Packit Service e18529
	/* 7.26.1 */
Packit Service e18529
	if (dmi_bcd_range(p[0], 0x01, 0x12))
Packit Bot 986715
		off += sprintf(time + off, "%02X", p[0]);
Packit Service e18529
	else
Packit Bot 986715
		off += sprintf(time + off, "*");
Packit Service e18529
	if (dmi_bcd_range(p[1], 0x01, 0x31))
Packit Bot 986715
		off += sprintf(time + off, "-%02X", p[1]);
Packit Service e18529
	else
Packit Bot 986715
		off += sprintf(time + off, "-*");
Packit Service e18529
	if (dmi_bcd_range(p[2], 0x00, 0x23))
Packit Bot 986715
		off += sprintf(time + off, " %02X", p[2]);
Packit Service e18529
	else
Packit Bot 986715
		off += sprintf(time + off, " *");
Packit Service e18529
	if (dmi_bcd_range(p[3], 0x00, 0x59))
Packit Bot 986715
		off += sprintf(time + off, ":%02X", p[3]);
Packit Service e18529
	else
Packit Bot 986715
		off += sprintf(time + off, ":*");
Packit Service e18529
	if (dmi_bcd_range(p[4], 0x00, 0x59))
Packit Bot 986715
		off += sprintf(time + off, ":%02X", p[4]);
Packit Service e18529
	else
Packit Bot 986715
		off += sprintf(time + off, ":*");
Packit Bot 986715
Packit Bot 986715
	pr_attr("Next Scheduled Power-on", time);
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 Bot 986715
static void dmi_voltage_probe_value(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%.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 Bot 986715
		pr_attr("Resolution", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Resolution", "%.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 Bot 986715
		pr_attr("Accuracy", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Accuracy", "%.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 Bot 986715
		pr_attr("Nominal Speed", "Unknown Or Non-rotating");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Nominal Speed", "%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 Bot 986715
static void dmi_temperature_probe_value(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%.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 Bot 986715
		pr_attr("Resolution", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Resolution", "%.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 Bot 986715
static void dmi_current_probe_value(const char *attr, u16 code)
Packit Service e18529
{
Packit Service e18529
	if (code == 0x8000)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "%.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 Bot 986715
		pr_attr("Resolution", "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr("Resolution", "%.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 Bot 986715
static void dmi_64bit_memory_error_address(const char *attr, u64 code)
Packit Service e18529
{
Packit Service e18529
	if (code.h == 0x80000000 && code.l == 0x00000000)
Packit Bot 986715
		pr_attr(attr, "Unknown");
Packit Service e18529
	else
Packit Bot 986715
		pr_attr(attr, "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 Bot adc92b
	/* 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,