mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
bhnd(4): Add support for three new NVRAM value types; booleans,
NULL (which we'll use to denote deleted values in bhnd_nvram_store), and opaque data (aka octet-strings). Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D8758
This commit is contained in:
parent
9be0790d19
commit
6cffadf0f0
9 changed files with 537 additions and 3 deletions
|
|
@ -39,6 +39,14 @@
|
|||
#include <stdint.h>
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/**
|
||||
* BHND NVRAM boolean type; guaranteed to be exactly 8-bits, representing
|
||||
* true as integer constant 1, and false as integer constant 0.
|
||||
*
|
||||
* Compatible with stdbool constants (true, false).
|
||||
*/
|
||||
typedef uint8_t bhnd_nvram_bool_t;
|
||||
|
||||
/**
|
||||
* NVRAM data sources supported by bhnd(4) devices.
|
||||
*/
|
||||
|
|
@ -94,6 +102,10 @@ typedef enum {
|
|||
BHND_NVRAM_TYPE_CHAR = 8, /**< ASCII/UTF-8 character */
|
||||
BHND_NVRAM_TYPE_STRING = 9, /**< ASCII/UTF-8 NUL-terminated
|
||||
string */
|
||||
BHND_NVRAM_TYPE_BOOL = 10, /**< uint8 boolean value. see
|
||||
bhnd_nvram_bool_t. */
|
||||
BHND_NVRAM_TYPE_NULL = 11, /**< NULL (empty) value */
|
||||
BHND_NVRAM_TYPE_DATA = 12, /**< opaque octet string */
|
||||
|
||||
/* 10-15 reserved for primitive (non-array) types */
|
||||
|
||||
|
|
@ -109,13 +121,17 @@ typedef enum {
|
|||
characters */
|
||||
BHND_NVRAM_TYPE_STRING_ARRAY = 25, /**< array of ASCII/UTF-8
|
||||
NUL-terminated strings */
|
||||
BHND_NVRAM_TYPE_BOOL_ARRAY = 26, /**< array of uint8 boolean
|
||||
values */
|
||||
} bhnd_nvram_type;
|
||||
|
||||
|
||||
bool bhnd_nvram_is_signed_type(bhnd_nvram_type type);
|
||||
bool bhnd_nvram_is_unsigned_type(bhnd_nvram_type type);
|
||||
bool bhnd_nvram_is_int_type(bhnd_nvram_type type);
|
||||
bool bhnd_nvram_is_array_type(bhnd_nvram_type type);
|
||||
bhnd_nvram_type bhnd_nvram_base_type(bhnd_nvram_type type);
|
||||
bhnd_nvram_type bhnd_nvram_raw_type(bhnd_nvram_type type);
|
||||
const char *bhnd_nvram_type_name(bhnd_nvram_type type);
|
||||
size_t bhnd_nvram_type_width(bhnd_nvram_type type);
|
||||
size_t bhnd_nvram_type_host_align(bhnd_nvram_type type);
|
||||
|
|
|
|||
|
|
@ -742,6 +742,27 @@ bhnd_nvram_plist_get_uint64(bhnd_nvram_plist *plist, const char *name,
|
|||
BHND_NVRAM_TYPE_UINT64));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the boolean representation of a named property's value.
|
||||
*
|
||||
* @param plist The property list to be queried.
|
||||
* @param name The name of the property value to be returned.
|
||||
* @param[out] val On success, the boolean value of @p name.
|
||||
*
|
||||
* @retval 0 success
|
||||
* @retval ENOENT If @p name is not found in @p plist.
|
||||
* @retval EFTYPE If coercion of the property's value to @p val.
|
||||
* @retval ERANGE If coercion of the property's value would overflow
|
||||
* (or underflow) @p val.
|
||||
*/
|
||||
int
|
||||
bhnd_nvram_plist_get_bool(bhnd_nvram_plist *plist, const char *name,
|
||||
bool *val)
|
||||
{
|
||||
return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
|
||||
BHND_NVRAM_TYPE_BOOL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new property value.
|
||||
*
|
||||
|
|
@ -900,6 +921,18 @@ bhnd_nvram_prop_type(bhnd_nvram_prop *prop)
|
|||
return (bhnd_nvram_val_type(prop->val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if @p prop has a NULL value type (BHND_NVRAM_TYPE_NULL), false
|
||||
* otherwise.
|
||||
*
|
||||
* @param prop The property to query.
|
||||
*/
|
||||
bool
|
||||
bhnd_nvram_prop_is_null(bhnd_nvram_prop *prop)
|
||||
{
|
||||
return (bhnd_nvram_prop_type(prop) == BHND_NVRAM_TYPE_NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a borrowed reference to the property's internal value representation.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ int bhnd_nvram_plist_get_uint64(bhnd_nvram_plist *plist,
|
|||
const char *name, uint64_t *val);
|
||||
int bhnd_nvram_plist_get_string(bhnd_nvram_plist *plist,
|
||||
const char *name, const char **val);
|
||||
int bhnd_nvram_plist_get_bool(bhnd_nvram_plist *plist,
|
||||
const char *name, bool *val);
|
||||
|
||||
bhnd_nvram_prop *bhnd_nvram_prop_new(const char *name,
|
||||
bhnd_nvram_val *val);
|
||||
|
|
@ -118,6 +120,8 @@ const char *bhnd_nvram_prop_name(bhnd_nvram_prop *prop);
|
|||
bhnd_nvram_val *bhnd_nvram_prop_val(bhnd_nvram_prop *prop);
|
||||
bhnd_nvram_type bhnd_nvram_prop_type(bhnd_nvram_prop *prop);
|
||||
|
||||
bool bhnd_nvram_prop_is_null(bhnd_nvram_prop *prop);
|
||||
|
||||
const void *bhnd_nvram_prop_bytes(bhnd_nvram_prop *prop,
|
||||
size_t *olen, bhnd_nvram_type *otype);
|
||||
int bhnd_nvram_prop_encode(bhnd_nvram_prop *prop,
|
||||
|
|
|
|||
|
|
@ -301,6 +301,9 @@ bhnd_nvram_store_setvar(struct bhnd_nvram_store *sc, const char *name,
|
|||
case BHND_NVRAM_TYPE_INT16:
|
||||
case BHND_NVRAM_TYPE_INT32:
|
||||
case BHND_NVRAM_TYPE_INT64:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT32_ARRAY:
|
||||
|
|
@ -311,6 +314,7 @@ bhnd_nvram_store_setvar(struct bhnd_nvram_store *sc, const char *name,
|
|||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
// TODO: non-char/string value support
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,12 @@ bhnd_nvram_type_name(bhnd_nvram_type type)
|
|||
return ("int64");
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
return ("string");
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
return ("bool");
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return ("null");
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return ("data");
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
return ("uint8[]");
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
|
|
@ -156,6 +162,8 @@ bhnd_nvram_type_name(bhnd_nvram_type type)
|
|||
return ("char[]");
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
return ("string[]");
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return ("bool[]");
|
||||
}
|
||||
|
||||
/* Quiesce gcc4.2 */
|
||||
|
|
@ -186,6 +194,9 @@ bhnd_nvram_is_signed_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_UINT32:
|
||||
case BHND_NVRAM_TYPE_UINT64:
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT32_ARRAY:
|
||||
|
|
@ -196,6 +207,7 @@ bhnd_nvram_is_signed_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
|
@ -243,6 +255,9 @@ bhnd_nvram_is_int_type(bhnd_nvram_type type)
|
|||
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT32_ARRAY:
|
||||
|
|
@ -253,6 +268,7 @@ bhnd_nvram_is_int_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
|
@ -279,6 +295,9 @@ bhnd_nvram_is_array_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64:
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (false);
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
|
|
@ -291,6 +310,7 @@ bhnd_nvram_is_array_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
@ -318,6 +338,9 @@ bhnd_nvram_base_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64:
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (type);
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY: return (BHND_NVRAM_TYPE_UINT8);
|
||||
|
|
@ -330,6 +353,63 @@ bhnd_nvram_base_type(bhnd_nvram_type type)
|
|||
case BHND_NVRAM_TYPE_INT64_ARRAY: return (BHND_NVRAM_TYPE_INT64);
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY: return (BHND_NVRAM_TYPE_CHAR);
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY: return (BHND_NVRAM_TYPE_STRING);
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY: return (BHND_NVRAM_TYPE_BOOL);
|
||||
}
|
||||
|
||||
/* Quiesce gcc4.2 */
|
||||
BHND_NV_PANIC("bhnd nvram type %u unknown", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw data type used to represent values of @p type, or return
|
||||
* @p type is @p type is not a complex type.
|
||||
*
|
||||
* @param type The type to query.
|
||||
*/
|
||||
bhnd_nvram_type
|
||||
bhnd_nvram_raw_type(bhnd_nvram_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
return (BHND_NVRAM_TYPE_UINT8);
|
||||
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
return (BHND_NVRAM_TYPE_UINT8_ARRAY);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL: {
|
||||
_Static_assert(sizeof(bhnd_nvram_bool_t) == sizeof(uint8_t),
|
||||
"bhnd_nvram_bool_t must be uint8-representable");
|
||||
return (BHND_NVRAM_TYPE_UINT8);
|
||||
}
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (BHND_NVRAM_TYPE_UINT8_ARRAY);
|
||||
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (BHND_NVRAM_TYPE_UINT8_ARRAY);
|
||||
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
return (BHND_NVRAM_TYPE_UINT8_ARRAY);
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_UINT16:
|
||||
case BHND_NVRAM_TYPE_UINT32:
|
||||
case BHND_NVRAM_TYPE_UINT64:
|
||||
case BHND_NVRAM_TYPE_INT8:
|
||||
case BHND_NVRAM_TYPE_INT16:
|
||||
case BHND_NVRAM_TYPE_INT32:
|
||||
case BHND_NVRAM_TYPE_INT64:
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT32_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT32_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
return (type);
|
||||
}
|
||||
|
||||
/* Quiesce gcc4.2 */
|
||||
|
|
@ -348,8 +428,16 @@ bhnd_nvram_type_width(bhnd_nvram_type type)
|
|||
switch (type) {
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (sizeof(bhnd_nvram_bool_t));
|
||||
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
|
|
@ -392,9 +480,18 @@ bhnd_nvram_type_host_align(bhnd_nvram_type type)
|
|||
switch (type) {
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
return (_Alignof(uint8_t));
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY: {
|
||||
_Static_assert(sizeof(bhnd_nvram_bool_t) == sizeof(uint8_t),
|
||||
"bhnd_nvram_bool_t must be uint8-representable");
|
||||
return (_Alignof(uint8_t));
|
||||
}
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return (1);
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
return (_Alignof(uint8_t));
|
||||
|
|
|
|||
|
|
@ -66,9 +66,19 @@ static int bhnd_nvram_val_set(bhnd_nvram_val *value, const void *inp,
|
|||
static int bhnd_nvram_val_set_inline(bhnd_nvram_val *value,
|
||||
const void *inp, size_t ilen, bhnd_nvram_type itype);
|
||||
|
||||
|
||||
static int bhnd_nvram_val_encode_data(const void *inp, size_t ilen,
|
||||
bhnd_nvram_type itype, void *outp, size_t *olen,
|
||||
bhnd_nvram_type otype);
|
||||
static int bhnd_nvram_val_encode_int(const void *inp, size_t ilen,
|
||||
bhnd_nvram_type itype, void *outp, size_t *olen,
|
||||
bhnd_nvram_type otype);
|
||||
static int bhnd_nvram_val_encode_null(const void *inp, size_t ilen,
|
||||
bhnd_nvram_type itype, void *outp, size_t *olen,
|
||||
bhnd_nvram_type otype);
|
||||
static int bhnd_nvram_val_encode_bool(const void *inp, size_t ilen,
|
||||
bhnd_nvram_type itype, void *outp, size_t *olen,
|
||||
bhnd_nvram_type otype);
|
||||
static int bhnd_nvram_val_encode_string(const void *inp, size_t ilen,
|
||||
bhnd_nvram_type itype, void *outp, size_t *olen,
|
||||
bhnd_nvram_type otype);
|
||||
|
|
@ -83,7 +93,6 @@ static int bhnd_nvram_val_encode_string(const void *inp, size_t ilen,
|
|||
.data_storage = BHND_NVRAM_VAL_DATA_NONE, \
|
||||
};
|
||||
|
||||
|
||||
/** Assert that @p value's backing representation state has initialized
|
||||
* as empty. */
|
||||
#define BHND_NVRAM_VAL_ASSERT_EMPTY(_value) \
|
||||
|
|
@ -120,6 +129,16 @@ bhnd_nvram_val_data_storage data_storage; /**< data storage */
|
|||
bhnd_nvram_type data_type; /**< data type */
|
||||
size_t data_len; /**< data size */
|
||||
|
||||
/* Shared NULL value instance */
|
||||
bhnd_nvram_val bhnd_nvram_val_null = {
|
||||
.refs = 1,
|
||||
.val_storage = BHND_NVRAM_VAL_STORAGE_STATIC,
|
||||
.fmt = &bhnd_nvram_val_null_fmt,
|
||||
.data_storage = BHND_NVRAM_VAL_DATA_INLINE,
|
||||
.data_type = BHND_NVRAM_TYPE_NULL,
|
||||
.data_len = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the human-readable name of @p fmt.
|
||||
*/
|
||||
|
|
@ -156,6 +175,12 @@ bhnd_nvram_val_default_fmt(bhnd_nvram_type type)
|
|||
return (&bhnd_nvram_val_char_fmt);
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
return (&bhnd_nvram_val_string_fmt);
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
return (&bhnd_nvram_val_bool_fmt);
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return (&bhnd_nvram_val_null_fmt);
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (&bhnd_nvram_val_data_fmt);
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
return (&bhnd_nvram_val_uint8_array_fmt);
|
||||
case BHND_NVRAM_TYPE_UINT16_ARRAY:
|
||||
|
|
@ -176,6 +201,8 @@ bhnd_nvram_val_default_fmt(bhnd_nvram_type type)
|
|||
return (&bhnd_nvram_val_char_array_fmt);
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
return (&bhnd_nvram_val_string_array_fmt);
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
return (&bhnd_nvram_val_bool_array_fmt);
|
||||
}
|
||||
|
||||
/* Quiesce gcc4.2 */
|
||||
|
|
@ -634,6 +661,156 @@ bhnd_nvram_val_release(bhnd_nvram_val *value)
|
|||
bhnd_nv_free(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard BHND_NVRAM_TYPE_NULL encoding implementation.
|
||||
*/
|
||||
static int
|
||||
bhnd_nvram_val_encode_null(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
||||
void *outp, size_t *olen, bhnd_nvram_type otype)
|
||||
{
|
||||
size_t limit, nbytes;
|
||||
|
||||
BHND_NV_ASSERT(itype == BHND_NVRAM_TYPE_NULL,
|
||||
("unsupported type: %d", itype));
|
||||
|
||||
/* Determine output byte limit */
|
||||
if (outp != NULL)
|
||||
limit = *olen;
|
||||
else
|
||||
limit = 0;
|
||||
|
||||
nbytes = 0;
|
||||
|
||||
/* Write to output */
|
||||
switch (otype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
/* Can be directly encoded as a zero-length NULL value */
|
||||
nbytes = 0;
|
||||
break;
|
||||
default:
|
||||
/* Not representable */
|
||||
return (EFTYPE);
|
||||
}
|
||||
|
||||
/* Provide required length */
|
||||
*olen = nbytes;
|
||||
if (limit < *olen) {
|
||||
if (outp == NULL)
|
||||
return (0);
|
||||
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard BHND_NVRAM_TYPE_BOOL encoding implementation.
|
||||
*/
|
||||
static int
|
||||
bhnd_nvram_val_encode_bool(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
||||
void *outp, size_t *olen, bhnd_nvram_type otype)
|
||||
{
|
||||
bhnd_nvram_bool_t bval;
|
||||
size_t limit, nbytes, nelem;
|
||||
int error;
|
||||
|
||||
BHND_NV_ASSERT(itype == BHND_NVRAM_TYPE_BOOL,
|
||||
("unsupported type: %d", itype));
|
||||
|
||||
/* Determine output byte limit */
|
||||
if (outp != NULL)
|
||||
limit = *olen;
|
||||
else
|
||||
limit = 0;
|
||||
|
||||
/* Must be exactly one element in input */
|
||||
if ((error = bhnd_nvram_value_nelem(inp, ilen, itype, &nelem)))
|
||||
return (error);
|
||||
|
||||
if (nelem != 1)
|
||||
return (EFTYPE);
|
||||
|
||||
/* Fetch (and normalize) boolean value */
|
||||
bval = (*(const bhnd_nvram_bool_t *)inp != 0) ? true : false;
|
||||
|
||||
/* Write to output */
|
||||
switch (otype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
/* False can be directly encoded as a zero-length NULL value */
|
||||
if (bval != false)
|
||||
return (EFTYPE);
|
||||
|
||||
nbytes = 0;
|
||||
break;
|
||||
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY: {
|
||||
/* Can encode as "true" or "false" */
|
||||
const char *str = bval ? "true" : "false";
|
||||
|
||||
nbytes = strlen(str) + 1;
|
||||
if (limit > nbytes)
|
||||
strcpy(outp, str);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* If output type is an integer, we can delegate to standard
|
||||
* integer encoding to encode as zero or one. */
|
||||
if (bhnd_nvram_is_int_type(otype)) {
|
||||
uint8_t ival = bval ? 1 : 0;
|
||||
|
||||
return (bhnd_nvram_val_encode_int(&ival, sizeof(ival),
|
||||
BHND_NVRAM_TYPE_UINT8, outp, olen, otype));
|
||||
}
|
||||
|
||||
/* Otherwise not representable */
|
||||
return (EFTYPE);
|
||||
}
|
||||
|
||||
/* Provide required length */
|
||||
*olen = nbytes;
|
||||
if (limit < *olen) {
|
||||
if (outp == NULL)
|
||||
return (0);
|
||||
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard BHND_NVRAM_TYPE_DATA encoding implementation.
|
||||
*/
|
||||
static int
|
||||
bhnd_nvram_val_encode_data(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
||||
void *outp, size_t *olen, bhnd_nvram_type otype)
|
||||
{
|
||||
BHND_NV_ASSERT(itype == BHND_NVRAM_TYPE_DATA,
|
||||
("unsupported type: %d", itype));
|
||||
|
||||
/* Write to output */
|
||||
switch (otype) {
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
/* If encoding as a string, produce an EFI-style hexadecimal
|
||||
* byte array (HF1F...) by interpreting the octet string
|
||||
* as an array of uint8 values */
|
||||
return (bhnd_nvram_value_printf("H%[]02hhX", inp, ilen,
|
||||
BHND_NVRAM_TYPE_UINT8_ARRAY, outp, olen, ""));
|
||||
|
||||
default:
|
||||
/* Fall back on direct interpretation as an array of 8-bit
|
||||
* integers array */
|
||||
return (bhnd_nvram_value_coerce(inp, ilen,
|
||||
BHND_NVRAM_TYPE_UINT8_ARRAY, outp, olen, otype));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Standard string/char array/char encoding implementation.
|
||||
*
|
||||
|
|
@ -673,6 +850,14 @@ bhnd_nvram_val_encode_string(const void *inp, size_t ilen,
|
|||
|
||||
/* Parse the string data and write to output */
|
||||
switch (otype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
/* Only an empty string may be represented as a NULL value */
|
||||
if (cstr_len != 0)
|
||||
return (EFTYPE);
|
||||
|
||||
*olen = 0;
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
/* String must contain exactly 1 non-terminating-NUL character
|
||||
|
|
@ -696,6 +881,99 @@ bhnd_nvram_val_encode_string(const void *inp, size_t ilen,
|
|||
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY: {
|
||||
const char *p;
|
||||
size_t plen;
|
||||
bhnd_nvram_bool_t bval;
|
||||
|
||||
/* Trim leading/trailing whitespace */
|
||||
p = cstr;
|
||||
plen = bhnd_nvram_trim_field(&p, cstr_len, '\0');
|
||||
|
||||
/* Parse string representation */
|
||||
if (strncasecmp(p, "true", plen) == 0 ||
|
||||
strncasecmp(p, "yes", plen) == 0 ||
|
||||
strncmp(p, "1", plen) == 0)
|
||||
{
|
||||
bval = true;
|
||||
} else if (strncasecmp(p, "false", plen) == 0 ||
|
||||
strncasecmp(p, "no", plen) == 0 ||
|
||||
strncmp(p, "0", plen) == 0)
|
||||
{
|
||||
bval = false;
|
||||
} else {
|
||||
/* Not a recognized boolean string */
|
||||
return (EFTYPE);
|
||||
}
|
||||
|
||||
/* Write to output */
|
||||
nbytes = sizeof(bhnd_nvram_bool_t);
|
||||
if (limit >= nbytes)
|
||||
*((bhnd_nvram_bool_t *)outp) = bval;
|
||||
|
||||
/* Provide required length */
|
||||
*olen = nbytes;
|
||||
if (limit < *olen && outp != NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
case BHND_NVRAM_TYPE_DATA: {
|
||||
const char *p;
|
||||
size_t plen, parsed_len;
|
||||
int error;
|
||||
|
||||
/* Trim leading/trailing whitespace */
|
||||
p = cstr;
|
||||
plen = bhnd_nvram_trim_field(&p, cstr_len, '\0');
|
||||
|
||||
/* Check for EFI-style hexadecimal byte array string format.
|
||||
* Must have a 'H' prefix */
|
||||
if (plen < 1 || bhnd_nv_toupper(*p) != 'H')
|
||||
return (EFTYPE);
|
||||
|
||||
/* Skip leading 'H' */
|
||||
p++;
|
||||
plen--;
|
||||
|
||||
/* Parse the input string's two-char octets until the end
|
||||
* of input is reached. The last octet may contain only
|
||||
* one char */
|
||||
while (plen > 0) {
|
||||
uint8_t byte;
|
||||
size_t byte_len = sizeof(byte);
|
||||
|
||||
/* Parse next two-character hex octet */
|
||||
error = bhnd_nvram_parse_int(p, bhnd_nv_ummin(plen, 2),
|
||||
16, &parsed_len, &byte, &byte_len, otype_base);
|
||||
if (error) {
|
||||
BHND_NV_DEBUG("error parsing '%.*s' as "
|
||||
"integer: %d\n", BHND_NV_PRINT_WIDTH(plen),
|
||||
p, error);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Write to output */
|
||||
if (limit > nbytes)
|
||||
*((uint8_t *)outp + nbytes) = byte;
|
||||
nbytes++;
|
||||
|
||||
/* Advance input */
|
||||
p += parsed_len;
|
||||
plen -= parsed_len;
|
||||
}
|
||||
|
||||
/* Provide required length */
|
||||
*olen = nbytes;
|
||||
if (limit < *olen && outp != NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_UINT16:
|
||||
|
|
@ -896,8 +1174,30 @@ bhnd_nvram_val_encode_int(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
|
||||
/* Write output */
|
||||
switch (otype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
/* Cannot encode an integer value as NULL */
|
||||
return (EFTYPE);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL: {
|
||||
bhnd_nvram_bool_t bval;
|
||||
|
||||
if (intv.u64 == 0 || intv.u64 == 1) {
|
||||
bval = intv.u64;
|
||||
} else {
|
||||
/* Encoding as a bool would lose information */
|
||||
return (ERANGE);
|
||||
}
|
||||
|
||||
nbytes = sizeof(bhnd_nvram_bool_t);
|
||||
if (limit >= nbytes)
|
||||
*((bhnd_nvram_bool_t *)outp) = bval;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
if (intv.u64 > UINT8_MAX)
|
||||
|
|
@ -1335,11 +1635,23 @@ bhnd_nvram_val_generic_encode_elem(bhnd_nvram_val *value, const void *inp,
|
|||
|
||||
itype = bhnd_nvram_val_elem_type(value);
|
||||
switch (itype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return (bhnd_nvram_val_encode_null(inp, ilen, itype, outp, olen,
|
||||
otype));
|
||||
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
return (bhnd_nvram_val_encode_data(inp, ilen, itype, outp,
|
||||
olen, otype));
|
||||
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
return (bhnd_nvram_val_encode_string(inp, ilen, itype, outp,
|
||||
olen, otype));
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
return (bhnd_nvram_val_encode_bool(inp, ilen, itype, outp, olen,
|
||||
otype));
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_UINT16:
|
||||
case BHND_NVRAM_TYPE_UINT32:
|
||||
|
|
@ -1486,10 +1798,22 @@ bhnd_nvram_val_set_inline(bhnd_nvram_val *value, const void *inp, size_t ilen,
|
|||
|
||||
/* Attempt to copy to inline storage */
|
||||
switch (itype) {
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
if (ilen != 0)
|
||||
return (EFAULT);
|
||||
|
||||
/* Nothing to copy */
|
||||
NV_STORE_INIT_INLINE();
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
NV_STORE_INLINE(uint8_t, ch);
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
NV_STORE_INLINE(bhnd_nvram_bool_t, b);
|
||||
return(0);
|
||||
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_INT8:
|
||||
NV_STORE_INLINE(uint8_t, u8);
|
||||
|
|
@ -1514,6 +1838,7 @@ bhnd_nvram_val_set_inline(bhnd_nvram_val *value, const void *inp, size_t ilen,
|
|||
NV_COPY_ARRRAY_INLINE(uint8_t, ch);
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
case BHND_NVRAM_TYPE_UINT8_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT8_ARRAY:
|
||||
NV_COPY_ARRRAY_INLINE(uint8_t, u8);
|
||||
|
|
@ -1534,6 +1859,10 @@ bhnd_nvram_val_set_inline(bhnd_nvram_val *value, const void *inp, size_t ilen,
|
|||
NV_COPY_ARRRAY_INLINE(uint64_t, u64);
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:
|
||||
NV_COPY_ARRRAY_INLINE(bhnd_nvram_bool_t, b);
|
||||
return(0);
|
||||
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
case BHND_NVRAM_TYPE_STRING_ARRAY:
|
||||
if (ilen > sizeof(value->data.ch))
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ struct bhnd_nvram_val {
|
|||
int32_t i32[2]; /**< 32-bit signed data */
|
||||
int64_t i64[1]; /**< 64-bit signed data */
|
||||
unsigned char ch[8]; /**< 8-bit character data */
|
||||
bhnd_nvram_bool_t b[8]; /**< 8-bit boolean data */
|
||||
const void *ptr; /**< external data */
|
||||
} data;
|
||||
};
|
||||
|
|
@ -258,7 +259,10 @@ BHND_NVRAM_VAL_FMT_DECL(int16);
|
|||
BHND_NVRAM_VAL_FMT_DECL(int32);
|
||||
BHND_NVRAM_VAL_FMT_DECL(int64);
|
||||
BHND_NVRAM_VAL_FMT_DECL(char);
|
||||
BHND_NVRAM_VAL_FMT_DECL(bool);
|
||||
BHND_NVRAM_VAL_FMT_DECL(string);
|
||||
BHND_NVRAM_VAL_FMT_DECL(data);
|
||||
BHND_NVRAM_VAL_FMT_DECL(null);
|
||||
|
||||
BHND_NVRAM_VAL_FMT_DECL(uint8_array);
|
||||
BHND_NVRAM_VAL_FMT_DECL(uint16_array);
|
||||
|
|
@ -269,6 +273,11 @@ BHND_NVRAM_VAL_FMT_DECL(int16_array);
|
|||
BHND_NVRAM_VAL_FMT_DECL(int32_array);
|
||||
BHND_NVRAM_VAL_FMT_DECL(int64_array);
|
||||
BHND_NVRAM_VAL_FMT_DECL(char_array);
|
||||
BHND_NVRAM_VAL_FMT_DECL(bool_array);
|
||||
BHND_NVRAM_VAL_FMT_DECL(string_array);
|
||||
|
||||
/** Shared NULL value instance */
|
||||
#define BHND_NVRAM_VAL_NULL (&bhnd_nvram_val_null)
|
||||
extern bhnd_nvram_val bhnd_nvram_val_null;
|
||||
|
||||
#endif /* _BHND_NVRAM_BHND_NVRAM_VALUE_H_ */
|
||||
|
|
|
|||
|
|
@ -215,7 +215,10 @@ BHND_NVRAM_VAL_FMT_NATIVE(int16, INT16);
|
|||
BHND_NVRAM_VAL_FMT_NATIVE(int32, INT32);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(int64, INT64);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(char, CHAR);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(bool, BOOL);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(string, STRING);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(data, DATA);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(null, NULL);
|
||||
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(uint8_array, UINT8_ARRAY);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(uint16_array, UINT16_ARRAY);
|
||||
|
|
@ -226,6 +229,7 @@ BHND_NVRAM_VAL_FMT_NATIVE(int16_array, INT16_ARRAY);
|
|||
BHND_NVRAM_VAL_FMT_NATIVE(int32_array, INT32_ARRAY);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(int64_array, INT64_ARRAY);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(char_array, CHAR_ARRAY);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(bool_array, BOOL_ARRAY);
|
||||
BHND_NVRAM_VAL_FMT_NATIVE(string_array, STRING_ARRAY);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -66,6 +66,15 @@ bhnd_nvram_value_check_aligned(const void *inp, size_t ilen,
|
|||
{
|
||||
size_t align, width;
|
||||
|
||||
/* As a special case, NULL values have no alignment, but must
|
||||
* always have a length of zero */
|
||||
if (itype == BHND_NVRAM_TYPE_NULL) {
|
||||
if (ilen != 0)
|
||||
return (EFAULT);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Check pointer alignment against the required host alignment */
|
||||
align = bhnd_nvram_type_host_align(itype);
|
||||
BHND_NV_ASSERT(align != 0, ("invalid zero alignment"));
|
||||
|
|
@ -119,6 +128,20 @@ bhnd_nvram_value_nelem(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
return (error);
|
||||
|
||||
switch (itype) {
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
/* Always exactly one element */
|
||||
*nelem = 1;
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
/* Must be zero length */
|
||||
if (ilen != 0)
|
||||
return (EFAULT);
|
||||
|
||||
/* Always exactly one element */
|
||||
*nelem = 1;
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_STRING:
|
||||
/* Always exactly one element */
|
||||
*nelem = 1;
|
||||
|
|
@ -165,7 +188,8 @@ bhnd_nvram_value_nelem(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
case BHND_NVRAM_TYPE_INT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT32_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY: {
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY: {
|
||||
size_t width = bhnd_nvram_type_width(itype);
|
||||
BHND_NV_ASSERT(width != 0, ("invalid width"));
|
||||
|
||||
|
|
@ -182,6 +206,7 @@ bhnd_nvram_value_nelem(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
case BHND_NVRAM_TYPE_UINT32:
|
||||
case BHND_NVRAM_TYPE_INT64:
|
||||
case BHND_NVRAM_TYPE_UINT64:
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
/* Length must be equal to the size of exactly one
|
||||
* element (arrays can represent zero elements -- non-array
|
||||
* types cannot) */
|
||||
|
|
@ -236,7 +261,8 @@ bhnd_nvram_value_size(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
case BHND_NVRAM_TYPE_INT16_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT32_ARRAY:
|
||||
case BHND_NVRAM_TYPE_INT64_ARRAY:
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY: {
|
||||
case BHND_NVRAM_TYPE_CHAR_ARRAY:
|
||||
case BHND_NVRAM_TYPE_BOOL_ARRAY:{
|
||||
size_t width;
|
||||
|
||||
width = bhnd_nvram_type_width(itype);
|
||||
|
|
@ -305,6 +331,18 @@ bhnd_nvram_value_size(const void *inp, size_t ilen, bhnd_nvram_type itype,
|
|||
return (size);
|
||||
}
|
||||
|
||||
case BHND_NVRAM_TYPE_NULL:
|
||||
return (0);
|
||||
|
||||
case BHND_NVRAM_TYPE_DATA:
|
||||
if (inp == NULL)
|
||||
return (0);
|
||||
|
||||
return (ilen);
|
||||
|
||||
case BHND_NVRAM_TYPE_BOOL:
|
||||
return (sizeof(bhnd_nvram_bool_t));
|
||||
|
||||
case BHND_NVRAM_TYPE_INT8:
|
||||
case BHND_NVRAM_TYPE_UINT8:
|
||||
case BHND_NVRAM_TYPE_CHAR:
|
||||
|
|
|
|||
Loading…
Reference in a new issue