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