1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. 24 * Copyright (c) 2017, Joyent, Inc. 25 * Copyright 2021 Oxide Computer Company 26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #include <sys/sysmacros.h> 31 #include <sys/param.h> 32 33 #include <smbios.h> 34 #include <alloca.h> 35 #include <limits.h> 36 #include <unistd.h> 37 #include <strings.h> 38 #include <stdlib.h> 39 #include <stdarg.h> 40 #include <stdio.h> 41 #include <fcntl.h> 42 #include <errno.h> 43 #include <ctype.h> 44 #include <libjedec.h> 45 46 #define SMBIOS_SUCCESS 0 47 #define SMBIOS_ERROR 1 48 #define SMBIOS_USAGE 2 49 50 static const char *g_pname; 51 static int g_hdr; 52 53 static int opt_e; 54 static int opt_i = -1; 55 static int opt_O; 56 static int opt_s; 57 static int opt_t = -1; 58 static int opt_x; 59 60 static boolean_t 61 smbios_vergteq(smbios_version_t *v, uint_t major, uint_t minor) 62 { 63 if (v->smbv_major > major) 64 return (B_TRUE); 65 if (v->smbv_major == major && 66 v->smbv_minor >= minor) 67 return (B_TRUE); 68 return (B_FALSE); 69 } 70 71 /*PRINTFLIKE2*/ 72 static void 73 smbios_warn(smbios_hdl_t *shp, const char *format, ...) 74 { 75 va_list ap; 76 77 va_start(ap, format); 78 (void) vfprintf(stderr, format, ap); 79 va_end(ap); 80 81 if (shp != NULL) { 82 (void) fprintf(stderr, ": %s", 83 smbios_errmsg(smbios_errno(shp))); 84 } 85 86 (void) fprintf(stderr, "\n"); 87 } 88 89 /*PRINTFLIKE2*/ 90 static void 91 oprintf(FILE *fp, const char *format, ...) 92 { 93 va_list ap; 94 95 va_start(ap, format); 96 (void) vfprintf(fp, format, ap); 97 va_end(ap); 98 } 99 100 /*PRINTFLIKE3*/ 101 static void 102 desc_printf(const char *d, FILE *fp, const char *format, ...) 103 { 104 va_list ap; 105 106 va_start(ap, format); 107 (void) vfprintf(fp, format, ap); 108 va_end(ap); 109 110 if (d != NULL) 111 (void) fprintf(fp, " (%s)\n", d); 112 else 113 (void) fprintf(fp, "\n"); 114 } 115 116 static void 117 flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits, 118 const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t)) 119 { 120 size_t i; 121 122 oprintf(fp, " %s: 0x%x\n", s, flags); 123 124 for (i = 0; i < bits; i++) { 125 uint_t f = 1 << i; 126 const char *n; 127 128 if (!(flags & f)) 129 continue; 130 131 if ((n = flag_name(f)) != NULL) 132 desc_printf(flag_desc(f), fp, "\t%s", n); 133 else 134 desc_printf(flag_desc(f), fp, "\t0x%x", f); 135 } 136 } 137 138 static void 139 flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits, 140 const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t)) 141 { 142 size_t i; 143 144 oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags); 145 146 for (i = 0; i < bits; i++) { 147 u_longlong_t f = 1ULL << i; 148 const char *n; 149 150 if (!(flags & f)) 151 continue; 152 153 if ((n = flag_name(f)) != NULL) 154 desc_printf(flag_desc(f), fp, "\t%s", n); 155 else 156 desc_printf(flag_desc(f), fp, "\t0x%llx", f); 157 } 158 } 159 160 static void 161 id_printf(FILE *fp, const char *s, id_t id) 162 { 163 switch (id) { 164 case SMB_ID_NONE: 165 oprintf(fp, "%sNone\n", s); 166 break; 167 case SMB_ID_NOTSUP: 168 oprintf(fp, "%sNot Supported\n", s); 169 break; 170 default: 171 oprintf(fp, "%s%u\n", s, (uint_t)id); 172 } 173 } 174 175 static void 176 jedec_print(FILE *fp, const char *desc, uint_t id) 177 { 178 const char *name; 179 uint_t cont, vendor; 180 181 /* 182 * SMBIOS encodes data in the way that the underlying memory standard 183 * does. In this case, the upper byte indicates the vendor that we care 184 * about while the lower byte indicates the number of continuations that 185 * are needed. libjedec indexes this based on zero (e.g. table 1 is zero 186 * continuations), which is how the spec encodes it. We add one so that 187 * we can match how the spec describes it. 188 */ 189 vendor = id >> 8; 190 cont = id & 0x7f; 191 name = libjedec_vendor_string(cont, vendor); 192 if (name == NULL) { 193 oprintf(fp, " %s: Bank: 0x%x Vendor: 0x%x\n", desc, cont + 1, 194 vendor); 195 } else { 196 oprintf(fp, " %s: Bank: 0x%x Vendor: 0x%x (%s)\n", desc, 197 cont + 1, vendor, name); 198 } 199 } 200 201 /* 202 * Print a 128-bit data as a series of 16 hex digits. 203 */ 204 static void 205 u128_print(FILE *fp, const char *desc, const uint8_t *data) 206 { 207 uint_t i; 208 209 oprintf(fp, "%s: ", desc); 210 for (i = 0; i < 16; i++) { 211 oprintf(fp, " %02x", data[i]); 212 } 213 oprintf(fp, "\n"); 214 } 215 216 /* 217 * Print a string that came from an SMBIOS table. We do this character by 218 * character so we can potentially escape strings. 219 */ 220 static void 221 str_print_label(FILE *fp, const char *header, const char *str, boolean_t label) 222 { 223 const char *c; 224 225 oprintf(fp, header); 226 if (label) { 227 oprintf(fp, ": "); 228 } 229 230 for (c = str; *c != '\0'; c++) { 231 if (isprint(*c)) { 232 oprintf(fp, "%c", *c); 233 } else { 234 oprintf(fp, "\\x%02x", *c); 235 } 236 } 237 238 oprintf(fp, "\n"); 239 } 240 241 static void 242 str_print_nolabel(FILE *fp, const char *ws, const char *str) 243 { 244 return (str_print_label(fp, ws, str, B_FALSE)); 245 } 246 247 static void 248 str_print(FILE *fp, const char *header, const char *str) 249 { 250 return (str_print_label(fp, header, str, B_TRUE)); 251 } 252 253 static int 254 check_oem(smbios_hdl_t *shp) 255 { 256 int i; 257 int cnt; 258 int rv; 259 id_t oem_id; 260 smbios_struct_t s; 261 const char **oem_str; 262 263 rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s); 264 if (rv != 0) { 265 return (-1); 266 } 267 268 oem_id = s.smbstr_id; 269 270 cnt = smbios_info_strtab(shp, oem_id, 0, NULL); 271 if (cnt > 0) { 272 oem_str = alloca(sizeof (char *) * cnt); 273 (void) smbios_info_strtab(shp, oem_id, cnt, oem_str); 274 275 for (i = 0; i < cnt; i++) { 276 if (strncmp(oem_str[i], SMB_PRMS1, 277 strlen(SMB_PRMS1) + 1) == 0) { 278 return (0); 279 } 280 } 281 } 282 283 return (-1); 284 } 285 286 static void 287 print_smbios_21(smbios_21_entry_t *ep, FILE *fp) 288 { 289 int i; 290 291 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 292 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor), 293 ep->smbe_eanchor); 294 295 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum); 296 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen); 297 oprintf(fp, "Entry Point Version: %u.%u\n", 298 ep->smbe_major, ep->smbe_minor); 299 oprintf(fp, "Max Structure Size: %u\n", ep->smbe_maxssize); 300 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision); 301 302 oprintf(fp, "Entry Point Revision Data:"); 303 for (i = 0; i < sizeof (ep->smbe_format); i++) 304 oprintf(fp, " 0x%02x", ep->smbe_format[i]); 305 oprintf(fp, "\n"); 306 307 oprintf(fp, "Intermediate Anchor Tag: %*.*s\n", 308 (int)sizeof (ep->smbe_ianchor), (int)sizeof (ep->smbe_ianchor), 309 ep->smbe_ianchor); 310 311 oprintf(fp, "Intermediate Checksum: 0x%x\n", ep->smbe_icksum); 312 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen); 313 oprintf(fp, "Structure Table Address: 0x%x\n", ep->smbe_staddr); 314 oprintf(fp, "Structure Table Entries: %u\n", ep->smbe_stnum); 315 oprintf(fp, "DMI BCD Revision: 0x%x\n", ep->smbe_bcdrev); 316 } 317 318 static void 319 print_smbios_30(smbios_30_entry_t *ep, FILE *fp) 320 { 321 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 322 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor), 323 ep->smbe_eanchor); 324 325 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum); 326 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen); 327 oprintf(fp, "SMBIOS Version: %u.%u\n", 328 ep->smbe_major, ep->smbe_minor); 329 oprintf(fp, "SMBIOS DocRev: 0x%x\n", ep->smbe_docrev); 330 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision); 331 332 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen); 333 oprintf(fp, "Structure Table Address: 0x%" PRIx64 "\n", 334 ep->smbe_staddr); 335 } 336 337 static void 338 print_smbios(smbios_hdl_t *shp, FILE *fp) 339 { 340 smbios_entry_t ep; 341 342 switch (smbios_info_smbios(shp, &ep)) { 343 case SMBIOS_ENTRY_POINT_21: 344 print_smbios_21(&ep.ep21, fp); 345 break; 346 case SMBIOS_ENTRY_POINT_30: 347 print_smbios_30(&ep.ep30, fp); 348 break; 349 } 350 } 351 352 static void 353 print_common(const smbios_info_t *ip, FILE *fp) 354 { 355 if (ip->smbi_manufacturer[0] != '\0') 356 str_print(fp, " Manufacturer", ip->smbi_manufacturer); 357 if (ip->smbi_product[0] != '\0') 358 str_print(fp, " Product", ip->smbi_product); 359 if (ip->smbi_version[0] != '\0') 360 str_print(fp, " Version", ip->smbi_version); 361 if (ip->smbi_serial[0] != '\0') 362 str_print(fp, " Serial Number", ip->smbi_serial); 363 if (ip->smbi_asset[0] != '\0') 364 str_print(fp, " Asset Tag", ip->smbi_asset); 365 if (ip->smbi_location[0] != '\0') 366 str_print(fp, " Location Tag", ip->smbi_location); 367 if (ip->smbi_part[0] != '\0') 368 str_print(fp, " Part Number", ip->smbi_part); 369 } 370 371 static void 372 print_bios(smbios_hdl_t *shp, FILE *fp) 373 { 374 smbios_bios_t b; 375 376 (void) smbios_info_bios(shp, &b); 377 378 str_print(fp, " Vendor", b.smbb_vendor); 379 str_print(fp, " Version String", b.smbb_version); 380 str_print(fp, " Release Date", b.smbb_reldate); 381 oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment); 382 oprintf(fp, " ROM Size: %" PRIu64 " bytes\n", b.smbb_extromsize); 383 oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize); 384 385 flag64_printf(fp, "Characteristics", 386 b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY, 387 smbios_bios_flag_name, smbios_bios_flag_desc); 388 389 if (b.smbb_nxcflags > SMB_BIOSXB_1) { 390 flag_printf(fp, "Characteristics Extension Byte 1", 391 b.smbb_xcflags[SMB_BIOSXB_1], 392 sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY, 393 smbios_bios_xb1_name, smbios_bios_xb1_desc); 394 } 395 396 if (b.smbb_nxcflags > SMB_BIOSXB_2) { 397 flag_printf(fp, "Characteristics Extension Byte 2", 398 b.smbb_xcflags[SMB_BIOSXB_2], 399 sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY, 400 smbios_bios_xb2_name, smbios_bios_xb2_desc); 401 } 402 403 if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) { 404 oprintf(fp, " Version Number: %u.%u\n", 405 b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor); 406 } 407 408 /* 409 * If the major and minor versions are 0xff then that indicates that the 410 * embedded controller does not exist. 411 */ 412 if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN && 413 b.smbb_ecfwv.smbv_major != 0xff && 414 b.smbb_ecfwv.smbv_minor != 0xff) { 415 oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n", 416 b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor); 417 } 418 } 419 420 static void 421 print_system(smbios_hdl_t *shp, FILE *fp) 422 { 423 smbios_system_t s; 424 uint_t i; 425 426 (void) smbios_info_system(shp, &s); 427 428 oprintf(fp, " UUID: "); 429 for (i = 0; i < s.smbs_uuidlen; i++) { 430 oprintf(fp, "%02x", s.smbs_uuid[i]); 431 if (i == 3 || i == 5 || i == 7 || i == 9) 432 oprintf(fp, "-"); 433 } 434 oprintf(fp, "\n"); 435 436 desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup), 437 fp, " Wake-Up Event: 0x%x", s.smbs_wakeup); 438 439 str_print(fp, " SKU Number", s.smbs_sku); 440 str_print(fp, " Family", s.smbs_family); 441 } 442 443 static void 444 print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp) 445 { 446 smbios_bboard_t b; 447 int chdl_cnt; 448 449 (void) smbios_info_bboard(shp, id, &b); 450 451 oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis); 452 453 flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY, 454 smbios_bboard_flag_name, smbios_bboard_flag_desc); 455 456 desc_printf(smbios_bboard_type_desc(b.smbb_type), 457 fp, " Board Type: 0x%x", b.smbb_type); 458 459 chdl_cnt = b.smbb_contn; 460 if (chdl_cnt != 0) { 461 id_t *chdl; 462 uint16_t hdl; 463 int i, n, cnt; 464 465 chdl = alloca(chdl_cnt * sizeof (id_t)); 466 cnt = smbios_info_contains(shp, id, chdl_cnt, chdl); 467 if (cnt > SMB_CONT_MAX) 468 return; 469 n = MIN(chdl_cnt, cnt); 470 471 oprintf(fp, "\n"); 472 for (i = 0; i < n; i++) { 473 hdl = (uint16_t)chdl[i]; 474 oprintf(fp, " Contained Handle: %u\n", hdl); 475 } 476 } 477 } 478 479 static void 480 print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp) 481 { 482 smbios_chassis_t c; 483 smbios_chassis_entry_t *elts; 484 uint_t nelts, i; 485 486 (void) smbios_info_chassis(shp, id, &c); 487 488 oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata); 489 str_print(fp, " SKU Number", 490 c.smbc_sku[0] == '\0' ? "<unknown>" : c.smbc_sku); 491 oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N"); 492 493 desc_printf(smbios_chassis_type_desc(c.smbc_type), 494 fp, " Chassis Type: 0x%x", c.smbc_type); 495 496 desc_printf(smbios_chassis_state_desc(c.smbc_bustate), 497 fp, " Boot-Up State: 0x%x", c.smbc_bustate); 498 499 desc_printf(smbios_chassis_state_desc(c.smbc_psstate), 500 fp, " Power Supply State: 0x%x", c.smbc_psstate); 501 502 desc_printf(smbios_chassis_state_desc(c.smbc_thstate), 503 fp, " Thermal State: 0x%x", c.smbc_thstate); 504 505 oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight); 506 oprintf(fp, " Power Cords: %u\n", c.smbc_cords); 507 508 oprintf(fp, " Element Records: %u\n", c.smbc_elems); 509 510 if (c.smbc_elems == 0) { 511 return; 512 } 513 514 if (smbios_info_chassis_elts(shp, id, &nelts, &elts) != 0) { 515 smbios_warn(shp, "failed to read chassis elements"); 516 return; 517 } 518 519 oprintf(fp, "\n"); 520 521 for (i = 0; i < nelts; i++) { 522 switch (elts[i].smbce_type) { 523 case SMB_CELT_BBOARD: 524 desc_printf(smbios_bboard_type_desc(elts[i].smbce_elt), 525 fp, " Contained SMBIOS Base Board Type: 0x%x", 526 elts[i].smbce_elt); 527 break; 528 case SMB_CELT_SMBIOS: 529 desc_printf(smbios_type_name(elts[i].smbce_elt), fp, 530 " Contained SMBIOS structure Type: %u", 531 elts[i].smbce_elt); 532 break; 533 default: 534 oprintf(fp, " Unknown contained Type: %u/%u\n", 535 elts[i].smbce_type, elts[i].smbce_elt); 536 break; 537 } 538 oprintf(fp, " Minimum number: %u\n", elts[i].smbce_min); 539 oprintf(fp, " Maximum number: %u\n", elts[i].smbce_max); 540 } 541 } 542 543 static void 544 print_processor(smbios_hdl_t *shp, id_t id, FILE *fp) 545 { 546 smbios_processor_t p; 547 uint_t status; 548 549 (void) smbios_info_processor(shp, id, &p); 550 status = SMB_PRSTATUS_STATUS(p.smbp_status); 551 552 desc_printf(smbios_processor_family_desc(p.smbp_family), 553 fp, " Family: %u", p.smbp_family); 554 555 oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid); 556 557 desc_printf(smbios_processor_type_desc(p.smbp_type), 558 fp, " Type: %u", p.smbp_type); 559 560 desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade), 561 fp, " Socket Upgrade: %u", p.smbp_upgrade); 562 563 oprintf(fp, " Socket Status: %s\n", 564 SMB_PRSTATUS_PRESENT(p.smbp_status) ? 565 "Populated" : "Not Populated"); 566 567 desc_printf(smbios_processor_status_desc(status), 568 fp, " Processor Status: %u", status); 569 570 if (SMB_PRV_LEGACY(p.smbp_voltage)) { 571 oprintf(fp, " Supported Voltages:"); 572 switch (p.smbp_voltage) { 573 case SMB_PRV_5V: 574 oprintf(fp, " 5.0V"); 575 break; 576 case SMB_PRV_33V: 577 oprintf(fp, " 3.3V"); 578 break; 579 case SMB_PRV_29V: 580 oprintf(fp, " 2.9V"); 581 break; 582 } 583 oprintf(fp, "\n"); 584 } else { 585 oprintf(fp, " Supported Voltages: %.1fV\n", 586 (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10); 587 } 588 589 if (p.smbp_corecount != 0) { 590 oprintf(fp, " Core Count: %u\n", p.smbp_corecount); 591 } else { 592 oprintf(fp, " Core Count: Unknown\n"); 593 } 594 595 if (p.smbp_coresenabled != 0) { 596 oprintf(fp, " Cores Enabled: %u\n", p.smbp_coresenabled); 597 } else { 598 oprintf(fp, " Cores Enabled: Unknown\n"); 599 } 600 601 if (p.smbp_threadcount != 0) { 602 oprintf(fp, " Thread Count: %u\n", p.smbp_threadcount); 603 } else { 604 oprintf(fp, " Thread Count: Unknown\n"); 605 } 606 607 if (p.smbp_cflags) { 608 flag_printf(fp, "Processor Characteristics", 609 p.smbp_cflags, sizeof (p.smbp_cflags) * NBBY, 610 smbios_processor_core_flag_name, 611 smbios_processor_core_flag_desc); 612 } 613 614 if (p.smbp_clkspeed != 0) 615 oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed); 616 else 617 oprintf(fp, " External Clock Speed: Unknown\n"); 618 619 if (p.smbp_maxspeed != 0) 620 oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed); 621 else 622 oprintf(fp, " Maximum Speed: Unknown\n"); 623 624 if (p.smbp_curspeed != 0) 625 oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed); 626 else 627 oprintf(fp, " Current Speed: Unknown\n"); 628 629 id_printf(fp, " L1 Cache Handle: ", p.smbp_l1cache); 630 id_printf(fp, " L2 Cache Handle: ", p.smbp_l2cache); 631 id_printf(fp, " L3 Cache Handle: ", p.smbp_l3cache); 632 } 633 634 static void 635 print_cache(smbios_hdl_t *shp, id_t id, FILE *fp) 636 { 637 smbios_cache_t c; 638 639 (void) smbios_info_cache(shp, id, &c); 640 641 oprintf(fp, " Level: %u\n", c.smba_level); 642 oprintf(fp, " Maximum Installed Size: %" PRIu64 " bytes\n", 643 c.smba_maxsize2); 644 645 if (c.smba_size2 != 0) { 646 oprintf(fp, " Installed Size: %" PRIu64 " bytes\n", 647 c.smba_size2); 648 } else { 649 oprintf(fp, " Installed Size: Not Installed\n"); 650 } 651 652 if (c.smba_speed != 0) 653 oprintf(fp, " Speed: %uns\n", c.smba_speed); 654 else 655 oprintf(fp, " Speed: Unknown\n"); 656 657 flag_printf(fp, "Supported SRAM Types", 658 c.smba_stype, sizeof (c.smba_stype) * NBBY, 659 smbios_cache_ctype_name, smbios_cache_ctype_desc); 660 661 desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 662 fp, " Current SRAM Type: 0x%x", c.smba_ctype); 663 664 desc_printf(smbios_cache_ecc_desc(c.smba_etype), 665 fp, " Error Correction Type: %u", c.smba_etype); 666 667 desc_printf(smbios_cache_logical_desc(c.smba_ltype), 668 fp, " Logical Cache Type: %u", c.smba_ltype); 669 670 desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 671 fp, " Associativity: %u", c.smba_assoc); 672 673 desc_printf(smbios_cache_mode_desc(c.smba_mode), 674 fp, " Mode: %u", c.smba_mode); 675 676 desc_printf(smbios_cache_loc_desc(c.smba_location), 677 fp, " Location: %u", c.smba_location); 678 679 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 680 smbios_cache_flag_name, smbios_cache_flag_desc); 681 } 682 683 static void 684 print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 685 { 686 smbios_port_t p; 687 688 (void) smbios_info_port(shp, id, &p); 689 690 str_print(fp, " Internal Reference Designator", p.smbo_iref); 691 str_print(fp, " External Reference Designator", p.smbo_eref); 692 693 desc_printf(smbios_port_conn_desc(p.smbo_itype), 694 fp, " Internal Connector Type: %u", p.smbo_itype); 695 696 desc_printf(smbios_port_conn_desc(p.smbo_etype), 697 fp, " External Connector Type: %u", p.smbo_etype); 698 699 desc_printf(smbios_port_type_desc(p.smbo_ptype), 700 fp, " Port Type: %u", p.smbo_ptype); 701 } 702 703 static void 704 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 705 { 706 smbios_slot_t s; 707 smbios_version_t v; 708 709 (void) smbios_info_slot(shp, id, &s); 710 smbios_info_smbios_version(shp, &v); 711 712 str_print(fp, " Reference Designator", s.smbl_name); 713 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 714 715 desc_printf(smbios_slot_type_desc(s.smbl_type), 716 fp, " Type: 0x%x", s.smbl_type); 717 718 desc_printf(smbios_slot_width_desc(s.smbl_width), 719 fp, " Width: 0x%x", s.smbl_width); 720 721 desc_printf(smbios_slot_usage_desc(s.smbl_usage), 722 fp, " Usage: 0x%x", s.smbl_usage); 723 724 desc_printf(smbios_slot_length_desc(s.smbl_length), 725 fp, " Length: 0x%x", s.smbl_length); 726 727 flag_printf(fp, "Slot Characteristics 1", 728 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 729 smbios_slot_ch1_name, smbios_slot_ch1_desc); 730 731 flag_printf(fp, "Slot Characteristics 2", 732 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 733 smbios_slot_ch2_name, smbios_slot_ch2_desc); 734 735 if (check_oem(shp) != 0 && !smbios_vergteq(&v, 2, 6)) 736 return; 737 738 oprintf(fp, " Segment Group: %u\n", s.smbl_sg); 739 oprintf(fp, " Bus Number: %u\n", s.smbl_bus); 740 oprintf(fp, " Device/Function Number: %u/%u\n", s.smbl_df >> 3, 741 s.smbl_df & 0x7); 742 743 if (s.smbl_dbw != 0) { 744 oprintf(fp, " Data Bus Width: %d\n", s.smbl_dbw); 745 } 746 747 if (s.smbl_npeers > 0) { 748 smbios_slot_peer_t *peer; 749 uint_t i, npeers; 750 751 if (smbios_info_slot_peers(shp, id, &npeers, &peer) != 0) { 752 smbios_warn(shp, "failed to read slot peer " 753 "information"); 754 return; 755 } 756 757 for (i = 0; i < npeers; i++) { 758 oprintf(fp, " Slot Peer %u:\n", i); 759 oprintf(fp, " Segment group: %u\n", 760 peer[i].smblp_group); 761 oprintf(fp, " Bus/Device/Function: %u/%u/%u\n", 762 peer[i].smblp_bus, peer[i].smblp_device, 763 peer[i].smblp_function); 764 oprintf(fp, " Electrical width: %u\n", 765 peer[i].smblp_data_width); 766 } 767 768 smbios_info_slot_peers_free(shp, npeers, peer); 769 } 770 771 if (s.smbl_info != 0) { 772 if (s.smbl_type >= SMB_SLT_PCIE && 773 s.smbl_type <= SMB_SLT_PCIEG6P) { 774 oprintf(fp, " PCIe Generation: %d\n", s.smbl_info); 775 } else { 776 oprintf(fp, " Slot Type: 0x%x\n", s.smbl_info); 777 } 778 } 779 780 if (s.smbl_pwidth != 0) { 781 desc_printf(smbios_slot_width_desc(s.smbl_pwidth), 782 fp, " Physical Width: 0x%x", s.smbl_pwidth); 783 } 784 785 if (s.smbl_pitch != 0) { 786 oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100, 787 s.smbl_pitch % 100); 788 } 789 790 /* 791 * The slot height was introduced in SMBIOS 3.5. However, a value of 792 * zero here does not mean that it is unknown, but rather that the 793 * concept is not applicable. Therefore we cannot use a standard check 794 * against zero for this and instead use the version. 795 */ 796 if (smbios_vergteq(&v, 3, 5)) { 797 desc_printf(smbios_slot_height_desc(s.smbl_height), fp, 798 " Height: 0x%x", s.smbl_height); 799 } else { 800 oprintf(fp, " Height: unknown\n"); 801 } 802 } 803 804 static void 805 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp) 806 { 807 boolean_t enabled; 808 smbios_obdev_ext_t oe; 809 const char *type; 810 811 (void) smbios_info_obdevs_ext(shp, id, &oe); 812 813 /* 814 * Bit 7 is always whether or not the device is enabled while bits 0:6 815 * are the actual device type. 816 */ 817 enabled = oe.smboe_dtype >> 7; 818 type = smbios_onboard_ext_type_desc(oe.smboe_dtype & 0x7f); 819 820 str_print(fp, " Reference Designator", oe.smboe_name); 821 oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" : 822 "false"); 823 oprintf(fp, " Device Type: %s\n", type); 824 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti); 825 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg); 826 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus); 827 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df); 828 } 829 830 static void 831 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 832 { 833 smbios_obdev_t *argv; 834 int i, argc; 835 836 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 837 argv = alloca(sizeof (smbios_obdev_t) * argc); 838 (void) smbios_info_obdevs(shp, id, argc, argv); 839 for (i = 0; i < argc; i++) 840 str_print_nolabel(fp, " ", argv[i].smbd_name); 841 } 842 } 843 844 static void 845 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 846 { 847 const char **argv; 848 int i, argc; 849 850 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 851 argv = alloca(sizeof (char *) * argc); 852 (void) smbios_info_strtab(shp, id, argc, argv); 853 for (i = 0; i < argc; i++) 854 str_print_nolabel(fp, " ", argv[i]); 855 } 856 } 857 858 static void 859 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 860 { 861 smbios_lang_t l; 862 863 (void) smbios_info_lang(shp, &l); 864 865 str_print(fp, " Current Language", l.smbla_cur); 866 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 867 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 868 oprintf(fp, " Installed Languages:\n"); 869 870 print_strtab(shp, id, fp); 871 } 872 873 /*ARGSUSED*/ 874 static void 875 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 876 { 877 smbios_evlog_t ev; 878 uint32_t i; 879 880 (void) smbios_info_eventlog(shp, &ev); 881 882 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 883 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 884 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 885 886 desc_printf(smbios_evlog_method_desc(ev.smbev_method), 887 fp, " Data Access Method: %u", ev.smbev_method); 888 889 flag_printf(fp, "Log Flags", 890 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 891 smbios_evlog_flag_name, smbios_evlog_flag_desc); 892 893 desc_printf(smbios_evlog_format_desc(ev.smbev_format), 894 fp, " Log Header Format: %u", ev.smbev_format); 895 896 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 897 oprintf(fp, " Data Access Address: "); 898 899 switch (ev.smbev_method) { 900 case SMB_EVM_1x1i_1x1d: 901 case SMB_EVM_2x1i_1x1d: 902 case SMB_EVM_1x2i_1x1d: 903 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 904 ev.smbev_addr.eva_io.evi_iaddr, 905 ev.smbev_addr.eva_io.evi_daddr); 906 break; 907 case SMB_EVM_GPNV: 908 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 909 break; 910 default: 911 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 912 } 913 914 oprintf(fp, " Type Descriptors:\n"); 915 916 for (i = 0; i < ev.smbev_typec; i++) { 917 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 918 ev.smbev_typev[i].smbevt_ltype, 919 ev.smbev_typev[i].smbevt_dtype); 920 } 921 } 922 923 static void 924 print_bytes(const uint8_t *data, size_t size, FILE *fp) 925 { 926 size_t row, rows = P2ROUNDUP(size, 16) / 16; 927 size_t col, cols; 928 929 char buf[17]; 930 uint8_t x; 931 932 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 933 "0123456789abcdef\n"); 934 935 for (row = 0; row < rows; row++) { 936 oprintf(fp, " %#6lx: ", (ulong_t)row * 16); 937 cols = MIN(size - row * 16, 16); 938 939 for (col = 0; col < cols; col++) { 940 if (col % 4 == 0) 941 oprintf(fp, " "); 942 x = *data++; 943 oprintf(fp, "%02x", x); 944 buf[col] = x <= ' ' || x > '~' ? '.' : x; 945 } 946 947 for (; col < 16; col++) { 948 if (col % 4 == 0) 949 oprintf(fp, " "); 950 oprintf(fp, " "); 951 buf[col] = ' '; 952 } 953 954 buf[col] = '\0'; 955 oprintf(fp, " %s\n", buf); 956 } 957 958 oprintf(fp, "\n"); 959 } 960 961 static void 962 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 963 { 964 smbios_memarray_t ma; 965 966 (void) smbios_info_memarray(shp, id, &ma); 967 968 desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 969 fp, " Location: %u", ma.smbma_location); 970 971 desc_printf(smbios_memarray_use_desc(ma.smbma_use), 972 fp, " Use: %u", ma.smbma_use); 973 974 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 975 fp, " ECC: %u", ma.smbma_ecc); 976 977 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 978 id_printf(fp, " Memory Error Data: ", ma.smbma_err); 979 oprintf(fp, " Max Capacity: %llu bytes\n", 980 (u_longlong_t)ma.smbma_size); 981 } 982 983 static void 984 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 985 { 986 smbios_memdevice_t md; 987 988 (void) smbios_info_memdevice(shp, id, &md); 989 990 id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 991 id_printf(fp, " Memory Error Data: ", md.smbmd_error); 992 993 if (md.smbmd_twidth != -1u) 994 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 995 else 996 oprintf(fp, " Total Width: Unknown\n"); 997 998 if (md.smbmd_dwidth != -1u) 999 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 1000 else 1001 oprintf(fp, " Data Width: Unknown\n"); 1002 1003 switch (md.smbmd_size) { 1004 case -1ull: 1005 oprintf(fp, " Size: Unknown\n"); 1006 break; 1007 case 0: 1008 oprintf(fp, " Size: Not Populated\n"); 1009 break; 1010 default: 1011 oprintf(fp, " Size: %llu bytes\n", 1012 (u_longlong_t)md.smbmd_size); 1013 } 1014 1015 desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 1016 fp, " Form Factor: %u", md.smbmd_form); 1017 1018 if (md.smbmd_set == 0) 1019 oprintf(fp, " Set: None\n"); 1020 else if (md.smbmd_set == (uint8_t)-1u) 1021 oprintf(fp, " Set: Unknown\n"); 1022 else 1023 oprintf(fp, " Set: %u\n", md.smbmd_set); 1024 1025 if (md.smbmd_rank != 0) { 1026 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank), 1027 fp, " Rank: %u", md.smbmd_rank); 1028 } else { 1029 oprintf(fp, " Rank: Unknown\n"); 1030 } 1031 1032 desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 1033 fp, " Memory Type: %u", md.smbmd_type); 1034 1035 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 1036 smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 1037 1038 if (md.smbmd_extspeed != 0) { 1039 oprintf(fp, " Speed: %" PRIu64 " MT/s\n", md.smbmd_extspeed); 1040 } else { 1041 oprintf(fp, " Speed: Unknown\n"); 1042 } 1043 1044 if (md.smbmd_extclkspeed != 0) { 1045 oprintf(fp, " Configured Speed: %" PRIu64 " MT/s\n", 1046 md.smbmd_extclkspeed); 1047 } else { 1048 oprintf(fp, " Configured Speed: Unknown\n"); 1049 } 1050 1051 str_print(fp, " Device Locator", md.smbmd_dloc); 1052 str_print(fp, " Bank Locator", md.smbmd_bloc); 1053 1054 if (md.smbmd_minvolt != 0) { 1055 oprintf(fp, " Minimum Voltage: %.2fV\n", 1056 md.smbmd_minvolt / 1000.0); 1057 } else { 1058 oprintf(fp, " Minimum Voltage: Unknown\n"); 1059 } 1060 1061 if (md.smbmd_maxvolt != 0) { 1062 oprintf(fp, " Maximum Voltage: %.2fV\n", 1063 md.smbmd_maxvolt / 1000.0); 1064 } else { 1065 oprintf(fp, " Maximum Voltage: Unknown\n"); 1066 } 1067 1068 if (md.smbmd_confvolt != 0) { 1069 oprintf(fp, " Configured Voltage: %.2fV\n", 1070 md.smbmd_confvolt / 1000.0); 1071 } else { 1072 oprintf(fp, " Configured Voltage: Unknown\n"); 1073 } 1074 1075 if (md.smbmd_memtech != 0) { 1076 desc_printf(smbios_memdevice_memtech_desc(md.smbmd_memtech), 1077 fp, " Memory Technology: %u", md.smbmd_memtech); 1078 } 1079 1080 if (md.smbmd_opcap_flags != 0) { 1081 flag_printf(fp, "Operating Mode Capabilities", 1082 md.smbmd_opcap_flags, sizeof (md.smbmd_opcap_flags) * NBBY, 1083 smbios_memdevice_op_capab_name, 1084 smbios_memdevice_op_capab_desc); 1085 } 1086 1087 if (md.smbmd_firmware_rev[0] != '\0') { 1088 str_print(fp, " Firmware Revision", md.smbmd_firmware_rev); 1089 } 1090 1091 if (md.smbmd_modmfg_id != 0) { 1092 jedec_print(fp, "Module Manufacturer ID", md.smbmd_modmfg_id); 1093 } 1094 1095 if (md.smbmd_modprod_id != 0) { 1096 jedec_print(fp, "Module Product ID", md.smbmd_modprod_id); 1097 } 1098 1099 if (md.smbmd_cntrlmfg_id != 0) { 1100 jedec_print(fp, "Memory Subsystem Controller Manufacturer ID", 1101 md.smbmd_cntrlmfg_id); 1102 } 1103 1104 if (md.smbmd_cntrlprod_id != 0) { 1105 jedec_print(fp, "Memory Subsystem Controller Product ID", 1106 md.smbmd_cntrlprod_id); 1107 } 1108 1109 if (md.smbmd_nvsize == UINT64_MAX) { 1110 oprintf(fp, " Non-volatile Size: Unknown\n"); 1111 } else if (md.smbmd_nvsize != 0) { 1112 oprintf(fp, " Non-volatile Size: %llu bytes\n", 1113 (u_longlong_t)md.smbmd_nvsize); 1114 } 1115 1116 if (md.smbmd_volatile_size == UINT64_MAX) { 1117 oprintf(fp, " Volatile Size: Unknown\n"); 1118 } else if (md.smbmd_volatile_size != 0) { 1119 oprintf(fp, " Volatile Size: %llu bytes\n", 1120 (u_longlong_t)md.smbmd_volatile_size); 1121 } 1122 1123 if (md.smbmd_cache_size == UINT64_MAX) { 1124 oprintf(fp, " Cache Size: Unknown\n"); 1125 } else if (md.smbmd_cache_size != 0) { 1126 oprintf(fp, " Cache Size: %llu bytes\n", 1127 (u_longlong_t)md.smbmd_cache_size); 1128 } 1129 1130 if (md.smbmd_logical_size == UINT64_MAX) { 1131 oprintf(fp, " Logical Size: Unknown\n"); 1132 } else if (md.smbmd_logical_size != 0) { 1133 oprintf(fp, " Logical Size: %llu bytes\n", 1134 (u_longlong_t)md.smbmd_logical_size); 1135 } 1136 } 1137 1138 static void 1139 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 1140 { 1141 smbios_memarrmap_t ma; 1142 1143 (void) smbios_info_memarrmap(shp, id, &ma); 1144 1145 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 1146 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 1147 1148 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 1149 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 1150 } 1151 1152 static void 1153 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 1154 { 1155 smbios_memdevmap_t md; 1156 1157 (void) smbios_info_memdevmap(shp, id, &md); 1158 1159 id_printf(fp, " Memory Device: ", md.smbmdm_device); 1160 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 1161 1162 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 1163 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 1164 1165 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 1166 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 1167 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 1168 } 1169 1170 static void 1171 print_hwsec(smbios_hdl_t *shp, FILE *fp) 1172 { 1173 smbios_hwsec_t h; 1174 1175 (void) smbios_info_hwsec(shp, &h); 1176 1177 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 1178 fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 1179 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 1180 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 1181 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 1182 fp, " Administrator Password Status: %u", h.smbh_adm_ps); 1183 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 1184 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 1185 } 1186 1187 static void 1188 print_vprobe(smbios_hdl_t *shp, id_t id, FILE *fp) 1189 { 1190 smbios_vprobe_t vp; 1191 1192 if (smbios_info_vprobe(shp, id, &vp) != 0) { 1193 smbios_warn(shp, "failed to read voltage probe information"); 1194 return; 1195 } 1196 1197 str_print(fp, " Description", vp.smbvp_description != NULL ? 1198 vp.smbvp_description : "unknown"); 1199 desc_printf(smbios_vprobe_loc_desc(vp.smbvp_location), 1200 fp, " Location: %u", vp.smbvp_location); 1201 desc_printf(smbios_vprobe_status_desc(vp.smbvp_status), 1202 fp, " Status: %u", vp.smbvp_status); 1203 1204 if (vp.smbvp_maxval != SMB_PROBE_UNKNOWN_VALUE) { 1205 oprintf(fp, " Maximum Possible Voltage: %u mV\n", 1206 vp.smbvp_maxval); 1207 } else { 1208 oprintf(fp, " Maximum Possible Voltage: unknown\n"); 1209 } 1210 1211 if (vp.smbvp_minval != SMB_PROBE_UNKNOWN_VALUE) { 1212 oprintf(fp, " Minimum Possible Voltage: %u mV\n", 1213 vp.smbvp_minval); 1214 } else { 1215 oprintf(fp, " Minimum Possible Voltage: unknown\n"); 1216 } 1217 1218 if (vp.smbvp_resolution != SMB_PROBE_UNKNOWN_VALUE) { 1219 oprintf(fp, " Probe Resolution: %u.%u mV\n", 1220 vp.smbvp_resolution / 10, 1221 vp.smbvp_resolution % 10); 1222 } else { 1223 oprintf(fp, " Probe Resolution: unknown\n"); 1224 } 1225 1226 if (vp.smbvp_tolerance != SMB_PROBE_UNKNOWN_VALUE) { 1227 oprintf(fp, " Probe Tolerance: +/-%u mV\n", 1228 vp.smbvp_tolerance); 1229 } else { 1230 oprintf(fp, " Probe Tolerance: unknown\n"); 1231 } 1232 1233 if (vp.smbvp_accuracy != SMB_PROBE_UNKNOWN_VALUE) { 1234 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n", 1235 vp.smbvp_accuracy / 100, 1236 vp.smbvp_accuracy % 100); 1237 } else { 1238 oprintf(fp, " Probe Accuracy: unknown\n"); 1239 } 1240 1241 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", vp.smbvp_oem); 1242 1243 if (vp.smbvp_nominal != SMB_PROBE_UNKNOWN_VALUE) { 1244 oprintf(fp, " Probe Nominal Value: %u mV\n", vp.smbvp_nominal); 1245 } else { 1246 oprintf(fp, " Probe Nominal Value: unknown\n"); 1247 } 1248 } 1249 1250 static void 1251 print_cooldev(smbios_hdl_t *shp, id_t id, FILE *fp) 1252 { 1253 smbios_cooldev_t cd; 1254 1255 if (smbios_info_cooldev(shp, id, &cd) != 0) { 1256 smbios_warn(shp, "failed to read cooling device " 1257 "information"); 1258 return; 1259 } 1260 1261 id_printf(fp, " Temperature Probe Handle: ", cd.smbcd_tprobe); 1262 desc_printf(smbios_cooldev_type_desc(cd.smbcd_type), 1263 fp, " Device Type: %u", cd.smbcd_type); 1264 desc_printf(smbios_cooldev_status_desc(cd.smbcd_status), 1265 fp, " Status: %u", cd.smbcd_status); 1266 oprintf(fp, " Cooling Unit Group: %u\n", cd.smbcd_group); 1267 oprintf(fp, " OEM- or BIOS- defined data: 0x%x\n", cd.smbcd_oem); 1268 if (cd.smbcd_nominal != SMB_PROBE_UNKNOWN_VALUE) { 1269 oprintf(fp, " Nominal Speed: %u RPM\n", cd.smbcd_nominal); 1270 } else { 1271 oprintf(fp, " Nominal Speed: unknown\n"); 1272 } 1273 1274 if (cd.smbcd_descr != NULL && cd.smbcd_descr[0] != '\0') { 1275 str_print(fp, " Description", cd.smbcd_descr); 1276 } 1277 } 1278 1279 static void 1280 print_tprobe(smbios_hdl_t *shp, id_t id, FILE *fp) 1281 { 1282 smbios_tprobe_t tp; 1283 1284 if (smbios_info_tprobe(shp, id, &tp) != 0) { 1285 smbios_warn(shp, "failed to read temperature probe " 1286 "information"); 1287 return; 1288 } 1289 1290 str_print(fp, " Description", tp.smbtp_description != NULL ? 1291 tp.smbtp_description : "unknown"); 1292 desc_printf(smbios_tprobe_loc_desc(tp.smbtp_location), 1293 fp, " Location: %u", tp.smbtp_location); 1294 desc_printf(smbios_tprobe_status_desc(tp.smbtp_status), 1295 fp, " Status: %u", tp.smbtp_status); 1296 1297 if (tp.smbtp_maxval != SMB_PROBE_UNKNOWN_VALUE) { 1298 oprintf(fp, " Maximum Possible Temperature: %u.%u C\n", 1299 tp.smbtp_maxval / 10, tp.smbtp_maxval % 10); 1300 } else { 1301 oprintf(fp, " Maximum Possible Temperature: unknown\n"); 1302 } 1303 1304 if (tp.smbtp_minval != SMB_PROBE_UNKNOWN_VALUE) { 1305 oprintf(fp, " Minimum Possible Temperature: %u.%u C\n", 1306 tp.smbtp_minval / 10, tp.smbtp_minval % 10); 1307 } else { 1308 oprintf(fp, " Minimum Possible Temperature: unknown\n"); 1309 } 1310 1311 if (tp.smbtp_resolution != SMB_PROBE_UNKNOWN_VALUE) { 1312 oprintf(fp, " Probe Resolution: %u.%03u C\n", 1313 tp.smbtp_resolution / 1000, 1314 tp.smbtp_resolution % 1000); 1315 } else { 1316 oprintf(fp, " Probe Resolution: unknown\n"); 1317 } 1318 1319 if (tp.smbtp_tolerance != SMB_PROBE_UNKNOWN_VALUE) { 1320 oprintf(fp, " Probe Tolerance: +/-%u.%u C\n", 1321 tp.smbtp_tolerance / 10, tp.smbtp_tolerance % 10); 1322 } else { 1323 oprintf(fp, " Probe Tolerance: unknown\n"); 1324 } 1325 1326 if (tp.smbtp_accuracy != SMB_PROBE_UNKNOWN_VALUE) { 1327 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n", 1328 tp.smbtp_accuracy / 100, 1329 tp.smbtp_accuracy % 100); 1330 } else { 1331 oprintf(fp, " Probe Accuracy: unknown\n"); 1332 } 1333 1334 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", tp.smbtp_oem); 1335 1336 if (tp.smbtp_nominal != SMB_PROBE_UNKNOWN_VALUE) { 1337 oprintf(fp, " Probe Nominal Value: %u.%u C\n", 1338 tp.smbtp_nominal / 10, tp.smbtp_nominal % 10); 1339 } else { 1340 oprintf(fp, " Probe Nominal Value: unknown\n"); 1341 } 1342 } 1343 1344 static void 1345 print_iprobe(smbios_hdl_t *shp, id_t id, FILE *fp) 1346 { 1347 smbios_iprobe_t ip; 1348 1349 if (smbios_info_iprobe(shp, id, &ip) != 0) { 1350 smbios_warn(shp, "failed to read current probe information"); 1351 return; 1352 } 1353 1354 str_print(fp, " Description", ip.smbip_description != NULL ? 1355 ip.smbip_description : "unknown"); 1356 desc_printf(smbios_iprobe_loc_desc(ip.smbip_location), 1357 fp, " Location: %u", ip.smbip_location); 1358 desc_printf(smbios_iprobe_status_desc(ip.smbip_status), 1359 fp, " Status: %u", ip.smbip_status); 1360 1361 if (ip.smbip_maxval != SMB_PROBE_UNKNOWN_VALUE) { 1362 oprintf(fp, " Maximum Possible Current: %u mA\n", 1363 ip.smbip_maxval); 1364 } else { 1365 oprintf(fp, " Maximum Possible Current: unknown\n"); 1366 } 1367 1368 if (ip.smbip_minval != SMB_PROBE_UNKNOWN_VALUE) { 1369 oprintf(fp, " Minimum Possible Current: %u mA\n", 1370 ip.smbip_minval); 1371 } else { 1372 oprintf(fp, " Minimum Possible Current: unknown\n"); 1373 } 1374 1375 if (ip.smbip_resolution != SMB_PROBE_UNKNOWN_VALUE) { 1376 oprintf(fp, " Probe Resolution: %u.%u mA\n", 1377 ip.smbip_resolution / 10, 1378 ip.smbip_resolution % 10); 1379 } else { 1380 oprintf(fp, " Probe Resolution: unknown\n"); 1381 } 1382 1383 if (ip.smbip_tolerance != SMB_PROBE_UNKNOWN_VALUE) { 1384 oprintf(fp, " Probe Tolerance: +/-%u mA\n", 1385 ip.smbip_tolerance); 1386 } else { 1387 oprintf(fp, " Probe Tolerance: unknown\n"); 1388 } 1389 1390 if (ip.smbip_accuracy != SMB_PROBE_UNKNOWN_VALUE) { 1391 oprintf(fp, " Probe Accuracy: +/-%u.%02u%%\n", 1392 ip.smbip_accuracy / 100, 1393 ip.smbip_accuracy % 100); 1394 } else { 1395 oprintf(fp, " Probe Accuracy: unknown\n"); 1396 } 1397 1398 oprintf(fp, " OEM- or BIOS- defined value: 0x%x\n", ip.smbip_oem); 1399 1400 if (ip.smbip_nominal != SMB_PROBE_UNKNOWN_VALUE) { 1401 oprintf(fp, " Probe Nominal Value: %u mA\n", ip.smbip_nominal); 1402 } else { 1403 oprintf(fp, " Probe Nominal Value: unknown\n"); 1404 } 1405 } 1406 1407 1408 static void 1409 print_boot(smbios_hdl_t *shp, FILE *fp) 1410 { 1411 smbios_boot_t b; 1412 1413 (void) smbios_info_boot(shp, &b); 1414 1415 desc_printf(smbios_boot_desc(b.smbt_status), 1416 fp, " Boot Status Code: 0x%x", b.smbt_status); 1417 1418 if (b.smbt_size != 0) { 1419 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 1420 print_bytes(b.smbt_data, b.smbt_size, fp); 1421 } 1422 } 1423 1424 static void 1425 print_ipmi(smbios_hdl_t *shp, FILE *fp) 1426 { 1427 smbios_ipmi_t i; 1428 1429 (void) smbios_info_ipmi(shp, &i); 1430 1431 desc_printf(smbios_ipmi_type_desc(i.smbip_type), 1432 fp, " Type: %u", i.smbip_type); 1433 1434 oprintf(fp, " BMC IPMI Version: %u.%u\n", 1435 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 1436 1437 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 1438 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 1439 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 1440 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 1441 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 1442 1443 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 1444 smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 1445 } 1446 1447 static void 1448 print_powersup(smbios_hdl_t *shp, id_t id, FILE *fp) 1449 { 1450 smbios_powersup_t p; 1451 1452 if (smbios_info_powersup(shp, id, &p) != 0) { 1453 smbios_warn(shp, "failed to read power supply information"); 1454 return; 1455 } 1456 1457 oprintf(fp, " Power Supply Group: %u\n", p.smbps_group); 1458 if (p.smbps_maxout != 0x8000) { 1459 oprintf(fp, " Maximum Output: %llu mW\n", p.smbps_maxout); 1460 } else { 1461 oprintf(fp, " Maximum Output: unknown\n"); 1462 } 1463 1464 flag_printf(fp, "Characteristics", p.smbps_flags, 1465 sizeof (p.smbps_flags) * NBBY, smbios_powersup_flag_name, 1466 smbios_powersup_flag_desc); 1467 1468 desc_printf(smbios_powersup_input_desc(p.smbps_ivrs), 1469 fp, " Input Voltage Range Switching: %u", p.smbps_ivrs); 1470 desc_printf(smbios_powersup_status_desc(p.smbps_status), 1471 fp, " Status: %u", p.smbps_status); 1472 desc_printf(smbios_powersup_type_desc(p.smbps_pstype), 1473 fp, " Type: %u", p.smbps_pstype); 1474 1475 if (p.smbps_vprobe != 0xffff) { 1476 oprintf(fp, " Voltage Probe Handle: %lu\n", p.smbps_vprobe); 1477 } 1478 1479 if (p.smbps_cooldev != 0xffff) { 1480 oprintf(fp, " Cooling Device Handle: %lu\n", p.smbps_cooldev); 1481 } 1482 1483 if (p.smbps_iprobe != 0xffff) { 1484 oprintf(fp, " Current Probe Handle: %lu\n", p.smbps_iprobe); 1485 } 1486 } 1487 1488 static void 1489 print_processor_info_riscv(smbios_hdl_t *shp, id_t id, FILE *fp) 1490 { 1491 smbios_processor_info_riscv_t rv; 1492 1493 if (smbios_info_processor_riscv(shp, id, &rv) != 0) { 1494 smbios_warn(shp, "failed to read RISC-V specific processor " 1495 "information"); 1496 return; 1497 } 1498 1499 if (rv.smbpirv_boothart != 0) { 1500 oprintf(fp, " Boot Hart\n"); 1501 } 1502 u128_print(fp, " Hart ID", rv.smbpirv_hartid); 1503 u128_print(fp, " Vendor ID", rv.smbpirv_vendid); 1504 u128_print(fp, " Architecture ID", rv.smbpirv_archid); 1505 u128_print(fp, " Implementation ID", rv.smbpirv_machid); 1506 flag64_printf(fp, " ISA", rv.smbpirv_isa, 1507 sizeof (rv.smbpirv_isa) * NBBY, smbios_riscv_isa_name, 1508 smbios_riscv_isa_desc); 1509 flag_printf(fp, " Privilege Levels", rv.smbpirv_privlvl, 1510 sizeof (rv.smbpirv_privlvl) * NBBY, smbios_riscv_priv_name, 1511 smbios_riscv_priv_desc); 1512 u128_print(fp, " Machine Exception Trap Delegation", 1513 rv.smbpirv_metdi); 1514 u128_print(fp, " Machine Interrupt Trap Delegation", 1515 rv.smbpirv_mitdi); 1516 desc_printf(smbios_riscv_width_desc(rv.smbpirv_xlen), 1517 fp, " Register Width: 0x%x", rv.smbpirv_xlen); 1518 desc_printf(smbios_riscv_width_desc(rv.smbpirv_mxlen), 1519 fp, " M-Mode Register Width: 0x%x", rv.smbpirv_mxlen); 1520 desc_printf(smbios_riscv_width_desc(rv.smbpirv_sxlen), 1521 fp, " S-Mode Register Width: 0x%x", rv.smbpirv_sxlen); 1522 desc_printf(smbios_riscv_width_desc(rv.smbpirv_uxlen), 1523 fp, " U-Mode Register Width: 0x%x", rv.smbpirv_uxlen); 1524 } 1525 1526 static void 1527 print_processor_info(smbios_hdl_t *shp, id_t id, FILE *fp) 1528 { 1529 smbios_processor_info_t p; 1530 1531 if (smbios_info_processor_info(shp, id, &p) != 0) { 1532 smbios_warn(shp, "failed to read processor additional " 1533 "information"); 1534 return; 1535 } 1536 1537 id_printf(fp, " Processor Handle: ", p.smbpi_processor); 1538 desc_printf(smbios_processor_info_type_desc(p.smbpi_ptype), 1539 fp, " Processor Type: %u", p.smbpi_ptype); 1540 1541 switch (p.smbpi_ptype) { 1542 case SMB_PROCINFO_T_RV32: 1543 case SMB_PROCINFO_T_RV64: 1544 case SMB_PROCINFO_T_RV128: 1545 oprintf(fp, " RISC-V Additional Processor Information:\n"); 1546 print_processor_info_riscv(shp, id, fp); 1547 break; 1548 default: 1549 break; 1550 } 1551 } 1552 1553 static void 1554 print_battery(smbios_hdl_t *shp, id_t id, FILE *fp) 1555 { 1556 smbios_battery_t bat; 1557 1558 if (smbios_info_battery(shp, id, &bat) != 0) { 1559 smbios_warn(shp, "failed to read battery information"); 1560 return; 1561 } 1562 1563 if (bat.smbb_date != NULL) { 1564 str_print(fp, " Manufacture Date", bat.smbb_date); 1565 } 1566 1567 if (bat.smbb_serial != NULL) { 1568 str_print(fp, " Serial Number", bat.smbb_serial); 1569 } 1570 1571 if (bat.smbb_chem != SMB_BDC_UNKNOWN) { 1572 desc_printf(smbios_battery_chem_desc(bat.smbb_chem), 1573 fp, " Battery Chemistry: 0x%x", bat.smbb_chem); 1574 } 1575 1576 if (bat.smbb_cap != 0) { 1577 oprintf(fp, " Design Capacity: %u mWh\n", bat.smbb_cap); 1578 } else { 1579 oprintf(fp, " Design Capacity: unknown\n"); 1580 } 1581 1582 if (bat.smbb_volt != 0) { 1583 oprintf(fp, " Design Voltage: %u mV\n", bat.smbb_volt); 1584 } else { 1585 oprintf(fp, " Design Voltage: unknown\n"); 1586 } 1587 1588 str_print(fp, " SBDS Version Number", bat.smbb_version); 1589 if (bat.smbb_err != UINT8_MAX) { 1590 oprintf(fp, " Maximum Error: %u\n", bat.smbb_err); 1591 } else { 1592 oprintf(fp, " Maximum Error: unknown\n", bat.smbb_err); 1593 } 1594 oprintf(fp, " SBDS Serial Number: %04x\n", bat.smbb_ssn); 1595 oprintf(fp, " SBDS Manufacture Date: %u-%02u-%02u\n", bat.smbb_syear, 1596 bat.smbb_smonth, bat.smbb_sday); 1597 str_print(fp, " SBDS Device Chemistry", bat.smbb_schem); 1598 oprintf(fp, " OEM-specific Information: 0x%08x\n", bat.smbb_oemdata); 1599 } 1600 1601 static void 1602 print_pointdev(smbios_hdl_t *shp, id_t id, FILE *fp) 1603 { 1604 smbios_pointdev_t pd; 1605 1606 if (smbios_info_pointdev(shp, id, &pd) != 0) { 1607 smbios_warn(shp, "failed to read pointer device information"); 1608 return; 1609 } 1610 1611 desc_printf(smbios_pointdev_type_desc(pd.smbpd_type), 1612 fp, " Type: %u", pd.smbpd_type); 1613 desc_printf(smbios_pointdev_iface_desc(pd.smbpd_iface), 1614 fp, " Interface: %u", pd.smbpd_iface); 1615 oprintf(fp, " Buttons: %u\n", pd.smbpd_nbuttons); 1616 } 1617 1618 static void 1619 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp) 1620 { 1621 int i; 1622 smbios_processor_ext_t ep; 1623 1624 if (check_oem(shp) != 0) 1625 return; 1626 1627 (void) smbios_info_extprocessor(shp, id, &ep); 1628 1629 oprintf(fp, " Processor: %u\n", ep.smbpe_processor); 1630 oprintf(fp, " FRU: %u\n", ep.smbpe_fru); 1631 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n); 1632 1633 for (i = 0; i < ep.smbpe_n; i++) { 1634 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i, 1635 ep.smbpe_apicid[i]); 1636 } 1637 } 1638 1639 static void 1640 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp) 1641 { 1642 smbios_port_ext_t epo; 1643 1644 if (check_oem(shp) != 0) 1645 return; 1646 1647 (void) smbios_info_extport(shp, id, &epo); 1648 1649 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis); 1650 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port); 1651 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype); 1652 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl); 1653 oprintf(fp, " PHY: %u\n", epo.smbporte_phy); 1654 } 1655 1656 static void 1657 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp) 1658 { 1659 smbios_pciexrc_t pcie; 1660 1661 if (check_oem(shp) != 0) 1662 return; 1663 1664 (void) smbios_info_pciexrc(shp, id, &pcie); 1665 1666 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb); 1667 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf); 1668 } 1669 1670 static void 1671 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp) 1672 { 1673 smbios_memarray_ext_t em; 1674 1675 if (check_oem(shp) != 0) 1676 return; 1677 1678 (void) smbios_info_extmemarray(shp, id, &em); 1679 1680 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma); 1681 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp); 1682 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf); 1683 } 1684 1685 static void 1686 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 1687 { 1688 int i; 1689 smbios_memdevice_ext_t emd; 1690 1691 if (check_oem(shp) != 0) 1692 return; 1693 1694 (void) smbios_info_extmemdevice(shp, id, &emd); 1695 1696 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md); 1697 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch); 1698 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs); 1699 1700 for (i = 0; i < emd.smbmdeve_ncs; i++) { 1701 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]); 1702 } 1703 } 1704 1705 static void 1706 print_strprop_info(smbios_hdl_t *shp, id_t id, FILE *fp) 1707 { 1708 smbios_strprop_t prop; 1709 1710 if (smbios_info_strprop(shp, id, &prop) != 0) { 1711 smbios_warn(shp, "failed to read string property information"); 1712 return; 1713 } 1714 1715 desc_printf(smbios_strprop_id_desc(prop.smbsp_prop_id), fp, 1716 " Property ID: %u", prop.smbsp_prop_id); 1717 if (prop.smbsp_prop_val != NULL) { 1718 str_print(fp, " Property Value", prop.smbsp_prop_val); 1719 } 1720 id_printf(fp, " Parent Handle: ", prop.smbsp_parent); 1721 } 1722 1723 static void 1724 print_fwinfo(smbios_hdl_t *shp, id_t id, FILE *fp) 1725 { 1726 smbios_fwinfo_t fw; 1727 smbios_fwinfo_comp_t *comps; 1728 uint_t ncomps, i; 1729 1730 if (smbios_info_fwinfo(shp, id, &fw) != 0) { 1731 smbios_warn(shp, "failed to read firmware inventory"); 1732 return; 1733 } 1734 1735 str_print(fp, " Component Name", fw.smbfw_name); 1736 str_print(fp, " ID", fw.smbfw_id); 1737 str_print(fp, " Release Date", fw.smbfw_reldate); 1738 str_print(fp, " Lowest Supported Version", fw.smbfw_lsv); 1739 desc_printf(smbios_fwinfo_vers_desc(fw.smbfw_vers_fmt), fp, 1740 " Version Format: %u", fw.smbfw_vers_fmt); 1741 desc_printf(smbios_fwinfo_id_desc(fw.smbfw_id_fmt), fp, 1742 " ID Format: %u", fw.smbfw_id_fmt); 1743 if (fw.smbfw_imgsz != UINT64_MAX) { 1744 oprintf(fp, " Image Size: %" PRIu64 "\n", fw.smbfw_imgsz); 1745 } else { 1746 oprintf(fp, " Image Size: unknown\n"); 1747 } 1748 1749 flag_printf(fp, "Characteristics", fw.smbfw_chars, 1750 sizeof (fw.smbfw_chars) * NBBY, smbios_fwinfo_ch_name, 1751 smbios_fwinfo_ch_desc); 1752 1753 desc_printf(smbios_fwinfo_state_desc(fw.smbfw_state), fp, " State: %u", 1754 fw.smbfw_state); 1755 oprintf(fp, " Number of Associated Components: %u\n", 1756 fw.smbfw_ncomps); 1757 1758 if (fw.smbfw_ncomps == 0) 1759 return; 1760 1761 if (smbios_info_fwinfo_comps(shp, id, &ncomps, &comps) == -1) { 1762 smbios_warn(shp, "failed to read firmware inventory " 1763 "components"); 1764 return; 1765 } 1766 1767 oprintf(fp, "\n Component Handles:\n"); 1768 for (i = 0; i < ncomps; i++) { 1769 oprintf(fp, " %ld\n", comps[i]); 1770 } 1771 } 1772 1773 static int 1774 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 1775 { 1776 smbios_info_t info; 1777 int hex = opt_x; 1778 const char *s; 1779 1780 if (opt_t != -1 && opt_t != sp->smbstr_type) 1781 return (0); /* skip struct if type doesn't match -t */ 1782 1783 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 1784 sp->smbstr_type == SMB_TYPE_MEMMOD)) 1785 return (0); /* skip struct if type is obsolete */ 1786 1787 if (g_hdr++ == 0 || !opt_s) 1788 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 1789 1790 oprintf(fp, "%-5u %-4lu", 1791 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 1792 1793 if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 1794 oprintf(fp, " %s (type %u)", s, sp->smbstr_type); 1795 else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 1796 sp->smbstr_type < SMB_TYPE_OEM_HI) 1797 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO", 1798 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type); 1799 else 1800 oprintf(fp, " %u", sp->smbstr_type); 1801 1802 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 1803 oprintf(fp, " (%s)\n", s); 1804 else 1805 oprintf(fp, "\n"); 1806 1807 if (opt_s) 1808 return (0); /* only print header line if -s specified */ 1809 1810 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 1811 oprintf(fp, "\n"); 1812 print_common(&info, fp); 1813 } 1814 1815 switch (sp->smbstr_type) { 1816 case SMB_TYPE_BIOS: 1817 oprintf(fp, "\n"); 1818 print_bios(shp, fp); 1819 break; 1820 case SMB_TYPE_SYSTEM: 1821 oprintf(fp, "\n"); 1822 print_system(shp, fp); 1823 break; 1824 case SMB_TYPE_BASEBOARD: 1825 oprintf(fp, "\n"); 1826 print_bboard(shp, sp->smbstr_id, fp); 1827 break; 1828 case SMB_TYPE_CHASSIS: 1829 oprintf(fp, "\n"); 1830 print_chassis(shp, sp->smbstr_id, fp); 1831 break; 1832 case SMB_TYPE_PROCESSOR: 1833 oprintf(fp, "\n"); 1834 print_processor(shp, sp->smbstr_id, fp); 1835 break; 1836 case SMB_TYPE_CACHE: 1837 oprintf(fp, "\n"); 1838 print_cache(shp, sp->smbstr_id, fp); 1839 break; 1840 case SMB_TYPE_PORT: 1841 oprintf(fp, "\n"); 1842 print_port(shp, sp->smbstr_id, fp); 1843 break; 1844 case SMB_TYPE_SLOT: 1845 oprintf(fp, "\n"); 1846 print_slot(shp, sp->smbstr_id, fp); 1847 break; 1848 case SMB_TYPE_OBDEVS: 1849 oprintf(fp, "\n"); 1850 print_obdevs(shp, sp->smbstr_id, fp); 1851 break; 1852 case SMB_TYPE_OEMSTR: 1853 case SMB_TYPE_SYSCONFSTR: 1854 oprintf(fp, "\n"); 1855 print_strtab(shp, sp->smbstr_id, fp); 1856 break; 1857 case SMB_TYPE_LANG: 1858 oprintf(fp, "\n"); 1859 print_lang(shp, sp->smbstr_id, fp); 1860 break; 1861 case SMB_TYPE_EVENTLOG: 1862 oprintf(fp, "\n"); 1863 print_evlog(shp, sp->smbstr_id, fp); 1864 break; 1865 case SMB_TYPE_MEMARRAY: 1866 oprintf(fp, "\n"); 1867 print_memarray(shp, sp->smbstr_id, fp); 1868 break; 1869 case SMB_TYPE_MEMDEVICE: 1870 oprintf(fp, "\n"); 1871 print_memdevice(shp, sp->smbstr_id, fp); 1872 break; 1873 case SMB_TYPE_MEMARRAYMAP: 1874 oprintf(fp, "\n"); 1875 print_memarrmap(shp, sp->smbstr_id, fp); 1876 break; 1877 case SMB_TYPE_MEMDEVICEMAP: 1878 oprintf(fp, "\n"); 1879 print_memdevmap(shp, sp->smbstr_id, fp); 1880 break; 1881 case SMB_TYPE_BATTERY: 1882 oprintf(fp, "\n"); 1883 print_battery(shp, sp->smbstr_id, fp); 1884 break; 1885 case SMB_TYPE_POINTDEV: 1886 oprintf(fp, "\n"); 1887 print_pointdev(shp, sp->smbstr_id, fp); 1888 break; 1889 case SMB_TYPE_SECURITY: 1890 oprintf(fp, "\n"); 1891 print_hwsec(shp, fp); 1892 break; 1893 case SMB_TYPE_VPROBE: 1894 oprintf(fp, "\n"); 1895 print_vprobe(shp, sp->smbstr_id, fp); 1896 break; 1897 case SMB_TYPE_COOLDEV: 1898 oprintf(fp, "\n"); 1899 print_cooldev(shp, sp->smbstr_id, fp); 1900 break; 1901 case SMB_TYPE_TPROBE: 1902 oprintf(fp, "\n"); 1903 print_tprobe(shp, sp->smbstr_id, fp); 1904 break; 1905 case SMB_TYPE_IPROBE: 1906 oprintf(fp, "\n"); 1907 print_iprobe(shp, sp->smbstr_id, fp); 1908 break; 1909 case SMB_TYPE_BOOT: 1910 oprintf(fp, "\n"); 1911 print_boot(shp, fp); 1912 break; 1913 case SMB_TYPE_IPMIDEV: 1914 oprintf(fp, "\n"); 1915 print_ipmi(shp, fp); 1916 break; 1917 case SMB_TYPE_POWERSUP: 1918 oprintf(fp, "\n"); 1919 print_powersup(shp, sp->smbstr_id, fp); 1920 break; 1921 case SMB_TYPE_OBDEVEXT: 1922 oprintf(fp, "\n"); 1923 print_obdevs_ext(shp, sp->smbstr_id, fp); 1924 break; 1925 case SMB_TYPE_PROCESSOR_INFO: 1926 oprintf(fp, "\n"); 1927 print_processor_info(shp, sp->smbstr_id, fp); 1928 break; 1929 case SMB_TYPE_STRPROP: 1930 oprintf(fp, "\n"); 1931 print_strprop_info(shp, sp->smbstr_id, fp); 1932 break; 1933 case SMB_TYPE_FWINFO: 1934 oprintf(fp, "\n"); 1935 print_fwinfo(shp, sp->smbstr_id, fp); 1936 break; 1937 case SUN_OEM_EXT_PROCESSOR: 1938 oprintf(fp, "\n"); 1939 print_extprocessor(shp, sp->smbstr_id, fp); 1940 break; 1941 case SUN_OEM_EXT_PORT: 1942 oprintf(fp, "\n"); 1943 print_extport(shp, sp->smbstr_id, fp); 1944 break; 1945 case SUN_OEM_PCIEXRC: 1946 oprintf(fp, "\n"); 1947 print_pciexrc(shp, sp->smbstr_id, fp); 1948 break; 1949 case SUN_OEM_EXT_MEMARRAY: 1950 oprintf(fp, "\n"); 1951 print_extmemarray(shp, sp->smbstr_id, fp); 1952 break; 1953 case SUN_OEM_EXT_MEMDEVICE: 1954 oprintf(fp, "\n"); 1955 print_extmemdevice(shp, sp->smbstr_id, fp); 1956 break; 1957 default: 1958 hex++; 1959 } 1960 1961 if (hex) 1962 print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 1963 else 1964 oprintf(fp, "\n"); 1965 1966 return (0); 1967 } 1968 1969 static uint16_t 1970 getu16(const char *name, const char *s) 1971 { 1972 u_longlong_t val; 1973 char *p; 1974 1975 errno = 0; 1976 val = strtoull(s, &p, 0); 1977 1978 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 1979 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1980 g_pname, name, s); 1981 exit(SMBIOS_USAGE); 1982 } 1983 1984 return ((uint16_t)val); 1985 } 1986 1987 static uint16_t 1988 getstype(const char *name, const char *s) 1989 { 1990 const char *ts; 1991 uint16_t t; 1992 1993 for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 1994 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 1995 return (t); 1996 } 1997 1998 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1999 g_pname, name, s); 2000 2001 exit(SMBIOS_USAGE); 2002 /*NOTREACHED*/ 2003 } 2004 2005 static int 2006 usage(FILE *fp) 2007 { 2008 (void) fprintf(fp, "Usage: %s " 2009 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 2010 2011 (void) fprintf(fp, 2012 "\t-B disable header validation for broken BIOSes\n" 2013 "\t-e display SMBIOS entry point information\n" 2014 "\t-i display only the specified structure\n" 2015 "\t-O display obsolete structure types\n" 2016 "\t-s display only a summary of structure identifiers and types\n" 2017 "\t-t display only the specified structure type\n" 2018 "\t-w write the raw data to the specified file\n" 2019 "\t-x display raw data for structures\n"); 2020 2021 return (SMBIOS_USAGE); 2022 } 2023 2024 int 2025 main(int argc, char *argv[]) 2026 { 2027 const char *ifile = NULL; 2028 const char *ofile = NULL; 2029 int oflags = 0; 2030 2031 smbios_hdl_t *shp; 2032 smbios_struct_t s; 2033 int err, fd, c; 2034 char *p; 2035 2036 if ((p = strrchr(argv[0], '/')) == NULL) 2037 g_pname = argv[0]; 2038 else 2039 g_pname = p + 1; 2040 2041 while (optind < argc) { 2042 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 2043 switch (c) { 2044 case 'B': 2045 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 2046 break; 2047 case 'e': 2048 opt_e++; 2049 break; 2050 case 'i': 2051 opt_i = getu16("struct ID", optarg); 2052 break; 2053 case 'O': 2054 opt_O++; 2055 break; 2056 case 's': 2057 opt_s++; 2058 break; 2059 case 't': 2060 if (isdigit(optarg[0])) 2061 opt_t = getu16("struct type", optarg); 2062 else 2063 opt_t = getstype("struct type", optarg); 2064 break; 2065 case 'w': 2066 ofile = optarg; 2067 break; 2068 case 'x': 2069 opt_x++; 2070 break; 2071 case 'Z': 2072 oflags |= SMB_O_ZIDS; /* undocumented */ 2073 break; 2074 default: 2075 return (usage(stderr)); 2076 } 2077 } 2078 2079 if (optind < argc) { 2080 if (ifile != NULL) { 2081 (void) fprintf(stderr, "%s: illegal " 2082 "argument -- %s\n", g_pname, argv[optind]); 2083 return (SMBIOS_USAGE); 2084 } 2085 ifile = argv[optind++]; 2086 } 2087 } 2088 2089 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 2090 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 2091 g_pname, smbios_errmsg(err)); 2092 return (SMBIOS_ERROR); 2093 } 2094 2095 if (opt_i == -1 && opt_t == -1 && opt_e == 0 && 2096 smbios_truncated(shp)) 2097 (void) fprintf(stderr, "%s: SMBIOS table is truncated\n", 2098 g_pname); 2099 2100 if (ofile != NULL) { 2101 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 2102 (void) fprintf(stderr, "%s: failed to open %s: %s\n", 2103 g_pname, ofile, strerror(errno)); 2104 err = SMBIOS_ERROR; 2105 } else if (smbios_write(shp, fd) != 0) { 2106 (void) fprintf(stderr, "%s: failed to write %s: %s\n", 2107 g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 2108 err = SMBIOS_ERROR; 2109 } 2110 smbios_close(shp); 2111 return (err); 2112 } 2113 2114 if (opt_e) { 2115 print_smbios(shp, stdout); 2116 smbios_close(shp); 2117 return (SMBIOS_SUCCESS); 2118 } 2119 2120 if (opt_O && (opt_i != -1 || opt_t != -1)) 2121 opt_O++; /* -i or -t imply displaying obsolete records */ 2122 2123 if (opt_i != -1) 2124 err = smbios_lookup_id(shp, opt_i, &s); 2125 else 2126 err = smbios_iter(shp, print_struct, stdout); 2127 2128 if (err != 0) { 2129 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 2130 g_pname, smbios_errmsg(smbios_errno(shp))); 2131 smbios_close(shp); 2132 return (SMBIOS_ERROR); 2133 } 2134 2135 if (opt_i != -1) 2136 (void) print_struct(shp, &s, stdout); 2137 2138 smbios_close(shp); 2139 return (SMBIOS_SUCCESS); 2140 } 2141