summaryrefslogtreecommitdiff
path: root/utils/regtools/tester.cpp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-04-07 11:28:04 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2014-05-01 19:34:18 +0200
commit4356666101e0e7985e65a19f86bc4a74519e93f9 (patch)
treebf8de8057d93d0fab0a30cae92a90f5a4edc79dc /utils/regtools/tester.cpp
parent3754624edc48539c5cc5acbf426ce909477e87d8 (diff)
downloadrockbox-4356666101e0e7985e65a19f86bc4a74519e93f9.tar.gz
rockbox-4356666101e0e7985e65a19f86bc4a74519e93f9.zip
regtools: completely rework qeditor, improve soc desc library and tools
The graphical editor can now display and editor description files. The library has been improved to provide more useful function. The XML format has been slightly changed: only one soc is allowed per file (this is was already de facto the case since <soc> was the root tag). Also introduce a DTD to validate the files. Change-Id: If70ba35b6dc0242bdb87411cf4baee9597798aac
Diffstat (limited to 'utils/regtools/tester.cpp')
-rw-r--r--utils/regtools/tester.cpp344
1 files changed, 305 insertions, 39 deletions
diff --git a/utils/regtools/tester.cpp b/utils/regtools/tester.cpp
index 1fa21c6894..1beba5fe9b 100644
--- a/utils/regtools/tester.cpp
+++ b/utils/regtools/tester.cpp
@@ -21,77 +21,343 @@
21#include "soc_desc.hpp" 21#include "soc_desc.hpp"
22#include <stdio.h> 22#include <stdio.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <map>
25#include <cstring>
24 26
25void print_value_desc(const soc_reg_field_value_t& value) 27template< typename T >
28bool build_map(const char *type, const std::vector< T >& vec,
29 std::map< std::string, size_t >& map)
26{ 30{
27 printf(" VALUE %s (%#x)\n", value.name.c_str(), value.value); 31 for(size_t i = 0; i < vec.size(); i++)
32 {
33 if(map.find(vec[i].name) != map.end())
34 {
35 printf("soc has duplicate %s '%s'\n", type, vec[i].name.c_str());
36 return false;
37 }
38 map[vec[i].name] = i;
39 }
40 return true;
28} 41}
29 42
30void print_field_desc(const soc_reg_field_t& field) 43template< typename T >
44bool build_map(const char *type, const std::vector< T >& a, const std::vector< T >& b,
45 std::vector< std::pair< size_t, size_t > >& m)
31{ 46{
32 printf(" FIELD %s (%d:%d)\n", field.name.c_str(), field.last_bit, 47 std::map< std::string, size_t > ma, mb;
33 field.first_bit); 48 if(!build_map(type, a, ma) || !build_map(type, b, mb))
34 for(size_t i = 0; i < field.value.size(); i++) 49 return false;
35 print_value_desc(field.value[i]); 50 std::map< std::string, size_t >::iterator it;
51 for(it = ma.begin(); it != ma.end(); ++it)
52 {
53 if(mb.find(it->first) == mb.end())
54 {
55 printf("%s '%s' exists in only one file\n", type, it->first.c_str());
56 return false;
57 }
58 m.push_back(std::make_pair(it->second, mb[it->first]));
59 }
60 for(it = mb.begin(); it != mb.end(); ++it)
61 {
62 if(ma.find(it->first) == ma.end())
63 {
64 printf("%s '%s' exists in only one file\n", type, it->first.c_str());
65 return false;
66 }
67 }
68 return true;
36} 69}
37 70
38std::string compute_sct(soc_reg_flags_t f) 71bool compare_value(const soc_t& soc, const soc_dev_t& dev, const soc_reg_t& reg,
72 const soc_reg_field_t& field, const soc_reg_field_value_t& a, const soc_reg_field_value_t& b)
39{ 73{
40 if(f & REG_HAS_SCT) return "SCT"; 74 if(a.value != b.value)
41 else return ""; 75 {
76 printf("register field value '%s.%s.%s.%s.%s' have different values\n", soc.name.c_str(),
77 dev.name.c_str(), reg.name.c_str(), field.name.c_str(), a.name.c_str());
78 return false;
79 }
80 if(a.desc != b.desc)
81 {
82 printf("register field value '%s.%s.%s.%s.%s' have different descriptions\n", soc.name.c_str(),
83 dev.name.c_str(), reg.name.c_str(), field.name.c_str(), a.name.c_str());
84 return false;
85 }
86 return true;
42} 87}
43 88
44void print_reg_addr_desc(const soc_reg_addr_t& reg) 89bool compare_field(const soc_t& soc, const soc_dev_t& dev, const soc_reg_t& reg,
90 const soc_reg_field_t& a, const soc_reg_field_t& b)
45{ 91{
46 printf(" ADDR %s %#x\n", reg.name.c_str(), reg.addr); 92 if(a.first_bit != b.first_bit || a.last_bit != b.last_bit)
93 {
94 printf("register address '%s.%s.%s.%s' have different bit ranges\n", soc.name.c_str(),
95 dev.name.c_str(), reg.name.c_str(), a.name.c_str());
96 return false;
97 }
98 if(a.desc != b.desc)
99 {
100 printf("register address '%s.%s.%s.%s' have different descriptions\n", soc.name.c_str(),
101 dev.name.c_str(), reg.name.c_str(), a.name.c_str());
102 return false;
103 }
104 /* values */
105 std::vector< std::pair< size_t, size_t > > map;
106 if(!build_map("field value", a.value, b.value, map))
107 return false;
108 for(size_t i = 0; i < map.size(); i++)
109 if(!compare_value(soc, dev, reg, a, a.value[map[i].first], b.value[map[i].second]))
110 return false;
111 return true;
47} 112}
48 113
49void print_reg_desc(const soc_reg_t& reg) 114bool compare_reg_addr(const soc_t& soc, const soc_dev_t& dev, const soc_reg_t& reg,
115 const soc_reg_addr_t& a, const soc_reg_addr_t& b)
50{ 116{
51 std::string sct = compute_sct(reg.flags); 117 if(a.addr != b.addr)
52 printf(" REG %s %s\n", reg.name.c_str(), sct.c_str()); 118 {
53 for(size_t i = 0; i < reg.addr.size(); i++) 119 printf("register address '%s.%s.%s.%s' have different values\n", soc.name.c_str(),
54 print_reg_addr_desc(reg.addr[i]); 120 dev.name.c_str(), reg.name.c_str(), a.name.c_str());
55 for(size_t i = 0; i < reg.field.size(); i++) 121 return false;
56 print_field_desc(reg.field[i]); 122 }
123 else
124 return true;
57} 125}
58 126
59void print_dev_addr_desc(const soc_dev_addr_t& dev) 127bool compare_reg(const soc_t& soc, const soc_dev_t& dev, const soc_reg_t& a,
128 const soc_reg_t& b)
60{ 129{
61 printf(" ADDR %s %#x\n", dev.name.c_str(), dev.addr); 130 if(a.desc != b.desc)
131 {
132 printf("register '%s.%s.%s' have different descriptions\n", soc.name.c_str(),
133 dev.name.c_str(), a.name.c_str());
134 return false;
135 }
136 if(a.flags != b.flags)
137 {
138 printf("device '%s.%s.%s' have different flags\n", soc.name.c_str(),
139 dev.name.c_str(), a.name.c_str());
140 return false;
141 }
142 if(a.formula.type != b.formula.type)
143 {
144 printf("device '%s.%s.%s' have different formula types\n", soc.name.c_str(),
145 dev.name.c_str(), a.name.c_str());
146 return false;
147 }
148 if(a.formula.string != b.formula.string)
149 {
150 printf("device '%s.%s.%s' have different formula string\n", soc.name.c_str(),
151 dev.name.c_str(), a.name.c_str());
152 return false;
153 }
154 /* addresses */
155 std::vector< std::pair< size_t, size_t > > map;
156 if(!build_map("register address", a.addr, b.addr, map))
157 return false;
158 for(size_t i = 0; i < map.size(); i++)
159 if(!compare_reg_addr(soc, dev, a, a.addr[map[i].first], b.addr[map[i].second]))
160 return false;
161 /* field */
162 map.clear();
163 if(!build_map("field", a.field, b.field, map))
164 return false;
165 for(size_t i = 0; i < map.size(); i++)
166 if(!compare_field(soc, dev, a, a.field[map[i].first], b.field[map[i].second]))
167 return false;
168 return true;
62} 169}
63 170
64void print_dev_desc(const soc_dev_t& dev) 171bool compare_dev_addr(const soc_t& soc, const soc_dev_t& dev, const soc_dev_addr_t& a,
172 const soc_dev_addr_t& b)
65{ 173{
66 printf(" DEV %s\n", dev.name.c_str()); 174 if(a.addr != b.addr)
67 for(size_t i = 0; i < dev.addr.size(); i++) 175 {
68 print_dev_addr_desc(dev.addr[i]); 176 printf("device address '%s.%s.%s' have different values\n", soc.name.c_str(),
69 for(size_t i = 0; i < dev.reg.size(); i++) 177 dev.name.c_str(), a.name.c_str());
70 print_reg_desc(dev.reg[i]); 178 return false;
179 }
180 else
181 return true;
71} 182}
72 183
73void print_soc_desc(const soc_t& soc) 184bool compare_dev(const soc_t& soc, const soc_dev_t& a, const soc_dev_t& b)
74{ 185{
75 printf("SOC %s (%s)\n", soc.name.c_str(), soc.desc.c_str()); 186 if(a.long_name != b.long_name)
76 for(size_t i = 0; i < soc.dev.size(); i++) 187 {
77 print_dev_desc(soc.dev[i]); 188 printf("device '%s.%s' have different long names\n", soc.name.c_str(),
189 a.name.c_str());
190 return false;
191 }
192 if(a.desc != b.desc)
193 {
194 printf("device '%s.%s' have different descriptions\n", soc.name.c_str(),
195 a.name.c_str());
196 return false;
197 }
198 if(a.version != b.version)
199 {
200 printf("device '%s.%s' have different versions\n", soc.name.c_str(),
201 a.name.c_str());
202 return false;
203 }
204 /* addresses */
205 std::vector< std::pair< size_t, size_t > > map;
206 if(!build_map("device address", a.addr, b.addr, map))
207 return false;
208 for(size_t i = 0; i < map.size(); i++)
209 if(!compare_dev_addr(soc, a, a.addr[map[i].first], b.addr[map[i].second]))
210 return false;
211 /* reg */
212 map.clear();
213 if(!build_map("register", a.reg, b.reg, map))
214 return false;
215 for(size_t i = 0; i < map.size(); i++)
216 if(!compare_reg(soc, a, a.reg[map[i].first], b.reg[map[i].second]))
217 return false;
218 return true;
219}
220
221bool compare_soc(const soc_t& a, const soc_t& b)
222{
223 if(a.name != b.name)
224 {
225 return printf("soc have different names\n");
226 return false;
227 }
228 if(a.desc != b.desc)
229 {
230 printf("soc '%s' have different descriptions\n", a.name.c_str());
231 return false;
232 }
233 std::vector< std::pair< size_t, size_t > > map;
234 if(!build_map("device", a.dev, b.dev, map))
235 return false;
236 for(size_t i = 0; i< map.size(); i++)
237 if(!compare_dev(a, a.dev[map[i].first], b.dev[map[i].second]))
238 return false;
239 return true;
240}
241
242int do_compare(int argc, char **argv)
243{
244 if(argc != 2)
245 return printf("compare mode expects two arguments\n");
246 soc_t soc[2];
247 if(!soc_desc_parse_xml(argv[0], soc[0]))
248 return printf("cannot read file '%s'\n", argv[0]);
249 if(!soc_desc_parse_xml(argv[1], soc[1]))
250 return printf("cannot read file '%s'\n", argv[1]);
251 if(compare_soc(soc[0], soc[1]))
252 printf("Files are identical.\n");
253 return 0;
254}
255
256int do_write(int argc, char **argv)
257{
258 if(argc != 2)
259 return printf("write mode expects two arguments\n");
260 soc_t soc;
261 if(!soc_desc_parse_xml(argv[0], soc))
262 return printf("cannot read file '%s'\n", argv[0]);
263 if(!soc_desc_produce_xml(argv[1], soc))
264 return printf("cannot write file '%s'\n", argv[1]);
265 return 0;
266}
267
268int do_check(int argc, char **argv)
269{
270 for(int i = 0; i < argc; i++)
271 {
272 soc_t soc;
273 if(!soc_desc_parse_xml(argv[i], soc))
274 {
275 printf("cannot read file '%s'\n", argv[i]);
276 continue;
277 }
278 printf("[%s]\n", argv[i]);
279 std::vector< soc_error_t > errs = soc.errors(true);
280 for(size_t i = 0; i < errs.size(); i++)
281 {
282 const soc_error_t& e = errs[i];
283 switch(e.level)
284 {
285 case SOC_ERROR_WARNING: printf("[WARN ] "); break;
286 case SOC_ERROR_FATAL: printf("[FATAL] "); break;
287 default: printf("[ UNK ] "); break;
288 }
289 printf("%s: %s\n", e.location.c_str(), e.message.c_str());
290 }
291 }
292 return 0;
293}
294
295int do_eval(int argc, char **argv)
296{
297 std::map< std::string, soc_word_t > map;
298 for(int i = 0; i < argc; i++)
299 {
300 std::string error;
301 std::string formula(argv[i]);
302 soc_word_t result;
303 if(strcmp(argv[i], "--var") == 0)
304 {
305 if(i + 1 >= argc)
306 break;
307 i++;
308 std::string str(argv[i]);
309 size_t pos = str.find('=');
310 if(pos == std::string::npos)
311 {
312 printf("invalid variable string '%s'\n", str.c_str());
313 continue;
314 }
315 std::string name = str.substr(0, pos);
316 std::string val = str.substr(pos + 1);
317 char *end;
318 soc_word_t v = strtoul(val.c_str(), &end, 0);
319 if(*end)
320 {
321 printf("invalid variable string '%s'\n", str.c_str());
322 continue;
323 }
324 printf("%s = %#lx\n", name.c_str(), (unsigned long)v);
325 map[name] = v;
326 continue;
327 }
328 if(!soc_desc_evaluate_formula(formula, map, result, error))
329 printf("error: %s\n", error.c_str());
330 else
331 printf("result: %lu (%#lx)\n", (unsigned long)result, (unsigned long)result);
332 }
333 return 0;
78} 334}
79 335
80void usage() 336void usage()
81{ 337{
82 printf("usage: tester <desc file>\n"); 338 printf("usage: tester <mode> [options]\n");
339 printf("modes:\n");
340 printf(" compare <desc file> <desc file>\n");
341 printf(" write <read file> <write file>\n");
342 printf(" check <files...>\n");
343 printf(" eval [<formula>|--var <name>=<val>]...\n");
83 exit(1); 344 exit(1);
84} 345}
85 346
86int main(int argc, char **argv) 347int main(int argc, char **argv)
87{ 348{
88 if(argc != 2) 349 if(argc < 2)
350 usage();
351 std::string mode = argv[1];
352 if(mode == "compare")
353 return do_compare(argc - 2, argv + 2);
354 else if(mode == "write")
355 return do_write(argc - 2, argv + 2);
356 else if(mode == "check")
357 return do_check(argc - 2, argv + 2);
358 else if(mode == "eval")
359 return do_eval(argc - 2, argv + 2);
360 else
89 usage(); 361 usage();
90 std::vector< soc_t > socs;
91 bool ret = soc_desc_parse_xml(argv[1], socs);
92 printf("parse result: %d\n", ret);
93 if(ret)
94 for(size_t i = 0; i < socs.size(); i++)
95 print_soc_desc(socs[i]);
96 return 0; 362 return 0;
97} \ No newline at end of file 363} \ No newline at end of file