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