|
1 /* |
|
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005, 2008. |
|
3 * |
|
4 * This program is free software; you can redistribute it and/or |
|
5 * modify it under the terms of the GNU General Public License as |
|
6 * published by the Free Software Foundation; either version 2 of the |
|
7 * License, or (at your option) any later version. |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 * General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
|
17 * USA |
|
18 */ |
|
19 |
|
20 %option noyywrap nounput |
|
21 |
|
22 %x INCLUDE |
|
23 %x BYTESTRING |
|
24 %x PROPNODENAME |
|
25 |
|
26 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] |
|
27 PATHCHAR ({PROPNODECHAR}|[/]) |
|
28 LABEL [a-zA-Z_][a-zA-Z0-9_]* |
|
29 STRING \"([^\\"]|\\.)*\" |
|
30 WS [[:space:]] |
|
31 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" |
|
32 LINECOMMENT "//".*\n |
|
33 GAP ({WS}|{COMMENT}|{LINECOMMENT})* |
|
34 |
|
35 %{ |
|
36 #include <string.h> |
|
37 #include <stdlib.h> |
|
38 #include <stdarg.h> |
|
39 |
|
40 #include <errno.h> |
|
41 #include <assert.h> |
|
42 #include <fnmatch.h> |
|
43 |
|
44 #include "srcpos.h" |
|
45 |
|
46 static int v1_tagged; /* = 0 */ |
|
47 static int cbase = 16; |
|
48 static int saw_hyphen; /* = 0 */ |
|
49 static unsigned long long last_val; |
|
50 static char *last_name; /* = NULL */ |
|
51 |
|
52 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
|
53 |
|
54 static inline void __attribute__((noreturn)) die(char * str, ...) |
|
55 { |
|
56 va_list ap; |
|
57 |
|
58 va_start(ap, str); |
|
59 fprintf(stderr, "FATAL ERROR: "); |
|
60 vfprintf(stderr, str, ap); |
|
61 exit(1); |
|
62 } |
|
63 |
|
64 static inline void *xmalloc(size_t len) |
|
65 { |
|
66 void *new = malloc(len); |
|
67 |
|
68 if (! new) |
|
69 die("malloc() failed\n"); |
|
70 |
|
71 return new; |
|
72 } |
|
73 |
|
74 const struct { |
|
75 const char *pattern; |
|
76 int obase, width; |
|
77 } guess_table[] = { |
|
78 { "*-frequency", 10, 0 }, |
|
79 { "num-*", 10, 0 }, |
|
80 { "#*-cells", 10, 0 }, |
|
81 { "*cache-line-size", 10, 0 }, |
|
82 { "*cache-block-size", 10, 0 }, |
|
83 { "*cache-size", 10, 0 }, |
|
84 { "*cache-sets", 10, 0 }, |
|
85 { "cell-index", 10, 0 }, |
|
86 { "bank-width", 10, 0 }, |
|
87 { "*-fifo-size", 10, 0 }, |
|
88 { "*-frame-size", 10, 0 }, |
|
89 { "*-channel", 10, 0 }, |
|
90 { "current-speed", 10, 0 }, |
|
91 { "phy-map", 16, 8 }, |
|
92 { "dcr-reg", 16, 3 }, |
|
93 { "reg", 16, 8 }, |
|
94 { "ranges", 16, 8}, |
|
95 }; |
|
96 %} |
|
97 |
|
98 %% |
|
99 <*>"/include/"{GAP}{STRING} ECHO; |
|
100 |
|
101 <*>\"([^\\"]|\\.)*\" ECHO; |
|
102 |
|
103 <*>"/dts-v1/" { |
|
104 die("Input dts file is already version 1\n"); |
|
105 } |
|
106 |
|
107 <*>"/memreserve/" { |
|
108 if (!v1_tagged) { |
|
109 fprintf(yyout, "/dts-v1/;\n\n"); |
|
110 v1_tagged = 1; |
|
111 } |
|
112 |
|
113 ECHO; |
|
114 BEGIN(INITIAL); |
|
115 } |
|
116 |
|
117 <*>{LABEL}: ECHO; |
|
118 |
|
119 <INITIAL>[bodh]# { |
|
120 if (*yytext == 'b') |
|
121 cbase = 2; |
|
122 else if (*yytext == 'o') |
|
123 cbase = 8; |
|
124 else if (*yytext == 'd') |
|
125 cbase = 10; |
|
126 else |
|
127 cbase = 16; |
|
128 } |
|
129 |
|
130 <INITIAL>[0-9a-fA-F]+ { |
|
131 unsigned long long val; |
|
132 int obase = 16, width = 0; |
|
133 int i; |
|
134 |
|
135 val = strtoull(yytext, NULL, cbase); |
|
136 |
|
137 if (saw_hyphen) |
|
138 val = val - last_val + 1; |
|
139 |
|
140 if (last_name) { |
|
141 for (i = 0; i < ARRAY_SIZE(guess_table); i++) |
|
142 if (fnmatch(guess_table[i].pattern, |
|
143 last_name, 0) == 0) { |
|
144 obase = guess_table[i].obase; |
|
145 width = guess_table[i].width; |
|
146 } |
|
147 } else { |
|
148 obase = 16; |
|
149 width = 16; |
|
150 } |
|
151 |
|
152 if (cbase != 16) |
|
153 obase = cbase; |
|
154 |
|
155 switch (obase) { |
|
156 case 2: |
|
157 case 16: |
|
158 fprintf(yyout, "0x%0*llx", width, val); |
|
159 break; |
|
160 case 8: |
|
161 fprintf(yyout, "0%0*llo", width, val); |
|
162 break; |
|
163 case 10: |
|
164 fprintf(yyout, "%*llu", width, val); |
|
165 break; |
|
166 } |
|
167 |
|
168 cbase = 16; |
|
169 last_val = val; |
|
170 saw_hyphen = 0; |
|
171 } |
|
172 |
|
173 \&{LABEL} ECHO; |
|
174 |
|
175 "&{/"{PATHCHAR}+\} ECHO; |
|
176 |
|
177 <INITIAL>"&/"{PATHCHAR}+ fprintf(yyout, "&{/%s}", yytext + 2); |
|
178 |
|
179 <BYTESTRING>[0-9a-fA-F]{2} ECHO; |
|
180 |
|
181 <BYTESTRING>"]" { |
|
182 ECHO; |
|
183 BEGIN(INITIAL); |
|
184 } |
|
185 |
|
186 <PROPNODENAME>{PROPNODECHAR}+ { |
|
187 ECHO; |
|
188 last_name = strdup(yytext); |
|
189 BEGIN(INITIAL); |
|
190 } |
|
191 |
|
192 <*>{GAP} ECHO; |
|
193 |
|
194 <*>- { /* Hack to convert old style memreserves */ |
|
195 saw_hyphen = 1; |
|
196 fprintf(yyout, " "); |
|
197 } |
|
198 |
|
199 <*>. { |
|
200 if (!v1_tagged) { |
|
201 fprintf(yyout, "/dts-v1/;\n\n"); |
|
202 v1_tagged = 1; |
|
203 } |
|
204 |
|
205 ECHO; |
|
206 if (yytext[0] == '[') { |
|
207 BEGIN(BYTESTRING); |
|
208 } |
|
209 if ((yytext[0] == '{') |
|
210 || (yytext[0] == ';')) { |
|
211 BEGIN(PROPNODENAME); |
|
212 } |
|
213 } |
|
214 |
|
215 %% |
|
216 static void usage(void) |
|
217 { |
|
218 fprintf(stderr, "convert-dtsv0 <v0 dts file>...\n"); |
|
219 exit(3); |
|
220 } |
|
221 |
|
222 static void convert_file(const char *fname) |
|
223 { |
|
224 const char suffix[] = "v1"; |
|
225 int len = strlen(fname); |
|
226 char *newname; |
|
227 |
|
228 newname = xmalloc(len + sizeof(suffix)); |
|
229 memcpy(newname, fname, len); |
|
230 memcpy(newname + len, suffix, sizeof(suffix)); |
|
231 |
|
232 srcpos_file = dtc_open_file(fname, NULL); |
|
233 yyin = srcpos_file->file; |
|
234 |
|
235 yyout = fopen(newname, "w"); |
|
236 if (!yyout) |
|
237 die("Couldn't open output file %s: %s\n", |
|
238 newname, strerror(errno)); |
|
239 |
|
240 while(yylex()) |
|
241 ; |
|
242 } |
|
243 |
|
244 int main(int argc, char *argv[]) |
|
245 { |
|
246 int i; |
|
247 |
|
248 if (argc < 2) |
|
249 usage(); |
|
250 |
|
251 for (i = 1; i < argc; i++) { |
|
252 fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]); |
|
253 convert_file(argv[i]); |
|
254 } |
|
255 |
|
256 exit(0); |
|
257 } |