diff options
Diffstat (limited to 'firmware/target/arm/tms320dm320/dsp/xml2h.py')
-rw-r--r-- | firmware/target/arm/tms320dm320/dsp/xml2h.py | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/dsp/xml2h.py b/firmware/target/arm/tms320dm320/dsp/xml2h.py new file mode 100644 index 0000000000..2d25c9028e --- /dev/null +++ b/firmware/target/arm/tms320dm320/dsp/xml2h.py | |||
@@ -0,0 +1,193 @@ | |||
1 | #!/usr/bin/python | ||
2 | # __________ __ ___. | ||
3 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | # \/ \/ \/ \/ \/ | ||
8 | # $Id$ | ||
9 | # | ||
10 | # Copyright (C) 2007 Catalin Patulea <cat@vv.carleton.ca> | ||
11 | # | ||
12 | # All files in this archive are subject to the GNU General Public License. | ||
13 | # See the file COPYING in the source tree root for full license agreement. | ||
14 | # | ||
15 | # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | # KIND, either express or implied. | ||
17 | # | ||
18 | |||
19 | import sys, os.path, array, re | ||
20 | from xml.dom import Node | ||
21 | from xml.dom.minidom import parse | ||
22 | |||
23 | |||
24 | C_IDENT_RE = re.compile('^[0-9a-zA-Z_]+$') | ||
25 | |||
26 | |||
27 | def getText(nodelist): | ||
28 | rc = "" | ||
29 | for node in nodelist: | ||
30 | if node.nodeType == node.TEXT_NODE: | ||
31 | rc = rc + node.data | ||
32 | return rc | ||
33 | |||
34 | |||
35 | def descendAll(root, tagname): | ||
36 | for child in root.childNodes: | ||
37 | if child.nodeType == Node.ELEMENT_NODE and child.tagName == tagname: | ||
38 | yield child | ||
39 | |||
40 | |||
41 | def descend(root, tagname): | ||
42 | return descendAll(root, tagname).next() | ||
43 | |||
44 | |||
45 | def getTagText(root, tagname): | ||
46 | try: | ||
47 | tag = descend(root, tagname) | ||
48 | except StopIteration: | ||
49 | return None | ||
50 | return getText(tag.childNodes) | ||
51 | |||
52 | |||
53 | def main(): | ||
54 | dom = parse(sys.stdin) | ||
55 | |||
56 | ofd = descend(dom, "ofd") | ||
57 | object_file = descend(ofd, "object_file") | ||
58 | object_file_name = descend(object_file, "name") | ||
59 | |||
60 | out_filepath = getText(object_file_name.childNodes) | ||
61 | sys.stderr.write("*.out filename (input): %s\n" % out_filepath) | ||
62 | |||
63 | out_file = open(out_filepath, "rb") | ||
64 | h_file = sys.stdout | ||
65 | |||
66 | h_file.write("""#ifndef DSP_IMAGE | ||
67 | #define DSP_IMAGE | ||
68 | /* | ||
69 | * Automatically generated by xml2h.py from %s. | ||
70 | * | ||
71 | * This program is free software; you can redistribute it and/or | ||
72 | * modify it under the terms of the GNU General Public License as | ||
73 | * published by the Free Software Foundation; either version 2 of | ||
74 | * the License, or (at your option) any later version. | ||
75 | * | ||
76 | * This program is distributed in the hope that it will be useful, | ||
77 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
78 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
79 | * GNU General Public License for more details. | ||
80 | * | ||
81 | * You should have received a copy of the GNU General Public License | ||
82 | * along with this program; if not, write to the Free Software | ||
83 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
84 | * MA 02111-1307 USA | ||
85 | * | ||
86 | */ | ||
87 | """ % out_filepath) | ||
88 | |||
89 | # Section data and directory. | ||
90 | h_directory = [""" | ||
91 | static const struct dsp_section dsp_image[] = {"""] | ||
92 | |||
93 | ti_coff = descend(object_file, "ti_coff") | ||
94 | for section in descendAll(ti_coff, "section"): | ||
95 | page = int(getTagText(section, "page") or "0", 16) | ||
96 | name = getTagText(section, "name") | ||
97 | physical_addr = int(getTagText(section, "physical_addr"), 16) | ||
98 | raw_data_size = int(getTagText(section, "raw_data_size"), 16) | ||
99 | copy = getTagText(section, "copy") | ||
100 | data = getTagText(section, "data") | ||
101 | regular = getTagText(section, "regular") | ||
102 | text = getTagText(section, "text") | ||
103 | bss = getTagText(section, "bss") | ||
104 | |||
105 | file_offsets = descend(section, "file_offsets") | ||
106 | raw_data_ptr = int(getTagText(file_offsets, "raw_data_ptr"), 16) | ||
107 | |||
108 | if copy: | ||
109 | # Empirically, .debug* sections have this attribute set. | ||
110 | sys.stderr.write( | ||
111 | "%s: didn't copy debug section ('copy' attribute set)\n" % | ||
112 | name) | ||
113 | continue | ||
114 | |||
115 | if raw_data_size == 0: | ||
116 | sys.stderr.write("%s: not copying empty section\n" % name) | ||
117 | continue | ||
118 | |||
119 | if raw_data_size % 2 != 0: | ||
120 | sys.stderr.write("%s: error, raw_data_size 0x%04x not a multiple " | ||
121 | "of word size (2 bytes)\n" % (name, raw_data_size)) | ||
122 | break | ||
123 | |||
124 | if data or regular or text: | ||
125 | sys.stderr.write("%s: placing 0x%04x words at 0x%04x from offset " | ||
126 | "0x%08x\n" % ( | ||
127 | name, raw_data_size >> 1, physical_addr, raw_data_ptr)) | ||
128 | |||
129 | sanitized_name = name.replace(".", "_") | ||
130 | h_file.write(("static const unsigned short _section%s[] = {\n" % | ||
131 | sanitized_name)) | ||
132 | |||
133 | out_file.seek(raw_data_ptr) | ||
134 | data = array.array('H') | ||
135 | data.fromfile(out_file, raw_data_size >> 1) | ||
136 | h_file.write("\t") | ||
137 | for word in data: | ||
138 | h_file.write("0x%04x, " % word) | ||
139 | h_file.write(""" | ||
140 | }; | ||
141 | """) | ||
142 | |||
143 | h_directory.append("\t{_section%s, 0x%04x, 0x%04x}," % ( | ||
144 | sanitized_name, physical_addr, raw_data_size >> 1)) | ||
145 | |||
146 | continue | ||
147 | |||
148 | if bss: | ||
149 | sys.stderr.write("%s: bss section, 0x%04x words at 0x%04x\n" % ( | ||
150 | name, raw_data_size >> 1, physical_addr)) | ||
151 | |||
152 | h_directory.append("\t{NULL /* %s */, 0x%04x, 0x%04x}," % ( | ||
153 | name, physical_addr, raw_data_size >> 1)) | ||
154 | continue | ||
155 | |||
156 | sys.stderr.write("%s: error, unprocessed section\n" % name) | ||
157 | |||
158 | h_file.write("\n") | ||
159 | |||
160 | h_directory.append("\t{NULL, 0, 0}") | ||
161 | h_directory.append("};") | ||
162 | |||
163 | h_file.write("\n".join(h_directory)) | ||
164 | h_file.write("\n") | ||
165 | |||
166 | # Symbols. | ||
167 | symbol_table = descend(ti_coff, "symbol_table") | ||
168 | h_file.write(""" | ||
169 | /* Symbol table, usable with the DSP_() macro (see dsp-target.h). */ | ||
170 | """) | ||
171 | for symbol in descendAll(symbol_table, "symbol"): | ||
172 | name = getTagText(symbol, "name") | ||
173 | kind = getTagText(symbol, "kind") | ||
174 | value = int(getTagText(symbol, "value"), 16) | ||
175 | |||
176 | if kind != "defined": | ||
177 | continue | ||
178 | |||
179 | if not C_IDENT_RE.match(name): | ||
180 | continue | ||
181 | |||
182 | h_file.write("#define %s 0x%04x\n" % (name, value)) | ||
183 | |||
184 | h_file.write("\n#endif\n") | ||
185 | h_file.close() | ||
186 | out_file.close() | ||
187 | |||
188 | dom.unlink() | ||
189 | |||
190 | |||
191 | if __name__ == "__main__": | ||
192 | main() | ||
193 | |||