Skip to content

Commit 17d64dc

Browse files
committed
dmidecode: Preliminary support for 64-bit entry point
Add preliminary support for the new _SM3_ 64-bit entry point defined in the SMBIOS specification version 3.0.0. 64-bit addresses are not actually supported yet, nor tables with size over 16-bit.
1 parent ce0ffde commit 17d64dc

File tree

2 files changed

+88
-10
lines changed

2 files changed

+88
-10
lines changed

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2015-04-27 Jean Delvare <[email protected]>
2+
3+
* dmidecode.c: Add preliminary support for the new _SM3_ 64-bit
4+
entry point defined in the SMBIOS specification version 3.0.0.
5+
16
2015-04-21 Roy Franz <[email protected]>
27

38
* util.c, util.h: Add utility function read_file, which reads an

dmidecode.c

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* DMI Decode
33
*
44
* Copyright (C) 2000-2002 Alan Cox <[email protected]>
5-
* Copyright (C) 2002-2014 Jean Delvare <[email protected]>
5+
* Copyright (C) 2002-2015 Jean Delvare <[email protected]>
66
*
77
* This program is free software; you can redistribute it and/or modify
88
* it under the terms of the GNU General Public License as published by
@@ -4360,8 +4360,9 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem,
43604360
{
43614361
if (opt.type == NULL)
43624362
{
4363-
printf("%u structures occupying %u bytes.\n",
4364-
num, len);
4363+
if (num)
4364+
printf("%u structures occupying %u bytes.\n",
4365+
num, len);
43654366
if (!(opt.flags & FLAG_FROM_DUMP))
43664367
printf("Table at 0x%08X.\n", base);
43674368
}
@@ -4388,7 +4389,8 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem,
43884389
}
43894390

43904391
data = buf;
4391-
while (i < num && data+4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
4392+
while ((i < num || !num)
4393+
&& data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
43924394
{
43934395
u8 *next;
43944396
struct dmi_header h;
@@ -4454,12 +4456,17 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem,
44544456
i++;
44554457
}
44564458

4459+
/*
4460+
* SMBIOS v3 64-bit entry points do not announce a structures count,
4461+
* and only indicate a maximum size for the table.
4462+
*/
44574463
if (!(opt.flags & FLAG_QUIET))
44584464
{
4459-
if (i != num)
4465+
if (num && i != num)
44604466
printf("Wrong DMI structures count: %d announced, "
44614467
"only %d decoded.\n", num, i);
4462-
if (data - buf != len)
4468+
if (data - buf > len
4469+
|| (num && data - buf < len))
44634470
printf("Wrong DMI structures length: %d bytes "
44644471
"announced, structures occupy %d bytes.\n",
44654472
len, (unsigned int)(data - buf));
@@ -4483,6 +4490,59 @@ static void overwrite_dmi_address(u8 *buf)
44834490
buf[0x0B] = 0;
44844491
}
44854492

4493+
/* Same thing for SMBIOS3 entry points */
4494+
static void overwrite_smbios3_address(u8 *buf)
4495+
{
4496+
buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13]
4497+
+ buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32;
4498+
buf[0x10] = 32;
4499+
buf[0x11] = 0;
4500+
buf[0x12] = 0;
4501+
buf[0x13] = 0;
4502+
buf[0x14] = 0;
4503+
buf[0x15] = 0;
4504+
buf[0x16] = 0;
4505+
buf[0x17] = 0;
4506+
}
4507+
4508+
static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
4509+
{
4510+
u16 ver;
4511+
u64 offset;
4512+
4513+
if (!checksum(buf, buf[0x06]))
4514+
return 0;
4515+
4516+
ver = (buf[0x07] << 8) + buf[0x08];
4517+
if (!(opt.flags & FLAG_QUIET))
4518+
printf("SMBIOS %u.%u.%u present.\n",
4519+
buf[0x07], buf[0x08], buf[0x09]);
4520+
4521+
offset = QWORD(buf + 0x10);
4522+
if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h)
4523+
{
4524+
fprintf(stderr, "64-bit addresses not supported, sorry.\n");
4525+
return 0;
4526+
}
4527+
4528+
dmi_table(offset.l, WORD(buf + 0x0C), 0, ver, devmem, flags);
4529+
4530+
if (opt.flags & FLAG_DUMP_BIN)
4531+
{
4532+
u8 crafted[32];
4533+
4534+
memcpy(crafted, buf, 32);
4535+
overwrite_smbios3_address(crafted);
4536+
4537+
if (!(opt.flags & FLAG_QUIET))
4538+
printf("# Writing %d bytes to %s.\n", crafted[0x06],
4539+
opt.dumpfile);
4540+
write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1);
4541+
}
4542+
4543+
return 1;
4544+
}
4545+
44864546
static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
44874547
{
44884548
u16 ver;
@@ -4659,7 +4719,12 @@ int main(int argc, char * const argv[])
46594719
goto exit_free;
46604720
}
46614721

4662-
if (memcmp(buf, "_SM_", 4) == 0)
4722+
if (memcmp(buf, "_SM3_", 5) == 0)
4723+
{
4724+
if (smbios3_decode(buf, opt.dumpfile, 0))
4725+
found++;
4726+
}
4727+
else if (memcmp(buf, "_SM_", 4) == 0)
46634728
{
46644729
if (smbios_decode(buf, opt.dumpfile, 0))
46654730
found++;
@@ -4684,8 +4749,8 @@ int main(int argc, char * const argv[])
46844749
printf("Getting SMBIOS data from sysfs.\n");
46854750
if (memcmp(buf, "_SM3_", 5) == 0)
46864751
{
4687-
if (!(opt.flags & FLAG_QUIET))
4688-
printf("SMBIOS v3 64-bit entry point found, but not supported.\n");
4752+
if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
4753+
found++;
46894754
}
46904755
else if (memcmp(buf, "_SM_", 4) == 0)
46914756
{
@@ -4740,7 +4805,15 @@ int main(int argc, char * const argv[])
47404805

47414806
for (fp = 0; fp <= 0xFFF0; fp += 16)
47424807
{
4743-
if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
4808+
if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0)
4809+
{
4810+
if (smbios3_decode(buf + fp, opt.devmem, 0))
4811+
{
4812+
found++;
4813+
fp += 16;
4814+
}
4815+
}
4816+
else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
47444817
{
47454818
if (smbios_decode(buf+fp, opt.devmem, 0))
47464819
{

0 commit comments

Comments
 (0)