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 (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>
44 #define SMBIOS_SUCCESS 0
45 #define SMBIOS_ERROR 1
46 #define SMBIOS_USAGE 2
48 static const char *g_pname
;
52 static int opt_i
= -1;
55 static int opt_t
= -1;
60 oprintf(FILE *fp
, const char *format
, ...)
65 (void) vfprintf(fp
, format
, ap
);
71 desc_printf(const char *d
, FILE *fp
, const char *format
, ...)
76 (void) vfprintf(fp
, format
, ap
);
80 (void) fprintf(fp
, " (%s)\n", d
);
82 (void) fprintf(fp
, "\n");
86 flag_printf(FILE *fp
, const char *s
, uint_t flags
, size_t bits
,
87 const char *(*flag_name
)(uint_t
), const char *(*flag_desc
)(uint_t
))
91 oprintf(fp
, " %s: 0x%x\n", s
, flags
);
93 for (i
= 0; i
< bits
; i
++) {
100 if ((n
= flag_name(f
)) != NULL
)
101 desc_printf(flag_desc(f
), fp
, "\t%s", n
);
103 desc_printf(flag_desc(f
), fp
, "\t0x%x", f
);
108 flag64_printf(FILE *fp
, const char *s
, uint64_t flags
, size_t bits
,
109 const char *(*flag_name
)(uint64_t), const char *(*flag_desc
)(uint64_t))
113 oprintf(fp
, " %s: 0x%llx\n", s
, (u_longlong_t
)flags
);
115 for (i
= 0; i
< bits
; i
++) {
116 u_longlong_t f
= 1ULL << i
;
122 if ((n
= flag_name(f
)) != NULL
)
123 desc_printf(flag_desc(f
), fp
, "\t%s", n
);
125 desc_printf(flag_desc(f
), fp
, "\t0x%llx", f
);
130 id_printf(FILE *fp
, const char *s
, id_t id
)
134 oprintf(fp
, "%sNone\n", s
);
137 oprintf(fp
, "%sNot Supported\n", s
);
140 oprintf(fp
, "%s%u\n", s
, (uint_t
)id
);
145 check_oem(smbios_hdl_t
*shp
)
152 const char **oem_str
;
154 rv
= smbios_lookup_type(shp
, SMB_TYPE_OEMSTR
, &s
);
159 oem_id
= s
.smbstr_id
;
161 cnt
= smbios_info_strtab(shp
, oem_id
, 0, NULL
);
163 oem_str
= alloca(sizeof (char *) * cnt
);
164 (void) smbios_info_strtab(shp
, oem_id
, cnt
, oem_str
);
166 for (i
= 0; i
< cnt
; i
++) {
167 if (strncmp(oem_str
[i
], SMB_PRMS1
,
168 strlen(SMB_PRMS1
) + 1) == 0) {
178 print_smbios_21(smbios_21_entry_t
*ep
, FILE *fp
)
182 oprintf(fp
, "Entry Point Anchor Tag: %*.*s\n",
183 (int)sizeof (ep
->smbe_eanchor
), (int)sizeof (ep
->smbe_eanchor
),
186 oprintf(fp
, "Entry Point Checksum: 0x%x\n", ep
->smbe_ecksum
);
187 oprintf(fp
, "Entry Point Length: %u\n", ep
->smbe_elen
);
188 oprintf(fp
, "Entry Point Version: %u.%u\n",
189 ep
->smbe_major
, ep
->smbe_minor
);
190 oprintf(fp
, "Max Structure Size: %u\n", ep
->smbe_maxssize
);
191 oprintf(fp
, "Entry Point Revision: 0x%x\n", ep
->smbe_revision
);
193 oprintf(fp
, "Entry Point Revision Data:");
194 for (i
= 0; i
< sizeof (ep
->smbe_format
); i
++)
195 oprintf(fp
, " 0x%02x", ep
->smbe_format
[i
]);
198 oprintf(fp
, "Intermediate Anchor Tag: %*.*s\n",
199 (int)sizeof (ep
->smbe_ianchor
), (int)sizeof (ep
->smbe_ianchor
),
202 oprintf(fp
, "Intermediate Checksum: 0x%x\n", ep
->smbe_icksum
);
203 oprintf(fp
, "Structure Table Length: %u\n", ep
->smbe_stlen
);
204 oprintf(fp
, "Structure Table Address: 0x%x\n", ep
->smbe_staddr
);
205 oprintf(fp
, "Structure Table Entries: %u\n", ep
->smbe_stnum
);
206 oprintf(fp
, "DMI BCD Revision: 0x%x\n", ep
->smbe_bcdrev
);
210 print_smbios_30(smbios_30_entry_t
*ep
, FILE *fp
)
212 oprintf(fp
, "Entry Point Anchor Tag: %*.*s\n",
213 (int)sizeof (ep
->smbe_eanchor
), (int)sizeof (ep
->smbe_eanchor
),
216 oprintf(fp
, "Entry Point Checksum: 0x%x\n", ep
->smbe_ecksum
);
217 oprintf(fp
, "Entry Point Length: %u\n", ep
->smbe_elen
);
218 oprintf(fp
, "SMBIOS Version: %u.%u\n",
219 ep
->smbe_major
, ep
->smbe_minor
);
220 oprintf(fp
, "SMBIOS DocRev: 0x%x\n", ep
->smbe_docrev
);
221 oprintf(fp
, "Entry Point Revision: 0x%x\n", ep
->smbe_revision
);
223 oprintf(fp
, "Structure Table Length: %u\n", ep
->smbe_stlen
);
224 oprintf(fp
, "Structure Table Address: 0x%" PRIx64
"\n",
229 print_smbios(smbios_hdl_t
*shp
, FILE *fp
)
233 switch (smbios_info_smbios(shp
, &ep
)) {
234 case SMBIOS_ENTRY_POINT_21
:
235 print_smbios_21(&ep
.ep21
, fp
);
237 case SMBIOS_ENTRY_POINT_30
:
238 print_smbios_30(&ep
.ep30
, fp
);
244 print_common(const smbios_info_t
*ip
, FILE *fp
)
246 if (ip
->smbi_manufacturer
[0] != '\0')
247 oprintf(fp
, " Manufacturer: %s\n", ip
->smbi_manufacturer
);
248 if (ip
->smbi_product
[0] != '\0')
249 oprintf(fp
, " Product: %s\n", ip
->smbi_product
);
250 if (ip
->smbi_version
[0] != '\0')
251 oprintf(fp
, " Version: %s\n", ip
->smbi_version
);
252 if (ip
->smbi_serial
[0] != '\0')
253 oprintf(fp
, " Serial Number: %s\n", ip
->smbi_serial
);
254 if (ip
->smbi_asset
[0] != '\0')
255 oprintf(fp
, " Asset Tag: %s\n", ip
->smbi_asset
);
256 if (ip
->smbi_location
[0] != '\0')
257 oprintf(fp
, " Location Tag: %s\n", ip
->smbi_location
);
258 if (ip
->smbi_part
[0] != '\0')
259 oprintf(fp
, " Part Number: %s\n", ip
->smbi_part
);
263 print_bios(smbios_hdl_t
*shp
, FILE *fp
)
267 (void) smbios_info_bios(shp
, &b
);
269 oprintf(fp
, " Vendor: %s\n", b
.smbb_vendor
);
270 oprintf(fp
, " Version String: %s\n", b
.smbb_version
);
271 oprintf(fp
, " Release Date: %s\n", b
.smbb_reldate
);
272 oprintf(fp
, " Address Segment: 0x%x\n", b
.smbb_segment
);
273 oprintf(fp
, " ROM Size: %" PRIu64
" bytes\n", b
.smbb_extromsize
);
274 oprintf(fp
, " Image Size: %u bytes\n", b
.smbb_runsize
);
276 flag64_printf(fp
, "Characteristics",
277 b
.smbb_cflags
, sizeof (b
.smbb_cflags
) * NBBY
,
278 smbios_bios_flag_name
, smbios_bios_flag_desc
);
280 if (b
.smbb_nxcflags
> SMB_BIOSXB_1
) {
281 flag_printf(fp
, "Characteristics Extension Byte 1",
282 b
.smbb_xcflags
[SMB_BIOSXB_1
],
283 sizeof (b
.smbb_xcflags
[SMB_BIOSXB_1
]) * NBBY
,
284 smbios_bios_xb1_name
, smbios_bios_xb1_desc
);
287 if (b
.smbb_nxcflags
> SMB_BIOSXB_2
) {
288 flag_printf(fp
, "Characteristics Extension Byte 2",
289 b
.smbb_xcflags
[SMB_BIOSXB_2
],
290 sizeof (b
.smbb_xcflags
[SMB_BIOSXB_2
]) * NBBY
,
291 smbios_bios_xb2_name
, smbios_bios_xb2_desc
);
294 if (b
.smbb_nxcflags
> SMB_BIOSXB_BIOS_MIN
) {
295 oprintf(fp
, " Version Number: %u.%u\n",
296 b
.smbb_biosv
.smbv_major
, b
.smbb_biosv
.smbv_minor
);
299 if (b
.smbb_nxcflags
> SMB_BIOSXB_ECFW_MIN
) {
300 oprintf(fp
, " Embedded Ctlr Firmware Version Number: %u.%u\n",
301 b
.smbb_ecfwv
.smbv_major
, b
.smbb_ecfwv
.smbv_minor
);
306 print_system(smbios_hdl_t
*shp
, FILE *fp
)
311 (void) smbios_info_system(shp
, &s
);
313 oprintf(fp
, " UUID: ");
314 for (i
= 0; i
< s
.smbs_uuidlen
; i
++) {
315 oprintf(fp
, "%02x", s
.smbs_uuid
[i
]);
316 if (i
== 3 || i
== 5 || i
== 7 || i
== 9)
321 desc_printf(smbios_system_wakeup_desc(s
.smbs_wakeup
),
322 fp
, " Wake-Up Event: 0x%x", s
.smbs_wakeup
);
324 oprintf(fp
, " SKU Number: %s\n", s
.smbs_sku
);
325 oprintf(fp
, " Family: %s\n", s
.smbs_family
);
329 print_bboard(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
334 (void) smbios_info_bboard(shp
, id
, &b
);
336 oprintf(fp
, " Chassis: %u\n", (uint_t
)b
.smbb_chassis
);
338 flag_printf(fp
, "Flags", b
.smbb_flags
, sizeof (b
.smbb_flags
) * NBBY
,
339 smbios_bboard_flag_name
, smbios_bboard_flag_desc
);
341 desc_printf(smbios_bboard_type_desc(b
.smbb_type
),
342 fp
, " Board Type: 0x%x", b
.smbb_type
);
344 chdl_cnt
= b
.smbb_contn
;
350 chdl
= alloca(chdl_cnt
* sizeof (id_t
));
351 cnt
= smbios_info_contains(shp
, id
, chdl_cnt
, chdl
);
352 if (cnt
> SMB_CONT_MAX
)
354 n
= MIN(chdl_cnt
, cnt
);
357 for (i
= 0; i
< n
; i
++) {
358 hdl
= (uint16_t)chdl
[i
];
359 oprintf(fp
, " Contained Handle: %u\n", hdl
);
365 print_chassis(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
370 (void) smbios_info_chassis(shp
, id
, &c
);
372 oprintf(fp
, " OEM Data: 0x%x\n", c
.smbc_oemdata
);
373 oprintf(fp
, " SKU number: %s\n",
374 c
.smbc_sku
[0] == '\0' ? "<unknown>" : c
.smbc_sku
);
375 oprintf(fp
, " Lock Present: %s\n", c
.smbc_lock
? "Y" : "N");
377 desc_printf(smbios_chassis_type_desc(c
.smbc_type
),
378 fp
, " Chassis Type: 0x%x", c
.smbc_type
);
380 desc_printf(smbios_chassis_state_desc(c
.smbc_bustate
),
381 fp
, " Boot-Up State: 0x%x", c
.smbc_bustate
);
383 desc_printf(smbios_chassis_state_desc(c
.smbc_psstate
),
384 fp
, " Power Supply State: 0x%x", c
.smbc_psstate
);
386 desc_printf(smbios_chassis_state_desc(c
.smbc_thstate
),
387 fp
, " Thermal State: 0x%x", c
.smbc_thstate
);
389 oprintf(fp
, " Chassis Height: %uu\n", c
.smbc_uheight
);
390 oprintf(fp
, " Power Cords: %u\n", c
.smbc_cords
);
392 elem_cnt
= c
.smbc_elems
;
393 oprintf(fp
, " Element Records: %u\n", elem_cnt
);
400 elems
= alloca(c
.smbc_elems
* sizeof (id_t
));
401 cnt
= smbios_info_contains(shp
, id
, elem_cnt
, elems
);
402 if (cnt
> SMB_CONT_MAX
)
404 n
= MIN(elem_cnt
, cnt
);
407 for (i
= 0; i
< n
; i
++) {
408 type
= (uint8_t)elems
[i
];
410 /* SMBIOS structrure Type */
411 desc_printf(smbios_type_name(type
& 0x7f), fp
,
412 " Contained SMBIOS structure Type: %u",
415 /* SMBIOS Base Board Type */
416 desc_printf(smbios_bboard_type_desc(type
), fp
,
417 " Contained SMBIOS Base Board Type: 0x%x",
425 print_processor(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
427 smbios_processor_t p
;
430 (void) smbios_info_processor(shp
, id
, &p
);
431 status
= SMB_PRSTATUS_STATUS(p
.smbp_status
);
433 desc_printf(smbios_processor_family_desc(p
.smbp_family
),
434 fp
, " Family: %u", p
.smbp_family
);
436 if (p
.smbp_family2
!= 0)
437 desc_printf(smbios_processor_family_desc(p
.smbp_family2
),
438 fp
, " Family Ext: %u", p
.smbp_family2
);
440 oprintf(fp
, " CPUID: 0x%llx\n", (u_longlong_t
)p
.smbp_cpuid
);
442 desc_printf(smbios_processor_type_desc(p
.smbp_type
),
443 fp
, " Type: %u", p
.smbp_type
);
445 desc_printf(smbios_processor_upgrade_desc(p
.smbp_upgrade
),
446 fp
, " Socket Upgrade: %u", p
.smbp_upgrade
);
448 oprintf(fp
, " Socket Status: %s\n",
449 SMB_PRSTATUS_PRESENT(p
.smbp_status
) ?
450 "Populated" : "Not Populated");
452 desc_printf(smbios_processor_status_desc(status
),
453 fp
, " Processor Status: %u", status
);
455 if (SMB_PRV_LEGACY(p
.smbp_voltage
)) {
456 oprintf(fp
, " Supported Voltages:");
457 switch (p
.smbp_voltage
) {
459 oprintf(fp
, " 5.0V");
462 oprintf(fp
, " 3.3V");
465 oprintf(fp
, " 2.9V");
470 oprintf(fp
, " Supported Voltages: %.1fV\n",
471 (float)SMB_PRV_VOLTAGE(p
.smbp_voltage
) / 10);
474 if (p
.smbp_corecount
!= 0) {
475 if (p
.smbp_corecount
!= 0xff || p
.smbp_corecount2
== 0)
476 oprintf(fp
, " Core Count: %u\n", p
.smbp_corecount
);
478 oprintf(fp
, " Core Count: %u\n", p
.smbp_corecount2
);
480 oprintf(fp
, " Core Count: Unknown\n");
483 if (p
.smbp_coresenabled
!= 0) {
484 if (p
.smbp_coresenabled
!= 0xff || p
.smbp_coresenabled2
== 0) {
485 oprintf(fp
, " Cores Enabled: %u\n",
486 p
.smbp_coresenabled
);
488 oprintf(fp
, " Cores Enabled: %u\n",
489 p
.smbp_coresenabled2
);
492 oprintf(fp
, " Cores Enabled: Unknown\n");
495 if (p
.smbp_threadcount
!= 0) {
496 if (p
.smbp_threadcount
!= 0xff || p
.smbp_threadcount2
== 0) {
497 oprintf(fp
, " Thread Count: %u\n",
500 oprintf(fp
, " Thread Count: %u\n",
501 p
.smbp_threadcount2
);
504 oprintf(fp
, " Thread Count: Unknown\n");
508 flag_printf(fp
, "Processor Characteristics",
509 p
.smbp_cflags
, sizeof (p
.smbp_cflags
) * NBBY
,
510 smbios_processor_core_flag_name
,
511 smbios_processor_core_flag_desc
);
514 if (p
.smbp_clkspeed
!= 0)
515 oprintf(fp
, " External Clock Speed: %uMHz\n", p
.smbp_clkspeed
);
517 oprintf(fp
, " External Clock Speed: Unknown\n");
519 if (p
.smbp_maxspeed
!= 0)
520 oprintf(fp
, " Maximum Speed: %uMHz\n", p
.smbp_maxspeed
);
522 oprintf(fp
, " Maximum Speed: Unknown\n");
524 if (p
.smbp_curspeed
!= 0)
525 oprintf(fp
, " Current Speed: %uMHz\n", p
.smbp_curspeed
);
527 oprintf(fp
, " Current Speed: Unknown\n");
529 id_printf(fp
, " L1 Cache: ", p
.smbp_l1cache
);
530 id_printf(fp
, " L2 Cache: ", p
.smbp_l2cache
);
531 id_printf(fp
, " L3 Cache: ", p
.smbp_l3cache
);
535 print_cache(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
539 (void) smbios_info_cache(shp
, id
, &c
);
541 oprintf(fp
, " Level: %u\n", c
.smba_level
);
542 oprintf(fp
, " Maximum Installed Size: %" PRIu64
" bytes\n",
545 if (c
.smba_size2
!= 0) {
546 oprintf(fp
, " Installed Size: %" PRIu64
" bytes\n",
549 oprintf(fp
, " Installed Size: Not Installed\n");
552 if (c
.smba_speed
!= 0)
553 oprintf(fp
, " Speed: %uns\n", c
.smba_speed
);
555 oprintf(fp
, " Speed: Unknown\n");
557 flag_printf(fp
, "Supported SRAM Types",
558 c
.smba_stype
, sizeof (c
.smba_stype
) * NBBY
,
559 smbios_cache_ctype_name
, smbios_cache_ctype_desc
);
561 desc_printf(smbios_cache_ctype_desc(c
.smba_ctype
),
562 fp
, " Current SRAM Type: 0x%x", c
.smba_ctype
);
564 desc_printf(smbios_cache_ecc_desc(c
.smba_etype
),
565 fp
, " Error Correction Type: %u", c
.smba_etype
);
567 desc_printf(smbios_cache_logical_desc(c
.smba_ltype
),
568 fp
, " Logical Cache Type: %u", c
.smba_ltype
);
570 desc_printf(smbios_cache_assoc_desc(c
.smba_assoc
),
571 fp
, " Associativity: %u", c
.smba_assoc
);
573 desc_printf(smbios_cache_mode_desc(c
.smba_mode
),
574 fp
, " Mode: %u", c
.smba_mode
);
576 desc_printf(smbios_cache_loc_desc(c
.smba_location
),
577 fp
, " Location: %u", c
.smba_location
);
579 flag_printf(fp
, "Flags", c
.smba_flags
, sizeof (c
.smba_flags
) * NBBY
,
580 smbios_cache_flag_name
, smbios_cache_flag_desc
);
584 print_port(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
588 (void) smbios_info_port(shp
, id
, &p
);
590 oprintf(fp
, " Internal Reference Designator: %s\n", p
.smbo_iref
);
591 oprintf(fp
, " External Reference Designator: %s\n", p
.smbo_eref
);
593 desc_printf(smbios_port_conn_desc(p
.smbo_itype
),
594 fp
, " Internal Connector Type: %u", p
.smbo_itype
);
596 desc_printf(smbios_port_conn_desc(p
.smbo_etype
),
597 fp
, " External Connector Type: %u", p
.smbo_etype
);
599 desc_printf(smbios_port_type_desc(p
.smbo_ptype
),
600 fp
, " Port Type: %u", p
.smbo_ptype
);
604 print_slot(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
609 (void) smbios_info_slot(shp
, id
, &s
);
610 smbios_info_smbios_version(shp
, &v
);
612 oprintf(fp
, " Reference Designator: %s\n", s
.smbl_name
);
613 oprintf(fp
, " Slot ID: 0x%x\n", s
.smbl_id
);
615 desc_printf(smbios_slot_type_desc(s
.smbl_type
),
616 fp
, " Type: 0x%x", s
.smbl_type
);
618 desc_printf(smbios_slot_width_desc(s
.smbl_width
),
619 fp
, " Width: 0x%x", s
.smbl_width
);
621 desc_printf(smbios_slot_usage_desc(s
.smbl_usage
),
622 fp
, " Usage: 0x%x", s
.smbl_usage
);
624 desc_printf(smbios_slot_length_desc(s
.smbl_length
),
625 fp
, " Length: 0x%x", s
.smbl_length
);
627 flag_printf(fp
, "Slot Characteristics 1",
628 s
.smbl_ch1
, sizeof (s
.smbl_ch1
) * NBBY
,
629 smbios_slot_ch1_name
, smbios_slot_ch1_desc
);
631 flag_printf(fp
, "Slot Characteristics 2",
632 s
.smbl_ch2
, sizeof (s
.smbl_ch2
) * NBBY
,
633 smbios_slot_ch2_name
, smbios_slot_ch2_desc
);
635 if (check_oem(shp
) != 0 && (v
.smbv_major
< 2 || v
.smbv_minor
< 6))
638 oprintf(fp
, " Segment Group: %u\n", s
.smbl_sg
);
639 oprintf(fp
, " Bus Number: %u\n", s
.smbl_bus
);
640 oprintf(fp
, " Device/Function Number: %u\n", s
.smbl_df
);
644 print_obdevs_ext(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
647 smbios_obdev_ext_t oe
;
650 (void) smbios_info_obdevs_ext(shp
, id
, &oe
);
653 * Bit 7 is always whether or not the device is enabled while bits 0:6
654 * are the actual device type.
656 enabled
= oe
.smboe_dtype
>> 7;
657 type
= smbios_onboard_type_desc(oe
.smboe_dtype
& 0x7f);
659 oprintf(fp
, " Reference Designator: %s\n", oe
.smboe_name
);
660 oprintf(fp
, " Device Enabled: %s\n", enabled
== B_TRUE
? "true" :
662 oprintf(fp
, " Device Type: %s\n", type
);
663 oprintf(fp
, " Device Type Instance: %u\n", oe
.smboe_dti
);
664 oprintf(fp
, " Segment Group Number: %u\n", oe
.smboe_sg
);
665 oprintf(fp
, " Bus Number: %u\n", oe
.smboe_bus
);
666 oprintf(fp
, " Device/Function Number: %u\n", oe
.smboe_df
);
670 print_obdevs(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
672 smbios_obdev_t
*argv
;
675 if ((argc
= smbios_info_obdevs(shp
, id
, 0, NULL
)) > 0) {
676 argv
= alloca(sizeof (smbios_obdev_t
) * argc
);
677 (void) smbios_info_obdevs(shp
, id
, argc
, argv
);
678 for (i
= 0; i
< argc
; i
++)
679 oprintf(fp
, " %s\n", argv
[i
].smbd_name
);
684 print_strtab(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
689 if ((argc
= smbios_info_strtab(shp
, id
, 0, NULL
)) > 0) {
690 argv
= alloca(sizeof (char *) * argc
);
691 (void) smbios_info_strtab(shp
, id
, argc
, argv
);
692 for (i
= 0; i
< argc
; i
++)
693 oprintf(fp
, " %s\n", argv
[i
]);
698 print_lang(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
702 (void) smbios_info_lang(shp
, &l
);
704 oprintf(fp
, " Current Language: %s\n", l
.smbla_cur
);
705 oprintf(fp
, " Language String Format: %u\n", l
.smbla_fmt
);
706 oprintf(fp
, " Number of Installed Languages: %u\n", l
.smbla_num
);
707 oprintf(fp
, " Installed Languages:\n");
709 print_strtab(shp
, id
, fp
);
714 print_evlog(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
719 (void) smbios_info_eventlog(shp
, &ev
);
721 oprintf(fp
, " Log Area Size: %lu bytes\n", (ulong_t
)ev
.smbev_size
);
722 oprintf(fp
, " Header Offset: %lu\n", (ulong_t
)ev
.smbev_hdr
);
723 oprintf(fp
, " Data Offset: %lu\n", (ulong_t
)ev
.smbev_data
);
725 desc_printf(smbios_evlog_method_desc(ev
.smbev_method
),
726 fp
, " Data Access Method: %u", ev
.smbev_method
);
728 flag_printf(fp
, "Log Flags",
729 ev
.smbev_flags
, sizeof (ev
.smbev_flags
) * NBBY
,
730 smbios_evlog_flag_name
, smbios_evlog_flag_desc
);
732 desc_printf(smbios_evlog_format_desc(ev
.smbev_format
),
733 fp
, " Log Header Format: %u", ev
.smbev_format
);
735 oprintf(fp
, " Update Token: 0x%x\n", ev
.smbev_token
);
736 oprintf(fp
, " Data Access Address: ");
738 switch (ev
.smbev_method
) {
739 case SMB_EVM_1x1i_1x1d
:
740 case SMB_EVM_2x1i_1x1d
:
741 case SMB_EVM_1x2i_1x1d
:
742 oprintf(fp
, "Index Address 0x%x, Data Address 0x%x\n",
743 ev
.smbev_addr
.eva_io
.evi_iaddr
,
744 ev
.smbev_addr
.eva_io
.evi_daddr
);
747 oprintf(fp
, "0x%x\n", ev
.smbev_addr
.eva_gpnv
);
750 oprintf(fp
, "0x%x\n", ev
.smbev_addr
.eva_addr
);
753 oprintf(fp
, " Type Descriptors:\n");
755 for (i
= 0; i
< ev
.smbev_typec
; i
++) {
756 oprintf(fp
, " %u: Log Type 0x%x, Data Type 0x%x\n", i
,
757 ev
.smbev_typev
[i
].smbevt_ltype
,
758 ev
.smbev_typev
[i
].smbevt_dtype
);
763 print_bytes(const uint8_t *data
, size_t size
, FILE *fp
)
765 size_t row
, rows
= P2ROUNDUP(size
, 16) / 16;
771 oprintf(fp
, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f "
772 "0123456789abcdef\n");
774 for (row
= 0; row
< rows
; row
++) {
775 oprintf(fp
, " %#6lx: ", (ulong_t
)row
* 16);
776 cols
= MIN(size
- row
* 16, 16);
778 for (col
= 0; col
< cols
; col
++) {
782 oprintf(fp
, "%02x", x
);
783 buf
[col
] = x
<= ' ' || x
> '~' ? '.' : x
;
786 for (; col
< 16; col
++) {
794 oprintf(fp
, " %s\n", buf
);
801 print_memarray(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
803 smbios_memarray_t ma
;
805 (void) smbios_info_memarray(shp
, id
, &ma
);
807 desc_printf(smbios_memarray_loc_desc(ma
.smbma_location
),
808 fp
, " Location: %u", ma
.smbma_location
);
810 desc_printf(smbios_memarray_use_desc(ma
.smbma_use
),
811 fp
, " Use: %u", ma
.smbma_use
);
813 desc_printf(smbios_memarray_ecc_desc(ma
.smbma_ecc
),
814 fp
, " ECC: %u", ma
.smbma_ecc
);
816 oprintf(fp
, " Number of Slots/Sockets: %u\n", ma
.smbma_ndevs
);
817 id_printf(fp
, " Memory Error Data: ", ma
.smbma_err
);
818 oprintf(fp
, " Max Capacity: %llu bytes\n",
819 (u_longlong_t
)ma
.smbma_size
);
823 print_memdevice(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
825 smbios_memdevice_t md
;
827 (void) smbios_info_memdevice(shp
, id
, &md
);
829 id_printf(fp
, " Physical Memory Array: ", md
.smbmd_array
);
830 id_printf(fp
, " Memory Error Data: ", md
.smbmd_error
);
832 if (md
.smbmd_twidth
!= -1u)
833 oprintf(fp
, " Total Width: %u bits\n", md
.smbmd_twidth
);
835 oprintf(fp
, " Total Width: Unknown\n");
837 if (md
.smbmd_dwidth
!= -1u)
838 oprintf(fp
, " Data Width: %u bits\n", md
.smbmd_dwidth
);
840 oprintf(fp
, " Data Width: Unknown\n");
842 switch (md
.smbmd_size
) {
844 oprintf(fp
, " Size: Unknown\n");
847 oprintf(fp
, " Size: Not Populated\n");
850 oprintf(fp
, " Size: %llu bytes\n",
851 (u_longlong_t
)md
.smbmd_size
);
854 desc_printf(smbios_memdevice_form_desc(md
.smbmd_form
),
855 fp
, " Form Factor: %u", md
.smbmd_form
);
857 if (md
.smbmd_set
== 0)
858 oprintf(fp
, " Set: None\n");
859 else if (md
.smbmd_set
== (uint8_t)-1u)
860 oprintf(fp
, " Set: Unknown\n");
862 oprintf(fp
, " Set: %u\n", md
.smbmd_set
);
864 if (md
.smbmd_rank
!= 0) {
865 desc_printf(smbios_memdevice_rank_desc(md
.smbmd_rank
),
866 fp
, " Rank: %u", md
.smbmd_rank
);
868 oprintf(fp
, " Rank: Unknown\n");
871 desc_printf(smbios_memdevice_type_desc(md
.smbmd_type
),
872 fp
, " Memory Type: %u", md
.smbmd_type
);
874 flag_printf(fp
, "Flags", md
.smbmd_flags
, sizeof (md
.smbmd_flags
) * NBBY
,
875 smbios_memdevice_flag_name
, smbios_memdevice_flag_desc
);
877 if (md
.smbmd_speed
!= 0)
878 oprintf(fp
, " Speed: %u MT/s\n", md
.smbmd_speed
);
880 oprintf(fp
, " Speed: Unknown\n");
882 if (md
.smbmd_clkspeed
!= 0)
883 oprintf(fp
, " Configured Speed: %u MT/s\n", md
.smbmd_clkspeed
);
885 oprintf(fp
, " Configured Speed: Unknown\n");
887 oprintf(fp
, " Device Locator: %s\n", md
.smbmd_dloc
);
888 oprintf(fp
, " Bank Locator: %s\n", md
.smbmd_bloc
);
890 if (md
.smbmd_minvolt
!= 0) {
891 oprintf(fp
, " Minimum Voltage: %.2fV\n",
892 md
.smbmd_minvolt
/ 1000.0);
894 oprintf(fp
, " Minimum Voltage: Unknown\n");
897 if (md
.smbmd_maxvolt
!= 0) {
898 oprintf(fp
, " Maximum Voltage: %.2fV\n",
899 md
.smbmd_maxvolt
/ 1000.0);
901 oprintf(fp
, " Maximum Voltage: Unknown\n");
904 if (md
.smbmd_confvolt
!= 0) {
905 oprintf(fp
, " Configured Voltage: %.2fV\n",
906 md
.smbmd_confvolt
/ 1000.0);
908 oprintf(fp
, " Configured Voltage: Unknown\n");
913 print_memarrmap(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
915 smbios_memarrmap_t ma
;
917 (void) smbios_info_memarrmap(shp
, id
, &ma
);
919 id_printf(fp
, " Physical Memory Array: ", ma
.smbmam_array
);
920 oprintf(fp
, " Devices per Row: %u\n", ma
.smbmam_width
);
922 oprintf(fp
, " Physical Address: 0x%llx\n Size: %llu bytes\n",
923 (u_longlong_t
)ma
.smbmam_addr
, (u_longlong_t
)ma
.smbmam_size
);
927 print_memdevmap(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
929 smbios_memdevmap_t md
;
931 (void) smbios_info_memdevmap(shp
, id
, &md
);
933 id_printf(fp
, " Memory Device: ", md
.smbmdm_device
);
934 id_printf(fp
, " Memory Array Mapped Address: ", md
.smbmdm_arrmap
);
936 oprintf(fp
, " Physical Address: 0x%llx\n Size: %llu bytes\n",
937 (u_longlong_t
)md
.smbmdm_addr
, (u_longlong_t
)md
.smbmdm_size
);
939 oprintf(fp
, " Partition Row Position: %u\n", md
.smbmdm_rpos
);
940 oprintf(fp
, " Interleave Position: %u\n", md
.smbmdm_ipos
);
941 oprintf(fp
, " Interleave Data Depth: %u\n", md
.smbmdm_idepth
);
945 print_hwsec(smbios_hdl_t
*shp
, FILE *fp
)
949 (void) smbios_info_hwsec(shp
, &h
);
951 desc_printf(smbios_hwsec_desc(h
.smbh_pwr_ps
),
952 fp
, " Power-On Password Status: %u", h
.smbh_pwr_ps
);
953 desc_printf(smbios_hwsec_desc(h
.smbh_kbd_ps
),
954 fp
, " Keyboard Password Status: %u", h
.smbh_kbd_ps
);
955 desc_printf(smbios_hwsec_desc(h
.smbh_adm_ps
),
956 fp
, " Administrator Password Status: %u", h
.smbh_adm_ps
);
957 desc_printf(smbios_hwsec_desc(h
.smbh_pan_ps
),
958 fp
, " Front Panel Reset Status: %u", h
.smbh_pan_ps
);
962 print_boot(smbios_hdl_t
*shp
, FILE *fp
)
966 (void) smbios_info_boot(shp
, &b
);
968 desc_printf(smbios_boot_desc(b
.smbt_status
),
969 fp
, " Boot Status Code: 0x%x", b
.smbt_status
);
971 if (b
.smbt_size
!= 0) {
972 oprintf(fp
, " Boot Data (%lu bytes):\n", (ulong_t
)b
.smbt_size
);
973 print_bytes(b
.smbt_data
, b
.smbt_size
, fp
);
978 print_ipmi(smbios_hdl_t
*shp
, FILE *fp
)
982 (void) smbios_info_ipmi(shp
, &i
);
984 desc_printf(smbios_ipmi_type_desc(i
.smbip_type
),
985 fp
, " Type: %u", i
.smbip_type
);
987 oprintf(fp
, " BMC IPMI Version: %u.%u\n",
988 i
.smbip_vers
.smbv_major
, i
.smbip_vers
.smbv_minor
);
990 oprintf(fp
, " i2c Bus Slave Address: 0x%x\n", i
.smbip_i2c
);
991 oprintf(fp
, " NV Storage Device Bus ID: 0x%x\n", i
.smbip_bus
);
992 oprintf(fp
, " BMC Base Address: 0x%llx\n", (u_longlong_t
)i
.smbip_addr
);
993 oprintf(fp
, " Interrupt Number: %u\n", i
.smbip_intr
);
994 oprintf(fp
, " Register Spacing: %u\n", i
.smbip_regspacing
);
996 flag_printf(fp
, "Flags", i
.smbip_flags
, sizeof (i
.smbip_flags
) * NBBY
,
997 smbios_ipmi_flag_name
, smbios_ipmi_flag_desc
);
1001 print_extprocessor(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1004 smbios_processor_ext_t ep
;
1006 if (check_oem(shp
) != 0)
1009 (void) smbios_info_extprocessor(shp
, id
, &ep
);
1011 oprintf(fp
, " Processor: %u\n", ep
.smbpe_processor
);
1012 oprintf(fp
, " FRU: %u\n", ep
.smbpe_fru
);
1013 oprintf(fp
, " Initial APIC ID count: %u\n\n", ep
.smbpe_n
);
1015 for (i
= 0; i
< ep
.smbpe_n
; i
++) {
1016 oprintf(fp
, " Logical Strand %u: Initial APIC ID: %u\n", i
,
1017 ep
.smbpe_apicid
[i
]);
1022 print_extport(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1024 smbios_port_ext_t epo
;
1026 if (check_oem(shp
) != 0)
1029 (void) smbios_info_extport(shp
, id
, &epo
);
1031 oprintf(fp
, " Chassis Handle: %u\n", epo
.smbporte_chassis
);
1032 oprintf(fp
, " Port Connector Handle: %u\n", epo
.smbporte_port
);
1033 oprintf(fp
, " Device Type: %u\n", epo
.smbporte_dtype
);
1034 oprintf(fp
, " Device Handle: %u\n", epo
.smbporte_devhdl
);
1035 oprintf(fp
, " PHY: %u\n", epo
.smbporte_phy
);
1039 print_pciexrc(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1041 smbios_pciexrc_t pcie
;
1043 if (check_oem(shp
) != 0)
1046 (void) smbios_info_pciexrc(shp
, id
, &pcie
);
1048 oprintf(fp
, " Component ID: %u\n", pcie
.smbpcie_bb
);
1049 oprintf(fp
, " BDF: 0x%x\n", pcie
.smbpcie_bdf
);
1053 print_extmemarray(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1055 smbios_memarray_ext_t em
;
1057 if (check_oem(shp
) != 0)
1060 (void) smbios_info_extmemarray(shp
, id
, &em
);
1062 oprintf(fp
, " Physical Memory Array Handle: %u\n", em
.smbmae_ma
);
1063 oprintf(fp
, " Component Parent Handle: %u\n", em
.smbmae_comp
);
1064 oprintf(fp
, " BDF: 0x%x\n", em
.smbmae_bdf
);
1068 print_extmemdevice(smbios_hdl_t
*shp
, id_t id
, FILE *fp
)
1071 smbios_memdevice_ext_t emd
;
1073 if (check_oem(shp
) != 0)
1076 (void) smbios_info_extmemdevice(shp
, id
, &emd
);
1078 oprintf(fp
, " Memory Device Handle: %u\n", emd
.smbmdeve_md
);
1079 oprintf(fp
, " DRAM Channel: %u\n", emd
.smbmdeve_drch
);
1080 oprintf(fp
, " Number of Chip Selects: %u\n", emd
.smbmdeve_ncs
);
1082 for (i
= 0; i
< emd
.smbmdeve_ncs
; i
++) {
1083 oprintf(fp
, " Chip Select: %u\n", emd
.smbmdeve_cs
[i
]);
1088 print_struct(smbios_hdl_t
*shp
, const smbios_struct_t
*sp
, void *fp
)
1094 if (opt_t
!= -1 && opt_t
!= sp
->smbstr_type
)
1095 return (0); /* skip struct if type doesn't match -t */
1097 if (!opt_O
&& (sp
->smbstr_type
== SMB_TYPE_MEMCTL
||
1098 sp
->smbstr_type
== SMB_TYPE_MEMMOD
))
1099 return (0); /* skip struct if type is obsolete */
1101 if (g_hdr
++ == 0 || !opt_s
)
1102 oprintf(fp
, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE");
1104 oprintf(fp
, "%-5u %-4lu",
1105 (uint_t
)sp
->smbstr_id
, (ulong_t
)sp
->smbstr_size
);
1107 if ((s
= smbios_type_name(sp
->smbstr_type
)) != NULL
)
1108 oprintf(fp
, " %s (type %u)", s
, sp
->smbstr_type
);
1109 else if (sp
->smbstr_type
> SMB_TYPE_OEM_LO
&&
1110 sp
->smbstr_type
< SMB_TYPE_OEM_HI
)
1111 oprintf(fp
, " %s+%u (type %u)", "SMB_TYPE_OEM_LO",
1112 sp
->smbstr_type
- SMB_TYPE_OEM_LO
, sp
->smbstr_type
);
1114 oprintf(fp
, " %u", sp
->smbstr_type
);
1116 if ((s
= smbios_type_desc(sp
->smbstr_type
)) != NULL
)
1117 oprintf(fp
, " (%s)\n", s
);
1122 return (0); /* only print header line if -s specified */
1124 if (smbios_info_common(shp
, sp
->smbstr_id
, &info
) == 0) {
1126 print_common(&info
, fp
);
1129 switch (sp
->smbstr_type
) {
1132 print_bios(shp
, fp
);
1134 case SMB_TYPE_SYSTEM
:
1136 print_system(shp
, fp
);
1138 case SMB_TYPE_BASEBOARD
:
1140 print_bboard(shp
, sp
->smbstr_id
, fp
);
1142 case SMB_TYPE_CHASSIS
:
1144 print_chassis(shp
, sp
->smbstr_id
, fp
);
1146 case SMB_TYPE_PROCESSOR
:
1148 print_processor(shp
, sp
->smbstr_id
, fp
);
1150 case SMB_TYPE_CACHE
:
1152 print_cache(shp
, sp
->smbstr_id
, fp
);
1156 print_port(shp
, sp
->smbstr_id
, fp
);
1160 print_slot(shp
, sp
->smbstr_id
, fp
);
1162 case SMB_TYPE_OBDEVS
:
1164 print_obdevs(shp
, sp
->smbstr_id
, fp
);
1166 case SMB_TYPE_OEMSTR
:
1167 case SMB_TYPE_SYSCONFSTR
:
1169 print_strtab(shp
, sp
->smbstr_id
, fp
);
1173 print_lang(shp
, sp
->smbstr_id
, fp
);
1175 case SMB_TYPE_EVENTLOG
:
1177 print_evlog(shp
, sp
->smbstr_id
, fp
);
1179 case SMB_TYPE_MEMARRAY
:
1181 print_memarray(shp
, sp
->smbstr_id
, fp
);
1183 case SMB_TYPE_MEMDEVICE
:
1185 print_memdevice(shp
, sp
->smbstr_id
, fp
);
1187 case SMB_TYPE_MEMARRAYMAP
:
1189 print_memarrmap(shp
, sp
->smbstr_id
, fp
);
1191 case SMB_TYPE_MEMDEVICEMAP
:
1193 print_memdevmap(shp
, sp
->smbstr_id
, fp
);
1195 case SMB_TYPE_SECURITY
:
1197 print_hwsec(shp
, fp
);
1201 print_boot(shp
, fp
);
1203 case SMB_TYPE_IPMIDEV
:
1205 print_ipmi(shp
, fp
);
1207 case SMB_TYPE_OBDEVEXT
:
1209 print_obdevs_ext(shp
, sp
->smbstr_id
, fp
);
1211 case SUN_OEM_EXT_PROCESSOR
:
1213 print_extprocessor(shp
, sp
->smbstr_id
, fp
);
1215 case SUN_OEM_EXT_PORT
:
1217 print_extport(shp
, sp
->smbstr_id
, fp
);
1219 case SUN_OEM_PCIEXRC
:
1221 print_pciexrc(shp
, sp
->smbstr_id
, fp
);
1223 case SUN_OEM_EXT_MEMARRAY
:
1225 print_extmemarray(shp
, sp
->smbstr_id
, fp
);
1227 case SUN_OEM_EXT_MEMDEVICE
:
1229 print_extmemdevice(shp
, sp
->smbstr_id
, fp
);
1236 print_bytes(sp
->smbstr_data
, sp
->smbstr_size
, fp
);
1244 getu16(const char *name
, const char *s
)
1250 val
= strtoull(s
, &p
, 0);
1252 if (errno
!= 0 || p
== s
|| *p
!= '\0' || val
> UINT16_MAX
) {
1253 (void) fprintf(stderr
, "%s: invalid %s argument -- %s\n",
1258 return ((uint16_t)val
);
1262 getstype(const char *name
, const char *s
)
1267 for (t
= 0; t
< SMB_TYPE_OEM_LO
; t
++) {
1268 if ((ts
= smbios_type_name(t
)) != NULL
&& strcmp(s
, ts
) == 0)
1272 (void) fprintf(stderr
, "%s: invalid %s argument -- %s\n",
1282 (void) fprintf(fp
, "Usage: %s "
1283 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname
);
1286 "\t-B disable header validation for broken BIOSes\n"
1287 "\t-e display SMBIOS entry point information\n"
1288 "\t-i display only the specified structure\n"
1289 "\t-O display obsolete structure types\n"
1290 "\t-s display only a summary of structure identifiers and types\n"
1291 "\t-t display only the specified structure type\n"
1292 "\t-w write the raw data to the specified file\n"
1293 "\t-x display raw data for structures\n");
1295 return (SMBIOS_USAGE
);
1299 main(int argc
, char *argv
[])
1301 const char *ifile
= NULL
;
1302 const char *ofile
= NULL
;
1310 if ((p
= strrchr(argv
[0], '/')) == NULL
)
1315 while (optind
< argc
) {
1316 while ((c
= getopt(argc
, argv
, "Bei:Ost:w:xZ")) != EOF
) {
1319 oflags
|= SMB_O_NOCKSUM
| SMB_O_NOVERS
;
1325 opt_i
= getu16("struct ID", optarg
);
1334 if (isdigit(optarg
[0]))
1335 opt_t
= getu16("struct type", optarg
);
1337 opt_t
= getstype("struct type", optarg
);
1346 oflags
|= SMB_O_ZIDS
; /* undocumented */
1349 return (usage(stderr
));
1353 if (optind
< argc
) {
1354 if (ifile
!= NULL
) {
1355 (void) fprintf(stderr
, "%s: illegal "
1356 "argument -- %s\n", g_pname
, argv
[optind
]);
1357 return (SMBIOS_USAGE
);
1359 ifile
= argv
[optind
++];
1363 if ((shp
= smbios_open(ifile
, SMB_VERSION
, oflags
, &err
)) == NULL
) {
1364 (void) fprintf(stderr
, "%s: failed to load SMBIOS: %s\n",
1365 g_pname
, smbios_errmsg(err
));
1366 return (SMBIOS_ERROR
);
1369 if (opt_i
== -1 && opt_t
== -1 && opt_e
== 0 &&
1370 smbios_truncated(shp
))
1371 (void) fprintf(stderr
, "%s: SMBIOS table is truncated\n",
1374 if (ofile
!= NULL
) {
1375 if ((fd
= open(ofile
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666)) == -1) {
1376 (void) fprintf(stderr
, "%s: failed to open %s: %s\n",
1377 g_pname
, ofile
, strerror(errno
));
1379 } else if (smbios_write(shp
, fd
) != 0) {
1380 (void) fprintf(stderr
, "%s: failed to write %s: %s\n",
1381 g_pname
, ofile
, smbios_errmsg(smbios_errno(shp
)));
1389 print_smbios(shp
, stdout
);
1391 return (SMBIOS_SUCCESS
);
1394 if (opt_O
&& (opt_i
!= -1 || opt_t
!= -1))
1395 opt_O
++; /* -i or -t imply displaying obsolete records */
1398 err
= smbios_lookup_id(shp
, opt_i
, &s
);
1400 err
= smbios_iter(shp
, print_struct
, stdout
);
1403 (void) fprintf(stderr
, "%s: failed to access SMBIOS: %s\n",
1404 g_pname
, smbios_errmsg(smbios_errno(shp
)));
1406 return (SMBIOS_ERROR
);
1410 (void) print_struct(shp
, &s
, stdout
);
1413 return (SMBIOS_SUCCESS
);