/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2015, Joyent, Inc.
*/
/* LINTLIBRARY */
/*
* String conversion routine for hardware capabilities types.
*/
#include <strings.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/auxv_SPARC.h>
#include <sys/auxv_386.h>
#include <elfcap.h>
/*
* Given a literal string, generate an initialization for an
* elfcap_str_t value.
*/
/*
* The items in the elfcap_desc_t arrays are required to be
* ordered so that the array index is related to the
* c_val field as:
*
* array[ndx].c_val = 2^ndx
*
* meaning that
*
* array[0].c_val = 2^0 = 1
* array[1].c_val = 2^1 = 2
* array[2].c_val = 2^2 = 4
* .
* .
* .
*
* Since 0 is not a valid value for the c_val field, we use it to
* mark an array entry that is a placeholder. This can happen if there
* is a hole in the assigned bits.
*
* The RESERVED_ELFCAP_DESC macro is used to reserve such holes.
*/
/*
* Define separators for output string processing. This must be kept in
* sync with the elfcap_fmt_t values in elfcap.h.
*/
};
/*
* Define all known software capabilities in all the supported styles.
* Order the capabilities by their numeric value. See SF1_SUNW_
*/
{ /* 0x00000001 */
},
{ /* 0x00000002 */
},
{ /* 0x00000004 */
}
};
/*
* Order the SPARC hardware capabilities to match their numeric value. See
* AV_SPARC_ values in sys/auxv_SPARC.h.
*/
{ /* 0x00000001 */
},
{ /* 0x00000002 */
},
{ /* 0x00000004 */
},
{ /* 0x00000008 */
},
{ /* 0x00000010 */
},
{ /* 0x00000020 */
},
{ /* 0x00000040 */
},
{ /* 0x00000080 */
},
{ /* 0x00000100 */
},
RESERVED_ELFCAP_DESC, /* 0x00000200 */
{ /* 0x00000400 */
},
{ /* 0x00000800 */
},
{ /* 0x00001000 */
},
{ /* 0x00002000 */
},
{ /* 0x00004000 */
},
{ /* 0x00008000 */
},
{ /* 0x00010000 */
STRDESC("AV_SPARC_ASI_CACHE_SPARING"),
}
};
/*
* Order the Intel hardware capabilities to match their numeric value. See
* AV_386_ values in sys/auxv_386.h.
*/
{ /* 0x00000001 */
},
{ /* 0x00000002 */
},
{ /* 0x00000004 */
},
{ /* 0x00000008 */
},
{ /* 0x00000010 */
},
{ /* 0x00000020 */
},
{ /* 0x00000040 */
},
{ /* 0x00000080 */
},
{ /* 0x00000100 */
},
{ /* 0x00000200 */
},
{ /* 0x00000400 */
},
{ /* 0x00000800 */
},
{ /* 0x00001000 */
},
/* 0x02000 withdrawn - do not assign */
{ /* 0x00004000 */
},
/* 0x08000 withdrawn - do not assign */
{ /* 0x00010000 */
},
{ /* 0x00020000 */
},
{ /* 0x00040000 */
},
{ /* 0x00080000 */
},
{ /* 0x00100000 */
},
{ /* 0x00200000 */
},
{ /* 0x00400000 */
},
{ /* 0x00800000 */
},
{ /* 0x01000000 */
},
{ /* 0x02000000 */
},
{ /* 0x04000000 */
},
{ /* 0x08000000 */
},
{ /* 0x10000000 */
},
{ /* 0x20000000 */
},
{ /* 0x40000000 */
},
{ /* 0x80000000 */
}
};
{ /* 0x00000001 */
},
{ /* 0x00000002 */
},
{ /* 0x00000004 */
},
{ /* 0x00000008 */
},
{ /* 0x00000010 */
},
{ /* 0x00000020 */
},
{ /* 0x00000040 */
},
{ /* 0x00000080 */
}
};
/*
* Concatenate a token to the string buffer. This can be a capabilities token
* or a separator token.
*/
static elfcap_err_t
{
return (ELFCAP_ERR_BUFOVFL);
return (ELFCAP_ERR_NONE);
}
static elfcap_err_t
const elfcap_str_t **ret_str)
{
switch (ELFCAP_STYLE_MASK(style)) {
case ELFCAP_STYLE_FULL:
break;
case ELFCAP_STYLE_UC:
break;
case ELFCAP_STYLE_LC:
break;
default:
return (ELFCAP_ERR_INVSTYLE);
}
return (ELFCAP_ERR_NONE);
}
/*
* Expand a capabilities value into the strings defined in the associated
* capabilities descriptor.
*/
static elfcap_err_t
{
if (val == 0)
return (ELFCAP_ERR_NONE);
return (err);
if (err != ELFCAP_ERR_NONE)
return (err);
return (err);
}
}
/*
* If there are any unknown bits remaining display the numeric value.
*/
if (val) {
return (err);
}
return (ELFCAP_ERR_NONE);
}
/*
* Expand a CA_SUNW_HW_1 value.
*/
{
/*
* Initialize the string buffer, and validate the format request.
*/
*str = '\0';
return (ELFCAP_ERR_INVFMT);
(mach == EM_SPARCV9))
return (ELFCAP_ERR_UNKMACH);
}
/*
* Expand a CA_SUNW_HW_2 value.
*/
{
/*
* Initialize the string buffer, and validate the format request.
*/
*str = '\0';
return (ELFCAP_ERR_INVFMT);
}
/*
* Expand a CA_SUNW_SF_1 value. Note, that at present these capabilities are
* common across all platforms. The use of "mach" is therefore redundant, but
* is retained for compatibility with the interface of elfcap_hw1_to_str(), and
* possible future expansion.
*/
/* ARGSUSED4 */
{
/*
* Initialize the string buffer, and validate the format request.
*/
*str = '\0';
return (ELFCAP_ERR_INVFMT);
}
/*
* Given a capability tag type and value, map it to a string representation.
*/
{
switch (tag) {
case CA_SUNW_HW_1:
case CA_SUNW_SF_1:
case CA_SUNW_HW_2:
}
return (ELFCAP_ERR_UNKTAG);
}
/*
* Determine a capabilities value from a capabilities string.
*/
static elfcap_mask_t
{
int err;
/*
* Skip "reserved" bits. These are unassigned bits in the
* middle of the assigned range.
*/
continue;
return (err);
if (style & ELFCAP_STYLE_F_ICMP) {
} else {
}
}
return (0);
}
{
}
{
(mach == EM_SPARCV9))
return (0);
}
{
return (0);
}
/*
* Given a capability tag type and value, return the capabilities values
* contained in the string.
*/
{
switch (tag) {
case CA_SUNW_HW_1:
case CA_SUNW_SF_1:
case CA_SUNW_HW_2:
}
return (0);
}
/*
* These functions allow the caller to get direct access to the
* cap descriptors.
*/
const elfcap_desc_t *
elfcap_getdesc_hw1_sparc(void)
{
return (hw1_sparc);
}
const elfcap_desc_t *
elfcap_getdesc_hw1_386(void)
{
return (hw1_386);
}
const elfcap_desc_t *
elfcap_getdesc_sf1(void)
{
return (sf1);
}