1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate /* LINTLIBRARY */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * String conversion routine for hardware capabilities types. 32*7c478bd9Sstevel@tonic-gate */ 33*7c478bd9Sstevel@tonic-gate #include <strings.h> 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <ctype.h> 36*7c478bd9Sstevel@tonic-gate #include <limits.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/elf.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/auxv_SPARC.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/auxv_386.h> 41*7c478bd9Sstevel@tonic-gate #include <elfcap.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* 44*7c478bd9Sstevel@tonic-gate * Define separators for val2str processing. 45*7c478bd9Sstevel@tonic-gate */ 46*7c478bd9Sstevel@tonic-gate static const Fmt_desc format[] = { 47*7c478bd9Sstevel@tonic-gate {" ", 1 }, 48*7c478bd9Sstevel@tonic-gate {" ", 2 }, 49*7c478bd9Sstevel@tonic-gate {" | ", 3 } 50*7c478bd9Sstevel@tonic-gate }; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* 53*7c478bd9Sstevel@tonic-gate * Define all known capabilities as both lower and upper case strings. This 54*7c478bd9Sstevel@tonic-gate * duplication is necessary, rather than have one string and use something 55*7c478bd9Sstevel@tonic-gate * like toupper(), as a client such as ld.so.1 doesn't need the overhead of 56*7c478bd9Sstevel@tonic-gate * dragging in the internationalization support of toupper(). The Intel 3DNow 57*7c478bd9Sstevel@tonic-gate * flags are a slightly odd convention too. 58*7c478bd9Sstevel@tonic-gate * 59*7c478bd9Sstevel@tonic-gate * Define all known software capabilities. 60*7c478bd9Sstevel@tonic-gate */ 61*7c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 62*7c478bd9Sstevel@tonic-gate static const char Sf1_fpknwn[] = "FPKNWN"; 63*7c478bd9Sstevel@tonic-gate static const char Sf1_fpused[] = "FPUSED"; 64*7c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 65*7c478bd9Sstevel@tonic-gate static const char Sf1_fpknwn[] = "fpknwn"; 66*7c478bd9Sstevel@tonic-gate static const char Sf1_fpused[] = "fpused"; 67*7c478bd9Sstevel@tonic-gate #else 68*7c478bd9Sstevel@tonic-gate #error "Software Capabilities - what case do you want?" 69*7c478bd9Sstevel@tonic-gate #endif 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate * Order the software capabilities to match their numeric value. See SF1_SUNW_ 73*7c478bd9Sstevel@tonic-gate * values in sys/elf.h. 74*7c478bd9Sstevel@tonic-gate */ 75*7c478bd9Sstevel@tonic-gate static const Cap_desc sf1[] = { 76*7c478bd9Sstevel@tonic-gate { SF1_SUNW_FPKNWN, Sf1_fpknwn, (sizeof (Sf1_fpknwn) - 1) }, 77*7c478bd9Sstevel@tonic-gate { SF1_SUNW_FPUSED, Sf1_fpused, (sizeof (Sf1_fpused) - 1) } 78*7c478bd9Sstevel@tonic-gate }; 79*7c478bd9Sstevel@tonic-gate static const uint_t sf1_num = sizeof (sf1) / sizeof (Cap_desc); 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * Define all known SPARC hardware capabilities. 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 85*7c478bd9Sstevel@tonic-gate static const char Hw1_s_mul32[] = "MUL32"; 86*7c478bd9Sstevel@tonic-gate static const char Hw1_s_div32[] = "DIV32"; 87*7c478bd9Sstevel@tonic-gate static const char Hw1_s_fsmuld[] = "FSMULD"; 88*7c478bd9Sstevel@tonic-gate static const char Hw1_s_v8plus[] = "V8PLUS"; 89*7c478bd9Sstevel@tonic-gate static const char Hw1_s_popc[] = "POPC"; 90*7c478bd9Sstevel@tonic-gate static const char Hw1_s_vis[] = "VIS"; 91*7c478bd9Sstevel@tonic-gate static const char Hw1_s_vis2[] = "VIS2"; 92*7c478bd9Sstevel@tonic-gate static const char Hw1_s_asi_blk_init[] = "ASI_BLK_INIT"; 93*7c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 94*7c478bd9Sstevel@tonic-gate static const char Hw1_s_mul32[] = "mul32"; 95*7c478bd9Sstevel@tonic-gate static const char Hw1_s_div32[] = "div32"; 96*7c478bd9Sstevel@tonic-gate static const char Hw1_s_fsmuld[] = "fsmuld"; 97*7c478bd9Sstevel@tonic-gate static const char Hw1_s_v8plus[] = "v8plus"; 98*7c478bd9Sstevel@tonic-gate static const char Hw1_s_popc[] = "popc"; 99*7c478bd9Sstevel@tonic-gate static const char Hw1_s_vis[] = "vis"; 100*7c478bd9Sstevel@tonic-gate static const char Hw1_s_vis2[] = "vis2"; 101*7c478bd9Sstevel@tonic-gate static const char Hw1_s_asi_blk_init[] = "asi_blk_init"; 102*7c478bd9Sstevel@tonic-gate #else 103*7c478bd9Sstevel@tonic-gate #error "Hardware Capabilities (sparc) - what case do you want?" 104*7c478bd9Sstevel@tonic-gate #endif 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * Order the SPARC hardware capabilities to match their numeric value. See 108*7c478bd9Sstevel@tonic-gate * AV_SPARC_ values in sys/auxv_SPARC.h. 109*7c478bd9Sstevel@tonic-gate */ 110*7c478bd9Sstevel@tonic-gate static const Cap_desc hw1_s[] = { 111*7c478bd9Sstevel@tonic-gate { AV_SPARC_MUL32, Hw1_s_mul32, sizeof (Hw1_s_mul32) - 1 }, 112*7c478bd9Sstevel@tonic-gate { AV_SPARC_DIV32, Hw1_s_div32, sizeof (Hw1_s_div32) - 1 }, 113*7c478bd9Sstevel@tonic-gate { AV_SPARC_FSMULD, Hw1_s_fsmuld, sizeof (Hw1_s_fsmuld) - 1 }, 114*7c478bd9Sstevel@tonic-gate { AV_SPARC_V8PLUS, Hw1_s_v8plus, sizeof (Hw1_s_v8plus) - 1 }, 115*7c478bd9Sstevel@tonic-gate { AV_SPARC_POPC, Hw1_s_popc, sizeof (Hw1_s_popc) - 1 }, 116*7c478bd9Sstevel@tonic-gate { AV_SPARC_VIS, Hw1_s_vis, sizeof (Hw1_s_vis) - 1 }, 117*7c478bd9Sstevel@tonic-gate { AV_SPARC_VIS2, Hw1_s_vis2, sizeof (Hw1_s_vis2) - 1 }, 118*7c478bd9Sstevel@tonic-gate { AV_SPARC_ASI_BLK_INIT, Hw1_s_asi_blk_init, 119*7c478bd9Sstevel@tonic-gate sizeof (Hw1_s_asi_blk_init) - 1 } 120*7c478bd9Sstevel@tonic-gate }; 121*7c478bd9Sstevel@tonic-gate static const uint_t hw1_s_num = sizeof (hw1_s) / sizeof (Cap_desc); 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* 124*7c478bd9Sstevel@tonic-gate * Define all known Intel hardware capabilities. 125*7c478bd9Sstevel@tonic-gate */ 126*7c478bd9Sstevel@tonic-gate #ifdef CAP_UPPERCASE 127*7c478bd9Sstevel@tonic-gate static const char Hw1_i_fpu[] = "FPU"; 128*7c478bd9Sstevel@tonic-gate static const char Hw1_i_tsc[] = "TSC"; 129*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cx8[] = "CX8"; 130*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sep[] = "SEP"; 131*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_sysc[] = "AMD_SYSC"; 132*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cmov[] = "CMOV"; 133*7c478bd9Sstevel@tonic-gate static const char Hw1_i_mmx[] = "MMX"; 134*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_mmx[] = "AMD_MMX"; 135*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnow[] = "AMD_3DNow"; 136*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnowx[] = "AMD_3DNowx"; 137*7c478bd9Sstevel@tonic-gate static const char Hw1_i_fxsr[] = "FXSR"; 138*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse[] = "SSE"; 139*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse2[] = "SSE2"; 140*7c478bd9Sstevel@tonic-gate static const char Hw1_i_pause[] = "PAUSE"; 141*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse3[] = "SSE3"; 142*7c478bd9Sstevel@tonic-gate static const char Hw1_i_mon[] = "MON"; 143*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cx16[] = "CX16"; 144*7c478bd9Sstevel@tonic-gate #elif CAP_LOWERCASE 145*7c478bd9Sstevel@tonic-gate static const char Hw1_i_fpu[] = "fpu"; 146*7c478bd9Sstevel@tonic-gate static const char Hw1_i_tsc[] = "tsc"; 147*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cx8[] = "cx8"; 148*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sep[] = "sep"; 149*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_sysc[] = "amd_sysc"; 150*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cmov[] = "cmov"; 151*7c478bd9Sstevel@tonic-gate static const char Hw1_i_mmx[] = "mmx"; 152*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_mmx[] = "amd_mmx"; 153*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnow[] = "amd_3dnow"; 154*7c478bd9Sstevel@tonic-gate static const char Hw1_i_amd_3dnowx[] = "amd_3dnowx"; 155*7c478bd9Sstevel@tonic-gate static const char Hw1_i_fxsr[] = "fxsr"; 156*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse[] = "sse"; 157*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse2[] = "sse2"; 158*7c478bd9Sstevel@tonic-gate static const char Hw1_i_pause[] = "pause"; 159*7c478bd9Sstevel@tonic-gate static const char Hw1_i_sse3[] = "sse3"; 160*7c478bd9Sstevel@tonic-gate static const char Hw1_i_mon[] = "mon"; 161*7c478bd9Sstevel@tonic-gate static const char Hw1_i_cx16[] = "cx16"; 162*7c478bd9Sstevel@tonic-gate #else 163*7c478bd9Sstevel@tonic-gate #error "Hardware Capabilities (intel) - what case do you want?" 164*7c478bd9Sstevel@tonic-gate #endif 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * Order the Intel hardware capabilities to match their numeric value. See 168*7c478bd9Sstevel@tonic-gate * AV_386_ values in sys/auxv_386.h. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate static const Cap_desc hw1_i[] = { 171*7c478bd9Sstevel@tonic-gate { AV_386_FPU, Hw1_i_fpu, sizeof (Hw1_i_fpu) - 1 }, 172*7c478bd9Sstevel@tonic-gate { AV_386_TSC, Hw1_i_tsc, sizeof (Hw1_i_tsc) - 1 }, 173*7c478bd9Sstevel@tonic-gate { AV_386_CX8, Hw1_i_cx8, sizeof (Hw1_i_cx8) - 1 }, 174*7c478bd9Sstevel@tonic-gate { AV_386_SEP, Hw1_i_sep, sizeof (Hw1_i_sep) - 1 }, 175*7c478bd9Sstevel@tonic-gate { AV_386_AMD_SYSC, Hw1_i_amd_sysc, sizeof (Hw1_i_amd_sysc) - 1 }, 176*7c478bd9Sstevel@tonic-gate { AV_386_CMOV, Hw1_i_cmov, sizeof (Hw1_i_cmov) - 1 }, 177*7c478bd9Sstevel@tonic-gate { AV_386_MMX, Hw1_i_mmx, sizeof (Hw1_i_mmx) - 1 }, 178*7c478bd9Sstevel@tonic-gate { AV_386_AMD_MMX, Hw1_i_amd_mmx, sizeof (Hw1_i_amd_mmx) - 1 }, 179*7c478bd9Sstevel@tonic-gate { AV_386_AMD_3DNow, Hw1_i_amd_3dnow, 180*7c478bd9Sstevel@tonic-gate sizeof (Hw1_i_amd_3dnow) - 1 }, 181*7c478bd9Sstevel@tonic-gate { AV_386_AMD_3DNowx, Hw1_i_amd_3dnowx, 182*7c478bd9Sstevel@tonic-gate sizeof (Hw1_i_amd_3dnowx) - 1 }, 183*7c478bd9Sstevel@tonic-gate { AV_386_FXSR, Hw1_i_fxsr, sizeof (Hw1_i_fxsr) - 1 }, 184*7c478bd9Sstevel@tonic-gate { AV_386_SSE, Hw1_i_sse, sizeof (Hw1_i_sse) - 1 }, 185*7c478bd9Sstevel@tonic-gate { AV_386_SSE2, Hw1_i_sse2, sizeof (Hw1_i_sse2) - 1 }, 186*7c478bd9Sstevel@tonic-gate { AV_386_PAUSE, Hw1_i_pause, sizeof (Hw1_i_pause) - 1 }, 187*7c478bd9Sstevel@tonic-gate { AV_386_SSE3, Hw1_i_sse3, sizeof (Hw1_i_sse3) - 1 }, 188*7c478bd9Sstevel@tonic-gate { AV_386_MON, Hw1_i_mon, sizeof (Hw1_i_mon) - 1 }, 189*7c478bd9Sstevel@tonic-gate { AV_386_CX16, Hw1_i_cx16, sizeof (Hw1_i_cx16) - 1 } 190*7c478bd9Sstevel@tonic-gate }; 191*7c478bd9Sstevel@tonic-gate static const uint_t hw1_i_num = sizeof (hw1_i) / sizeof (Cap_desc); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * Concatenate a token to the string buffer. This can be a capailities token 195*7c478bd9Sstevel@tonic-gate * or a separator token. 196*7c478bd9Sstevel@tonic-gate */ 197*7c478bd9Sstevel@tonic-gate static int 198*7c478bd9Sstevel@tonic-gate token(char **ostr, size_t *olen, const char *nstr, size_t nlen) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate if (*olen < nlen) 201*7c478bd9Sstevel@tonic-gate return (CAP_ERR_BUFOVFL); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate (void) strcat(*ostr, nstr); 204*7c478bd9Sstevel@tonic-gate *ostr += nlen; 205*7c478bd9Sstevel@tonic-gate *olen -= nlen; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate return (0); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * Expand a capabilities value into the strings defined in the associated 212*7c478bd9Sstevel@tonic-gate * capabilities descriptor. 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate static int 215*7c478bd9Sstevel@tonic-gate expand(uint64_t val, const Cap_desc *cdp, uint_t cnum, char *str, size_t slen, 216*7c478bd9Sstevel@tonic-gate int fmt) 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate uint_t cnt, mask; 219*7c478bd9Sstevel@tonic-gate int follow = 0, err; 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate if (val == 0) 222*7c478bd9Sstevel@tonic-gate return (0); 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate for (cnt = WORD_BIT, mask = 0x80000000; cnt; cnt--, 225*7c478bd9Sstevel@tonic-gate (mask = mask >> 1)) { 226*7c478bd9Sstevel@tonic-gate if ((val & mask) && (cnt <= cnum) && cdp[cnt - 1].c_val) { 227*7c478bd9Sstevel@tonic-gate if (follow++ && ((err = token(&str, &slen, 228*7c478bd9Sstevel@tonic-gate format[fmt].f_str, format[fmt].f_len)) != 0)) 229*7c478bd9Sstevel@tonic-gate return (err); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate if ((err = token(&str, &slen, cdp[cnt - 1].c_str, 232*7c478bd9Sstevel@tonic-gate cdp[cnt - 1].c_len)) != 0) 233*7c478bd9Sstevel@tonic-gate return (err); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate val = val & ~mask; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * If there are any unknown bits remaining display the numeric value. 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate if (val) { 243*7c478bd9Sstevel@tonic-gate if (follow && ((err = token(&str, &slen, format[fmt].f_str, 244*7c478bd9Sstevel@tonic-gate format[fmt].f_len)) != 0)) 245*7c478bd9Sstevel@tonic-gate return (err); 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate (void) snprintf(str, slen, "0x%llx", val); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate return (0); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate /* 253*7c478bd9Sstevel@tonic-gate * Expand a CA_SUNW_HW_1 value. 254*7c478bd9Sstevel@tonic-gate */ 255*7c478bd9Sstevel@tonic-gate int 256*7c478bd9Sstevel@tonic-gate hwcap_1_val2str(uint64_t val, char *str, size_t len, int fmt, ushort_t mach) 257*7c478bd9Sstevel@tonic-gate { 258*7c478bd9Sstevel@tonic-gate /* 259*7c478bd9Sstevel@tonic-gate * Initialize the string buffer, and validate the format request. 260*7c478bd9Sstevel@tonic-gate */ 261*7c478bd9Sstevel@tonic-gate *str = '\0'; 262*7c478bd9Sstevel@tonic-gate if (fmt > CAP_MAX_TYPE) 263*7c478bd9Sstevel@tonic-gate return (CAP_ERR_INVFMT); 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64)) 266*7c478bd9Sstevel@tonic-gate return (expand(val, &hw1_i[0], hw1_i_num, str, len, fmt)); 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 269*7c478bd9Sstevel@tonic-gate (mach == EM_SPARCV9)) 270*7c478bd9Sstevel@tonic-gate return (expand(val, &hw1_s[0], hw1_s_num, str, len, fmt)); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate return (CAP_ERR_UNKMACH); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate /* 276*7c478bd9Sstevel@tonic-gate * Expand a CA_SUNW_SF_1 value. Note, that at present these capabilities are 277*7c478bd9Sstevel@tonic-gate * common across all platforms. The use of "mach" is therefore redundant, but 278*7c478bd9Sstevel@tonic-gate * is retained for compatibility with the interface of hwcap_1_val2str(), and 279*7c478bd9Sstevel@tonic-gate * possible future expansion. 280*7c478bd9Sstevel@tonic-gate */ 281*7c478bd9Sstevel@tonic-gate int 282*7c478bd9Sstevel@tonic-gate /* ARGSUSED4 */ 283*7c478bd9Sstevel@tonic-gate sfcap_1_val2str(uint64_t val, char *str, size_t len, int fmt, ushort_t mach) 284*7c478bd9Sstevel@tonic-gate { 285*7c478bd9Sstevel@tonic-gate /* 286*7c478bd9Sstevel@tonic-gate * Initialize the string buffer, and validate the format request. 287*7c478bd9Sstevel@tonic-gate */ 288*7c478bd9Sstevel@tonic-gate *str = '\0'; 289*7c478bd9Sstevel@tonic-gate if (fmt > CAP_MAX_TYPE) 290*7c478bd9Sstevel@tonic-gate return (CAP_ERR_INVFMT); 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate return (expand(val, &sf1[0], sf1_num, str, len, fmt)); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate /* 296*7c478bd9Sstevel@tonic-gate * Determine capability type from the capability tag. 297*7c478bd9Sstevel@tonic-gate */ 298*7c478bd9Sstevel@tonic-gate int 299*7c478bd9Sstevel@tonic-gate cap_val2str(uint64_t tag, uint64_t val, char *str, size_t len, int fmt, 300*7c478bd9Sstevel@tonic-gate ushort_t mach) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate if (tag == CA_SUNW_HW_1) 303*7c478bd9Sstevel@tonic-gate return (hwcap_1_val2str(val, str, len, fmt, mach)); 304*7c478bd9Sstevel@tonic-gate if (tag == CA_SUNW_SF_1) 305*7c478bd9Sstevel@tonic-gate return (sfcap_1_val2str(val, str, len, fmt, mach)); 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate return (CAP_ERR_UNKTAG); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* 311*7c478bd9Sstevel@tonic-gate * Determine a capabilities value from a capabilities string. 312*7c478bd9Sstevel@tonic-gate */ 313*7c478bd9Sstevel@tonic-gate static uint64_t 314*7c478bd9Sstevel@tonic-gate value(const char *str, const Cap_desc *cdp, uint_t cnum) 315*7c478bd9Sstevel@tonic-gate { 316*7c478bd9Sstevel@tonic-gate uint_t num; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate for (num = 0; num < cnum; num++) { 319*7c478bd9Sstevel@tonic-gate if (strcmp(str, cdp[num].c_str) == 0) 320*7c478bd9Sstevel@tonic-gate return (cdp[num].c_val); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate return (0); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate uint64_t 326*7c478bd9Sstevel@tonic-gate sfcap_1_str2val(const char *str, ushort_t mach) 327*7c478bd9Sstevel@tonic-gate { 328*7c478bd9Sstevel@tonic-gate return (value(str, &sf1[0], sf1_num)); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate uint64_t 332*7c478bd9Sstevel@tonic-gate hwcap_1_str2val(const char *str, ushort_t mach) 333*7c478bd9Sstevel@tonic-gate { 334*7c478bd9Sstevel@tonic-gate if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64)) 335*7c478bd9Sstevel@tonic-gate return (value(str, &hw1_i[0], hw1_i_num)); 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 338*7c478bd9Sstevel@tonic-gate (mach == EM_SPARCV9)) 339*7c478bd9Sstevel@tonic-gate return (value(str, &hw1_s[0], hw1_s_num)); 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate return (0); 342*7c478bd9Sstevel@tonic-gate } 343