xref: /freebsd/sys/dev/bhnd/nvram/bhnd_nvram_data_spromvar.h (revision 9ff086544d5f85b58349e28ed36a9811b8fe5cf9)
1 /*-
2  * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  *
29  * $FreeBSD$
30  */
31 
32 #ifndef _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_
33 #define _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_
34 
35 #ifdef _KERNEL
36 #include <sys/bitstring.h>
37 #else
38 #include <bitstring.h>
39 #endif
40 
41 #include "bhnd_nvram_private.h"
42 
43 #include "bhnd_nvram_datavar.h"
44 #include "bhnd_nvram_io.h"
45 
46 /** The maximum number of array elements encoded in a single SPROM variable */
47 #define	BHND_SPROM_ARRAY_MAXLEN	12
48 
49 typedef struct bhnd_sprom_opcode_state		bhnd_sprom_opcode_state;
50 typedef struct bhnd_sprom_opcode_bind		bhnd_sprom_opcode_bind;
51 typedef struct bhnd_sprom_opcode_var		bhnd_sprom_opcode_var;
52 typedef struct bhnd_sprom_opcode_idx_entry	bhnd_sprom_opcode_idx_entry;
53 
54 int				 bhnd_sprom_opcode_init(
55 				     bhnd_sprom_opcode_state *state,
56 				     const bhnd_sprom_layout *layout);
57 void				 bhnd_sprom_opcode_fini(
58 				     bhnd_sprom_opcode_state *state);
59 
60 bhnd_sprom_opcode_idx_entry	*bhnd_sprom_opcode_index_find(
61 				     bhnd_sprom_opcode_state *state,
62 				     const char *name);
63 bhnd_sprom_opcode_idx_entry	*bhnd_sprom_opcode_index_next(
64 				     bhnd_sprom_opcode_state *state,
65 				     bhnd_sprom_opcode_idx_entry *prev);
66 
67 int				 bhnd_sprom_opcode_parse_var(
68 				     bhnd_sprom_opcode_state *state,
69 				     bhnd_sprom_opcode_idx_entry *entry);
70 
71 int				 bhnd_sprom_opcode_seek(
72 				     bhnd_sprom_opcode_state *state,
73 				     bhnd_sprom_opcode_idx_entry *entry);
74 int				 bhnd_sprom_opcode_next_binding(
75 				     bhnd_sprom_opcode_state *state);
76 int				 bhnd_sprom_opcode_apply_scale(
77 				     bhnd_sprom_opcode_state *state,
78 				      uint32_t *value);
79 
80 /**
81  * SPROM opcode per-bind evaluation state.
82  */
83 struct bhnd_sprom_opcode_bind {
84 	uint8_t		count;
85 	uint32_t	skip_in;		/**< input element skips */
86 	bool		skip_in_negative;	/**< skip_in should be subtracted */
87 	uint32_t	skip_out;		/**< output element skip */
88 };
89 
90 /**
91  * SPROM opcode per-variable evaluation state.
92  */
93 struct bhnd_sprom_opcode_var {
94 	uint8_t			nelem;		/**< variable array length */
95 	uint32_t		mask;		/**< current bind input mask */
96 	int8_t			shift;		/**< current bind input shift */
97 	bhnd_nvram_type		base_type;	/**< current bind input type */
98 	uint32_t		scale;		/**< current scale to apply to scaled encodings */
99 	bhnd_sprom_opcode_bind	bind;		/**< current bind state */
100 	bool			have_bind;	/**< if bind state is defined */
101 	size_t			bind_total;	/**< total count of bind operations performed */
102 };
103 
104 /**
105  * SPROM opcode variable definition states.
106  *
107  * Ordered to support inequality comparisons
108  * (e.g. >= SPROM_OPCODE_VAR_STATE_OPEN)
109  */
110 typedef enum {
111 	SPROM_OPCODE_VAR_STATE_NONE	= 1,	/**< no variable entry available */
112 	SPROM_OPCODE_VAR_STATE_OPEN	= 2,	/**< currently parsing a variable entry */
113 	SPROM_OPCODE_VAR_STATE_DONE	= 3	/**< full variable entry has been parsed */
114 } bhnd_sprom_opcode_var_state;
115 
116 /**
117  * SPROM opcode evaluation state
118  */
119 struct bhnd_sprom_opcode_state {
120 	const bhnd_sprom_layout		*layout;	/**< SPROM layout */
121 
122 	bhnd_sprom_opcode_idx_entry	*idx;		/**< variable index (NULL during initialization) */
123 	size_t				 num_idx;	/**< variable index entry count */
124 
125 	/** Current SPROM revision range */
126 	bitstr_t			 bit_decl(revs, SPROM_OP_REV_MAX);
127 
128 	const uint8_t			*input;		/**< opcode input position */
129 
130 	/* State preserved across variable definitions */
131 	uint32_t			 offset;	/**< SPROM offset */
132 	size_t				 vid;		/**< Variable ID */
133 
134 	/* State reset after end of each variable definition */
135 	bhnd_sprom_opcode_var		 var;		/**< variable record (if any) */
136 	bhnd_sprom_opcode_var_state	 var_state;	/**< variable record state */
137 };
138 
139 /**
140  * SPROM opcode variable index entry
141  */
142 struct bhnd_sprom_opcode_idx_entry {
143 	uint16_t	vid;		/**< SPROM variable ID */
144 	uint16_t	offset;		/**< SPROM input offset */
145 	uint16_t	opcodes;	/**< SPROM opcode offset */
146 };
147 
148 /**
149  * SPROM value storage.
150  *
151  * Sufficient for representing the native encoding of any defined SPROM
152  * variable.
153  */
154 union bhnd_nvram_sprom_storage {
155 	uint8_t		u8[BHND_SPROM_ARRAY_MAXLEN];
156 	uint16_t	u16[BHND_SPROM_ARRAY_MAXLEN];
157 	uint32_t	u32[BHND_SPROM_ARRAY_MAXLEN];
158 	int8_t		i8[BHND_SPROM_ARRAY_MAXLEN];
159 	int16_t		i16[BHND_SPROM_ARRAY_MAXLEN];
160 	int32_t		i32[BHND_SPROM_ARRAY_MAXLEN];
161 	char		ch[BHND_SPROM_ARRAY_MAXLEN];
162 };
163 
164 /**
165  * SPROM data class instance state.
166  */
167 struct bhnd_nvram_sprom {
168 	struct bhnd_nvram_data	 nv;		/**< common instance state */
169 	struct bhnd_nvram_io	*data;		/**< backing SPROM image */
170 	const bhnd_sprom_layout	*layout;	/**< layout definition */
171 	bhnd_sprom_opcode_state	 state;		/**< opcode eval state */
172 };
173 
174 #endif /* _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ */
175