From 53bafb796b654d1f7206196fd97cf8ba0b08ad7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 28 Sep 2015 12:29:58 +0200 Subject: Imported Upstream version 3.0 --- dmidecode.c | 419 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 315 insertions(+), 104 deletions(-) (limited to 'dmidecode.c') diff --git a/dmidecode.c b/dmidecode.c index 0599759..f41c85b 100644 --- a/dmidecode.c +++ b/dmidecode.c @@ -2,7 +2,7 @@ * DMI Decode * * Copyright (C) 2000-2002 Alan Cox - * Copyright (C) 2002-2010 Jean Delvare + * Copyright (C) 2002-2015 Jean Delvare * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ * are deemed to be part of the source code. * * Unless specified otherwise, all references are aimed at the "System - * Management BIOS Reference Specification, Version 2.8.0" document, + * Management BIOS Reference Specification, Version 3.0.0" document, * available from http://www.dmtf.org/standards/smbios. * * Note to contributors: @@ -69,12 +69,30 @@ #define out_of_spec "" static const char *bad_index = ""; -#define SUPPORTED_SMBIOS_VER 0x0207 +#define SUPPORTED_SMBIOS_VER 0x0300 + +#define FLAG_NO_FILE_OFFSET (1 << 0) +#define FLAG_STOP_AT_EOT (1 << 1) + +#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point" +#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI" /* * Type-independant Stuff */ +/* Returns 1 if the buffer contains only printable ASCII characters */ +int is_printable(const u8 *data, int len) +{ + int i; + + for (i = 0; i < len; i++) + if (data[i] < 32 || data[i] >= 127) + return 0; + + return 1; +} + const char *dmi_string(const struct dmi_header *dm, u8 s) { char *bp = (char *)dm->data; @@ -529,12 +547,15 @@ static const char *dmi_chassis_type(u8 code) "CompactPCI", "AdvancedTCA", "Blade", - "Blade Enclosing" /* 0x1D */ + "Blade Enclosing", + "Tablet", + "Convertible", + "Detachable" /* 0x20 */ }; code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */ - if (code >= 0x01 && code <= 0x1D) + if (code >= 0x01 && code <= 0x20) return type[code - 0x01]; return out_of_spec; } @@ -695,6 +716,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { 0x29, "Core Duo Mobile" }, { 0x2A, "Core Solo Mobile" }, { 0x2B, "Atom" }, + { 0x2C, "Core M" }, { 0x30, "Alpha" }, { 0x31, "Alpha 21064" }, @@ -712,7 +734,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { 0x3D, "Opteron 6200" }, { 0x3E, "Opteron 4200" }, { 0x3F, "FX" }, - { 0x40, "MIPS" }, { 0x41, "MIPS R4000" }, { 0x42, "MIPS R4200" }, @@ -729,7 +750,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { 0x4D, "Opteron 6300" }, { 0x4E, "Opteron 3300" }, { 0x4F, "FirePro" }, - { 0x50, "SPARC" }, { 0x51, "SuperSPARC" }, { 0x52, "MicroSPARC II" }, @@ -746,6 +766,9 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { 0x63, "68010" }, { 0x64, "68020" }, { 0x65, "68030" }, + { 0x66, "Athlon X4" }, + { 0x67, "Opteron X1000" }, + { 0x68, "Opteron X2000" }, { 0x70, "Hobbit" }, @@ -821,7 +844,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { 0xC9, "G4" }, { 0xCA, "G5" }, { 0xCB, "ESA/390 G6" }, - { 0xCC, "z/Architectur" }, + { 0xCC, "z/Architecture" }, { 0xCD, "Core i5" }, { 0xCE, "Core i3" }, @@ -1014,11 +1037,11 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch sig = 1; else if ((type >= 0x18 && type <= 0x1D) /* AMD */ || type == 0x1F /* AMD */ - || (type >= 0x38 && type <= 0x3E) /* AMD */ - || (type >= 0x46 && type <= 0x49) /* AMD */ + || (type >= 0x38 && type <= 0x3F) /* AMD */ + || (type >= 0x46 && type <= 0x4F) /* AMD */ || (type >= 0x83 && type <= 0x8F) /* AMD */ || (type >= 0xB6 && type <= 0xB7) /* AMD */ - || (type >= 0xE6 && type <= 0xEF)) /* AMD */ + || (type >= 0xE4 && type <= 0xEF)) /* AMD */ sig = 2; else if (type == 0x01 || type == 0x02) { @@ -1173,10 +1196,14 @@ static const char *dmi_processor_upgrade(u8 code) "Socket FM1", "Socket FM2", "Socket LGA2011-3", - "Socket LGA1356-3" /* 0x2C */ + "Socket LGA1356-3", + "Socket LGA1150", + "Socket BGA1168", + "Socket BGA1234", + "Socket BGA1364" /* 0x30 */ }; - if (code >= 0x01 && code <= 0x2A) + if (code >= 0x01 && code <= 0x30) return upgrade[code - 0x01]; return out_of_spec; } @@ -1672,7 +1699,20 @@ static const char *dmi_slot_type(u8 code) "AGP 2x", "AGP 4x", "PCI-X", - "AGP 8x" /* 0x13 */ + "AGP 8x", + "M.2 Socket 1-DP", + "M.2 Socket 1-SD", + "M.2 Socket 2", + "M.2 Socket 3", + "MXM Type I", + "MXM Type II", + "MXM Type III", + "MXM Type III-HE", + "MXM Type IV", + "MXM 3.0 Type A", + "MXM 3.0 Type B", + "PCI Express 2 SFF-8639", + "PCI Express 3 SFF-8639" /* 0x20 */ }; static const char *type_0xA0[] = { "PC-98/C20", /* 0xA0 */ @@ -1699,8 +1739,12 @@ static const char *dmi_slot_type(u8 code) "PCI Express 3 x8", "PCI Express 3 x16" /* 0xB6 */ }; + /* + * Note to developers: when adding entries to these lists, check if + * function dmi_slot_id below needs updating too. + */ - if (code >= 0x01 && code <= 0x13) + if (code >= 0x01 && code <= 0x20) return type[code - 0x01]; if (code >= 0xA0 && code <= 0xB6) return type_0xA0[code - 0xA0]; @@ -1780,6 +1824,8 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix) case 0x11: /* AGP */ case 0x12: /* PCI-X */ case 0x13: /* AGP */ + case 0x1F: /* PCI Express 2 */ + case 0x20: /* PCI Express 3 */ case 0xA5: /* PCI Express */ case 0xA6: /* PCI Express */ case 0xA7: /* PCI Express */ @@ -1792,6 +1838,12 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix) case 0xAE: /* PCI Express 2 */ case 0xAF: /* PCI Express 2 */ case 0xB0: /* PCI Express 2 */ + case 0xB1: /* PCI Express 3 */ + case 0xB2: /* PCI Express 3 */ + case 0xB3: /* PCI Express 3 */ + case 0xB4: /* PCI Express 3 */ + case 0xB5: /* PCI Express 3 */ + case 0xB6: /* PCI Express 3 */ printf("%sID: %u\n", prefix, code1); break; case 0x07: /* PCMCIA */ @@ -2236,7 +2288,7 @@ static void dmi_memory_voltage_value(u16 code) if (code == 0) printf(" Unknown"); else - printf(" %.3f V", (float)(i16)code / 1000); + printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000); } static const char *dmi_memory_device_form_factor(u8 code) @@ -2303,10 +2355,15 @@ static const char *dmi_memory_device_type(u8 code) "Reserved", "Reserved", "DDR3", - "FBD2", /* 0x19 */ + "FBD2", + "DDR4", + "LPDDR", + "LPDDR2", + "LPDDR3", + "LPDDR4" /* 0x1E */ }; - if (code >= 0x01 && code <= 0x19) + if (code >= 0x01 && code <= 0x1E) return type[code - 0x01]; return out_of_spec; } @@ -2338,7 +2395,7 @@ static void dmi_memory_device_type_detail(u16 code) { int i; - for (i = 1; i <= 14; i++) + for (i = 1; i <= 15; i++) if (code & (1 << i)) printf(" %s", detail[i - 1]); } @@ -2883,6 +2940,25 @@ static void dmi_64bit_memory_error_address(u64 code) * 7.35 Management Device (Type 34) */ +/* + * Several boards have a bug where some type 34 structures have their + * length incorrectly set to 0x10 instead of 0x0B. This causes the + * first 5 characters of the device name to be trimmed. It's easy to + * check and fix, so do it, but warn. + */ +static void dmi_fixup_type_34(struct dmi_header *h) +{ + u8 *p = h->data; + + /* Make sure the hidden data is ASCII only */ + if (h->length == 0x10 + && is_printable(p + 0x0B, 0x10 - 0x0B)) + { + printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B); + h->length = 0x0B; + } +} + static const char *dmi_management_device_type(u8 code) { /* 7.35.1 */ @@ -3155,7 +3231,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) const u8 *data = h->data; /* - * Note: DMI types 37, 39 and 40 are untested + * Note: DMI types 37 and 42 are untested */ switch (h->type) { @@ -3350,11 +3426,17 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) dmi_string(h, data[0x22])); if (h->length < 0x28) break; if (data[0x23] != 0) - printf("\tCore Count: %u\n", data[0x23]); + printf("\tCore Count: %u\n", + h->length >= 0x2C && data[0x23] == 0xFF ? + WORD(data + 0x2A) : data[0x23]); if (data[0x24] != 0) - printf("\tCore Enabled: %u\n", data[0x24]); + printf("\tCore Enabled: %u\n", + h->length >= 0x2E && data[0x24] == 0xFF ? + WORD(data + 0x2C) : data[0x24]); if (data[0x25] != 0) - printf("\tThread Count: %u\n", data[0x25]); + printf("\tThread Count: %u\n", + h->length >= 0x30 && data[0x25] == 0xFF ? + WORD(data + 0x2E) : data[0x25]); printf("\tCharacteristics:"); dmi_processor_characteristics(WORD(data + 0x26), "\t\t"); break; @@ -3657,13 +3739,13 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) dmi_memory_device_speed(WORD(data + 0x20)); printf("\n"); if (h->length < 0x28) break; - printf("\tMinimum voltage: "); + printf("\tMinimum Voltage:"); dmi_memory_voltage_value(WORD(data + 0x22)); printf("\n"); - printf("\tMaximum voltage: "); + printf("\tMaximum Voltage:"); dmi_memory_voltage_value(WORD(data + 0x24)); printf("\n"); - printf("\tConfigured voltage: "); + printf("\tConfigured Voltage:"); dmi_memory_voltage_value(WORD(data + 0x26)); printf("\n"); break; @@ -4212,8 +4294,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) case 40: /* 7.41 Additional Information */ if (h->length < 0x0B) break; - if (!(opt.flags & FLAG_QUIET)) - dmi_additional_info(h, ""); + if (opt.flags & FLAG_QUIET) + return; + dmi_additional_info(h, ""); break; case 41: /* 7.42 Onboard Device Extended Information */ @@ -4306,65 +4389,21 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver } } -static void dmi_table_dump(u32 base, u16 len, const char *devmem) +static void dmi_table_dump(const u8 *buf, u32 len) { - u8 *buf; - - if ((buf = mem_chunk(base, len, devmem)) == NULL) - { - fprintf(stderr, "Failed to read table, sorry.\n"); - return; - } - if (!(opt.flags & FLAG_QUIET)) printf("# Writing %d bytes to %s.\n", len, opt.dumpfile); write_dump(32, len, buf, opt.dumpfile, 0); - free(buf); } -static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) +static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) { - u8 *buf; u8 *data; int i = 0; - if (ver > SUPPORTED_SMBIOS_VER) - { - printf("# SMBIOS implementations newer than version %u.%u are not\n" - "# fully supported by this version of dmidecode.\n", - SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); - } - - if (opt.flags & FLAG_DUMP_BIN) - { - dmi_table_dump(base, len, devmem); - return; - } - - if (!(opt.flags & FLAG_QUIET)) - { - if (opt.type == NULL) - { - printf("%u structures occupying %u bytes.\n", - num, len); - if (!(opt.flags & FLAG_FROM_DUMP)) - printf("Table at 0x%08X.\n", base); - } - printf("\n"); - } - - if ((buf = mem_chunk(base, len, devmem)) == NULL) - { - fprintf(stderr, "Table is unreachable, sorry." -#ifndef USE_MMAP - " Try compiling dmidecode with -DUSE_MMAP." -#endif - "\n"); - return; - } - data = buf; - while (i < num && data+4 <= buf + len) /* 4 is the length of an SMBIOS structure header */ + while ((i < num || !num) + && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */ { u8 *next; struct dmi_header h; @@ -4372,7 +4411,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) to_dmi_header(&h, data); display = ((opt.type == NULL || opt.type[h.type]) - && !((opt.flags & FLAG_QUIET) && (h.type > 39 && h.type <= 127)) + && !((opt.flags & FLAG_QUIET) && (h.type == 126 || h.type == 127)) && !opt.string); /* @@ -4399,17 +4438,22 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) h.handle, h.type, h.length); /* assign vendor for vendor-specific decodes later */ - if (h.type == 0 && h.length >= 5) + if (h.type == 1 && h.length >= 5) dmi_set_vendor(dmi_string(&h, data[0x04])); + /* Fixup a common mistake */ + if (h.type == 34) + dmi_fixup_type_34(&h); + /* look for the next handle */ next = data + h.length; - while (next - buf + 1 < len && (next[0] != 0 || next[1] != 0)) + while ((unsigned long)(next - buf + 1) < len + && (next[0] != 0 || next[1] != 0)) next++; next += 2; if (display) { - if (next - buf <= len) + if ((unsigned long)(next - buf) <= len) { if (opt.flags & FLAG_DUMP) { @@ -4428,19 +4472,79 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) data = next; i++; + + /* SMBIOS v3 requires stopping at this marker */ + if (h.type == 127 && (flags & FLAG_STOP_AT_EOT)) + break; } + /* + * SMBIOS v3 64-bit entry points do not announce a structures count, + * and only indicate a maximum size for the table. + */ if (!(opt.flags & FLAG_QUIET)) { - if (i != num) + if (num && i != num) printf("Wrong DMI structures count: %d announced, " "only %d decoded.\n", num, i); - if (data - buf != len) - printf("Wrong DMI structures length: %d bytes " - "announced, structures occupy %d bytes.\n", - len, (unsigned int)(data - buf)); + if ((unsigned long)(data - buf) > len + || (num && (unsigned long)(data - buf) < len)) + printf("Wrong DMI structures length: %u bytes " + "announced, structures occupy %lu bytes.\n", + len, (unsigned long)(data - buf)); + } +} + +static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem, + u32 flags) +{ + u8 *buf; + + if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET)) + { + printf("# SMBIOS implementations newer than version %u.%u are not\n" + "# fully supported by this version of dmidecode.\n", + SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF); } + if (!(opt.flags & FLAG_QUIET)) + { + if (opt.type == NULL) + { + if (num) + printf("%u structures occupying %u bytes.\n", + num, len); + if (!(opt.flags & FLAG_FROM_DUMP)) + printf("Table at 0x%08llX.\n", + (unsigned long long)base); + } + printf("\n"); + } + + /* + * When we are reading the DMI table from sysfs, we want to print + * the address of the table (done above), but the offset of the + * data in the file is 0. When reading from /dev/mem, the offset + * in the file is the address. + */ + if (flags & FLAG_NO_FILE_OFFSET) + base = 0; + + if ((buf = mem_chunk(base, len, devmem)) == NULL) + { + fprintf(stderr, "Table is unreachable, sorry." +#ifndef USE_MMAP + " Try compiling dmidecode with -DUSE_MMAP." +#endif + "\n"); + return; + } + + if (opt.flags & FLAG_DUMP_BIN) + dmi_table_dump(buf, len); + else + dmi_table_decode(buf, len, num, ver, flags); + free(buf); } @@ -4459,7 +4563,61 @@ static void overwrite_dmi_address(u8 *buf) buf[0x0B] = 0; } -static int smbios_decode(u8 *buf, const char *devmem) +/* Same thing for SMBIOS3 entry points */ +static void overwrite_smbios3_address(u8 *buf) +{ + buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13] + + buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32; + buf[0x10] = 32; + buf[0x11] = 0; + buf[0x12] = 0; + buf[0x13] = 0; + buf[0x14] = 0; + buf[0x15] = 0; + buf[0x16] = 0; + buf[0x17] = 0; +} + +static int smbios3_decode(u8 *buf, const char *devmem, u32 flags) +{ + u16 ver; + u64 offset; + + if (!checksum(buf, buf[0x06])) + return 0; + + ver = (buf[0x07] << 8) + buf[0x08]; + if (!(opt.flags & FLAG_QUIET)) + printf("SMBIOS %u.%u.%u present.\n", + buf[0x07], buf[0x08], buf[0x09]); + + offset = QWORD(buf + 0x10); + if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8) + { + fprintf(stderr, "64-bit addresses not supported, sorry.\n"); + return 0; + } + + dmi_table(((off_t)offset.h << 32) | offset.l, + WORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT); + + if (opt.flags & FLAG_DUMP_BIN) + { + u8 crafted[32]; + + memcpy(crafted, buf, 32); + overwrite_smbios3_address(crafted); + + if (!(opt.flags & FLAG_QUIET)) + printf("# Writing %d bytes to %s.\n", crafted[0x06], + opt.dumpfile); + write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1); + } + + return 1; +} + +static int smbios_decode(u8 *buf, const char *devmem, u32 flags) { u16 ver; @@ -4491,7 +4649,7 @@ static int smbios_decode(u8 *buf, const char *devmem) ver >> 8, ver & 0xFF); dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), - ver, devmem); + ver, devmem, flags); if (opt.flags & FLAG_DUMP_BIN) { @@ -4509,7 +4667,7 @@ static int smbios_decode(u8 *buf, const char *devmem) return 1; } -static int legacy_decode(u8 *buf, const char *devmem) +static int legacy_decode(u8 *buf, const char *devmem, u32 flags) { if (!checksum(buf, 0x0F)) return 0; @@ -4519,7 +4677,7 @@ static int legacy_decode(u8 *buf, const char *devmem) buf[0x0E] >> 4, buf[0x0E] & 0x0F); dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), - ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem); + ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags); if (opt.flags & FLAG_DUMP_BIN) { @@ -4528,7 +4686,9 @@ static int legacy_decode(u8 *buf, const char *devmem) memcpy(crafted, buf, 16); overwrite_dmi_address(crafted); - printf("# Writing %d bytes to %s.\n", 0x0F, opt.dumpfile); + if (!(opt.flags & FLAG_QUIET)) + printf("# Writing %d bytes to %s.\n", 0x0F, + opt.dumpfile); write_dump(0, 0x0F, crafted, opt.dumpfile, 1); } @@ -4540,7 +4700,7 @@ static int legacy_decode(u8 *buf, const char *devmem) */ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) -static int address_from_efi(size_t *address) +static int address_from_efi(off_t *address) { FILE *efi_systab; const char *filename; @@ -4564,12 +4724,13 @@ static int address_from_efi(size_t *address) { char *addrp = strchr(linebuf, '='); *(addrp++) = '\0'; - if (strcmp(linebuf, "SMBIOS") == 0) + if (strcmp(linebuf, "SMBIOS3") == 0 + || strcmp(linebuf, "SMBIOS") == 0) { - *address = strtoul(addrp, NULL, 0); + *address = strtoull(addrp, NULL, 0); if (!(opt.flags & FLAG_QUIET)) - printf("# SMBIOS entry point at 0x%08lx\n", - (unsigned long)*address); + printf("# %s entry point at 0x%08llx\n", + linebuf, (unsigned long long)*address); ret = 0; break; } @@ -4586,7 +4747,7 @@ int main(int argc, char * const argv[]) { int ret = 0; /* Returned value */ int found = 0; - size_t fp; + off_t fp; int efi; u8 *buf; @@ -4633,20 +4794,57 @@ int main(int argc, char * const argv[]) goto exit_free; } - if (memcmp(buf, "_SM_", 4) == 0) + if (memcmp(buf, "_SM3_", 5) == 0) { - if (smbios_decode(buf, opt.dumpfile)) + if (smbios3_decode(buf, opt.dumpfile, 0)) + found++; + } + else if (memcmp(buf, "_SM_", 4) == 0) + { + if (smbios_decode(buf, opt.dumpfile, 0)) found++; } else if (memcmp(buf, "_DMI_", 5) == 0) { - if (legacy_decode(buf, opt.dumpfile)) + if (legacy_decode(buf, opt.dumpfile, 0)) found++; } goto done; } - /* First try EFI (ia64, Intel-based Mac) */ + /* + * First try reading from sysfs tables. The entry point file could + * contain one of several types of entry points, so read enough for + * the largest one, then determine what type it contains. + */ + if (!(opt.flags & FLAG_NO_SYSFS) + && (buf = read_file(0x20, SYS_ENTRY_FILE)) != NULL) + { + if (!(opt.flags & FLAG_QUIET)) + printf("Getting SMBIOS data from sysfs.\n"); + if (memcmp(buf, "_SM3_", 5) == 0) + { + if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) + found++; + } + else if (memcmp(buf, "_SM_", 4) == 0) + { + if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) + found++; + } + else if (memcmp(buf, "_DMI_", 5) == 0) + { + if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) + found++; + } + + if (found) + goto done; + if (!(opt.flags & FLAG_QUIET)) + printf("Failed to get SMBIOS data from sysfs.\n"); + } + + /* Next try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(&fp); switch (efi) { @@ -4657,17 +4855,22 @@ int main(int argc, char * const argv[]) goto exit_free; } + if (!(opt.flags & FLAG_QUIET)) + printf("Found SMBIOS entry point in EFI, reading table from %s.\n", + opt.devmem); if ((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) { ret = 1; goto exit_free; } - if (smbios_decode(buf, opt.devmem)) + if (smbios_decode(buf, opt.devmem, 0)) found++; goto done; memory_scan: + if (!(opt.flags & FLAG_QUIET)) + printf("Scanning %s for entry point.\n", opt.devmem); /* Fallback to memory scan (x86, x86_64) */ if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL) { @@ -4677,9 +4880,17 @@ memory_scan: for (fp = 0; fp <= 0xFFF0; fp += 16) { - if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) + if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0) + { + if (smbios3_decode(buf + fp, opt.devmem, 0)) + { + found++; + fp += 16; + } + } + else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { - if (smbios_decode(buf+fp, opt.devmem)) + if (smbios_decode(buf + fp, opt.devmem, 0)) { found++; fp += 16; @@ -4687,7 +4898,7 @@ memory_scan: } else if (memcmp(buf + fp, "_DMI_", 5) == 0) { - if (legacy_decode(buf + fp, opt.devmem)) + if (legacy_decode(buf + fp, opt.devmem, 0)) found++; } } -- cgit v1.2.3