1*84ab085aSmws /* 2*84ab085aSmws * CDDL HEADER START 3*84ab085aSmws * 4*84ab085aSmws * The contents of this file are subject to the terms of the 5*84ab085aSmws * Common Development and Distribution License, Version 1.0 only 6*84ab085aSmws * (the "License"). You may not use this file except in compliance 7*84ab085aSmws * with the License. 8*84ab085aSmws * 9*84ab085aSmws * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*84ab085aSmws * or http://www.opensolaris.org/os/licensing. 11*84ab085aSmws * See the License for the specific language governing permissions 12*84ab085aSmws * and limitations under the License. 13*84ab085aSmws * 14*84ab085aSmws * When distributing Covered Code, include this CDDL HEADER in each 15*84ab085aSmws * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*84ab085aSmws * If applicable, add the following below this CDDL HEADER, with the 17*84ab085aSmws * fields enclosed by brackets "[]" replaced with your own identifying 18*84ab085aSmws * information: Portions Copyright [yyyy] [name of copyright owner] 19*84ab085aSmws * 20*84ab085aSmws * CDDL HEADER END 21*84ab085aSmws */ 22*84ab085aSmws 23*84ab085aSmws /* 24*84ab085aSmws * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*84ab085aSmws * Use is subject to license terms. 26*84ab085aSmws */ 27*84ab085aSmws 28*84ab085aSmws #pragma ident "%Z%%M% %I% %E% SMI" 29*84ab085aSmws 30*84ab085aSmws #include <sys/sysmacros.h> 31*84ab085aSmws #include <sys/param.h> 32*84ab085aSmws 33*84ab085aSmws #include <smbios.h> 34*84ab085aSmws #include <alloca.h> 35*84ab085aSmws #include <limits.h> 36*84ab085aSmws #include <unistd.h> 37*84ab085aSmws #include <strings.h> 38*84ab085aSmws #include <stdlib.h> 39*84ab085aSmws #include <stdarg.h> 40*84ab085aSmws #include <stdio.h> 41*84ab085aSmws #include <fcntl.h> 42*84ab085aSmws #include <errno.h> 43*84ab085aSmws #include <ctype.h> 44*84ab085aSmws 45*84ab085aSmws #define SMBIOS_SUCCESS 0 46*84ab085aSmws #define SMBIOS_ERROR 1 47*84ab085aSmws #define SMBIOS_USAGE 2 48*84ab085aSmws 49*84ab085aSmws static const char *g_pname; 50*84ab085aSmws static int g_hdr; 51*84ab085aSmws 52*84ab085aSmws static int opt_e; 53*84ab085aSmws static int opt_i = -1; 54*84ab085aSmws static int opt_O; 55*84ab085aSmws static int opt_s; 56*84ab085aSmws static int opt_t = -1; 57*84ab085aSmws static int opt_x; 58*84ab085aSmws 59*84ab085aSmws /*PRINTFLIKE2*/ 60*84ab085aSmws static void 61*84ab085aSmws oprintf(FILE *fp, const char *format, ...) 62*84ab085aSmws { 63*84ab085aSmws va_list ap; 64*84ab085aSmws 65*84ab085aSmws va_start(ap, format); 66*84ab085aSmws (void) vfprintf(fp, format, ap); 67*84ab085aSmws va_end(ap); 68*84ab085aSmws } 69*84ab085aSmws 70*84ab085aSmws /*PRINTFLIKE3*/ 71*84ab085aSmws static void 72*84ab085aSmws desc_printf(const char *d, FILE *fp, const char *format, ...) 73*84ab085aSmws { 74*84ab085aSmws va_list ap; 75*84ab085aSmws 76*84ab085aSmws va_start(ap, format); 77*84ab085aSmws (void) vfprintf(fp, format, ap); 78*84ab085aSmws va_end(ap); 79*84ab085aSmws 80*84ab085aSmws if (d != NULL) 81*84ab085aSmws (void) fprintf(fp, " (%s)\n", d); 82*84ab085aSmws else 83*84ab085aSmws (void) fprintf(fp, "\n"); 84*84ab085aSmws } 85*84ab085aSmws 86*84ab085aSmws static void 87*84ab085aSmws flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits, 88*84ab085aSmws const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t)) 89*84ab085aSmws { 90*84ab085aSmws size_t i; 91*84ab085aSmws 92*84ab085aSmws oprintf(fp, " %s: 0x%x\n", s, flags); 93*84ab085aSmws 94*84ab085aSmws for (i = 0; i < bits; i++) { 95*84ab085aSmws uint_t f = 1 << i; 96*84ab085aSmws const char *n; 97*84ab085aSmws 98*84ab085aSmws if (!(flags & f)) 99*84ab085aSmws continue; 100*84ab085aSmws 101*84ab085aSmws if ((n = flag_name(f)) != NULL) 102*84ab085aSmws desc_printf(flag_desc(f), fp, "\t%s", n); 103*84ab085aSmws else 104*84ab085aSmws desc_printf(flag_desc(f), fp, "\t0x%x", f); 105*84ab085aSmws } 106*84ab085aSmws } 107*84ab085aSmws 108*84ab085aSmws static void 109*84ab085aSmws flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits, 110*84ab085aSmws const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t)) 111*84ab085aSmws { 112*84ab085aSmws size_t i; 113*84ab085aSmws 114*84ab085aSmws oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags); 115*84ab085aSmws 116*84ab085aSmws for (i = 0; i < bits; i++) { 117*84ab085aSmws u_longlong_t f = 1ULL << i; 118*84ab085aSmws const char *n; 119*84ab085aSmws 120*84ab085aSmws if (!(flags & f)) 121*84ab085aSmws continue; 122*84ab085aSmws 123*84ab085aSmws if ((n = flag_name(f)) != NULL) 124*84ab085aSmws desc_printf(flag_desc(f), fp, "\t%s", n); 125*84ab085aSmws else 126*84ab085aSmws desc_printf(flag_desc(f), fp, "\t0x%llx", f); 127*84ab085aSmws } 128*84ab085aSmws } 129*84ab085aSmws 130*84ab085aSmws static void 131*84ab085aSmws id_printf(FILE *fp, const char *s, id_t id) 132*84ab085aSmws { 133*84ab085aSmws switch (id) { 134*84ab085aSmws case SMB_ID_NONE: 135*84ab085aSmws oprintf(fp, "%sNone\n", s); 136*84ab085aSmws break; 137*84ab085aSmws case SMB_ID_NOTSUP: 138*84ab085aSmws oprintf(fp, "%sNot Supported\n", s); 139*84ab085aSmws break; 140*84ab085aSmws default: 141*84ab085aSmws oprintf(fp, "%s%u\n", s, (uint_t)id); 142*84ab085aSmws } 143*84ab085aSmws } 144*84ab085aSmws 145*84ab085aSmws static void 146*84ab085aSmws print_smbios(smbios_hdl_t *shp, FILE *fp) 147*84ab085aSmws { 148*84ab085aSmws smbios_entry_t ep; 149*84ab085aSmws int i; 150*84ab085aSmws 151*84ab085aSmws smbios_info_smbios(shp, &ep); 152*84ab085aSmws 153*84ab085aSmws oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 154*84ab085aSmws (int)sizeof (ep.smbe_eanchor), (int)sizeof (ep.smbe_eanchor), 155*84ab085aSmws ep.smbe_eanchor); 156*84ab085aSmws 157*84ab085aSmws oprintf(fp, "Entry Point Checksum: 0x%x\n", ep.smbe_ecksum); 158*84ab085aSmws oprintf(fp, "Entry Point Length: %u\n", ep.smbe_elen); 159*84ab085aSmws oprintf(fp, "Entry Point Version: %u.%u\n", 160*84ab085aSmws ep.smbe_major, ep.smbe_minor); 161*84ab085aSmws oprintf(fp, "Max Structure Size: %u\n", ep.smbe_maxssize); 162*84ab085aSmws oprintf(fp, "Entry Point Revision: 0x%x\n", ep.smbe_revision); 163*84ab085aSmws 164*84ab085aSmws oprintf(fp, "Entry Point Revision Data:"); 165*84ab085aSmws for (i = 0; i < sizeof (ep.smbe_format); i++) 166*84ab085aSmws oprintf(fp, " 0x%02x", ep.smbe_format[i]); 167*84ab085aSmws oprintf(fp, "\n"); 168*84ab085aSmws 169*84ab085aSmws oprintf(fp, "Intermediate Anchor Tag: %*.*s\n", 170*84ab085aSmws (int)sizeof (ep.smbe_ianchor), (int)sizeof (ep.smbe_ianchor), 171*84ab085aSmws ep.smbe_ianchor); 172*84ab085aSmws 173*84ab085aSmws oprintf(fp, "Intermediate Checksum: 0x%x\n", ep.smbe_icksum); 174*84ab085aSmws oprintf(fp, "Structure Table Length: %u\n", ep.smbe_stlen); 175*84ab085aSmws oprintf(fp, "Structure Table Address: 0x%x\n", ep.smbe_staddr); 176*84ab085aSmws oprintf(fp, "Structure Table Entries: %u\n", ep.smbe_stnum); 177*84ab085aSmws oprintf(fp, "DMI BCD Revision: 0x%x\n", ep.smbe_bcdrev); 178*84ab085aSmws } 179*84ab085aSmws 180*84ab085aSmws static void 181*84ab085aSmws print_common(const smbios_info_t *ip, FILE *fp) 182*84ab085aSmws { 183*84ab085aSmws if (ip->smbi_manufacturer[0] != '\0') 184*84ab085aSmws oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer); 185*84ab085aSmws if (ip->smbi_product[0] != '\0') 186*84ab085aSmws oprintf(fp, " Product: %s\n", ip->smbi_product); 187*84ab085aSmws if (ip->smbi_version[0] != '\0') 188*84ab085aSmws oprintf(fp, " Version: %s\n", ip->smbi_version); 189*84ab085aSmws if (ip->smbi_serial[0] != '\0') 190*84ab085aSmws oprintf(fp, " Serial Number: %s\n", ip->smbi_serial); 191*84ab085aSmws if (ip->smbi_asset[0] != '\0') 192*84ab085aSmws oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset); 193*84ab085aSmws if (ip->smbi_location[0] != '\0') 194*84ab085aSmws oprintf(fp, " Location Tag: %s\n", ip->smbi_location); 195*84ab085aSmws if (ip->smbi_part[0] != '\0') 196*84ab085aSmws oprintf(fp, " Part Number: %s\n", ip->smbi_part); 197*84ab085aSmws } 198*84ab085aSmws 199*84ab085aSmws static void 200*84ab085aSmws print_bios(smbios_hdl_t *shp, FILE *fp) 201*84ab085aSmws { 202*84ab085aSmws smbios_bios_t b; 203*84ab085aSmws 204*84ab085aSmws (void) smbios_info_bios(shp, &b); 205*84ab085aSmws 206*84ab085aSmws oprintf(fp, " Vendor: %s\n", b.smbb_vendor); 207*84ab085aSmws oprintf(fp, " Version String: %s\n", b.smbb_version); 208*84ab085aSmws oprintf(fp, " Release Date: %s\n", b.smbb_reldate); 209*84ab085aSmws oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment); 210*84ab085aSmws oprintf(fp, " ROM Size: %u bytes\n", b.smbb_romsize); 211*84ab085aSmws oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize); 212*84ab085aSmws 213*84ab085aSmws flag64_printf(fp, "Characteristics", 214*84ab085aSmws b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY, 215*84ab085aSmws smbios_bios_flag_name, smbios_bios_flag_desc); 216*84ab085aSmws 217*84ab085aSmws if (b.smbb_nxcflags > SMB_BIOSXB_1) { 218*84ab085aSmws flag_printf(fp, "Characteristics Extension Byte 1", 219*84ab085aSmws b.smbb_xcflags[SMB_BIOSXB_1], 220*84ab085aSmws sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY, 221*84ab085aSmws smbios_bios_xb1_name, smbios_bios_xb1_desc); 222*84ab085aSmws } 223*84ab085aSmws 224*84ab085aSmws if (b.smbb_nxcflags > SMB_BIOSXB_2) { 225*84ab085aSmws flag_printf(fp, "Characteristics Extension Byte 2", 226*84ab085aSmws b.smbb_xcflags[SMB_BIOSXB_2], 227*84ab085aSmws sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY, 228*84ab085aSmws smbios_bios_xb2_name, smbios_bios_xb2_desc); 229*84ab085aSmws } 230*84ab085aSmws 231*84ab085aSmws if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) { 232*84ab085aSmws oprintf(fp, " Version Number: %u.%u\n", 233*84ab085aSmws b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor); 234*84ab085aSmws } 235*84ab085aSmws 236*84ab085aSmws if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN) { 237*84ab085aSmws oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n", 238*84ab085aSmws b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor); 239*84ab085aSmws } 240*84ab085aSmws } 241*84ab085aSmws 242*84ab085aSmws static void 243*84ab085aSmws print_system(smbios_hdl_t *shp, FILE *fp) 244*84ab085aSmws { 245*84ab085aSmws smbios_system_t s; 246*84ab085aSmws uint_t i; 247*84ab085aSmws 248*84ab085aSmws (void) smbios_info_system(shp, &s); 249*84ab085aSmws 250*84ab085aSmws oprintf(fp, " UUID: "); 251*84ab085aSmws for (i = 0; i < s.smbs_uuidlen; i++) { 252*84ab085aSmws oprintf(fp, "%02x", s.smbs_uuid[i]); 253*84ab085aSmws if (i == 3 || i == 5 || i == 7 || i == 9) 254*84ab085aSmws oprintf(fp, "-"); 255*84ab085aSmws } 256*84ab085aSmws oprintf(fp, "\n"); 257*84ab085aSmws 258*84ab085aSmws desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup), 259*84ab085aSmws fp, " Wake-Up Event: 0x%x", s.smbs_wakeup); 260*84ab085aSmws 261*84ab085aSmws oprintf(fp, " SKU Number: %s\n", s.smbs_sku); 262*84ab085aSmws oprintf(fp, " Family: %s\n", s.smbs_family); 263*84ab085aSmws } 264*84ab085aSmws 265*84ab085aSmws static void 266*84ab085aSmws print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp) 267*84ab085aSmws { 268*84ab085aSmws smbios_bboard_t b; 269*84ab085aSmws 270*84ab085aSmws (void) smbios_info_bboard(shp, id, &b); 271*84ab085aSmws 272*84ab085aSmws oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis); 273*84ab085aSmws 274*84ab085aSmws flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY, 275*84ab085aSmws smbios_bboard_flag_name, smbios_bboard_flag_desc); 276*84ab085aSmws 277*84ab085aSmws desc_printf(smbios_bboard_type_desc(b.smbb_type), 278*84ab085aSmws fp, " Board Type: 0x%x", b.smbb_type); 279*84ab085aSmws } 280*84ab085aSmws 281*84ab085aSmws static void 282*84ab085aSmws print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp) 283*84ab085aSmws { 284*84ab085aSmws smbios_chassis_t c; 285*84ab085aSmws 286*84ab085aSmws (void) smbios_info_chassis(shp, id, &c); 287*84ab085aSmws 288*84ab085aSmws oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata); 289*84ab085aSmws oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N"); 290*84ab085aSmws 291*84ab085aSmws desc_printf(smbios_chassis_type_desc(c.smbc_type), 292*84ab085aSmws fp, " Chassis Type: 0x%x", c.smbc_type); 293*84ab085aSmws 294*84ab085aSmws desc_printf(smbios_chassis_state_desc(c.smbc_bustate), 295*84ab085aSmws fp, " Boot-Up State: 0x%x", c.smbc_bustate); 296*84ab085aSmws 297*84ab085aSmws desc_printf(smbios_chassis_state_desc(c.smbc_psstate), 298*84ab085aSmws fp, " Power Supply State: 0x%x", c.smbc_psstate); 299*84ab085aSmws 300*84ab085aSmws desc_printf(smbios_chassis_state_desc(c.smbc_thstate), 301*84ab085aSmws fp, " Thermal State: 0x%x", c.smbc_thstate); 302*84ab085aSmws 303*84ab085aSmws oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight); 304*84ab085aSmws oprintf(fp, " Power Cords: %u\n", c.smbc_cords); 305*84ab085aSmws oprintf(fp, " Element Records: %u\n", c.smbc_elems); 306*84ab085aSmws } 307*84ab085aSmws 308*84ab085aSmws static void 309*84ab085aSmws print_processor(smbios_hdl_t *shp, id_t id, FILE *fp) 310*84ab085aSmws { 311*84ab085aSmws smbios_processor_t p; 312*84ab085aSmws uint_t status; 313*84ab085aSmws 314*84ab085aSmws (void) smbios_info_processor(shp, id, &p); 315*84ab085aSmws status = SMB_PRSTATUS_STATUS(p.smbp_status); 316*84ab085aSmws 317*84ab085aSmws desc_printf(smbios_processor_family_desc(p.smbp_family), 318*84ab085aSmws fp, " Family: %u", p.smbp_family); 319*84ab085aSmws 320*84ab085aSmws oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid); 321*84ab085aSmws 322*84ab085aSmws desc_printf(smbios_processor_type_desc(p.smbp_type), 323*84ab085aSmws fp, " Type: %u", p.smbp_type); 324*84ab085aSmws 325*84ab085aSmws desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade), 326*84ab085aSmws fp, " Socket Upgrade: %u", p.smbp_upgrade); 327*84ab085aSmws 328*84ab085aSmws oprintf(fp, " Socket Status: %s\n", 329*84ab085aSmws SMB_PRSTATUS_PRESENT(p.smbp_status) ? 330*84ab085aSmws "Populated" : "Not Populated"); 331*84ab085aSmws 332*84ab085aSmws desc_printf(smbios_processor_status_desc(status), 333*84ab085aSmws fp, " Processor Status: %u", status); 334*84ab085aSmws 335*84ab085aSmws if (SMB_PRV_LEGACY(p.smbp_voltage)) { 336*84ab085aSmws oprintf(fp, " Supported Voltages:"); 337*84ab085aSmws switch (p.smbp_voltage) { 338*84ab085aSmws case SMB_PRV_5V: 339*84ab085aSmws oprintf(fp, " 5.0V"); 340*84ab085aSmws break; 341*84ab085aSmws case SMB_PRV_33V: 342*84ab085aSmws oprintf(fp, " 3.3V"); 343*84ab085aSmws break; 344*84ab085aSmws case SMB_PRV_29V: 345*84ab085aSmws oprintf(fp, " 2.9V"); 346*84ab085aSmws break; 347*84ab085aSmws } 348*84ab085aSmws oprintf(fp, "\n"); 349*84ab085aSmws } else { 350*84ab085aSmws oprintf(fp, " Supported Voltages: %.1fV\n", 351*84ab085aSmws (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10); 352*84ab085aSmws } 353*84ab085aSmws 354*84ab085aSmws if (p.smbp_clkspeed != 0) 355*84ab085aSmws oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed); 356*84ab085aSmws else 357*84ab085aSmws oprintf(fp, " External Clock Speed: Unknown\n"); 358*84ab085aSmws 359*84ab085aSmws if (p.smbp_maxspeed != 0) 360*84ab085aSmws oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed); 361*84ab085aSmws else 362*84ab085aSmws oprintf(fp, " Maximum Speed: Unknown\n"); 363*84ab085aSmws 364*84ab085aSmws if (p.smbp_curspeed != 0) 365*84ab085aSmws oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed); 366*84ab085aSmws else 367*84ab085aSmws oprintf(fp, " Current Speed: Unknown\n"); 368*84ab085aSmws 369*84ab085aSmws id_printf(fp, " L1 Cache: ", p.smbp_l1cache); 370*84ab085aSmws id_printf(fp, " L2 Cache: ", p.smbp_l2cache); 371*84ab085aSmws id_printf(fp, " L3 Cache: ", p.smbp_l3cache); 372*84ab085aSmws } 373*84ab085aSmws 374*84ab085aSmws static void 375*84ab085aSmws print_cache(smbios_hdl_t *shp, id_t id, FILE *fp) 376*84ab085aSmws { 377*84ab085aSmws smbios_cache_t c; 378*84ab085aSmws 379*84ab085aSmws (void) smbios_info_cache(shp, id, &c); 380*84ab085aSmws 381*84ab085aSmws oprintf(fp, " Level: %u\n", c.smba_level); 382*84ab085aSmws oprintf(fp, " Maximum Installed Size: %u bytes\n", c.smba_maxsize); 383*84ab085aSmws 384*84ab085aSmws if (c.smba_size != 0) 385*84ab085aSmws oprintf(fp, " Installed Size: %u bytes\n", c.smba_size); 386*84ab085aSmws else 387*84ab085aSmws oprintf(fp, " Installed Size: Not Installed\n"); 388*84ab085aSmws 389*84ab085aSmws if (c.smba_speed != 0) 390*84ab085aSmws oprintf(fp, " Speed: %uns\n", c.smba_speed); 391*84ab085aSmws else 392*84ab085aSmws oprintf(fp, " Speed: Unknown\n"); 393*84ab085aSmws 394*84ab085aSmws flag_printf(fp, "Supported SRAM Types", 395*84ab085aSmws c.smba_stype, sizeof (c.smba_stype) * NBBY, 396*84ab085aSmws smbios_cache_ctype_name, smbios_cache_ctype_desc); 397*84ab085aSmws 398*84ab085aSmws desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 399*84ab085aSmws fp, " Current SRAM Type: 0x%x", c.smba_ctype); 400*84ab085aSmws 401*84ab085aSmws desc_printf(smbios_cache_ecc_desc(c.smba_etype), 402*84ab085aSmws fp, " Error Correction Type: %u", c.smba_etype); 403*84ab085aSmws 404*84ab085aSmws desc_printf(smbios_cache_logical_desc(c.smba_ltype), 405*84ab085aSmws fp, " Logical Cache Type: %u", c.smba_ltype); 406*84ab085aSmws 407*84ab085aSmws desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 408*84ab085aSmws fp, " Associativity: %u", c.smba_assoc); 409*84ab085aSmws 410*84ab085aSmws desc_printf(smbios_cache_mode_desc(c.smba_mode), 411*84ab085aSmws fp, " Mode: %u", c.smba_mode); 412*84ab085aSmws 413*84ab085aSmws desc_printf(smbios_cache_loc_desc(c.smba_location), 414*84ab085aSmws fp, " Location: %u", c.smba_location); 415*84ab085aSmws 416*84ab085aSmws flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 417*84ab085aSmws smbios_cache_flag_name, smbios_cache_flag_desc); 418*84ab085aSmws } 419*84ab085aSmws 420*84ab085aSmws static void 421*84ab085aSmws print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 422*84ab085aSmws { 423*84ab085aSmws smbios_port_t p; 424*84ab085aSmws 425*84ab085aSmws (void) smbios_info_port(shp, id, &p); 426*84ab085aSmws 427*84ab085aSmws oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref); 428*84ab085aSmws oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref); 429*84ab085aSmws 430*84ab085aSmws desc_printf(smbios_port_conn_desc(p.smbo_itype), 431*84ab085aSmws fp, " Internal Connector Type: %u", p.smbo_itype); 432*84ab085aSmws 433*84ab085aSmws desc_printf(smbios_port_conn_desc(p.smbo_etype), 434*84ab085aSmws fp, " External Connector Type: %u", p.smbo_etype); 435*84ab085aSmws 436*84ab085aSmws desc_printf(smbios_port_type_desc(p.smbo_ptype), 437*84ab085aSmws fp, " Port Type: %u", p.smbo_ptype); 438*84ab085aSmws } 439*84ab085aSmws 440*84ab085aSmws static void 441*84ab085aSmws print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 442*84ab085aSmws { 443*84ab085aSmws smbios_slot_t s; 444*84ab085aSmws 445*84ab085aSmws (void) smbios_info_slot(shp, id, &s); 446*84ab085aSmws 447*84ab085aSmws oprintf(fp, " Reference Designator: %s\n", s.smbl_name); 448*84ab085aSmws oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 449*84ab085aSmws 450*84ab085aSmws desc_printf(smbios_slot_type_desc(s.smbl_type), 451*84ab085aSmws fp, " Type: 0x%x", s.smbl_type); 452*84ab085aSmws 453*84ab085aSmws desc_printf(smbios_slot_width_desc(s.smbl_width), 454*84ab085aSmws fp, " Width: 0x%x", s.smbl_width); 455*84ab085aSmws 456*84ab085aSmws desc_printf(smbios_slot_usage_desc(s.smbl_usage), 457*84ab085aSmws fp, " Usage: 0x%x", s.smbl_usage); 458*84ab085aSmws 459*84ab085aSmws desc_printf(smbios_slot_length_desc(s.smbl_length), 460*84ab085aSmws fp, " Length: 0x%x", s.smbl_length); 461*84ab085aSmws 462*84ab085aSmws flag_printf(fp, "Slot Characteristics 1", 463*84ab085aSmws s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 464*84ab085aSmws smbios_slot_ch1_name, smbios_slot_ch1_desc); 465*84ab085aSmws 466*84ab085aSmws flag_printf(fp, "Slot Characteristics 2", 467*84ab085aSmws s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 468*84ab085aSmws smbios_slot_ch2_name, smbios_slot_ch2_desc); 469*84ab085aSmws } 470*84ab085aSmws 471*84ab085aSmws static void 472*84ab085aSmws print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 473*84ab085aSmws { 474*84ab085aSmws smbios_obdev_t *argv; 475*84ab085aSmws int i, argc; 476*84ab085aSmws 477*84ab085aSmws if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 478*84ab085aSmws argv = alloca(sizeof (smbios_obdev_t) * argc); 479*84ab085aSmws (void) smbios_info_obdevs(shp, id, argc, argv); 480*84ab085aSmws for (i = 0; i < argc; i++) 481*84ab085aSmws oprintf(fp, " %s\n", argv[i].smbd_name); 482*84ab085aSmws } 483*84ab085aSmws } 484*84ab085aSmws 485*84ab085aSmws static void 486*84ab085aSmws print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 487*84ab085aSmws { 488*84ab085aSmws const char **argv; 489*84ab085aSmws int i, argc; 490*84ab085aSmws 491*84ab085aSmws if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 492*84ab085aSmws argv = alloca(sizeof (char *) * argc); 493*84ab085aSmws (void) smbios_info_strtab(shp, id, argc, argv); 494*84ab085aSmws for (i = 0; i < argc; i++) 495*84ab085aSmws oprintf(fp, " %s\n", argv[i]); 496*84ab085aSmws } 497*84ab085aSmws } 498*84ab085aSmws 499*84ab085aSmws static void 500*84ab085aSmws print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 501*84ab085aSmws { 502*84ab085aSmws smbios_lang_t l; 503*84ab085aSmws 504*84ab085aSmws (void) smbios_info_lang(shp, &l); 505*84ab085aSmws 506*84ab085aSmws oprintf(fp, " Current Language: %s\n", l.smbla_cur); 507*84ab085aSmws oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 508*84ab085aSmws oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 509*84ab085aSmws oprintf(fp, " Installed Languages:\n"); 510*84ab085aSmws 511*84ab085aSmws print_strtab(shp, id, fp); 512*84ab085aSmws } 513*84ab085aSmws 514*84ab085aSmws /*ARGSUSED*/ 515*84ab085aSmws static void 516*84ab085aSmws print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 517*84ab085aSmws { 518*84ab085aSmws smbios_evlog_t ev; 519*84ab085aSmws uint32_t i; 520*84ab085aSmws 521*84ab085aSmws (void) smbios_info_eventlog(shp, &ev); 522*84ab085aSmws 523*84ab085aSmws oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 524*84ab085aSmws oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 525*84ab085aSmws oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 526*84ab085aSmws 527*84ab085aSmws desc_printf(smbios_evlog_method_desc(ev.smbev_method), 528*84ab085aSmws fp, " Data Access Method: %u", ev.smbev_method); 529*84ab085aSmws 530*84ab085aSmws flag_printf(fp, "Log Flags", 531*84ab085aSmws ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 532*84ab085aSmws smbios_evlog_flag_name, smbios_evlog_flag_desc); 533*84ab085aSmws 534*84ab085aSmws desc_printf(smbios_evlog_format_desc(ev.smbev_format), 535*84ab085aSmws fp, " Log Header Format: %u", ev.smbev_format); 536*84ab085aSmws 537*84ab085aSmws oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 538*84ab085aSmws oprintf(fp, " Data Access Address: "); 539*84ab085aSmws 540*84ab085aSmws switch (ev.smbev_method) { 541*84ab085aSmws case SMB_EVM_1x1i_1x1d: 542*84ab085aSmws case SMB_EVM_2x1i_1x1d: 543*84ab085aSmws case SMB_EVM_1x2i_1x1d: 544*84ab085aSmws oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 545*84ab085aSmws ev.smbev_addr.eva_io.evi_iaddr, 546*84ab085aSmws ev.smbev_addr.eva_io.evi_daddr); 547*84ab085aSmws break; 548*84ab085aSmws case SMB_EVM_GPNV: 549*84ab085aSmws oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 550*84ab085aSmws break; 551*84ab085aSmws default: 552*84ab085aSmws oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 553*84ab085aSmws } 554*84ab085aSmws 555*84ab085aSmws oprintf(fp, " Type Descriptors:\n"); 556*84ab085aSmws 557*84ab085aSmws for (i = 0; i < ev.smbev_typec; i++) { 558*84ab085aSmws oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 559*84ab085aSmws ev.smbev_typev[i].smbevt_ltype, 560*84ab085aSmws ev.smbev_typev[i].smbevt_dtype); 561*84ab085aSmws } 562*84ab085aSmws } 563*84ab085aSmws 564*84ab085aSmws static void 565*84ab085aSmws print_bytes(const uint8_t *data, size_t size, FILE *fp) 566*84ab085aSmws { 567*84ab085aSmws size_t row, rows = P2ROUNDUP(size, 16) / 16; 568*84ab085aSmws size_t col, cols; 569*84ab085aSmws 570*84ab085aSmws char buf[17]; 571*84ab085aSmws uint8_t x; 572*84ab085aSmws 573*84ab085aSmws oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 574*84ab085aSmws "0123456789abcdef\n"); 575*84ab085aSmws 576*84ab085aSmws for (row = 0; row < rows; row++) { 577*84ab085aSmws oprintf(fp, " %#4lx: ", (ulong_t)row * 16); 578*84ab085aSmws cols = MIN(size - row * 16, 16); 579*84ab085aSmws 580*84ab085aSmws for (col = 0; col < cols; col++) { 581*84ab085aSmws if (col % 4 == 0) 582*84ab085aSmws oprintf(fp, " "); 583*84ab085aSmws x = *data++; 584*84ab085aSmws oprintf(fp, "%02x", x); 585*84ab085aSmws buf[col] = x <= ' ' || x > '~' ? '.' : x; 586*84ab085aSmws } 587*84ab085aSmws 588*84ab085aSmws for (; col < 16; col++) { 589*84ab085aSmws if (col % 4 == 0) 590*84ab085aSmws oprintf(fp, " "); 591*84ab085aSmws oprintf(fp, " "); 592*84ab085aSmws buf[col] = ' '; 593*84ab085aSmws } 594*84ab085aSmws 595*84ab085aSmws buf[col] = '\0'; 596*84ab085aSmws oprintf(fp, " %s\n", buf); 597*84ab085aSmws } 598*84ab085aSmws 599*84ab085aSmws oprintf(fp, "\n"); 600*84ab085aSmws } 601*84ab085aSmws 602*84ab085aSmws static void 603*84ab085aSmws print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 604*84ab085aSmws { 605*84ab085aSmws smbios_memarray_t ma; 606*84ab085aSmws 607*84ab085aSmws (void) smbios_info_memarray(shp, id, &ma); 608*84ab085aSmws 609*84ab085aSmws desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 610*84ab085aSmws fp, " Location: %u", ma.smbma_location); 611*84ab085aSmws 612*84ab085aSmws desc_printf(smbios_memarray_use_desc(ma.smbma_use), 613*84ab085aSmws fp, " Use: %u", ma.smbma_use); 614*84ab085aSmws 615*84ab085aSmws desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 616*84ab085aSmws fp, " ECC: %u", ma.smbma_ecc); 617*84ab085aSmws 618*84ab085aSmws oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 619*84ab085aSmws id_printf(fp, " Memory Error Data: ", ma.smbma_err); 620*84ab085aSmws oprintf(fp, " Max Capacity: %llu bytes\n", 621*84ab085aSmws (u_longlong_t)ma.smbma_size); 622*84ab085aSmws } 623*84ab085aSmws 624*84ab085aSmws static void 625*84ab085aSmws print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 626*84ab085aSmws { 627*84ab085aSmws smbios_memdevice_t md; 628*84ab085aSmws 629*84ab085aSmws (void) smbios_info_memdevice(shp, id, &md); 630*84ab085aSmws 631*84ab085aSmws id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 632*84ab085aSmws id_printf(fp, " Memory Error Data: ", md.smbmd_error); 633*84ab085aSmws 634*84ab085aSmws if (md.smbmd_twidth != -1u) 635*84ab085aSmws oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 636*84ab085aSmws else 637*84ab085aSmws oprintf(fp, " Total Width: Unknown\n"); 638*84ab085aSmws 639*84ab085aSmws if (md.smbmd_dwidth != -1u) 640*84ab085aSmws oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 641*84ab085aSmws else 642*84ab085aSmws oprintf(fp, " Data Width: Unknown\n"); 643*84ab085aSmws 644*84ab085aSmws switch (md.smbmd_size) { 645*84ab085aSmws case -1ull: 646*84ab085aSmws oprintf(fp, " Size: Unknown\n"); 647*84ab085aSmws break; 648*84ab085aSmws case 0: 649*84ab085aSmws oprintf(fp, " Size: Not Populated\n"); 650*84ab085aSmws break; 651*84ab085aSmws default: 652*84ab085aSmws oprintf(fp, " Size: %llu bytes\n", 653*84ab085aSmws (u_longlong_t)md.smbmd_size); 654*84ab085aSmws } 655*84ab085aSmws 656*84ab085aSmws desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 657*84ab085aSmws fp, " Form Factor: %u", md.smbmd_form); 658*84ab085aSmws 659*84ab085aSmws if (md.smbmd_set == 0) 660*84ab085aSmws oprintf(fp, " Set: None\n"); 661*84ab085aSmws else if (md.smbmd_set == (uint8_t)-1u) 662*84ab085aSmws oprintf(fp, " Set: Unknown\n"); 663*84ab085aSmws else 664*84ab085aSmws oprintf(fp, " Set: %u\n", md.smbmd_set); 665*84ab085aSmws 666*84ab085aSmws desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 667*84ab085aSmws fp, " Memory Type: %u", md.smbmd_type); 668*84ab085aSmws 669*84ab085aSmws flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 670*84ab085aSmws smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 671*84ab085aSmws 672*84ab085aSmws if (md.smbmd_speed != 0) 673*84ab085aSmws oprintf(fp, " Speed: %uns\n", md.smbmd_speed); 674*84ab085aSmws else 675*84ab085aSmws oprintf(fp, " Speed: Unknown\n"); 676*84ab085aSmws 677*84ab085aSmws oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc); 678*84ab085aSmws oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc); 679*84ab085aSmws } 680*84ab085aSmws 681*84ab085aSmws static void 682*84ab085aSmws print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 683*84ab085aSmws { 684*84ab085aSmws smbios_memarrmap_t ma; 685*84ab085aSmws 686*84ab085aSmws (void) smbios_info_memarrmap(shp, id, &ma); 687*84ab085aSmws 688*84ab085aSmws id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 689*84ab085aSmws oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 690*84ab085aSmws 691*84ab085aSmws oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 692*84ab085aSmws (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 693*84ab085aSmws } 694*84ab085aSmws 695*84ab085aSmws static void 696*84ab085aSmws print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 697*84ab085aSmws { 698*84ab085aSmws smbios_memdevmap_t md; 699*84ab085aSmws 700*84ab085aSmws (void) smbios_info_memdevmap(shp, id, &md); 701*84ab085aSmws 702*84ab085aSmws id_printf(fp, " Memory Device: ", md.smbmdm_device); 703*84ab085aSmws id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 704*84ab085aSmws 705*84ab085aSmws oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 706*84ab085aSmws (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 707*84ab085aSmws 708*84ab085aSmws oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 709*84ab085aSmws oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 710*84ab085aSmws oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 711*84ab085aSmws } 712*84ab085aSmws 713*84ab085aSmws static void 714*84ab085aSmws print_hwsec(smbios_hdl_t *shp, FILE *fp) 715*84ab085aSmws { 716*84ab085aSmws smbios_hwsec_t h; 717*84ab085aSmws 718*84ab085aSmws (void) smbios_info_hwsec(shp, &h); 719*84ab085aSmws 720*84ab085aSmws desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 721*84ab085aSmws fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 722*84ab085aSmws desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 723*84ab085aSmws fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 724*84ab085aSmws desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 725*84ab085aSmws fp, " Administrator Password Status: %u", h.smbh_adm_ps); 726*84ab085aSmws desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 727*84ab085aSmws fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 728*84ab085aSmws } 729*84ab085aSmws 730*84ab085aSmws static void 731*84ab085aSmws print_boot(smbios_hdl_t *shp, FILE *fp) 732*84ab085aSmws { 733*84ab085aSmws smbios_boot_t b; 734*84ab085aSmws 735*84ab085aSmws (void) smbios_info_boot(shp, &b); 736*84ab085aSmws 737*84ab085aSmws desc_printf(smbios_boot_desc(b.smbt_status), 738*84ab085aSmws fp, " Boot Status Code: 0x%x", b.smbt_status); 739*84ab085aSmws 740*84ab085aSmws if (b.smbt_size != 0) { 741*84ab085aSmws oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 742*84ab085aSmws print_bytes(b.smbt_data, b.smbt_size, fp); 743*84ab085aSmws } 744*84ab085aSmws } 745*84ab085aSmws 746*84ab085aSmws static void 747*84ab085aSmws print_ipmi(smbios_hdl_t *shp, FILE *fp) 748*84ab085aSmws { 749*84ab085aSmws smbios_ipmi_t i; 750*84ab085aSmws 751*84ab085aSmws (void) smbios_info_ipmi(shp, &i); 752*84ab085aSmws 753*84ab085aSmws desc_printf(smbios_ipmi_type_desc(i.smbip_type), 754*84ab085aSmws fp, " Type: %u", i.smbip_type); 755*84ab085aSmws 756*84ab085aSmws oprintf(fp, " BMC IPMI Version: %u.%u\n", 757*84ab085aSmws i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 758*84ab085aSmws 759*84ab085aSmws oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 760*84ab085aSmws oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 761*84ab085aSmws oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 762*84ab085aSmws oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 763*84ab085aSmws oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 764*84ab085aSmws 765*84ab085aSmws flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 766*84ab085aSmws smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 767*84ab085aSmws } 768*84ab085aSmws 769*84ab085aSmws static int 770*84ab085aSmws print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 771*84ab085aSmws { 772*84ab085aSmws smbios_info_t info; 773*84ab085aSmws int hex = opt_x; 774*84ab085aSmws const char *s; 775*84ab085aSmws 776*84ab085aSmws if (opt_t != -1 && opt_t != sp->smbstr_type) 777*84ab085aSmws return (0); /* skip struct if type doesn't match -t */ 778*84ab085aSmws 779*84ab085aSmws if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 780*84ab085aSmws sp->smbstr_type == SMB_TYPE_MEMMOD)) 781*84ab085aSmws return (0); /* skip struct if type is obsolete */ 782*84ab085aSmws 783*84ab085aSmws if (g_hdr++ == 0 || !opt_s) 784*84ab085aSmws oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 785*84ab085aSmws 786*84ab085aSmws oprintf(fp, "%-5u %-4lu", 787*84ab085aSmws (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 788*84ab085aSmws 789*84ab085aSmws if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 790*84ab085aSmws oprintf(fp, " %s", s); 791*84ab085aSmws else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 792*84ab085aSmws sp->smbstr_type < SMB_TYPE_OEM_HI) 793*84ab085aSmws oprintf(fp, " %s+%u", "SMB_TYPE_OEM_LO", 794*84ab085aSmws sp->smbstr_type - SMB_TYPE_OEM_LO); 795*84ab085aSmws else 796*84ab085aSmws oprintf(fp, " %u", sp->smbstr_type); 797*84ab085aSmws 798*84ab085aSmws if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 799*84ab085aSmws oprintf(fp, " (%s)\n", s); 800*84ab085aSmws else 801*84ab085aSmws oprintf(fp, "\n"); 802*84ab085aSmws 803*84ab085aSmws if (opt_s) 804*84ab085aSmws return (0); /* only print header line if -s specified */ 805*84ab085aSmws 806*84ab085aSmws if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 807*84ab085aSmws oprintf(fp, "\n"); 808*84ab085aSmws print_common(&info, fp); 809*84ab085aSmws } 810*84ab085aSmws 811*84ab085aSmws switch (sp->smbstr_type) { 812*84ab085aSmws case SMB_TYPE_BIOS: 813*84ab085aSmws oprintf(fp, "\n"); 814*84ab085aSmws print_bios(shp, fp); 815*84ab085aSmws break; 816*84ab085aSmws case SMB_TYPE_SYSTEM: 817*84ab085aSmws oprintf(fp, "\n"); 818*84ab085aSmws print_system(shp, fp); 819*84ab085aSmws break; 820*84ab085aSmws case SMB_TYPE_BASEBOARD: 821*84ab085aSmws oprintf(fp, "\n"); 822*84ab085aSmws print_bboard(shp, sp->smbstr_id, fp); 823*84ab085aSmws break; 824*84ab085aSmws case SMB_TYPE_CHASSIS: 825*84ab085aSmws oprintf(fp, "\n"); 826*84ab085aSmws print_chassis(shp, sp->smbstr_id, fp); 827*84ab085aSmws break; 828*84ab085aSmws case SMB_TYPE_PROCESSOR: 829*84ab085aSmws oprintf(fp, "\n"); 830*84ab085aSmws print_processor(shp, sp->smbstr_id, fp); 831*84ab085aSmws break; 832*84ab085aSmws case SMB_TYPE_CACHE: 833*84ab085aSmws oprintf(fp, "\n"); 834*84ab085aSmws print_cache(shp, sp->smbstr_id, fp); 835*84ab085aSmws break; 836*84ab085aSmws case SMB_TYPE_PORT: 837*84ab085aSmws oprintf(fp, "\n"); 838*84ab085aSmws print_port(shp, sp->smbstr_id, fp); 839*84ab085aSmws break; 840*84ab085aSmws case SMB_TYPE_SLOT: 841*84ab085aSmws oprintf(fp, "\n"); 842*84ab085aSmws print_slot(shp, sp->smbstr_id, fp); 843*84ab085aSmws break; 844*84ab085aSmws case SMB_TYPE_OBDEVS: 845*84ab085aSmws oprintf(fp, "\n"); 846*84ab085aSmws print_obdevs(shp, sp->smbstr_id, fp); 847*84ab085aSmws break; 848*84ab085aSmws case SMB_TYPE_OEMSTR: 849*84ab085aSmws case SMB_TYPE_SYSCONFSTR: 850*84ab085aSmws oprintf(fp, "\n"); 851*84ab085aSmws print_strtab(shp, sp->smbstr_id, fp); 852*84ab085aSmws break; 853*84ab085aSmws case SMB_TYPE_LANG: 854*84ab085aSmws oprintf(fp, "\n"); 855*84ab085aSmws print_lang(shp, sp->smbstr_id, fp); 856*84ab085aSmws break; 857*84ab085aSmws case SMB_TYPE_EVENTLOG: 858*84ab085aSmws oprintf(fp, "\n"); 859*84ab085aSmws print_evlog(shp, sp->smbstr_id, fp); 860*84ab085aSmws break; 861*84ab085aSmws case SMB_TYPE_MEMARRAY: 862*84ab085aSmws oprintf(fp, "\n"); 863*84ab085aSmws print_memarray(shp, sp->smbstr_id, fp); 864*84ab085aSmws break; 865*84ab085aSmws case SMB_TYPE_MEMDEVICE: 866*84ab085aSmws oprintf(fp, "\n"); 867*84ab085aSmws print_memdevice(shp, sp->smbstr_id, fp); 868*84ab085aSmws break; 869*84ab085aSmws case SMB_TYPE_MEMARRAYMAP: 870*84ab085aSmws oprintf(fp, "\n"); 871*84ab085aSmws print_memarrmap(shp, sp->smbstr_id, fp); 872*84ab085aSmws break; 873*84ab085aSmws case SMB_TYPE_MEMDEVICEMAP: 874*84ab085aSmws oprintf(fp, "\n"); 875*84ab085aSmws print_memdevmap(shp, sp->smbstr_id, fp); 876*84ab085aSmws break; 877*84ab085aSmws case SMB_TYPE_SECURITY: 878*84ab085aSmws oprintf(fp, "\n"); 879*84ab085aSmws print_hwsec(shp, fp); 880*84ab085aSmws break; 881*84ab085aSmws case SMB_TYPE_BOOT: 882*84ab085aSmws oprintf(fp, "\n"); 883*84ab085aSmws print_boot(shp, fp); 884*84ab085aSmws break; 885*84ab085aSmws case SMB_TYPE_IPMIDEV: 886*84ab085aSmws oprintf(fp, "\n"); 887*84ab085aSmws print_ipmi(shp, fp); 888*84ab085aSmws break; 889*84ab085aSmws default: 890*84ab085aSmws hex++; 891*84ab085aSmws } 892*84ab085aSmws 893*84ab085aSmws if (hex) 894*84ab085aSmws print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 895*84ab085aSmws else 896*84ab085aSmws oprintf(fp, "\n"); 897*84ab085aSmws 898*84ab085aSmws return (0); 899*84ab085aSmws } 900*84ab085aSmws 901*84ab085aSmws static uint16_t 902*84ab085aSmws getu16(const char *name, const char *s) 903*84ab085aSmws { 904*84ab085aSmws u_longlong_t val; 905*84ab085aSmws char *p; 906*84ab085aSmws 907*84ab085aSmws errno = 0; 908*84ab085aSmws val = strtoull(s, &p, 0); 909*84ab085aSmws 910*84ab085aSmws if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 911*84ab085aSmws (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 912*84ab085aSmws g_pname, name, s); 913*84ab085aSmws exit(SMBIOS_USAGE); 914*84ab085aSmws } 915*84ab085aSmws 916*84ab085aSmws return ((uint16_t)val); 917*84ab085aSmws } 918*84ab085aSmws 919*84ab085aSmws static uint16_t 920*84ab085aSmws getstype(const char *name, const char *s) 921*84ab085aSmws { 922*84ab085aSmws const char *ts; 923*84ab085aSmws uint16_t t; 924*84ab085aSmws 925*84ab085aSmws for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 926*84ab085aSmws if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 927*84ab085aSmws return (t); 928*84ab085aSmws } 929*84ab085aSmws 930*84ab085aSmws (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 931*84ab085aSmws g_pname, name, s); 932*84ab085aSmws 933*84ab085aSmws exit(SMBIOS_USAGE); 934*84ab085aSmws /*NOTREACHED*/ 935*84ab085aSmws } 936*84ab085aSmws 937*84ab085aSmws static int 938*84ab085aSmws usage(FILE *fp) 939*84ab085aSmws { 940*84ab085aSmws (void) fprintf(fp, "Usage: %s " 941*84ab085aSmws "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 942*84ab085aSmws 943*84ab085aSmws (void) fprintf(fp, 944*84ab085aSmws "\t-B disable header validation for broken BIOSes\n" 945*84ab085aSmws "\t-e display SMBIOS entry point information\n" 946*84ab085aSmws "\t-i display only the specified structure\n" 947*84ab085aSmws "\t-O display obsolete structure types\n" 948*84ab085aSmws "\t-s display only a summary of structure identifiers and types\n" 949*84ab085aSmws "\t-t display only the specified structure type\n" 950*84ab085aSmws "\t-w write the raw data to the specified file\n" 951*84ab085aSmws "\t-x display raw data for structures\n"); 952*84ab085aSmws 953*84ab085aSmws return (SMBIOS_USAGE); 954*84ab085aSmws } 955*84ab085aSmws 956*84ab085aSmws int 957*84ab085aSmws main(int argc, char *argv[]) 958*84ab085aSmws { 959*84ab085aSmws const char *ifile = NULL; 960*84ab085aSmws const char *ofile = NULL; 961*84ab085aSmws int oflags = 0; 962*84ab085aSmws 963*84ab085aSmws smbios_hdl_t *shp; 964*84ab085aSmws smbios_struct_t s; 965*84ab085aSmws int err, fd, c; 966*84ab085aSmws char *p; 967*84ab085aSmws 968*84ab085aSmws if ((p = strrchr(argv[0], '/')) == NULL) 969*84ab085aSmws g_pname = argv[0]; 970*84ab085aSmws else 971*84ab085aSmws g_pname = p + 1; 972*84ab085aSmws 973*84ab085aSmws while (optind < argc) { 974*84ab085aSmws while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 975*84ab085aSmws switch (c) { 976*84ab085aSmws case 'B': 977*84ab085aSmws oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 978*84ab085aSmws break; 979*84ab085aSmws case 'e': 980*84ab085aSmws opt_e++; 981*84ab085aSmws break; 982*84ab085aSmws case 'i': 983*84ab085aSmws opt_i = getu16("struct ID", optarg); 984*84ab085aSmws break; 985*84ab085aSmws case 'O': 986*84ab085aSmws opt_O++; 987*84ab085aSmws break; 988*84ab085aSmws case 's': 989*84ab085aSmws opt_s++; 990*84ab085aSmws break; 991*84ab085aSmws case 't': 992*84ab085aSmws if (isdigit(optarg[0])) 993*84ab085aSmws opt_t = getu16("struct type", optarg); 994*84ab085aSmws else 995*84ab085aSmws opt_t = getstype("struct type", optarg); 996*84ab085aSmws break; 997*84ab085aSmws case 'w': 998*84ab085aSmws ofile = optarg; 999*84ab085aSmws break; 1000*84ab085aSmws case 'x': 1001*84ab085aSmws opt_x++; 1002*84ab085aSmws break; 1003*84ab085aSmws case 'Z': 1004*84ab085aSmws oflags |= SMB_O_ZIDS; /* undocumented */ 1005*84ab085aSmws break; 1006*84ab085aSmws default: 1007*84ab085aSmws return (usage(stderr)); 1008*84ab085aSmws } 1009*84ab085aSmws } 1010*84ab085aSmws 1011*84ab085aSmws if (optind < argc) { 1012*84ab085aSmws if (ifile != NULL) { 1013*84ab085aSmws (void) fprintf(stderr, "%s: illegal " 1014*84ab085aSmws "argument -- %s\n", g_pname, argv[optind]); 1015*84ab085aSmws return (SMBIOS_USAGE); 1016*84ab085aSmws } 1017*84ab085aSmws ifile = argv[optind++]; 1018*84ab085aSmws } 1019*84ab085aSmws } 1020*84ab085aSmws 1021*84ab085aSmws if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 1022*84ab085aSmws (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 1023*84ab085aSmws g_pname, smbios_errmsg(err)); 1024*84ab085aSmws return (SMBIOS_ERROR); 1025*84ab085aSmws } 1026*84ab085aSmws 1027*84ab085aSmws if (ofile != NULL) { 1028*84ab085aSmws if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 1029*84ab085aSmws (void) fprintf(stderr, "%s: failed to open %s: %s\n", 1030*84ab085aSmws g_pname, ofile, strerror(errno)); 1031*84ab085aSmws err = SMBIOS_ERROR; 1032*84ab085aSmws } else if (smbios_write(shp, fd) != 0) { 1033*84ab085aSmws (void) fprintf(stderr, "%s: failed to write %s: %s\n", 1034*84ab085aSmws g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 1035*84ab085aSmws err = SMBIOS_ERROR; 1036*84ab085aSmws } 1037*84ab085aSmws smbios_close(shp); 1038*84ab085aSmws return (err); 1039*84ab085aSmws } 1040*84ab085aSmws 1041*84ab085aSmws if (opt_e) { 1042*84ab085aSmws print_smbios(shp, stdout); 1043*84ab085aSmws smbios_close(shp); 1044*84ab085aSmws return (SMBIOS_SUCCESS); 1045*84ab085aSmws } 1046*84ab085aSmws 1047*84ab085aSmws if (opt_O && (opt_i != -1 || opt_t != -1)) 1048*84ab085aSmws opt_O++; /* -i or -t imply displaying obsolete records */ 1049*84ab085aSmws 1050*84ab085aSmws if (opt_i != -1) 1051*84ab085aSmws err = smbios_lookup_id(shp, opt_i, &s); 1052*84ab085aSmws else 1053*84ab085aSmws err = smbios_iter(shp, print_struct, stdout); 1054*84ab085aSmws 1055*84ab085aSmws if (err != 0) { 1056*84ab085aSmws (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 1057*84ab085aSmws g_pname, smbios_errmsg(smbios_errno(shp))); 1058*84ab085aSmws smbios_close(shp); 1059*84ab085aSmws return (SMBIOS_ERROR); 1060*84ab085aSmws } 1061*84ab085aSmws 1062*84ab085aSmws if (opt_i != -1) 1063*84ab085aSmws (void) print_struct(shp, &s, stdout); 1064*84ab085aSmws 1065*84ab085aSmws smbios_close(shp); 1066*84ab085aSmws return (SMBIOS_SUCCESS); 1067*84ab085aSmws } 1068