#ifndef _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_
#define _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/malloc.h>
#include <sys/stdarg.h>
#else
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#endif
#include "bhnd_nvram.h"
#include "bhnd_nvram_value.h"
extern const uint8_t bhnd_nvram_crc8_tab[];
struct bhnd_nvram_vardefn;
#ifdef _KERNEL
MALLOC_DECLARE(M_BHND_NVRAM);
#define bhnd_nv_isupper(c) isupper(c)
#define bhnd_nv_islower(c) islower(c)
#define bhnd_nv_isalpha(c) isalpha(c)
#define bhnd_nv_isprint(c) isprint(c)
#define bhnd_nv_isspace(c) isspace(c)
#define bhnd_nv_isdigit(c) isdigit(c)
#define bhnd_nv_isxdigit(c) isxdigit(c)
#define bhnd_nv_toupper(c) toupper(c)
#define bhnd_nv_malloc(size) malloc((size), M_BHND_NVRAM, M_NOWAIT)
#define bhnd_nv_calloc(n, size) mallocarray((n), (size), M_BHND_NVRAM, \
M_NOWAIT | M_ZERO)
#define bhnd_nv_reallocf(buf, size) reallocf((buf), (size), M_BHND_NVRAM, \
M_NOWAIT)
#define bhnd_nv_free(buf) free((buf), M_BHND_NVRAM)
#define bhnd_nv_asprintf(buf, fmt, ...) asprintf((buf), M_BHND_NVRAM, \
fmt, ## __VA_ARGS__)
static inline char *
bhnd_nv_strdup(const char *str)
{
char *dest;
size_t len;
len = strlen(str);
dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT);
if (dest == NULL)
return (NULL);
memcpy(dest, str, len);
dest[len] = '\0';
return (dest);
}
static inline char *
bhnd_nv_strndup(const char *str, size_t len)
{
char *dest;
len = strnlen(str, len);
dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT);
if (dest == NULL)
return (NULL);
memcpy(dest, str, len);
dest[len] = '\0';
return (dest);
}
#ifdef INVARIANTS
#define BHND_NV_INVARIANTS
#endif
#define BHND_NV_ASSERT(expr, ...) KASSERT(expr, __VA_ARGS__)
#define BHND_NV_VERBOSE (bootverbose)
#define BHND_NV_PANIC(...) panic(__VA_ARGS__)
#define BHND_NV_LOG(fmt, ...) \
printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
#define bhnd_nv_ummax(a, b) ummax((a), (b))
#define bhnd_nv_ummin(a, b) ummin((a), (b))
#else
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define bhnd_nv_isupper(c) ((c) >= 'A' && (c) <= 'Z')
#define bhnd_nv_islower(c) ((c) >= 'a' && (c) <= 'z')
#define bhnd_nv_isalpha(c) (bhnd_nv_isupper(c) || bhnd_nv_islower(c))
#define bhnd_nv_isprint(c) ((c) >= ' ' && (c) <= '~')
#define bhnd_nv_isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
#define bhnd_nv_isdigit(c) isdigit(c)
#define bhnd_nv_isxdigit(c) isxdigit(c)
#define bhnd_nv_toupper(c) ((c) - \
(('a' - 'A') * ((c) >= 'a' && (c) <= 'z')))
#define bhnd_nv_malloc(size) malloc((size))
#define bhnd_nv_calloc(n, size) calloc((n), (size))
#define bhnd_nv_reallocf(buf, size) reallocf((buf), (size))
#define bhnd_nv_free(buf) free((buf))
#define bhnd_nv_strdup(str) strdup(str)
#define bhnd_nv_strndup(str, len) strndup(str, len)
#define bhnd_nv_asprintf(buf, fmt, ...) asprintf((buf), fmt, ## __VA_ARGS__)
#ifndef NDEBUG
#define BHND_NV_INVARIANTS
#endif
#ifdef BHND_NV_INVARIANTS
#define BHND_NV_ASSERT(expr, msg) do { \
if (!(expr)) { \
fprintf(stderr, "Assertion failed: %s, function %s, " \
"file %s, line %u\n", __STRING(expr), __FUNCTION__, \
__FILE__, __LINE__); \
BHND_NV_PANIC msg; \
} \
} while(0)
#else
#define BHND_NV_ASSERT(expr, msg)
#endif
#define BHND_NV_VERBOSE (0)
#define BHND_NV_PANIC(fmt, ...) do { \
fprintf(stderr, "panic: " fmt "\n", ##__VA_ARGS__); \
abort(); \
} while(0)
#define BHND_NV_LOG(fmt, ...) \
fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
static inline uintmax_t
bhnd_nv_ummax(uintmax_t a, uintmax_t b)
{
return (a > b ? a : b);
}
static inline uintmax_t
bhnd_nv_ummin(uintmax_t a, uintmax_t b)
{
return (a < b ? a : b);
}
#endif
#ifdef BHND_NV_VERBOSE
#define BHND_NV_DEBUG(...) BHND_NV_LOG(__VA_ARGS__)
#else
#define BHND_NV_DEBUG(...)
#endif
#define BHND_NV_PRINT_WIDTH(_len) \
((_len) > (INT_MAX) ? (INT_MAX) : (int)(_len))
int bhnd_nvram_value_coerce(const void *inp,
size_t ilen, bhnd_nvram_type itype,
void *outp, size_t *olen,
bhnd_nvram_type otype);
int bhnd_nvram_value_check_aligned(const void *inp,
size_t ilen, bhnd_nvram_type itype);
int bhnd_nvram_value_nelem(const void *inp,
size_t ilen, bhnd_nvram_type itype,
size_t *nelem);
size_t bhnd_nvram_value_size(const void *inp,
size_t ilen, bhnd_nvram_type itype,
size_t nelem);
int bhnd_nvram_value_printf(const char *fmt,
const void *inp, size_t ilen,
bhnd_nvram_type itype, char *outp,
size_t *olen, ...);
int bhnd_nvram_value_vprintf(const char *fmt,
const void *inp, size_t ilen,
bhnd_nvram_type itype, char *outp,
size_t *olen, va_list ap);
const void *bhnd_nvram_value_array_next(const void *inp,
size_t ilen, bhnd_nvram_type itype,
const void *prev, size_t *olen);
const struct bhnd_nvram_vardefn *bhnd_nvram_find_vardefn(const char *varname);
const struct bhnd_nvram_vardefn *bhnd_nvram_get_vardefn(size_t id);
size_t bhnd_nvram_get_vardefn_id(
const struct bhnd_nvram_vardefn *defn);
int bhnd_nvram_parse_int(const char *s,
size_t maxlen, u_int base, size_t *nbytes,
void *outp, size_t *olen,
bhnd_nvram_type otype);
int bhnd_nvram_parse_env(const char *env,
size_t env_len, char delim,
const char **name, size_t *name_len,
const char **value, size_t *value_len);
size_t bhnd_nvram_parse_field(const char **inp,
size_t ilen, char delim);
size_t bhnd_nvram_trim_field(const char **inp,
size_t ilen, char delim);
const char *bhnd_nvram_trim_path_name(const char *name);
bool bhnd_nvram_validate_name(const char *name);
static inline uint8_t
bhnd_nvram_crc8(const void *buf, size_t size, uint8_t crc)
{
const uint8_t *p = (const uint8_t *)buf;
while (size--)
crc = bhnd_nvram_crc8_tab[(crc ^ *p++)];
return (crc);
}
#define BHND_NVRAM_CRC8_INITIAL 0xFF
#define BHND_NVRAM_CRC8_VALID 0x9F
enum {
BHND_NVRAM_VF_MFGINT = 1<<0,
BHND_NVRAM_VF_IGNALL1 = 1<<1
};
enum {
SPROM_LAYOUT_MAGIC_NONE = (1<<0),
};
struct bhnd_nvram_vardefn {
const char *name;
const char *desc;
const char *help;
bhnd_nvram_type type;
uint8_t nelem;
const bhnd_nvram_val_fmt *fmt;
uint32_t flags;
};
extern const struct bhnd_nvram_vardefn bhnd_nvram_vardefns[];
extern const size_t bhnd_nvram_num_vardefns;
typedef struct bhnd_sprom_layout {
size_t size;
uint8_t rev;
uint8_t flags;
size_t srev_offset;
size_t magic_offset;
uint16_t magic_value;
size_t crc_offset;
const uint8_t *bindings;
size_t bindings_size;
uint16_t num_vars;
} bhnd_sprom_layout;
extern const struct bhnd_sprom_layout bhnd_sprom_layouts[];
extern const size_t bhnd_sprom_num_layouts;
#define SPROM_OPC_MASK 0xF0
#define SPROM_IMM_MASK 0x0F
#define SPROM_IMM_MAX SPROM_IMM_MASK
#define SPROM_OP_DATA_U8 0x00
#define SPROM_OP_DATA_U8_SCALED 0x01
#define SPROM_OP_DATA_U16 0x02
#define SPROM_OP_DATA_U32 0x03
#define SPROM_OP_DATA_I8 0x04
#define SPROM_OPCODE_EXT 0x00
#define SPROM_OPCODE_EOF 0x00
#define SPROM_OPCODE_NELEM 0x01
#define SPROM_OPCODE_VAR_END 0x02
#define SPROM_OPCODE_TYPE 0x03
#define SPROM_OPCODE_VAR_IMM 0x10
#define SPROM_OPCODE_VAR_REL_IMM 0x20
#define SPROM_OPCODE_VAR 0x30
#define SPROM_OPCODE_REV_IMM 0x40
#define SPROM_OPCODE_REV_RANGE 0x50
#define SPROM_OP_REV_RANGE_MAX 0x0F
#define SPROM_OP_REV_START_MASK 0xF0
#define SPROM_OP_REV_START_SHIFT 4
#define SPROM_OP_REV_END_MASK 0x0F
#define SPROM_OP_REV_END_SHIFT 0
#define SPROM_OPCODE_MASK_IMM 0x60
#define SPROM_OPCODE_MASK 0x70
#define SPROM_OPCODE_SHIFT_IMM 0x80
#define SPROM_OPCODE_SHIFT 0x90
#define SPROM_OPCODE_OFFSET_REL_IMM 0xA0
#define SPROM_OPCODE_OFFSET 0xB0
#define SPROM_OPCODE_TYPE_IMM 0xC0
#define SPROM_OPCODE_DO_BIND 0xD0
#define SPROM_OP_BIND_SKIP_IN_MASK 0x03
#define SPROM_OP_BIND_SKIP_IN_SHIFT 0
#define SPROM_OP_BIND_SKIP_IN_SIGN (1<<2)
#define SPROM_OP_BIND_SKIP_OUT_MASK 0x08
#define SPROM_OP_BIND_SKIP_OUT_SHIFT 3
#define SPROM_OPCODE_DO_BINDN_IMM 0xE0
#define SPROM_OPCODE_DO_BINDN 0xF0
#define SPROM_OPCODE_IS_EXT(_opcode) \
(((_opcode) & SPROM_OPC_MASK) == SPROM_OPCODE_EXT)
#define SPROM_OPCODE_OP(_opcode) \
(SPROM_OPCODE_IS_EXT(_opcode) ? (_opcode) : ((_opcode) & SPROM_OPC_MASK))
#define SPROM_OPCODE_IMM(_opcode) \
(SPROM_OPCODE_IS_EXT(_opcode) ? 0 : ((_opcode) & SPROM_IMM_MASK))
#define SPROM_OP_IS_IMPLICIT_VAR_END(_opcode) \
(((_opcode) == SPROM_OPCODE_VAR_IMM) || \
((_opcode) == SPROM_OPCODE_VAR_REL_IMM) || \
((_opcode) == SPROM_OPCODE_VAR) || \
((_opcode) == SPROM_OPCODE_REV_IMM) || \
((_opcode) == SPROM_OPCODE_REV_RANGE))
#define SPROM_OP_IS_VAR_END(_opcode) \
(((_opcode) == SPROM_OPCODE_VAR_END) || \
SPROM_OP_IS_IMPLICIT_VAR_END(_opcode))
#define SPROM_OP_IMM_MAX SPROM_IMM_MASK
#define SPROM_OP_REV_MAX MAX(SPROM_OP_REV_RANGE_MAX, SPROM_IMM_MAX)
#endif