blob: 562dd7959be4dc5a482338bfe8009cf028913cfe [file] [log] [blame]
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +01001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * The 'smbios' command displays information from the SMBIOS table.
4 *
5 * Copyright (c) 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6 */
7
8#include <command.h>
9#include <hexdump.h>
10#include <mapmem.h>
11#include <smbios.h>
12#include <tables_csum.h>
13#include <asm/global_data.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
Raymond Mao6a125b32024-12-06 14:54:26 -080017static const struct str_lookup_table wakeup_type_strings[] = {
18 { SMBIOS_WAKEUP_TYPE_RESERVED, "Reserved" },
19 { SMBIOS_WAKEUP_TYPE_OTHER, "Other" },
20 { SMBIOS_WAKEUP_TYPE_UNKNOWN, "Unknown" },
21 { SMBIOS_WAKEUP_TYPE_APM_TIMER, "APM Timer" },
22 { SMBIOS_WAKEUP_TYPE_MODEM_RING, "Modem Ring" },
23 { SMBIOS_WAKEUP_TYPE_LAN_REMOTE, "Lan Remote" },
24 { SMBIOS_WAKEUP_TYPE_POWER_SWITCH, "Power Switch" },
25 { SMBIOS_WAKEUP_TYPE_PCI_PME, "PCI PME#" },
26 { SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED, "AC Power Restored" },
Heinrich Schuchardt58b796b2024-02-10 12:06:47 +010027};
28
Raymond Mao6a125b32024-12-06 14:54:26 -080029static const struct str_lookup_table boardtype_strings[] = {
30 { SMBIOS_BOARD_TYPE_UNKNOWN, "Unknown" },
31 { SMBIOS_BOARD_TYPE_OTHER, "Other" },
32 { SMBIOS_BOARD_TYPE_SERVER_BLADE, "Server Blade" },
33 { SMBIOS_BOARD_TYPE_CON_SWITCH, "Connectivity Switch" },
34 { SMBIOS_BOARD_TYPE_SM_MODULE, "System Management Module" },
35 { SMBIOS_BOARD_TYPE_PROCESSOR_MODULE, "Processor Module" },
36 { SMBIOS_BOARD_TYPE_IO_MODULE, "I/O Module" },
37 { SMBIOS_BOARD_TYPE_MEM_MODULE, "Memory Module" },
38 { SMBIOS_BOARD_TYPE_DAUGHTER_BOARD, "Daughter board" },
39 { SMBIOS_BOARD_TYPE_MOTHERBOARD, "Motherboard" },
40 { SMBIOS_BOARD_TYPE_PROC_MEM_MODULE, "Processor/Memory Module" },
41 { SMBIOS_BOARD_TYPE_PROC_IO_MODULE, "Processor/IO Module" },
42 { SMBIOS_BOARD_TYPE_INTERCON, "Interconnect board" },
43};
44
45static const struct str_lookup_table chassis_state_strings[] = {
46 { SMBIOS_STATE_OTHER, "Other" },
47 { SMBIOS_STATE_UNKNOWN, "Unknown" },
48 { SMBIOS_STATE_SAFE, "Safe" },
49 { SMBIOS_STATE_WARNING, "Warning" },
50 { SMBIOS_STATE_CRITICAL, "Critical" },
51 { SMBIOS_STATE_NONRECOVERABLE, "Non-recoverable" },
52};
53
54static const struct str_lookup_table chassis_security_strings[] = {
55 { SMBIOS_SECURITY_OTHER, "Other" },
56 { SMBIOS_SECURITY_UNKNOWN, "Unknown" },
57 { SMBIOS_SECURITY_NONE, "None" },
58 { SMBIOS_SECURITY_EXTINT_LOCK, "External interface locked out" },
59 { SMBIOS_SECURITY_EXTINT_EN, "External interface enabled" },
60};
61
62static const struct str_lookup_table processor_type_strings[] = {
63 { SMBIOS_PROCESSOR_TYPE_OTHER, "Other" },
64 { SMBIOS_PROCESSOR_TYPE_UNKNOWN, "Unknown" },
65 { SMBIOS_PROCESSOR_TYPE_CENTRAL, "Central Processor" },
66 { SMBIOS_PROCESSOR_TYPE_MATH, "Math Processor" },
67 { SMBIOS_PROCESSOR_TYPE_DSP, "DSP Processor" },
68 { SMBIOS_PROCESSOR_TYPE_VIDEO, "Video Processor" },
69};
70
71static const struct str_lookup_table processor_family_strings[] = {
72 { SMBIOS_PROCESSOR_FAMILY_OTHER, "Other" },
73 { SMBIOS_PROCESSOR_FAMILY_UNKNOWN, "Unknown" },
74 { SMBIOS_PROCESSOR_FAMILY_RSVD, "Reserved" },
75 { SMBIOS_PROCESSOR_FAMILY_ARMV7, "ARMv7" },
76 { SMBIOS_PROCESSOR_FAMILY_ARMV8, "ARMv8" },
77 { SMBIOS_PROCESSOR_FAMILY_RV32, "RISC-V RV32" },
78 { SMBIOS_PROCESSOR_FAMILY_RV64, "RISC-V RV64" },
79};
80
81static const struct str_lookup_table processor_upgrade_strings[] = {
82 { SMBIOS_PROCESSOR_UPGRADE_OTHER, "Other" },
83 { SMBIOS_PROCESSOR_UPGRADE_UNKNOWN, "Unknown" },
84 { SMBIOS_PROCESSOR_UPGRADE_NONE, "None" },
85};
86
87static const struct str_lookup_table err_corr_type_strings[] = {
88 { SMBIOS_CACHE_ERRCORR_OTHER, "Other" },
89 { SMBIOS_CACHE_ERRCORR_UNKNOWN, "Unknown" },
90 { SMBIOS_CACHE_ERRCORR_NONE, "None" },
91 { SMBIOS_CACHE_ERRCORR_PARITY, "Parity" },
92 { SMBIOS_CACHE_ERRCORR_SBITECC, "Single-bit ECC" },
93 { SMBIOS_CACHE_ERRCORR_MBITECC, "Multi-bit ECC" },
94};
95
96static const struct str_lookup_table sys_cache_type_strings[] = {
97 { SMBIOS_CACHE_SYSCACHE_TYPE_OTHER, "Other" },
98 { SMBIOS_CACHE_SYSCACHE_TYPE_UNKNOWN, "Unknown" },
99 { SMBIOS_CACHE_SYSCACHE_TYPE_INST, "Instruction" },
100 { SMBIOS_CACHE_SYSCACHE_TYPE_DATA, "Data" },
101 { SMBIOS_CACHE_SYSCACHE_TYPE_UNIFIED, "Unified" },
102};
103
104static const struct str_lookup_table associativity_strings[] = {
105 { SMBIOS_CACHE_ASSOC_OTHER, "Other" },
106 { SMBIOS_CACHE_ASSOC_UNKNOWN, "Unknown" },
107 { SMBIOS_CACHE_ASSOC_DMAPPED, "Direct Mapped" },
108 { SMBIOS_CACHE_ASSOC_2WAY, "2-way Set-Associative" },
109 { SMBIOS_CACHE_ASSOC_4WAY, "4-way Set-Associative" },
110 { SMBIOS_CACHE_ASSOC_FULLY, "Fully Associative" },
111 { SMBIOS_CACHE_ASSOC_8WAY, "8-way Set-Associative" },
112 { SMBIOS_CACHE_ASSOC_16WAY, "16-way Set-Associative" },
113 { SMBIOS_CACHE_ASSOC_12WAY, "12-way Set-Associative" },
114 { SMBIOS_CACHE_ASSOC_24WAY, "24-way Set-Associative" },
115 { SMBIOS_CACHE_ASSOC_32WAY, "32-way Set-Associative" },
116 { SMBIOS_CACHE_ASSOC_48WAY, "48-way Set-Associative" },
117 { SMBIOS_CACHE_ASSOC_64WAY, "64-way Set-Associative" },
118 { SMBIOS_CACHE_ASSOC_20WAY, "20-way Set-Associative" },
119
120};
121
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100122/**
123 * smbios_get_string() - get SMBIOS string from table
124 *
125 * @table: SMBIOS table
126 * @index: index of the string
127 * Return: address of string, may point to empty string
128 */
129static const char *smbios_get_string(void *table, int index)
130{
131 const char *str = (char *)table +
132 ((struct smbios_header *)table)->length;
Raymond Mao6a125b32024-12-06 14:54:26 -0800133 static const char fallback[] = "";
Heinrich Schuchardtbaf24c72024-01-29 18:01:27 +0100134
135 if (!index)
136 return fallback;
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100137
138 if (!*str)
139 ++str;
140 for (--index; *str && index; --index)
141 str += strlen(str) + 1;
142
143 return str;
144}
145
146static struct smbios_header *next_table(struct smbios_header *table)
147{
148 const char *str;
149
150 if (table->type == SMBIOS_END_OF_TABLE)
151 return NULL;
152
Heinrich Schuchardtbaf24c72024-01-29 18:01:27 +0100153 str = smbios_get_string(table, -1);
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100154 return (struct smbios_header *)(++str);
155}
156
157static void smbios_print_generic(struct smbios_header *table)
158{
159 char *str = (char *)table + table->length;
160
161 if (CONFIG_IS_ENABLED(HEXDUMP)) {
162 printf("Header and Data:\n");
163 print_hex_dump("\t", DUMP_PREFIX_OFFSET, 16, 1,
164 table, table->length, false);
165 }
166 if (*str) {
167 printf("Strings:\n");
168 for (int index = 1; *str; ++index) {
169 printf("\tString %u: %s\n", index, str);
170 str += strlen(str) + 1;
171 }
172 }
173}
174
Raymond Mao6a125b32024-12-06 14:54:26 -0800175static void smbios_print_str(const char *label, void *table, u8 index)
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100176{
177 printf("\t%s: %s\n", label, smbios_get_string(table, index));
178}
179
Raymond Mao6a125b32024-12-06 14:54:26 -0800180static void smbios_print_lookup_str(const struct str_lookup_table *table,
181 u16 index, u16 array_size,
182 const char *prefix)
183{
184 int i;
185 const char *str = NULL;
186
187 for (i = 0; i < array_size; i++) {
188 if ((table + i)->idx == index)
189 str = (table + i)->str;
190 }
191
192 if (str)
193 printf("\t%s: %s\n", prefix, str);
194 else
195 printf("\t%s: [%04x]\n", prefix, index);
196}
197
198static void smbios_print_type0(struct smbios_type0 *table)
Heinrich Schuchardt58b796b2024-02-10 12:06:47 +0100199{
Raymond Mao6a125b32024-12-06 14:54:26 -0800200 printf("BIOS Information\n");
201 smbios_print_str("Vendor", table, table->vendor);
202 smbios_print_str("BIOS Version", table, table->bios_ver);
203 /* Keep table->bios_start_segment as 0 for UEFI-based systems */
204 smbios_print_str("BIOS Release Date", table, table->bios_release_date);
205 printf("\tBIOS ROM Size: 0x%02x\n", table->bios_rom_size);
206 printf("\tBIOS Characteristics: 0x%016llx\n",
207 table->bios_characteristics);
208 printf("\tBIOS Characteristics Extension Byte 1: 0x%02x\n",
209 table->bios_characteristics_ext1);
210 printf("\tBIOS Characteristics Extension Byte 2: 0x%02x\n",
211 table->bios_characteristics_ext2);
212 printf("\tSystem BIOS Major Release: 0x%02x\n",
213 table->bios_major_release);
214 printf("\tSystem BIOS Minor Release: 0x%02x\n",
215 table->bios_minor_release);
216 printf("\tEmbedded Controller Firmware Major Release: 0x%02x\n",
217 table->ec_major_release);
218 printf("\tEmbedded Controller Firmware Minor Release: 0x%02x\n",
219 table->ec_minor_release);
220 printf("\tExtended BIOS ROM Size: 0x%04x\n",
221 table->extended_bios_rom_size);
Heinrich Schuchardt58b796b2024-02-10 12:06:47 +0100222}
223
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100224static void smbios_print_type1(struct smbios_type1 *table)
225{
226 printf("System Information\n");
227 smbios_print_str("Manufacturer", table, table->manufacturer);
228 smbios_print_str("Product Name", table, table->product_name);
229 smbios_print_str("Version", table, table->version);
230 smbios_print_str("Serial Number", table, table->serial_number);
Raymond Maof4b933d2024-12-06 14:54:18 -0800231 if (table->hdr.length >= SMBIOS_TYPE1_LENGTH_V21) {
Heinrich Schuchardt5b3bfee2024-01-29 18:51:24 +0100232 printf("\tUUID: %pUl\n", table->uuid);
Raymond Mao6a125b32024-12-06 14:54:26 -0800233 smbios_print_lookup_str(wakeup_type_strings,
234 table->wakeup_type,
235 ARRAY_SIZE(wakeup_type_strings),
236 "Wake-up Type");
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100237 }
Raymond Maof4b933d2024-12-06 14:54:18 -0800238 if (table->hdr.length >= SMBIOS_TYPE1_LENGTH_V24) {
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100239 smbios_print_str("SKU Number", table, table->sku_number);
Heinrich Schuchardt58b796b2024-02-10 12:06:47 +0100240 smbios_print_str("Family", table, table->family);
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100241 }
242}
243
244static void smbios_print_type2(struct smbios_type2 *table)
245{
Raymond Mao6a125b32024-12-06 14:54:26 -0800246 int i;
247 u8 *addr = (u8 *)table + offsetof(struct smbios_type2, eos);
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100248
Raymond Mao6a125b32024-12-06 14:54:26 -0800249 printf("Baseboard Information\n");
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100250 smbios_print_str("Manufacturer", table, table->manufacturer);
251 smbios_print_str("Product Name", table, table->product_name);
252 smbios_print_str("Version", table, table->version);
253 smbios_print_str("Serial Number", table, table->serial_number);
254 smbios_print_str("Asset Tag", table, table->asset_tag_number);
Raymond Mao6a125b32024-12-06 14:54:26 -0800255 printf("\tFeature Flags: 0x%02x\n", table->feature_flags);
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100256 smbios_print_str("Chassis Location", table, table->chassis_location);
Heinrich Schuchardtb1d31082024-01-29 18:09:50 +0100257 printf("\tChassis Handle: 0x%04x\n", table->chassis_handle);
Raymond Mao6a125b32024-12-06 14:54:26 -0800258 smbios_print_lookup_str(boardtype_strings,
259 table->board_type,
260 ARRAY_SIZE(boardtype_strings),
261 "Board Type");
262 printf("\tNumber of Contained Object Handles: 0x%02x\n",
263 table->number_contained_objects);
264 if (!table->number_contained_objects)
265 return;
266
267 printf("\tContained Object Handles:\n");
268 for (i = 0; i < table->number_contained_objects; i++) {
269 printf("\t\tObject[%03d]:\n", i);
270 if (CONFIG_IS_ENABLED(HEXDUMP))
271 print_hex_dump("\t\t", DUMP_PREFIX_OFFSET, 16, 1, addr,
272 sizeof(u16), false);
273 addr += sizeof(u16);
274 }
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100275 printf("\n");
276}
277
Raymond Mao6a125b32024-12-06 14:54:26 -0800278static void smbios_print_type3(struct smbios_type3 *table)
279{
280 int i;
281 u8 *addr = (u8 *)table + offsetof(struct smbios_type3, sku_number);
282
283 printf("Baseboard Information\n");
284 smbios_print_str("Manufacturer", table, table->manufacturer);
285 printf("\tType: 0x%02x\n", table->chassis_type);
286 smbios_print_str("Version", table, table->version);
287 smbios_print_str("Serial Number", table, table->serial_number);
288 smbios_print_str("Asset Tag", table, table->asset_tag_number);
289 smbios_print_lookup_str(chassis_state_strings,
290 table->bootup_state,
291 ARRAY_SIZE(chassis_state_strings),
292 "Boot-up State");
293 smbios_print_lookup_str(chassis_state_strings,
294 table->power_supply_state,
295 ARRAY_SIZE(chassis_state_strings),
296 "Power Supply State");
297 smbios_print_lookup_str(chassis_state_strings,
298 table->thermal_state,
299 ARRAY_SIZE(chassis_state_strings),
300 "Thermal State");
301 smbios_print_lookup_str(chassis_security_strings,
302 table->security_status,
303 ARRAY_SIZE(chassis_security_strings),
304 "Security Status");
305 printf("\tOEM-defined: 0x%08x\n", table->oem_defined);
306 printf("\tHeight: 0x%02x\n", table->height);
307 printf("\tNumber of Power Cords: 0x%02x\n",
308 table->number_of_power_cords);
309 printf("\tContained Element Count: 0x%02x\n", table->element_count);
310 printf("\tContained Element Record Length: 0x%02x\n",
311 table->element_record_length);
312 if (table->element_count) {
313 printf("\tContained Elements:\n");
314 for (i = 0; i < table->element_count; i++) {
315 printf("\t\tElement[%03d]:\n", i);
316 if (CONFIG_IS_ENABLED(HEXDUMP))
317 print_hex_dump("\t\t", DUMP_PREFIX_OFFSET, 16,
318 1, addr,
319 table->element_record_length,
320 false);
321 printf("\t\tContained Element Type: 0x%02x\n", *addr);
322 printf("\t\tContained Element Minimum: 0x%02x\n",
323 *(addr + 1));
324 printf("\t\tContained Element Maximum: 0x%02x\n",
325 *(addr + 2));
326 addr += table->element_record_length;
327 }
328 }
329 smbios_print_str("SKU Number", table, *addr);
330}
331
332static void smbios_print_type4(struct smbios_type4 *table)
333{
334 printf("Processor Information:\n");
335 smbios_print_str("Socket Designation", table, table->socket_design);
336 smbios_print_lookup_str(processor_type_strings,
337 table->processor_type,
338 ARRAY_SIZE(processor_type_strings),
339 "Processor Type");
340 smbios_print_lookup_str(processor_family_strings,
341 table->processor_family,
342 ARRAY_SIZE(processor_family_strings),
343 "Processor Family");
344 smbios_print_str("Processor Manufacturer", table,
345 table->processor_manufacturer);
346 printf("\tProcessor ID word 0: 0x%08x\n", table->processor_id[0]);
347 printf("\tProcessor ID word 1: 0x%08x\n", table->processor_id[1]);
348 smbios_print_str("Processor Version", table, table->processor_version);
349 printf("\tVoltage: 0x%02x\n", table->voltage);
350 printf("\tExternal Clock: 0x%04x\n", table->external_clock);
351 printf("\tMax Speed: 0x%04x\n", table->max_speed);
352 printf("\tCurrent Speed: 0x%04x\n", table->current_speed);
353 printf("\tStatus: 0x%02x\n", table->status);
354 smbios_print_lookup_str(processor_upgrade_strings,
355 table->processor_upgrade,
356 ARRAY_SIZE(processor_upgrade_strings),
357 "Processor Upgrade");
358 printf("\tL1 Cache Handle: 0x%04x\n", table->l1_cache_handle);
359 printf("\tL2 Cache Handle: 0x%04x\n", table->l2_cache_handle);
360 printf("\tL3 Cache Handle: 0x%04x\n", table->l3_cache_handle);
361 smbios_print_str("Serial Number", table, table->serial_number);
362 smbios_print_str("Asset Tag", table, table->asset_tag);
363 smbios_print_str("Part Number", table, table->part_number);
364 printf("\tCore Count: 0x%02x\n", table->core_count);
365 printf("\tCore Enabled: 0x%02x\n", table->core_enabled);
366 printf("\tThread Count: 0x%02x\n", table->thread_count);
367 printf("\tProcessor Characteristics: 0x%04x\n",
368 table->processor_characteristics);
369 smbios_print_lookup_str(processor_family_strings,
370 table->processor_family2,
371 ARRAY_SIZE(processor_family_strings),
372 "Processor Family 2");
373 printf("\tCore Count 2: 0x%04x\n", table->core_count2);
374 printf("\tCore Enabled 2: 0x%04x\n", table->core_enabled2);
375 printf("\tThread Count 2: 0x%04x\n", table->thread_count2);
376 printf("\tThread Enabled: 0x%04x\n", table->thread_enabled);
377}
378
379static void smbios_print_type7(struct smbios_type7 *table)
380{
381 printf("Cache Information:\n");
382 smbios_print_str("Socket Designation", table,
383 table->socket_design);
384 printf("\tCache Configuration: 0x%04x\n", table->config.data);
385 printf("\tMaximum Cache Size: 0x%04x\n", table->max_size.data);
386 printf("\tInstalled Size: 0x%04x\n", table->inst_size.data);
387 printf("\tSupported SRAM Type: 0x%04x\n", table->supp_sram_type.data);
388 printf("\tCurrent SRAM Type: 0x%04x\n", table->curr_sram_type.data);
389 printf("\tCache Speed: 0x%02x\n", table->speed);
390 smbios_print_lookup_str(err_corr_type_strings,
391 table->err_corr_type,
392 ARRAY_SIZE(err_corr_type_strings),
393 "Error Correction Type");
394 smbios_print_lookup_str(sys_cache_type_strings,
395 table->sys_cache_type,
396 ARRAY_SIZE(sys_cache_type_strings),
397 "System Cache Type");
398 smbios_print_lookup_str(associativity_strings,
399 table->associativity,
400 ARRAY_SIZE(associativity_strings),
401 "Associativity");
402 printf("\tMaximum Cache Size 2: 0x%08x\n", table->max_size2.data);
403 printf("\tInstalled Cache Size 2: 0x%08x\n", table->inst_size2.data);
404}
405
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100406static void smbios_print_type127(struct smbios_type127 *table)
407{
408 printf("End Of Table\n");
409}
410
411static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
412 char *const argv[])
413{
414 ulong addr;
415 void *entry;
416 u32 size;
417 char version[12];
418 struct smbios_header *table;
419 static const char smbios_sig[] = "_SM_";
420 static const char smbios3_sig[] = "_SM3_";
421 size_t count = 0;
Heinrich Schuchardt4bdecef2024-01-31 23:34:46 +0100422 u32 table_maximum_size;
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100423
424 addr = gd_smbios_start();
425 if (!addr) {
426 log_warning("SMBIOS not available\n");
427 return CMD_RET_FAILURE;
428 }
429 entry = map_sysmem(addr, 0);
430 if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
431 struct smbios3_entry *entry3 = entry;
432
433 table = (void *)(uintptr_t)entry3->struct_table_address;
434 snprintf(version, sizeof(version), "%d.%d.%d",
435 entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
436 table = (void *)(uintptr_t)entry3->struct_table_address;
437 size = entry3->length;
Heinrich Schuchardt68e948a2024-01-31 23:49:34 +0100438 table_maximum_size = entry3->table_maximum_size;
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100439 } else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
440 struct smbios_entry *entry2 = entry;
441
442 snprintf(version, sizeof(version), "%d.%d",
443 entry2->major_ver, entry2->minor_ver);
444 table = (void *)(uintptr_t)entry2->struct_table_address;
445 size = entry2->length;
Heinrich Schuchardt4bdecef2024-01-31 23:34:46 +0100446 table_maximum_size = entry2->struct_table_length;
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100447 } else {
448 log_err("Unknown SMBIOS anchor format\n");
449 return CMD_RET_FAILURE;
450 }
451 if (table_compute_checksum(entry, size)) {
452 log_err("Invalid anchor checksum\n");
453 return CMD_RET_FAILURE;
454 }
455 printf("SMBIOS %s present.\n", version);
456
457 for (struct smbios_header *pos = table; pos; pos = next_table(pos))
458 ++count;
Heinrich Schuchardt4bdecef2024-01-31 23:34:46 +0100459 printf("%zd structures occupying %d bytes\n", count, table_maximum_size);
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100460 printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
461
462 for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
463 printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n",
464 pos->handle, pos->type, pos->length,
465 (unsigned long long)map_to_sysmem(pos));
466 switch (pos->type) {
Raymond Mao6a125b32024-12-06 14:54:26 -0800467 case SMBIOS_BIOS_INFORMATION:
468 smbios_print_type0((struct smbios_type0 *)pos);
469 break;
470 case SMBIOS_SYSTEM_INFORMATION:
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100471 smbios_print_type1((struct smbios_type1 *)pos);
472 break;
Raymond Mao6a125b32024-12-06 14:54:26 -0800473 case SMBIOS_BOARD_INFORMATION:
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100474 smbios_print_type2((struct smbios_type2 *)pos);
475 break;
Raymond Mao6a125b32024-12-06 14:54:26 -0800476 case SMBIOS_SYSTEM_ENCLOSURE:
477 smbios_print_type3((struct smbios_type3 *)pos);
478 break;
479 case SMBIOS_PROCESSOR_INFORMATION:
480 smbios_print_type4((struct smbios_type4 *)pos);
481 break;
482 case SMBIOS_CACHE_INFORMATION:
483 smbios_print_type7((struct smbios_type7 *)pos);
484 break;
485 case SMBIOS_END_OF_TABLE:
Heinrich Schuchardtbf11df82024-01-25 16:54:34 +0100486 smbios_print_type127((struct smbios_type127 *)pos);
487 break;
488 default:
489 smbios_print_generic(pos);
490 break;
491 }
492 }
493
494 return CMD_RET_SUCCESS;
495}
496
497U_BOOT_LONGHELP(smbios, "- display SMBIOS information");
498
499U_BOOT_CMD(smbios, 1, 0, do_smbios, "display SMBIOS information",
500 smbios_help_text);