comm: add -Wall
[unleashed.git] / usr / src / cmd / smbios / smbios.c
bloba40e393a91a10001d6fb435b906d859dcae3a3f4
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
24 * Copyright (c) 2017, Joyent, Inc.
25 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 #include <sys/sysmacros.h>
30 #include <sys/param.h>
32 #include <smbios.h>
33 #include <alloca.h>
34 #include <limits.h>
35 #include <unistd.h>
36 #include <strings.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <ctype.h>
44 #define SMBIOS_SUCCESS 0
45 #define SMBIOS_ERROR 1
46 #define SMBIOS_USAGE 2
48 static const char *g_pname;
49 static int g_hdr;
51 static int opt_e;
52 static int opt_i = -1;
53 static int opt_O;
54 static int opt_s;
55 static int opt_t = -1;
56 static int opt_x;
58 /*PRINTFLIKE2*/
59 static void
60 smbios_warn(smbios_hdl_t *shp, const char *format, ...)
62 va_list ap;
64 va_start(ap, format);
65 (void) vfprintf(stderr, format, ap);
66 va_end(ap);
68 if (shp != NULL) {
69 (void) fprintf(stderr, ": %s",
70 smbios_errmsg(smbios_errno(shp)));
73 (void) fprintf(stderr, "\n");
76 /*PRINTFLIKE2*/
77 static void
78 oprintf(FILE *fp, const char *format, ...)
80 va_list ap;
82 va_start(ap, format);
83 (void) vfprintf(fp, format, ap);
84 va_end(ap);
87 /*PRINTFLIKE3*/
88 static void
89 desc_printf(const char *d, FILE *fp, const char *format, ...)
91 va_list ap;
93 va_start(ap, format);
94 (void) vfprintf(fp, format, ap);
95 va_end(ap);
97 if (d != NULL)
98 (void) fprintf(fp, " (%s)\n", d);
99 else
100 (void) fprintf(fp, "\n");
103 static void
104 flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits,
105 const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t))
107 size_t i;
109 oprintf(fp, " %s: 0x%x\n", s, flags);
111 for (i = 0; i < bits; i++) {
112 uint_t f = 1 << i;
113 const char *n;
115 if (!(flags & f))
116 continue;
118 if ((n = flag_name(f)) != NULL)
119 desc_printf(flag_desc(f), fp, "\t%s", n);
120 else
121 desc_printf(flag_desc(f), fp, "\t0x%x", f);
125 static void
126 flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits,
127 const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t))
129 size_t i;
131 oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags);
133 for (i = 0; i < bits; i++) {
134 u_longlong_t f = 1ULL << i;
135 const char *n;
137 if (!(flags & f))
138 continue;
140 if ((n = flag_name(f)) != NULL)
141 desc_printf(flag_desc(f), fp, "\t%s", n);
142 else
143 desc_printf(flag_desc(f), fp, "\t0x%llx", f);
147 static void
148 id_printf(FILE *fp, const char *s, id_t id)
150 switch (id) {
151 case SMB_ID_NONE:
152 oprintf(fp, "%sNone\n", s);
153 break;
154 case SMB_ID_NOTSUP:
155 oprintf(fp, "%sNot Supported\n", s);
156 break;
157 default:
158 oprintf(fp, "%s%u\n", s, (uint_t)id);
162 static int
163 check_oem(smbios_hdl_t *shp)
165 int i;
166 int cnt;
167 int rv;
168 id_t oem_id;
169 smbios_struct_t s;
170 const char **oem_str;
172 rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s);
173 if (rv != 0) {
174 return (-1);
177 oem_id = s.smbstr_id;
179 cnt = smbios_info_strtab(shp, oem_id, 0, NULL);
180 if (cnt > 0) {
181 oem_str = alloca(sizeof (char *) * cnt);
182 (void) smbios_info_strtab(shp, oem_id, cnt, oem_str);
184 for (i = 0; i < cnt; i++) {
185 if (strncmp(oem_str[i], SMB_PRMS1,
186 strlen(SMB_PRMS1) + 1) == 0) {
187 return (0);
192 return (-1);
195 static void
196 print_smbios_21(smbios_21_entry_t *ep, FILE *fp)
198 int i;
200 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n",
201 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor),
202 ep->smbe_eanchor);
204 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum);
205 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen);
206 oprintf(fp, "Entry Point Version: %u.%u\n",
207 ep->smbe_major, ep->smbe_minor);
208 oprintf(fp, "Max Structure Size: %u\n", ep->smbe_maxssize);
209 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision);
211 oprintf(fp, "Entry Point Revision Data:");
212 for (i = 0; i < sizeof (ep->smbe_format); i++)
213 oprintf(fp, " 0x%02x", ep->smbe_format[i]);
214 oprintf(fp, "\n");
216 oprintf(fp, "Intermediate Anchor Tag: %*.*s\n",
217 (int)sizeof (ep->smbe_ianchor), (int)sizeof (ep->smbe_ianchor),
218 ep->smbe_ianchor);
220 oprintf(fp, "Intermediate Checksum: 0x%x\n", ep->smbe_icksum);
221 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen);
222 oprintf(fp, "Structure Table Address: 0x%x\n", ep->smbe_staddr);
223 oprintf(fp, "Structure Table Entries: %u\n", ep->smbe_stnum);
224 oprintf(fp, "DMI BCD Revision: 0x%x\n", ep->smbe_bcdrev);
227 static void
228 print_smbios_30(smbios_30_entry_t *ep, FILE *fp)
230 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n",
231 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor),
232 ep->smbe_eanchor);
234 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum);
235 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen);
236 oprintf(fp, "SMBIOS Version: %u.%u\n",
237 ep->smbe_major, ep->smbe_minor);
238 oprintf(fp, "SMBIOS DocRev: 0x%x\n", ep->smbe_docrev);
239 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision);
241 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen);
242 oprintf(fp, "Structure Table Address: 0x%" PRIx64 "\n",
243 ep->smbe_staddr);
246 static void
247 print_smbios(smbios_hdl_t *shp, FILE *fp)
249 smbios_entry_t ep;
251 switch (smbios_info_smbios(shp, &ep)) {
252 case SMBIOS_ENTRY_POINT_21:
253 print_smbios_21(&ep.ep21, fp);
254 break;
255 case SMBIOS_ENTRY_POINT_30:
256 print_smbios_30(&ep.ep30, fp);
257 break;
261 static void
262 print_common(const smbios_info_t *ip, FILE *fp)
264 if (ip->smbi_manufacturer[0] != '\0')
265 oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer);
266 if (ip->smbi_product[0] != '\0')
267 oprintf(fp, " Product: %s\n", ip->smbi_product);
268 if (ip->smbi_version[0] != '\0')
269 oprintf(fp, " Version: %s\n", ip->smbi_version);
270 if (ip->smbi_serial[0] != '\0')
271 oprintf(fp, " Serial Number: %s\n", ip->smbi_serial);
272 if (ip->smbi_asset[0] != '\0')
273 oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset);
274 if (ip->smbi_location[0] != '\0')
275 oprintf(fp, " Location Tag: %s\n", ip->smbi_location);
276 if (ip->smbi_part[0] != '\0')
277 oprintf(fp, " Part Number: %s\n", ip->smbi_part);
280 static void
281 print_bios(smbios_hdl_t *shp, FILE *fp)
283 smbios_bios_t b;
285 (void) smbios_info_bios(shp, &b);
287 oprintf(fp, " Vendor: %s\n", b.smbb_vendor);
288 oprintf(fp, " Version String: %s\n", b.smbb_version);
289 oprintf(fp, " Release Date: %s\n", b.smbb_reldate);
290 oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment);
291 oprintf(fp, " ROM Size: %" PRIu64 " bytes\n", b.smbb_extromsize);
292 oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize);
294 flag64_printf(fp, "Characteristics",
295 b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY,
296 smbios_bios_flag_name, smbios_bios_flag_desc);
298 if (b.smbb_nxcflags > SMB_BIOSXB_1) {
299 flag_printf(fp, "Characteristics Extension Byte 1",
300 b.smbb_xcflags[SMB_BIOSXB_1],
301 sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY,
302 smbios_bios_xb1_name, smbios_bios_xb1_desc);
305 if (b.smbb_nxcflags > SMB_BIOSXB_2) {
306 flag_printf(fp, "Characteristics Extension Byte 2",
307 b.smbb_xcflags[SMB_BIOSXB_2],
308 sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY,
309 smbios_bios_xb2_name, smbios_bios_xb2_desc);
312 if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) {
313 oprintf(fp, " Version Number: %u.%u\n",
314 b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor);
318 * If the major and minor versions are 0xff then that indicates that the
319 * embedded controller does not exist.
321 if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN &&
322 b.smbb_ecfwv.smbv_major != 0xff &&
323 b.smbb_ecfwv.smbv_minor != 0xff) {
324 oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n",
325 b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor);
329 static void
330 print_system(smbios_hdl_t *shp, FILE *fp)
332 smbios_system_t s;
333 uint_t i;
335 (void) smbios_info_system(shp, &s);
337 oprintf(fp, " UUID: ");
338 for (i = 0; i < s.smbs_uuidlen; i++) {
339 oprintf(fp, "%02x", s.smbs_uuid[i]);
340 if (i == 3 || i == 5 || i == 7 || i == 9)
341 oprintf(fp, "-");
343 oprintf(fp, "\n");
345 desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup),
346 fp, " Wake-Up Event: 0x%x", s.smbs_wakeup);
348 oprintf(fp, " SKU Number: %s\n", s.smbs_sku);
349 oprintf(fp, " Family: %s\n", s.smbs_family);
352 static void
353 print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp)
355 smbios_bboard_t b;
356 int chdl_cnt;
358 (void) smbios_info_bboard(shp, id, &b);
360 oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis);
362 flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY,
363 smbios_bboard_flag_name, smbios_bboard_flag_desc);
365 desc_printf(smbios_bboard_type_desc(b.smbb_type),
366 fp, " Board Type: 0x%x", b.smbb_type);
368 chdl_cnt = b.smbb_contn;
369 if (chdl_cnt != 0) {
370 id_t *chdl;
371 uint16_t hdl;
372 int i, n, cnt;
374 chdl = alloca(chdl_cnt * sizeof (id_t));
375 cnt = smbios_info_contains(shp, id, chdl_cnt, chdl);
376 if (cnt > SMB_CONT_MAX)
377 return;
378 n = MIN(chdl_cnt, cnt);
380 oprintf(fp, "\n");
381 for (i = 0; i < n; i++) {
382 hdl = (uint16_t)chdl[i];
383 oprintf(fp, " Contained Handle: %u\n", hdl);
388 static void
389 print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp)
391 smbios_chassis_t c;
392 int elem_cnt;
394 (void) smbios_info_chassis(shp, id, &c);
396 oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata);
397 oprintf(fp, " SKU number: %s\n",
398 c.smbc_sku[0] == '\0' ? "<unknown>" : c.smbc_sku);
399 oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N");
401 desc_printf(smbios_chassis_type_desc(c.smbc_type),
402 fp, " Chassis Type: 0x%x", c.smbc_type);
404 desc_printf(smbios_chassis_state_desc(c.smbc_bustate),
405 fp, " Boot-Up State: 0x%x", c.smbc_bustate);
407 desc_printf(smbios_chassis_state_desc(c.smbc_psstate),
408 fp, " Power Supply State: 0x%x", c.smbc_psstate);
410 desc_printf(smbios_chassis_state_desc(c.smbc_thstate),
411 fp, " Thermal State: 0x%x", c.smbc_thstate);
413 oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight);
414 oprintf(fp, " Power Cords: %u\n", c.smbc_cords);
416 elem_cnt = c.smbc_elems;
417 oprintf(fp, " Element Records: %u\n", elem_cnt);
419 if (elem_cnt > 0) {
420 id_t *elems;
421 uint8_t type;
422 int i, n, cnt;
424 elems = alloca(c.smbc_elems * sizeof (id_t));
425 cnt = smbios_info_contains(shp, id, elem_cnt, elems);
426 if (cnt > SMB_CONT_MAX)
427 return;
428 n = MIN(elem_cnt, cnt);
430 oprintf(fp, "\n");
431 for (i = 0; i < n; i++) {
432 type = (uint8_t)elems[i];
433 if (type & 0x80) {
434 /* SMBIOS structrure Type */
435 desc_printf(smbios_type_name(type & 0x7f), fp,
436 " Contained SMBIOS structure Type: %u",
437 type & 0x80);
438 } else {
439 /* SMBIOS Base Board Type */
440 desc_printf(smbios_bboard_type_desc(type), fp,
441 " Contained SMBIOS Base Board Type: 0x%x",
442 type);
448 static void
449 print_processor(smbios_hdl_t *shp, id_t id, FILE *fp)
451 smbios_processor_t p;
452 uint_t status;
454 (void) smbios_info_processor(shp, id, &p);
455 status = SMB_PRSTATUS_STATUS(p.smbp_status);
457 desc_printf(smbios_processor_family_desc(p.smbp_family),
458 fp, " Family: %u", p.smbp_family);
460 if (p.smbp_family2 != 0)
461 desc_printf(smbios_processor_family_desc(p.smbp_family2),
462 fp, " Family Ext: %u", p.smbp_family2);
464 oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid);
466 desc_printf(smbios_processor_type_desc(p.smbp_type),
467 fp, " Type: %u", p.smbp_type);
469 desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade),
470 fp, " Socket Upgrade: %u", p.smbp_upgrade);
472 oprintf(fp, " Socket Status: %s\n",
473 SMB_PRSTATUS_PRESENT(p.smbp_status) ?
474 "Populated" : "Not Populated");
476 desc_printf(smbios_processor_status_desc(status),
477 fp, " Processor Status: %u", status);
479 if (SMB_PRV_LEGACY(p.smbp_voltage)) {
480 oprintf(fp, " Supported Voltages:");
481 switch (p.smbp_voltage) {
482 case SMB_PRV_5V:
483 oprintf(fp, " 5.0V");
484 break;
485 case SMB_PRV_33V:
486 oprintf(fp, " 3.3V");
487 break;
488 case SMB_PRV_29V:
489 oprintf(fp, " 2.9V");
490 break;
492 oprintf(fp, "\n");
493 } else {
494 oprintf(fp, " Supported Voltages: %.1fV\n",
495 (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10);
498 if (p.smbp_corecount != 0) {
499 if (p.smbp_corecount != 0xff || p.smbp_corecount2 == 0)
500 oprintf(fp, " Core Count: %u\n", p.smbp_corecount);
501 else
502 oprintf(fp, " Core Count: %u\n", p.smbp_corecount2);
503 } else {
504 oprintf(fp, " Core Count: Unknown\n");
507 if (p.smbp_coresenabled != 0) {
508 if (p.smbp_coresenabled != 0xff || p.smbp_coresenabled2 == 0) {
509 oprintf(fp, " Cores Enabled: %u\n",
510 p.smbp_coresenabled);
511 } else {
512 oprintf(fp, " Cores Enabled: %u\n",
513 p.smbp_coresenabled2);
515 } else {
516 oprintf(fp, " Cores Enabled: Unknown\n");
519 if (p.smbp_threadcount != 0) {
520 if (p.smbp_threadcount != 0xff || p.smbp_threadcount2 == 0) {
521 oprintf(fp, " Thread Count: %u\n",
522 p.smbp_threadcount);
523 } else {
524 oprintf(fp, " Thread Count: %u\n",
525 p.smbp_threadcount2);
527 } else {
528 oprintf(fp, " Thread Count: Unknown\n");
531 if (p.smbp_cflags) {
532 flag_printf(fp, "Processor Characteristics",
533 p.smbp_cflags, sizeof (p.smbp_cflags) * NBBY,
534 smbios_processor_core_flag_name,
535 smbios_processor_core_flag_desc);
538 if (p.smbp_clkspeed != 0)
539 oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed);
540 else
541 oprintf(fp, " External Clock Speed: Unknown\n");
543 if (p.smbp_maxspeed != 0)
544 oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed);
545 else
546 oprintf(fp, " Maximum Speed: Unknown\n");
548 if (p.smbp_curspeed != 0)
549 oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed);
550 else
551 oprintf(fp, " Current Speed: Unknown\n");
553 id_printf(fp, " L1 Cache Handle: ", p.smbp_l1cache);
554 id_printf(fp, " L2 Cache Handle: ", p.smbp_l2cache);
555 id_printf(fp, " L3 Cache Handle: ", p.smbp_l3cache);
558 static void
559 print_cache(smbios_hdl_t *shp, id_t id, FILE *fp)
561 smbios_cache_t c;
563 (void) smbios_info_cache(shp, id, &c);
565 oprintf(fp, " Level: %u\n", c.smba_level);
566 oprintf(fp, " Maximum Installed Size: %" PRIu64 " bytes\n",
567 c.smba_maxsize2);
569 if (c.smba_size2 != 0) {
570 oprintf(fp, " Installed Size: %" PRIu64 " bytes\n",
571 c.smba_size2);
572 } else {
573 oprintf(fp, " Installed Size: Not Installed\n");
576 if (c.smba_speed != 0)
577 oprintf(fp, " Speed: %uns\n", c.smba_speed);
578 else
579 oprintf(fp, " Speed: Unknown\n");
581 flag_printf(fp, "Supported SRAM Types",
582 c.smba_stype, sizeof (c.smba_stype) * NBBY,
583 smbios_cache_ctype_name, smbios_cache_ctype_desc);
585 desc_printf(smbios_cache_ctype_desc(c.smba_ctype),
586 fp, " Current SRAM Type: 0x%x", c.smba_ctype);
588 desc_printf(smbios_cache_ecc_desc(c.smba_etype),
589 fp, " Error Correction Type: %u", c.smba_etype);
591 desc_printf(smbios_cache_logical_desc(c.smba_ltype),
592 fp, " Logical Cache Type: %u", c.smba_ltype);
594 desc_printf(smbios_cache_assoc_desc(c.smba_assoc),
595 fp, " Associativity: %u", c.smba_assoc);
597 desc_printf(smbios_cache_mode_desc(c.smba_mode),
598 fp, " Mode: %u", c.smba_mode);
600 desc_printf(smbios_cache_loc_desc(c.smba_location),
601 fp, " Location: %u", c.smba_location);
603 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY,
604 smbios_cache_flag_name, smbios_cache_flag_desc);
607 static void
608 print_port(smbios_hdl_t *shp, id_t id, FILE *fp)
610 smbios_port_t p;
612 (void) smbios_info_port(shp, id, &p);
614 oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref);
615 oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref);
617 desc_printf(smbios_port_conn_desc(p.smbo_itype),
618 fp, " Internal Connector Type: %u", p.smbo_itype);
620 desc_printf(smbios_port_conn_desc(p.smbo_etype),
621 fp, " External Connector Type: %u", p.smbo_etype);
623 desc_printf(smbios_port_type_desc(p.smbo_ptype),
624 fp, " Port Type: %u", p.smbo_ptype);
627 static void
628 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp)
630 smbios_slot_t s;
631 smbios_version_t v;
633 (void) smbios_info_slot(shp, id, &s);
634 smbios_info_smbios_version(shp, &v);
636 oprintf(fp, " Reference Designator: %s\n", s.smbl_name);
637 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id);
639 desc_printf(smbios_slot_type_desc(s.smbl_type),
640 fp, " Type: 0x%x", s.smbl_type);
642 desc_printf(smbios_slot_width_desc(s.smbl_width),
643 fp, " Width: 0x%x", s.smbl_width);
645 desc_printf(smbios_slot_usage_desc(s.smbl_usage),
646 fp, " Usage: 0x%x", s.smbl_usage);
648 desc_printf(smbios_slot_length_desc(s.smbl_length),
649 fp, " Length: 0x%x", s.smbl_length);
651 flag_printf(fp, "Slot Characteristics 1",
652 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY,
653 smbios_slot_ch1_name, smbios_slot_ch1_desc);
655 flag_printf(fp, "Slot Characteristics 2",
656 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY,
657 smbios_slot_ch2_name, smbios_slot_ch2_desc);
659 if (check_oem(shp) != 0 && (v.smbv_major < 2 || v.smbv_minor < 6))
660 return;
662 oprintf(fp, " Segment Group: %u\n", s.smbl_sg);
663 oprintf(fp, " Bus Number: %u\n", s.smbl_bus);
664 oprintf(fp, " Device/Function Number: %u\n", s.smbl_df);
667 static void
668 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp)
670 boolean_t enabled;
671 smbios_obdev_ext_t oe;
672 const char *type;
674 (void) smbios_info_obdevs_ext(shp, id, &oe);
677 * Bit 7 is always whether or not the device is enabled while bits 0:6
678 * are the actual device type.
680 enabled = oe.smboe_dtype >> 7;
681 type = smbios_onboard_type_desc(oe.smboe_dtype & 0x7f);
683 oprintf(fp, " Reference Designator: %s\n", oe.smboe_name);
684 oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" :
685 "false");
686 oprintf(fp, " Device Type: %s\n", type);
687 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti);
688 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg);
689 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus);
690 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df);
693 static void
694 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp)
696 smbios_obdev_t *argv;
697 int i, argc;
699 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) {
700 argv = alloca(sizeof (smbios_obdev_t) * argc);
701 (void) smbios_info_obdevs(shp, id, argc, argv);
702 for (i = 0; i < argc; i++)
703 oprintf(fp, " %s\n", argv[i].smbd_name);
707 static void
708 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp)
710 const char **argv;
711 int i, argc;
713 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) {
714 argv = alloca(sizeof (char *) * argc);
715 (void) smbios_info_strtab(shp, id, argc, argv);
716 for (i = 0; i < argc; i++)
717 oprintf(fp, " %s\n", argv[i]);
721 static void
722 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp)
724 smbios_lang_t l;
726 (void) smbios_info_lang(shp, &l);
728 oprintf(fp, " Current Language: %s\n", l.smbla_cur);
729 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt);
730 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num);
731 oprintf(fp, " Installed Languages:\n");
733 print_strtab(shp, id, fp);
736 /*ARGSUSED*/
737 static void
738 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp)
740 smbios_evlog_t ev;
741 uint32_t i;
743 (void) smbios_info_eventlog(shp, &ev);
745 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size);
746 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr);
747 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data);
749 desc_printf(smbios_evlog_method_desc(ev.smbev_method),
750 fp, " Data Access Method: %u", ev.smbev_method);
752 flag_printf(fp, "Log Flags",
753 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY,
754 smbios_evlog_flag_name, smbios_evlog_flag_desc);
756 desc_printf(smbios_evlog_format_desc(ev.smbev_format),
757 fp, " Log Header Format: %u", ev.smbev_format);
759 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token);
760 oprintf(fp, " Data Access Address: ");
762 switch (ev.smbev_method) {
763 case SMB_EVM_1x1i_1x1d:
764 case SMB_EVM_2x1i_1x1d:
765 case SMB_EVM_1x2i_1x1d:
766 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n",
767 ev.smbev_addr.eva_io.evi_iaddr,
768 ev.smbev_addr.eva_io.evi_daddr);
769 break;
770 case SMB_EVM_GPNV:
771 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv);
772 break;
773 default:
774 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr);
777 oprintf(fp, " Type Descriptors:\n");
779 for (i = 0; i < ev.smbev_typec; i++) {
780 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i,
781 ev.smbev_typev[i].smbevt_ltype,
782 ev.smbev_typev[i].smbevt_dtype);
786 static void
787 print_bytes(const uint8_t *data, size_t size, FILE *fp)
789 size_t row, rows = P2ROUNDUP(size, 16) / 16;
790 size_t col, cols;
792 char buf[17];
793 uint8_t x;
795 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f "
796 "0123456789abcdef\n");
798 for (row = 0; row < rows; row++) {
799 oprintf(fp, " %#6lx: ", (ulong_t)row * 16);
800 cols = MIN(size - row * 16, 16);
802 for (col = 0; col < cols; col++) {
803 if (col % 4 == 0)
804 oprintf(fp, " ");
805 x = *data++;
806 oprintf(fp, "%02x", x);
807 buf[col] = x <= ' ' || x > '~' ? '.' : x;
810 for (; col < 16; col++) {
811 if (col % 4 == 0)
812 oprintf(fp, " ");
813 oprintf(fp, " ");
814 buf[col] = ' ';
817 buf[col] = '\0';
818 oprintf(fp, " %s\n", buf);
821 oprintf(fp, "\n");
824 static void
825 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp)
827 smbios_memarray_t ma;
829 (void) smbios_info_memarray(shp, id, &ma);
831 desc_printf(smbios_memarray_loc_desc(ma.smbma_location),
832 fp, " Location: %u", ma.smbma_location);
834 desc_printf(smbios_memarray_use_desc(ma.smbma_use),
835 fp, " Use: %u", ma.smbma_use);
837 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc),
838 fp, " ECC: %u", ma.smbma_ecc);
840 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs);
841 id_printf(fp, " Memory Error Data: ", ma.smbma_err);
842 oprintf(fp, " Max Capacity: %llu bytes\n",
843 (u_longlong_t)ma.smbma_size);
846 static void
847 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp)
849 smbios_memdevice_t md;
851 (void) smbios_info_memdevice(shp, id, &md);
853 id_printf(fp, " Physical Memory Array: ", md.smbmd_array);
854 id_printf(fp, " Memory Error Data: ", md.smbmd_error);
856 if (md.smbmd_twidth != -1u)
857 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth);
858 else
859 oprintf(fp, " Total Width: Unknown\n");
861 if (md.smbmd_dwidth != -1u)
862 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth);
863 else
864 oprintf(fp, " Data Width: Unknown\n");
866 switch (md.smbmd_size) {
867 case -1ull:
868 oprintf(fp, " Size: Unknown\n");
869 break;
870 case 0:
871 oprintf(fp, " Size: Not Populated\n");
872 break;
873 default:
874 oprintf(fp, " Size: %llu bytes\n",
875 (u_longlong_t)md.smbmd_size);
878 desc_printf(smbios_memdevice_form_desc(md.smbmd_form),
879 fp, " Form Factor: %u", md.smbmd_form);
881 if (md.smbmd_set == 0)
882 oprintf(fp, " Set: None\n");
883 else if (md.smbmd_set == (uint8_t)-1u)
884 oprintf(fp, " Set: Unknown\n");
885 else
886 oprintf(fp, " Set: %u\n", md.smbmd_set);
888 if (md.smbmd_rank != 0) {
889 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank),
890 fp, " Rank: %u", md.smbmd_rank);
891 } else {
892 oprintf(fp, " Rank: Unknown\n");
895 desc_printf(smbios_memdevice_type_desc(md.smbmd_type),
896 fp, " Memory Type: %u", md.smbmd_type);
898 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY,
899 smbios_memdevice_flag_name, smbios_memdevice_flag_desc);
901 if (md.smbmd_speed != 0)
902 oprintf(fp, " Speed: %u MT/s\n", md.smbmd_speed);
903 else
904 oprintf(fp, " Speed: Unknown\n");
906 if (md.smbmd_clkspeed != 0)
907 oprintf(fp, " Configured Speed: %u MT/s\n", md.smbmd_clkspeed);
908 else
909 oprintf(fp, " Configured Speed: Unknown\n");
911 oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc);
912 oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc);
914 if (md.smbmd_minvolt != 0) {
915 oprintf(fp, " Minimum Voltage: %.2fV\n",
916 md.smbmd_minvolt / 1000.0);
917 } else {
918 oprintf(fp, " Minimum Voltage: Unknown\n");
921 if (md.smbmd_maxvolt != 0) {
922 oprintf(fp, " Maximum Voltage: %.2fV\n",
923 md.smbmd_maxvolt / 1000.0);
924 } else {
925 oprintf(fp, " Maximum Voltage: Unknown\n");
928 if (md.smbmd_confvolt != 0) {
929 oprintf(fp, " Configured Voltage: %.2fV\n",
930 md.smbmd_confvolt / 1000.0);
931 } else {
932 oprintf(fp, " Configured Voltage: Unknown\n");
936 static void
937 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp)
939 smbios_memarrmap_t ma;
941 (void) smbios_info_memarrmap(shp, id, &ma);
943 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array);
944 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width);
946 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n",
947 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size);
950 static void
951 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp)
953 smbios_memdevmap_t md;
955 (void) smbios_info_memdevmap(shp, id, &md);
957 id_printf(fp, " Memory Device: ", md.smbmdm_device);
958 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap);
960 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n",
961 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size);
963 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos);
964 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos);
965 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth);
968 static void
969 print_hwsec(smbios_hdl_t *shp, FILE *fp)
971 smbios_hwsec_t h;
973 (void) smbios_info_hwsec(shp, &h);
975 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps),
976 fp, " Power-On Password Status: %u", h.smbh_pwr_ps);
977 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps),
978 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps);
979 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps),
980 fp, " Administrator Password Status: %u", h.smbh_adm_ps);
981 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps),
982 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps);
985 static void
986 print_vprobe(smbios_hdl_t *shp, id_t id, FILE *fp)
988 smbios_vprobe_t vp;
990 if (smbios_info_vprobe(shp, id, &vp) != 0) {
991 smbios_warn(shp, "failed to read voltage probe information");
992 return;
995 oprintf(fp, " Description: %s\n", vp.smbvp_description != NULL ?
996 vp.smbvp_description : "unknown");
997 desc_printf(smbios_vprobe_loc_desc(vp.smbvp_location),
998 fp, " Location: %u", vp.smbvp_location);
999 desc_printf(smbios_vprobe_status_desc(vp.smbvp_status),
1000 fp, " Status: %u", vp.smbvp_status);
1002 if (vp.smbvp_maxval != SMB_PROBE_UNKNOWN_VALUE) {
1003 oprintf(fp, " Maximum Possible Voltage: %u mV\n",
1004 vp.smbvp_maxval);
1005 } else {
1006 oprintf(fp, " Maximum Possible Voltage: unknown\n");
1009 if (vp.smbvp_minval != SMB_PROBE_UNKNOWN_VALUE) {
1010 oprintf(fp, " Minimum Possible Voltage: %u mV\n",
1011 vp.smbvp_minval);
1012 } else {
1013 oprintf(fp, " Minimum Possible Voltage: unknown\n");
1016 if (vp.smbvp_resolution != SMB_PROBE_UNKNOWN_VALUE) {
1017 oprintf(fp, " Probe Resolution: %u.%u mV\n",
1018 vp.smbvp_resolution / 10,
1019 vp.smbvp_resolution % 10);
1020 } else {
1021 oprintf(fp, " Probe Resolution: unknown\n");
1024 if (vp.smbvp_tolerance != SMB_PROBE_UNKNOWN_VALUE) {
1025 oprintf(fp, " Probe Tolerance: +/-%u mV\n",
1026 vp.smbvp_tolerance);
1027 } else {
1028 oprintf(fp, " Probe Tolerance: unknown\n");
1031 if (vp.smbvp_accuracy != SMB_PROBE_UNKNOWN_VALUE) {
1032 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n",
1033 vp.smbvp_accuracy / 100,
1034 vp.smbvp_accuracy % 100);
1035 } else {
1036 oprintf(fp, " Probe Accuracy: unknown\n");
1039 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", vp.smbvp_oem);
1041 if (vp.smbvp_nominal != SMB_PROBE_UNKNOWN_VALUE) {
1042 oprintf(fp, " Probe Nominal Value: %u mV\n", vp.smbvp_nominal);
1043 } else {
1044 oprintf(fp, " Probe Nominal Value: unknown\n");
1048 static void
1049 print_cooldev(smbios_hdl_t *shp, id_t id, FILE *fp)
1051 smbios_cooldev_t cd;
1053 if (smbios_info_cooldev(shp, id, &cd) != 0) {
1054 smbios_warn(shp, "failed to read cooling device "
1055 "information");
1056 return;
1059 id_printf(fp, " Temperature Probe Handle: ", cd.smbcd_tprobe);
1060 desc_printf(smbios_cooldev_type_desc(cd.smbcd_type),
1061 fp, " Device Type: %u", cd.smbcd_type);
1062 desc_printf(smbios_cooldev_status_desc(cd.smbcd_status),
1063 fp, " Status: %u", cd.smbcd_status);
1064 oprintf(fp, " Cooling Unit Group: %u\n", cd.smbcd_group);
1065 oprintf(fp, " OEM- or BIOS- defined data: 0x%x\n", cd.smbcd_oem);
1066 if (cd.smbcd_nominal != SMB_PROBE_UNKNOWN_VALUE) {
1067 oprintf(fp, " Nominal Speed: %u RPM\n", cd.smbcd_nominal);
1068 } else {
1069 oprintf(fp, " Nominal Speed: unknown\n");
1072 if (cd.smbcd_descr != NULL && cd.smbcd_descr[0] != '\0') {
1073 oprintf(fp, " Description: %s\n", cd.smbcd_descr);
1077 static void
1078 print_tprobe(smbios_hdl_t *shp, id_t id, FILE *fp)
1080 smbios_tprobe_t tp;
1082 if (smbios_info_tprobe(shp, id, &tp) != 0) {
1083 smbios_warn(shp, "failed to read temperature probe "
1084 "information");
1085 return;
1088 oprintf(fp, " Description: %s\n", tp.smbtp_description != NULL ?
1089 tp.smbtp_description : "unknown");
1090 desc_printf(smbios_tprobe_loc_desc(tp.smbtp_location),
1091 fp, " Location: %u", tp.smbtp_location);
1092 desc_printf(smbios_tprobe_status_desc(tp.smbtp_status),
1093 fp, " Status: %u", tp.smbtp_status);
1095 if (tp.smbtp_maxval != SMB_PROBE_UNKNOWN_VALUE) {
1096 oprintf(fp, " Maximum Possible Temperature: %u.%u C\n",
1097 tp.smbtp_maxval / 10, tp.smbtp_maxval % 10);
1098 } else {
1099 oprintf(fp, " Maximum Possible Temperature: unknown\n");
1102 if (tp.smbtp_minval != SMB_PROBE_UNKNOWN_VALUE) {
1103 oprintf(fp, " Minimum Possible Temperature: %u.%u C\n",
1104 tp.smbtp_minval / 10, tp.smbtp_minval % 10);
1105 } else {
1106 oprintf(fp, " Minimum Possible Temperature: unknown\n");
1109 if (tp.smbtp_resolution != SMB_PROBE_UNKNOWN_VALUE) {
1110 oprintf(fp, " Probe Resolution: %u.%03u C\n",
1111 tp.smbtp_resolution / 1000,
1112 tp.smbtp_resolution % 1000);
1113 } else {
1114 oprintf(fp, " Probe Resolution: unknown\n");
1117 if (tp.smbtp_tolerance != SMB_PROBE_UNKNOWN_VALUE) {
1118 oprintf(fp, " Probe Tolerance: +/-%u.%u C\n",
1119 tp.smbtp_tolerance / 10, tp.smbtp_tolerance % 10);
1120 } else {
1121 oprintf(fp, " Probe Tolerance: unknown\n");
1124 if (tp.smbtp_accuracy != SMB_PROBE_UNKNOWN_VALUE) {
1125 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n",
1126 tp.smbtp_accuracy / 100,
1127 tp.smbtp_accuracy % 100);
1128 } else {
1129 oprintf(fp, " Probe Accuracy: unknown\n");
1132 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", tp.smbtp_oem);
1134 if (tp.smbtp_nominal != SMB_PROBE_UNKNOWN_VALUE) {
1135 oprintf(fp, " Probe Nominal Value: %u.%u C\n",
1136 tp.smbtp_nominal / 10, tp.smbtp_nominal % 10);
1137 } else {
1138 oprintf(fp, " Probe Nominal Value: unknown\n");
1142 static void
1143 print_iprobe(smbios_hdl_t *shp, id_t id, FILE *fp)
1145 smbios_iprobe_t ip;
1147 if (smbios_info_iprobe(shp, id, &ip) != 0) {
1148 smbios_warn(shp, "failed to read current probe information");
1149 return;
1152 oprintf(fp, " Description: %s\n", ip.smbip_description != NULL ?
1153 ip.smbip_description : "unknown");
1154 desc_printf(smbios_iprobe_loc_desc(ip.smbip_location),
1155 fp, " Location: %u", ip.smbip_location);
1156 desc_printf(smbios_iprobe_status_desc(ip.smbip_status),
1157 fp, " Status: %u", ip.smbip_status);
1159 if (ip.smbip_maxval != SMB_PROBE_UNKNOWN_VALUE) {
1160 oprintf(fp, " Maximum Possible Current: %u mA\n",
1161 ip.smbip_maxval);
1162 } else {
1163 oprintf(fp, " Maximum Possible Current: unknown\n");
1166 if (ip.smbip_minval != SMB_PROBE_UNKNOWN_VALUE) {
1167 oprintf(fp, " Minimum Possible Current: %u mA\n",
1168 ip.smbip_minval);
1169 } else {
1170 oprintf(fp, " Minimum Possible Current: unknown\n");
1173 if (ip.smbip_resolution != SMB_PROBE_UNKNOWN_VALUE) {
1174 oprintf(fp, " Probe Resolution: %u.%u mA\n",
1175 ip.smbip_resolution / 10,
1176 ip.smbip_resolution % 10);
1177 } else {
1178 oprintf(fp, " Probe Resolution: unknown\n");
1181 if (ip.smbip_tolerance != SMB_PROBE_UNKNOWN_VALUE) {
1182 oprintf(fp, " Probe Tolerance: +/-%u mA\n",
1183 ip.smbip_tolerance);
1184 } else {
1185 oprintf(fp, " Probe Tolerance: unknown\n");
1188 if (ip.smbip_accuracy != SMB_PROBE_UNKNOWN_VALUE) {
1189 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n",
1190 ip.smbip_accuracy / 100,
1191 ip.smbip_accuracy % 100);
1192 } else {
1193 oprintf(fp, " Probe Accuracy: unknown\n");
1196 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", ip.smbip_oem);
1198 if (ip.smbip_nominal != SMB_PROBE_UNKNOWN_VALUE) {
1199 oprintf(fp, " Probe Nominal Value: %u mA\n", ip.smbip_nominal);
1200 } else {
1201 oprintf(fp, " Probe Nominal Value: unknown\n");
1206 static void
1207 print_boot(smbios_hdl_t *shp, FILE *fp)
1209 smbios_boot_t b;
1211 (void) smbios_info_boot(shp, &b);
1213 desc_printf(smbios_boot_desc(b.smbt_status),
1214 fp, " Boot Status Code: 0x%x", b.smbt_status);
1216 if (b.smbt_size != 0) {
1217 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size);
1218 print_bytes(b.smbt_data, b.smbt_size, fp);
1222 static void
1223 print_ipmi(smbios_hdl_t *shp, FILE *fp)
1225 smbios_ipmi_t i;
1227 (void) smbios_info_ipmi(shp, &i);
1229 desc_printf(smbios_ipmi_type_desc(i.smbip_type),
1230 fp, " Type: %u", i.smbip_type);
1232 oprintf(fp, " BMC IPMI Version: %u.%u\n",
1233 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor);
1235 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c);
1236 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus);
1237 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr);
1238 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr);
1239 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing);
1241 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY,
1242 smbios_ipmi_flag_name, smbios_ipmi_flag_desc);
1245 static void
1246 print_powersup(smbios_hdl_t *shp, id_t id, FILE *fp)
1248 smbios_powersup_t p;
1250 if (smbios_info_powersup(shp, id, &p) != 0) {
1251 smbios_warn(shp, "failed to read power supply information");
1252 return;
1255 oprintf(fp, " Power Supply Group: %u\n", p.smbps_group);
1256 if (p.smbps_maxout != 0x8000) {
1257 oprintf(fp, " Maximum Output: %llu mW\n", p.smbps_maxout);
1258 } else {
1259 oprintf(fp, " Maximum Output: unknown\n");
1262 flag_printf(fp, "Characteristics", p.smbps_flags,
1263 sizeof (p.smbps_flags) * NBBY, smbios_powersup_flag_name,
1264 smbios_powersup_flag_desc);
1266 desc_printf(smbios_powersup_input_desc(p.smbps_ivrs),
1267 fp, " Input Voltage Range Switching: %u", p.smbps_ivrs);
1268 desc_printf(smbios_powersup_status_desc(p.smbps_status),
1269 fp, " Status: %u", p.smbps_status);
1270 desc_printf(smbios_powersup_type_desc(p.smbps_pstype),
1271 fp, " Type: %u", p.smbps_pstype);
1273 if (p.smbps_vprobe != 0xffff) {
1274 oprintf(fp, " Voltage Probe Handle: %lu\n", p.smbps_vprobe);
1277 if (p.smbps_cooldev != 0xffff) {
1278 oprintf(fp, " Cooling Device Handle: %lu\n", p.smbps_cooldev);
1281 if (p.smbps_iprobe != 0xffff) {
1282 oprintf(fp, " Current Probe Handle: %lu\n", p.smbps_iprobe);
1286 static void
1287 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp)
1289 int i;
1290 smbios_processor_ext_t ep;
1292 if (check_oem(shp) != 0)
1293 return;
1295 (void) smbios_info_extprocessor(shp, id, &ep);
1297 oprintf(fp, " Processor: %u\n", ep.smbpe_processor);
1298 oprintf(fp, " FRU: %u\n", ep.smbpe_fru);
1299 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n);
1301 for (i = 0; i < ep.smbpe_n; i++) {
1302 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i,
1303 ep.smbpe_apicid[i]);
1307 static void
1308 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp)
1310 smbios_port_ext_t epo;
1312 if (check_oem(shp) != 0)
1313 return;
1315 (void) smbios_info_extport(shp, id, &epo);
1317 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis);
1318 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port);
1319 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype);
1320 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl);
1321 oprintf(fp, " PHY: %u\n", epo.smbporte_phy);
1324 static void
1325 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp)
1327 smbios_pciexrc_t pcie;
1329 if (check_oem(shp) != 0)
1330 return;
1332 (void) smbios_info_pciexrc(shp, id, &pcie);
1334 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb);
1335 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf);
1338 static void
1339 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp)
1341 smbios_memarray_ext_t em;
1343 if (check_oem(shp) != 0)
1344 return;
1346 (void) smbios_info_extmemarray(shp, id, &em);
1348 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma);
1349 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp);
1350 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf);
1353 static void
1354 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp)
1356 int i;
1357 smbios_memdevice_ext_t emd;
1359 if (check_oem(shp) != 0)
1360 return;
1362 (void) smbios_info_extmemdevice(shp, id, &emd);
1364 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md);
1365 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch);
1366 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs);
1368 for (i = 0; i < emd.smbmdeve_ncs; i++) {
1369 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]);
1373 static int
1374 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp)
1376 smbios_info_t info;
1377 int hex = opt_x;
1378 const char *s;
1380 if (opt_t != -1 && opt_t != sp->smbstr_type)
1381 return (0); /* skip struct if type doesn't match -t */
1383 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL ||
1384 sp->smbstr_type == SMB_TYPE_MEMMOD))
1385 return (0); /* skip struct if type is obsolete */
1387 if (g_hdr++ == 0 || !opt_s)
1388 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE");
1390 oprintf(fp, "%-5u %-4lu",
1391 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size);
1393 if ((s = smbios_type_name(sp->smbstr_type)) != NULL)
1394 oprintf(fp, " %s (type %u)", s, sp->smbstr_type);
1395 else if (sp->smbstr_type > SMB_TYPE_OEM_LO &&
1396 sp->smbstr_type < SMB_TYPE_OEM_HI)
1397 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO",
1398 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type);
1399 else
1400 oprintf(fp, " %u", sp->smbstr_type);
1402 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL)
1403 oprintf(fp, " (%s)\n", s);
1404 else
1405 oprintf(fp, "\n");
1407 if (opt_s)
1408 return (0); /* only print header line if -s specified */
1410 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) {
1411 oprintf(fp, "\n");
1412 print_common(&info, fp);
1415 switch (sp->smbstr_type) {
1416 case SMB_TYPE_BIOS:
1417 oprintf(fp, "\n");
1418 print_bios(shp, fp);
1419 break;
1420 case SMB_TYPE_SYSTEM:
1421 oprintf(fp, "\n");
1422 print_system(shp, fp);
1423 break;
1424 case SMB_TYPE_BASEBOARD:
1425 oprintf(fp, "\n");
1426 print_bboard(shp, sp->smbstr_id, fp);
1427 break;
1428 case SMB_TYPE_CHASSIS:
1429 oprintf(fp, "\n");
1430 print_chassis(shp, sp->smbstr_id, fp);
1431 break;
1432 case SMB_TYPE_PROCESSOR:
1433 oprintf(fp, "\n");
1434 print_processor(shp, sp->smbstr_id, fp);
1435 break;
1436 case SMB_TYPE_CACHE:
1437 oprintf(fp, "\n");
1438 print_cache(shp, sp->smbstr_id, fp);
1439 break;
1440 case SMB_TYPE_PORT:
1441 oprintf(fp, "\n");
1442 print_port(shp, sp->smbstr_id, fp);
1443 break;
1444 case SMB_TYPE_SLOT:
1445 oprintf(fp, "\n");
1446 print_slot(shp, sp->smbstr_id, fp);
1447 break;
1448 case SMB_TYPE_OBDEVS:
1449 oprintf(fp, "\n");
1450 print_obdevs(shp, sp->smbstr_id, fp);
1451 break;
1452 case SMB_TYPE_OEMSTR:
1453 case SMB_TYPE_SYSCONFSTR:
1454 oprintf(fp, "\n");
1455 print_strtab(shp, sp->smbstr_id, fp);
1456 break;
1457 case SMB_TYPE_LANG:
1458 oprintf(fp, "\n");
1459 print_lang(shp, sp->smbstr_id, fp);
1460 break;
1461 case SMB_TYPE_EVENTLOG:
1462 oprintf(fp, "\n");
1463 print_evlog(shp, sp->smbstr_id, fp);
1464 break;
1465 case SMB_TYPE_MEMARRAY:
1466 oprintf(fp, "\n");
1467 print_memarray(shp, sp->smbstr_id, fp);
1468 break;
1469 case SMB_TYPE_MEMDEVICE:
1470 oprintf(fp, "\n");
1471 print_memdevice(shp, sp->smbstr_id, fp);
1472 break;
1473 case SMB_TYPE_MEMARRAYMAP:
1474 oprintf(fp, "\n");
1475 print_memarrmap(shp, sp->smbstr_id, fp);
1476 break;
1477 case SMB_TYPE_MEMDEVICEMAP:
1478 oprintf(fp, "\n");
1479 print_memdevmap(shp, sp->smbstr_id, fp);
1480 break;
1481 case SMB_TYPE_SECURITY:
1482 oprintf(fp, "\n");
1483 print_hwsec(shp, fp);
1484 break;
1485 case SMB_TYPE_VPROBE:
1486 oprintf(fp, "\n");
1487 print_vprobe(shp, sp->smbstr_id, fp);
1488 break;
1489 case SMB_TYPE_COOLDEV:
1490 oprintf(fp, "\n");
1491 print_cooldev(shp, sp->smbstr_id, fp);
1492 break;
1493 case SMB_TYPE_TPROBE:
1494 oprintf(fp, "\n");
1495 print_tprobe(shp, sp->smbstr_id, fp);
1496 break;
1497 case SMB_TYPE_IPROBE:
1498 oprintf(fp, "\n");
1499 print_iprobe(shp, sp->smbstr_id, fp);
1500 break;
1501 case SMB_TYPE_BOOT:
1502 oprintf(fp, "\n");
1503 print_boot(shp, fp);
1504 break;
1505 case SMB_TYPE_IPMIDEV:
1506 oprintf(fp, "\n");
1507 print_ipmi(shp, fp);
1508 break;
1509 case SMB_TYPE_POWERSUP:
1510 oprintf(fp, "\n");
1511 print_powersup(shp, sp->smbstr_id, fp);
1512 break;
1513 case SMB_TYPE_OBDEVEXT:
1514 oprintf(fp, "\n");
1515 print_obdevs_ext(shp, sp->smbstr_id, fp);
1516 break;
1517 case SUN_OEM_EXT_PROCESSOR:
1518 oprintf(fp, "\n");
1519 print_extprocessor(shp, sp->smbstr_id, fp);
1520 break;
1521 case SUN_OEM_EXT_PORT:
1522 oprintf(fp, "\n");
1523 print_extport(shp, sp->smbstr_id, fp);
1524 break;
1525 case SUN_OEM_PCIEXRC:
1526 oprintf(fp, "\n");
1527 print_pciexrc(shp, sp->smbstr_id, fp);
1528 break;
1529 case SUN_OEM_EXT_MEMARRAY:
1530 oprintf(fp, "\n");
1531 print_extmemarray(shp, sp->smbstr_id, fp);
1532 break;
1533 case SUN_OEM_EXT_MEMDEVICE:
1534 oprintf(fp, "\n");
1535 print_extmemdevice(shp, sp->smbstr_id, fp);
1536 break;
1537 default:
1538 hex++;
1541 if (hex)
1542 print_bytes(sp->smbstr_data, sp->smbstr_size, fp);
1543 else
1544 oprintf(fp, "\n");
1546 return (0);
1549 static uint16_t
1550 getu16(const char *name, const char *s)
1552 u_longlong_t val;
1553 char *p;
1555 errno = 0;
1556 val = strtoull(s, &p, 0);
1558 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) {
1559 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
1560 g_pname, name, s);
1561 exit(SMBIOS_USAGE);
1564 return ((uint16_t)val);
1567 static uint16_t
1568 getstype(const char *name, const char *s)
1570 const char *ts;
1571 uint16_t t;
1573 for (t = 0; t < SMB_TYPE_OEM_LO; t++) {
1574 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0)
1575 return (t);
1578 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n",
1579 g_pname, name, s);
1581 exit(SMBIOS_USAGE);
1582 /*NOTREACHED*/
1585 static int
1586 usage(FILE *fp)
1588 (void) fprintf(fp, "Usage: %s "
1589 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname);
1591 (void) fprintf(fp,
1592 "\t-B disable header validation for broken BIOSes\n"
1593 "\t-e display SMBIOS entry point information\n"
1594 "\t-i display only the specified structure\n"
1595 "\t-O display obsolete structure types\n"
1596 "\t-s display only a summary of structure identifiers and types\n"
1597 "\t-t display only the specified structure type\n"
1598 "\t-w write the raw data to the specified file\n"
1599 "\t-x display raw data for structures\n");
1601 return (SMBIOS_USAGE);
1605 main(int argc, char *argv[])
1607 const char *ifile = NULL;
1608 const char *ofile = NULL;
1609 int oflags = 0;
1611 smbios_hdl_t *shp;
1612 smbios_struct_t s;
1613 int err, fd, c;
1614 char *p;
1616 if ((p = strrchr(argv[0], '/')) == NULL)
1617 g_pname = argv[0];
1618 else
1619 g_pname = p + 1;
1621 while (optind < argc) {
1622 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) {
1623 switch (c) {
1624 case 'B':
1625 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS;
1626 break;
1627 case 'e':
1628 opt_e++;
1629 break;
1630 case 'i':
1631 opt_i = getu16("struct ID", optarg);
1632 break;
1633 case 'O':
1634 opt_O++;
1635 break;
1636 case 's':
1637 opt_s++;
1638 break;
1639 case 't':
1640 if (isdigit(optarg[0]))
1641 opt_t = getu16("struct type", optarg);
1642 else
1643 opt_t = getstype("struct type", optarg);
1644 break;
1645 case 'w':
1646 ofile = optarg;
1647 break;
1648 case 'x':
1649 opt_x++;
1650 break;
1651 case 'Z':
1652 oflags |= SMB_O_ZIDS; /* undocumented */
1653 break;
1654 default:
1655 return (usage(stderr));
1659 if (optind < argc) {
1660 if (ifile != NULL) {
1661 (void) fprintf(stderr, "%s: illegal "
1662 "argument -- %s\n", g_pname, argv[optind]);
1663 return (SMBIOS_USAGE);
1665 ifile = argv[optind++];
1669 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) {
1670 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n",
1671 g_pname, smbios_errmsg(err));
1672 return (SMBIOS_ERROR);
1675 if (opt_i == -1 && opt_t == -1 && opt_e == 0 &&
1676 smbios_truncated(shp))
1677 (void) fprintf(stderr, "%s: SMBIOS table is truncated\n",
1678 g_pname);
1680 if (ofile != NULL) {
1681 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
1682 (void) fprintf(stderr, "%s: failed to open %s: %s\n",
1683 g_pname, ofile, strerror(errno));
1684 err = SMBIOS_ERROR;
1685 } else if (smbios_write(shp, fd) != 0) {
1686 (void) fprintf(stderr, "%s: failed to write %s: %s\n",
1687 g_pname, ofile, smbios_errmsg(smbios_errno(shp)));
1688 err = SMBIOS_ERROR;
1690 smbios_close(shp);
1691 return (err);
1694 if (opt_e) {
1695 print_smbios(shp, stdout);
1696 smbios_close(shp);
1697 return (SMBIOS_SUCCESS);
1700 if (opt_O && (opt_i != -1 || opt_t != -1))
1701 opt_O++; /* -i or -t imply displaying obsolete records */
1703 if (opt_i != -1)
1704 err = smbios_lookup_id(shp, opt_i, &s);
1705 else
1706 err = smbios_iter(shp, print_struct, stdout);
1708 if (err != 0) {
1709 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n",
1710 g_pname, smbios_errmsg(smbios_errno(shp)));
1711 smbios_close(shp);
1712 return (SMBIOS_ERROR);
1715 if (opt_i != -1)
1716 (void) print_struct(shp, &s, stdout);
1718 smbios_close(shp);
1719 return (SMBIOS_SUCCESS);