summaryrefslogtreecommitdiff
path: root/utils/regtools/headergen.cpp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-06-12 19:49:26 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-06-12 19:49:26 +0200
commit7143ea681c377fe5901bd79801366a26ae0d394a (patch)
tree34fdaaa83590130b57b187878a89394505950b82 /utils/regtools/headergen.cpp
parent11da9d23fe323ce452fcd04a10a0ddf78eaa63ea (diff)
downloadrockbox-7143ea681c377fe5901bd79801366a26ae0d394a.tar.gz
rockbox-7143ea681c377fe5901bd79801366a26ae0d394a.zip
imxtools: move regtools to its own directory
The register tools are in no way stmp specific. The XML description of the registers is powerful enough to describe the STMP register which should be more than enough to describe virtually all other SoCs. The generators follow the STMP coding convention but others could be used as well. Change-Id: If1a9f56e4a3594161688de34adbea698e5aaecd8
Diffstat (limited to 'utils/regtools/headergen.cpp')
-rw-r--r--utils/regtools/headergen.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/utils/regtools/headergen.cpp b/utils/regtools/headergen.cpp
new file mode 100644
index 0000000000..b6905363d8
--- /dev/null
+++ b/utils/regtools/headergen.cpp
@@ -0,0 +1,274 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 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#include "desc_parser.hpp"
22#include <stdio.h>
23#include <stdlib.h>
24#include <algorithm>
25#include <map>
26
27#define error(...) do{ fprintf(stderr, __VA_ARGS__); exit(1); } while(0)
28
29std::string g_soc_name;
30std::string g_soc_dev;
31std::string g_soc_reg;
32std::string g_soc_dev_regs_base;
33std::string g_soc_dev_reg_core_name;
34
35namespace {
36
37std::string tolower(const std::string s)
38{
39 std::string res = s;
40 std::transform(res.begin(), res.end(), res.begin(), ::tolower);
41 return res;
42}
43
44std::string toupper(const std::string& s)
45{
46 std::string res = s;
47 std::transform(res.begin(), res.end(), res.begin(), ::toupper);
48 return res;
49}
50
51}
52
53void fprint_copyright(FILE *f)
54{
55 fprintf(f,"\
56/***************************************************************************\n\
57 * __________ __ ___.\n\
58 * Open \\______ \\ ____ ____ | | _\\_ |__ _______ ___\n\
59 * Source | _// _ \\_/ ___\\| |/ /| __ \\ / _ \\ \\/ /\n\
60 * Jukebox | | ( <_> ) \\___| < | \\_\\ ( <_> > < <\n\
61 * Firmware |____|_ /\\____/ \\___ >__|_ \\|___ /\\____/__/\\_ \\\n\
62 * \\/ \\/ \\/ \\/ \\/\n\
63 * This file was automatically generated by headergen, DO NOT EDIT it.\n\
64 *\n\
65 * Copyright (C) 2012 by Amaury Pouly\n\
66 *\n\
67 * This program is free software; you can redistribute it and/or\n\
68 * modify it under the terms of the GNU General Public License\n\
69 * as published by the Free Software Foundation; either version 2\n\
70 * of the License, or (at your option) any later version.\n\
71 *\n\
72 * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n\
73 * KIND, either express or implied.\n\
74 *\n\
75 ****************************************************************************/\n");
76}
77
78void fprint_include_guard_ex(FILE *f, bool begin, const std::string& name)
79{
80 if(begin)
81 {
82 fprintf(f, "#ifndef %s\n", name.c_str());
83 fprintf(f, "#define %s\n", name.c_str());
84 fprintf(f, "\n#include \"imx233.h\"\n");
85 }
86 else
87 fprintf(f, "#endif /* %s */\n", name.c_str());
88}
89
90void fprint_include_guard(FILE *f, bool begin)
91{
92 std::string name = "__" + toupper(g_soc_name) + "__" + toupper(g_soc_dev)
93 + "__H__";
94 fprint_include_guard_ex(f, begin, name);
95}
96
97void fprint_fields(FILE *f, const std::vector< soc_reg_field_t >& fields)
98{
99 for(size_t i = 0; i < fields.size(); i++)
100 {
101 fprintf(f, "#define BM_%s_%s %#x\n", g_soc_dev_reg_core_name.c_str(),
102 fields[i].name.c_str(), fields[i].bitmask());
103 fprintf(f, "#define BP_%s_%s %d\n", g_soc_dev_reg_core_name.c_str(),
104 fields[i].name.c_str(), fields[i].first_bit);
105 fprintf(f, "#define BF_%s_%s(v) (((v) << %d) & %#x)\n",
106 g_soc_dev_reg_core_name.c_str(), fields[i].name.c_str(),
107 fields[i].first_bit, fields[i].bitmask());
108 if(fields[i].values.size() > 0)
109 {
110 fprintf(f, "#define BF_%s_%s_V(sym) ((BV_%s_%s__##sym << %d) & %#x)\n",
111 g_soc_dev_reg_core_name.c_str(), fields[i].name.c_str(),
112 g_soc_dev_reg_core_name.c_str(), fields[i].name.c_str(),
113 fields[i].first_bit, fields[i].bitmask());
114 }
115 for(size_t j = 0; j < fields[i].values.size(); j++)
116 {
117 fprintf(f, "#define BV_%s_%s__%s %#x\n", g_soc_dev_reg_core_name.c_str(),
118 fields[i].name.c_str(), fields[i].values[j].name.c_str(),
119 fields[i].values[j].value);
120 }
121 }
122}
123
124void fprint_reg(FILE *f, const soc_reg_t& reg)
125{
126 g_soc_dev_reg_core_name = toupper(g_soc_dev) + "_" + toupper(reg.name);
127
128 fprintf(f, "#define RA_%s %#x\n", g_soc_dev_reg_core_name.c_str(), reg.addr);
129 fprintf(f, "#define HW_%s HW_REG(%s, %s)\n", g_soc_dev_reg_core_name.c_str(),
130 toupper(g_soc_dev).c_str(), toupper(reg.name).c_str());
131 if(reg.flags & REG_HAS_SCT)
132 {
133 fprintf(f, "#define HW_%s_SET HW_SET(%s, %s)\n", g_soc_dev_reg_core_name.c_str(),
134 toupper(g_soc_dev).c_str(), toupper(reg.name).c_str());
135 fprintf(f, "#define HW_%s_CLR HW_CLR(%s, %s)\n", g_soc_dev_reg_core_name.c_str(),
136 toupper(g_soc_dev).c_str(), toupper(reg.name).c_str());
137 fprintf(f, "#define HW_%s_TOG HW_TOG(%s, %s)\n", g_soc_dev_reg_core_name.c_str(),
138 toupper(g_soc_dev).c_str(), toupper(reg.name).c_str());
139 }
140 fprint_fields(f, reg.fields);
141 fprintf(f, "\n");
142}
143
144void fprint_mreg(FILE *f, const soc_multireg_t& mreg)
145{
146}
147
148void gen_dev_header(const std::string& filename, const soc_dev_t& dev)
149{
150 g_soc_dev = dev.name;
151 printf(" Generate header for device %s: write to %s\n", dev.name.c_str(),
152 filename.c_str());
153 FILE *f = fopen(filename.c_str(), "w");
154 if(f == NULL)
155 error("Cannot open file %s\n", filename.c_str());
156 fprint_copyright(f);
157 fprint_include_guard(f, true);
158 fprintf(f, "\n");
159 g_soc_dev_regs_base = "RB_" + toupper(dev.name);
160 fprintf(f, "#define %s %#x\n", g_soc_dev_regs_base.c_str(), dev.addr);
161 fprintf(f, "\n");
162
163 for(size_t i = 0; i < dev.regs.size(); i++)
164 fprint_reg(f, dev.regs[i]);
165 for(size_t i = 0; i < dev.multiregs.size(); i++)
166 fprint_mreg(f, dev.multiregs[i]);
167
168 fprint_include_guard(f, false);
169 fclose(f);
170}
171
172void gen_mdev_header(const std::string& filename, const soc_multidev_t& dev)
173{
174 g_soc_dev = dev.name;
175 printf(" Generate header for multi device %s: write to %s\n", dev.name.c_str(),
176 filename.c_str());
177}
178
179void gen_soc_headers(const std::string& prefix, const soc_t& soc)
180{
181 printf("Generate headers for soc %s: use directory %s (must exists)\n", soc.desc.c_str(),
182 prefix.c_str());
183 for(size_t i = 0; i < soc.devs.size(); i++)
184 {
185 std::string name = soc.devs[i].name;
186 name = tolower(name);
187 gen_dev_header(prefix + "/regs-" + name + ".h", soc.devs[i]);
188 }
189 for(size_t i = 0; i < soc.multidevs.size(); i++)
190 {
191 std::string name = soc.multidevs[i].name;
192 name = tolower(name);
193 gen_mdev_header(prefix + "/regs-" + name + ".h", soc.multidevs[i]);
194 }
195}
196
197void gen_headers(const std::string& prefix, const std::vector< soc_t >& socs)
198{
199 for(size_t i = 0; i < socs.size(); i++)
200 {
201 g_soc_name = socs[i].name;
202 gen_soc_headers(prefix + "/" + socs[i].name, socs[i]);
203 }
204}
205
206typedef std::map< std::string, std::vector< std::string > > general_dev_list_t;
207general_dev_list_t build_general_dev_list(const std::vector< soc_t >& socs)
208{
209 general_dev_list_t map;
210 for(size_t i = 0; i < socs.size(); i++)
211 {
212 for(size_t j = 0; j < socs[i].devs.size(); j++)
213 map[tolower(socs[i].devs[j].name)].push_back(socs[i].name);
214 for(size_t j = 0; j < socs[i].multidevs.size(); j++)
215 map[tolower(socs[i].multidevs[j].name)].push_back(socs[i].name);
216 }
217 return map;
218}
219
220void gen_select_header(const std::string& filename, const std::string& dev,
221 const std::vector< std::string >& socs)
222{
223 printf("Generate select header for device %s: write to %s\n", dev.c_str(),
224 filename.c_str());
225
226 std::string guard = "__SELECT__" + toupper(dev) + "__H__";
227 FILE *f = fopen(filename.c_str(), "w");
228 if(f == NULL)
229 error("Cannot open file %s\n", filename.c_str());
230 fprint_copyright(f);
231 fprint_include_guard_ex(f, true, guard);
232 fprintf(f, "\n");
233
234 for(size_t i = 0; i < socs.size(); i++)
235 {
236 fprintf(f, "#define %s_INCLUDE \"%s/regs-%s.h\"\n",
237 toupper(socs[i]).c_str(), tolower(socs[i]).c_str(),
238 tolower(dev).c_str());
239 }
240 fprintf(f, "\n#include \"regs-select.h\"\n\n");
241 for(size_t i = 0; i < socs.size(); i++)
242 {
243 fprintf(f, "#undef %s_INCLUDE\n", toupper(socs[i]).c_str());
244 }
245 fprintf(f, "\n");
246 fprint_include_guard_ex(f, false, guard);
247 fclose(f);
248}
249
250void gen_selectors(const std::string& prefix, const std::vector< soc_t >& socs)
251{
252 general_dev_list_t map = build_general_dev_list(socs);
253 for(general_dev_list_t::iterator it = map.begin(); it != map.end(); ++it)
254 gen_select_header(prefix + "/regs-" + it->first + ".h", it->first, it->second);
255}
256
257void usage()
258{
259 printf("usage: headergen <desc file> <output prefix>\n");
260 exit(1);
261}
262
263int main(int argc, char **argv)
264{
265 if(argc != 3)
266 usage();
267 std::vector< soc_t > socs;
268 bool ret = parse_soc_desc(argv[1], socs);
269 printf("parse result: %d\n", ret);
270 if(!ret) return 1;
271 gen_headers(argv[2], socs);
272 gen_selectors(argv[2], socs);
273 return 0;
274} \ No newline at end of file