xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/cap.c (revision 56726c7e)
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
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * 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  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
2369112eddSAli Bahrami  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*56726c7eSRobert Mustacchi  *
26*56726c7eSRobert Mustacchi  * Copyright 2022 Oxide Computer Company
277c478bd9Sstevel@tonic-gate  */
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	<elfcap.h>
357c478bd9Sstevel@tonic-gate #include	"cap_msg.h"
36c13de8f6Sab #include	"_conv.h"
377c478bd9Sstevel@tonic-gate 
38*56726c7eSRobert Mustacchi /*
39*56726c7eSRobert Mustacchi  * These are assertions that the various sizes that are dependent on elfcap.c
40*56726c7eSRobert Mustacchi  * are actually all the same.
41*56726c7eSRobert Mustacchi  */
42*56726c7eSRobert Mustacchi #if CONV_CAP_VAL_HW1_BUFSIZE != ELFCAP_HW1_BUFSIZE
43*56726c7eSRobert Mustacchi #error "libconv needs to update CONV_CAP_VAL_HW1_BUFSIZE to match elfcap.h"
44*56726c7eSRobert Mustacchi #endif
45*56726c7eSRobert Mustacchi 
46*56726c7eSRobert Mustacchi #if CONV_CAP_VAL_HW2_BUFSIZE != ELFCAP_HW2_BUFSIZE
47*56726c7eSRobert Mustacchi #error "libconv needs to update CONV_CAP_VAL_HW2_BUFSIZE to match elfcap.h"
48*56726c7eSRobert Mustacchi #endif
49*56726c7eSRobert Mustacchi 
50*56726c7eSRobert Mustacchi #if CONV_CAP_VAL_HW3_BUFSIZE != ELFCAP_HW3_BUFSIZE
51*56726c7eSRobert Mustacchi #error "libconv needs to update CONV_CAP_VAL_HW3_BUFSIZE to match elfcap.h"
52*56726c7eSRobert Mustacchi #endif
53*56726c7eSRobert Mustacchi 
54*56726c7eSRobert Mustacchi #if CONV_CAP_VAL_SF1_BUFSIZE != ELFCAP_SF1_BUFSIZE
55*56726c7eSRobert Mustacchi #error "libconv needs to update CONV_CAP_VAL_SF1_BUFSIZE to match elfcap.h"
56*56726c7eSRobert Mustacchi #endif
57*56726c7eSRobert Mustacchi 
584f680cc6SAli Bahrami const conv_ds_t **
conv_cap_tag_strings(Conv_fmt_flags_t fmt_flags)594f680cc6SAli Bahrami conv_cap_tag_strings(Conv_fmt_flags_t fmt_flags)
607c478bd9Sstevel@tonic-gate {
61*56726c7eSRobert Mustacchi #if	(CA_SUNW_NUM != (CA_SUNW_HW_3 + 1))
6269112eddSAli Bahrami #error	"CA_SUNW_NUM has grown"
6369112eddSAli Bahrami #endif
644f680cc6SAli Bahrami 	static const Msg	tags_cf[] = {
654f680cc6SAli Bahrami 		MSG_CA_SUNW_NULL_CF,	MSG_CA_SUNW_HW_1_CF,
6608278a5eSRod Evans 		MSG_CA_SUNW_SF_1_CF,	MSG_CA_SUNW_HW_2_CF,
6708278a5eSRod Evans 		MSG_CA_SUNW_PLAT_CF,	MSG_CA_SUNW_MACH_CF,
68*56726c7eSRobert Mustacchi 		MSG_CA_SUNW_ID_CF,	MSG_CA_SUNW_HW_3_CF
694f680cc6SAli Bahrami 	};
704f680cc6SAli Bahrami 	static const Msg	tags_nf[] = {
714f680cc6SAli Bahrami 		MSG_CA_SUNW_NULL_NF,	MSG_CA_SUNW_HW_1_NF,
7269112eddSAli Bahrami 		MSG_CA_SUNW_SF_1_NF,	MSG_CA_SUNW_HW_2_NF,
7308278a5eSRod Evans 		MSG_CA_SUNW_PLAT_NF,	MSG_CA_SUNW_MACH_NF,
74*56726c7eSRobert Mustacchi 		MSG_CA_SUNW_ID_NF,	MSG_CA_SUNW_HW_3_NF
754f680cc6SAli Bahrami 	};
764f680cc6SAli Bahrami 	static const conv_ds_msg_t ds_tags_cf = {
774f680cc6SAli Bahrami 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_cf) };
784f680cc6SAli Bahrami 	static const conv_ds_msg_t ds_tags_nf = {
794f680cc6SAli Bahrami 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_nf) };
807c478bd9Sstevel@tonic-gate 
814f680cc6SAli Bahrami 	static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_tags_cf), NULL };
824f680cc6SAli Bahrami 	static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_tags_nf), NULL };
837c478bd9Sstevel@tonic-gate 
844f680cc6SAli Bahrami 
854f680cc6SAli Bahrami 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
864f680cc6SAli Bahrami 	    ds_nf : ds_cf);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate 
894f680cc6SAli Bahrami conv_iter_ret_t
conv_iter_cap_tags(Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)904f680cc6SAli Bahrami conv_iter_cap_tags(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
914f680cc6SAli Bahrami     void *uvalue)
927c478bd9Sstevel@tonic-gate {
934f680cc6SAli Bahrami 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
944f680cc6SAli Bahrami 	    conv_cap_tag_strings(fmt_flags), func, uvalue));
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
974f680cc6SAli Bahrami /*
984f680cc6SAli Bahrami  * Given an array of elfcap_desc_t, and a count, call the specified
994f680cc6SAli Bahrami  * iteration for each value in the array.
1004f680cc6SAli Bahrami  */
1014f680cc6SAli Bahrami static conv_iter_ret_t
conv_iter_elfcap(const elfcap_desc_t * cdp,uint_t cnum,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)1024f680cc6SAli Bahrami conv_iter_elfcap(const elfcap_desc_t *cdp, uint_t cnum,
1034f680cc6SAli Bahrami     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
1047c478bd9Sstevel@tonic-gate {
1054f680cc6SAli Bahrami 	const char	*str;
1064f680cc6SAli Bahrami 
1074f680cc6SAli Bahrami 	fmt_flags = CONV_TYPE_FMT_ALT(fmt_flags);
1084f680cc6SAli Bahrami 
1094f680cc6SAli Bahrami 	for (; cnum-- > 0; cdp++) {
1104f680cc6SAli Bahrami 		/*
1114f680cc6SAli Bahrami 		 * Skip "reserved" bits. These are unassigned bits in the
1124f680cc6SAli Bahrami 		 * middle of the assigned range.
1134f680cc6SAli Bahrami 		 */
1144f680cc6SAli Bahrami 		if (cdp->c_val == 0)
1154f680cc6SAli Bahrami 			continue;
1167c478bd9Sstevel@tonic-gate 
1174f680cc6SAli Bahrami 		switch (fmt_flags) {
1184f680cc6SAli Bahrami 		default:
1194f680cc6SAli Bahrami 			str = cdp->c_full.s_str;
1204f680cc6SAli Bahrami 			break;
1214f680cc6SAli Bahrami 		case CONV_FMT_ALT_CFNP:
1224f680cc6SAli Bahrami 			str = cdp->c_uc.s_str;
1234f680cc6SAli Bahrami 			break;
1244f680cc6SAli Bahrami 		case CONV_FMT_ALT_NF:
1254f680cc6SAli Bahrami 			str = cdp->c_lc.s_str;
1264f680cc6SAli Bahrami 			break;
1274f680cc6SAli Bahrami 		}
1284f680cc6SAli Bahrami 
1294f680cc6SAli Bahrami 		if ((* func)(str, cdp->c_val, uvalue) == CONV_ITER_DONE)
1304f680cc6SAli Bahrami 			return (CONV_ITER_DONE);
1314f680cc6SAli Bahrami 	}
1324f680cc6SAli Bahrami 
1334f680cc6SAli Bahrami 	return (CONV_ITER_CONT);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1364f680cc6SAli Bahrami /*
13708278a5eSRod Evans  * Iterate the strings for CA_SUNW_HW.
1384f680cc6SAli Bahrami  */
1394f680cc6SAli Bahrami conv_iter_ret_t
conv_iter_cap_val_hw1(Half mach,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)1404f680cc6SAli Bahrami conv_iter_cap_val_hw1(Half mach, Conv_fmt_flags_t fmt_flags,
1414f680cc6SAli Bahrami     conv_iter_cb_t func, void *uvalue)
1427c478bd9Sstevel@tonic-gate {
1434f680cc6SAli Bahrami 	if ((mach == EM_386) || (mach == EM_486) ||
1444f680cc6SAli Bahrami 	    (mach == EM_AMD64) || (mach == CONV_MACH_ALL))
1454f680cc6SAli Bahrami 		if (conv_iter_elfcap(elfcap_getdesc_hw1_386(),
1464f680cc6SAli Bahrami 		    ELFCAP_NUM_HW1_386, fmt_flags, func, uvalue) ==
1474f680cc6SAli Bahrami 		    CONV_ITER_DONE)
1484f680cc6SAli Bahrami 			return (CONV_ITER_DONE);
1494f680cc6SAli Bahrami 
1504f680cc6SAli Bahrami 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
1514f680cc6SAli Bahrami 	    (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL))
1524f680cc6SAli Bahrami 		if (conv_iter_elfcap(elfcap_getdesc_hw1_sparc(),
1534f680cc6SAli Bahrami 		    ELFCAP_NUM_HW1_SPARC, fmt_flags, func, uvalue) ==
1544f680cc6SAli Bahrami 		    CONV_ITER_DONE)
1554f680cc6SAli Bahrami 			return (CONV_ITER_DONE);
1567c478bd9Sstevel@tonic-gate 
1574f680cc6SAli Bahrami 	return (CONV_ITER_CONT);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
16008278a5eSRod Evans conv_iter_ret_t
16108278a5eSRod Evans /* ARGSUSED0 */
conv_iter_cap_val_hw2(Half mach,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)16208278a5eSRod Evans conv_iter_cap_val_hw2(Half mach, Conv_fmt_flags_t fmt_flags,
16308278a5eSRod Evans     conv_iter_cb_t func, void *uvalue)
16408278a5eSRod Evans {
165*56726c7eSRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_486) ||
166*56726c7eSRobert Mustacchi 	    (mach == EM_AMD64) || (mach == CONV_MACH_ALL))
167*56726c7eSRobert Mustacchi 		if (conv_iter_elfcap(elfcap_getdesc_hw2_386(),
168*56726c7eSRobert Mustacchi 		    ELFCAP_NUM_HW2_386, fmt_flags, func, uvalue) ==
169*56726c7eSRobert Mustacchi 		    CONV_ITER_DONE)
170*56726c7eSRobert Mustacchi 			return (CONV_ITER_DONE);
171*56726c7eSRobert Mustacchi 
17208278a5eSRod Evans 	return (CONV_ITER_DONE);
17308278a5eSRod Evans }
17408278a5eSRod Evans 
1754f680cc6SAli Bahrami /*
1764f680cc6SAli Bahrami  * Iterate the strings for CA_SUNW_SF1
1774f680cc6SAli Bahrami  */
1784f680cc6SAli Bahrami conv_iter_ret_t
conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)1794f680cc6SAli Bahrami conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
1804f680cc6SAli Bahrami     void *uvalue)
1817c478bd9Sstevel@tonic-gate {
1824f680cc6SAli Bahrami 	return (conv_iter_elfcap(elfcap_getdesc_sf1(), ELFCAP_NUM_SF1,
1834f680cc6SAli Bahrami 	    fmt_flags, func, uvalue));
1847c478bd9Sstevel@tonic-gate }
185*56726c7eSRobert Mustacchi 
186*56726c7eSRobert Mustacchi conv_iter_ret_t
conv_iter_cap_val_hw3(Half mach,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)187*56726c7eSRobert Mustacchi conv_iter_cap_val_hw3(Half mach, Conv_fmt_flags_t fmt_flags,
188*56726c7eSRobert Mustacchi     conv_iter_cb_t func, void *uvalue)
189*56726c7eSRobert Mustacchi {
190*56726c7eSRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_486) ||
191*56726c7eSRobert Mustacchi 	    (mach == EM_AMD64) || (mach == CONV_MACH_ALL))
192*56726c7eSRobert Mustacchi 		if (conv_iter_elfcap(elfcap_getdesc_hw3_386(),
193*56726c7eSRobert Mustacchi 		    ELFCAP_NUM_HW3_386, fmt_flags, func, uvalue) ==
194*56726c7eSRobert Mustacchi 		    CONV_ITER_DONE)
195*56726c7eSRobert Mustacchi 			return (CONV_ITER_DONE);
196*56726c7eSRobert Mustacchi 
197*56726c7eSRobert Mustacchi 	return (CONV_ITER_DONE);
198*56726c7eSRobert Mustacchi }
199