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 44 #define SMBIOS_SUCCESS 0 45 #define SMBIOS_ERROR 1 46 #define SMBIOS_USAGE 2 47 48 static const char *g_pname; 49 static int g_hdr; 50 51 static int opt_e; 52 static int opt_i = -1; 53 static int opt_O; 54 static int opt_s; 55 static int opt_t = -1; 56 static int opt_x; 57 58 /*PRINTFLIKE2*/ 59 static void 60 smbios_warn(smbios_hdl_t *shp, const char *format, ...) 61 { 62 va_list ap; 63 64 va_start(ap, format); 65 (void) vfprintf(stderr, format, ap); 66 va_end(ap); 67 68 if (shp != NULL) { 69 (void) fprintf(stderr, ": %s", 70 smbios_errmsg(smbios_errno(shp))); 71 } 72 73 (void) fprintf(stderr, "\n"); 74 } 75 76 /*PRINTFLIKE2*/ 77 static void 78 oprintf(FILE *fp, const char *format, ...) 79 { 80 va_list ap; 81 82 va_start(ap, format); 83 (void) vfprintf(fp, format, ap); 84 va_end(ap); 85 } 86 87 /*PRINTFLIKE3*/ 88 static void 89 desc_printf(const char *d, FILE *fp, const char *format, ...) 90 { 91 va_list ap; 92 93 va_start(ap, format); 94 (void) vfprintf(fp, format, ap); 95 va_end(ap); 96 97 if (d != NULL) 98 (void) fprintf(fp, " (%s)\n", d); 99 else 100 (void) fprintf(fp, "\n"); 101 } 102 103 static void 104 flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits, 105 const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t)) 106 { 107 size_t i; 108 109 oprintf(fp, " %s: 0x%x\n", s, flags); 110 111 for (i = 0; i < bits; i++) { 112 uint_t f = 1 << i; 113 const char *n; 114 115 if (!(flags & f)) 116 continue; 117 118 if ((n = flag_name(f)) != NULL) 119 desc_printf(flag_desc(f), fp, "\t%s", n); 120 else 121 desc_printf(flag_desc(f), fp, "\t0x%x", f); 122 } 123 } 124 125 static void 126 flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits, 127 const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t)) 128 { 129 size_t i; 130 131 oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags); 132 133 for (i = 0; i < bits; i++) { 134 u_longlong_t f = 1ULL << i; 135 const char *n; 136 137 if (!(flags & f)) 138 continue; 139 140 if ((n = flag_name(f)) != NULL) 141 desc_printf(flag_desc(f), fp, "\t%s", n); 142 else 143 desc_printf(flag_desc(f), fp, "\t0x%llx", f); 144 } 145 } 146 147 static void 148 id_printf(FILE *fp, const char *s, id_t id) 149 { 150 switch (id) { 151 case SMB_ID_NONE: 152 oprintf(fp, "%sNone\n", s); 153 break; 154 case SMB_ID_NOTSUP: 155 oprintf(fp, "%sNot Supported\n", s); 156 break; 157 default: 158 oprintf(fp, "%s%u\n", s, (uint_t)id); 159 } 160 } 161 162 static int 163 check_oem(smbios_hdl_t *shp) 164 { 165 int i; 166 int cnt; 167 int rv; 168 id_t oem_id; 169 smbios_struct_t s; 170 const char **oem_str; 171 172 rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s); 173 if (rv != 0) { 174 return (-1); 175 } 176 177 oem_id = s.smbstr_id; 178 179 cnt = smbios_info_strtab(shp, oem_id, 0, NULL); 180 if (cnt > 0) { 181 oem_str = alloca(sizeof (char *) * cnt); 182 (void) smbios_info_strtab(shp, oem_id, cnt, oem_str); 183 184 for (i = 0; i < cnt; i++) { 185 if (strncmp(oem_str[i], SMB_PRMS1, 186 strlen(SMB_PRMS1) + 1) == 0) { 187 return (0); 188 } 189 } 190 } 191 192 return (-1); 193 } 194 195 static void 196 print_smbios_21(smbios_21_entry_t *ep, FILE *fp) 197 { 198 int i; 199 200 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 201 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor), 202 ep->smbe_eanchor); 203 204 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum); 205 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen); 206 oprintf(fp, "Entry Point Version: %u.%u\n", 207 ep->smbe_major, ep->smbe_minor); 208 oprintf(fp, "Max Structure Size: %u\n", ep->smbe_maxssize); 209 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision); 210 211 oprintf(fp, "Entry Point Revision Data:"); 212 for (i = 0; i < sizeof (ep->smbe_format); i++) 213 oprintf(fp, " 0x%02x", ep->smbe_format[i]); 214 oprintf(fp, "\n"); 215 216 oprintf(fp, "Intermediate Anchor Tag: %*.*s\n", 217 (int)sizeof (ep->smbe_ianchor), (int)sizeof (ep->smbe_ianchor), 218 ep->smbe_ianchor); 219 220 oprintf(fp, "Intermediate Checksum: 0x%x\n", ep->smbe_icksum); 221 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen); 222 oprintf(fp, "Structure Table Address: 0x%x\n", ep->smbe_staddr); 223 oprintf(fp, "Structure Table Entries: %u\n", ep->smbe_stnum); 224 oprintf(fp, "DMI BCD Revision: 0x%x\n", ep->smbe_bcdrev); 225 } 226 227 static void 228 print_smbios_30(smbios_30_entry_t *ep, FILE *fp) 229 { 230 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 231 (int)sizeof (ep->smbe_eanchor), (int)sizeof (ep->smbe_eanchor), 232 ep->smbe_eanchor); 233 234 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep->smbe_ecksum); 235 oprintf(fp, "Entry Point Length: %u\n", ep->smbe_elen); 236 oprintf(fp, "SMBIOS Version: %u.%u\n", 237 ep->smbe_major, ep->smbe_minor); 238 oprintf(fp, "SMBIOS DocRev: 0x%x\n", ep->smbe_docrev); 239 oprintf(fp, "Entry Point Revision: 0x%x\n", ep->smbe_revision); 240 241 oprintf(fp, "Structure Table Length: %u\n", ep->smbe_stlen); 242 oprintf(fp, "Structure Table Address: 0x%" PRIx64 "\n", 243 ep->smbe_staddr); 244 } 245 246 static void 247 print_smbios(smbios_hdl_t *shp, FILE *fp) 248 { 249 smbios_entry_t ep; 250 251 switch (smbios_info_smbios(shp, &ep)) { 252 case SMBIOS_ENTRY_POINT_21: 253 print_smbios_21(&ep.ep21, fp); 254 break; 255 case SMBIOS_ENTRY_POINT_30: 256 print_smbios_30(&ep.ep30, fp); 257 break; 258 } 259 } 260 261 static void 262 print_common(const smbios_info_t *ip, FILE *fp) 263 { 264 if (ip->smbi_manufacturer[0] != '\0') 265 oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer); 266 if (ip->smbi_product[0] != '\0') 267 oprintf(fp, " Product: %s\n", ip->smbi_product); 268 if (ip->smbi_version[0] != '\0') 269 oprintf(fp, " Version: %s\n", ip->smbi_version); 270 if (ip->smbi_serial[0] != '\0') 271 oprintf(fp, " Serial Number: %s\n", ip->smbi_serial); 272 if (ip->smbi_asset[0] != '\0') 273 oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset); 274 if (ip->smbi_location[0] != '\0') 275 oprintf(fp, " Location Tag: %s\n", ip->smbi_location); 276 if (ip->smbi_part[0] != '\0') 277 oprintf(fp, " Part Number: %s\n", ip->smbi_part); 278 } 279 280 static void 281 print_bios(smbios_hdl_t *shp, FILE *fp) 282 { 283 smbios_bios_t b; 284 285 (void) smbios_info_bios(shp, &b); 286 287 oprintf(fp, " Vendor: %s\n", b.smbb_vendor); 288 oprintf(fp, " Version String: %s\n", b.smbb_version); 289 oprintf(fp, " Release Date: %s\n", b.smbb_reldate); 290 oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment); 291 oprintf(fp, " ROM Size: %" PRIu64 " bytes\n", b.smbb_extromsize); 292 oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize); 293 294 flag64_printf(fp, "Characteristics", 295 b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY, 296 smbios_bios_flag_name, smbios_bios_flag_desc); 297 298 if (b.smbb_nxcflags > SMB_BIOSXB_1) { 299 flag_printf(fp, "Characteristics Extension Byte 1", 300 b.smbb_xcflags[SMB_BIOSXB_1], 301 sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY, 302 smbios_bios_xb1_name, smbios_bios_xb1_desc); 303 } 304 305 if (b.smbb_nxcflags > SMB_BIOSXB_2) { 306 flag_printf(fp, "Characteristics Extension Byte 2", 307 b.smbb_xcflags[SMB_BIOSXB_2], 308 sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY, 309 smbios_bios_xb2_name, smbios_bios_xb2_desc); 310 } 311 312 if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) { 313 oprintf(fp, " Version Number: %u.%u\n", 314 b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor); 315 } 316 317 if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN) { 318 oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n", 319 b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor); 320 } 321 } 322 323 static void 324 print_system(smbios_hdl_t *shp, FILE *fp) 325 { 326 smbios_system_t s; 327 uint_t i; 328 329 (void) smbios_info_system(shp, &s); 330 331 oprintf(fp, " UUID: "); 332 for (i = 0; i < s.smbs_uuidlen; i++) { 333 oprintf(fp, "%02x", s.smbs_uuid[i]); 334 if (i == 3 || i == 5 || i == 7 || i == 9) 335 oprintf(fp, "-"); 336 } 337 oprintf(fp, "\n"); 338 339 desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup), 340 fp, " Wake-Up Event: 0x%x", s.smbs_wakeup); 341 342 oprintf(fp, " SKU Number: %s\n", s.smbs_sku); 343 oprintf(fp, " Family: %s\n", s.smbs_family); 344 } 345 346 static void 347 print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp) 348 { 349 smbios_bboard_t b; 350 int chdl_cnt; 351 352 (void) smbios_info_bboard(shp, id, &b); 353 354 oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis); 355 356 flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY, 357 smbios_bboard_flag_name, smbios_bboard_flag_desc); 358 359 desc_printf(smbios_bboard_type_desc(b.smbb_type), 360 fp, " Board Type: 0x%x", b.smbb_type); 361 362 chdl_cnt = b.smbb_contn; 363 if (chdl_cnt != 0) { 364 id_t *chdl; 365 uint16_t hdl; 366 int i, n, cnt; 367 368 chdl = alloca(chdl_cnt * sizeof (id_t)); 369 cnt = smbios_info_contains(shp, id, chdl_cnt, chdl); 370 if (cnt > SMB_CONT_MAX) 371 return; 372 n = MIN(chdl_cnt, cnt); 373 374 oprintf(fp, "\n"); 375 for (i = 0; i < n; i++) { 376 hdl = (uint16_t)chdl[i]; 377 oprintf(fp, " Contained Handle: %u\n", hdl); 378 } 379 } 380 } 381 382 static void 383 print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp) 384 { 385 smbios_chassis_t c; 386 int elem_cnt; 387 388 (void) smbios_info_chassis(shp, id, &c); 389 390 oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata); 391 oprintf(fp, " SKU number: %s\n", 392 c.smbc_sku[0] == '\0' ? "<unknown>" : c.smbc_sku); 393 oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N"); 394 395 desc_printf(smbios_chassis_type_desc(c.smbc_type), 396 fp, " Chassis Type: 0x%x", c.smbc_type); 397 398 desc_printf(smbios_chassis_state_desc(c.smbc_bustate), 399 fp, " Boot-Up State: 0x%x", c.smbc_bustate); 400 401 desc_printf(smbios_chassis_state_desc(c.smbc_psstate), 402 fp, " Power Supply State: 0x%x", c.smbc_psstate); 403 404 desc_printf(smbios_chassis_state_desc(c.smbc_thstate), 405 fp, " Thermal State: 0x%x", c.smbc_thstate); 406 407 oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight); 408 oprintf(fp, " Power Cords: %u\n", c.smbc_cords); 409 410 elem_cnt = c.smbc_elems; 411 oprintf(fp, " Element Records: %u\n", elem_cnt); 412 413 if (elem_cnt > 0) { 414 id_t *elems; 415 uint8_t type; 416 int i, n, cnt; 417 418 elems = alloca(c.smbc_elems * sizeof (id_t)); 419 cnt = smbios_info_contains(shp, id, elem_cnt, elems); 420 if (cnt > SMB_CONT_MAX) 421 return; 422 n = MIN(elem_cnt, cnt); 423 424 oprintf(fp, "\n"); 425 for (i = 0; i < n; i++) { 426 type = (uint8_t)elems[i]; 427 if (type & 0x80) { 428 /* SMBIOS structrure Type */ 429 desc_printf(smbios_type_name(type & 0x7f), fp, 430 " Contained SMBIOS structure Type: %u", 431 type & 0x80); 432 } else { 433 /* SMBIOS Base Board Type */ 434 desc_printf(smbios_bboard_type_desc(type), fp, 435 " Contained SMBIOS Base Board Type: 0x%x", 436 type); 437 } 438 } 439 } 440 } 441 442 static void 443 print_processor(smbios_hdl_t *shp, id_t id, FILE *fp) 444 { 445 smbios_processor_t p; 446 uint_t status; 447 448 (void) smbios_info_processor(shp, id, &p); 449 status = SMB_PRSTATUS_STATUS(p.smbp_status); 450 451 desc_printf(smbios_processor_family_desc(p.smbp_family), 452 fp, " Family: %u", p.smbp_family); 453 454 if (p.smbp_family2 != 0) 455 desc_printf(smbios_processor_family_desc(p.smbp_family2), 456 fp, " Family Ext: %u", p.smbp_family2); 457 458 oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid); 459 460 desc_printf(smbios_processor_type_desc(p.smbp_type), 461 fp, " Type: %u", p.smbp_type); 462 463 desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade), 464 fp, " Socket Upgrade: %u", p.smbp_upgrade); 465 466 oprintf(fp, " Socket Status: %s\n", 467 SMB_PRSTATUS_PRESENT(p.smbp_status) ? 468 "Populated" : "Not Populated"); 469 470 desc_printf(smbios_processor_status_desc(status), 471 fp, " Processor Status: %u", status); 472 473 if (SMB_PRV_LEGACY(p.smbp_voltage)) { 474 oprintf(fp, " Supported Voltages:"); 475 switch (p.smbp_voltage) { 476 case SMB_PRV_5V: 477 oprintf(fp, " 5.0V"); 478 break; 479 case SMB_PRV_33V: 480 oprintf(fp, " 3.3V"); 481 break; 482 case SMB_PRV_29V: 483 oprintf(fp, " 2.9V"); 484 break; 485 } 486 oprintf(fp, "\n"); 487 } else { 488 oprintf(fp, " Supported Voltages: %.1fV\n", 489 (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10); 490 } 491 492 if (p.smbp_corecount != 0) { 493 if (p.smbp_corecount != 0xff || p.smbp_corecount2 == 0) 494 oprintf(fp, " Core Count: %u\n", p.smbp_corecount); 495 else 496 oprintf(fp, " Core Count: %u\n", p.smbp_corecount2); 497 } else { 498 oprintf(fp, " Core Count: Unknown\n"); 499 } 500 501 if (p.smbp_coresenabled != 0) { 502 if (p.smbp_coresenabled != 0xff || p.smbp_coresenabled2 == 0) { 503 oprintf(fp, " Cores Enabled: %u\n", 504 p.smbp_coresenabled); 505 } else { 506 oprintf(fp, " Cores Enabled: %u\n", 507 p.smbp_coresenabled2); 508 } 509 } else { 510 oprintf(fp, " Cores Enabled: Unknown\n"); 511 } 512 513 if (p.smbp_threadcount != 0) { 514 if (p.smbp_threadcount != 0xff || p.smbp_threadcount2 == 0) { 515 oprintf(fp, " Thread Count: %u\n", 516 p.smbp_threadcount); 517 } else { 518 oprintf(fp, " Thread Count: %u\n", 519 p.smbp_threadcount2); 520 } 521 } else { 522 oprintf(fp, " Thread Count: Unknown\n"); 523 } 524 525 if (p.smbp_cflags) { 526 flag_printf(fp, "Processor Characteristics", 527 p.smbp_cflags, sizeof (p.smbp_cflags) * NBBY, 528 smbios_processor_core_flag_name, 529 smbios_processor_core_flag_desc); 530 } 531 532 if (p.smbp_clkspeed != 0) 533 oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed); 534 else 535 oprintf(fp, " External Clock Speed: Unknown\n"); 536 537 if (p.smbp_maxspeed != 0) 538 oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed); 539 else 540 oprintf(fp, " Maximum Speed: Unknown\n"); 541 542 if (p.smbp_curspeed != 0) 543 oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed); 544 else 545 oprintf(fp, " Current Speed: Unknown\n"); 546 547 id_printf(fp, " L1 Cache Handle: ", p.smbp_l1cache); 548 id_printf(fp, " L2 Cache Handle: ", p.smbp_l2cache); 549 id_printf(fp, " L3 Cache Handle: ", p.smbp_l3cache); 550 } 551 552 static void 553 print_cache(smbios_hdl_t *shp, id_t id, FILE *fp) 554 { 555 smbios_cache_t c; 556 557 (void) smbios_info_cache(shp, id, &c); 558 559 oprintf(fp, " Level: %u\n", c.smba_level); 560 oprintf(fp, " Maximum Installed Size: %" PRIu64 " bytes\n", 561 c.smba_maxsize2); 562 563 if (c.smba_size2 != 0) { 564 oprintf(fp, " Installed Size: %" PRIu64 " bytes\n", 565 c.smba_size2); 566 } else { 567 oprintf(fp, " Installed Size: Not Installed\n"); 568 } 569 570 if (c.smba_speed != 0) 571 oprintf(fp, " Speed: %uns\n", c.smba_speed); 572 else 573 oprintf(fp, " Speed: Unknown\n"); 574 575 flag_printf(fp, "Supported SRAM Types", 576 c.smba_stype, sizeof (c.smba_stype) * NBBY, 577 smbios_cache_ctype_name, smbios_cache_ctype_desc); 578 579 desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 580 fp, " Current SRAM Type: 0x%x", c.smba_ctype); 581 582 desc_printf(smbios_cache_ecc_desc(c.smba_etype), 583 fp, " Error Correction Type: %u", c.smba_etype); 584 585 desc_printf(smbios_cache_logical_desc(c.smba_ltype), 586 fp, " Logical Cache Type: %u", c.smba_ltype); 587 588 desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 589 fp, " Associativity: %u", c.smba_assoc); 590 591 desc_printf(smbios_cache_mode_desc(c.smba_mode), 592 fp, " Mode: %u", c.smba_mode); 593 594 desc_printf(smbios_cache_loc_desc(c.smba_location), 595 fp, " Location: %u", c.smba_location); 596 597 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 598 smbios_cache_flag_name, smbios_cache_flag_desc); 599 } 600 601 static void 602 print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 603 { 604 smbios_port_t p; 605 606 (void) smbios_info_port(shp, id, &p); 607 608 oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref); 609 oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref); 610 611 desc_printf(smbios_port_conn_desc(p.smbo_itype), 612 fp, " Internal Connector Type: %u", p.smbo_itype); 613 614 desc_printf(smbios_port_conn_desc(p.smbo_etype), 615 fp, " External Connector Type: %u", p.smbo_etype); 616 617 desc_printf(smbios_port_type_desc(p.smbo_ptype), 618 fp, " Port Type: %u", p.smbo_ptype); 619 } 620 621 static void 622 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 623 { 624 smbios_slot_t s; 625 smbios_version_t v; 626 627 (void) smbios_info_slot(shp, id, &s); 628 smbios_info_smbios_version(shp, &v); 629 630 oprintf(fp, " Reference Designator: %s\n", s.smbl_name); 631 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 632 633 desc_printf(smbios_slot_type_desc(s.smbl_type), 634 fp, " Type: 0x%x", s.smbl_type); 635 636 desc_printf(smbios_slot_width_desc(s.smbl_width), 637 fp, " Width: 0x%x", s.smbl_width); 638 639 desc_printf(smbios_slot_usage_desc(s.smbl_usage), 640 fp, " Usage: 0x%x", s.smbl_usage); 641 642 desc_printf(smbios_slot_length_desc(s.smbl_length), 643 fp, " Length: 0x%x", s.smbl_length); 644 645 flag_printf(fp, "Slot Characteristics 1", 646 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 647 smbios_slot_ch1_name, smbios_slot_ch1_desc); 648 649 flag_printf(fp, "Slot Characteristics 2", 650 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 651 smbios_slot_ch2_name, smbios_slot_ch2_desc); 652 653 if (check_oem(shp) != 0 && (v.smbv_major < 2 || v.smbv_minor < 6)) 654 return; 655 656 oprintf(fp, " Segment Group: %u\n", s.smbl_sg); 657 oprintf(fp, " Bus Number: %u\n", s.smbl_bus); 658 oprintf(fp, " Device/Function Number: %u\n", s.smbl_df); 659 } 660 661 static void 662 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp) 663 { 664 boolean_t enabled; 665 smbios_obdev_ext_t oe; 666 const char *type; 667 668 (void) smbios_info_obdevs_ext(shp, id, &oe); 669 670 /* 671 * Bit 7 is always whether or not the device is enabled while bits 0:6 672 * are the actual device type. 673 */ 674 enabled = oe.smboe_dtype >> 7; 675 type = smbios_onboard_type_desc(oe.smboe_dtype & 0x7f); 676 677 oprintf(fp, " Reference Designator: %s\n", oe.smboe_name); 678 oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" : 679 "false"); 680 oprintf(fp, " Device Type: %s\n", type); 681 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti); 682 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg); 683 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus); 684 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df); 685 } 686 687 static void 688 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 689 { 690 smbios_obdev_t *argv; 691 int i, argc; 692 693 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 694 argv = alloca(sizeof (smbios_obdev_t) * argc); 695 (void) smbios_info_obdevs(shp, id, argc, argv); 696 for (i = 0; i < argc; i++) 697 oprintf(fp, " %s\n", argv[i].smbd_name); 698 } 699 } 700 701 static void 702 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 703 { 704 const char **argv; 705 int i, argc; 706 707 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 708 argv = alloca(sizeof (char *) * argc); 709 (void) smbios_info_strtab(shp, id, argc, argv); 710 for (i = 0; i < argc; i++) 711 oprintf(fp, " %s\n", argv[i]); 712 } 713 } 714 715 static void 716 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 717 { 718 smbios_lang_t l; 719 720 (void) smbios_info_lang(shp, &l); 721 722 oprintf(fp, " Current Language: %s\n", l.smbla_cur); 723 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 724 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 725 oprintf(fp, " Installed Languages:\n"); 726 727 print_strtab(shp, id, fp); 728 } 729 730 /*ARGSUSED*/ 731 static void 732 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 733 { 734 smbios_evlog_t ev; 735 uint32_t i; 736 737 (void) smbios_info_eventlog(shp, &ev); 738 739 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 740 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 741 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 742 743 desc_printf(smbios_evlog_method_desc(ev.smbev_method), 744 fp, " Data Access Method: %u", ev.smbev_method); 745 746 flag_printf(fp, "Log Flags", 747 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 748 smbios_evlog_flag_name, smbios_evlog_flag_desc); 749 750 desc_printf(smbios_evlog_format_desc(ev.smbev_format), 751 fp, " Log Header Format: %u", ev.smbev_format); 752 753 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 754 oprintf(fp, " Data Access Address: "); 755 756 switch (ev.smbev_method) { 757 case SMB_EVM_1x1i_1x1d: 758 case SMB_EVM_2x1i_1x1d: 759 case SMB_EVM_1x2i_1x1d: 760 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 761 ev.smbev_addr.eva_io.evi_iaddr, 762 ev.smbev_addr.eva_io.evi_daddr); 763 break; 764 case SMB_EVM_GPNV: 765 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 766 break; 767 default: 768 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 769 } 770 771 oprintf(fp, " Type Descriptors:\n"); 772 773 for (i = 0; i < ev.smbev_typec; i++) { 774 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 775 ev.smbev_typev[i].smbevt_ltype, 776 ev.smbev_typev[i].smbevt_dtype); 777 } 778 } 779 780 static void 781 print_bytes(const uint8_t *data, size_t size, FILE *fp) 782 { 783 size_t row, rows = P2ROUNDUP(size, 16) / 16; 784 size_t col, cols; 785 786 char buf[17]; 787 uint8_t x; 788 789 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 790 "0123456789abcdef\n"); 791 792 for (row = 0; row < rows; row++) { 793 oprintf(fp, " %#6lx: ", (ulong_t)row * 16); 794 cols = MIN(size - row * 16, 16); 795 796 for (col = 0; col < cols; col++) { 797 if (col % 4 == 0) 798 oprintf(fp, " "); 799 x = *data++; 800 oprintf(fp, "%02x", x); 801 buf[col] = x <= ' ' || x > '~' ? '.' : x; 802 } 803 804 for (; col < 16; col++) { 805 if (col % 4 == 0) 806 oprintf(fp, " "); 807 oprintf(fp, " "); 808 buf[col] = ' '; 809 } 810 811 buf[col] = '\0'; 812 oprintf(fp, " %s\n", buf); 813 } 814 815 oprintf(fp, "\n"); 816 } 817 818 static void 819 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 820 { 821 smbios_memarray_t ma; 822 823 (void) smbios_info_memarray(shp, id, &ma); 824 825 desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 826 fp, " Location: %u", ma.smbma_location); 827 828 desc_printf(smbios_memarray_use_desc(ma.smbma_use), 829 fp, " Use: %u", ma.smbma_use); 830 831 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 832 fp, " ECC: %u", ma.smbma_ecc); 833 834 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 835 id_printf(fp, " Memory Error Data: ", ma.smbma_err); 836 oprintf(fp, " Max Capacity: %llu bytes\n", 837 (u_longlong_t)ma.smbma_size); 838 } 839 840 static void 841 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 842 { 843 smbios_memdevice_t md; 844 845 (void) smbios_info_memdevice(shp, id, &md); 846 847 id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 848 id_printf(fp, " Memory Error Data: ", md.smbmd_error); 849 850 if (md.smbmd_twidth != -1u) 851 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 852 else 853 oprintf(fp, " Total Width: Unknown\n"); 854 855 if (md.smbmd_dwidth != -1u) 856 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 857 else 858 oprintf(fp, " Data Width: Unknown\n"); 859 860 switch (md.smbmd_size) { 861 case -1ull: 862 oprintf(fp, " Size: Unknown\n"); 863 break; 864 case 0: 865 oprintf(fp, " Size: Not Populated\n"); 866 break; 867 default: 868 oprintf(fp, " Size: %llu bytes\n", 869 (u_longlong_t)md.smbmd_size); 870 } 871 872 desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 873 fp, " Form Factor: %u", md.smbmd_form); 874 875 if (md.smbmd_set == 0) 876 oprintf(fp, " Set: None\n"); 877 else if (md.smbmd_set == (uint8_t)-1u) 878 oprintf(fp, " Set: Unknown\n"); 879 else 880 oprintf(fp, " Set: %u\n", md.smbmd_set); 881 882 if (md.smbmd_rank != 0) { 883 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank), 884 fp, " Rank: %u", md.smbmd_rank); 885 } else { 886 oprintf(fp, " Rank: Unknown\n"); 887 } 888 889 desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 890 fp, " Memory Type: %u", md.smbmd_type); 891 892 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 893 smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 894 895 if (md.smbmd_speed != 0) 896 oprintf(fp, " Speed: %u MT/s\n", md.smbmd_speed); 897 else 898 oprintf(fp, " Speed: Unknown\n"); 899 900 if (md.smbmd_clkspeed != 0) 901 oprintf(fp, " Configured Speed: %u MT/s\n", md.smbmd_clkspeed); 902 else 903 oprintf(fp, " Configured Speed: Unknown\n"); 904 905 oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc); 906 oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc); 907 908 if (md.smbmd_minvolt != 0) { 909 oprintf(fp, " Minimum Voltage: %.2fV\n", 910 md.smbmd_minvolt / 1000.0); 911 } else { 912 oprintf(fp, " Minimum Voltage: Unknown\n"); 913 } 914 915 if (md.smbmd_maxvolt != 0) { 916 oprintf(fp, " Maximum Voltage: %.2fV\n", 917 md.smbmd_maxvolt / 1000.0); 918 } else { 919 oprintf(fp, " Maximum Voltage: Unknown\n"); 920 } 921 922 if (md.smbmd_confvolt != 0) { 923 oprintf(fp, " Configured Voltage: %.2fV\n", 924 md.smbmd_confvolt / 1000.0); 925 } else { 926 oprintf(fp, " Configured Voltage: Unknown\n"); 927 } 928 } 929 930 static void 931 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 932 { 933 smbios_memarrmap_t ma; 934 935 (void) smbios_info_memarrmap(shp, id, &ma); 936 937 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 938 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 939 940 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 941 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 942 } 943 944 static void 945 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 946 { 947 smbios_memdevmap_t md; 948 949 (void) smbios_info_memdevmap(shp, id, &md); 950 951 id_printf(fp, " Memory Device: ", md.smbmdm_device); 952 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 953 954 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 955 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 956 957 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 958 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 959 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 960 } 961 962 static void 963 print_hwsec(smbios_hdl_t *shp, FILE *fp) 964 { 965 smbios_hwsec_t h; 966 967 (void) smbios_info_hwsec(shp, &h); 968 969 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 970 fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 971 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 972 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 973 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 974 fp, " Administrator Password Status: %u", h.smbh_adm_ps); 975 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 976 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 977 } 978 979 static void 980 print_boot(smbios_hdl_t *shp, FILE *fp) 981 { 982 smbios_boot_t b; 983 984 (void) smbios_info_boot(shp, &b); 985 986 desc_printf(smbios_boot_desc(b.smbt_status), 987 fp, " Boot Status Code: 0x%x", b.smbt_status); 988 989 if (b.smbt_size != 0) { 990 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 991 print_bytes(b.smbt_data, b.smbt_size, fp); 992 } 993 } 994 995 static void 996 print_ipmi(smbios_hdl_t *shp, FILE *fp) 997 { 998 smbios_ipmi_t i; 999 1000 (void) smbios_info_ipmi(shp, &i); 1001 1002 desc_printf(smbios_ipmi_type_desc(i.smbip_type), 1003 fp, " Type: %u", i.smbip_type); 1004 1005 oprintf(fp, " BMC IPMI Version: %u.%u\n", 1006 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 1007 1008 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 1009 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 1010 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 1011 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 1012 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 1013 1014 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 1015 smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 1016 } 1017 1018 static void 1019 print_powersup(smbios_hdl_t *shp, id_t id, FILE *fp) 1020 { 1021 smbios_powersup_t p; 1022 1023 if (smbios_info_powersup(shp, id, &p) != 0) { 1024 smbios_warn(shp, "failed to read power supply information"); 1025 return; 1026 } 1027 1028 oprintf(fp, " Power Supply Group: %u\n", p.smbps_group); 1029 if (p.smbps_maxout != 0x8000) { 1030 oprintf(fp, " Maximum Output: %llu mW\n", p.smbps_maxout); 1031 } else { 1032 oprintf(fp, " Maximum Output: unknown\n"); 1033 } 1034 1035 flag_printf(fp, "Characteristics", p.smbps_flags, 1036 sizeof (p.smbps_flags) * NBBY, smbios_powersup_flag_name, 1037 smbios_powersup_flag_desc); 1038 1039 desc_printf(smbios_powersup_input_desc(p.smbps_ivrs), 1040 fp, " Input Voltage Range Switching: %u", p.smbps_ivrs); 1041 desc_printf(smbios_powersup_status_desc(p.smbps_status), 1042 fp, " Status: %u", p.smbps_status); 1043 desc_printf(smbios_powersup_type_desc(p.smbps_pstype), 1044 fp, " Type: %u", p.smbps_pstype); 1045 1046 if (p.smbps_vprobe != 0xffff) { 1047 oprintf(fp, " Voltage Probe Handle: %lu\n", p.smbps_vprobe); 1048 } 1049 1050 if (p.smbps_cooldev != 0xffff) { 1051 oprintf(fp, " Cooling Device Handle: %lu\n", p.smbps_cooldev); 1052 } 1053 1054 if (p.smbps_iprobe != 0xffff) { 1055 oprintf(fp, " Current Probe Handle: %lu\n", p.smbps_iprobe); 1056 } 1057 } 1058 1059 static void 1060 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp) 1061 { 1062 int i; 1063 smbios_processor_ext_t ep; 1064 1065 if (check_oem(shp) != 0) 1066 return; 1067 1068 (void) smbios_info_extprocessor(shp, id, &ep); 1069 1070 oprintf(fp, " Processor: %u\n", ep.smbpe_processor); 1071 oprintf(fp, " FRU: %u\n", ep.smbpe_fru); 1072 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n); 1073 1074 for (i = 0; i < ep.smbpe_n; i++) { 1075 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i, 1076 ep.smbpe_apicid[i]); 1077 } 1078 } 1079 1080 static void 1081 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp) 1082 { 1083 smbios_port_ext_t epo; 1084 1085 if (check_oem(shp) != 0) 1086 return; 1087 1088 (void) smbios_info_extport(shp, id, &epo); 1089 1090 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis); 1091 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port); 1092 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype); 1093 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl); 1094 oprintf(fp, " PHY: %u\n", epo.smbporte_phy); 1095 } 1096 1097 static void 1098 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp) 1099 { 1100 smbios_pciexrc_t pcie; 1101 1102 if (check_oem(shp) != 0) 1103 return; 1104 1105 (void) smbios_info_pciexrc(shp, id, &pcie); 1106 1107 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb); 1108 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf); 1109 } 1110 1111 static void 1112 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp) 1113 { 1114 smbios_memarray_ext_t em; 1115 1116 if (check_oem(shp) != 0) 1117 return; 1118 1119 (void) smbios_info_extmemarray(shp, id, &em); 1120 1121 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma); 1122 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp); 1123 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf); 1124 } 1125 1126 static void 1127 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 1128 { 1129 int i; 1130 smbios_memdevice_ext_t emd; 1131 1132 if (check_oem(shp) != 0) 1133 return; 1134 1135 (void) smbios_info_extmemdevice(shp, id, &emd); 1136 1137 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md); 1138 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch); 1139 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs); 1140 1141 for (i = 0; i < emd.smbmdeve_ncs; i++) { 1142 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]); 1143 } 1144 } 1145 1146 static int 1147 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 1148 { 1149 smbios_info_t info; 1150 int hex = opt_x; 1151 const char *s; 1152 1153 if (opt_t != -1 && opt_t != sp->smbstr_type) 1154 return (0); /* skip struct if type doesn't match -t */ 1155 1156 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 1157 sp->smbstr_type == SMB_TYPE_MEMMOD)) 1158 return (0); /* skip struct if type is obsolete */ 1159 1160 if (g_hdr++ == 0 || !opt_s) 1161 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 1162 1163 oprintf(fp, "%-5u %-4lu", 1164 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 1165 1166 if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 1167 oprintf(fp, " %s (type %u)", s, sp->smbstr_type); 1168 else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 1169 sp->smbstr_type < SMB_TYPE_OEM_HI) 1170 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO", 1171 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type); 1172 else 1173 oprintf(fp, " %u", sp->smbstr_type); 1174 1175 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 1176 oprintf(fp, " (%s)\n", s); 1177 else 1178 oprintf(fp, "\n"); 1179 1180 if (opt_s) 1181 return (0); /* only print header line if -s specified */ 1182 1183 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 1184 oprintf(fp, "\n"); 1185 print_common(&info, fp); 1186 } 1187 1188 switch (sp->smbstr_type) { 1189 case SMB_TYPE_BIOS: 1190 oprintf(fp, "\n"); 1191 print_bios(shp, fp); 1192 break; 1193 case SMB_TYPE_SYSTEM: 1194 oprintf(fp, "\n"); 1195 print_system(shp, fp); 1196 break; 1197 case SMB_TYPE_BASEBOARD: 1198 oprintf(fp, "\n"); 1199 print_bboard(shp, sp->smbstr_id, fp); 1200 break; 1201 case SMB_TYPE_CHASSIS: 1202 oprintf(fp, "\n"); 1203 print_chassis(shp, sp->smbstr_id, fp); 1204 break; 1205 case SMB_TYPE_PROCESSOR: 1206 oprintf(fp, "\n"); 1207 print_processor(shp, sp->smbstr_id, fp); 1208 break; 1209 case SMB_TYPE_CACHE: 1210 oprintf(fp, "\n"); 1211 print_cache(shp, sp->smbstr_id, fp); 1212 break; 1213 case SMB_TYPE_PORT: 1214 oprintf(fp, "\n"); 1215 print_port(shp, sp->smbstr_id, fp); 1216 break; 1217 case SMB_TYPE_SLOT: 1218 oprintf(fp, "\n"); 1219 print_slot(shp, sp->smbstr_id, fp); 1220 break; 1221 case SMB_TYPE_OBDEVS: 1222 oprintf(fp, "\n"); 1223 print_obdevs(shp, sp->smbstr_id, fp); 1224 break; 1225 case SMB_TYPE_OEMSTR: 1226 case SMB_TYPE_SYSCONFSTR: 1227 oprintf(fp, "\n"); 1228 print_strtab(shp, sp->smbstr_id, fp); 1229 break; 1230 case SMB_TYPE_LANG: 1231 oprintf(fp, "\n"); 1232 print_lang(shp, sp->smbstr_id, fp); 1233 break; 1234 case SMB_TYPE_EVENTLOG: 1235 oprintf(fp, "\n"); 1236 print_evlog(shp, sp->smbstr_id, fp); 1237 break; 1238 case SMB_TYPE_MEMARRAY: 1239 oprintf(fp, "\n"); 1240 print_memarray(shp, sp->smbstr_id, fp); 1241 break; 1242 case SMB_TYPE_MEMDEVICE: 1243 oprintf(fp, "\n"); 1244 print_memdevice(shp, sp->smbstr_id, fp); 1245 break; 1246 case SMB_TYPE_MEMARRAYMAP: 1247 oprintf(fp, "\n"); 1248 print_memarrmap(shp, sp->smbstr_id, fp); 1249 break; 1250 case SMB_TYPE_MEMDEVICEMAP: 1251 oprintf(fp, "\n"); 1252 print_memdevmap(shp, sp->smbstr_id, fp); 1253 break; 1254 case SMB_TYPE_SECURITY: 1255 oprintf(fp, "\n"); 1256 print_hwsec(shp, fp); 1257 break; 1258 case SMB_TYPE_BOOT: 1259 oprintf(fp, "\n"); 1260 print_boot(shp, fp); 1261 break; 1262 case SMB_TYPE_IPMIDEV: 1263 oprintf(fp, "\n"); 1264 print_ipmi(shp, fp); 1265 break; 1266 case SMB_TYPE_POWERSUP: 1267 oprintf(fp, "\n"); 1268 print_powersup(shp, sp->smbstr_id, fp); 1269 break; 1270 case SMB_TYPE_OBDEVEXT: 1271 oprintf(fp, "\n"); 1272 print_obdevs_ext(shp, sp->smbstr_id, fp); 1273 break; 1274 case SUN_OEM_EXT_PROCESSOR: 1275 oprintf(fp, "\n"); 1276 print_extprocessor(shp, sp->smbstr_id, fp); 1277 break; 1278 case SUN_OEM_EXT_PORT: 1279 oprintf(fp, "\n"); 1280 print_extport(shp, sp->smbstr_id, fp); 1281 break; 1282 case SUN_OEM_PCIEXRC: 1283 oprintf(fp, "\n"); 1284 print_pciexrc(shp, sp->smbstr_id, fp); 1285 break; 1286 case SUN_OEM_EXT_MEMARRAY: 1287 oprintf(fp, "\n"); 1288 print_extmemarray(shp, sp->smbstr_id, fp); 1289 break; 1290 case SUN_OEM_EXT_MEMDEVICE: 1291 oprintf(fp, "\n"); 1292 print_extmemdevice(shp, sp->smbstr_id, fp); 1293 break; 1294 default: 1295 hex++; 1296 } 1297 1298 if (hex) 1299 print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 1300 else 1301 oprintf(fp, "\n"); 1302 1303 return (0); 1304 } 1305 1306 static uint16_t 1307 getu16(const char *name, const char *s) 1308 { 1309 u_longlong_t val; 1310 char *p; 1311 1312 errno = 0; 1313 val = strtoull(s, &p, 0); 1314 1315 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 1316 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1317 g_pname, name, s); 1318 exit(SMBIOS_USAGE); 1319 } 1320 1321 return ((uint16_t)val); 1322 } 1323 1324 static uint16_t 1325 getstype(const char *name, const char *s) 1326 { 1327 const char *ts; 1328 uint16_t t; 1329 1330 for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 1331 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 1332 return (t); 1333 } 1334 1335 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1336 g_pname, name, s); 1337 1338 exit(SMBIOS_USAGE); 1339 /*NOTREACHED*/ 1340 } 1341 1342 static int 1343 usage(FILE *fp) 1344 { 1345 (void) fprintf(fp, "Usage: %s " 1346 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 1347 1348 (void) fprintf(fp, 1349 "\t-B disable header validation for broken BIOSes\n" 1350 "\t-e display SMBIOS entry point information\n" 1351 "\t-i display only the specified structure\n" 1352 "\t-O display obsolete structure types\n" 1353 "\t-s display only a summary of structure identifiers and types\n" 1354 "\t-t display only the specified structure type\n" 1355 "\t-w write the raw data to the specified file\n" 1356 "\t-x display raw data for structures\n"); 1357 1358 return (SMBIOS_USAGE); 1359 } 1360 1361 int 1362 main(int argc, char *argv[]) 1363 { 1364 const char *ifile = NULL; 1365 const char *ofile = NULL; 1366 int oflags = 0; 1367 1368 smbios_hdl_t *shp; 1369 smbios_struct_t s; 1370 int err, fd, c; 1371 char *p; 1372 1373 if ((p = strrchr(argv[0], '/')) == NULL) 1374 g_pname = argv[0]; 1375 else 1376 g_pname = p + 1; 1377 1378 while (optind < argc) { 1379 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 1380 switch (c) { 1381 case 'B': 1382 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 1383 break; 1384 case 'e': 1385 opt_e++; 1386 break; 1387 case 'i': 1388 opt_i = getu16("struct ID", optarg); 1389 break; 1390 case 'O': 1391 opt_O++; 1392 break; 1393 case 's': 1394 opt_s++; 1395 break; 1396 case 't': 1397 if (isdigit(optarg[0])) 1398 opt_t = getu16("struct type", optarg); 1399 else 1400 opt_t = getstype("struct type", optarg); 1401 break; 1402 case 'w': 1403 ofile = optarg; 1404 break; 1405 case 'x': 1406 opt_x++; 1407 break; 1408 case 'Z': 1409 oflags |= SMB_O_ZIDS; /* undocumented */ 1410 break; 1411 default: 1412 return (usage(stderr)); 1413 } 1414 } 1415 1416 if (optind < argc) { 1417 if (ifile != NULL) { 1418 (void) fprintf(stderr, "%s: illegal " 1419 "argument -- %s\n", g_pname, argv[optind]); 1420 return (SMBIOS_USAGE); 1421 } 1422 ifile = argv[optind++]; 1423 } 1424 } 1425 1426 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 1427 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 1428 g_pname, smbios_errmsg(err)); 1429 return (SMBIOS_ERROR); 1430 } 1431 1432 if (opt_i == -1 && opt_t == -1 && opt_e == 0 && 1433 smbios_truncated(shp)) 1434 (void) fprintf(stderr, "%s: SMBIOS table is truncated\n", 1435 g_pname); 1436 1437 if (ofile != NULL) { 1438 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 1439 (void) fprintf(stderr, "%s: failed to open %s: %s\n", 1440 g_pname, ofile, strerror(errno)); 1441 err = SMBIOS_ERROR; 1442 } else if (smbios_write(shp, fd) != 0) { 1443 (void) fprintf(stderr, "%s: failed to write %s: %s\n", 1444 g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 1445 err = SMBIOS_ERROR; 1446 } 1447 smbios_close(shp); 1448 return (err); 1449 } 1450 1451 if (opt_e) { 1452 print_smbios(shp, stdout); 1453 smbios_close(shp); 1454 return (SMBIOS_SUCCESS); 1455 } 1456 1457 if (opt_O && (opt_i != -1 || opt_t != -1)) 1458 opt_O++; /* -i or -t imply displaying obsolete records */ 1459 1460 if (opt_i != -1) 1461 err = smbios_lookup_id(shp, opt_i, &s); 1462 else 1463 err = smbios_iter(shp, print_struct, stdout); 1464 1465 if (err != 0) { 1466 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 1467 g_pname, smbios_errmsg(smbios_errno(shp))); 1468 smbios_close(shp); 1469 return (SMBIOS_ERROR); 1470 } 1471 1472 if (opt_i != -1) 1473 (void) print_struct(shp, &s, stdout); 1474 1475 smbios_close(shp); 1476 return (SMBIOS_SUCCESS); 1477 } 1478