xref: /freebsd/sys/dev/bhnd/nvram/bhnd_nvram_private.h (revision e453e498cbb88570a3ff7b3679de65c88707da95)
177cb4d3eSLandon J. Fuller /*-
277cb4d3eSLandon J. Fuller  * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
377cb4d3eSLandon J. Fuller  * All rights reserved.
477cb4d3eSLandon J. Fuller  *
577cb4d3eSLandon J. Fuller  * Redistribution and use in source and binary forms, with or without
677cb4d3eSLandon J. Fuller  * modification, are permitted provided that the following conditions
777cb4d3eSLandon J. Fuller  * are met:
877cb4d3eSLandon J. Fuller  * 1. Redistributions of source code must retain the above copyright
977cb4d3eSLandon J. Fuller  *    notice, this list of conditions and the following disclaimer,
1077cb4d3eSLandon J. Fuller  *    without modification.
1177cb4d3eSLandon J. Fuller  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1277cb4d3eSLandon J. Fuller  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1377cb4d3eSLandon J. Fuller  *    redistribution must be conditioned upon including a substantially
1477cb4d3eSLandon J. Fuller  *    similar Disclaimer requirement for further binary redistribution.
1577cb4d3eSLandon J. Fuller  *
1677cb4d3eSLandon J. Fuller  * NO WARRANTY
1777cb4d3eSLandon J. Fuller  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1877cb4d3eSLandon J. Fuller  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1977cb4d3eSLandon J. Fuller  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2077cb4d3eSLandon J. Fuller  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2177cb4d3eSLandon J. Fuller  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2277cb4d3eSLandon J. Fuller  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2377cb4d3eSLandon J. Fuller  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2477cb4d3eSLandon J. Fuller  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2577cb4d3eSLandon J. Fuller  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2677cb4d3eSLandon J. Fuller  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2777cb4d3eSLandon J. Fuller  * THE POSSIBILITY OF SUCH DAMAGES.
2877cb4d3eSLandon J. Fuller  *
2977cb4d3eSLandon J. Fuller  */
3077cb4d3eSLandon J. Fuller 
3177cb4d3eSLandon J. Fuller #ifndef _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_
3277cb4d3eSLandon J. Fuller #define _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_
3377cb4d3eSLandon J. Fuller 
3477cb4d3eSLandon J. Fuller /*
3577cb4d3eSLandon J. Fuller  * Private BHND NVRAM definitions.
3677cb4d3eSLandon J. Fuller  */
3777cb4d3eSLandon J. Fuller 
3877cb4d3eSLandon J. Fuller #include <sys/param.h>
3977cb4d3eSLandon J. Fuller 
4077cb4d3eSLandon J. Fuller #ifdef _KERNEL
4177cb4d3eSLandon J. Fuller #include <sys/malloc.h>
42*e453e498SBrooks Davis #include <sys/stdarg.h>
4377cb4d3eSLandon J. Fuller #else
4477cb4d3eSLandon J. Fuller #include <stdarg.h>
4577cb4d3eSLandon J. Fuller #include <stdbool.h>
4677cb4d3eSLandon J. Fuller #include <stdint.h>
4777cb4d3eSLandon J. Fuller #include <stdlib.h>
4877cb4d3eSLandon J. Fuller #endif
4977cb4d3eSLandon J. Fuller 
5077cb4d3eSLandon J. Fuller #include "bhnd_nvram.h"
5177cb4d3eSLandon J. Fuller #include "bhnd_nvram_value.h"
5277cb4d3eSLandon J. Fuller 
5377cb4d3eSLandon J. Fuller /*
5477cb4d3eSLandon J. Fuller  * bhnd_nvram_crc8() lookup table.
5577cb4d3eSLandon J. Fuller  */
5677cb4d3eSLandon J. Fuller extern const uint8_t bhnd_nvram_crc8_tab[];
5777cb4d3eSLandon J. Fuller 
5877cb4d3eSLandon J. Fuller /* Forward declarations */
5977cb4d3eSLandon J. Fuller struct bhnd_nvram_vardefn;
6077cb4d3eSLandon J. Fuller 
6177cb4d3eSLandon J. Fuller #ifdef _KERNEL
6277cb4d3eSLandon J. Fuller 
6377cb4d3eSLandon J. Fuller MALLOC_DECLARE(M_BHND_NVRAM);
6477cb4d3eSLandon J. Fuller 
6577cb4d3eSLandon J. Fuller #define	bhnd_nv_isupper(c)	isupper(c)
6677cb4d3eSLandon J. Fuller #define	bhnd_nv_islower(c)	islower(c)
6777cb4d3eSLandon J. Fuller #define	bhnd_nv_isalpha(c)	isalpha(c)
6877cb4d3eSLandon J. Fuller #define	bhnd_nv_isprint(c)	isprint(c)
6977cb4d3eSLandon J. Fuller #define	bhnd_nv_isspace(c)	isspace(c)
7077cb4d3eSLandon J. Fuller #define	bhnd_nv_isdigit(c)	isdigit(c)
7177cb4d3eSLandon J. Fuller #define	bhnd_nv_isxdigit(c)	isxdigit(c)
7277cb4d3eSLandon J. Fuller #define	bhnd_nv_toupper(c)	toupper(c)
7377cb4d3eSLandon J. Fuller 
7419be09f3SLandon J. Fuller #define	bhnd_nv_malloc(size)		malloc((size), M_BHND_NVRAM, M_NOWAIT)
7592e1020aSPedro F. Giffuni #define	bhnd_nv_calloc(n, size)		mallocarray((n), (size), M_BHND_NVRAM, \
7619be09f3SLandon J. Fuller 					    M_NOWAIT | M_ZERO)
7777cb4d3eSLandon J. Fuller #define	bhnd_nv_reallocf(buf, size)	reallocf((buf), (size), M_BHND_NVRAM, \
7819be09f3SLandon J. Fuller 					    M_NOWAIT)
7977cb4d3eSLandon J. Fuller #define	bhnd_nv_free(buf)		free((buf), M_BHND_NVRAM)
8019be09f3SLandon J. Fuller #define	bhnd_nv_asprintf(buf, fmt, ...)	asprintf((buf), M_BHND_NVRAM,	\
8119be09f3SLandon J. Fuller 					    fmt, ## __VA_ARGS__)
8219be09f3SLandon J. Fuller 
8319be09f3SLandon J. Fuller /* We need our own strdup() implementation to pass required M_NOWAIT */
8419be09f3SLandon J. Fuller static inline char *
bhnd_nv_strdup(const char * str)8519be09f3SLandon J. Fuller bhnd_nv_strdup(const char *str)
8619be09f3SLandon J. Fuller {
8719be09f3SLandon J. Fuller 	char	*dest;
8819be09f3SLandon J. Fuller 	size_t	 len;
8919be09f3SLandon J. Fuller 
9019be09f3SLandon J. Fuller 	len = strlen(str);
9119be09f3SLandon J. Fuller 	dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT);
92397b9e40SLandon J. Fuller 	if (dest == NULL)
93397b9e40SLandon J. Fuller 		return (NULL);
94397b9e40SLandon J. Fuller 
9519be09f3SLandon J. Fuller 	memcpy(dest, str, len);
9619be09f3SLandon J. Fuller 	dest[len] = '\0';
9719be09f3SLandon J. Fuller 
9819be09f3SLandon J. Fuller 	return (dest);
9919be09f3SLandon J. Fuller }
10019be09f3SLandon J. Fuller 
10119be09f3SLandon J. Fuller /* We need our own strndup() implementation to pass required M_NOWAIT */
10219be09f3SLandon J. Fuller static inline char *
bhnd_nv_strndup(const char * str,size_t len)10319be09f3SLandon J. Fuller bhnd_nv_strndup(const char *str, size_t len)
10419be09f3SLandon J. Fuller {
10519be09f3SLandon J. Fuller 	char	*dest;
10619be09f3SLandon J. Fuller 
10719be09f3SLandon J. Fuller 	len = strnlen(str, len);
10819be09f3SLandon J. Fuller 	dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT);
109397b9e40SLandon J. Fuller 	if (dest == NULL)
110397b9e40SLandon J. Fuller 		return (NULL);
111397b9e40SLandon J. Fuller 
11219be09f3SLandon J. Fuller 	memcpy(dest, str, len);
11319be09f3SLandon J. Fuller 	dest[len] = '\0';
11419be09f3SLandon J. Fuller 
11519be09f3SLandon J. Fuller 	return (dest);
11619be09f3SLandon J. Fuller }
11777cb4d3eSLandon J. Fuller 
11877cb4d3eSLandon J. Fuller #ifdef INVARIANTS
11977cb4d3eSLandon J. Fuller #define	BHND_NV_INVARIANTS
12077cb4d3eSLandon J. Fuller #endif
12177cb4d3eSLandon J. Fuller 
12277cb4d3eSLandon J. Fuller #define	BHND_NV_ASSERT(expr, ...)	KASSERT(expr, __VA_ARGS__)
12377cb4d3eSLandon J. Fuller 
12477cb4d3eSLandon J. Fuller #define	BHND_NV_VERBOSE			(bootverbose)
12577cb4d3eSLandon J. Fuller #define	BHND_NV_PANIC(...)		panic(__VA_ARGS__)
12677cb4d3eSLandon J. Fuller #define	BHND_NV_LOG(fmt, ...)		\
12777cb4d3eSLandon J. Fuller 	printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
12877cb4d3eSLandon J. Fuller 
12977cb4d3eSLandon J. Fuller #define	bhnd_nv_ummax(a, b)		ummax((a), (b))
13077cb4d3eSLandon J. Fuller #define	bhnd_nv_ummin(a, b)		ummin((a), (b))
13177cb4d3eSLandon J. Fuller 
13277cb4d3eSLandon J. Fuller #else /* !_KERNEL */
13377cb4d3eSLandon J. Fuller 
13477cb4d3eSLandon J. Fuller #include <assert.h>
13577cb4d3eSLandon J. Fuller #include <stdint.h>
13677cb4d3eSLandon J. Fuller #include <stdio.h>
13777cb4d3eSLandon J. Fuller #include <stdlib.h>
13877cb4d3eSLandon J. Fuller 
13977cb4d3eSLandon J. Fuller /* ASCII-specific ctype variants that work consistently regardless
14077cb4d3eSLandon J. Fuller  * of current locale */
14177cb4d3eSLandon J. Fuller #define	bhnd_nv_isupper(c)	((c) >= 'A' && (c) <= 'Z')
14277cb4d3eSLandon J. Fuller #define	bhnd_nv_islower(c)	((c) >= 'a' && (c) <= 'z')
14377cb4d3eSLandon J. Fuller #define	bhnd_nv_isalpha(c)	(bhnd_nv_isupper(c) || bhnd_nv_islower(c))
14477cb4d3eSLandon J. Fuller #define	bhnd_nv_isprint(c)	((c) >= ' ' && (c) <= '~')
14577cb4d3eSLandon J. Fuller #define	bhnd_nv_isspace(c)	((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
14677cb4d3eSLandon J. Fuller #define	bhnd_nv_isdigit(c)	isdigit(c)
14777cb4d3eSLandon J. Fuller #define	bhnd_nv_isxdigit(c)	isxdigit(c)
14877cb4d3eSLandon J. Fuller #define	bhnd_nv_toupper(c)	((c) -	\
14977cb4d3eSLandon J. Fuller     (('a' - 'A') * ((c) >= 'a' && (c) <= 'z')))
15077cb4d3eSLandon J. Fuller 
15177cb4d3eSLandon J. Fuller #define	bhnd_nv_malloc(size)		malloc((size))
15277cb4d3eSLandon J. Fuller #define	bhnd_nv_calloc(n, size)		calloc((n), (size))
15377cb4d3eSLandon J. Fuller #define	bhnd_nv_reallocf(buf, size)	reallocf((buf), (size))
15477cb4d3eSLandon J. Fuller #define	bhnd_nv_free(buf)		free((buf))
155eb686149SLandon J. Fuller #define	bhnd_nv_strdup(str)		strdup(str)
15677cb4d3eSLandon J. Fuller #define	bhnd_nv_strndup(str, len)	strndup(str, len)
15719be09f3SLandon J. Fuller #define	bhnd_nv_asprintf(buf, fmt, ...)	asprintf((buf), fmt, ## __VA_ARGS__)
15877cb4d3eSLandon J. Fuller 
15977cb4d3eSLandon J. Fuller #ifndef NDEBUG
16077cb4d3eSLandon J. Fuller #define	BHND_NV_INVARIANTS
16177cb4d3eSLandon J. Fuller #endif
16277cb4d3eSLandon J. Fuller 
16319be09f3SLandon J. Fuller #ifdef BHND_NV_INVARIANTS
16419be09f3SLandon J. Fuller 
16519be09f3SLandon J. Fuller #define	BHND_NV_ASSERT(expr, msg)	do {				\
16619be09f3SLandon J. Fuller 	if (!(expr)) {							\
16719be09f3SLandon J. Fuller 		fprintf(stderr, "Assertion failed: %s, function %s, "	\
16819be09f3SLandon J. Fuller 		    "file %s, line %u\n", __STRING(expr), __FUNCTION__,	\
16919be09f3SLandon J. Fuller 		    __FILE__, __LINE__);				\
17019be09f3SLandon J. Fuller 		BHND_NV_PANIC msg;					\
17119be09f3SLandon J. Fuller 	}								\
17219be09f3SLandon J. Fuller } while(0)
17319be09f3SLandon J. Fuller 
17419be09f3SLandon J. Fuller #else /* !BHND_NV_INVARIANTS */
17519be09f3SLandon J. Fuller 
17619be09f3SLandon J. Fuller #define	BHND_NV_ASSERT(expr, msg)
17719be09f3SLandon J. Fuller 
17819be09f3SLandon J. Fuller #endif /* BHND_NV_INVARIANTS */
17977cb4d3eSLandon J. Fuller 
18077cb4d3eSLandon J. Fuller #define	BHND_NV_VERBOSE			(0)
18177cb4d3eSLandon J. Fuller #define	BHND_NV_PANIC(fmt, ...)		do {			\
18277cb4d3eSLandon J. Fuller 	fprintf(stderr, "panic: " fmt "\n", ##__VA_ARGS__);	\
18377cb4d3eSLandon J. Fuller 	abort();						\
18477cb4d3eSLandon J. Fuller } while(0)
18577cb4d3eSLandon J. Fuller #define	BHND_NV_LOG(fmt, ...)					\
18677cb4d3eSLandon J. Fuller 	fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
18777cb4d3eSLandon J. Fuller 
18877cb4d3eSLandon J. Fuller static inline uintmax_t
bhnd_nv_ummax(uintmax_t a,uintmax_t b)18977cb4d3eSLandon J. Fuller bhnd_nv_ummax(uintmax_t a, uintmax_t b)
19077cb4d3eSLandon J. Fuller {
19177cb4d3eSLandon J. Fuller         return (a > b ? a : b);
19277cb4d3eSLandon J. Fuller }
19377cb4d3eSLandon J. Fuller 
19477cb4d3eSLandon J. Fuller static inline uintmax_t
bhnd_nv_ummin(uintmax_t a,uintmax_t b)19577cb4d3eSLandon J. Fuller bhnd_nv_ummin(uintmax_t a, uintmax_t b)
19677cb4d3eSLandon J. Fuller {
19777cb4d3eSLandon J. Fuller 
19877cb4d3eSLandon J. Fuller         return (a < b ? a : b);
19977cb4d3eSLandon J. Fuller }
20077cb4d3eSLandon J. Fuller 
20177cb4d3eSLandon J. Fuller #endif /* _KERNEL */
20277cb4d3eSLandon J. Fuller 
20377cb4d3eSLandon J. Fuller #ifdef BHND_NV_VERBOSE
20477cb4d3eSLandon J. Fuller #define	BHND_NV_DEBUG(...)	BHND_NV_LOG(__VA_ARGS__)
20577cb4d3eSLandon J. Fuller #else /* !BHND_NV_VERBOSE */
20677cb4d3eSLandon J. Fuller #define	BHND_NV_DEBUG(...)
20777cb4d3eSLandon J. Fuller #endif /* BHND_NV_VERBOSE */
20877cb4d3eSLandon J. Fuller 
20977cb4d3eSLandon J. Fuller /* Limit a size_t value to a suitable range for use as a printf string field
21077cb4d3eSLandon J. Fuller  * width */
21177cb4d3eSLandon J. Fuller #define	BHND_NV_PRINT_WIDTH(_len)	\
21277cb4d3eSLandon J. Fuller 	((_len) > (INT_MAX) ? (INT_MAX) : (int)(_len))
21377cb4d3eSLandon J. Fuller 
21477cb4d3eSLandon J. Fuller int				 bhnd_nvram_value_coerce(const void *inp,
21577cb4d3eSLandon J. Fuller 				     size_t ilen, bhnd_nvram_type itype,
21677cb4d3eSLandon J. Fuller 				     void *outp, size_t *olen,
21777cb4d3eSLandon J. Fuller 				     bhnd_nvram_type otype);
21877cb4d3eSLandon J. Fuller 
2199be0790dSLandon J. Fuller int				 bhnd_nvram_value_check_aligned(const void *inp,
2209be0790dSLandon J. Fuller 				     size_t ilen, bhnd_nvram_type itype);
2219be0790dSLandon J. Fuller 
2229be0790dSLandon J. Fuller int				 bhnd_nvram_value_nelem(const void *inp,
2239be0790dSLandon J. Fuller 				     size_t ilen, bhnd_nvram_type itype,
22477cb4d3eSLandon J. Fuller 				     size_t *nelem);
2259be0790dSLandon J. Fuller 
2269be0790dSLandon J. Fuller size_t				 bhnd_nvram_value_size(const void *inp,
2279be0790dSLandon J. Fuller 				     size_t ilen, bhnd_nvram_type itype,
22877cb4d3eSLandon J. Fuller 				     size_t nelem);
22977cb4d3eSLandon J. Fuller 
23077cb4d3eSLandon J. Fuller int				 bhnd_nvram_value_printf(const char *fmt,
23177cb4d3eSLandon J. Fuller 				     const void *inp, size_t ilen,
23277cb4d3eSLandon J. Fuller 				     bhnd_nvram_type itype, char *outp,
23377cb4d3eSLandon J. Fuller 				     size_t *olen, ...);
23477cb4d3eSLandon J. Fuller int				 bhnd_nvram_value_vprintf(const char *fmt,
23577cb4d3eSLandon J. Fuller 				     const void *inp, size_t ilen,
23677cb4d3eSLandon J. Fuller 				     bhnd_nvram_type itype, char *outp,
23777cb4d3eSLandon J. Fuller 				     size_t *olen, va_list ap);
23877cb4d3eSLandon J. Fuller 
2399be0790dSLandon J. Fuller const void			*bhnd_nvram_value_array_next(const void *inp,
2409be0790dSLandon J. Fuller 				     size_t ilen, bhnd_nvram_type itype,
2419be0790dSLandon J. Fuller 				     const void *prev, size_t *olen);
2429be0790dSLandon J. Fuller 
24377cb4d3eSLandon J. Fuller const struct bhnd_nvram_vardefn	*bhnd_nvram_find_vardefn(const char *varname);
24477cb4d3eSLandon J. Fuller const struct bhnd_nvram_vardefn	*bhnd_nvram_get_vardefn(size_t id);
24577cb4d3eSLandon J. Fuller size_t				 bhnd_nvram_get_vardefn_id(
24677cb4d3eSLandon J. Fuller 				     const struct bhnd_nvram_vardefn *defn);
24777cb4d3eSLandon J. Fuller 
24877cb4d3eSLandon J. Fuller int				 bhnd_nvram_parse_int(const char *s,
24977cb4d3eSLandon J. Fuller 				     size_t maxlen,  u_int base, size_t *nbytes,
25077cb4d3eSLandon J. Fuller 				     void *outp, size_t *olen,
25177cb4d3eSLandon J. Fuller 				     bhnd_nvram_type otype);
25277cb4d3eSLandon J. Fuller 
25377cb4d3eSLandon J. Fuller int				 bhnd_nvram_parse_env(const char *env,
25477cb4d3eSLandon J. Fuller 				     size_t env_len, char delim,
25577cb4d3eSLandon J. Fuller 				     const char **name, size_t *name_len,
25677cb4d3eSLandon J. Fuller 				     const char **value, size_t *value_len);
25777cb4d3eSLandon J. Fuller 
25877cb4d3eSLandon J. Fuller size_t				 bhnd_nvram_parse_field(const char **inp,
25977cb4d3eSLandon J. Fuller 				     size_t ilen, char delim);
26077cb4d3eSLandon J. Fuller size_t				 bhnd_nvram_trim_field(const char **inp,
26177cb4d3eSLandon J. Fuller 				     size_t ilen, char delim);
26277cb4d3eSLandon J. Fuller 
26319be09f3SLandon J. Fuller const char			*bhnd_nvram_trim_path_name(const char *name);
26419be09f3SLandon J. Fuller 
26519be09f3SLandon J. Fuller bool				 bhnd_nvram_validate_name(const char *name);
26677cb4d3eSLandon J. Fuller 
26777cb4d3eSLandon J. Fuller /**
26877cb4d3eSLandon J. Fuller  * Calculate CRC-8 over @p buf using the Broadcom SPROM/NVRAM CRC-8
26977cb4d3eSLandon J. Fuller  * polynomial.
27077cb4d3eSLandon J. Fuller  *
27177cb4d3eSLandon J. Fuller  * @param buf input buffer
27277cb4d3eSLandon J. Fuller  * @param size buffer size
27377cb4d3eSLandon J. Fuller  * @param crc last computed crc, or BHND_NVRAM_CRC8_INITIAL
27477cb4d3eSLandon J. Fuller  */
27577cb4d3eSLandon J. Fuller static inline uint8_t
bhnd_nvram_crc8(const void * buf,size_t size,uint8_t crc)27677cb4d3eSLandon J. Fuller bhnd_nvram_crc8(const void *buf, size_t size, uint8_t crc)
27777cb4d3eSLandon J. Fuller {
27877cb4d3eSLandon J. Fuller 	const uint8_t *p = (const uint8_t *)buf;
27977cb4d3eSLandon J. Fuller 	while (size--)
28077cb4d3eSLandon J. Fuller 		crc = bhnd_nvram_crc8_tab[(crc ^ *p++)];
28177cb4d3eSLandon J. Fuller 
28277cb4d3eSLandon J. Fuller 	return (crc);
28377cb4d3eSLandon J. Fuller }
28477cb4d3eSLandon J. Fuller 
28577cb4d3eSLandon J. Fuller #define	BHND_NVRAM_CRC8_INITIAL	0xFF	/**< Initial bhnd_nvram_crc8 value */
28677cb4d3eSLandon J. Fuller #define	BHND_NVRAM_CRC8_VALID	0x9F	/**< Valid CRC-8 checksum */
28777cb4d3eSLandon J. Fuller 
28877cb4d3eSLandon J. Fuller /** NVRAM variable flags */
28977cb4d3eSLandon J. Fuller enum {
29077cb4d3eSLandon J. Fuller 	BHND_NVRAM_VF_MFGINT	= 1<<0,	/**< mfg-internal variable; should not
29177cb4d3eSLandon J. Fuller 					     be externally visible */
29277cb4d3eSLandon J. Fuller 	BHND_NVRAM_VF_IGNALL1	= 1<<1	/**< hide variable if its value has all
29377cb4d3eSLandon J. Fuller 					     bits set. */
29477cb4d3eSLandon J. Fuller };
29577cb4d3eSLandon J. Fuller 
29677cb4d3eSLandon J. Fuller /**
29777cb4d3eSLandon J. Fuller  * SPROM layout flags
29877cb4d3eSLandon J. Fuller  */
29977cb4d3eSLandon J. Fuller enum {
30077cb4d3eSLandon J. Fuller 	/**
30177cb4d3eSLandon J. Fuller 	 * SPROM layout does not have magic identification value.
30277cb4d3eSLandon J. Fuller 	 *
30377cb4d3eSLandon J. Fuller 	 * This applies to SPROM revisions 1-3, where the actual
30477cb4d3eSLandon J. Fuller 	 * layout must be determined by looking for a matching sromrev
30577cb4d3eSLandon J. Fuller 	 * at the expected offset, and then verifying the CRC to ensure
30677cb4d3eSLandon J. Fuller 	 * that the match was not a false positive.
30777cb4d3eSLandon J. Fuller 	 */
30877cb4d3eSLandon J. Fuller 	SPROM_LAYOUT_MAGIC_NONE	= (1<<0),
30977cb4d3eSLandon J. Fuller };
31077cb4d3eSLandon J. Fuller 
31177cb4d3eSLandon J. Fuller /** NVRAM variable definition */
31277cb4d3eSLandon J. Fuller struct bhnd_nvram_vardefn {
31377cb4d3eSLandon J. Fuller 	const char			*name;	/**< variable name */
31477cb4d3eSLandon J. Fuller 	const char			*desc;	/**< human readable description,
31577cb4d3eSLandon J. Fuller 						     or NULL */
31677cb4d3eSLandon J. Fuller 	const char			*help;	/**< human readable help text,
31777cb4d3eSLandon J. Fuller 						     or NULL */
31877cb4d3eSLandon J. Fuller 	bhnd_nvram_type			 type;	/**< variable type */
31977cb4d3eSLandon J. Fuller 	uint8_t				 nelem;	/**< element count, or 1 if not
32077cb4d3eSLandon J. Fuller 						     an array-typed variable */
321c283839dSLandon J. Fuller 	const bhnd_nvram_val_fmt	*fmt;	/**< value format */
32277cb4d3eSLandon J. Fuller 	uint32_t			 flags;	/**< flags (BHND_NVRAM_VF_*) */
32377cb4d3eSLandon J. Fuller };
32477cb4d3eSLandon J. Fuller 
32577cb4d3eSLandon J. Fuller /*
32677cb4d3eSLandon J. Fuller  * NVRAM variable definitions generated from nvram_map.
32777cb4d3eSLandon J. Fuller  */
32877cb4d3eSLandon J. Fuller extern const struct bhnd_nvram_vardefn bhnd_nvram_vardefns[];
32977cb4d3eSLandon J. Fuller extern const size_t bhnd_nvram_num_vardefns;
33077cb4d3eSLandon J. Fuller 
33177cb4d3eSLandon J. Fuller /**
33277cb4d3eSLandon J. Fuller  * SPROM layout descriptor.
33377cb4d3eSLandon J. Fuller  */
334c283839dSLandon J. Fuller typedef struct bhnd_sprom_layout {
33577cb4d3eSLandon J. Fuller 	size_t		 size;		/**< SPROM image size, in bytes */
33677cb4d3eSLandon J. Fuller 	uint8_t		 rev;		/**< SPROM revision */
33777cb4d3eSLandon J. Fuller 	uint8_t		 flags;		/**< layout flags (SPROM_LAYOUT_*) */
33877cb4d3eSLandon J. Fuller 	size_t		 srev_offset;	/**< offset to SROM revision */
33977cb4d3eSLandon J. Fuller 	size_t		 magic_offset;	/**< offset to magic value */
34077cb4d3eSLandon J. Fuller 	uint16_t	 magic_value;	/**< expected magic value */
341c283839dSLandon J. Fuller 	size_t		 crc_offset;	/**< offset to crc8 value */
34277cb4d3eSLandon J. Fuller 	const uint8_t	*bindings;	/**< SPROM binding opcode table */
34377cb4d3eSLandon J. Fuller 	size_t		 bindings_size;	/**< SPROM binding opcode table size */
34477cb4d3eSLandon J. Fuller 	uint16_t	 num_vars;	/**< total number of variables defined
34577cb4d3eSLandon J. Fuller 					     for this layout by the binding
34677cb4d3eSLandon J. Fuller 					     table */
347c283839dSLandon J. Fuller } bhnd_sprom_layout;
34877cb4d3eSLandon J. Fuller 
34977cb4d3eSLandon J. Fuller /*
35077cb4d3eSLandon J. Fuller  * SPROM layout descriptions generated from nvram_map.
35177cb4d3eSLandon J. Fuller  */
35277cb4d3eSLandon J. Fuller extern const struct bhnd_sprom_layout bhnd_sprom_layouts[];
35377cb4d3eSLandon J. Fuller extern const size_t bhnd_sprom_num_layouts;
35477cb4d3eSLandon J. Fuller 
35577cb4d3eSLandon J. Fuller /*
35677cb4d3eSLandon J. Fuller  * SPROM binding opcodes.
35777cb4d3eSLandon J. Fuller  *
35877cb4d3eSLandon J. Fuller  * Most opcodes are provided with two variants:
35977cb4d3eSLandon J. Fuller  *
36077cb4d3eSLandon J. Fuller  * - Standard:	The opcode's data directly follows the opcode. The data type
36177cb4d3eSLandon J. Fuller  * 		(SPROM_OPCODE_DATA_*) is encoded in the opcode immediate (IMM).
36277cb4d3eSLandon J. Fuller  * - Immediate:	The opcode's data is encoded directly in the opcode immediate
36377cb4d3eSLandon J. Fuller  *		(IMM).
36477cb4d3eSLandon J. Fuller  */
36577cb4d3eSLandon J. Fuller #define	SPROM_OPC_MASK			0xF0	/**< operation mask */
36677cb4d3eSLandon J. Fuller #define	SPROM_IMM_MASK			0x0F	/**< immediate value mask */
36777cb4d3eSLandon J. Fuller #define	SPROM_IMM_MAX			SPROM_IMM_MASK
36877cb4d3eSLandon J. Fuller #define	  SPROM_OP_DATA_U8		  0x00	/**< data is u8 */
36977cb4d3eSLandon J. Fuller #define	  SPROM_OP_DATA_U8_SCALED	  0x01	/**< data is u8; multiply by
37077cb4d3eSLandon J. Fuller 						     type width */
37177cb4d3eSLandon J. Fuller #define	  SPROM_OP_DATA_U16		  0x02	/**< data is u16-le */
37277cb4d3eSLandon J. Fuller #define	  SPROM_OP_DATA_U32		  0x03	/**< data is u32-le */
37377cb4d3eSLandon J. Fuller #define	  SPROM_OP_DATA_I8		  0x04	/**< data is i8 */
37477cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_EXT		0x00	/**< extended opcodes defined
37577cb4d3eSLandon J. Fuller 						     in IMM */
37677cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_EOF		0x00	/**< marks end of opcode
37777cb4d3eSLandon J. Fuller 						     stream */
37877cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_NELEM		0x01	/**< variable array element
37977cb4d3eSLandon J. Fuller 						     count follows as U8 */
38077cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_VAR_END		0x02	/**< marks end of variable
38177cb4d3eSLandon J. Fuller 						     definition */
38277cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_TYPE		0x03	/**< input type follows as U8
38377cb4d3eSLandon J. Fuller 						     (see BHND_NVRAM_TYPE_*) */
38477cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_VAR_IMM		0x10	/**< variable ID (imm) */
38577cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_VAR_REL_IMM	0x20	/**< relative variable ID
38677cb4d3eSLandon J. Fuller 						     (last ID + imm) */
38777cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_VAR		0x30	/**< variable ID */
38877cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_REV_IMM		0x40	/**< revision range (imm) */
38977cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_REV_RANGE		0x50	/**< revision range (8-bit range)*/
39077cb4d3eSLandon J. Fuller #define	  SPROM_OP_REV_RANGE_MAX	  0x0F	/**< maximum representable SROM
39177cb4d3eSLandon J. Fuller 						     revision */
39277cb4d3eSLandon J. Fuller #define	  SPROM_OP_REV_START_MASK	  0xF0
39377cb4d3eSLandon J. Fuller #define	  SPROM_OP_REV_START_SHIFT	  4
39477cb4d3eSLandon J. Fuller #define	  SPROM_OP_REV_END_MASK	 	  0x0F
39577cb4d3eSLandon J. Fuller #define	  SPROM_OP_REV_END_SHIFT	  0
39677cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_MASK_IMM		0x60	/**< value mask (imm) */
39777cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_MASK		0x70	/**< value mask */
39877cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_SHIFT_IMM		0x80	/**< value shift (unsigned
39977cb4d3eSLandon J. Fuller 						     imm, multipled by 2) */
40077cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_SHIFT		0x90	/**< value shift */
40177cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_OFFSET_REL_IMM	0xA0	/**< relative input offset
40277cb4d3eSLandon J. Fuller 						     (last offset +
40377cb4d3eSLandon J. Fuller 						      (imm * type width)) */
40477cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_OFFSET		0xB0	/**< input offset */
40577cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_TYPE_IMM		0xC0	/**< input type (imm,
40677cb4d3eSLandon J. Fuller 						     see BHND_NVRAM_TYPE_*) */
40777cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_DO_BIND		0xD0	/**< bind current value,
40877cb4d3eSLandon J. Fuller 						     advance input/output
40977cb4d3eSLandon J. Fuller 						     offsets as per IMM */
41077cb4d3eSLandon J. Fuller #define	  SPROM_OP_BIND_SKIP_IN_MASK	  0x03	/**< the number of input
41177cb4d3eSLandon J. Fuller 						     elements to advance after
41277cb4d3eSLandon J. Fuller 						     the bind */
41377cb4d3eSLandon J. Fuller #define	  SPROM_OP_BIND_SKIP_IN_SHIFT	  0
41477cb4d3eSLandon J. Fuller #define	  SPROM_OP_BIND_SKIP_IN_SIGN	 (1<<2)	/**< SKIP_IN sign bit */
41577cb4d3eSLandon J. Fuller #define	  SPROM_OP_BIND_SKIP_OUT_MASK	  0x08	/**< the number of output
41677cb4d3eSLandon J. Fuller 						     elements to advance after
41777cb4d3eSLandon J. Fuller 						     the bind */
41877cb4d3eSLandon J. Fuller #define	  SPROM_OP_BIND_SKIP_OUT_SHIFT	  3
41977cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_DO_BINDN_IMM	0xE0	/**< bind IMM times, advancing
42077cb4d3eSLandon J. Fuller 						     input/output offsets by one
42177cb4d3eSLandon J. Fuller 						     element each time */
42277cb4d3eSLandon J. Fuller #define	SPROM_OPCODE_DO_BINDN		0xF0	/**< bind N times, advancing
42377cb4d3eSLandon J. Fuller 						     input/output offsets as per
42477cb4d3eSLandon J. Fuller 						     SPROM_OP_BIND_SKIP_IN/SPROM_OP_BIND_SKIP_OUT
42577cb4d3eSLandon J. Fuller 						     IMM values. The U8 element
42677cb4d3eSLandon J. Fuller 						     count follows. */
42777cb4d3eSLandon J. Fuller 
42877cb4d3eSLandon J. Fuller /** Evaluates to true if opcode is an extended opcode */
42977cb4d3eSLandon J. Fuller #define SPROM_OPCODE_IS_EXT(_opcode)	\
43077cb4d3eSLandon J. Fuller     (((_opcode) & SPROM_OPC_MASK) == SPROM_OPCODE_EXT)
43177cb4d3eSLandon J. Fuller 
43277cb4d3eSLandon J. Fuller /** Return the opcode constant for a simple or extended opcode */
43377cb4d3eSLandon J. Fuller #define SPROM_OPCODE_OP(_opcode)	\
43477cb4d3eSLandon J. Fuller     (SPROM_OPCODE_IS_EXT(_opcode) ? (_opcode) : ((_opcode) & SPROM_OPC_MASK))
43577cb4d3eSLandon J. Fuller 
43677cb4d3eSLandon J. Fuller /** Return the opcode immediate for a simple opcode, or zero if this is
43777cb4d3eSLandon J. Fuller   * an extended opcode  */
43877cb4d3eSLandon J. Fuller #define SPROM_OPCODE_IMM(_opcode)	\
43977cb4d3eSLandon J. Fuller     (SPROM_OPCODE_IS_EXT(_opcode) ? 0 : ((_opcode) & SPROM_IMM_MASK))
44077cb4d3eSLandon J. Fuller 
44177cb4d3eSLandon J. Fuller /** Evaluates to true if the given opcode produces an implicit
44277cb4d3eSLandon J. Fuller  *  SPROM_OPCODE_VAR_END instruction for any open variable */
44377cb4d3eSLandon J. Fuller #define	SPROM_OP_IS_IMPLICIT_VAR_END(_opcode)		\
44477cb4d3eSLandon J. Fuller     (((_opcode) == SPROM_OPCODE_VAR_IMM)	||	\
44577cb4d3eSLandon J. Fuller      ((_opcode) == SPROM_OPCODE_VAR_REL_IMM)	||	\
44677cb4d3eSLandon J. Fuller      ((_opcode) == SPROM_OPCODE_VAR)		||	\
44777cb4d3eSLandon J. Fuller      ((_opcode) == SPROM_OPCODE_REV_IMM)	||	\
44877cb4d3eSLandon J. Fuller      ((_opcode) == SPROM_OPCODE_REV_RANGE))
44977cb4d3eSLandon J. Fuller 
45077cb4d3eSLandon J. Fuller /** Evaluates to true if the given opcode is either an explicit
45177cb4d3eSLandon J. Fuller   * SPROM_OPCODE_VAR_END instruction, or is an opcode that produces an
45277cb4d3eSLandon J. Fuller   * implicit terminatation of any open variable */
45377cb4d3eSLandon J. Fuller #define	SPROM_OP_IS_VAR_END(_opcode)		\
45477cb4d3eSLandon J. Fuller      (((_opcode) == SPROM_OPCODE_VAR_END) ||	\
45577cb4d3eSLandon J. Fuller      SPROM_OP_IS_IMPLICIT_VAR_END(_opcode))
45677cb4d3eSLandon J. Fuller 
45777cb4d3eSLandon J. Fuller /** maximum representable immediate value */
45877cb4d3eSLandon J. Fuller #define	SPROM_OP_IMM_MAX	SPROM_IMM_MASK
45977cb4d3eSLandon J. Fuller 
46077cb4d3eSLandon J. Fuller /** maximum representable SROM revision */
46177cb4d3eSLandon J. Fuller #define	SPROM_OP_REV_MAX	MAX(SPROM_OP_REV_RANGE_MAX, SPROM_IMM_MAX)
46277cb4d3eSLandon J. Fuller 
46377cb4d3eSLandon J. Fuller #endif /* _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_ */
464