svn commit: r310293 - head/sys/dev/bhnd/nvram
Landon J. Fuller
landonf at FreeBSD.org
Mon Dec 19 20:23:21 UTC 2016
Author: landonf
Date: Mon Dec 19 20:23:19 2016
New Revision: 310293
URL: https://svnweb.freebsd.org/changeset/base/310293
Log:
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
Modified:
head/sys/dev/bhnd/nvram/bhnd_nvram.h
head/sys/dev/bhnd/nvram/bhnd_nvram_plist.c
head/sys/dev/bhnd/nvram/bhnd_nvram_plist.h
head/sys/dev/bhnd/nvram/bhnd_nvram_store.c
head/sys/dev/bhnd/nvram/bhnd_nvram_subr.c
head/sys/dev/bhnd/nvram/bhnd_nvram_value.c
head/sys/dev/bhnd/nvram/bhnd_nvram_value.h
head/sys/dev/bhnd/nvram/bhnd_nvram_value_fmts.c
head/sys/dev/bhnd/nvram/bhnd_nvram_value_subr.c
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram.h
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram.h Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram.h Mon Dec 19 20:23:19 2016 (r310293)
@@ -40,6 +40,14 @@
#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.
*/
typedef enum {
@@ -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);
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_plist.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_plist.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_plist.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -743,6 +743,27 @@ bhnd_nvram_plist_get_uint64(bhnd_nvram_p
}
/**
+ * 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.
*
* The caller is responsible for releasing the returned property value
@@ -901,6 +922,18 @@ bhnd_nvram_prop_type(bhnd_nvram_prop *pr
}
/**
+ * 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.
*
* @param prop The property to query.
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_plist.h
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_plist.h Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_plist.h Mon Dec 19 20:23:19 2016 (r310293)
@@ -104,6 +104,8 @@ int bhnd_nvram_plist_get_uint64(bhnd_
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_n
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,
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_store.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_store.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_store.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -301,6 +301,9 @@ bhnd_nvram_store_setvar(struct bhnd_nvra
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_nvra
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);
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_subr.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_subr.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_subr.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -136,6 +136,12 @@ bhnd_nvram_type_name(bhnd_nvram_type typ
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 typ
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_typ
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_typ
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 t
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 t
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
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
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 typ
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 typ
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 ty
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_ty
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));
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_value.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_value.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_value.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -66,9 +66,19 @@ static int bhnd_nvram_val_set(bhnd_nvra
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
.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_storag
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_ty
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_ty
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 */
@@ -635,6 +662,156 @@ bhnd_nvram_val_release(bhnd_nvram_val *v
}
/**
+ * 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.
*
* Input type must be one of:
@@ -673,6 +850,14 @@ bhnd_nvram_val_encode_string(const void
/* 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
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 *in
/* 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_
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
/* 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
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
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))
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_value.h
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_value.h Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_value.h Mon Dec 19 20:23:19 2016 (r310293)
@@ -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_ */
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_value_fmts.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_value_fmts.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_value_fmts.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -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, I
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);
/**
Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_value_subr.c
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_value_subr.c Mon Dec 19 20:20:33 2016 (r310292)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_value_subr.c Mon Dec 19 20:23:19 2016 (r310293)
@@ -66,6 +66,15 @@ bhnd_nvram_value_check_aligned(const voi
{
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,
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,
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,
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, s
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, s
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:
More information about the svn-src-all
mailing list