Skip to content

Commit c1a2520

Browse files
committedDec 16, 2022
dmidecode: Add a --no-quirks option
This new option is aimed at firmware developers to help them validate their work. When this option is used, quirks and fixups are disabled in dmidecode, which will dumbly decode everything found in the table even if it is known to be incorrect. Signed-off-by: Jean Delvare <jdelvare@suse.de>
1 parent 67dc0b2 commit c1a2520

File tree

4 files changed

+39
-22
lines changed

4 files changed

+39
-22
lines changed
 

‎dmidecode.c

+28-22
Original file line numberDiff line numberDiff line change
@@ -2722,7 +2722,7 @@ static void dmi_memory_device_width(const char *attr, u16 code)
27222722
/*
27232723
* If no memory module is present, width may be 0
27242724
*/
2725-
if (code == 0xFFFF || code == 0)
2725+
if (code == 0xFFFF || (code == 0 && !(opt.flags & FLAG_NO_QUIRKS)))
27262726
pr_attr(attr, "Unknown");
27272727
else
27282728
pr_attr(attr, "%u bits", code);
@@ -4720,7 +4720,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
47204720
dmi_memory_device_type_detail(WORD(data + 0x13));
47214721
if (h->length < 0x17) break;
47224722
/* If no module is present, the remaining fields are irrelevant */
4723-
if (WORD(data + 0x0C) == 0)
4723+
if (WORD(data + 0x0C) == 0 && !(opt.flags & FLAG_NO_QUIRKS))
47244724
break;
47254725
dmi_memory_device_speed("Speed", WORD(data + 0x15),
47264726
h->length >= 0x5C ?
@@ -5544,7 +5544,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
55445544
}
55455545

55465546
/* Fixup a common mistake */
5547-
if (h.type == 34)
5547+
if (h.type == 34 && !(opt.flags & FLAG_NO_QUIRKS))
55485548
dmi_fixup_type_34(&h, display);
55495549

55505550
if (display)
@@ -5735,6 +5735,29 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
57355735
return 1;
57365736
}
57375737

5738+
static void dmi_fixup_version(u16 *ver)
5739+
{
5740+
/* Some BIOS report weird SMBIOS version, fix that up */
5741+
switch (*ver)
5742+
{
5743+
case 0x021F:
5744+
case 0x0221:
5745+
if (!(opt.flags & FLAG_QUIET))
5746+
fprintf(stderr,
5747+
"SMBIOS version fixup (2.%d -> 2.%d).\n",
5748+
*ver & 0xFF, 3);
5749+
*ver = 0x0203;
5750+
break;
5751+
case 0x0233:
5752+
if (!(opt.flags & FLAG_QUIET))
5753+
fprintf(stderr,
5754+
"SMBIOS version fixup (2.%d -> 2.%d).\n",
5755+
51, 6);
5756+
*ver = 0x0206;
5757+
break;
5758+
}
5759+
}
5760+
57385761
static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
57395762
{
57405763
u16 ver;
@@ -5759,25 +5782,8 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
57595782
return 0;
57605783

57615784
ver = (buf[0x06] << 8) + buf[0x07];
5762-
/* Some BIOS report weird SMBIOS version, fix that up */
5763-
switch (ver)
5764-
{
5765-
case 0x021F:
5766-
case 0x0221:
5767-
if (!(opt.flags & FLAG_QUIET))
5768-
fprintf(stderr,
5769-
"SMBIOS version fixup (2.%d -> 2.%d).\n",
5770-
ver & 0xFF, 3);
5771-
ver = 0x0203;
5772-
break;
5773-
case 0x0233:
5774-
if (!(opt.flags & FLAG_QUIET))
5775-
fprintf(stderr,
5776-
"SMBIOS version fixup (2.%d -> 2.%d).\n",
5777-
51, 6);
5778-
ver = 0x0206;
5779-
break;
5780-
}
5785+
if (!(opt.flags & FLAG_NO_QUIRKS))
5786+
dmi_fixup_version(&ver);
57815787
if (!(opt.flags & FLAG_QUIET))
57825788
pr_info("SMBIOS %u.%u present.",
57835789
ver >> 8, ver & 0xFF);

‎dmiopt.c

+5
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ int parse_command_line(int argc, char * const argv[])
270270
{ "dev-mem", required_argument, NULL, 'd' },
271271
{ "help", no_argument, NULL, 'h' },
272272
{ "quiet", no_argument, NULL, 'q' },
273+
{ "no-quirks", no_argument, NULL, 'Q' },
273274
{ "string", required_argument, NULL, 's' },
274275
{ "type", required_argument, NULL, 't' },
275276
{ "dump", no_argument, NULL, 'u' },
@@ -302,6 +303,9 @@ int parse_command_line(int argc, char * const argv[])
302303
case 'q':
303304
opt.flags |= FLAG_QUIET;
304305
break;
306+
case 'Q':
307+
opt.flags |= FLAG_NO_QUIRKS;
308+
break;
305309
case 's':
306310
if (parse_opt_string(optarg) < 0)
307311
return -1;
@@ -371,6 +375,7 @@ void print_help(void)
371375
" -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
372376
" -h, --help Display this help text and exit\n"
373377
" -q, --quiet Less verbose output\n"
378+
" --no-quirks Decode everything without quirks\n"
374379
" -s, --string KEYWORD Only display the value of the given DMI string\n"
375380
" -t, --type TYPE Only display the entries of given type\n"
376381
" -H, --handle HANDLE Only display the entry of given handle\n"

‎dmiopt.h

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern struct opt opt;
4646
#define FLAG_DUMP_BIN (1 << 4)
4747
#define FLAG_FROM_DUMP (1 << 5)
4848
#define FLAG_NO_SYSFS (1 << 6)
49+
#define FLAG_NO_QUIRKS (1 << 7)
4950

5051
int parse_command_line(int argc, char * const argv[]);
5152
void print_help(void);

‎man/dmidecode.8

+5
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
7070
Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not
7171
displayed. Meta-data and handle references are hidden.
7272
.TP
73+
.BR " " " " "--no-quirks"
74+
Decode everything exactly as it is in the table, without trying to fix up
75+
common mistakes or hide irrelevant fields.
76+
This mode is primarily aimed at firmware developers.
77+
.TP
7378
.BR "-s" ", " "--string \fIKEYWORD\fP"
7479
Only display the value of the \s-1DMI\s0 string identified by \fIKEYWORD\fP.
7580
It must be a keyword from the following list:

0 commit comments

Comments
 (0)
Please sign in to comment.