Codebase list dmidecode / 918cb82
Merge branch 'release/debian/3.4-1' Jörg Frings-Fürst 1 year, 9 months ago
16 changed file(s) with 1292 addition(s) and 381 deletion(s). Raw diff Collapse all Expand all
2020 Tyler Bell <tyler.bell@hp.com>
2121 Xie XiuQi <xiexiuqi@huawei.com>
2222 Petr Oros <poros@redhat.com>
23 Prabhakar Pujeri <prabhakar.pujeri@dell.com>
24 Erwan Velu <e.velu@criteo.com>
25 Jerry Hoemann <jerry.hoemann@hpe.com>
2326
2427 MANY THANKS TO (IN CHRONOLOGICAL ORDER)
2528 Werner Heuser
8992 Stefan Tauner
9093 Naga Chumbalkar
9194 Jens Rosenboom
95 Lianbo Jiang
96 Tianjia Zhang
97 Ivan Tkachenko
0 Version 3.4 (Mon Jun 27 2022)
1 - Support for SMBIOS 3.4.0. This includes new memory device types, new
2 processor upgrades, new slot types and characteristics, decoding of memory
3 module extended speed, new system slot types, new processor characteristics
4 and new format of Processor ID.
5 - Support for SMBIOS 3.5.0. This includes new processor upgrades, BIOS
6 characteristics, new slot characteristics, new on-board device types, new
7 pointing device interface types, and a new record type (type 45 -
8 Firmware Inventory Information).
9 - Decode HPE OEM records 194, 199, 203, 236, 237, 238 ans 240.
10 - Bug fixes:
11 Fix OEM vendor name matching
12 Fix ASCII filtering of strings
13 Fix crash with option -u
14 - Minor improvements:
15 Skip details of uninstalled memory modules
16 Don't display the raw CPU ID in quiet mode
17 Improve the formatting of the manual pages
18
019 Version 3.3 (Wed Oct 14 2020)
120 - [BUILD] Allow overriding build settings from the environment.
221 - [COMPATIBILITY] Document how the UUID fields are interpreted.
0 dmidecode (3.4-1) unstable; urgency=medium
1
2 * New upstream release.
3 - Remove upstream applied patches:
4 + debian/patches/0145-Fix_condition_error_in_ascii_filter.patch
5 + debian/patches/0150-Fix_crash.patch
6 - Refresh upstream signing key.
7 * Declare compliance with Debian Policy 4.6.1.0 (No changes needed).
8 * debian/copyright:
9 - Add year 2022 to myself.
10
11 -- Jörg Frings-Fürst <debian@jff.email> Thu, 30 Jun 2022 20:37:08 +0200
12
013 dmidecode (3.3-3) unstable; urgency=medium
114
215 * Add Architecture riscv64 (Closes: #991854).
22 Priority: optional
33 Maintainer: Jörg Frings-Fürst <debian@jff.email>
44 Build-Depends: debhelper-compat (= 13)
5 Standards-Version: 4.6.0.0
5 Standards-Version: 4.6.1.0
66 Rules-Requires-Root: no
77 Vcs-Git: git://jff.email/opt/git/dmidecode.git
88 Vcs-Browser: https://jff.email/cgit/dmidecode.git/
1212 Files: debian/*
1313 Copyright: 2003-2007 Petter Reinholdtsen <pere@debian.org>
1414 2011-2012 Daniel Baumann <daniel.baumann@progress-technologies.net>
15 2014-2021 Jörg Frings-Fürst <debian@jff.email>
15 2014-2022 Jörg Frings-Fürst <debian@jff.email>
1616 License: GPL-2+
1717
1818 License: GPL-2+
0 0145-Fix_condition_error_in_ascii_filter.patch
1 0150-Fix_crash.patch
0 #0145-Fix_condition_error_in_ascii_filter.patch
1 #0150-Fix_crash.patch
22 0100-ansi-c.patch
33 0001-hurd.patch
44 #0005-build.patch
0 -----BEGIN PGP ARMORED FILE-----
1 Comment: Use "gpg --dearmor" for unpacking
0 -----BEGIN PGP PUBLIC KEY BLOCK-----
21
3 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
66 =9biY
67 -----END PGP ARMORED FILE-----
2 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
60 Qu7m8XPTuUj0t1Fvq0Xleoa74ot+e+pKWAaR40U=
61 =3wf6
62 -----END PGP PUBLIC KEY BLOCK-----
8484 #define out_of_spec "<OUT OF SPEC>"
8585 static const char *bad_index = "<BAD INDEX>";
8686
87 #define SUPPORTED_SMBIOS_VER 0x030300
87 enum cpuid_type cpuid_type = cpuid_none;
88
89 #define SUPPORTED_SMBIOS_VER 0x030500
8890
8991 #define FLAG_NO_FILE_OFFSET (1 << 0)
9092 #define FLAG_STOP_AT_EOT (1 << 1)
115117 size_t i;
116118
117119 for (i = 0; i < len; i++)
118 if (bp[i] < 32 || bp[i] == 127)
120 if (bp[i] < 32 || bp[i] >= 127)
119121 bp[i] = '.';
120122 }
121123
200202 "Additional Information",
201203 "Onboard Device",
202204 "Management Controller Host Interface",
203 "TPM Device", /* 43 */
205 "TPM Device",
206 "Processor",
207 "Firmware",
208 "String Property" /* 46 */
204209 };
205210
206211 if (code >= 128)
207212 return "OEM-specific";
208 if (code <= 43)
213 if (code <= 46)
209214 return type[code];
210215 return out_of_spec;
211216 }
247252 {
248253 int j, l = strlen(s) + 1;
249254
250 off = 0;
251255 for (row = 0; row < ((l - 1) >> 4) + 1; row++)
252256 {
257 off = 0;
253258 for (j = 0; j < 16 && j < l - (row << 4); j++)
254259 off += sprintf(raw_data + off,
255260 j ? " %02X" : "%02X",
266271 }
267272
268273 /* shift is 0 if the value is in bytes, 1 if it is in kilobytes */
269 static void dmi_print_memory_size(const char *attr, u64 code, int shift)
274 void dmi_print_memory_size(const char *attr, u64 code, int shift)
270275 {
271276 unsigned long capacity;
272277 u16 split[7];
423428 "Function key-initiated network boot is supported",
424429 "Targeted content distribution is supported",
425430 "UEFI is supported",
426 "System is a virtual machine" /* 4 */
431 "System is a virtual machine",
432 "Manufacturing mode is supported",
433 "Manufacturing mode is enabled" /* 6 */
427434 };
428435 int i;
429436
430 for (i = 0; i <= 4; i++)
437 for (i = 0; i <= 6; i++)
431438 if (code & (1 << i))
432439 pr_list_item("%s", characteristics[i]);
433440 }
10361043 }
10371044 }
10381045
1046 static enum cpuid_type dmi_get_cpuid_type(const struct dmi_header *h)
1047 {
1048 const u8 *data = h->data;
1049 const u8 *p = data + 0x08;
1050 u16 type;
1051
1052 type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
1053 WORD(data + 0x28) : data[0x06];
1054
1055 if (type == 0x05) /* 80386 */
1056 {
1057 return cpuid_80386;
1058 }
1059 else if (type == 0x06) /* 80486 */
1060 {
1061 u16 dx = WORD(p);
1062 /*
1063 * Not all 80486 CPU support the CPUID instruction, we have to find
1064 * whether the one we have here does or not. Note that this trick
1065 * works only because we know that 80486 must be little-endian.
1066 */
1067 if ((dx & 0x0F00) == 0x0400
1068 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
1069 && ((dx & 0x000F) >= 0x0003))
1070 return cpuid_x86_intel;
1071 else
1072 return cpuid_80486;
1073 }
1074 else if ((type >= 0x100 && type <= 0x101) /* ARM */
1075 || (type >= 0x118 && type <= 0x119)) /* ARM */
1076 {
1077 /*
1078 * The field's format depends on the processor's support of
1079 * the SMCCC_ARCH_SOC_ID architectural call. Software can determine
1080 * the support for SoC ID by examining the Processor Characteristics field
1081 * for "Arm64 SoC ID" bit.
1082 */
1083 if (h->length >= 0x28
1084 && (WORD(data + 0x26) & (1 << 9)))
1085 return cpuid_arm_soc_id;
1086 else
1087 return cpuid_arm_legacy;
1088 }
1089 else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
1090 || (type >= 0x28 && type <= 0x2F) /* Intel */
1091 || (type >= 0xA1 && type <= 0xB3) /* Intel */
1092 || type == 0xB5 /* Intel */
1093 || (type >= 0xB9 && type <= 0xC7) /* Intel */
1094 || (type >= 0xCD && type <= 0xCF) /* Intel */
1095 || (type >= 0xD2 && type <= 0xDB) /* VIA, Intel */
1096 || (type >= 0xDD && type <= 0xE0)) /* Intel */
1097 return cpuid_x86_intel;
1098 else if ((type >= 0x18 && type <= 0x1D) /* AMD */
1099 || type == 0x1F /* AMD */
1100 || (type >= 0x38 && type <= 0x3F) /* AMD */
1101 || (type >= 0x46 && type <= 0x4F) /* AMD */
1102 || (type >= 0x66 && type <= 0x6B) /* AMD */
1103 || (type >= 0x83 && type <= 0x8F) /* AMD */
1104 || (type >= 0xB6 && type <= 0xB7) /* AMD */
1105 || (type >= 0xE4 && type <= 0xEF)) /* AMD */
1106 return cpuid_x86_amd;
1107 else if (type == 0x01 || type == 0x02)
1108 {
1109 const char *version = dmi_string(h, data[0x10]);
1110 /*
1111 * Some X86-class CPU have family "Other" or "Unknown". In this case,
1112 * we use the version string to determine if they are known to
1113 * support the CPUID instruction.
1114 */
1115 if (strncmp(version, "Pentium III MMX", 15) == 0
1116 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
1117 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
1118 || strcmp(version, "Genuine Intel(R) CPU U1400") == 0)
1119 return cpuid_x86_intel;
1120 else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
1121 || strncmp(version, "AMD Opteron(tm)", 15) == 0
1122 || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0)
1123 return cpuid_x86_amd;
1124 }
1125
1126 /* neither X86 nor ARM */
1127 return cpuid_none;
1128 }
1129
1130 void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...),
1131 const char *label, enum cpuid_type sig, const u8 *p)
1132 {
1133 u32 eax, midr, jep106, soc_revision;
1134 u16 dx;
1135
1136 switch (sig)
1137 {
1138 case cpuid_80386:
1139 dx = WORD(p);
1140 /*
1141 * 80386 have a different signature.
1142 */
1143 print_cb(label,
1144 "Type %u, Family %u, Major Stepping %u, Minor Stepping %u",
1145 dx >> 12, (dx >> 8) & 0xF,
1146 (dx >> 4) & 0xF, dx & 0xF);
1147 return;
1148
1149 case cpuid_80486:
1150 dx = WORD(p);
1151 print_cb(label,
1152 "Type %u, Family %u, Model %u, Stepping %u",
1153 (dx >> 12) & 0x3, (dx >> 8) & 0xF,
1154 (dx >> 4) & 0xF, dx & 0xF);
1155 return;
1156
1157 case cpuid_arm_legacy: /* ARM before SOC ID */
1158 midr = DWORD(p);
1159 /*
1160 * The format of this field was not defined for ARM processors
1161 * before version 3.1.0 of the SMBIOS specification, so we
1162 * silently skip it if it reads all zeroes.
1163 */
1164 if (midr == 0)
1165 return;
1166 print_cb(label,
1167 "Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u",
1168 midr >> 24, (midr >> 20) & 0xF,
1169 (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
1170 return;
1171
1172 case cpuid_arm_soc_id: /* ARM with SOC ID */
1173 /*
1174 * If Soc ID is supported, the first DWORD is the JEP-106 code;
1175 * the second DWORD is the SoC revision value.
1176 */
1177 jep106 = DWORD(p);
1178 soc_revision = DWORD(p + 4);
1179 /*
1180 * According to SMC Calling Convention (SMCCC) v1.3 specification
1181 * (https://developer.arm.com/documentation/den0028/d/), the format
1182 * of the values returned by the SMCCC_ARCH_SOC_ID call is as follows:
1183 *
1184 * JEP-106 code for the SiP (SoC_ID_type == 0)
1185 * Bit[31] must be zero
1186 * Bits[30:24] JEP-106 bank index for the SiP
1187 * Bits[23:16] JEP-106 identification code with parity bit for the SiP
1188 * Bits[15:0] Implementation defined SoC ID
1189 *
1190 * SoC revision (SoC_ID_type == 1)
1191 * Bit[31] must be zero
1192 * Bits[30:0] SoC revision
1193 */
1194 pr_attr("Signature",
1195 "JEP-106 Bank 0x%02x Manufacturer 0x%02x, SoC ID 0x%04x, SoC Revision 0x%08x",
1196 (jep106 >> 24) & 0x7F, (jep106 >> 16) & 0x7F, jep106 & 0xFFFF, soc_revision);
1197 return;
1198
1199 case cpuid_x86_intel: /* Intel */
1200 eax = DWORD(p);
1201 /*
1202 * Extra flags are now returned in the ECX register when
1203 * one calls the CPUID instruction. Their meaning is
1204 * explained in table 3-5, but DMI doesn't support this
1205 * yet.
1206 */
1207 print_cb(label,
1208 "Type %u, Family %u, Model %u, Stepping %u",
1209 (eax >> 12) & 0x3,
1210 ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F),
1211 ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F),
1212 eax & 0xF);
1213 break;
1214
1215 case cpuid_x86_amd: /* AMD, publication #25481 revision 2.28 */
1216 eax = DWORD(p);
1217 print_cb(label, "Family %u, Model %u, Stepping %u",
1218 ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0),
1219 ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0),
1220 eax & 0xF);
1221 break;
1222 default:
1223 return;
1224 }
1225 }
1226
10391227 static void dmi_processor_id(const struct dmi_header *h)
10401228 {
10411229 /* Intel AP-485 revision 36, table 2-4 */
10751263 };
10761264 const u8 *data = h->data;
10771265 const u8 *p = data + 0x08;
1078 u32 eax, edx;
1079 int sig = 0;
1080 u16 type;
1081
1082 type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
1083 WORD(data + 0x28) : data[0x06];
1266 enum cpuid_type sig = dmi_get_cpuid_type(h);
1267 u32 edx;
10841268
10851269 /*
10861270 * This might help learn about new processors supporting the
10871271 * CPUID instruction or another form of identification.
10881272 */
1089 pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X",
1090 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1091
1092 if (type == 0x05) /* 80386 */
1093 {
1094 u16 dx = WORD(p);
1095 /*
1096 * 80386 have a different signature.
1097 */
1098 pr_attr("Signature",
1099 "Type %u, Family %u, Major Stepping %u, Minor Stepping %u",
1100 dx >> 12, (dx >> 8) & 0xF,
1101 (dx >> 4) & 0xF, dx & 0xF);
1273 if (!(opt.flags & FLAG_QUIET))
1274 pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X",
1275 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1276
1277 dmi_print_cpuid(pr_attr, "Signature", sig, p);
1278
1279 if (sig != cpuid_x86_intel && sig != cpuid_x86_amd)
11021280 return;
1103 }
1104 if (type == 0x06) /* 80486 */
1105 {
1106 u16 dx = WORD(p);
1107 /*
1108 * Not all 80486 CPU support the CPUID instruction, we have to find
1109 * wether the one we have here does or not. Note that this trick
1110 * works only because we know that 80486 must be little-endian.
1111 */
1112 if ((dx & 0x0F00) == 0x0400
1113 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
1114 && ((dx & 0x000F) >= 0x0003))
1115 sig = 1;
1116 else
1117 {
1118 pr_attr("Signature",
1119 "Type %u, Family %u, Model %u, Stepping %u",
1120 (dx >> 12) & 0x3, (dx >> 8) & 0xF,
1121 (dx >> 4) & 0xF, dx & 0xF);
1122 return;
1123 }
1124 }
1125 else if ((type >= 0x100 && type <= 0x101) /* ARM */
1126 || (type >= 0x118 && type <= 0x119)) /* ARM */
1127 {
1128 u32 midr = DWORD(p);
1129 /*
1130 * The format of this field was not defined for ARM processors
1131 * before version 3.1.0 of the SMBIOS specification, so we
1132 * silently skip it if it reads all zeroes.
1133 */
1134 if (midr == 0)
1135 return;
1136 pr_attr("Signature",
1137 "Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u",
1138 midr >> 24, (midr >> 20) & 0xF,
1139 (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
1140 return;
1141 }
1142 else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
1143 || (type >= 0x28 && type <= 0x2F) /* Intel */
1144 || (type >= 0xA1 && type <= 0xB3) /* Intel */
1145 || type == 0xB5 /* Intel */
1146 || (type >= 0xB9 && type <= 0xC7) /* Intel */
1147 || (type >= 0xCD && type <= 0xCF) /* Intel */
1148 || (type >= 0xD2 && type <= 0xDB) /* VIA, Intel */
1149 || (type >= 0xDD && type <= 0xE0)) /* Intel */
1150 sig = 1;
1151 else if ((type >= 0x18 && type <= 0x1D) /* AMD */
1152 || type == 0x1F /* AMD */
1153 || (type >= 0x38 && type <= 0x3F) /* AMD */
1154 || (type >= 0x46 && type <= 0x4F) /* AMD */
1155 || (type >= 0x66 && type <= 0x6B) /* AMD */
1156 || (type >= 0x83 && type <= 0x8F) /* AMD */
1157 || (type >= 0xB6 && type <= 0xB7) /* AMD */
1158 || (type >= 0xE4 && type <= 0xEF)) /* AMD */
1159 sig = 2;
1160 else if (type == 0x01 || type == 0x02)
1161 {
1162 const char *version = dmi_string(h, data[0x10]);
1163 /*
1164 * Some X86-class CPU have family "Other" or "Unknown". In this case,
1165 * we use the version string to determine if they are known to
1166 * support the CPUID instruction.
1167 */
1168 if (strncmp(version, "Pentium III MMX", 15) == 0
1169 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0
1170 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0
1171 || strcmp(version, "Genuine Intel(R) CPU U1400") == 0)
1172 sig = 1;
1173 else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
1174 || strncmp(version, "AMD Opteron(tm)", 15) == 0
1175 || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0)
1176 sig = 2;
1177 else
1178 return;
1179 }
1180 else /* neither X86 nor ARM */
1181 return;
1182
1183 /*
1184 * Extra flags are now returned in the ECX register when one calls
1185 * the CPUID instruction. Their meaning is explained in table 3-5, but
1186 * DMI doesn't support this yet.
1187 */
1188 eax = DWORD(p);
1189 edx = DWORD(p + 4);
1190 switch (sig)
1191 {
1192 case 1: /* Intel */
1193 pr_attr("Signature",
1194 "Type %u, Family %u, Model %u, Stepping %u",
1195 (eax >> 12) & 0x3,
1196 ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F),
1197 ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F),
1198 eax & 0xF);
1199 break;
1200 case 2: /* AMD, publication #25481 revision 2.28 */
1201 pr_attr("Signature", "Family %u, Model %u, Stepping %u",
1202 ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0),
1203 ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0),
1204 eax & 0xF);
1205 break;
1206 }
12071281
12081282 edx = DWORD(p + 4);
12091283 if ((edx & 0xBFEFFBFF) == 0)
13541428 "Socket LGA2066",
13551429 "Socket BGA1392",
13561430 "Socket BGA1510",
1357 "Socket BGA1528" /* 0x3C */
1358 };
1359
1360 if (code >= 0x01 && code <= 0x3C)
1431 "Socket BGA1528",
1432 "Socket LGA4189",
1433 "Socket LGA1200",
1434 "Socket LGA4677" /* 0x3F */
1435 };
1436
1437 if (code >= 0x01 && code <= 0x3F)
13611438 return upgrade[code - 0x01];
13621439 return out_of_spec;
13631440 }
13851462 "Hardware Thread",
13861463 "Execute Protection",
13871464 "Enhanced Virtualization",
1388 "Power/Performance Control" /* 7 */
1465 "Power/Performance Control",
1466 "128-bit Capable",
1467 "Arm64 SoC ID" /* 9 */
13891468 };
13901469
13911470 if ((code & 0x00FC) == 0)
13951474 int i;
13961475
13971476 pr_list_start(attr, NULL);
1398 for (i = 2; i <= 7; i++)
1477 for (i = 2; i <= 9; i++)
13991478 if (code & (1 << i))
14001479 pr_list_item("%s", characteristics[i - 2]);
14011480 pr_list_end();
19302009 "MXM Type IV",
19312010 "MXM 3.0 Type A",
19322011 "MXM 3.0 Type B",
1933 "PCI Express 2 SFF-8639",
1934 "PCI Express 3 SFF-8639",
2012 "PCI Express 2 SFF-8639 (U.2)",
2013 "PCI Express 3 SFF-8639 (U.2)",
19352014 "PCI Express Mini 52-pin with bottom-side keep-outs",
19362015 "PCI Express Mini 52-pin without bottom-side keep-outs",
1937 "PCI Express Mini 76-pin" /* 0x23 */
2016 "PCI Express Mini 76-pin",
2017 "PCI Express 4 SFF-8639 (U.2)",
2018 "PCI Express 5 SFF-8639 (U.2)",
2019 "OCP NIC 3.0 Small Form Factor (SFF)",
2020 "OCP NIC 3.0 Large Form Factor (LFF)",
2021 "OCP NIC Prior to 3.0" /* 0x28 */
19382022 };
19392023 static const char *type_0x30[] = {
19402024 "CXL FLexbus 1.0" /* 0x30 */
19692053 "PCI Express 4 x2",
19702054 "PCI Express 4 x4",
19712055 "PCI Express 4 x8",
1972 "PCI Express 4 x16" /* 0xBD */
2056 "PCI Express 4 x16",
2057 "PCI Express 5",
2058 "PCI Express 5 x1",
2059 "PCI Express 5 x2",
2060 "PCI Express 5 x4",
2061 "PCI Express 5 x8",
2062 "PCI Express 5 x16",
2063 "PCI Express 6+",
2064 "EDSFF E1",
2065 "EDSFF E3" /* 0xC6 */
19732066 };
19742067 /*
19752068 * Note to developers: when adding entries to these lists, check if
19762069 * function dmi_slot_id below needs updating too.
19772070 */
19782071
1979 if (code >= 0x01 && code <= 0x23)
2072 if (code >= 0x01 && code <= 0x28)
19802073 return type[code - 0x01];
19812074 if (code == 0x30)
19822075 return type_0x30[code - 0x30];
1983 if (code >= 0xA0 && code <= 0xBD)
2076 if (code >= 0xA0 && code <= 0xC6)
19842077 return type_0xA0[code - 0xA0];
19852078 return out_of_spec;
19862079 }
19872080
1988 static const char *dmi_slot_bus_width(u8 code)
2081 /* If hide_unknown is set, return NULL instead of "Other" or "Unknown" */
2082 static const char *dmi_slot_bus_width(u8 code, int hide_unknown)
19892083 {
19902084 /* 7.10.2 */
19912085 static const char *width[] = {
1992 "", /* 0x01, "Other" */
1993 "", /* "Unknown" */
1994 "8-bit ",
1995 "16-bit ",
1996 "32-bit ",
1997 "64-bit ",
1998 "128-bit ",
1999 "x1 ",
2000 "x2 ",
2001 "x4 ",
2002 "x8 ",
2003 "x12 ",
2004 "x16 ",
2005 "x32 " /* 0x0E */
2086 "Other", /* 0x01 */
2087 "Unknown",
2088 "8-bit",
2089 "16-bit",
2090 "32-bit",
2091 "64-bit",
2092 "128-bit",
2093 "x1",
2094 "x2",
2095 "x4",
2096 "x8",
2097 "x12",
2098 "x16",
2099 "x32" /* 0x0E */
20062100 };
20072101
20082102 if (code >= 0x01 && code <= 0x0E)
2103 {
2104 if (code <= 0x02 && hide_unknown)
2105 return NULL;
20092106 return width[code - 0x01];
2107 }
20102108 return out_of_spec;
2109 }
2110
2111 static void dmi_slot_type_with_width(u8 type, u8 width)
2112 {
2113 const char *type_str, *width_str;
2114
2115 type_str = dmi_slot_type(type);
2116 width_str = dmi_slot_bus_width(width, 1);
2117
2118 if (width_str)
2119 pr_attr("Type", "%s %s", width_str, type_str);
2120 else
2121 pr_attr("Type", "%s", type_str);
20112122 }
20122123
20132124 static const char *dmi_slot_current_usage(u8 code)
20902201 case 0xBB: /* PCI Express 4 */
20912202 case 0xBC: /* PCI Express 4 */
20922203 case 0xBD: /* PCI Express 4 */
2204 case 0xBE: /* PCI Express 5 */
2205 case 0xBF: /* PCI Express 5 */
2206 case 0xC0: /* PCI Express 5 */
2207 case 0xC1: /* PCI Express 5 */
2208 case 0xC2: /* PCI Express 5 */
2209 case 0xC3: /* PCI Express 5 */
2210 case 0xC4: /* PCI Express 6+ */
20932211 pr_attr("ID", "%u", code1);
20942212 break;
20952213 case 0x07: /* PCMCIA */
21152233 "PME signal is supported", /* 0 */
21162234 "Hot-plug devices are supported",
21172235 "SMBus signal is supported",
2118 "PCIe slot bifurcation is supported" /* 3 */
2236 "PCIe slot bifurcation is supported",
2237 "Async/surprise removal is supported",
2238 "Flexbus slot, CXL 1.0 capable",
2239 "Flexbus slot, CXL 2.0 capable" /* 6 */
21192240 };
21202241
21212242 if (code1 & (1 << 0))
21302251 for (i = 1; i <= 7; i++)
21312252 if (code1 & (1 << i))
21322253 pr_list_item("%s", characteristics1[i - 1]);
2133 for (i = 0; i <= 3; i++)
2254 for (i = 0; i <= 6; i++)
21342255 if (code2 & (1 << i))
21352256 pr_list_item("%s", characteristics2[i]);
21362257 pr_list_end();
21522273
21532274 for (i = 1; i <= n; i++, data += 5)
21542275 {
2155 sprintf(attr, "Peer Device %hu", i);
2276 sprintf(attr, "Peer Device %hhu", (u8)i);
21562277 pr_attr(attr, "%04x:%02x:%02x.%x (Width %u)",
21572278 WORD(data), data[2], data[3] >> 3, data[3] & 0x07,
21582279 data[4]);
21592280 }
2281 }
2282
2283 static void dmi_slot_information(u8 type, u8 code)
2284 {
2285 switch (type)
2286 {
2287 case 0x1F: /* PCI Express 2 */
2288 case 0x20: /* PCI Express 3 */
2289 case 0x21: /* PCI Express Mini */
2290 case 0x22: /* PCI Express Mini */
2291 case 0x23: /* PCI Express Mini */
2292 case 0xA5: /* PCI Express */
2293 case 0xA6: /* PCI Express */
2294 case 0xA7: /* PCI Express */
2295 case 0xA8: /* PCI Express */
2296 case 0xA9: /* PCI Express */
2297 case 0xAA: /* PCI Express */
2298 case 0xAB: /* PCI Express 2 */
2299 case 0xAC: /* PCI Express 2 */
2300 case 0xAD: /* PCI Express 2 */
2301 case 0xAE: /* PCI Express 2 */
2302 case 0xAF: /* PCI Express 2 */
2303 case 0xB0: /* PCI Express 2 */
2304 case 0xB1: /* PCI Express 3 */
2305 case 0xB2: /* PCI Express 3 */
2306 case 0xB3: /* PCI Express 3 */
2307 case 0xB4: /* PCI Express 3 */
2308 case 0xB5: /* PCI Express 3 */
2309 case 0xB6: /* PCI Express 3 */
2310 case 0xB8: /* PCI Express 4 */
2311 case 0xB9: /* PCI Express 4 */
2312 case 0xBA: /* PCI Express 4 */
2313 case 0xBB: /* PCI Express 4 */
2314 case 0xBC: /* PCI Express 4 */
2315 case 0xBD: /* PCI Express 4 */
2316 case 0xBE: /* PCI Express 5 */
2317 case 0xBF: /* PCI Express 5 */
2318 case 0xC0: /* PCI Express 5 */
2319 case 0xC1: /* PCI Express 5 */
2320 case 0xC2: /* PCI Express 5 */
2321 case 0xC3: /* PCI Express 5 */
2322 case 0xC4: /* PCI Express 6+ */
2323 if (code)
2324 pr_attr("PCI Express Generation", "%u", code);
2325 break;
2326 }
2327 }
2328
2329 static void dmi_slot_physical_width(u8 code)
2330 {
2331 if (code)
2332 pr_attr("Slot Physical Width", "%s",
2333 dmi_slot_bus_width(code, 0));
2334 }
2335
2336 static void dmi_slot_pitch(u16 code)
2337 {
2338 if (code)
2339 pr_attr("Pitch", "%u.%02u mm", code / 100, code % 100);
2340 }
2341
2342 static const char *dmi_slot_height(u8 code)
2343 {
2344 /* 7.10.3 */
2345 static const char *height[] = {
2346 "Not applicable", /* 0x00 */
2347 "Other",
2348 "Unknown",
2349 "Full height",
2350 "Low-profile" /* 0x04 */
2351 };
2352
2353 if (code <= 0x04)
2354 return height[code];
2355 return out_of_spec;
21602356 }
21612357
21622358 /*
21762372 "Sound",
21772373 "PATA Controller",
21782374 "SATA Controller",
2179 "SAS Controller" /* 0x0A */
2180 };
2181
2182 if (code >= 0x01 && code <= 0x0A)
2375 "SAS Controller",
2376 "Wireless LAN",
2377 "Bluetooth",
2378 "WWAN",
2379 "eMMC",
2380 "NVMe Controller",
2381 "UFS Controller" /* 0x10 */
2382 };
2383
2384 if (code >= 0x01 && code <= 0x10)
21832385 return type[code - 0x01];
21842386 return out_of_spec;
21852387 }
22182420
22192421 for (i = 1; i <= count; i++)
22202422 {
2221 sprintf(attr, "String %hu", i);
2423 sprintf(attr, "String %hhu", (u8)i);
22222424 pr_attr(attr, "%s",dmi_string(h, i));
22232425 }
22242426 }
22362438
22372439 for (i = 1; i <= count; i++)
22382440 {
2239 sprintf(attr, "Option %hu", i);
2441 sprintf(attr, "Option %hhu", (u8)i);
22402442 pr_attr(attr, "%s",dmi_string(h, i));
22412443 }
22422444 }
24202622 {
24212623 if (len >= 0x02)
24222624 {
2423 sprintf(attr, "Descriptor %hu", i + 1);
2625 sprintf(attr, "Descriptor %d", i + 1);
24242626 pr_attr(attr, "%s",
24252627 dmi_event_log_descriptor_type(p[i * len]));
2426 sprintf(attr, "Data Format %hu", i + 1);
2628 sprintf(attr, "Data Format %d", i + 1);
24272629 pr_attr(attr, "%s",
24282630 dmi_event_log_descriptor_format(p[i * len + 1]));
24292631 }
26382840 "LPDDR4",
26392841 "Logical non-volatile device",
26402842 "HBM",
2641 "HBM2" /* 0x21 */
2642 };
2643
2644 if (code >= 0x01 && code <= 0x21)
2843 "HBM2",
2844 "DDR5",
2845 "LPDDR5" /* 0x23 */
2846 };
2847
2848 if (code >= 0x01 && code <= 0x23)
26452849 return type[code - 0x01];
26462850 return out_of_spec;
26472851 }
26832887 }
26842888 }
26852889
2686 static void dmi_memory_device_speed(const char *attr, u16 code)
2687 {
2688 if (code == 0)
2689 pr_attr(attr, "Unknown");
2690 else
2691 pr_attr(attr, "%u MT/s", code);
2890 static void dmi_memory_device_speed(const char *attr, u16 code1, u32 code2)
2891 {
2892 if (code1 == 0xFFFF)
2893 {
2894 if (code2 == 0)
2895 pr_attr(attr, "Unknown");
2896 else
2897 pr_attr(attr, "%lu MT/s", code2);
2898 }
2899 else
2900 {
2901 if (code1 == 0)
2902 pr_attr(attr, "Unknown");
2903 else
2904 pr_attr(attr, "%u MT/s", code1);
2905 }
26922906 }
26932907
26942908 static void dmi_memory_technology(u8 code)
29473161 static const char *interface_0xA0[] = {
29483162 "Bus Mouse DB-9", /* 0xA0 */
29493163 "Bus Mouse Micro DIN",
2950 "USB" /* 0xA2 */
3164 "USB",
3165 "I2C",
3166 "SPI" /* 0xA4 */
29513167 };
29523168
29533169 if (code >= 0x01 && code <= 0x08)
29543170 return interface[code - 0x01];
2955 if (code >= 0xA0 && code <= 0xA2)
3171 if (code >= 0xA0 && code <= 0xA4)
29563172 return interface_0xA0[code - 0xA0];
29573173 return out_of_spec;
29583174 }
33893605
33903606 for (i = 1; i <= count; i++)
33913607 {
3392 sprintf(attr, "Device %hu Load", i);
3608 sprintf(attr, "Device %hhu Load", (u8)i);
33933609 pr_attr(attr, "%u", p[3 * i]);
33943610 if (!(opt.flags & FLAG_QUIET))
33953611 {
3396 sprintf(attr, "Device %hu Handle", i);
3612 sprintf(attr, "Device %hhu Handle", (u8)i);
33973613 pr_attr(attr, "0x%04X", WORD(p + 3 * i + 1));
33983614 }
33993615 }
37063922 * convenience. It could get passed from the SMBIOS
37073923 * header, but that's a lot of passing of pointers just
37083924 * to get that info, and the only thing it is used for is
3709 * to determine the endianess of the field. Since we only
3925 * to determine the endianness of the field. Since we only
37103926 * do this parsing on versions of SMBIOS after 3.1.1, and the
3711 * endianess of the field is always little after version 2.6.0
3927 * endianness of the field is always little after version 2.6.0
37123928 * we can just pick a sufficiently recent version here.
37133929 */
37143930 dmi_system_uuid(pr_subattr, "Service UUID", &rdata[0], 0x311);
37153931
37163932 /*
37173933 * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type
3718 * Note, using decimal indicies here, as the DSP0270
3934 * Note, using decimal indices here, as the DSP0270
37193935 * uses decimal, so as to make it more comparable
37203936 */
37213937 assign_val = rdata[16];
40104226 }
40114227
40124228 /*
4229 * 7.46 Firmware Inventory Information (Type 45)
4230 */
4231
4232 static void dmi_firmware_characteristics(u16 code)
4233 {
4234 /* 7.46.3 */
4235 static const char *characteristics[] = {
4236 "Updatable", /* 0 */
4237 "Write-Protect" /* 1 */
4238 };
4239 int i;
4240
4241 for (i = 0; i <= 1; i++)
4242 pr_list_item("%s: %s", characteristics[i],
4243 (code & (1 << i)) ? "Yes" : "No");
4244 }
4245
4246 static const char *dmi_firmware_state(u8 code)
4247 {
4248 /* 7.46.4 */
4249 static const char *state[] = {
4250 "Other", /* 0x01 */
4251 "Unknown",
4252 "Disabled",
4253 "Enabled",
4254 "Absent",
4255 "Stand-by Offline",
4256 "Stand-by Spare",
4257 "Unavailable Offline" /* 0x08 */
4258 };
4259
4260 if (code >= 0x01 && code <= 0x08)
4261 return state[code - 0x01];
4262 return out_of_spec;
4263 }
4264
4265 static void dmi_firmware_components(u8 count, const u8 *p)
4266 {
4267 int i;
4268
4269 pr_list_start("Associated Components", "%u", count);
4270 for (i = 0; i < count; i++)
4271 pr_list_item("0x%04X", WORD(p + sizeof(u16) * i));
4272 pr_list_end();
4273 }
4274
4275 /*
40134276 * Main
40144277 */
40154278
40324295 pr_attr("Release Date", "%s",
40334296 dmi_string(h, data[0x08]));
40344297 /*
4035 * On IA-64, the BIOS base address will read 0 because
4036 * there is no BIOS. Skip the base address and the
4037 * runtime size in this case.
4298 * On IA-64 and UEFI-based systems, the BIOS base
4299 * address will read 0 because there is no BIOS. Skip
4300 * the base address and the runtime size in this case.
40384301 */
40394302 if (WORD(data + 0x06) != 0)
40404303 {
43014564 if (h->length < 0x0C) break;
43024565 pr_attr("Designation", "%s",
43034566 dmi_string(h, data[0x04]));
4304 pr_attr("Type", "%s%s",
4305 dmi_slot_bus_width(data[0x06]),
4306 dmi_slot_type(data[0x05]));
4567 dmi_slot_type_with_width(data[0x05], data[0x06]);
43074568 pr_attr("Current Usage", "%s",
43084569 dmi_slot_current_usage(data[0x07]));
43094570 pr_attr("Length", "%s",
43184579 if (h->length < 0x13) break;
43194580 pr_attr("Data Bus Width", "%u", data[0x11]);
43204581 pr_attr("Peer Devices", "%u", data[0x12]);
4321 if (h->length - 0x13 >= data[0x12] * 5)
4322 dmi_slot_peers(data[0x12], data + 0x13);
4582 if (h->length < 0x13 + data[0x12] * 5) break;
4583 dmi_slot_peers(data[0x12], data + 0x13);
4584 if (h->length < 0x17 + data[0x12] * 5) break;
4585 dmi_slot_information(data[0x05], data[0x13 + data[0x12] * 5]);
4586 dmi_slot_physical_width(data[0x14 + data[0x12] * 5]);
4587 dmi_slot_pitch(WORD(data + 0x15 + data[0x12] * 5));
4588 if (h->length < 0x18 + data[0x12] * 5) break;
4589 pr_attr("Height", "%s",
4590 dmi_slot_height(data[0x17 + data[0x12] * 5]));
43234591 break;
43244592
43254593 case 10: /* 7.11 On Board Devices Information */
44504718 dmi_memory_device_type(data[0x12]));
44514719 dmi_memory_device_type_detail(WORD(data + 0x13));
44524720 if (h->length < 0x17) break;
4453 dmi_memory_device_speed("Speed", WORD(data + 0x15));
4721 /* If no module is present, the remaining fields are irrelevant */
4722 if (WORD(data + 0x0C) == 0)
4723 break;
4724 dmi_memory_device_speed("Speed", WORD(data + 0x15),
4725 h->length >= 0x5C ?
4726 DWORD(data + 0x54) : 0);
44544727 if (h->length < 0x1B) break;
44554728 pr_attr("Manufacturer", "%s",
44564729 dmi_string(h, data[0x17]));
44674740 pr_attr("Rank", "%u", data[0x1B] & 0x0F);
44684741 if (h->length < 0x22) break;
44694742 dmi_memory_device_speed("Configured Memory Speed",
4470 WORD(data + 0x20));
4743 WORD(data + 0x20),
4744 h->length >= 0x5C ?
4745 DWORD(data + 0x58) : 0);
44714746 if (h->length < 0x28) break;
44724747 dmi_memory_voltage_value("Minimum Voltage",
44734748 WORD(data + 0x22));
50505325 DWORD(data + 0x1B));
50515326 break;
50525327
5053 case 126: /* 7.44 Inactive */
5328 case 45: /* 7.46 Firmware Inventory Information */
5329 pr_handle_name("Firmware Inventory Information");
5330 if (h->length < 0x18) break;
5331 pr_attr("Firmware Component Name", "%s",
5332 dmi_string(h, data[0x04]));
5333 pr_attr("Firmware Version", "%s",
5334 dmi_string(h, data[0x05]));
5335 pr_attr("Firmware ID", "%s", dmi_string(h, data[0x07]));
5336 pr_attr("Release Date", "%s", dmi_string(h, data[0x09]));
5337 pr_attr("Manufacturer", "%s", dmi_string(h, data[0x0A]));
5338 pr_attr("Lowest Supported Firmware Version", "%s",
5339 dmi_string(h, data[0x0B]));
5340 dmi_memory_size("Image Size", QWORD(data + 0x0C));
5341 pr_list_start("Characteristics", NULL);
5342 dmi_firmware_characteristics(WORD(data + 0x14));
5343 pr_list_end();
5344 pr_attr("State", "%s", dmi_firmware_state(data[0x16]));
5345 if (h->length < 0x18 + data[0x17] * 2) break;
5346 if (!(opt.flags & FLAG_QUIET))
5347 dmi_firmware_components(data[0x17], data + 0x18);
5348 break;
5349
5350 case 126:
50545351 pr_handle_name("Inactive");
50555352 break;
50565353
5057 case 127: /* 7.45 End Of Table */
5354 case 127:
50585355 pr_handle_name("End Of Table");
50595356 break;
50605357
51415438 u8 *data;
51425439 int i = 0;
51435440
5441 /* First pass: Save specific values needed to decode OEM types */
5442 data = buf;
5443 while ((i < num || !num)
5444 && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
5445 {
5446 u8 *next;
5447 struct dmi_header h;
5448
5449 to_dmi_header(&h, data);
5450
5451 /*
5452 * If a short entry is found (less than 4 bytes), not only it
5453 * is invalid, but we cannot reliably locate the next entry.
5454 * Also stop at end-of-table marker if so instructed.
5455 */
5456 if (h.length < 4 ||
5457 (h.type == 127 &&
5458 (opt.flags & (FLAG_QUIET | FLAG_STOP_AT_EOT))))
5459 break;
5460 i++;
5461
5462 /* Look for the next handle */
5463 next = data + h.length;
5464 while ((unsigned long)(next - buf + 1) < len
5465 && (next[0] != 0 || next[1] != 0))
5466 next++;
5467 next += 2;
5468
5469 /* Make sure the whole structure fits in the table */
5470 if ((unsigned long)(next - buf) > len)
5471 break;
5472
5473 /* Assign vendor for vendor-specific decodes later */
5474 if (h.type == 1 && h.length >= 6)
5475 dmi_set_vendor(_dmi_string(&h, data[0x04], 0),
5476 _dmi_string(&h, data[0x05], 0));
5477
5478 /* Remember CPUID type for HPE type 199 */
5479 if (h.type == 4 && h.length >= 0x1A && cpuid_type == cpuid_none)
5480 cpuid_type = dmi_get_cpuid_type(&h);
5481 data = next;
5482 }
5483
5484 /* Second pass: Actually decode the data */
5485 i = 0;
51445486 data = buf;
51455487 while ((i < num || !num)
51465488 && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
51995541 data = next;
52005542 break;
52015543 }
5202
5203 /* assign vendor for vendor-specific decodes later */
5204 if (h.type == 1 && h.length >= 5)
5205 dmi_set_vendor(dmi_string(&h, data[0x04]));
52065544
52075545 /* Fixup a common mistake */
52085546 if (h.type == 34)
3030 u8 *data;
3131 };
3232
33 enum cpuid_type
34 {
35 cpuid_none,
36 cpuid_80386,
37 cpuid_80486,
38 cpuid_arm_legacy,
39 cpuid_arm_soc_id,
40 cpuid_x86_intel,
41 cpuid_x86_amd,
42 };
43
44 extern enum cpuid_type cpuid_type;
45
3346 int is_printable(const u8 *data, int len);
3447 const char *dmi_string(const struct dmi_header *dm, u8 s);
48 void dmi_print_memory_size(const char *addr, u64 code, int shift);
49 void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...),
50 const char *label, enum cpuid_type sig, const u8 *p);
3551
3652 #endif
2222 #include <string.h>
2323
2424 #include "types.h"
25 #include "util.h"
2526 #include "dmidecode.h"
2627 #include "dmioem.h"
28 #include "dmiopt.h"
2729 #include "dmioutput.h"
2830
2931 /*
4143 };
4244
4345 static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
46 static const char *dmi_product = NULL;
4447
4548 /*
4649 * Remember the system vendor for later use. We only actually store the
4750 * value if we know how to decode at least one specific entry type for
4851 * that vendor.
4952 */
50 void dmi_set_vendor(const char *s)
51 {
52 int len;
53 void dmi_set_vendor(const char *v, const char *p)
54 {
55 const struct { const char *str; enum DMI_VENDORS id; } vendor[] = {
56 { "Acer", VENDOR_ACER },
57 { "HP", VENDOR_HP },
58 { "Hewlett-Packard", VENDOR_HP },
59 { "HPE", VENDOR_HPE },
60 { "Hewlett Packard Enterprise", VENDOR_HPE },
61 { "IBM", VENDOR_IBM },
62 { "LENOVO", VENDOR_LENOVO },
63 };
64 unsigned int i;
65 size_t len;
5366
5467 /*
5568 * Often DMI strings have trailing spaces. Ignore these
5669 * when checking for known vendor names.
5770 */
58 len = strlen(s);
59 while (len && s[len - 1] == ' ')
71 len = v ? strlen(v) : 0;
72 while (len && v[len - 1] == ' ')
6073 len--;
6174
62 if (strncmp(s, "Acer", len) == 0)
63 dmi_vendor = VENDOR_ACER;
64 else if (strncmp(s, "HP", len) == 0 || strncmp(s, "Hewlett-Packard", len) == 0)
65 dmi_vendor = VENDOR_HP;
66 else if (strncmp(s, "HPE", len) == 0 || strncmp(s, "Hewlett Packard Enterprise", len) == 0)
67 dmi_vendor = VENDOR_HPE;
68 else if (strncmp(s, "IBM", len) == 0)
69 dmi_vendor = VENDOR_IBM;
70 else if (strncmp(s, "LENOVO", len) == 0)
71 dmi_vendor = VENDOR_LENOVO;
75 for (i = 0; i < ARRAY_SIZE(vendor); i++)
76 {
77 if (strlen(vendor[i].str) == len &&
78 strncmp(v, vendor[i].str, len) == 0)
79 {
80 dmi_vendor = vendor[i].id;
81 break;
82 }
83 }
84
85 dmi_product = p;
7286 }
7387
7488 /*
132146 if (id == 0xFF)
133147 id = ++nic_ctr;
134148
135 sprintf(attr, "NIC %hu", id);
149 sprintf(attr, "NIC %hhu", id);
136150 if (dev == 0x00 && bus == 0x00)
137151 pr_attr(attr, "Disabled");
138152 else if (dev == 0xFF && bus == 0xFF)
146160 }
147161 }
148162
163 typedef enum { G6 = 6, G7, G8, G9, G10, G10P } dmi_hpegen_t;
164
165 static int dmi_hpegen(const char *s)
166 {
167 struct { const char *name; dmi_hpegen_t gen; } table[] = {
168 { "Gen10 Plus", G10P },
169 { "Gen10", G10 },
170 { "Gen9", G9 },
171 { "Gen8", G8 },
172 { "G7", G7 },
173 { "G6", G6 },
174 };
175 unsigned int i;
176
177 if (!strstr(s, "ProLiant") && !strstr(s, "Apollo") &&
178 !strstr(s, "Synergy") && !strstr(s, "Edgeline"))
179 return -1;
180
181 for (i = 0; i < ARRAY_SIZE(table); i++) {
182 if (strstr(s, table[i].name))
183 return(table[i].gen);
184 }
185
186 return (dmi_vendor == VENDOR_HPE) ? G10P : G6;
187 }
188
189 static void dmi_hp_240_attr(u64 defined, u64 set)
190 {
191 static const char *attributes[] = {
192 "Updatable",
193 "Reset Required",
194 "Authentication Required",
195 "In Use",
196 "UEFI Image",
197 };
198 unsigned int i;
199
200 pr_attr("Attributes Defined/Set", NULL);
201 for (i = 0; i < ARRAY_SIZE(attributes); i++)
202 {
203 if (!(defined.l & (1UL << i)))
204 continue;
205 pr_subattr(attributes[i], "%s", set.l & (1UL << i) ? "Yes" : "No");
206 }
207 }
208
209 static void dmi_hp_203_assoc_hndl(const char *fname, u16 num)
210 {
211 if (opt.flags & FLAG_QUIET)
212 return;
213
214 if (num == 0xFFFE)
215 pr_attr(fname, "N/A");
216 else
217 pr_attr(fname, "0x%04X", num);
218 }
219
220 static void dmi_hp_203_pciinfo(const char *fname, u16 num)
221 {
222 if (num == 0xFFFF)
223 pr_attr(fname, "Device Not Present");
224 else
225 pr_attr(fname, "0x%04x", num);
226 }
227
228 static void dmi_hp_203_bayenc(const char *fname, u8 num)
229 {
230 switch (num)
231 {
232 case 0x00:
233 pr_attr(fname, "Unknown");
234 break;
235 case 0xff:
236 pr_attr(fname, "Do Not Display");
237 break;
238 default:
239 pr_attr(fname, "%d", num);
240 }
241 }
242
243 static void dmi_hp_203_devtyp(const char *fname, unsigned int code)
244 {
245 const char *str = "Reserved";
246 static const char *type[] = {
247 "Unknown", /* 0x00 */
248 "Reserved",
249 "Reserved",
250 "Flexible LOM",
251 "Embedded LOM",
252 "NIC in a Slot",
253 "Storage Controller",
254 "Smart Array Storage Controller",
255 "USB Hard Disk",
256 "Other PCI Device",
257 "RAM Disk",
258 "Firmware Volume",
259 "UEFI Shell",
260 "Generic UEFI USB Boot Entry",
261 "Dynamic Smart Array Controller",
262 "File",
263 "NVME Hard Drive",
264 "NVDIMM" /* 0x11 */
265 };
266
267 if (code < ARRAY_SIZE(type))
268 str = type[code];
269
270 pr_attr(fname, "%s", str);
271 }
272
273 static void dmi_hp_203_devloc(const char *fname, unsigned int code)
274 {
275 const char *str = "Reserved";
276 static const char *location[] = {
277 "Unknown", /* 0x00 */
278 "Embedded",
279 "iLO Virtual Media",
280 "Front USB Port",
281 "Rear USB Port",
282 "Internal USB",
283 "Internal SD Card",
284 "Internal Virutal USB (Embedded NAND)",
285 "Embedded SATA Port",
286 "Embedded Smart Array",
287 "PCI Slot",
288 "RAM Memory",
289 "USB",
290 "Dynamic Smart Array Controller",
291 "URL",
292 "NVMe Drive Bay" /* 0x0F */
293 };
294
295 if (code < ARRAY_SIZE(location))
296 str = location[code];
297
298 pr_attr(fname, "%s", str);
299 }
300
301 static void dmi_hp_238_loc(const char *fname, unsigned int code)
302 {
303 const char *str = "Reserved";
304 static const char *location[] = {
305 "Internal", /* 0x00 */
306 "Front of Server",
307 "Rear of Server",
308 "Embedded internal SD Card",
309 "iLO USB",
310 "HP NAND Controller (USX 2065 or other)",
311 "Reserved",
312 "Debug Port", /* 0x07 */
313 };
314
315 if (code < ARRAY_SIZE(location))
316 str = location[code];
317
318 pr_attr(fname, "%s", str);
319 }
320
321 static void dmi_hp_238_flags(const char *fname, unsigned int code)
322 {
323 const char *str = "Reserved";
324 static const char *flags[] = {
325 "Not Shared", /* 0x00 */
326 "Shared with physical switch",
327 "Shared with automatic control", /* 0x02 */
328 };
329
330 if (code < ARRAY_SIZE(flags))
331 str = flags[code];
332
333 pr_attr(fname, "%s", str);
334 }
335
336 static void dmi_hp_238_speed(const char *fname, unsigned int code)
337 {
338 const char *str = "Reserved";
339 static const char *speed[] = {
340 "Reserved", /* 0x00 */
341 "USB 1.1 Full Speed",
342 "USB 2.0 High Speed",
343 "USB 3.0 Super Speed" /* 0x03 */
344 };
345
346 if (code < ARRAY_SIZE(speed))
347 str = speed[code];
348
349 pr_attr(fname, "%s", str);
350 }
351
149352 static int dmi_decode_hp(const struct dmi_header *h)
150353 {
151354 u8 *data = h->data;
152355 int nic, ptr;
153356 u32 feat;
154357 const char *company = (dmi_vendor == VENDOR_HP) ? "HP" : "HPE";
358 int gen;
359
360 gen = dmi_hpegen(dmi_product);
361 if (gen < 0)
362 return 0;
155363
156364 switch (h->type)
157365 {
366 case 194:
367 /*
368 * Vendor Specific: Super IO Enable/Disable Features
369 *
370 * Offset | Name | Width | Description
371 * -------------------------------------
372 * 0x00 | Type | BYTE | 0xC2, Super IO Enable/Disable Indicator
373 * 0x01 | Length | BYTE | Length of structure
374 * 0x02 | Handle | WORD | Unique handle
375 * 0x04 | Dev Status | BYTE | Device Status
376 */
377 pr_handle_name("%s ProLiant Super IO Enable/Disable Indicator", company);
378 if (h->length < 0x05) break;
379 feat = data[0x04];
380 pr_attr("Serial Port A", "%s", feat & (1 << 0) ? "Enabled" : "Disabled");
381 pr_attr("Serial Port B", "%s", feat & (1 << 1) ? "Enabled" : "Disabled");
382 pr_attr("Parallel Port", "%s", feat & (1 << 2) ? "Enabled" : "Disabled");
383 pr_attr("Floppy Disk Port", "%s", feat & (1 << 3) ? "Enabled" : "Disabled");
384 pr_attr("Virtual Serial Port", "%s", feat & (1 << 4) ? "Enabled" : "Disabled");
385 break;
386
387 case 199:
388 /*
389 * Vendor Specific: CPU Microcode Patch
390 *
391 * Offset | Name | Width | Description
392 * -------------------------------------
393 * 0x00 | Type | BYTE | 0xC7, CPU Microcode Patch
394 * 0x01 | Length | BYTE | Length of structure
395 * 0x02 | Handle | WORD | Unique handle
396 * 0x04 | Patch Info | Varies| { <DWORD: ID, DWORD Date, DWORD CPUID> ...}
397 */
398 if (gen < G9) return 0;
399 pr_handle_name("%s ProLiant CPU Microcode Patch Support Info", company);
400
401 for (ptr = 0x4; ptr + 12 <= h->length; ptr += 12) {
402 u32 cpuid = DWORD(data + ptr + 2 * 4);
403 u32 date;
404
405 /* AMD omits BaseFamily. Reconstruction valid on family >= 15. */
406 if (cpuid_type == cpuid_x86_amd)
407 cpuid = ((cpuid & 0xfff00) << 8) | 0x0f00 | (cpuid & 0xff);
408
409 dmi_print_cpuid(pr_attr, "CPU ID", cpuid_type, (u8 *) &cpuid);
410
411 date = DWORD(data + ptr + 4);
412 pr_subattr("Date", "%04x-%02x-%02x",
413 date & 0xffff, (date >> 24) & 0xff, (date >> 16) & 0xff);
414 pr_subattr("Patch", "0x%X", DWORD(data + ptr));
415 }
416 break;
417
418 case 203:
419 /*
420 * Vendor Specific: HP Device Correlation Record
421 *
422 * Offset | Name | Width | Description
423 * -------------------------------------
424 * 0x00 | Type | BYTE | 0xCB, Correlation Record
425 * 0x01 | Length | BYTE | Length of structure
426 * 0x02 | Handle | WORD | Unique handle
427 * 0x04 | Assoc Device | WORD | Handle of Associated Type 9 or Type 41 Record
428 * 0x06 | Assoc SMBus | WORD | Handle of Associated Type 228 SMBus Segment Record
429 * 0x08 | PCI Vendor ID| WORD | PCI Vendor ID of device 0xFFFF -> not present
430 * 0x0A | PCI Device ID| WORD | PCI Device ID of device 0xFFFF -> not present
431 * 0x0C | PCI SubVendor| WORD | PCI Sub Vendor ID of device 0xFFFF -> not present
432 * 0x0E | PCI SubDevice| WORD | PCI Sub Device ID of device 0xFFFF -> not present
433 * 0x10 | Class Code | BYTE | PCI Class Code of Endpoint. 0xFF if device not present.
434 * 0x11 | Class SubCode| BYTE | PCI Sub Class Code of Endpoint. 0xFF if device not present.
435 * 0x12 | Parent Handle| WORD |
436 * 0x14 | Flags | WORD |
437 * 0x16 | Device Type | BYTE | UEFI only
438 * 0x17 | Device Loc | BYTE | Device Location
439 * 0x18 | Dev Instance | BYTE | Device Instance
440 * 0x19 | Sub Instance | BYTE | NIC Port # or NVMe Drive Bay
441 * 0x1A | Bay | BYTE |
442 * 0x1B | Enclosure | BYTE |
443 * 0x1C | UEFI Dev Path| STRING| String number for UEFI Device Path
444 * 0x1D | Struct Name | STRING| String number for UEFI Device Structured Name
445 * 0x1E | Device Name | STRING| String number for UEFI Device Name
446 * 0x1F | UEFI Location| STRING| String number for UEFI Location
447 * 0x20 | Assoc Handle | WORD | Type 9 Handle. Defined if Flags[0] == 1.
448 * 0x22 | Part Number | STRING| PCI Device Part Number
449 * 0x23 | Serial Number| STRING| PCI Device Serial Number
450 * 0x24 | Seg Number | WORD | Segment Group number. 0 -> Single group topology
451 * 0x26 | Bus Number | BYTE | PCI Device Bus Number
452 * 0x27 | Func Number | BTYE | PCI Device and Function Number
453 */
454 if (gen < G9) return 0;
455 pr_handle_name("%s Device Correlation Record", company);
456 if (h->length < 0x1F) break;
457 dmi_hp_203_assoc_hndl("Associated Device Record", WORD(data + 0x04));
458 dmi_hp_203_assoc_hndl("Associated SMBus Record", WORD(data + 0x06));
459 if (WORD(data + 0x08) == 0xffff && WORD(data + 0x0A) == 0xffff &&
460 WORD(data + 0x0C) == 0xffff && WORD(data + 0x0E) == 0xffff &&
461 data[0x10] == 0xFF && data[0x11] == 0xFF)
462 {
463 pr_attr("PCI Device Info", "Device Not Present");
464 }
465 else
466 {
467 dmi_hp_203_pciinfo("PCI Vendor ID", WORD(data + 0x08));
468 dmi_hp_203_pciinfo("PCI Device ID", WORD(data + 0x0A));
469 dmi_hp_203_pciinfo("PCI Sub Vendor ID", WORD(data + 0x0C));
470 dmi_hp_203_pciinfo("PCI Sub Device ID", WORD(data + 0x0E));
471 dmi_hp_203_pciinfo("PCI Class Code", (char)data[0x10]);
472 dmi_hp_203_pciinfo("PCI Sub Class Code", (char)data[0x11]);
473 }
474 dmi_hp_203_assoc_hndl("Parent Handle", WORD(data + 0x12));
475 pr_attr("Flags", "0x%04X", WORD(data + 0x14));
476 dmi_hp_203_devtyp("Device Type", data[0x16]);
477 dmi_hp_203_devloc("Device Location", data[0x17]);
478 pr_attr("Device Instance", "%d", data[0x18]);
479 pr_attr("Device Sub-Instance", "%d", data[0x19]);
480 dmi_hp_203_bayenc("Bay", data[0x1A]);
481 dmi_hp_203_bayenc("Enclosure", data[0x1B]);
482 pr_attr("Device Path", "%s", dmi_string(h, data[0x1C]));
483 pr_attr("Structured Name", "%s", dmi_string(h, data[0x1D]));
484 pr_attr("Device Name", "%s", dmi_string(h, data[0x1E]));
485 if (h->length < 0x22) break;
486 pr_attr("UEFI Location", "%s", dmi_string(h, data[0x1F]));
487 if (!(opt.flags & FLAG_QUIET))
488 {
489 if (WORD(data + 0x14) & 1)
490 pr_attr("Associated Real/Phys Handle", "0x%04X",
491 WORD(data + 0x20));
492 else
493 pr_attr("Associated Real/Phys Handle", "N/A");
494 }
495 if (h->length < 0x24) break;
496 pr_attr("PCI Part Number", "%s", dmi_string(h, data[0x22]));
497 pr_attr("Serial Number", "%s", dmi_string(h, data[0x23]));
498 if (h->length < 0x28) break;
499 pr_attr("Segment Group Number", "0x%04x", WORD(data + 0x24));
500 pr_attr("PCI Device", "%02x:%02x.%x",
501 data[0x26], data[0x27] >> 3, data[0x27] & 7);
502 break;
503
158504 case 204:
159505 /*
160506 * Vendor Specific: HPE ProLiant System/Rack Locator
205551 nic++;
206552 ptr += 8;
207553 }
208 break;
209
210 case 233:
211 /*
212 * Vendor Specific: HPE ProLiant NIC MAC Information
213 *
214 * This prints the BIOS NIC number,
215 * PCI bus/device/function, and MAC address
216 *
217 * Offset | Name | Width | Description
218 * -------------------------------------
219 * 0x00 | Type | BYTE | 0xE9, NIC structure
220 * 0x01 | Length | BYTE | Length of structure
221 * 0x02 | Handle | WORD | Unique handle
222 * 0x04 | Grp No | WORD | 0 for single segment
223 * 0x06 | Bus No | BYTE | PCI Bus
224 * 0x07 | Dev No | BYTE | PCI Device/Function No
225 * 0x08 | MAC | 32B | MAC addr padded w/ 0s
226 * 0x28 | Port No| BYTE | Each NIC maps to a Port
227 */
228 pr_handle_name("%s BIOS PXE NIC PCI and MAC Information",
229 company);
230 if (h->length < 0x0E) break;
231 /* If the record isn't long enough, we don't have an ID
232 * use 0xFF to use the internal counter.
233 * */
234 nic = h->length > 0x28 ? data[0x28] : 0xFF;
235 dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07],
236 &data[0x08]);
237554 break;
238555
239556 case 212:
281598 pr_subattr("UEFI", "%s", feat & 0x1400 ? "Yes" : "No");
282599 break;
283600
601 case 233:
602 /*
603 * Vendor Specific: HPE ProLiant NIC MAC Information
604 *
605 * This prints the BIOS NIC number,
606 * PCI bus/device/function, and MAC address
607 *
608 * Offset | Name | Width | Description
609 * -------------------------------------
610 * 0x00 | Type | BYTE | 0xE9, NIC structure
611 * 0x01 | Length | BYTE | Length of structure
612 * 0x02 | Handle | WORD | Unique handle
613 * 0x04 | Grp No | WORD | 0 for single segment
614 * 0x06 | Bus No | BYTE | PCI Bus
615 * 0x07 | Dev No | BYTE | PCI Device/Function No
616 * 0x08 | MAC | 32B | MAC addr padded w/ 0s
617 * 0x28 | Port No| BYTE | Each NIC maps to a Port
618 */
619 pr_handle_name("%s BIOS PXE NIC PCI and MAC Information",
620 company);
621 if (h->length < 0x0E) break;
622 /* If the record isn't long enough, we don't have an ID
623 * use 0xFF to use the internal counter.
624 * */
625 nic = h->length > 0x28 ? data[0x28] : 0xFF;
626 dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07],
627 &data[0x08]);
628 break;
629
630 case 236:
631 /*
632 * Vendor Specific: HPE ProLiant HDD Backplane
633 *
634 * Offset | Name | Width | Description
635 * ---------------------------------------
636 * 0x00 | Type | BYTE | 0xEC, HDD Backplane
637 * 0x01 | Length | BYTE | Length of structure
638 * 0x02 | Handle | WORD | Unique handle
639 * 0x04 | I2C Address| BYTE | Backplane FRU I2C Address
640 * 0x05 | Box Number | WORD | Backplane Box Number
641 * 0x07 | NVRAM ID | WORD | Backplane NVRAM ID
642 * 0x09 | WWID | QWORD | SAS Expander WWID
643 * 0x11 | Total Bays | BYTE | Total SAS Bays
644 * 0x12 | A0 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA0
645 * 0x13 | A2 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA2
646 * 0x14 | Name | STRING| (deprecated) Backplane Name
647 */
648 pr_handle_name("%s HDD Backplane FRU Information", company);
649 if (h->length < 0x08) break;
650 pr_attr("FRU I2C Address", "0x%X raw(0x%X)", data[0x4] >> 1, data[0x4]);
651 pr_attr("Box Number", "%d", WORD(data + 0x5));
652 pr_attr("NVRAM ID", "0x%X", WORD(data + 0x7));
653 if (h->length < 0x11) break;
654 pr_attr("SAS Expander WWID", "0x%X", QWORD(data + 0x9));
655 if (h->length < 0x12) break;
656 pr_attr("Total SAS Bays", "%d", data[0x11]);
657 if (h->length < 0x15) break;
658 if (gen < G10P) {
659 pr_attr("A0 Bay Count", "%d", data[0x12]);
660 pr_attr("A2 Bay Count", "%d", data[0x13]);
661 pr_attr("Backplane Name", "%s", dmi_string(h, data[0x14]));
662 }
663 break;
664
665 case 237:
666 /*
667 * Vendor Specific: HPE DIMM Vendor Part Number Information
668 *
669 * Offset | Name | Width | Description
670 * ---------------------------------------
671 * 0x00 | Type | BYTE | 0xED, DIMM Vendor Part Number information record
672 * 0x01 | Length | BYTE | Length of structure
673 * 0x02 | Handle | WORD | Unique handle
674 * 0x04 | Hand Assoc | WORD | Handle to map to Type 17
675 * 0x06 | Manufacture|STRING | DIMM Manufacturer
676 * 0x07 | Part Number|STRING | DIMM Manufacturer's Part Number
677 * 0x08 | Serial Num |STRING | DIMM Vendor Serial Number
678 * 0x09 | Spare Part |STRING | DIMM Spare Part Number
679 */
680 if (gen < G9) return 0;
681 pr_handle_name("%s DIMM Vendor Information", company);
682 if (h->length < 0x08) break;
683 if (!(opt.flags & FLAG_QUIET))
684 pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
685 pr_attr("DIMM Manufacturer", "%s", dmi_string(h, data[0x06]));
686 pr_attr("DIMM Manufacturer Part Number", "%s", dmi_string(h, data[0x07]));
687 if (h->length < 0x09) break;
688 pr_attr("DIMM Vendor Serial Number", "%s", dmi_string(h, data[0x08]));
689 if (h->length < 0x0A) break;
690 pr_attr("DIMM Spare Part Number", "%s", dmi_string(h, data[0x09]));
691 break;
692
693 case 238:
694 /*
695 * Vendor Specific: HPE USB Port Connector Correlation Record
696 *
697 * Offset | Name | Width | Description
698 * ---------------------------------------
699 * 0x00 | Type | BYTE | 0xEE, HP Device Correlation Record
700 * 0x01 | Length | BYTE | Length of structure
701 * 0x02 | Handle | WORD | Unique handle
702 * 0x04 | Hand Assoc | WORD | Handle to map to Type 8
703 * 0x06 | Parent Bus | BYTE | PCI Bus number of USB controller of this port
704 * 0x07 | Par Dev/Fun| BYTE | PCI Dev/Fun of USB Controller of this port
705 * 0x08 | Location | BYTE | Enumerated value of location of USB port
706 * 0x09 | Flags | WORD | USB Shared Management Port
707 * 0x0B | Port Inst | BYTE | Instance number for this type of USB port
708 * 0x0C | Parent Hub | BYTE | Instance number of internal Hub
709 * 0x0D | Port Speed | BYTE | Enumerated value of speed configured by BIOS
710 * 0x0E | Device Path| STRING| UEFI Device Path of USB endpoint
711 */
712 if (gen < G9) return 0;
713 pr_handle_name("%s Proliant USB Port Connector Correlation Record", company);
714 if (h->length < 0x0F) break;
715 if (!(opt.flags & FLAG_QUIET))
716 pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
717 pr_attr("PCI Device", "%02x:%02x.%x", data[0x6],
718 data[0x7] >> 3, data[0x7] & 0x7);
719 dmi_hp_238_loc("Location", data[0x8]);
720 dmi_hp_238_flags("Management Port", WORD(data + 0x9));
721 pr_attr("Port Instance", "%d", data[0xB]);
722 if (data[0xC] != 0xFE)
723 pr_attr("Parent Hub Port Instance", "%d", data[0xC]);
724 else
725 pr_attr("Parent Hub Port Instance", "N/A");
726 dmi_hp_238_speed("Port Speed Capability", data[0xD]);
727 pr_attr("Device Path", "%s", dmi_string(h, data[0xE]));
728 break;
729
730 case 240:
731 /*
732 * Vendor Specific: HPE Proliant Inventory Record
733 *
734 * Reports firmware version information for devices that report their
735 * firmware using their UEFI drivers. Additionally provides association
736 * with other SMBIOS records, such as Type 203 (which in turn is
737 * associated with Types 9, 41, and 228).
738 *
739 * Offset | Name | Width | Description
740 * ---------------------------------------
741 * 0x00 | Type | BYTE | 0xF0, HP Firmware Inventory Record
742 * 0x01 | Length | BYTE | Length of structure
743 * 0x02 | Handle | WORD | Unique handle
744 * 0x04 | Hndl Assoc | WORD | Handle to map to Type 203
745 * 0x06 | Pkg Vers | DWORD | FW Vers Release of All FW in Device
746 * 0x0A | Ver String | STRING| FW Version String
747 * 0x0B | Image Size | QWORD | FW image size (bytes)
748 * 0x13 | Attributes | QWORD | Bitfield: Is attribute defined?
749 * 0x1B | Attr Set | QWORD | BitField: If defined, is attribute set?
750 * 0x23 | Version | DWORD | Lowest supported version.
751 */
752 pr_handle_name("%s Proliant Inventory Record", company);
753 if (h->length < 0x27) break;
754 if (!(opt.flags & FLAG_QUIET))
755 pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
756 pr_attr("Package Version", "0x%08X", DWORD(data + 0x6));
757 pr_attr("Version String", "%s", dmi_string(h, data[0x0A]));
758
759 if (DWORD(data + 0x0B))
760 dmi_print_memory_size("Image Size", QWORD(data + 0xB), 0);
761 else
762 pr_attr("Image Size", "Not Available");
763
764 dmi_hp_240_attr(QWORD(data + 0x13), QWORD(data + 0x1B));
765
766 if (DWORD(data + 0x23))
767 pr_attr("Lowest Supported Version", "0x%08X", DWORD(data + 0x23));
768 else
769 pr_attr("Lowest Supported Version", "Not Available");
770 break;
771
284772 default:
285773 return 0;
286774 }
2020
2121 struct dmi_header;
2222
23 void dmi_set_vendor(const char *s);
23 void dmi_set_vendor(const char *s, const char *p);
2424 int dmi_decode_oem(const struct dmi_header *h);
44 .\"
55 .SH SYNOPSIS
66 .B biosdecode
7 .RB [ OPTIONS ]
7 .RI [ OPTIONS ]
88 .\"
99 .SH DESCRIPTION
1010 .B biosdecode
5858 .\"
5959 .SH OPTIONS
6060 .TP
61 .BR "-d" ", " "--dev-mem FILE"
62 Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
61 .BR "-d" ", " "--dev-mem \fIFILE\fP"
62 Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
6363 .TP
64 .BR " " " " "--pir full"
65 Decode the details of the PCI IRQ routing table
64 .BR " " " " "--pir \fBfull\fP"
65 Decode the details of the PCI IRQ routing table.
66 Only \fBfull\fP mode is supported.
6667 .TP
6768 .BR "-h" ", " "--help"
6869 Display usage information and exit
44 .\"
55 .SH SYNOPSIS
66 .B dmidecode
7 .RB [ OPTIONS ]
7 .RI [ OPTIONS ]
88 .\"
99 .SH DESCRIPTION
1010 .B dmidecode
6262 .\"
6363 .SH OPTIONS
6464 .TP
65 .BR "-d" ", " "--dev-mem FILE"
66 Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
65 .BR "-d" ", " "--dev-mem \fIFILE\fP"
66 Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
6767 .TP
6868 .BR "-q" ", " "--quiet"
6969 Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not
7070 displayed. Meta-data and handle references are hidden.
7171 .TP
72 .BR "-s" ", " "--string KEYWORD"
73 Only display the value of the \s-1DMI\s0 string identified by \fBKEYWORD\fR.
74 \fBKEYWORD\fR must be a keyword from the following list: \fBbios-vendor\fR,
75 \fBbios-version\fR, \fBbios-release-date\fR,
76 \fBbios-revision\fR, \fBfirmware-revision\fR,
77 \fBsystem-manufacturer\fR, \fBsystem-product-name\fR,
78 \fBsystem-version\fR, \fBsystem-serial-number\fR,
79 \fBsystem-uuid\fR, \fBsystem-sku-number\fR, \fBsystem-family\fR,
80 \fBbaseboard-manufacturer\fR, \fBbaseboard-product-name\fR,
81 \fBbaseboard-version\fR, \fBbaseboard-serial-number\fR,
82 \fBbaseboard-asset-tag\fR, \fBchassis-manufacturer\fR,
83 \fBchassis-type\fR,
84 \fBchassis-version\fR, \fBchassis-serial-number\fR,
85 \fBchassis-asset-tag\fR, \fBprocessor-family\fR,
86 \fBprocessor-manufacturer\fR,
87 \fBprocessor-version\fR, \fBprocessor-frequency\fR.
72 .BR "-s" ", " "--string \fIKEYWORD\fP"
73 Only display the value of the \s-1DMI\s0 string identified by \fIKEYWORD\fP.
74 It must be a keyword from the following list:
75 .nh
76 .BR bios\-vendor ,
77 .BR bios\-version ,
78 .BR bios\-release\-date ,
79 .BR bios\-revision ,
80 .BR firmware\-revision ,
81 .BR system\-manufacturer ,
82 .BR system\-product\-name ,
83 .BR system\-version ,
84 .BR system\-serial\-number ,
85 .BR system\-uuid ,
86 .BR system\-sku\-number ,
87 .BR system\-family ,
88 .BR baseboard\-manufacturer ,
89 .BR baseboard\-product\-name ,
90 .BR baseboard\-version ,
91 .BR baseboard\-serial\-number ,
92 .BR baseboard\-asset\-tag ,
93 .BR chassis\-manufacturer ,
94 .BR chassis\-type ,
95 .BR chassis\-version ,
96 .BR chassis\-serial\-number ,
97 .BR chassis\-asset\-tag ,
98 .BR processor\-family ,
99 .BR processor\-manufacturer ,
100 .BR processor\-version ,
101 .BR processor\-frequency .
102 .hy
88103 Each keyword corresponds to a given \s-1DMI\s0 type and a given offset
89104 within this entry type.
90105 Not all strings may be meaningful or even defined on all systems. Some
91106 keywords may return more than one result on some systems (e.g.
92 \fBprocessor-version\fR on a multi-processor system).
93 If \fBKEYWORD\fR is not provided or not valid, a list of all valid
107 .nh
108 .B processor\-version
109 .hy
110 on a multi-processor system).
111 If \fIKEYWORD\fP is not provided or not valid, a list of all valid
94112 keywords is printed and
95113 .B dmidecode
96114 exits with an error.
103121 .IR /sys/devices/virtual/dmi/id .
104122 Most of these files are even readable by regular users.
105123 .TP
106 .BR "-t" ", " "--type TYPE"
107 Only display the entries of type \fBTYPE\fR. \fBTYPE\fR can be either a
124 .BR "-t" ", " "--type \fITYPE\fP"
125 Only display the entries of type \fITYPE\fP. It can be either a
108126 \s-1DMI\s0 type number, or a comma-separated list of type numbers, or a
109 keyword from the following list: \fBbios\fR, \fBsystem\fR,
110 \fBbaseboard\fR, \fBchassis\fR, \fBprocessor\fR, \fBmemory\fR,
111 \fBcache\fR, \fBconnector\fR, \fBslot\fR. Refer to the DMI TYPES section
112 below for details.
127 keyword from the following list:
128 .nh
129 .BR bios ,
130 .BR system ,
131 .BR baseboard ,
132 .BR chassis ,
133 .BR processor ,
134 .BR memory ,
135 .BR cache ,
136 .BR connector ,
137 .BR slot .
138 .hy
139 Refer to the DMI TYPES section below for details.
113140 If this option is used more than once, the set of displayed entries will be
114141 the union of all the given types.
115 If \fBTYPE\fR is not provided or not valid, a list of all valid keywords
142 If \fITYPE\fP is not provided or not valid, a list of all valid keywords
116143 is printed and
117144 .B dmidecode
118145 exits with an error.
119146 .TP
120 .BR "-H" ", " "--handle HANDLE"
121 Only display the entry whose handle matches \fBHANDLE\fR. \fBHANDLE\fR
122 is a 16-bit integer.
147 .BR "-H" ", " "--handle \fIHANDLE\fP"
148 Only display the entry whose handle matches \fIHANDLE\fP.
149 \fIHANDLE\fP is a 16-bit integer.
123150 .TP
124151 .BR "-u" ", " "--dump"
125152 Do not decode the entries, dump their contents as hexadecimal instead.
127154 you. The strings attached to each entry are displayed as both
128155 hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging.
129156 .TP
130 .BR " " " " "--dump-bin FILE"
157 .BR " " " " "--dump-bin \fIFILE\fP"
131158 Do not decode the entries, instead dump the DMI data to a file in binary
132 form. The generated file is suitable to pass to \fB--from-dump\fR
159 form. The generated file is suitable to pass to \fB--from-dump\fP
133160 later.
134161 .TP
135 .BR " " " " "--from-dump FILE"
136 Read the DMI data from a binary file previously generated using
137 \fB--dump-bin\fR.
162 .BR " " " " "--from-dump \fIFILE\fP"
163 Read the DMI data from a binary file previously generated using
164 \fB--dump-bin\fP.
138165 .TP
139166 .BR " " " " "--no-sysfs"
140167 Do not attempt to read DMI data from sysfs files. This is mainly useful for
141168 debugging.
142169 .TP
143 .BR " " " " "--oem-string N"
144 Only display the value of the \s-1OEM\s0 string number \fBN\fR. The first
145 \s-1OEM\s0 string has number 1. With special value "count", return the
170 .BR " " " " "--oem-string \fIN\fP"
171 Only display the value of the \s-1OEM\s0 string number \fIN\fP. The first
172 \s-1OEM\s0 string has number \fB1\fP. With special value \fBcount\fP, return the
146173 number of OEM strings instead.
147174 .TP
148175 .BR "-h" ", " "--help"
151178 .BR "-V" ", " "--version"
152179 Display the version and exit
153180 .P
154 Options --string, --type, --dump-bin and --oem-string
181 Options
182 .BR --string ,
183 .BR --type,
184 .BR --dump-bin " and " --oem-string
155185 determine the output format and are mutually exclusive.
156186 .P
157187 Please note in case of
219249 will display these entries by default, but it can only decode them
220250 when the vendors have contributed documentation or code for them.
221251
222 Keywords can be used instead of type numbers with \fB--type\fR.
252 Keywords can be used instead of type numbers with \fB--type\fP.
223253 Each keyword is equivalent to a list of type numbers:
224254
225255 .TS
249279 dmidecode --type BIOS
250280 .\"
251281 .SH BINARY DUMP FILE FORMAT
252 The binary dump files generated by --dump-bin and read using --from-dump
282 The binary dump files generated by \fB--dump-bin\fP and read using \fB--from-dump\fP
253283 are formatted as follows:
254284 .IP \(bu "\w'\(bu'u+1n"
255285 The SMBIOS or DMI entry point is located at offset 0x00.
44 .\"
55 .SH SYNOPSIS
66 .B ownership
7 .RB [ OPTIONS ]
7 .RI [ OPTIONS ]
88 .\"
99 .SH DESCRIPTION
1010 .B ownership
1818 .\"
1919 .SH OPTIONS
2020 .TP
21 .BR "-d" ", " "--dev-mem FILE"
22 Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
21 .BR "-d" ", " "--dev-mem \fIFILE\fP"
22 Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
2323 .TP
2424 .BR "-h" ", " "--help"
2525 Display usage information and exit
44 .\"
55 .SH SYNOPSIS
66 .B vpddecode
7 .RB [ OPTIONS ]
7 .RI [ OPTIONS ]
88 .\"
99 .SH DESCRIPTION
1010 .B vpddecode
3131 .\"
3232 .SH OPTIONS
3333 .TP
34 .BR "-d" ", " "--dev-mem FILE"
35 Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
34 .BR "-d" ", " "--dev-mem \fIFILE\fP"
35 Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
3636 .TP
37 .BR "-s" ", " "--string KEYWORD"
38 Only display the value of the \s-1VPD\s0 string identified by \fBKEYWORD\fR.
39 \fBKEYWORD\fR must be a keyword from the following list: \fBbios-build-id\fR,
40 \fBbox-serial-number\fR, \fBmotherboard-serial-number\fR,
41 \fBmachine-type-model\fR, \fBbios-release-date\fR.
37 .BR "-s" ", " "--string \fIKEYWORD\fP"
38 Only display the value of the \s-1VPD\s0 string identified by \fIKEYWORD\fP.
39 It must be a keyword from the following list:
40 .nh
41 .BR bios-build-id ,
42 .BR box-serial-number ,
43 .BR motherboard-serial-number ,
44 .BR machine-type-model ,
45 .BR bios-release-date .
46 .hy
4247 Each keyword corresponds to an offset and a length within the \s-1VPD\s0
4348 record.
4449 Not all strings may be defined on all \s-1VPD\s0-enabled systems.
45 If \fBKEYWORD\fR is not provided or not valid, a list of all valid
50 If \fIKEYWORD\fP is not provided or not valid, a list of all valid
4651 keywords is printed and
4752 .B vpddecode
4853 exits with an error.
4954 This option cannot be used more than once.
50 Mutually exclusive with \fB--dump\fR.
55 Mutually exclusive with \fB--dump\fP.
5156 .TP
5257 .BR "-u" ", " "--dump"
5358 Do not decode the VPD records, dump their contents as hexadecimal instead.
5459 Note that this is still a text output, no binary data will be thrown upon
5560 you. ASCII equivalent is displayed when possible. This option is mainly
5661 useful for debugging.
57 Mutually exclusive with \fB--string\fR.
62 Mutually exclusive with \fB--string\fP.
5863 .TP
5964 .BR "-h" ", " "--help"
6065 Display usage information and exit
0 #define VERSION "3.3"
0 #define VERSION "3.4"