8585#define out_of_spec "<OUT OF SPEC>"
8686static const char * bad_index = "<BAD INDEX>" ;
8787
88- #define SUPPORTED_SMBIOS_VER 0x030200
88+ #define SUPPORTED_SMBIOS_VER 0x030300
8989
9090#define FLAG_NO_FILE_OFFSET (1 << 0)
9191#define FLAG_STOP_AT_EOT (1 << 1)
@@ -814,7 +814,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
814814 { 0x3D , "Opteron 6200" },
815815 { 0x3E , "Opteron 4200" },
816816 { 0x3F , "FX" },
817-
818817 { 0x40 , "MIPS" },
819818 { 0x41 , "MIPS R4000" },
820819 { 0x42 , "MIPS R4200" },
@@ -831,7 +830,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
831830 { 0x4D , "Opteron 6300" },
832831 { 0x4E , "Opteron 3300" },
833832 { 0x4F , "FirePro" },
834-
835833 { 0x50 , "SPARC" },
836834 { 0x51 , "SuperSPARC" },
837835 { 0x52 , "MicroSPARC II" },
@@ -1000,6 +998,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
1000998
1001999 code = (data [0x06 ] == 0xFE && h -> length >= 0x2A ) ?
10021000 WORD (data + 0x28 ) : data [0x06 ];
1001+
10031002 /* Special case for ambiguous value 0xBE */
10041003 if (code == 0xBE )
10051004 {
@@ -1108,7 +1107,7 @@ static void dmi_processor_id(const struct dmi_header *h)
11081107 u16 dx = WORD (p );
11091108 /*
11101109 * Not all 80486 CPU support the CPUID instruction, we have to find
1111- * wether the one we have here does or not. Note that this trick
1110+ * whether the one we have here does or not. Note that this trick
11121111 * works only because we know that 80486 must be little-endian.
11131112 */
11141113 if ((dx & 0x0F00 ) == 0x0400
@@ -1356,10 +1355,12 @@ static const char *dmi_processor_upgrade(u8 code)
13561355 "Socket LGA2066" ,
13571356 "Socket BGA1392" ,
13581357 "Socket BGA1510" ,
1359- "Socket BGA1528" /* 0x3C */
1358+ "Socket BGA1528" ,
1359+ "Socket LGA4189" ,
1360+ "Socket LGA1200" /* 0x3E */
13601361 };
13611362
1362- if (code >= 0x01 && code <= 0x3C )
1363+ if (code >= 0x01 && code <= 0x3E )
13631364 return upgrade [code - 0x01 ];
13641365 return out_of_spec ;
13651366}
@@ -1387,7 +1388,9 @@ static void dmi_processor_characteristics(const char *attr, u16 code)
13871388 "Hardware Thread" ,
13881389 "Execute Protection" ,
13891390 "Enhanced Virtualization" ,
1390- "Power/Performance Control" /* 7 */
1391+ "Power/Performance Control" ,
1392+ "128-bit Capable" ,
1393+ "Arm64 SoC ID" /* 9 */
13911394 };
13921395
13931396 if ((code & 0x00FC ) == 0 )
@@ -1397,7 +1400,7 @@ static void dmi_processor_characteristics(const char *attr, u16 code)
13971400 int i ;
13981401
13991402 pr_list_start (attr , NULL );
1400- for (i = 2 ; i <= 7 ; i ++ )
1403+ for (i = 2 ; i <= 9 ; i ++ )
14011404 if (code & (1 << i ))
14021405 pr_list_item ("%s" , characteristics [i - 2 ]);
14031406 pr_list_end ();
@@ -1932,11 +1935,16 @@ static const char *dmi_slot_type(u8 code)
19321935 "MXM Type IV" ,
19331936 "MXM 3.0 Type A" ,
19341937 "MXM 3.0 Type B" ,
1935- "PCI Express 2 SFF-8639" ,
1936- "PCI Express 3 SFF-8639" ,
1938+ "PCI Express 2 SFF-8639 (U.2) " ,
1939+ "PCI Express 3 SFF-8639 (U.2) " ,
19371940 "PCI Express Mini 52-pin with bottom-side keep-outs" ,
19381941 "PCI Express Mini 52-pin without bottom-side keep-outs" ,
1939- "PCI Express Mini 76-pin" /* 0x23 */
1942+ "PCI Express Mini 76-pin" ,
1943+ "PCI Express 4 SFF-8639 (U.2)" ,
1944+ "PCI Express 5 SFF-8639 (U.2)" ,
1945+ "OCP NIC 3.0 Small Form Factor (SFF)" ,
1946+ "OCP NIC 3.0 Large Form Factor (LFF)" ,
1947+ "OCP NIC Prior to 3.0" /* 0x28 */
19401948 };
19411949 static const char * type_0x30 [] = {
19421950 "CXL FLexbus 1.0" /* 0x30 */
@@ -1971,18 +1979,27 @@ static const char *dmi_slot_type(u8 code)
19711979 "PCI Express 4 x2" ,
19721980 "PCI Express 4 x4" ,
19731981 "PCI Express 4 x8" ,
1974- "PCI Express 4 x16" /* 0xBD */
1982+ "PCI Express 4 x16" ,
1983+ "PCI Express 5" ,
1984+ "PCI Express 5 x1" ,
1985+ "PCI Express 5 x2" ,
1986+ "PCI Express 5 x4" ,
1987+ "PCI Express 5 x8" ,
1988+ "PCI Express 5 x16" ,
1989+ "PCI Express 6+" ,
1990+ "EDSFF E1" ,
1991+ "EDSFF E3" /* 0xC6 */
19751992 };
19761993 /*
19771994 * Note to developers: when adding entries to these lists, check if
19781995 * function dmi_slot_id below needs updating too.
19791996 */
19801997
1981- if (code >= 0x01 && code <= 0x23 )
1998+ if (code >= 0x01 && code <= 0x28 )
19821999 return type [code - 0x01 ];
19832000 if (code == 0x30 )
19842001 return type_0x30 [code - 0x30 ];
1985- if (code >= 0xA0 && code <= 0xBD )
2002+ if (code >= 0xA0 && code <= 0xC6 )
19862003 return type_0xA0 [code - 0xA0 ];
19872004 return out_of_spec ;
19882005}
@@ -2117,7 +2134,10 @@ static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2)
21172134 "PME signal is supported" , /* 0 */
21182135 "Hot-plug devices are supported" ,
21192136 "SMBus signal is supported" ,
2120- "PCIe slot bifurcation is supported" /* 3 */
2137+ "PCIe slot bifurcation is supported" ,
2138+ "Async/surprise removal is supported" ,
2139+ "Flexbus slot, CXL 1.0 capable" ,
2140+ "Flexbus slot, CXL 2.0 capable" /* 6 */
21212141 };
21222142
21232143 if (code1 & (1 << 0 ))
@@ -2132,7 +2152,7 @@ static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2)
21322152 for (i = 1 ; i <= 7 ; i ++ )
21332153 if (code1 & (1 << i ))
21342154 pr_list_item ("%s" , characteristics1 [i - 1 ]);
2135- for (i = 0 ; i <= 3 ; i ++ )
2155+ for (i = 0 ; i <= 6 ; i ++ )
21362156 if (code2 & (1 << i ))
21372157 pr_list_item ("%s" , characteristics2 [i ]);
21382158 pr_list_end ();
@@ -2640,10 +2660,12 @@ static const char *dmi_memory_device_type(u8 code)
26402660 "LPDDR4" ,
26412661 "Logical non-volatile device" ,
26422662 "HBM" ,
2643- "HBM2" /* 0x21 */
2663+ "HBM2" ,
2664+ "DDR5" ,
2665+ "LPDDR5" /* 0x23 */
26442666 };
26452667
2646- if (code >= 0x01 && code <= 0x21 )
2668+ if (code >= 0x01 && code <= 0x23 )
26472669 return type [code - 0x01 ];
26482670 return out_of_spec ;
26492671}
@@ -2685,12 +2707,22 @@ static void dmi_memory_device_type_detail(u16 code)
26852707 }
26862708}
26872709
2688- static void dmi_memory_device_speed (const char * attr , u16 code )
2710+ static void dmi_memory_device_speed (const char * attr , u16 code1 , u32 code2 )
26892711{
2690- if (code == 0 )
2691- pr_attr (attr , "Unknown" );
2712+ if (code1 == 0xFFFF )
2713+ {
2714+ if (code2 == 0 )
2715+ pr_attr (attr , "Unknown" );
2716+ else
2717+ pr_attr (attr , "%lu MT/s" , code2 );
2718+ }
26922719 else
2693- pr_attr (attr , "%u MT/s" , code );
2720+ {
2721+ if (code1 == 0 )
2722+ pr_attr (attr , "Unknown" );
2723+ else
2724+ pr_attr (attr , "%u MT/s" , code1 );
2725+ }
26942726}
26952727
26962728static void dmi_memory_technology (u8 code )
@@ -3708,16 +3740,16 @@ static void dmi_parse_protocol_record(u8 *rec)
37083740 * convenience. It could get passed from the SMBIOS
37093741 * header, but that's a lot of passing of pointers just
37103742 * to get that info, and the only thing it is used for is
3711- * to determine the endianess of the field. Since we only
3743+ * to determine the endianness of the field. Since we only
37123744 * do this parsing on versions of SMBIOS after 3.1.1, and the
3713- * endianess of the field is always little after version 2.6.0
3745+ * endianness of the field is always little after version 2.6.0
37143746 * we can just pick a sufficiently recent version here.
37153747 */
37163748 dmi_system_uuid (pr_subattr , "Service UUID" , & rdata [0 ], 0x311 );
37173749
37183750 /*
37193751 * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type
3720- * Note, using decimal indicies here, as the DSP0270
3752+ * Note, using decimal indices here, as the DSP0270
37213753 * uses decimal, so as to make it more comparable
37223754 */
37233755 assign_val = rdata [16 ];
@@ -4452,7 +4484,12 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
44524484 dmi_memory_device_type (data [0x12 ]));
44534485 dmi_memory_device_type_detail (WORD (data + 0x13 ));
44544486 if (h -> length < 0x17 ) break ;
4455- dmi_memory_device_speed ("Speed" , WORD (data + 0x15 ));
4487+ /* If no module is present, the remaining fields are irrelevant */
4488+ if (WORD (data + 0x0C ) == 0 )
4489+ break ;
4490+ dmi_memory_device_speed ("Speed" , WORD (data + 0x15 ),
4491+ h -> length >= 0x5C ?
4492+ DWORD (data + 0x54 ) : 0 );
44564493 if (h -> length < 0x1B ) break ;
44574494 pr_attr ("Manufacturer" , "%s" ,
44584495 dmi_string (h , data [0x17 ]));
@@ -4469,7 +4506,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
44694506 pr_attr ("Rank" , "%u" , data [0x1B ] & 0x0F );
44704507 if (h -> length < 0x22 ) break ;
44714508 dmi_memory_device_speed ("Configured Memory Speed" ,
4472- WORD (data + 0x20 ));
4509+ WORD (data + 0x20 ),
4510+ h -> length >= 0x5C ?
4511+ DWORD (data + 0x58 ) : 0 );
44734512 if (h -> length < 0x28 ) break ;
44744513 dmi_memory_voltage_value ("Minimum Voltage" ,
44754514 WORD (data + 0x22 ));
@@ -5219,7 +5258,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
52195258 /* In quiet mode, stop decoding at end of table marker */
52205259 if ((opt .flags & FLAG_QUIET ) && h .type == 127 )
52215260 break ;
5222-
5261+
52235262 if (display
52245263 && (!(opt .flags & FLAG_QUIET ) || (opt .flags & FLAG_DUMP )))
52255264 pr_handle (& h );
@@ -5251,8 +5290,9 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
52515290 }
52525291
52535292 /* assign vendor for vendor-specific decodes later */
5254- if (h .type == 1 && h .length >= 5 )
5255- dmi_set_vendor (dmi_string (& h , data [0x04 ]));
5293+ if (h .type == 1 && h .length >= 6 )
5294+ dmi_set_vendor (_dmi_string (& h , data [0x04 ], 0 ),
5295+ _dmi_string (& h , data [0x05 ], 0 ));
52565296
52575297 /* Fixup a common mistake */
52585298 if (h .type == 34 )
@@ -5323,7 +5363,7 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
53235363 }
53245364 pr_sep ();
53255365 }
5326-
5366+
53275367 if ((flags & FLAG_NO_FILE_OFFSET ) || (opt .flags & FLAG_FROM_DUMP ))
53285368 {
53295369 /*
0 commit comments