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]
23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #include <sys/sysmacros.h>
29 #include <sys/param.h>
43 #define SMBIOS_SUCCESS 0
44 #define SMBIOS_ERROR 1
45 #define SMBIOS_USAGE 2
47 static const char *g_pname
;
51 static int opt_i
= -1;
54 static int opt_t
= -1;
59 oprintf(FILE *fp
, const char *format
, ...)
64 (void) vfprintf(fp
, format
, ap
);
70 desc_printf(const char *d
, FILE *fp
, const char *format
, ...)
75 (void) vfprintf(fp
, format
, ap
);
79 (void) fprintf(fp
, " (%s)\n", d
);
81 (void) fprintf(fp
, "\n");
85 flag_printf(FILE *fp
, const char *s
, uint_t flags
, size_t bits
,
86 const char *(*flag_name
)(uint_t
), const char *(*flag_desc
)(uint_t
))
90 oprintf(fp
, " %s: 0x%x\n", s
, flags
);
92 for (i
= 0; i
< bits
; i
++) {
99 if ((n
= flag_name(f
)) != NULL
)
100 desc_printf(flag_desc(f
), fp
, "\t%s", n
);
102 desc_printf(flag_desc(f
), fp
, "\t0x%x", f
);
107 flag64_printf(FILE *fp
, const char *s
, uint64_t flags
, size_t bits
,
108 const char *(*flag_name
)(uint64_t), const char *(*flag_desc
)(uint64_t))
112 oprintf(fp
, " %s: 0x%llx\n", s
, (u_longlong_t
)flags
);
114 for (i
= 0; i
< bits
; i
++) {
115 u_longlong_t f
= 1ULL << i
;
121 if ((n
= flag_name(f
)) != NULL
)
122 desc_printf(flag_desc(f
), fp
, "\t%s", n
);
124 desc_printf(flag_desc(f
), fp
, "\t0x%llx", f
);
129 id_printf(FILE *fp
, const char *s
, id_t id
)
133 oprintf(fp
, "%sNone\n", s
);
136 oprintf(fp
, "%sNot Supported\n", s
);
139 oprintf(fp
, "%s%u\n", s
, (uint_t
)id
);
144 check_oem(smbios_hdl_t
*shp
)
151 const char **oem_str
;
153 rv
= smbios_lookup_type(shp
, SMB_TYPE_OEMSTR
, &s
);
158 oem_id
= s
.smbstr_id
;
160 cnt
= smbios_info_strtab(shp
, oem_id
, 0, NULL
);
162 oem_str
= alloca(sizeof (char *) * cnt
);
163 (void) smbios_info_strtab(shp
, oem_id
, cnt
, oem_str
);
165 for (i
= 0; i
< cnt
; i
++) {
166 if (strncmp(oem_str
[i
], SMB_PRMS1
,
167 strlen(SMB_PRMS1
) + 1) == 0) {
177 print_smbios(smbios_hdl_t
*shp
, FILE *fp
)
182 smbios_info_smbios(shp
, &ep
);
184 oprintf(fp
, "Entry Point Anchor Tag: %*.*s\n",
185 (int)sizeof (ep
.smbe_eanchor
), (int)sizeof (ep
.smbe_eanchor
),
188 oprintf(fp
, "Entry Point Checksum: 0x%x\n", ep
.smbe_ecksum
);
189 oprintf(fp
, "Entry Point Length: %u\n", ep
.smbe_elen
);
190 oprintf(fp
, "Entry Point Version: %u.%u\n",
191 ep
.smbe_major
, ep
.smbe_minor
);
192 oprintf(fp
, "Max Structure Size: %u\n", ep
.smbe_maxssize
);
193 oprintf(fp
, "Entry Point Revision: 0x%x\n", ep
.smbe_revision
);
195 oprintf(fp
, "Entry Point Revision Data:");
196 for (i
= 0; i
< sizeof (ep
.smbe_format
); i
++)
197 oprintf(fp
, " 0x%02x", ep
.smbe_format
[i
]);
200 oprintf(fp
, "Intermediate Anchor Tag: %*.*s\n",
201 (int)sizeof (ep
.smbe_ianchor
), (int)sizeof (ep
.smbe_ianchor
),
204 oprintf(fp
, "Intermediate Checksum: 0x%x\n", ep
.smbe_icksum
);
205 oprintf(fp
, "Structure Table Length: %u\n", ep
.smbe_stlen
);
206 oprintf(fp
, "Structure Table Address: 0x%x\n", ep
.smbe_staddr
);
207 oprintf(fp
, "Structure Table Entries: %u\n", ep
.smbe_stnum
);
208 oprintf(fp
, "DMI BCD Revision: 0x%x\n", ep
.smbe_bcdrev
);
212 print_common(const smbios_info_t
*ip
, FILE *fp
)
214 if (ip
->smbi_manufacturer
[0] != '\0')
215 oprintf(fp
, " Manufacturer: %s\n", ip
->smbi_manufacturer
);
216 if (ip
->smbi_product
[0] != '\0')
217 oprintf(fp
, " Product: %s\n", ip
->smbi_product
);
218 if (ip
->smbi_version
[0] != '\0')
219 oprintf(fp
, " Version: %s\n", ip
->smbi_version
);
220 if (ip
->smbi_serial
[0] != '\0')
221 oprintf(fp
, " Serial Number: %s\n", ip
->smbi_serial
);
222 if (ip
->smbi_asset
[0] != '\0')
223 oprintf(fp
, " Asset Tag: %s\n", ip
->smbi_asset
);
224 if (ip
->smbi_location
[0] != '\0')
225 oprintf(fp
, " Location Tag: %s\n", ip
->smbi_location
);
226 if (ip
->smbi_part
[0] != '\0')
227 oprintf(fp
, " Part Number: %s\n", ip
->smbi_part
);
231 print_bios(smbios_hdl_t
*shp
, FILE *fp
)
235 (void) smbios_info_bios(shp
, &b
);
237 oprintf(fp
, " Vendor: %s\n", b
.smbb_vendor
);
238 oprintf(fp
, " Version String: %s\n", b
.smbb_version
);
239 oprintf(fp
, " Release Date: %s\n", b
.smbb_reldate
);
240 oprintf(fp
, " Address Segment: 0x%x\n", b
.smbb_segment
);
241 oprintf(fp
, " ROM Size: %u bytes\n", b
.smbb_romsize
);
242 oprintf(fp
, " Image Size: %u bytes\n", b
.smbb_runsize
);
244 flag64_printf(fp
, "Characteristics",
245 b
.smbb_cflags
, sizeof (b
.smbb_cflags
) * NBBY
,
246 smbios_bios_flag_name
, smbios_bios_flag_desc
);
248 if (b
.smbb_nxcflags
> SMB_BIOSXB_1
) {
249 flag_printf(fp
, "Characteristics Extension Byte 1",
250 b
.smbb_xcflags
[SMB_BIOSXB_1
],
251 sizeof (b
.smbb_xcflags
[SMB_BIOSXB_1
]) * NBBY
,
252 smbios_bios_xb1_name
, smbios_bios_xb1_desc
);
255 if (b
.smbb_nxcflags
> SMB_BIOSXB_2
) {
256 flag_printf(fp
, "Characteristics Extension Byte 2",
257 b
.smbb_xcflags
[SMB_BIOSXB_2
],
258 sizeof (b
.smbb_xcflags
[SMB_BIOSXB_2
]) * NBBY
,
259 smbios_bios_xb2_name
, smbios_bios_xb2_desc
);
262 if (b
.smbb_nxcflags
> SMB_BIOSXB_BIOS_MIN
) {
263 oprintf(fp
, " Version Number: %u.%u\n",
264 b
.smbb_biosv
.smbv_major
, b
.smbb_biosv
.smbv_minor
);
267 if (b
.smbb_nxcflags
> SMB_BIOSXB_ECFW_MIN
) {
268 oprintf(fp
, " Embedded Ctlr Firmware Version Number: %u.%u\n",
269 b
.smbb_ecfwv
.smbv_major
, b
.smbb_ecfwv
.smbv_minor
);
274 print_system(smbios_hdl_t
*shp
, FILE *fp
)
279 (void) smbios_info_system(shp
, &s
);
281 oprintf(fp
, " UUID: ");
282 for (i
= 0; i
< s
.smbs_uuidlen
; i
++) {
283 oprintf(fp
, "%02x", s
.smbs_uuid
[i
]);
284 if (i
== 3 || i
== 5 || i
== 7 || i
== 9)
289 desc_printf(smbios_system_wakeup_desc(s
.smbs_wakeup
),
290 fp
, " Wake-Up Event: 0x%x", s
.smbs_wakeup
);
292 oprintf(fp
, " SKU Number: %s\n", s
.smbs_sku
);
293 oprintf(fp
, " Family: %s\n", s
.smbs_family
);
297 print_bboard(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
302 (void) smbios_info_bboard(shp
, id
, &b
);
304 oprintf(fp
, " Chassis: %u\n", (uint_t
)b
.smbb_chassis
);
306 flag_printf(fp
, "Flags", b
.smbb_flags
, sizeof (b
.smbb_flags
) * NBBY
,
307 smbios_bboard_flag_name
, smbios_bboard_flag_desc
);
309 desc_printf(smbios_bboard_type_desc(b
.smbb_type
),
310 fp
, " Board Type: 0x%x", b
.smbb_type
);
312 chdl_cnt
= b
.smbb_contn
;
318 chdl
= alloca(chdl_cnt
* sizeof (id_t
));
319 cnt
= smbios_info_contains(shp
, id
, chdl_cnt
, chdl
);
320 if (cnt
> SMB_CONT_MAX
)
322 n
= MIN(chdl_cnt
, cnt
);
325 for (i
= 0; i
< n
; i
++) {
326 hdl
= (uint16_t)chdl
[i
];
327 oprintf(fp
, " Contained Handle: %u\n", hdl
);
333 print_chassis(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
338 (void) smbios_info_chassis(shp
, id
, &c
);
340 oprintf(fp
, " OEM Data: 0x%x\n", c
.smbc_oemdata
);
341 oprintf(fp
, " SKU number: %s\n",
342 c
.smbc_sku
== NULL
? "<unknown>" : c
.smbc_sku
);
343 oprintf(fp
, " Lock Present: %s\n", c
.smbc_lock
? "Y" : "N");
345 desc_printf(smbios_chassis_type_desc(c
.smbc_type
),
346 fp
, " Chassis Type: 0x%x", c
.smbc_type
);
348 desc_printf(smbios_chassis_state_desc(c
.smbc_bustate
),
349 fp
, " Boot-Up State: 0x%x", c
.smbc_bustate
);
351 desc_printf(smbios_chassis_state_desc(c
.smbc_psstate
),
352 fp
, " Power Supply State: 0x%x", c
.smbc_psstate
);
354 desc_printf(smbios_chassis_state_desc(c
.smbc_thstate
),
355 fp
, " Thermal State: 0x%x", c
.smbc_thstate
);
357 oprintf(fp
, " Chassis Height: %uu\n", c
.smbc_uheight
);
358 oprintf(fp
, " Power Cords: %u\n", c
.smbc_cords
);
360 elem_cnt
= c
.smbc_elems
;
361 oprintf(fp
, " Element Records: %u\n", elem_cnt
);
368 elems
= alloca(c
.smbc_elems
* sizeof (id_t
));
369 cnt
= smbios_info_contains(shp
, id
, elem_cnt
, elems
);
370 if (cnt
> SMB_CONT_MAX
)
372 n
= MIN(elem_cnt
, cnt
);
375 for (i
= 0; i
< n
; i
++) {
376 type
= (uint8_t)elems
[i
];
378 /* SMBIOS structrure Type */
379 desc_printf(smbios_type_name(type
& 0x7f), fp
,
380 " Contained SMBIOS structure Type: %u",
383 /* SMBIOS Base Board Type */
384 desc_printf(smbios_bboard_type_desc(type
), fp
,
385 " Contained SMBIOS Base Board Type: 0x%x",
393 print_processor(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
395 smbios_processor_t p
;
398 (void) smbios_info_processor(shp
, id
, &p
);
399 status
= SMB_PRSTATUS_STATUS(p
.smbp_status
);
401 desc_printf(smbios_processor_family_desc(p
.smbp_family
),
402 fp
, " Family: %u", p
.smbp_family
);
404 if (p
.smbp_family2
!= 0)
405 desc_printf(smbios_processor_family_desc(p
.smbp_family2
),
406 fp
, " Family Ext: %u", p
.smbp_family2
);
408 oprintf(fp
, " CPUID: 0x%llx\n", (u_longlong_t
)p
.smbp_cpuid
);
410 desc_printf(smbios_processor_type_desc(p
.smbp_type
),
411 fp
, " Type: %u", p
.smbp_type
);
413 desc_printf(smbios_processor_upgrade_desc(p
.smbp_upgrade
),
414 fp
, " Socket Upgrade: %u", p
.smbp_upgrade
);
416 oprintf(fp
, " Socket Status: %s\n",
417 SMB_PRSTATUS_PRESENT(p
.smbp_status
) ?
418 "Populated" : "Not Populated");
420 desc_printf(smbios_processor_status_desc(status
),
421 fp
, " Processor Status: %u", status
);
423 if (SMB_PRV_LEGACY(p
.smbp_voltage
)) {
424 oprintf(fp
, " Supported Voltages:");
425 switch (p
.smbp_voltage
) {
427 oprintf(fp
, " 5.0V");
430 oprintf(fp
, " 3.3V");
433 oprintf(fp
, " 2.9V");
438 oprintf(fp
, " Supported Voltages: %.1fV\n",
439 (float)SMB_PRV_VOLTAGE(p
.smbp_voltage
) / 10);
442 if (p
.smbp_corecount
!= 0)
443 oprintf(fp
, " Core Count: %u\n", p
.smbp_corecount
);
445 oprintf(fp
, " Core Count: Unknown\n");
447 if (p
.smbp_coresenabled
!= 0)
448 oprintf(fp
, " Cores Enabled: %u\n", p
.smbp_coresenabled
);
450 oprintf(fp
, " Cores Enabled: Unknown\n");
452 if (p
.smbp_threadcount
!= 0)
453 oprintf(fp
, " Thread Count: %u\n", p
.smbp_threadcount
);
455 oprintf(fp
, " Thread Count: Unknown\n");
458 flag_printf(fp
, "Processor Characteristics",
459 p
.smbp_cflags
, sizeof (p
.smbp_cflags
) * NBBY
,
460 smbios_processor_core_flag_name
,
461 smbios_processor_core_flag_desc
);
464 if (p
.smbp_clkspeed
!= 0)
465 oprintf(fp
, " External Clock Speed: %uMHz\n", p
.smbp_clkspeed
);
467 oprintf(fp
, " External Clock Speed: Unknown\n");
469 if (p
.smbp_maxspeed
!= 0)
470 oprintf(fp
, " Maximum Speed: %uMHz\n", p
.smbp_maxspeed
);
472 oprintf(fp
, " Maximum Speed: Unknown\n");
474 if (p
.smbp_curspeed
!= 0)
475 oprintf(fp
, " Current Speed: %uMHz\n", p
.smbp_curspeed
);
477 oprintf(fp
, " Current Speed: Unknown\n");
479 id_printf(fp
, " L1 Cache: ", p
.smbp_l1cache
);
480 id_printf(fp
, " L2 Cache: ", p
.smbp_l2cache
);
481 id_printf(fp
, " L3 Cache: ", p
.smbp_l3cache
);
485 print_cache(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
489 (void) smbios_info_cache(shp
, id
, &c
);
491 oprintf(fp
, " Level: %u\n", c
.smba_level
);
492 oprintf(fp
, " Maximum Installed Size: %u bytes\n", c
.smba_maxsize
);
494 if (c
.smba_size
!= 0)
495 oprintf(fp
, " Installed Size: %u bytes\n", c
.smba_size
);
497 oprintf(fp
, " Installed Size: Not Installed\n");
499 if (c
.smba_speed
!= 0)
500 oprintf(fp
, " Speed: %uns\n", c
.smba_speed
);
502 oprintf(fp
, " Speed: Unknown\n");
504 flag_printf(fp
, "Supported SRAM Types",
505 c
.smba_stype
, sizeof (c
.smba_stype
) * NBBY
,
506 smbios_cache_ctype_name
, smbios_cache_ctype_desc
);
508 desc_printf(smbios_cache_ctype_desc(c
.smba_ctype
),
509 fp
, " Current SRAM Type: 0x%x", c
.smba_ctype
);
511 desc_printf(smbios_cache_ecc_desc(c
.smba_etype
),
512 fp
, " Error Correction Type: %u", c
.smba_etype
);
514 desc_printf(smbios_cache_logical_desc(c
.smba_ltype
),
515 fp
, " Logical Cache Type: %u", c
.smba_ltype
);
517 desc_printf(smbios_cache_assoc_desc(c
.smba_assoc
),
518 fp
, " Associativity: %u", c
.smba_assoc
);
520 desc_printf(smbios_cache_mode_desc(c
.smba_mode
),
521 fp
, " Mode: %u", c
.smba_mode
);
523 desc_printf(smbios_cache_loc_desc(c
.smba_location
),
524 fp
, " Location: %u", c
.smba_location
);
526 flag_printf(fp
, "Flags", c
.smba_flags
, sizeof (c
.smba_flags
) * NBBY
,
527 smbios_cache_flag_name
, smbios_cache_flag_desc
);
531 print_port(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
535 (void) smbios_info_port(shp
, id
, &p
);
537 oprintf(fp
, " Internal Reference Designator: %s\n", p
.smbo_iref
);
538 oprintf(fp
, " External Reference Designator: %s\n", p
.smbo_eref
);
540 desc_printf(smbios_port_conn_desc(p
.smbo_itype
),
541 fp
, " Internal Connector Type: %u", p
.smbo_itype
);
543 desc_printf(smbios_port_conn_desc(p
.smbo_etype
),
544 fp
, " External Connector Type: %u", p
.smbo_etype
);
546 desc_printf(smbios_port_type_desc(p
.smbo_ptype
),
547 fp
, " Port Type: %u", p
.smbo_ptype
);
551 print_slot(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
556 (void) smbios_info_slot(shp
, id
, &s
);
557 (void) smbios_info_smbios(shp
, &e
);
559 oprintf(fp
, " Reference Designator: %s\n", s
.smbl_name
);
560 oprintf(fp
, " Slot ID: 0x%x\n", s
.smbl_id
);
562 desc_printf(smbios_slot_type_desc(s
.smbl_type
),
563 fp
, " Type: 0x%x", s
.smbl_type
);
565 desc_printf(smbios_slot_width_desc(s
.smbl_width
),
566 fp
, " Width: 0x%x", s
.smbl_width
);
568 desc_printf(smbios_slot_usage_desc(s
.smbl_usage
),
569 fp
, " Usage: 0x%x", s
.smbl_usage
);
571 desc_printf(smbios_slot_length_desc(s
.smbl_length
),
572 fp
, " Length: 0x%x", s
.smbl_length
);
574 flag_printf(fp
, "Slot Characteristics 1",
575 s
.smbl_ch1
, sizeof (s
.smbl_ch1
) * NBBY
,
576 smbios_slot_ch1_name
, smbios_slot_ch1_desc
);
578 flag_printf(fp
, "Slot Characteristics 2",
579 s
.smbl_ch2
, sizeof (s
.smbl_ch2
) * NBBY
,
580 smbios_slot_ch2_name
, smbios_slot_ch2_desc
);
582 if (check_oem(shp
) != 0 && (e
.smbe_major
< 2 || e
.smbe_minor
< 6))
585 oprintf(fp
, " Segment Group: %u\n", s
.smbl_sg
);
586 oprintf(fp
, " Bus Number: %u\n", s
.smbl_bus
);
587 oprintf(fp
, " Device/Function Number: %u\n", s
.smbl_df
);
591 print_obdevs_ext(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
593 smbios_obdev_ext_t oe
;
595 (void) smbios_info_obdevs_ext(shp
, id
, &oe
);
597 oprintf(fp
, " Reference Designator: %s\n", oe
.smboe_name
);
598 oprintf(fp
, " Device Type: %u\n", oe
.smboe_dtype
);
599 oprintf(fp
, " Device Type Instance: %u\n", oe
.smboe_dti
);
600 oprintf(fp
, " Segment Group Number: %u\n", oe
.smboe_sg
);
601 oprintf(fp
, " Bus Number: %u\n", oe
.smboe_bus
);
602 oprintf(fp
, " Device/Function Number: %u\n", oe
.smboe_df
);
606 print_obdevs(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
608 smbios_obdev_t
*argv
;
611 if ((argc
= smbios_info_obdevs(shp
, id
, 0, NULL
)) > 0) {
612 argv
= alloca(sizeof (smbios_obdev_t
) * argc
);
613 (void) smbios_info_obdevs(shp
, id
, argc
, argv
);
614 for (i
= 0; i
< argc
; i
++)
615 oprintf(fp
, " %s\n", argv
[i
].smbd_name
);
620 print_strtab(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
625 if ((argc
= smbios_info_strtab(shp
, id
, 0, NULL
)) > 0) {
626 argv
= alloca(sizeof (char *) * argc
);
627 (void) smbios_info_strtab(shp
, id
, argc
, argv
);
628 for (i
= 0; i
< argc
; i
++)
629 oprintf(fp
, " %s\n", argv
[i
]);
634 print_lang(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
638 (void) smbios_info_lang(shp
, &l
);
640 oprintf(fp
, " Current Language: %s\n", l
.smbla_cur
);
641 oprintf(fp
, " Language String Format: %u\n", l
.smbla_fmt
);
642 oprintf(fp
, " Number of Installed Languages: %u\n", l
.smbla_num
);
643 oprintf(fp
, " Installed Languages:\n");
645 print_strtab(shp
, id
, fp
);
650 print_evlog(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
655 (void) smbios_info_eventlog(shp
, &ev
);
657 oprintf(fp
, " Log Area Size: %lu bytes\n", (ulong_t
)ev
.smbev_size
);
658 oprintf(fp
, " Header Offset: %lu\n", (ulong_t
)ev
.smbev_hdr
);
659 oprintf(fp
, " Data Offset: %lu\n", (ulong_t
)ev
.smbev_data
);
661 desc_printf(smbios_evlog_method_desc(ev
.smbev_method
),
662 fp
, " Data Access Method: %u", ev
.smbev_method
);
664 flag_printf(fp
, "Log Flags",
665 ev
.smbev_flags
, sizeof (ev
.smbev_flags
) * NBBY
,
666 smbios_evlog_flag_name
, smbios_evlog_flag_desc
);
668 desc_printf(smbios_evlog_format_desc(ev
.smbev_format
),
669 fp
, " Log Header Format: %u", ev
.smbev_format
);
671 oprintf(fp
, " Update Token: 0x%x\n", ev
.smbev_token
);
672 oprintf(fp
, " Data Access Address: ");
674 switch (ev
.smbev_method
) {
675 case SMB_EVM_1x1i_1x1d
:
676 case SMB_EVM_2x1i_1x1d
:
677 case SMB_EVM_1x2i_1x1d
:
678 oprintf(fp
, "Index Address 0x%x, Data Address 0x%x\n",
679 ev
.smbev_addr
.eva_io
.evi_iaddr
,
680 ev
.smbev_addr
.eva_io
.evi_daddr
);
683 oprintf(fp
, "0x%x\n", ev
.smbev_addr
.eva_gpnv
);
686 oprintf(fp
, "0x%x\n", ev
.smbev_addr
.eva_addr
);
689 oprintf(fp
, " Type Descriptors:\n");
691 for (i
= 0; i
< ev
.smbev_typec
; i
++) {
692 oprintf(fp
, " %u: Log Type 0x%x, Data Type 0x%x\n", i
,
693 ev
.smbev_typev
[i
].smbevt_ltype
,
694 ev
.smbev_typev
[i
].smbevt_dtype
);
699 print_bytes(const uint8_t *data
, size_t size
, FILE *fp
)
701 size_t row
, rows
= P2ROUNDUP(size
, 16) / 16;
707 oprintf(fp
, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f "
708 "0123456789abcdef\n");
710 for (row
= 0; row
< rows
; row
++) {
711 oprintf(fp
, " %#4lx: ", (ulong_t
)row
* 16);
712 cols
= MIN(size
- row
* 16, 16);
714 for (col
= 0; col
< cols
; col
++) {
718 oprintf(fp
, "%02x", x
);
719 buf
[col
] = x
<= ' ' || x
> '~' ? '.' : x
;
722 for (; col
< 16; col
++) {
730 oprintf(fp
, " %s\n", buf
);
737 print_memarray(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
739 smbios_memarray_t ma
;
741 (void) smbios_info_memarray(shp
, id
, &ma
);
743 desc_printf(smbios_memarray_loc_desc(ma
.smbma_location
),
744 fp
, " Location: %u", ma
.smbma_location
);
746 desc_printf(smbios_memarray_use_desc(ma
.smbma_use
),
747 fp
, " Use: %u", ma
.smbma_use
);
749 desc_printf(smbios_memarray_ecc_desc(ma
.smbma_ecc
),
750 fp
, " ECC: %u", ma
.smbma_ecc
);
752 oprintf(fp
, " Number of Slots/Sockets: %u\n", ma
.smbma_ndevs
);
753 id_printf(fp
, " Memory Error Data: ", ma
.smbma_err
);
754 oprintf(fp
, " Max Capacity: %llu bytes\n",
755 (u_longlong_t
)ma
.smbma_size
);
759 print_memdevice(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
761 smbios_memdevice_t md
;
763 (void) smbios_info_memdevice(shp
, id
, &md
);
765 id_printf(fp
, " Physical Memory Array: ", md
.smbmd_array
);
766 id_printf(fp
, " Memory Error Data: ", md
.smbmd_error
);
768 if (md
.smbmd_twidth
!= -1u)
769 oprintf(fp
, " Total Width: %u bits\n", md
.smbmd_twidth
);
771 oprintf(fp
, " Total Width: Unknown\n");
773 if (md
.smbmd_dwidth
!= -1u)
774 oprintf(fp
, " Data Width: %u bits\n", md
.smbmd_dwidth
);
776 oprintf(fp
, " Data Width: Unknown\n");
778 switch (md
.smbmd_size
) {
780 oprintf(fp
, " Size: Unknown\n");
783 oprintf(fp
, " Size: Not Populated\n");
786 oprintf(fp
, " Size: %llu bytes\n",
787 (u_longlong_t
)md
.smbmd_size
);
790 desc_printf(smbios_memdevice_form_desc(md
.smbmd_form
),
791 fp
, " Form Factor: %u", md
.smbmd_form
);
793 if (md
.smbmd_set
== 0)
794 oprintf(fp
, " Set: None\n");
795 else if (md
.smbmd_set
== (uint8_t)-1u)
796 oprintf(fp
, " Set: Unknown\n");
798 oprintf(fp
, " Set: %u\n", md
.smbmd_set
);
800 if (md
.smbmd_rank
!= 0) {
801 desc_printf(smbios_memdevice_rank_desc(md
.smbmd_rank
),
802 fp
, " Rank: %u", md
.smbmd_rank
);
804 oprintf(fp
, " Rank: Unknown\n");
807 desc_printf(smbios_memdevice_type_desc(md
.smbmd_type
),
808 fp
, " Memory Type: %u", md
.smbmd_type
);
810 flag_printf(fp
, "Flags", md
.smbmd_flags
, sizeof (md
.smbmd_flags
) * NBBY
,
811 smbios_memdevice_flag_name
, smbios_memdevice_flag_desc
);
813 if (md
.smbmd_speed
!= 0)
814 oprintf(fp
, " Speed: %u MHz\n", md
.smbmd_speed
);
816 oprintf(fp
, " Speed: Unknown\n");
818 if (md
.smbmd_clkspeed
!= 0)
819 oprintf(fp
, " Configured Speed: %u MHz\n", md
.smbmd_clkspeed
);
821 oprintf(fp
, " Configured Speed: Unknown\n");
823 oprintf(fp
, " Device Locator: %s\n", md
.smbmd_dloc
);
824 oprintf(fp
, " Bank Locator: %s\n", md
.smbmd_bloc
);
826 if (md
.smbmd_minvolt
!= 0) {
827 oprintf(fp
, " Minimum Voltage: %.2fV\n",
828 md
.smbmd_minvolt
/ 1000.0);
830 oprintf(fp
, " Minimum Voltage: Unknown\n");
833 if (md
.smbmd_maxvolt
!= 0) {
834 oprintf(fp
, " Maximum Voltage: %.2fV\n",
835 md
.smbmd_maxvolt
/ 1000.0);
837 oprintf(fp
, " Maximum Voltage: Unknown\n");
840 if (md
.smbmd_confvolt
!= 0) {
841 oprintf(fp
, " Configured Voltage: %.2fV\n",
842 md
.smbmd_confvolt
/ 1000.0);
844 oprintf(fp
, " Configured Voltage: Unknown\n");
849 print_memarrmap(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
851 smbios_memarrmap_t ma
;
853 (void) smbios_info_memarrmap(shp
, id
, &ma
);
855 id_printf(fp
, " Physical Memory Array: ", ma
.smbmam_array
);
856 oprintf(fp
, " Devices per Row: %u\n", ma
.smbmam_width
);
858 oprintf(fp
, " Physical Address: 0x%llx\n Size: %llu bytes\n",
859 (u_longlong_t
)ma
.smbmam_addr
, (u_longlong_t
)ma
.smbmam_size
);
863 print_memdevmap(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
865 smbios_memdevmap_t md
;
867 (void) smbios_info_memdevmap(shp
, id
, &md
);
869 id_printf(fp
, " Memory Device: ", md
.smbmdm_device
);
870 id_printf(fp
, " Memory Array Mapped Address: ", md
.smbmdm_arrmap
);
872 oprintf(fp
, " Physical Address: 0x%llx\n Size: %llu bytes\n",
873 (u_longlong_t
)md
.smbmdm_addr
, (u_longlong_t
)md
.smbmdm_size
);
875 oprintf(fp
, " Partition Row Position: %u\n", md
.smbmdm_rpos
);
876 oprintf(fp
, " Interleave Position: %u\n", md
.smbmdm_ipos
);
877 oprintf(fp
, " Interleave Data Depth: %u\n", md
.smbmdm_idepth
);
881 print_hwsec(smbios_hdl_t
*shp
, FILE *fp
)
885 (void) smbios_info_hwsec(shp
, &h
);
887 desc_printf(smbios_hwsec_desc(h
.smbh_pwr_ps
),
888 fp
, " Power-On Password Status: %u", h
.smbh_pwr_ps
);
889 desc_printf(smbios_hwsec_desc(h
.smbh_kbd_ps
),
890 fp
, " Keyboard Password Status: %u", h
.smbh_kbd_ps
);
891 desc_printf(smbios_hwsec_desc(h
.smbh_adm_ps
),
892 fp
, " Administrator Password Status: %u", h
.smbh_adm_ps
);
893 desc_printf(smbios_hwsec_desc(h
.smbh_pan_ps
),
894 fp
, " Front Panel Reset Status: %u", h
.smbh_pan_ps
);
898 print_boot(smbios_hdl_t
*shp
, FILE *fp
)
902 (void) smbios_info_boot(shp
, &b
);
904 desc_printf(smbios_boot_desc(b
.smbt_status
),
905 fp
, " Boot Status Code: 0x%x", b
.smbt_status
);
907 if (b
.smbt_size
!= 0) {
908 oprintf(fp
, " Boot Data (%lu bytes):\n", (ulong_t
)b
.smbt_size
);
909 print_bytes(b
.smbt_data
, b
.smbt_size
, fp
);
914 print_ipmi(smbios_hdl_t
*shp
, FILE *fp
)
918 (void) smbios_info_ipmi(shp
, &i
);
920 desc_printf(smbios_ipmi_type_desc(i
.smbip_type
),
921 fp
, " Type: %u", i
.smbip_type
);
923 oprintf(fp
, " BMC IPMI Version: %u.%u\n",
924 i
.smbip_vers
.smbv_major
, i
.smbip_vers
.smbv_minor
);
926 oprintf(fp
, " i2c Bus Slave Address: 0x%x\n", i
.smbip_i2c
);
927 oprintf(fp
, " NV Storage Device Bus ID: 0x%x\n", i
.smbip_bus
);
928 oprintf(fp
, " BMC Base Address: 0x%llx\n", (u_longlong_t
)i
.smbip_addr
);
929 oprintf(fp
, " Interrupt Number: %u\n", i
.smbip_intr
);
930 oprintf(fp
, " Register Spacing: %u\n", i
.smbip_regspacing
);
932 flag_printf(fp
, "Flags", i
.smbip_flags
, sizeof (i
.smbip_flags
) * NBBY
,
933 smbios_ipmi_flag_name
, smbios_ipmi_flag_desc
);
937 print_extprocessor(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
940 smbios_processor_ext_t ep
;
942 if (check_oem(shp
) != 0)
945 (void) smbios_info_extprocessor(shp
, id
, &ep
);
947 oprintf(fp
, " Processor: %u\n", ep
.smbpe_processor
);
948 oprintf(fp
, " FRU: %u\n", ep
.smbpe_fru
);
949 oprintf(fp
, " Initial APIC ID count: %u\n\n", ep
.smbpe_n
);
951 for (i
= 0; i
< ep
.smbpe_n
; i
++) {
952 oprintf(fp
, " Logical Strand %u: Initial APIC ID: %u\n", i
,
958 print_extport(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
960 smbios_port_ext_t epo
;
962 if (check_oem(shp
) != 0)
965 (void) smbios_info_extport(shp
, id
, &epo
);
967 oprintf(fp
, " Chassis Handle: %u\n", epo
.smbporte_chassis
);
968 oprintf(fp
, " Port Connector Handle: %u\n", epo
.smbporte_port
);
969 oprintf(fp
, " Device Type: %u\n", epo
.smbporte_dtype
);
970 oprintf(fp
, " Device Handle: %u\n", epo
.smbporte_devhdl
);
971 oprintf(fp
, " PHY: %u\n", epo
.smbporte_phy
);
975 print_pciexrc(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
977 smbios_pciexrc_t pcie
;
979 if (check_oem(shp
) != 0)
982 (void) smbios_info_pciexrc(shp
, id
, &pcie
);
984 oprintf(fp
, " Component ID: %u\n", pcie
.smbpcie_bb
);
985 oprintf(fp
, " BDF: 0x%x\n", pcie
.smbpcie_bdf
);
989 print_extmemarray(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
991 smbios_memarray_ext_t em
;
993 if (check_oem(shp
) != 0)
996 (void) smbios_info_extmemarray(shp
, id
, &em
);
998 oprintf(fp
, " Physical Memory Array Handle: %u\n", em
.smbmae_ma
);
999 oprintf(fp
, " Component Parent Handle: %u\n", em
.smbmae_comp
);
1000 oprintf(fp
, " BDF: 0x%x\n", em
.smbmae_bdf
);
1004 print_extmemdevice(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1007 smbios_memdevice_ext_t emd
;
1009 if (check_oem(shp
) != 0)
1012 (void) smbios_info_extmemdevice(shp
, id
, &emd
);
1014 oprintf(fp
, " Memory Device Handle: %u\n", emd
.smbmdeve_md
);
1015 oprintf(fp
, " DRAM Channel: %u\n", emd
.smbmdeve_drch
);
1016 oprintf(fp
, " Number of Chip Selects: %u\n", emd
.smbmdeve_ncs
);
1018 for (i
= 0; i
< emd
.smbmdeve_ncs
; i
++) {
1019 oprintf(fp
, " Chip Select: %u\n", emd
.smbmdeve_cs
[i
]);
1024 print_struct(smbios_hdl_t
*shp
, const smbios_struct_t
*sp
, void *fp
)
1030 if (opt_t
!= -1 && opt_t
!= sp
->smbstr_type
)
1031 return (0); /* skip struct if type doesn't match -t */
1033 if (!opt_O
&& (sp
->smbstr_type
== SMB_TYPE_MEMCTL
||
1034 sp
->smbstr_type
== SMB_TYPE_MEMMOD
))
1035 return (0); /* skip struct if type is obsolete */
1037 if (g_hdr
++ == 0 || !opt_s
)
1038 oprintf(fp
, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE");
1040 oprintf(fp
, "%-5u %-4lu",
1041 (uint_t
)sp
->smbstr_id
, (ulong_t
)sp
->smbstr_size
);
1043 if ((s
= smbios_type_name(sp
->smbstr_type
)) != NULL
)
1044 oprintf(fp
, " %s (type %u)", s
, sp
->smbstr_type
);
1045 else if (sp
->smbstr_type
> SMB_TYPE_OEM_LO
&&
1046 sp
->smbstr_type
< SMB_TYPE_OEM_HI
)
1047 oprintf(fp
, " %s+%u (type %u)", "SMB_TYPE_OEM_LO",
1048 sp
->smbstr_type
- SMB_TYPE_OEM_LO
, sp
->smbstr_type
);
1050 oprintf(fp
, " %u", sp
->smbstr_type
);
1052 if ((s
= smbios_type_desc(sp
->smbstr_type
)) != NULL
)
1053 oprintf(fp
, " (%s)\n", s
);
1058 return (0); /* only print header line if -s specified */
1060 if (smbios_info_common(shp
, sp
->smbstr_id
, &info
) == 0) {
1062 print_common(&info
, fp
);
1065 switch (sp
->smbstr_type
) {
1068 print_bios(shp
, fp
);
1070 case SMB_TYPE_SYSTEM
:
1072 print_system(shp
, fp
);
1074 case SMB_TYPE_BASEBOARD
:
1076 print_bboard(shp
, sp
->smbstr_id
, fp
);
1078 case SMB_TYPE_CHASSIS
:
1080 print_chassis(shp
, sp
->smbstr_id
, fp
);
1082 case SMB_TYPE_PROCESSOR
:
1084 print_processor(shp
, sp
->smbstr_id
, fp
);
1086 case SMB_TYPE_CACHE
:
1088 print_cache(shp
, sp
->smbstr_id
, fp
);
1092 print_port(shp
, sp
->smbstr_id
, fp
);
1096 print_slot(shp
, sp
->smbstr_id
, fp
);
1098 case SMB_TYPE_OBDEVS
:
1100 print_obdevs(shp
, sp
->smbstr_id
, fp
);
1102 case SMB_TYPE_OEMSTR
:
1103 case SMB_TYPE_SYSCONFSTR
:
1105 print_strtab(shp
, sp
->smbstr_id
, fp
);
1109 print_lang(shp
, sp
->smbstr_id
, fp
);
1111 case SMB_TYPE_EVENTLOG
:
1113 print_evlog(shp
, sp
->smbstr_id
, fp
);
1115 case SMB_TYPE_MEMARRAY
:
1117 print_memarray(shp
, sp
->smbstr_id
, fp
);
1119 case SMB_TYPE_MEMDEVICE
:
1121 print_memdevice(shp
, sp
->smbstr_id
, fp
);
1123 case SMB_TYPE_MEMARRAYMAP
:
1125 print_memarrmap(shp
, sp
->smbstr_id
, fp
);
1127 case SMB_TYPE_MEMDEVICEMAP
:
1129 print_memdevmap(shp
, sp
->smbstr_id
, fp
);
1131 case SMB_TYPE_SECURITY
:
1133 print_hwsec(shp
, fp
);
1137 print_boot(shp
, fp
);
1139 case SMB_TYPE_IPMIDEV
:
1141 print_ipmi(shp
, fp
);
1143 case SMB_TYPE_OBDEVEXT
:
1145 print_obdevs_ext(shp
, sp
->smbstr_id
, fp
);
1147 case SUN_OEM_EXT_PROCESSOR
:
1149 print_extprocessor(shp
, sp
->smbstr_id
, fp
);
1151 case SUN_OEM_EXT_PORT
:
1153 print_extport(shp
, sp
->smbstr_id
, fp
);
1155 case SUN_OEM_PCIEXRC
:
1157 print_pciexrc(shp
, sp
->smbstr_id
, fp
);
1159 case SUN_OEM_EXT_MEMARRAY
:
1161 print_extmemarray(shp
, sp
->smbstr_id
, fp
);
1163 case SUN_OEM_EXT_MEMDEVICE
:
1165 print_extmemdevice(shp
, sp
->smbstr_id
, fp
);
1172 print_bytes(sp
->smbstr_data
, sp
->smbstr_size
, fp
);
1180 getu16(const char *name
, const char *s
)
1186 val
= strtoull(s
, &p
, 0);
1188 if (errno
!= 0 || p
== s
|| *p
!= '\0' || val
> UINT16_MAX
) {
1189 (void) fprintf(stderr
, "%s: invalid %s argument -- %s\n",
1194 return ((uint16_t)val
);
1198 getstype(const char *name
, const char *s
)
1203 for (t
= 0; t
< SMB_TYPE_OEM_LO
; t
++) {
1204 if ((ts
= smbios_type_name(t
)) != NULL
&& strcmp(s
, ts
) == 0)
1208 (void) fprintf(stderr
, "%s: invalid %s argument -- %s\n",
1218 (void) fprintf(fp
, "Usage: %s "
1219 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname
);
1222 "\t-B disable header validation for broken BIOSes\n"
1223 "\t-e display SMBIOS entry point information\n"
1224 "\t-i display only the specified structure\n"
1225 "\t-O display obsolete structure types\n"
1226 "\t-s display only a summary of structure identifiers and types\n"
1227 "\t-t display only the specified structure type\n"
1228 "\t-w write the raw data to the specified file\n"
1229 "\t-x display raw data for structures\n");
1231 return (SMBIOS_USAGE
);
1235 main(int argc
, char *argv
[])
1237 const char *ifile
= NULL
;
1238 const char *ofile
= NULL
;
1246 if ((p
= strrchr(argv
[0], '/')) == NULL
)
1251 while (optind
< argc
) {
1252 while ((c
= getopt(argc
, argv
, "Bei:Ost:w:xZ")) != EOF
) {
1255 oflags
|= SMB_O_NOCKSUM
| SMB_O_NOVERS
;
1261 opt_i
= getu16("struct ID", optarg
);
1270 if (isdigit(optarg
[0]))
1271 opt_t
= getu16("struct type", optarg
);
1273 opt_t
= getstype("struct type", optarg
);
1282 oflags
|= SMB_O_ZIDS
; /* undocumented */
1285 return (usage(stderr
));
1289 if (optind
< argc
) {
1290 if (ifile
!= NULL
) {
1291 (void) fprintf(stderr
, "%s: illegal "
1292 "argument -- %s\n", g_pname
, argv
[optind
]);
1293 return (SMBIOS_USAGE
);
1295 ifile
= argv
[optind
++];
1299 if ((shp
= smbios_open(ifile
, SMB_VERSION
, oflags
, &err
)) == NULL
) {
1300 (void) fprintf(stderr
, "%s: failed to load SMBIOS: %s\n",
1301 g_pname
, smbios_errmsg(err
));
1302 return (SMBIOS_ERROR
);
1305 if (ofile
!= NULL
) {
1306 if ((fd
= open(ofile
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666)) == -1) {
1307 (void) fprintf(stderr
, "%s: failed to open %s: %s\n",
1308 g_pname
, ofile
, strerror(errno
));
1310 } else if (smbios_write(shp
, fd
) != 0) {
1311 (void) fprintf(stderr
, "%s: failed to write %s: %s\n",
1312 g_pname
, ofile
, smbios_errmsg(smbios_errno(shp
)));
1320 print_smbios(shp
, stdout
);
1322 return (SMBIOS_SUCCESS
);
1325 if (opt_O
&& (opt_i
!= -1 || opt_t
!= -1))
1326 opt_O
++; /* -i or -t imply displaying obsolete records */
1329 err
= smbios_lookup_id(shp
, opt_i
, &s
);
1331 err
= smbios_iter(shp
, print_struct
, stdout
);
1334 (void) fprintf(stderr
, "%s: failed to access SMBIOS: %s\n",
1335 g_pname
, smbios_errmsg(smbios_errno(shp
)));
1337 return (SMBIOS_ERROR
);
1341 (void) print_struct(shp
, &s
, stdout
);
1344 return (SMBIOS_SUCCESS
);