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