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