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 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * String conversion routine for hardware capabilities types. 29 */ 30 #include <strings.h> 31 #include <stdio.h> 32 #include <elfcap.h> 33 #include "cap_msg.h" 34 #include "_conv.h" 35 36 const conv_ds_t ** 37 conv_cap_tag_strings(Conv_fmt_flags_t fmt_flags) 38 { 39 #if (CA_SUNW_NUM != (CA_SUNW_ID + 1)) 40 #error "CA_SUNW_NUM has grown" 41 #endif 42 static const Msg tags_cf[] = { 43 MSG_CA_SUNW_NULL_CF, MSG_CA_SUNW_HW_1_CF, 44 MSG_CA_SUNW_SF_1_CF, MSG_CA_SUNW_HW_2_CF, 45 MSG_CA_SUNW_PLAT_CF, MSG_CA_SUNW_MACH_CF, 46 MSG_CA_SUNW_ID_CF 47 }; 48 static const Msg tags_nf[] = { 49 MSG_CA_SUNW_NULL_NF, MSG_CA_SUNW_HW_1_NF, 50 MSG_CA_SUNW_SF_1_NF, MSG_CA_SUNW_HW_2_NF, 51 MSG_CA_SUNW_PLAT_NF, MSG_CA_SUNW_MACH_NF, 52 MSG_CA_SUNW_ID_NF 53 }; 54 static const conv_ds_msg_t ds_tags_cf = { 55 CONV_DS_MSG_INIT(ELFCLASSNONE, tags_cf) }; 56 static const conv_ds_msg_t ds_tags_nf = { 57 CONV_DS_MSG_INIT(ELFCLASSNONE, tags_nf) }; 58 59 static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_tags_cf), NULL }; 60 static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_tags_nf), NULL }; 61 62 63 return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ? 64 ds_nf : ds_cf); 65 } 66 67 conv_iter_ret_t 68 conv_iter_cap_tags(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, 69 void *uvalue) 70 { 71 return (conv_iter_ds(ELFOSABI_NONE, EM_NONE, 72 conv_cap_tag_strings(fmt_flags), func, uvalue)); 73 } 74 75 /* 76 * Given an array of elfcap_desc_t, and a count, call the specified 77 * iteration for each value in the array. 78 */ 79 static conv_iter_ret_t 80 conv_iter_elfcap(const elfcap_desc_t *cdp, uint_t cnum, 81 Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue) 82 { 83 const char *str; 84 85 fmt_flags = CONV_TYPE_FMT_ALT(fmt_flags); 86 87 for (; cnum-- > 0; cdp++) { 88 /* 89 * Skip "reserved" bits. These are unassigned bits in the 90 * middle of the assigned range. 91 */ 92 if (cdp->c_val == 0) 93 continue; 94 95 switch (fmt_flags) { 96 default: 97 str = cdp->c_full.s_str; 98 break; 99 case CONV_FMT_ALT_CFNP: 100 str = cdp->c_uc.s_str; 101 break; 102 case CONV_FMT_ALT_NF: 103 str = cdp->c_lc.s_str; 104 break; 105 } 106 107 if ((* func)(str, cdp->c_val, uvalue) == CONV_ITER_DONE) 108 return (CONV_ITER_DONE); 109 } 110 111 return (CONV_ITER_CONT); 112 } 113 114 /* 115 * Iterate the strings for CA_SUNW_HW. 116 */ 117 conv_iter_ret_t 118 conv_iter_cap_val_hw1(Half mach, Conv_fmt_flags_t fmt_flags, 119 conv_iter_cb_t func, void *uvalue) 120 { 121 if ((mach == EM_386) || (mach == EM_486) || 122 (mach == EM_AMD64) || (mach == CONV_MACH_ALL)) 123 if (conv_iter_elfcap(elfcap_getdesc_hw1_386(), 124 ELFCAP_NUM_HW1_386, fmt_flags, func, uvalue) == 125 CONV_ITER_DONE) 126 return (CONV_ITER_DONE); 127 128 if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 129 (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL)) 130 if (conv_iter_elfcap(elfcap_getdesc_hw1_sparc(), 131 ELFCAP_NUM_HW1_SPARC, fmt_flags, func, uvalue) == 132 CONV_ITER_DONE) 133 return (CONV_ITER_DONE); 134 135 return (CONV_ITER_CONT); 136 } 137 138 conv_iter_ret_t 139 /* ARGSUSED0 */ 140 conv_iter_cap_val_hw2(Half mach, Conv_fmt_flags_t fmt_flags, 141 conv_iter_cb_t func, void *uvalue) 142 { 143 return (CONV_ITER_DONE); 144 } 145 146 /* 147 * Iterate the strings for CA_SUNW_SF1 148 */ 149 conv_iter_ret_t 150 conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, 151 void *uvalue) 152 { 153 return (conv_iter_elfcap(elfcap_getdesc_sf1(), ELFCAP_NUM_SF1, 154 fmt_flags, func, uvalue)); 155 } 156