xref: /freebsd/sys/dev/bhnd/nvram/bhnd_nvram_data_spromvar.h (revision 2ff63af9b88c7413b7d71715b5532625752a248e)
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  */
30 
31 #ifndef _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_
32 #define _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_
33 
34 #ifdef _KERNEL
35 #include <sys/bitstring.h>
36 #else
37 #include <bitstring.h>
38 #endif
39 
40 #include "bhnd_nvram_private.h"
41 
42 #include "bhnd_nvram_datavar.h"
43 #include "bhnd_nvram_io.h"
44 
45 /** The maximum number of array elements encoded in a single SPROM variable */
46 #define	BHND_SPROM_ARRAY_MAXLEN	12
47 
48 typedef struct bhnd_sprom_opcode_state		bhnd_sprom_opcode_state;
49 typedef struct bhnd_sprom_opcode_bind		bhnd_sprom_opcode_bind;
50 typedef struct bhnd_sprom_opcode_var		bhnd_sprom_opcode_var;
51 typedef struct bhnd_sprom_opcode_idx_entry	bhnd_sprom_opcode_idx_entry;
52 
53 int				 bhnd_sprom_opcode_init(
54 				     bhnd_sprom_opcode_state *state,
55 				     const bhnd_sprom_layout *layout);
56 void				 bhnd_sprom_opcode_fini(
57 				     bhnd_sprom_opcode_state *state);
58 
59 bhnd_sprom_opcode_idx_entry	*bhnd_sprom_opcode_index_find(
60 				     bhnd_sprom_opcode_state *state,
61 				     const char *name);
62 bhnd_sprom_opcode_idx_entry	*bhnd_sprom_opcode_index_next(
63 				     bhnd_sprom_opcode_state *state,
64 				     bhnd_sprom_opcode_idx_entry *prev);
65 
66 int				 bhnd_sprom_opcode_init_entry(
67 				     bhnd_sprom_opcode_state *state,
68 				     bhnd_sprom_opcode_idx_entry *entry);
69 
70 int				 bhnd_sprom_opcode_eval_var(
71 				     bhnd_sprom_opcode_state *state,
72 				     bhnd_sprom_opcode_idx_entry *entry);
73 
74 int				 bhnd_sprom_opcode_seek(
75 				     bhnd_sprom_opcode_state *state,
76 				     bhnd_sprom_opcode_idx_entry *entry);
77 int				 bhnd_sprom_opcode_next_var(
78 				     bhnd_sprom_opcode_state *state);
79 int				 bhnd_sprom_opcode_next_binding(
80 				     bhnd_sprom_opcode_state *state);
81 int				 bhnd_sprom_opcode_apply_scale(
82 				     bhnd_sprom_opcode_state *state,
83 				      uint32_t *value);
84 
85 /**
86  * SPROM opcode per-bind evaluation state.
87  */
88 struct bhnd_sprom_opcode_bind {
89 	uint8_t		count;
90 	uint32_t	skip_in;		/**< input element skips */
91 	bool		skip_in_negative;	/**< skip_in should be subtracted */
92 	uint32_t	skip_out;		/**< output element skip */
93 };
94 
95 /**
96  * SPROM opcode per-variable evaluation state.
97  */
98 struct bhnd_sprom_opcode_var {
99 	uint8_t			nelem;		/**< variable array length */
100 	uint32_t		mask;		/**< current bind input mask */
101 	int8_t			shift;		/**< current bind input shift */
102 	bhnd_nvram_type		base_type;	/**< current bind input type */
103 	uint32_t		scale;		/**< current scale to apply to scaled encodings */
104 	bhnd_sprom_opcode_bind	bind;		/**< current bind state */
105 	bool			have_bind;	/**< if bind state is defined */
106 	size_t			bind_total;	/**< total count of bind operations performed */
107 };
108 
109 /**
110  * SPROM opcode variable definition states.
111  *
112  * Ordered to support inequality comparisons
113  * (e.g. >= SPROM_OPCODE_VAR_STATE_OPEN)
114  */
115 typedef enum {
116 	SPROM_OPCODE_VAR_STATE_NONE	= 1,	/**< no variable entry available */
117 	SPROM_OPCODE_VAR_STATE_OPEN	= 2,	/**< currently parsing a variable entry */
118 	SPROM_OPCODE_VAR_STATE_DONE	= 3	/**< full variable entry has been parsed */
119 } bhnd_sprom_opcode_var_state;
120 
121 /**
122  * SPROM opcode evaluation state
123  */
124 struct bhnd_sprom_opcode_state {
125 	const bhnd_sprom_layout		*layout;	/**< SPROM layout */
126 
127 	bhnd_sprom_opcode_idx_entry	*idx;		/**< variable index (NULL during initialization) */
128 	size_t				 num_idx;	/**< variable index entry count */
129 
130 	/** Current SPROM revision range */
131 	bitstr_t			 bit_decl(revs, SPROM_OP_REV_MAX);
132 
133 	const uint8_t			*input;		/**< opcode input position */
134 
135 	/* State preserved across variable definitions */
136 	uint32_t			 offset;	/**< SPROM offset */
137 	size_t				 vid;		/**< Variable ID */
138 
139 	/* State reset after end of each variable definition */
140 	bhnd_sprom_opcode_var		 var;		/**< variable record (if any) */
141 	bhnd_sprom_opcode_var_state	 var_state;	/**< variable record state */
142 };
143 
144 /**
145  * SPROM opcode variable index entry
146  */
147 struct bhnd_sprom_opcode_idx_entry {
148 	uint16_t	vid;		/**< SPROM variable ID */
149 	uint16_t	offset;		/**< SPROM input offset */
150 	uint16_t	opcodes;	/**< SPROM opcode offset */
151 };
152 
153 /**
154  * SPROM value storage.
155  *
156  * Sufficient for representing the native encoding of any defined SPROM
157  * variable.
158  */
159 union bhnd_nvram_sprom_storage {
160 	uint8_t		u8[BHND_SPROM_ARRAY_MAXLEN];
161 	uint16_t	u16[BHND_SPROM_ARRAY_MAXLEN];
162 	uint32_t	u32[BHND_SPROM_ARRAY_MAXLEN];
163 	int8_t		i8[BHND_SPROM_ARRAY_MAXLEN];
164 	int16_t		i16[BHND_SPROM_ARRAY_MAXLEN];
165 	int32_t		i32[BHND_SPROM_ARRAY_MAXLEN];
166 	char		ch[BHND_SPROM_ARRAY_MAXLEN];
167 };
168 
169 /**
170  * SPROM data class instance state.
171  */
172 struct bhnd_nvram_sprom {
173 	struct bhnd_nvram_data	 nv;		/**< common instance state */
174 	struct bhnd_nvram_io	*data;		/**< backing SPROM image */
175 	const bhnd_sprom_layout	*layout;	/**< layout definition */
176 	bhnd_sprom_opcode_state	 state;		/**< opcode eval state */
177 };
178 
179 #endif /* _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ */
180