diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-12-14 11:53:55 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2015-09-11 16:40:19 +0200 |
commit | 1cada1f8339d6b5f8506277f80e62aaef77ab774 (patch) | |
tree | 8477120e97832d659d2ffc471a8bfde73ad4c36e /utils/regtools/include | |
parent | c8d3638b9ebc24e4766714da1c9f961e350799c6 (diff) | |
download | rockbox-1cada1f8339d6b5f8506277f80e62aaef77ab774.tar.gz rockbox-1cada1f8339d6b5f8506277f80e62aaef77ab774.zip |
soc_desc: new version of the desc file format
Fix qeditor to use the old soc_desc_v1.
Port hwstub_shell to the new description format.
Change-Id: I9fefbff534bfaa5c3603bb3dd8307a2b76e88cfc
Diffstat (limited to 'utils/regtools/include')
-rw-r--r-- | utils/regtools/include/soc_desc.hpp | 384 | ||||
-rw-r--r-- | utils/regtools/include/soc_desc_v1.hpp | 230 |
2 files changed, 614 insertions, 0 deletions
diff --git a/utils/regtools/include/soc_desc.hpp b/utils/regtools/include/soc_desc.hpp new file mode 100644 index 0000000000..66f2e3b6e1 --- /dev/null +++ b/utils/regtools/include/soc_desc.hpp | |||
@@ -0,0 +1,384 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2014 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __SOC_DESC__ | ||
22 | #define __SOC_DESC__ | ||
23 | |||
24 | #include <stdint.h> | ||
25 | #include <vector> | ||
26 | #include <list> | ||
27 | #include <string> | ||
28 | #include <map> | ||
29 | |||
30 | namespace soc_desc | ||
31 | { | ||
32 | |||
33 | const size_t MAJOR_VERSION = 2; | ||
34 | const size_t MINOR_VERSION = 0; | ||
35 | const size_t REVISION_VERSION = 0; | ||
36 | |||
37 | /** Typedef for SoC types: word, address and flags */ | ||
38 | typedef uint32_t soc_addr_t; | ||
39 | typedef uint32_t soc_word_t; | ||
40 | typedef int soc_id_t; | ||
41 | |||
42 | /** Error class */ | ||
43 | class error_t | ||
44 | { | ||
45 | public: | ||
46 | enum level_t | ||
47 | { | ||
48 | INFO, | ||
49 | WARNING, | ||
50 | FATAL | ||
51 | }; | ||
52 | error_t(level_t lvl, const std::string& loc, const std::string& msg) | ||
53 | :m_level(lvl), m_loc(loc), m_msg(msg) {} | ||
54 | level_t level() const { return m_level; } | ||
55 | std::string location() const { return m_loc; } | ||
56 | std::string message() const { return m_msg; } | ||
57 | protected: | ||
58 | level_t m_level; | ||
59 | std::string m_loc, m_msg; | ||
60 | }; | ||
61 | |||
62 | /** Error context to log errors */ | ||
63 | class error_context_t | ||
64 | { | ||
65 | public: | ||
66 | void add(const error_t& err) { m_list.push_back(err); } | ||
67 | size_t count() const { return m_list.size(); } | ||
68 | error_t get(size_t i) const { return m_list[i]; } | ||
69 | protected: | ||
70 | std::vector< error_t > m_list; | ||
71 | }; | ||
72 | |||
73 | /** | ||
74 | * Bare representation of the format | ||
75 | */ | ||
76 | |||
77 | /** Enumerated value (aka named value), represents a special value for a field */ | ||
78 | struct enum_t | ||
79 | { | ||
80 | soc_id_t id; /** ID (must be unique among field enums) */ | ||
81 | std::string name; /** Name (must be unique among field enums) */ | ||
82 | std::string desc; /** Optional description of the meaning of this value */ | ||
83 | soc_word_t value; /** Value of the field */ | ||
84 | }; | ||
85 | |||
86 | /** Register field information */ | ||
87 | struct field_t | ||
88 | { | ||
89 | soc_id_t id; /** ID (must be unique among register fields) */ | ||
90 | std::string name; /** Name (must be unique among register fields) */ | ||
91 | std::string desc; /** Optional description of the field */ | ||
92 | size_t pos; /** Position of the least significant bit */ | ||
93 | size_t width; /** Width of the field in bits */ | ||
94 | std::vector< enum_t > enum_; /** List of special values */ | ||
95 | |||
96 | /** Returns the bit mask of the field within the register */ | ||
97 | soc_word_t bitmask() const | ||
98 | { | ||
99 | // WARNING beware of the case where width is 32 | ||
100 | if(width == 32) | ||
101 | return 0xffffffff; | ||
102 | else | ||
103 | return ((1 << width) - 1) << pos; | ||
104 | } | ||
105 | |||
106 | /** Extract field value from register value */ | ||
107 | soc_word_t extract(soc_word_t reg_val) const | ||
108 | { | ||
109 | return (reg_val & bitmask()) >> pos; | ||
110 | } | ||
111 | |||
112 | /** Replace the field value in a register value */ | ||
113 | soc_word_t replace(soc_word_t reg_val, soc_word_t field_val) const | ||
114 | { | ||
115 | return (reg_val & ~bitmask()) | ((field_val << pos) & bitmask()); | ||
116 | } | ||
117 | |||
118 | /** Return field value index, or -1 if none */ | ||
119 | int find_value(soc_word_t v) const | ||
120 | { | ||
121 | for(size_t i = 0; i < enum_.size(); i++) | ||
122 | if(enum_[i].value == v) | ||
123 | return i; | ||
124 | return -1; | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | /** Register information */ | ||
129 | struct register_t | ||
130 | { | ||
131 | size_t width; /** Size in bits */ | ||
132 | std::vector< field_t > field; /** List of fields */ | ||
133 | }; | ||
134 | |||
135 | /** Node address range information */ | ||
136 | struct range_t | ||
137 | { | ||
138 | enum type_t | ||
139 | { | ||
140 | STRIDE, /** Addresses are given by a base address and a stride */ | ||
141 | FORMULA /** Addresses are given by a formula */ | ||
142 | }; | ||
143 | |||
144 | type_t type; /** Range type */ | ||
145 | size_t first; /** First index in the range */ | ||
146 | size_t count; /** Number of indexes in the range */ | ||
147 | soc_word_t base; /** Base address (for STRIDE) */ | ||
148 | soc_word_t stride; /** Stride value (for STRIDE) */ | ||
149 | std::string formula; /** Formula (for FORMULA) */ | ||
150 | std::string variable; /** Formula variable name (for FORMULA) */ | ||
151 | }; | ||
152 | |||
153 | /** Node instance information */ | ||
154 | struct instance_t | ||
155 | { | ||
156 | enum type_t | ||
157 | { | ||
158 | SINGLE, /** There is a single instance at a specified address */ | ||
159 | RANGE /** There are multiple addresses forming a range */ | ||
160 | }; | ||
161 | |||
162 | soc_id_t id; /** ID (must be unique among node instances) */ | ||
163 | std::string name; /** Name (must be unique among node instances) */ | ||
164 | std::string title; /** Optional instance human name */ | ||
165 | std::string desc; /** Optional description of the instance */ | ||
166 | type_t type; /** Instance type */ | ||
167 | soc_word_t addr; /** Address (for SINGLE) */ | ||
168 | range_t range; /** Range (for RANGE) */ | ||
169 | }; | ||
170 | |||
171 | /** Node information */ | ||
172 | struct node_t | ||
173 | { | ||
174 | soc_id_t id; /** ID (must be unique among nodes) */ | ||
175 | std::string name; /** Name (must be unique for the among nodes) */ | ||
176 | std::string title; /** Optional node human name */ | ||
177 | std::string desc; /** Optional description of the node */ | ||
178 | std::vector< register_t> register_; /** Optional register */ | ||
179 | std::vector< instance_t> instance; /** List of instances */ | ||
180 | std::vector< node_t > node; /** List of sub-nodes */ | ||
181 | }; | ||
182 | |||
183 | /** System-on-chip information */ | ||
184 | struct soc_t | ||
185 | { | ||
186 | std::string name; /** Codename of the SoC */ | ||
187 | std::string title; /** Human name of the SoC */ | ||
188 | std::string desc; /** Optional description of the SoC */ | ||
189 | std::string isa; /** Instruction Set Assembly */ | ||
190 | std::string version; /** Description version */ | ||
191 | std::vector< std::string > author; /** List of authors of the description */ | ||
192 | std::vector< node_t > node; /** List of nodes */ | ||
193 | }; | ||
194 | |||
195 | /** Parse a SoC description from a XML file, put it into <soc>. */ | ||
196 | bool parse_xml(const std::string& filename, soc_t& soc, error_context_t& error_ctx); | ||
197 | /** Write a SoC description to a XML file, overwriting it. A file can contain | ||
198 | * multiple Soc descriptions */ | ||
199 | bool produce_xml(const std::string& filename, const soc_t& soc, error_context_t& error_ctx); | ||
200 | /** Formula parser: try to parse and evaluate a formula with some variables */ | ||
201 | bool evaluate_formula(const std::string& formula, | ||
202 | const std::map< std::string, soc_word_t>& var, soc_word_t& result, | ||
203 | const std::string& loc, error_context_t& error_ctx); | ||
204 | |||
205 | /** | ||
206 | * Convenience API to manipulate the format | ||
207 | * | ||
208 | * The idea is that *_ref_t objects are stable pointers: they stay valid even | ||
209 | * when the underlying soc changes. In particular: | ||
210 | * - modifying any structure data (except id fields) preserves all references | ||
211 | * - removing a structure invalidates all references pointing to this structure | ||
212 | * and its children | ||
213 | * - adding any structure preserves all references | ||
214 | * These references can be used to get pointers to the actual data | ||
215 | * of the representation when it needs to be read or write. | ||
216 | */ | ||
217 | |||
218 | class soc_ref_t; | ||
219 | class node_ref_t; | ||
220 | class register_ref_t; | ||
221 | class field_ref_t; | ||
222 | class node_inst_t; | ||
223 | |||
224 | /** SoC reference */ | ||
225 | class soc_ref_t | ||
226 | { | ||
227 | soc_t *m_soc; /* pointer to the soc */ | ||
228 | public: | ||
229 | /** Builds an invalid reference */ | ||
230 | soc_ref_t(); | ||
231 | /** Builds a reference to a soc */ | ||
232 | soc_ref_t(soc_t *soc); | ||
233 | /** Checks whether this reference is valid */ | ||
234 | bool valid() const; | ||
235 | /** Returns a pointer to the soc */ | ||
236 | soc_t *get() const; | ||
237 | /** Returns a reference to the root node */ | ||
238 | node_ref_t root() const; | ||
239 | /** Returns a reference to the root node instance */ | ||
240 | node_inst_t root_inst() const; | ||
241 | /** Compare this reference to another */ | ||
242 | bool operator==(const soc_ref_t& r) const; | ||
243 | inline bool operator!=(const soc_ref_t& r) const { return !operator==(r); } | ||
244 | }; | ||
245 | |||
246 | /** SoC node reference | ||
247 | * NOTE: the root soc node is presented as a node with empty path */ | ||
248 | class node_ref_t | ||
249 | { | ||
250 | friend class soc_ref_t; | ||
251 | friend class node_inst_t; | ||
252 | soc_ref_t m_soc; /* reference to the soc */ | ||
253 | std::vector< soc_id_t > m_path; /* path from the root */ | ||
254 | |||
255 | node_ref_t(soc_ref_t soc); | ||
256 | node_ref_t(soc_ref_t soc, const std::vector< soc_id_t >& path); | ||
257 | public: | ||
258 | /** Builds an invalid reference */ | ||
259 | node_ref_t(); | ||
260 | /** Check whether this reference is valid */ | ||
261 | bool valid() const; | ||
262 | /** Check whether this reference is the root node */ | ||
263 | bool is_root() const; | ||
264 | /** Returns a pointer to the node, or 0 if invalid or root */ | ||
265 | node_t *get() const; | ||
266 | /** Returns a reference to the soc */ | ||
267 | soc_ref_t soc() const; | ||
268 | /** Returns a reference to the parent node */ | ||
269 | node_ref_t parent() const; | ||
270 | /** Returns a reference to the register (which may be on a parent node) */ | ||
271 | register_ref_t reg() const; | ||
272 | /** Returns a list of references to the sub-nodes */ | ||
273 | std::vector< node_ref_t > children() const; | ||
274 | /** Returns a reference to a specific child */ | ||
275 | node_ref_t child(const std::string& name) const; | ||
276 | /** Returns the path of the node, as the list of node names from the root */ | ||
277 | std::vector< std::string > path() const; | ||
278 | /** Returns the name of the node */ | ||
279 | std::string name() const; | ||
280 | /** Compare this reference to another */ | ||
281 | bool operator==(const node_ref_t& r) const; | ||
282 | inline bool operator!=(const node_ref_t& r) const { return !operator==(r); } | ||
283 | }; | ||
284 | |||
285 | /** SoC register reference */ | ||
286 | class register_ref_t | ||
287 | { | ||
288 | friend class node_ref_t; | ||
289 | node_ref_t m_node; /* reference to the node owning the register */ | ||
290 | |||
291 | register_ref_t(node_ref_t node); | ||
292 | public: | ||
293 | /** Builds an invalid reference */ | ||
294 | register_ref_t(); | ||
295 | /** Check whether this reference is valid/exists */ | ||
296 | bool valid() const; | ||
297 | /** Returns a pointer to the register, or 0 */ | ||
298 | register_t *get() const; | ||
299 | /** Returns a reference to the node containing the register */ | ||
300 | node_ref_t node() const; | ||
301 | /** Returns a list of references to the fields of the register */ | ||
302 | std::vector< field_ref_t > fields() const; | ||
303 | /** Returns a reference to a particular field */ | ||
304 | field_ref_t field(const std::string& name) const; | ||
305 | /** Compare this reference to another */ | ||
306 | bool operator==(const register_ref_t& r) const; | ||
307 | inline bool operator!=(const register_ref_t& r) const { return !operator==(r); } | ||
308 | }; | ||
309 | |||
310 | /** SoC register field reference */ | ||
311 | class field_ref_t | ||
312 | { | ||
313 | friend class register_ref_t; | ||
314 | register_ref_t m_reg; /* reference to the register */ | ||
315 | soc_id_t m_id; /* field name */ | ||
316 | |||
317 | field_ref_t(register_ref_t reg, soc_id_t id); | ||
318 | public: | ||
319 | /** Builds an invalid reference */ | ||
320 | field_ref_t(); | ||
321 | /** Check whether this reference is valid/exists */ | ||
322 | bool valid() const; | ||
323 | /** Returns a pointer to the field, or 0 */ | ||
324 | field_t *get() const; | ||
325 | /** Returns a reference to the register containing the field */ | ||
326 | register_ref_t reg() const; | ||
327 | /** Compare this reference to another */ | ||
328 | bool operator==(const field_ref_t& r) const; | ||
329 | inline bool operator!=(const field_ref_t& r) const { return !operator==(r); } | ||
330 | }; | ||
331 | |||
332 | /** SoC node instance | ||
333 | * NOTE: the root soc node is presented as a node with a single instance at 0 */ | ||
334 | class node_inst_t | ||
335 | { | ||
336 | friend class node_ref_t; | ||
337 | friend class soc_ref_t; | ||
338 | node_ref_t m_node; /* reference to the node */ | ||
339 | std::vector< soc_id_t > m_id_path; /* list of instance IDs */ | ||
340 | std::vector< size_t > m_index_path; /* list of instance indexes */ | ||
341 | |||
342 | node_inst_t(soc_ref_t soc); | ||
343 | node_inst_t(node_ref_t soc, const std::vector< soc_id_t >& path, | ||
344 | const std::vector< size_t >& indexes); | ||
345 | public: | ||
346 | /** Builds an invalid reference */ | ||
347 | node_inst_t(); | ||
348 | /** Check whether this instance is valid/exists */ | ||
349 | bool valid() const; | ||
350 | /** Returns a reference to the soc */ | ||
351 | soc_ref_t soc() const; | ||
352 | /** Returns a reference to the node */ | ||
353 | node_ref_t node() const; | ||
354 | /** Check whether this reference is the root node instance */ | ||
355 | bool is_root() const; | ||
356 | /** Returns a reference to the parent instance */ | ||
357 | node_inst_t parent() const; | ||
358 | /** Returns a pointer to the instance of the node, or 0 */ | ||
359 | instance_t *get() const; | ||
360 | /** Returns the address of this instance */ | ||
361 | soc_addr_t addr() const; | ||
362 | /** Returns an instance to a child of this node's instance. If the subnode | ||
363 | * instance is a range, the returned reference is invalid */ | ||
364 | node_inst_t child(const std::string& name) const; | ||
365 | /** Returns an instance to a child of this node's instance with a range index. | ||
366 | * If the subnode is not not a range or if the index is out of bounds, | ||
367 | * the returned reference is invalid */ | ||
368 | node_inst_t child(const std::string& name, size_t index) const; | ||
369 | /** Returns a list of all instances of subnodes of this node's instance */ | ||
370 | std::vector< node_inst_t > children() const; | ||
371 | /** Returns the name of the instance */ | ||
372 | std::string name() const; | ||
373 | /** Checks whether this instance is indexed */ | ||
374 | bool is_indexed() const; | ||
375 | /** Returns the index of the instance */ | ||
376 | size_t index() const; | ||
377 | /** Compare this reference to another */ | ||
378 | bool operator==(const node_inst_t& r) const; | ||
379 | inline bool operator!=(const node_inst_t& r) const { return !operator==(r); } | ||
380 | }; | ||
381 | |||
382 | } // soc_desc | ||
383 | |||
384 | #endif /* __SOC_DESC__ */ | ||
diff --git a/utils/regtools/include/soc_desc_v1.hpp b/utils/regtools/include/soc_desc_v1.hpp new file mode 100644 index 0000000000..33368e88d4 --- /dev/null +++ b/utils/regtools/include/soc_desc_v1.hpp | |||
@@ -0,0 +1,230 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2012 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __SOC_DESC_V1__ | ||
22 | #define __SOC_DESC_V1__ | ||
23 | |||
24 | #include <stdint.h> | ||
25 | #include <vector> | ||
26 | #include <list> | ||
27 | #include <string> | ||
28 | #include <map> | ||
29 | |||
30 | /** | ||
31 | * These data structures represent the SoC register in a convenient way. | ||
32 | * The basic structure is the following: | ||
33 | * - each SoC has several devices | ||
34 | * - each device has a generic name, a list of {name,address} and several registers | ||
35 | * - each register has a generic name, a list of {name,address}, flags, | ||
36 | * several fields | ||
37 | * - each field has a name, a first and last bit position, can apply either | ||
38 | * to all addresses of a register or be specific to one only and has several values | ||
39 | * - each field value has a name and a value | ||
40 | * | ||
41 | * All addresses, values and names are relative to the parents. For example a field | ||
42 | * value BV_LCDIF_CTRL_WORD_LENGTH_18_BIT is represented has: | ||
43 | * - device LCDIF, register CTRL, field WORD_LENGTH, value 16_BIT | ||
44 | * The address of CTRL is related to the address of LCDIF, the value of 16_BIT | ||
45 | * ignores the position of the WORD_LENGTH field in the register. | ||
46 | */ | ||
47 | |||
48 | namespace soc_desc_v1 | ||
49 | { | ||
50 | |||
51 | const size_t MAJOR_VERSION = 1; | ||
52 | const size_t MINOR_VERSION = 4; | ||
53 | const size_t REVISION_VERSION = 1; | ||
54 | |||
55 | /** | ||
56 | * Typedef for SoC types: word, address and flags */ | ||
57 | typedef uint32_t soc_addr_t; | ||
58 | typedef uint32_t soc_word_t; | ||
59 | typedef uint32_t soc_reg_flags_t; | ||
60 | |||
61 | /** SoC error gravity level */ | ||
62 | enum soc_error_level_t | ||
63 | { | ||
64 | SOC_ERROR_WARNING, | ||
65 | SOC_ERROR_FATAL, | ||
66 | }; | ||
67 | |||
68 | /** SoC description error */ | ||
69 | struct soc_error_t | ||
70 | { | ||
71 | soc_error_level_t level; /// level (warning, fatal, ...) | ||
72 | std::string location; /// human description of the location | ||
73 | std::string message; /// message | ||
74 | }; | ||
75 | |||
76 | /** SoC register generic formula */ | ||
77 | enum soc_reg_formula_type_t | ||
78 | { | ||
79 | REG_FORMULA_NONE, /// register has no generic formula | ||
80 | REG_FORMULA_STRING, /// register has a generic formula represented by a string | ||
81 | }; | ||
82 | |||
83 | /** <soc_reg_t>.<flags> values */ | ||
84 | const soc_reg_flags_t REG_HAS_SCT = 1 << 0; /// register SCT variants | ||
85 | |||
86 | /** SoC register field named value */ | ||
87 | struct soc_reg_field_value_t | ||
88 | { | ||
89 | std::string name; /// name of the value | ||
90 | soc_word_t value; /// numeric value | ||
91 | std::string desc; /// human description | ||
92 | |||
93 | std::vector< soc_error_t > errors(bool recursive); | ||
94 | }; | ||
95 | |||
96 | /** SoC register field */ | ||
97 | struct soc_reg_field_t | ||
98 | { | ||
99 | std::string name; /// name of the field | ||
100 | std::string desc; /// human description | ||
101 | unsigned first_bit, last_bit; /// bit range of the field | ||
102 | |||
103 | soc_reg_field_t():first_bit(0), last_bit(31) {} | ||
104 | |||
105 | /** Return field bitmask in register */ | ||
106 | soc_word_t bitmask() const | ||
107 | { | ||
108 | // WARNING beware of the case where first_bit=0 and last_bit=31 | ||
109 | if(first_bit == 0 && last_bit == 31) | ||
110 | return 0xffffffff; | ||
111 | else | ||
112 | return ((1 << (last_bit - first_bit + 1)) - 1) << first_bit; | ||
113 | } | ||
114 | |||
115 | /** Extract field value from register value */ | ||
116 | soc_word_t extract(soc_word_t reg_val) const | ||
117 | { | ||
118 | return (reg_val & bitmask()) >> first_bit; | ||
119 | } | ||
120 | |||
121 | /** Replace the field value in a register value */ | ||
122 | soc_word_t replace(soc_word_t reg_val, soc_word_t field_val) const | ||
123 | { | ||
124 | return (reg_val & ~bitmask()) | ((field_val << first_bit) & bitmask()); | ||
125 | } | ||
126 | |||
127 | bool is_reserved() const | ||
128 | { | ||
129 | return name.substr(0, 4) == "RSVD" || name.substr(0, 5) == "RSRVD"; | ||
130 | } | ||
131 | |||
132 | /** Return field value index, or -1 if none */ | ||
133 | int find_value(soc_word_t v) const | ||
134 | { | ||
135 | for(size_t i = 0; i < value.size(); i++) | ||
136 | if(value[i].value == v) | ||
137 | return i; | ||
138 | return -1; | ||
139 | } | ||
140 | |||
141 | std::vector< soc_reg_field_value_t > value; | ||
142 | |||
143 | std::vector< soc_error_t > errors(bool recursive); | ||
144 | }; | ||
145 | |||
146 | /** SoC register address */ | ||
147 | struct soc_reg_addr_t | ||
148 | { | ||
149 | std::string name; /// actual register name | ||
150 | soc_addr_t addr; /// actual register address (relative to device) | ||
151 | |||
152 | std::vector< soc_error_t > errors(bool recursive); | ||
153 | }; | ||
154 | |||
155 | /** SoC register formula */ | ||
156 | struct soc_reg_formula_t | ||
157 | { | ||
158 | enum soc_reg_formula_type_t type; | ||
159 | std::string string; /// for STRING | ||
160 | |||
161 | std::vector< soc_error_t > errors(bool recursive); | ||
162 | }; | ||
163 | |||
164 | /** SoC register */ | ||
165 | struct soc_reg_t | ||
166 | { | ||
167 | std::string name; /// generic name (for multi registers) or actual name | ||
168 | std::string desc; /// human description | ||
169 | std::vector< soc_reg_addr_t > addr; /// instances of the registers | ||
170 | soc_reg_formula_t formula; /// formula for the instance addresses | ||
171 | soc_reg_flags_t flags; /// ORed value | ||
172 | |||
173 | std::vector< soc_reg_field_t > field; | ||
174 | |||
175 | std::vector< soc_error_t > errors(bool recursive); | ||
176 | }; | ||
177 | |||
178 | /** Soc device address */ | ||
179 | struct soc_dev_addr_t | ||
180 | { | ||
181 | std::string name; /// actual device name | ||
182 | soc_addr_t addr; | ||
183 | |||
184 | std::vector< soc_error_t > errors(bool recursive); | ||
185 | }; | ||
186 | |||
187 | /** SoC device */ | ||
188 | struct soc_dev_t | ||
189 | { | ||
190 | std::string name; /// generic name (of multi devices) or actual name | ||
191 | std::string long_name; /// human friendly name | ||
192 | std::string desc; /// human description | ||
193 | std::string version; /// description version | ||
194 | std::vector< soc_dev_addr_t > addr; | ||
195 | |||
196 | std::vector< soc_reg_t > reg; | ||
197 | |||
198 | std::vector< soc_error_t > errors(bool recursive); | ||
199 | }; | ||
200 | |||
201 | /** SoC */ | ||
202 | struct soc_t | ||
203 | { | ||
204 | std::string name; /// codename (rockbox) | ||
205 | std::string desc; /// SoC name | ||
206 | |||
207 | std::vector< soc_dev_t > dev; | ||
208 | |||
209 | std::vector< soc_error_t > errors(bool recursive); | ||
210 | }; | ||
211 | |||
212 | /** Parse a SoC description from a XML file, append it to <soc>. */ | ||
213 | bool parse_xml(const std::string& filename, soc_t& soc); | ||
214 | /** Write a SoC description to a XML file, overwriting it. A file can contain | ||
215 | * multiple Soc descriptions */ | ||
216 | bool produce_xml(const std::string& filename, const soc_t& soc); | ||
217 | /** Normalise a soc description by reordering elemnts so that: | ||
218 | * - devices are sorted by first name | ||
219 | * - registers are sorted by first address | ||
220 | * - fields are sorted by last bit | ||
221 | * - values are sorted by value */ | ||
222 | void normalize(soc_t& soc); | ||
223 | /** Formula parser: try to parse and evaluate a formula with some variables */ | ||
224 | bool evaluate_formula(const std::string& formula, | ||
225 | const std::map< std::string, soc_word_t>& var, soc_word_t& result, | ||
226 | std::string& error); | ||
227 | |||
228 | } // soc_desc_v1 | ||
229 | |||
230 | #endif /* __SOC_DESC_V1__ */ \ No newline at end of file | ||