Home | History | Annotate | Download | only in common
      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 2009 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 	static const Msg	tags_cf[] = {
     40 		MSG_CA_SUNW_NULL_CF,	MSG_CA_SUNW_HW_1_CF,
     41 		MSG_CA_SUNW_SF_1_CF
     42 	};
     43 	static const Msg	tags_nf[] = {
     44 		MSG_CA_SUNW_NULL_NF,	MSG_CA_SUNW_HW_1_NF,
     45 		MSG_CA_SUNW_SF_1_NF
     46 	};
     47 	static const conv_ds_msg_t ds_tags_cf = {
     48 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_cf) };
     49 	static const conv_ds_msg_t ds_tags_nf = {
     50 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_nf) };
     51 
     52 	static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_tags_cf), NULL };
     53 	static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_tags_nf), NULL };
     54 
     55 
     56 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
     57 	    ds_nf : ds_cf);
     58 }
     59 
     60 conv_iter_ret_t
     61 conv_iter_cap_tags(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
     62     void *uvalue)
     63 {
     64 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
     65 	    conv_cap_tag_strings(fmt_flags), func, uvalue));
     66 }
     67 
     68 /*
     69  * Given an array of elfcap_desc_t, and a count, call the specified
     70  * iteration for each value in the array.
     71  */
     72 static conv_iter_ret_t
     73 conv_iter_elfcap(const elfcap_desc_t *cdp, uint_t cnum,
     74     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
     75 {
     76 	const char	*str;
     77 
     78 	fmt_flags = CONV_TYPE_FMT_ALT(fmt_flags);
     79 
     80 	for (; cnum-- > 0; cdp++) {
     81 		/*
     82 		 * Skip "reserved" bits. These are unassigned bits in the
     83 		 * middle of the assigned range.
     84 		 */
     85 		if (cdp->c_val == 0)
     86 			continue;
     87 
     88 		switch (fmt_flags) {
     89 		default:
     90 			str = cdp->c_full.s_str;
     91 			break;
     92 		case CONV_FMT_ALT_CFNP:
     93 			str = cdp->c_uc.s_str;
     94 			break;
     95 		case CONV_FMT_ALT_NF:
     96 			str = cdp->c_lc.s_str;
     97 			break;
     98 		}
     99 
    100 		if ((* func)(str, cdp->c_val, uvalue) == CONV_ITER_DONE)
    101 			return (CONV_ITER_DONE);
    102 	}
    103 
    104 	return (CONV_ITER_CONT);
    105 }
    106 
    107 /*
    108  * Iterate the strings for CA_SUNW_HW1
    109  */
    110 conv_iter_ret_t
    111 conv_iter_cap_val_hw1(Half mach, Conv_fmt_flags_t fmt_flags,
    112     conv_iter_cb_t func, void *uvalue)
    113 {
    114 	if ((mach == EM_386) || (mach == EM_486) ||
    115 	    (mach == EM_AMD64) || (mach == CONV_MACH_ALL))
    116 		if (conv_iter_elfcap(elfcap_getdesc_hw1_386(),
    117 		    ELFCAP_NUM_HW1_386, fmt_flags, func, uvalue) ==
    118 		    CONV_ITER_DONE)
    119 			return (CONV_ITER_DONE);
    120 
    121 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
    122 	    (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL))
    123 		if (conv_iter_elfcap(elfcap_getdesc_hw1_sparc(),
    124 		    ELFCAP_NUM_HW1_SPARC, fmt_flags, func, uvalue) ==
    125 		    CONV_ITER_DONE)
    126 			return (CONV_ITER_DONE);
    127 
    128 	return (CONV_ITER_CONT);
    129 }
    130 
    131 /*
    132  * Iterate the strings for CA_SUNW_SF1
    133  */
    134 conv_iter_ret_t
    135 conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    136     void *uvalue)
    137 {
    138 	return (conv_iter_elfcap(elfcap_getdesc_sf1(), ELFCAP_NUM_SF1,
    139 	    fmt_flags, func, uvalue));
    140 }
    141