diff options
Diffstat (limited to 'utils/regtools/include/soc_desc_v1.hpp')
-rw-r--r-- | utils/regtools/include/soc_desc_v1.hpp | 230 |
1 files changed, 230 insertions, 0 deletions
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 | ||