From 1c9b2bb810c0f4162ddd99759bec6f0b714eb5eb Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 27 Dec 2020 01:34:48 +0300 Subject: [PATCH] Update to 3c111e4f with SMBIOS 3.3 improvements --- LICENSE | 6 +- NEWS | 18 +++ README.md | 2 +- dmidecode.c | 102 +++++++++++------ dmidecode.xcodeproj/project.pbxproj | 2 +- dmioem.c | 165 ++++++++++++++++++++-------- dmioem.h | 2 +- dmiopt.c | 1 + man/dmidecode.8 | 3 +- man/vpddecode.8 | 2 - types.h | 4 +- version.h | 2 +- 12 files changed, 222 insertions(+), 87 deletions(-) diff --git a/LICENSE b/LICENSE index 25c6445..d159169 100644 --- a/LICENSE +++ b/LICENSE @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License diff --git a/NEWS b/NEWS index 18b0325..cd950d8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,21 @@ +Version 3.3 (Wed Oct 14 2020) + - [BUILD] Allow overriding build settings from the environment. + - [COMPATIBILITY] Document how the UUID fields are interpreted. + - [PORTABILITY] Don't use memcpy on /dev/mem on arm64. + - [PORTABILITY] Only scan /dev/mem for entry point on x86. + - Support for SMBIOS 3.3.0. This includes new processor names, new port + connector types, and new memory device form factors, types and + technologies. + - Add bios-revision, firmware-revision and system-sku-number to -s option. + - Use the most appropriate unit for cache size. + - Decode system slot base bus width and peers. + - Important bug fixes: + Fix Redfish Hostname print length + Fix formatting of TPM table output + Fix System Slot Information for PCIe SSD + Don't choke on invalid processor voltage + - Use the most appropriate unit for cache size. + Version 3.2 (Wed Sep 14 2018) - [COMPATIBILITY] The UUID is now displayed using lowercase letters, per RFC 4122 (#53569). You must ensure that any code parsing it is diff --git a/README.md b/README.md index b00e75d..aa31b02 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ dmidecode This dmidecode version supports Apple-specific table decoding as well as native macOS SMBIOS reading through I/O Registry. Synced with -[upstream](http://git.savannah.gnu.org/cgit/dmidecode.git) up to 5b3c8e99. +[upstream](http://git.savannah.gnu.org/cgit/dmidecode.git) up to 3c111e4f. **INTRODUCTION** diff --git a/dmidecode.c b/dmidecode.c index ab694fe..d79ca70 100644 --- a/dmidecode.c +++ b/dmidecode.c @@ -85,7 +85,7 @@ #define out_of_spec "" static const char *bad_index = ""; -#define SUPPORTED_SMBIOS_VER 0x030200 +#define SUPPORTED_SMBIOS_VER 0x030300 #define FLAG_NO_FILE_OFFSET (1 << 0) #define FLAG_STOP_AT_EOT (1 << 1) @@ -814,7 +814,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" }, @@ -831,7 +830,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" }, @@ -1000,6 +998,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06]; + /* Special case for ambiguous value 0xBE */ if (code == 0xBE) { @@ -1108,7 +1107,7 @@ static void dmi_processor_id(const struct dmi_header *h) u16 dx = WORD(p); /* * Not all 80486 CPU support the CPUID instruction, we have to find - * wether the one we have here does or not. Note that this trick + * whether the one we have here does or not. Note that this trick * works only because we know that 80486 must be little-endian. */ if ((dx & 0x0F00) == 0x0400 @@ -1356,10 +1355,12 @@ static const char *dmi_processor_upgrade(u8 code) "Socket LGA2066", "Socket BGA1392", "Socket BGA1510", - "Socket BGA1528" /* 0x3C */ + "Socket BGA1528", + "Socket LGA4189", + "Socket LGA1200" /* 0x3E */ }; - if (code >= 0x01 && code <= 0x3C) + if (code >= 0x01 && code <= 0x3E) return upgrade[code - 0x01]; return out_of_spec; } @@ -1387,7 +1388,9 @@ static void dmi_processor_characteristics(const char *attr, u16 code) "Hardware Thread", "Execute Protection", "Enhanced Virtualization", - "Power/Performance Control" /* 7 */ + "Power/Performance Control", + "128-bit Capable", + "Arm64 SoC ID" /* 9 */ }; if ((code & 0x00FC) == 0) @@ -1397,7 +1400,7 @@ static void dmi_processor_characteristics(const char *attr, u16 code) int i; pr_list_start(attr, NULL); - for (i = 2; i <= 7; i++) + for (i = 2; i <= 9; i++) if (code & (1 << i)) pr_list_item("%s", characteristics[i - 2]); pr_list_end(); @@ -1932,11 +1935,16 @@ static const char *dmi_slot_type(u8 code) "MXM Type IV", "MXM 3.0 Type A", "MXM 3.0 Type B", - "PCI Express 2 SFF-8639", - "PCI Express 3 SFF-8639", + "PCI Express 2 SFF-8639 (U.2)", + "PCI Express 3 SFF-8639 (U.2)", "PCI Express Mini 52-pin with bottom-side keep-outs", "PCI Express Mini 52-pin without bottom-side keep-outs", - "PCI Express Mini 76-pin" /* 0x23 */ + "PCI Express Mini 76-pin", + "PCI Express 4 SFF-8639 (U.2)", + "PCI Express 5 SFF-8639 (U.2)", + "OCP NIC 3.0 Small Form Factor (SFF)", + "OCP NIC 3.0 Large Form Factor (LFF)", + "OCP NIC Prior to 3.0" /* 0x28 */ }; static const char *type_0x30[] = { "CXL FLexbus 1.0" /* 0x30 */ @@ -1971,18 +1979,27 @@ static const char *dmi_slot_type(u8 code) "PCI Express 4 x2", "PCI Express 4 x4", "PCI Express 4 x8", - "PCI Express 4 x16" /* 0xBD */ + "PCI Express 4 x16", + "PCI Express 5", + "PCI Express 5 x1", + "PCI Express 5 x2", + "PCI Express 5 x4", + "PCI Express 5 x8", + "PCI Express 5 x16", + "PCI Express 6+", + "EDSFF E1", + "EDSFF E3" /* 0xC6 */ }; /* * Note to developers: when adding entries to these lists, check if * function dmi_slot_id below needs updating too. */ - if (code >= 0x01 && code <= 0x23) + if (code >= 0x01 && code <= 0x28) return type[code - 0x01]; if (code == 0x30) return type_0x30[code - 0x30]; - if (code >= 0xA0 && code <= 0xBD) + if (code >= 0xA0 && code <= 0xC6) return type_0xA0[code - 0xA0]; return out_of_spec; } @@ -2117,7 +2134,10 @@ static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2) "PME signal is supported", /* 0 */ "Hot-plug devices are supported", "SMBus signal is supported", - "PCIe slot bifurcation is supported" /* 3 */ + "PCIe slot bifurcation is supported", + "Async/surprise removal is supported", + "Flexbus slot, CXL 1.0 capable", + "Flexbus slot, CXL 2.0 capable" /* 6 */ }; if (code1 & (1 << 0)) @@ -2132,7 +2152,7 @@ static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2) for (i = 1; i <= 7; i++) if (code1 & (1 << i)) pr_list_item("%s", characteristics1[i - 1]); - for (i = 0; i <= 3; i++) + for (i = 0; i <= 6; i++) if (code2 & (1 << i)) pr_list_item("%s", characteristics2[i]); pr_list_end(); @@ -2640,10 +2660,12 @@ static const char *dmi_memory_device_type(u8 code) "LPDDR4", "Logical non-volatile device", "HBM", - "HBM2" /* 0x21 */ + "HBM2", + "DDR5", + "LPDDR5" /* 0x23 */ }; - if (code >= 0x01 && code <= 0x21) + if (code >= 0x01 && code <= 0x23) return type[code - 0x01]; return out_of_spec; } @@ -2685,12 +2707,22 @@ static void dmi_memory_device_type_detail(u16 code) } } -static void dmi_memory_device_speed(const char *attr, u16 code) +static void dmi_memory_device_speed(const char *attr, u16 code1, u32 code2) { - if (code == 0) - pr_attr(attr, "Unknown"); + if (code1 == 0xFFFF) + { + if (code2 == 0) + pr_attr(attr, "Unknown"); + else + pr_attr(attr, "%lu MT/s", code2); + } else - pr_attr(attr, "%u MT/s", code); + { + if (code1 == 0) + pr_attr(attr, "Unknown"); + else + pr_attr(attr, "%u MT/s", code1); + } } static void dmi_memory_technology(u8 code) @@ -3708,16 +3740,16 @@ static void dmi_parse_protocol_record(u8 *rec) * convenience. It could get passed from the SMBIOS * header, but that's a lot of passing of pointers just * to get that info, and the only thing it is used for is - * to determine the endianess of the field. Since we only + * to determine the endianness of the field. Since we only * do this parsing on versions of SMBIOS after 3.1.1, and the - * endianess of the field is always little after version 2.6.0 + * endianness of the field is always little after version 2.6.0 * we can just pick a sufficiently recent version here. */ dmi_system_uuid(pr_subattr, "Service UUID", &rdata[0], 0x311); /* * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type - * Note, using decimal indicies here, as the DSP0270 + * Note, using decimal indices here, as the DSP0270 * uses decimal, so as to make it more comparable */ assign_val = rdata[16]; @@ -4452,7 +4484,12 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) dmi_memory_device_type(data[0x12])); dmi_memory_device_type_detail(WORD(data + 0x13)); if (h->length < 0x17) break; - dmi_memory_device_speed("Speed", WORD(data + 0x15)); + /* If no module is present, the remaining fields are irrelevant */ + if (WORD(data + 0x0C) == 0) + break; + dmi_memory_device_speed("Speed", WORD(data + 0x15), + h->length >= 0x5C ? + DWORD(data + 0x54) : 0); if (h->length < 0x1B) break; pr_attr("Manufacturer", "%s", dmi_string(h, data[0x17])); @@ -4469,7 +4506,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) pr_attr("Rank", "%u", data[0x1B] & 0x0F); if (h->length < 0x22) break; dmi_memory_device_speed("Configured Memory Speed", - WORD(data + 0x20)); + WORD(data + 0x20), + h->length >= 0x5C ? + DWORD(data + 0x58) : 0); if (h->length < 0x28) break; dmi_memory_voltage_value("Minimum Voltage", WORD(data + 0x22)); @@ -5219,7 +5258,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) /* In quiet mode, stop decoding at end of table marker */ if ((opt.flags & FLAG_QUIET) && h.type == 127) break; - + if (display && (!(opt.flags & FLAG_QUIET) || (opt.flags & FLAG_DUMP))) pr_handle(&h); @@ -5251,8 +5290,9 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) } /* assign vendor for vendor-specific decodes later */ - if (h.type == 1 && h.length >= 5) - dmi_set_vendor(dmi_string(&h, data[0x04])); + if (h.type == 1 && h.length >= 6) + dmi_set_vendor(_dmi_string(&h, data[0x04], 0), + _dmi_string(&h, data[0x05], 0)); /* Fixup a common mistake */ if (h.type == 34) @@ -5323,7 +5363,7 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, } pr_sep(); } - + if ((flags & FLAG_NO_FILE_OFFSET) || (opt.flags & FLAG_FROM_DUMP)) { /* diff --git a/dmidecode.xcodeproj/project.pbxproj b/dmidecode.xcodeproj/project.pbxproj index 89b621b..fe20913 100644 --- a/dmidecode.xcodeproj/project.pbxproj +++ b/dmidecode.xcodeproj/project.pbxproj @@ -109,7 +109,7 @@ 12ECFB3A1852EADE0028E3A9 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + LastUpgradeCheck = 1230; }; buildConfigurationList = 12ECFB3D1852EADE0028E3A9 /* Build configuration list for PBXProject "dmidecode" */; compatibilityVersion = "Xcode 3.2"; diff --git a/dmioem.c b/dmioem.c index 60b6674..180a95d 100644 --- a/dmioem.c +++ b/dmioem.c @@ -23,6 +23,7 @@ #include #include "types.h" +#include "util.h" #include "dmidecode.h" #include "dmioem.h" #include "dmioutput.h" @@ -42,34 +43,46 @@ enum DMI_VENDORS }; static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN; +static const char *dmi_product = NULL; /* * Remember the system vendor for later use. We only actually store the * value if we know how to decode at least one specific entry type for * that vendor. */ -void dmi_set_vendor(const char *s) +void dmi_set_vendor(const char *v, const char *p) { - int len; + const struct { const char *str; enum DMI_VENDORS id; } vendor[] = { + { "Acer", VENDOR_ACER }, + { "HP", VENDOR_HP }, + { "Hewlett-Packard", VENDOR_HP }, + { "HPE", VENDOR_HPE }, + { "Hewlett Packard Enterprise", VENDOR_HPE }, + { "IBM", VENDOR_IBM }, + { "LENOVO", VENDOR_LENOVO }, + }; + unsigned int i; + size_t len; /* * Often DMI strings have trailing spaces. Ignore these * when checking for known vendor names. */ - len = strlen(s); - while (len && s[len - 1] == ' ') + len = v ? strlen(v) : 0; + while (len && v[len - 1] == ' ') len--; - if (strncmp(s, "Acer", len) == 0) - dmi_vendor = VENDOR_ACER; - else if (strncmp(s, "HP", len) == 0 || strncmp(s, "Hewlett-Packard", len) == 0) - dmi_vendor = VENDOR_HP; - else if (strncmp(s, "HPE", len) == 0 || strncmp(s, "Hewlett Packard Enterprise", len) == 0) - dmi_vendor = VENDOR_HPE; - else if (strncmp(s, "IBM", len) == 0) - dmi_vendor = VENDOR_IBM; - else if (strncmp(s, "LENOVO", len) == 0) - dmi_vendor = VENDOR_LENOVO; + for (i = 0; i < ARRAY_SIZE(vendor); i++) + { + if (strlen(vendor[i].str) == len && + strncmp(v, vendor[i].str, len) == 0) + { + dmi_vendor = vendor[i].id; + break; + } + } + + dmi_product = p; } /* @@ -147,12 +160,43 @@ static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac) } } +typedef enum { G6 = 6, G7, G8, G9, G10, G10P } dmi_hpegen_t; + +static int dmi_hpegen(const char *s) +{ + struct { const char *name; dmi_hpegen_t gen; } table[] = { + { "Gen10 Plus", G10P }, + { "Gen10", G10 }, + { "Gen9", G9 }, + { "Gen8", G8 }, + { "G7", G7 }, + { "G6", G6 }, + }; + unsigned int i; + + if (!strstr(s, "ProLiant") && !strstr(s, "Apollo") && + !strstr(s, "Synergy") && !strstr(s, "Edgeline")) + return -1; + + for (i = 0; i < ARRAY_SIZE(table); i++) { + if (strstr(s, table[i].name)) + return(table[i].gen); + } + + return (dmi_vendor == VENDOR_HPE) ? G10P : G6; +} + static int dmi_decode_hp(const struct dmi_header *h) { u8 *data = h->data; int nic, ptr; u32 feat; const char *company = (dmi_vendor == VENDOR_HP) ? "HP" : "HPE"; + int gen; + + gen = dmi_hpegen(dmi_product); + if (gen < 0) + return 0; switch (h->type) { @@ -208,35 +252,6 @@ static int dmi_decode_hp(const struct dmi_header *h) } break; - case 233: - /* - * Vendor Specific: HPE ProLiant NIC MAC Information - * - * This prints the BIOS NIC number, - * PCI bus/device/function, and MAC address - * - * Offset | Name | Width | Description - * ------------------------------------- - * 0x00 | Type | BYTE | 0xE9, NIC structure - * 0x01 | Length | BYTE | Length of structure - * 0x02 | Handle | WORD | Unique handle - * 0x04 | Grp No | WORD | 0 for single segment - * 0x06 | Bus No | BYTE | PCI Bus - * 0x07 | Dev No | BYTE | PCI Device/Function No - * 0x08 | MAC | 32B | MAC addr padded w/ 0s - * 0x28 | Port No| BYTE | Each NIC maps to a Port - */ - pr_handle_name("%s BIOS PXE NIC PCI and MAC Information", - company); - if (h->length < 0x0E) break; - /* If the record isn't long enough, we don't have an ID - * use 0xFF to use the internal counter. - * */ - nic = h->length > 0x28 ? data[0x28] : 0xFF; - dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07], - &data[0x08]); - break; - case 212: /* * Vendor Specific: HPE 64-bit CRU Information @@ -282,6 +297,70 @@ static int dmi_decode_hp(const struct dmi_header *h) pr_subattr("UEFI", "%s", feat & 0x1400 ? "Yes" : "No"); break; + case 233: + /* + * Vendor Specific: HPE ProLiant NIC MAC Information + * + * This prints the BIOS NIC number, + * PCI bus/device/function, and MAC address + * + * Offset | Name | Width | Description + * ------------------------------------- + * 0x00 | Type | BYTE | 0xE9, NIC structure + * 0x01 | Length | BYTE | Length of structure + * 0x02 | Handle | WORD | Unique handle + * 0x04 | Grp No | WORD | 0 for single segment + * 0x06 | Bus No | BYTE | PCI Bus + * 0x07 | Dev No | BYTE | PCI Device/Function No + * 0x08 | MAC | 32B | MAC addr padded w/ 0s + * 0x28 | Port No| BYTE | Each NIC maps to a Port + */ + pr_handle_name("%s BIOS PXE NIC PCI and MAC Information", + company); + if (h->length < 0x0E) break; + /* If the record isn't long enough, we don't have an ID + * use 0xFF to use the internal counter. + * */ + nic = h->length > 0x28 ? data[0x28] : 0xFF; + dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07], + &data[0x08]); + break; + + case 236: + /* + * Vendor Specific: HPE ProLiant HDD Backplane + * + * Offset | Name | Width | Description + * --------------------------------------- + * 0x00 | Type | BYTE | 0xEC, HDD Backplane + * 0x01 | Length | BYTE | Length of structure + * 0x02 | Handle | WORD | Unique handle + * 0x04 | I2C Address| BYTE | Backplane FRU I2C Address + * 0x05 | Box Number | WORD | Backplane Box Number + * 0x07 | NVRAM ID | WORD | Backplane NVRAM ID + * 0x09 | WWID | QWORD | SAS Expander WWID + * 0x11 | Total Bays | BYTE | Total SAS Bays + * 0x12 | A0 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA0 + * 0x13 | A2 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA2 + * 0x14 | Name | STRING| (deprecated) Backplane Name + */ + pr_handle_name("%s HDD Backplane FRU Information", company); + + pr_attr("FRU I2C Address", "0x%X raw(0x%X)", data[0x4] >> 1, data[0x4]); + pr_attr("Box Number", "%d", WORD(data + 0x5)); + pr_attr("NVRAM ID", "0x%X", WORD(data + 0x7)); + if (h->length < 0x11) break; + pr_attr("SAS Expander WWID", "0x%X", QWORD(data + 0x9)); + if (h->length < 0x12) break; + pr_attr("Total SAS Bays", "%d", data[0x11]); + if (h->length < 0x15) break; + if (gen < G10P) { + pr_attr("A0 Bay Count", "%d", data[0x12]); + pr_attr("A2 Bay Count", "%d", data[0x13]); + pr_attr("Backplane Name", "%s", dmi_string(h, data[0x14])); + } + break; + default: return 0; } diff --git a/dmioem.h b/dmioem.h index 3916766..b79b769 100644 --- a/dmioem.h +++ b/dmioem.h @@ -21,5 +21,5 @@ struct dmi_header; -void dmi_set_vendor(const char *s); +void dmi_set_vendor(const char *s, const char *p); int dmi_decode_oem(const struct dmi_header *h); diff --git a/dmiopt.c b/dmiopt.c index 8feb2cd..fe0bef8 100644 --- a/dmiopt.c +++ b/dmiopt.c @@ -158,6 +158,7 @@ static const struct string_keyword opt_string_keyword[] = { { "system-version", 1, 0x06 }, { "system-serial-number", 1, 0x07 }, { "system-uuid", 1, 0x08 }, /* dmi_system_uuid() */ + { "system-sku-number", 1, 0x19 }, { "system-family", 1, 0x1a }, { "baseboard-manufacturer", 2, 0x04 }, { "baseboard-product-name", 2, 0x05 }, diff --git a/man/dmidecode.8 b/man/dmidecode.8 index c715309..64dc7e7 100644 --- a/man/dmidecode.8 +++ b/man/dmidecode.8 @@ -77,7 +77,7 @@ Only display the value of the \s-1DMI\s0 string identified by \fBKEYWORD\fR. \fBbios-revision\fR, \fBfirmware-revision\fR, \fBsystem-manufacturer\fR, \fBsystem-product-name\fR, \fBsystem-version\fR, \fBsystem-serial-number\fR, -\fBsystem-uuid\fR, \fBsystem-family\fR, +\fBsystem-uuid\fR, \fBsystem-sku-number\fR, \fBsystem-family\fR, \fBbaseboard-manufacturer\fR, \fBbaseboard-product-name\fR, \fBbaseboard-version\fR, \fBbaseboard-serial-number\fR, \fBbaseboard-asset-tag\fR, \fBchassis-manufacturer\fR, @@ -164,7 +164,6 @@ output data is not reliable. .\" .SH "DMI TYPES" The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types: - .TS r l __ diff --git a/man/vpddecode.8 b/man/vpddecode.8 index 10f031b..1cc2b76 100644 --- a/man/vpddecode.8 +++ b/man/vpddecode.8 @@ -19,14 +19,12 @@ Box Serial Number Motherboard Serial Number .IP \(bu Machine Type/Model - .PP Some systems have these additional items: .IP \(bu "\w'\(bu'u+1n" BIOS Release Date .IP \(bu Default Flash Image File Name - .PP Note that these additional items are not documented by IBM, so this is guess work, and as such should not be blindly trusted. Feedback about diff --git a/types.h b/types.h index 5e6bcf0..51c32d7 100644 --- a/types.h +++ b/types.h @@ -34,10 +34,10 @@ typedef struct { static inline u64 U64(u32 low, u32 high) { u64 self; - + self.l = low; self.h = high; - + return self; } #endif diff --git a/version.h b/version.h index 47ea683..195f221 100644 --- a/version.h +++ b/version.h @@ -1 +1 @@ -#define VERSION "3.2c" +#define VERSION "3.3a"