17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1820c2cdShyw * Common Development and Distribution License (the "License"). 6*1820c2cdShyw * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*1820c2cdShyw * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* LINTLIBRARY */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * String conversion routine for hardware capabilities types. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate #include <strings.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <ctype.h> 357c478bd9Sstevel@tonic-gate #include <limits.h> 367c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 377c478bd9Sstevel@tonic-gate #include <sys/elf.h> 387c478bd9Sstevel@tonic-gate #include <sys/auxv_SPARC.h> 397c478bd9Sstevel@tonic-gate #include <sys/auxv_386.h> 407c478bd9Sstevel@tonic-gate #include <elfcap.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * Define separators for val2str processing. 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate static const Fmt_desc format[] = { 467c478bd9Sstevel@tonic-gate {" ", 1 }, 477c478bd9Sstevel@tonic-gate {" ", 2 }, 487c478bd9Sstevel@tonic-gate {" | ", 3 } 497c478bd9Sstevel@tonic-gate }; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * Define all known capabilities as both lower and upper case strings. This 537c478bd9Sstevel@tonic-gate * duplication is necessary, rather than have one string and use something 547c478bd9Sstevel@tonic-gate * like toupper(), as a client such as ld.so.1 doesn't need the overhead of 557c478bd9Sstevel@tonic-gate * dragging in the internationalization support of toupper(). The Intel 3DNow 567c478bd9Sstevel@tonic-gate * flags are a slightly odd convention too. 577c478bd9Sstevel@tonic-gate * 587c478bd9Sstevel@tonic-gate * Define all known software capabilities. 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 617c478bd9Sstevel@tonic-gate static const char Sf1_fpknwn[] = "FPKNWN"; 627c478bd9Sstevel@tonic-gate static const char Sf1_fpused[] = "FPUSED"; 637c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 647c478bd9Sstevel@tonic-gate static const char Sf1_fpknwn[] = "fpknwn"; 657c478bd9Sstevel@tonic-gate static const char Sf1_fpused[] = "fpused"; 667c478bd9Sstevel@tonic-gate #else 677c478bd9Sstevel@tonic-gate #error "Software Capabilities - what case do you want?" 687c478bd9Sstevel@tonic-gate #endif 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * Order the software capabilities to match their numeric value. See SF1_SUNW_ 727c478bd9Sstevel@tonic-gate * values in sys/elf.h. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate static const Cap_desc sf1[] = { 757c478bd9Sstevel@tonic-gate { SF1_SUNW_FPKNWN, Sf1_fpknwn, (sizeof (Sf1_fpknwn) - 1) }, 767c478bd9Sstevel@tonic-gate { SF1_SUNW_FPUSED, Sf1_fpused, (sizeof (Sf1_fpused) - 1) } 777c478bd9Sstevel@tonic-gate }; 787c478bd9Sstevel@tonic-gate static const uint_t sf1_num = sizeof (sf1) / sizeof (Cap_desc); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * Define all known SPARC hardware capabilities. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 847c478bd9Sstevel@tonic-gate static const char Hw1_s_mul32[] = "MUL32"; 857c478bd9Sstevel@tonic-gate static const char Hw1_s_div32[] = "DIV32"; 867c478bd9Sstevel@tonic-gate static const char Hw1_s_fsmuld[] = "FSMULD"; 877c478bd9Sstevel@tonic-gate static const char Hw1_s_v8plus[] = "V8PLUS"; 887c478bd9Sstevel@tonic-gate static const char Hw1_s_popc[] = "POPC"; 897c478bd9Sstevel@tonic-gate static const char Hw1_s_vis[] = "VIS"; 907c478bd9Sstevel@tonic-gate static const char Hw1_s_vis2[] = "VIS2"; 917c478bd9Sstevel@tonic-gate static const char Hw1_s_asi_blk_init[] = "ASI_BLK_INIT"; 92*1820c2cdShyw static const char Hw1_s_fmaf[] = "FMAF"; 937c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 947c478bd9Sstevel@tonic-gate static const char Hw1_s_mul32[] = "mul32"; 957c478bd9Sstevel@tonic-gate static const char Hw1_s_div32[] = "div32"; 967c478bd9Sstevel@tonic-gate static const char Hw1_s_fsmuld[] = "fsmuld"; 977c478bd9Sstevel@tonic-gate static const char Hw1_s_v8plus[] = "v8plus"; 987c478bd9Sstevel@tonic-gate static const char Hw1_s_popc[] = "popc"; 997c478bd9Sstevel@tonic-gate static const char Hw1_s_vis[] = "vis"; 1007c478bd9Sstevel@tonic-gate static const char Hw1_s_vis2[] = "vis2"; 1017c478bd9Sstevel@tonic-gate static const char Hw1_s_asi_blk_init[] = "asi_blk_init"; 102*1820c2cdShyw static const char Hw1_s_fmaf[] = "fmaf"; 103*1820c2cdShyw 1047c478bd9Sstevel@tonic-gate #else 1057c478bd9Sstevel@tonic-gate #error "Hardware Capabilities (sparc) - what case do you want?" 1067c478bd9Sstevel@tonic-gate #endif 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate /* 1097c478bd9Sstevel@tonic-gate * Order the SPARC hardware capabilities to match their numeric value. See 1107c478bd9Sstevel@tonic-gate * AV_SPARC_ values in sys/auxv_SPARC.h. 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate static const Cap_desc hw1_s[] = { 1137c478bd9Sstevel@tonic-gate { AV_SPARC_MUL32, Hw1_s_mul32, sizeof (Hw1_s_mul32) - 1 }, 1147c478bd9Sstevel@tonic-gate { AV_SPARC_DIV32, Hw1_s_div32, sizeof (Hw1_s_div32) - 1 }, 1157c478bd9Sstevel@tonic-gate { AV_SPARC_FSMULD, Hw1_s_fsmuld, sizeof (Hw1_s_fsmuld) - 1 }, 1167c478bd9Sstevel@tonic-gate { AV_SPARC_V8PLUS, Hw1_s_v8plus, sizeof (Hw1_s_v8plus) - 1 }, 1177c478bd9Sstevel@tonic-gate { AV_SPARC_POPC, Hw1_s_popc, sizeof (Hw1_s_popc) - 1 }, 1187c478bd9Sstevel@tonic-gate { AV_SPARC_VIS, Hw1_s_vis, sizeof (Hw1_s_vis) - 1 }, 1197c478bd9Sstevel@tonic-gate { AV_SPARC_VIS2, Hw1_s_vis2, sizeof (Hw1_s_vis2) - 1 }, 1207c478bd9Sstevel@tonic-gate { AV_SPARC_ASI_BLK_INIT, Hw1_s_asi_blk_init, 121*1820c2cdShyw sizeof (Hw1_s_asi_blk_init) - 1 }, 122*1820c2cdShyw { AV_SPARC_FMAF, Hw1_s_fmaf, sizeof (Hw1_s_fmaf) - 1 } 1237c478bd9Sstevel@tonic-gate }; 1247c478bd9Sstevel@tonic-gate static const uint_t hw1_s_num = sizeof (hw1_s) / sizeof (Cap_desc); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * Define all known Intel hardware capabilities. 1287c478bd9Sstevel@tonic-gate */ 1297c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 1307c478bd9Sstevel@tonic-gate static const char Hw1_i_fpu[] = "FPU"; 1317c478bd9Sstevel@tonic-gate static const char Hw1_i_tsc[] = "TSC"; 1327c478bd9Sstevel@tonic-gate static const char Hw1_i_cx8[] = "CX8"; 1337c478bd9Sstevel@tonic-gate static const char Hw1_i_sep[] = "SEP"; 1347c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_sysc[] = "AMD_SYSC"; 1357c478bd9Sstevel@tonic-gate static const char Hw1_i_cmov[] = "CMOV"; 1367c478bd9Sstevel@tonic-gate static const char Hw1_i_mmx[] = "MMX"; 1377c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_mmx[] = "AMD_MMX"; 1387c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnow[] = "AMD_3DNow"; 1397c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnowx[] = "AMD_3DNowx"; 1407c478bd9Sstevel@tonic-gate static const char Hw1_i_fxsr[] = "FXSR"; 1417c478bd9Sstevel@tonic-gate static const char Hw1_i_sse[] = "SSE"; 1427c478bd9Sstevel@tonic-gate static const char Hw1_i_sse2[] = "SSE2"; 1437c478bd9Sstevel@tonic-gate static const char Hw1_i_pause[] = "PAUSE"; 1447c478bd9Sstevel@tonic-gate static const char Hw1_i_sse3[] = "SSE3"; 1457c478bd9Sstevel@tonic-gate static const char Hw1_i_mon[] = "MON"; 1467c478bd9Sstevel@tonic-gate static const char Hw1_i_cx16[] = "CX16"; 1477c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 1487c478bd9Sstevel@tonic-gate static const char Hw1_i_fpu[] = "fpu"; 1497c478bd9Sstevel@tonic-gate static const char Hw1_i_tsc[] = "tsc"; 1507c478bd9Sstevel@tonic-gate static const char Hw1_i_cx8[] = "cx8"; 1517c478bd9Sstevel@tonic-gate static const char Hw1_i_sep[] = "sep"; 1527c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_sysc[] = "amd_sysc"; 1537c478bd9Sstevel@tonic-gate static const char Hw1_i_cmov[] = "cmov"; 1547c478bd9Sstevel@tonic-gate static const char Hw1_i_mmx[] = "mmx"; 1557c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_mmx[] = "amd_mmx"; 1567c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnow[] = "amd_3dnow"; 1577c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnowx[] = "amd_3dnowx"; 1587c478bd9Sstevel@tonic-gate static const char Hw1_i_fxsr[] = "fxsr"; 1597c478bd9Sstevel@tonic-gate static const char Hw1_i_sse[] = "sse"; 1607c478bd9Sstevel@tonic-gate static const char Hw1_i_sse2[] = "sse2"; 1617c478bd9Sstevel@tonic-gate static const char Hw1_i_pause[] = "pause"; 1627c478bd9Sstevel@tonic-gate static const char Hw1_i_sse3[] = "sse3"; 1637c478bd9Sstevel@tonic-gate static const char Hw1_i_mon[] = "mon"; 1647c478bd9Sstevel@tonic-gate static const char Hw1_i_cx16[] = "cx16"; 1657c478bd9Sstevel@tonic-gate #else 1667c478bd9Sstevel@tonic-gate #error "Hardware Capabilities (intel) - what case do you want?" 1677c478bd9Sstevel@tonic-gate #endif 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * Order the Intel hardware capabilities to match their numeric value. See 1717c478bd9Sstevel@tonic-gate * AV_386_ values in sys/auxv_386.h. 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate static const Cap_desc hw1_i[] = { 1747c478bd9Sstevel@tonic-gate { AV_386_FPU, Hw1_i_fpu, sizeof (Hw1_i_fpu) - 1 }, 1757c478bd9Sstevel@tonic-gate { AV_386_TSC, Hw1_i_tsc, sizeof (Hw1_i_tsc) - 1 }, 1767c478bd9Sstevel@tonic-gate { AV_386_CX8, Hw1_i_cx8, sizeof (Hw1_i_cx8) - 1 }, 1777c478bd9Sstevel@tonic-gate { AV_386_SEP, Hw1_i_sep, sizeof (Hw1_i_sep) - 1 }, 1787c478bd9Sstevel@tonic-gate { AV_386_AMD_SYSC, Hw1_i_amd_sysc, sizeof (Hw1_i_amd_sysc) - 1 }, 1797c478bd9Sstevel@tonic-gate { AV_386_CMOV, Hw1_i_cmov, sizeof (Hw1_i_cmov) - 1 }, 1807c478bd9Sstevel@tonic-gate { AV_386_MMX, Hw1_i_mmx, sizeof (Hw1_i_mmx) - 1 }, 1817c478bd9Sstevel@tonic-gate { AV_386_AMD_MMX, Hw1_i_amd_mmx, sizeof (Hw1_i_amd_mmx) - 1 }, 1827c478bd9Sstevel@tonic-gate { AV_386_AMD_3DNow, Hw1_i_amd_3dnow, 1837c478bd9Sstevel@tonic-gate sizeof (Hw1_i_amd_3dnow) - 1 }, 1847c478bd9Sstevel@tonic-gate { AV_386_AMD_3DNowx, Hw1_i_amd_3dnowx, 1857c478bd9Sstevel@tonic-gate sizeof (Hw1_i_amd_3dnowx) - 1 }, 1867c478bd9Sstevel@tonic-gate { AV_386_FXSR, Hw1_i_fxsr, sizeof (Hw1_i_fxsr) - 1 }, 1877c478bd9Sstevel@tonic-gate { AV_386_SSE, Hw1_i_sse, sizeof (Hw1_i_sse) - 1 }, 1887c478bd9Sstevel@tonic-gate { AV_386_SSE2, Hw1_i_sse2, sizeof (Hw1_i_sse2) - 1 }, 1897c478bd9Sstevel@tonic-gate { AV_386_PAUSE, Hw1_i_pause, sizeof (Hw1_i_pause) - 1 }, 1907c478bd9Sstevel@tonic-gate { AV_386_SSE3, Hw1_i_sse3, sizeof (Hw1_i_sse3) - 1 }, 1917c478bd9Sstevel@tonic-gate { AV_386_MON, Hw1_i_mon, sizeof (Hw1_i_mon) - 1 }, 1927c478bd9Sstevel@tonic-gate { AV_386_CX16, Hw1_i_cx16, sizeof (Hw1_i_cx16) - 1 } 1937c478bd9Sstevel@tonic-gate }; 1947c478bd9Sstevel@tonic-gate static const uint_t hw1_i_num = sizeof (hw1_i) / sizeof (Cap_desc); 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * Concatenate a token to the string buffer. This can be a capailities token 1987c478bd9Sstevel@tonic-gate * or a separator token. 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate static int 2017c478bd9Sstevel@tonic-gate token(char **ostr, size_t *olen, const char *nstr, size_t nlen) 2027c478bd9Sstevel@tonic-gate { 2037c478bd9Sstevel@tonic-gate if (*olen < nlen) 2047c478bd9Sstevel@tonic-gate return (CAP_ERR_BUFOVFL); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate (void) strcat(*ostr, nstr); 2077c478bd9Sstevel@tonic-gate *ostr += nlen; 2087c478bd9Sstevel@tonic-gate *olen -= nlen; 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate return (0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * Expand a capabilities value into the strings defined in the associated 2157c478bd9Sstevel@tonic-gate * capabilities descriptor. 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate static int 2187c478bd9Sstevel@tonic-gate expand(uint64_t val, const Cap_desc *cdp, uint_t cnum, char *str, size_t slen, 2197c478bd9Sstevel@tonic-gate int fmt) 2207c478bd9Sstevel@tonic-gate { 2217c478bd9Sstevel@tonic-gate uint_t cnt, mask; 2227c478bd9Sstevel@tonic-gate int follow = 0, err; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (val == 0) 2257c478bd9Sstevel@tonic-gate return (0); 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate for (cnt = WORD_BIT, mask = 0x80000000; cnt; cnt--, 2287c478bd9Sstevel@tonic-gate (mask = mask >> 1)) { 2297c478bd9Sstevel@tonic-gate if ((val & mask) && (cnt <= cnum) && cdp[cnt - 1].c_val) { 2307c478bd9Sstevel@tonic-gate if (follow++ && ((err = token(&str, &slen, 2317c478bd9Sstevel@tonic-gate format[fmt].f_str, format[fmt].f_len)) != 0)) 2327c478bd9Sstevel@tonic-gate return (err); 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate if ((err = token(&str, &slen, cdp[cnt - 1].c_str, 2357c478bd9Sstevel@tonic-gate cdp[cnt - 1].c_len)) != 0) 2367c478bd9Sstevel@tonic-gate return (err); 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate val = val & ~mask; 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* 2437c478bd9Sstevel@tonic-gate * If there are any unknown bits remaining display the numeric value. 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate if (val) { 2467c478bd9Sstevel@tonic-gate if (follow && ((err = token(&str, &slen, format[fmt].f_str, 2477c478bd9Sstevel@tonic-gate format[fmt].f_len)) != 0)) 2487c478bd9Sstevel@tonic-gate return (err); 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate (void) snprintf(str, slen, "0x%llx", val); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate return (0); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * Expand a CA_SUNW_HW_1 value. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate int 2597c478bd9Sstevel@tonic-gate hwcap_1_val2str(uint64_t val, char *str, size_t len, int fmt, ushort_t mach) 2607c478bd9Sstevel@tonic-gate { 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * Initialize the string buffer, and validate the format request. 2637c478bd9Sstevel@tonic-gate */ 2647c478bd9Sstevel@tonic-gate *str = '\0'; 2657c478bd9Sstevel@tonic-gate if (fmt > CAP_MAX_TYPE) 2667c478bd9Sstevel@tonic-gate return (CAP_ERR_INVFMT); 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64)) 2697c478bd9Sstevel@tonic-gate return (expand(val, &hw1_i[0], hw1_i_num, str, len, fmt)); 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 2727c478bd9Sstevel@tonic-gate (mach == EM_SPARCV9)) 2737c478bd9Sstevel@tonic-gate return (expand(val, &hw1_s[0], hw1_s_num, str, len, fmt)); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate return (CAP_ERR_UNKMACH); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Expand a CA_SUNW_SF_1 value. Note, that at present these capabilities are 2807c478bd9Sstevel@tonic-gate * common across all platforms. The use of "mach" is therefore redundant, but 2817c478bd9Sstevel@tonic-gate * is retained for compatibility with the interface of hwcap_1_val2str(), and 2827c478bd9Sstevel@tonic-gate * possible future expansion. 2837c478bd9Sstevel@tonic-gate */ 2847c478bd9Sstevel@tonic-gate int 2857c478bd9Sstevel@tonic-gate /* ARGSUSED4 */ 2867c478bd9Sstevel@tonic-gate sfcap_1_val2str(uint64_t val, char *str, size_t len, int fmt, ushort_t mach) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate /* 2897c478bd9Sstevel@tonic-gate * Initialize the string buffer, and validate the format request. 2907c478bd9Sstevel@tonic-gate */ 2917c478bd9Sstevel@tonic-gate *str = '\0'; 2927c478bd9Sstevel@tonic-gate if (fmt > CAP_MAX_TYPE) 2937c478bd9Sstevel@tonic-gate return (CAP_ERR_INVFMT); 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate return (expand(val, &sf1[0], sf1_num, str, len, fmt)); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * Determine capability type from the capability tag. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate int 3027c478bd9Sstevel@tonic-gate cap_val2str(uint64_t tag, uint64_t val, char *str, size_t len, int fmt, 3037c478bd9Sstevel@tonic-gate ushort_t mach) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate if (tag == CA_SUNW_HW_1) 3067c478bd9Sstevel@tonic-gate return (hwcap_1_val2str(val, str, len, fmt, mach)); 3077c478bd9Sstevel@tonic-gate if (tag == CA_SUNW_SF_1) 3087c478bd9Sstevel@tonic-gate return (sfcap_1_val2str(val, str, len, fmt, mach)); 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate return (CAP_ERR_UNKTAG); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * Determine a capabilities value from a capabilities string. 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate static uint64_t 3177c478bd9Sstevel@tonic-gate value(const char *str, const Cap_desc *cdp, uint_t cnum) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate uint_t num; 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate for (num = 0; num < cnum; num++) { 3227c478bd9Sstevel@tonic-gate if (strcmp(str, cdp[num].c_str) == 0) 3237c478bd9Sstevel@tonic-gate return (cdp[num].c_val); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate return (0); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate uint64_t 3297c478bd9Sstevel@tonic-gate sfcap_1_str2val(const char *str, ushort_t mach) 3307c478bd9Sstevel@tonic-gate { 3317c478bd9Sstevel@tonic-gate return (value(str, &sf1[0], sf1_num)); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate uint64_t 3357c478bd9Sstevel@tonic-gate hwcap_1_str2val(const char *str, ushort_t mach) 3367c478bd9Sstevel@tonic-gate { 3377c478bd9Sstevel@tonic-gate if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64)) 3387c478bd9Sstevel@tonic-gate return (value(str, &hw1_i[0], hw1_i_num)); 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 3417c478bd9Sstevel@tonic-gate (mach == EM_SPARCV9)) 3427c478bd9Sstevel@tonic-gate return (value(str, &hw1_s[0], hw1_s_num)); 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate return (0); 3457c478bd9Sstevel@tonic-gate } 346