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 noinput
21
22%x INCLUDE
23%x BYTESTRING
24%x PROPNODENAME
25
26PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
27PATHCHAR	({PROPNODECHAR}|[/])
28LABEL		[a-zA-Z_][a-zA-Z0-9_]*
29STRING		\"([^\\"]|\\.)*\"
30WS		[[:space:]]
31COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
32LINECOMMENT	"//".*\n
33GAP		({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#include "util.h"
46
47static int v1_tagged; /* = 0 */
48static int cbase = 16;
49static int saw_hyphen; /* = 0 */
50static unsigned long long last_val;
51static char *last_name; /* = NULL */
52
53#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
54
55const struct {
56	const char *pattern;
57	int obase, width;
58} guess_table[] = {
59	{ "*-frequency", 10, 0 },
60	{ "num-*", 10, 0 },
61	{ "#*-cells", 10, 0 },
62	{ "*cache-line-size", 10, 0 },
63	{ "*cache-block-size", 10, 0 },
64	{ "*cache-size", 10, 0 },
65	{ "*cache-sets", 10, 0 },
66	{ "cell-index", 10, 0 },
67	{ "bank-width", 10, 0 },
68	{ "*-fifo-size", 10, 0 },
69	{ "*-frame-size", 10, 0 },
70	{ "*-channel", 10, 0 },
71	{ "current-speed", 10, 0 },
72	{ "phy-map", 16, 8 },
73	{ "dcr-reg", 16, 3 },
74	{ "reg", 16, 8 },
75	{ "ranges", 16, 8},
76};
77%}
78
79%%
80<*>"/include/"{GAP}{STRING}	ECHO;
81
82<*>\"([^\\"]|\\.)*\"	ECHO;
83
84<*>"/dts-v1/"	{
85			die("Input dts file is already version 1\n");
86		}
87
88<*>"/memreserve/"	{
89			if (!v1_tagged) {
90				fprintf(yyout, "/dts-v1/;\n\n");
91				v1_tagged = 1;
92			}
93
94			ECHO;
95			BEGIN(INITIAL);
96		}
97
98<*>{LABEL}:		ECHO;
99
100<INITIAL>[bodh]# {
101			if (*yytext == 'b')
102				cbase = 2;
103			else if (*yytext == 'o')
104				cbase = 8;
105			else if (*yytext == 'd')
106				cbase = 10;
107			else
108				cbase = 16;
109		}
110
111<INITIAL>[0-9a-fA-F]+	{
112			unsigned long long val;
113			int obase = 16, width = 0;
114			int i;
115
116			val = strtoull(yytext, NULL, cbase);
117
118			if (saw_hyphen)
119				val = val - last_val + 1;
120
121			if (last_name) {
122				for (i = 0; i < ARRAY_SIZE(guess_table); i++)
123					if (fnmatch(guess_table[i].pattern,
124					    last_name, 0) == 0) {
125						obase = guess_table[i].obase;
126						width = guess_table[i].width;
127					}
128			} else {
129				obase = 16;
130				width = 16;
131			}
132
133			if (cbase != 16)
134				obase = cbase;
135
136			switch (obase) {
137			case 2:
138			case 16:
139				fprintf(yyout, "0x%0*llx", width, val);
140				break;
141			case 8:
142				fprintf(yyout, "0%0*llo", width, val);
143				break;
144			case 10:
145				fprintf(yyout, "%*llu", width, val);
146				break;
147			}
148
149			cbase = 16;
150			last_val = val;
151			saw_hyphen = 0;
152		}
153
154\&{LABEL}		ECHO;
155
156"&{/"{PATHCHAR}+\}	ECHO;
157
158<INITIAL>"&/"{PATHCHAR}+ fprintf(yyout, "&{/%s}", yytext + 2);
159
160<BYTESTRING>[0-9a-fA-F]{2} ECHO;
161
162<BYTESTRING>"]"	{
163			ECHO;
164			BEGIN(INITIAL);
165		}
166
167<PROPNODENAME>{PROPNODECHAR}+ {
168			ECHO;
169			last_name = xstrdup(yytext);
170			BEGIN(INITIAL);
171		}
172
173<*>{GAP}	ECHO;
174
175<*>-		{	/* Hack to convert old style memreserves */
176			saw_hyphen = 1;
177			fprintf(yyout, " ");
178		}
179
180<*>.		{
181			if (!v1_tagged) {
182				fprintf(yyout, "/dts-v1/;\n\n");
183				v1_tagged = 1;
184			}
185
186			ECHO;
187			if (yytext[0] == '[') {
188				BEGIN(BYTESTRING);
189			}
190			if ((yytext[0] == '{')
191			    || (yytext[0] == ';')) {
192				BEGIN(PROPNODENAME);
193			}
194		}
195
196%%
197static void usage(void)
198{
199	fprintf(stderr, "convert-dtsv0 <v0 dts file>...\n");
200	exit(3);
201}
202
203static void convert_file(const char *fname)
204{
205	const char suffix[] = "v1";
206	int len = strlen(fname);
207	char *newname;
208
209	newname = xmalloc(len + sizeof(suffix));
210	memcpy(newname, fname, len);
211	memcpy(newname + len, suffix, sizeof(suffix));
212
213	srcpos_file = dtc_open_file(fname, NULL);
214	yyin = srcpos_file->file;
215
216	yyout = fopen(newname, "w");
217	if (!yyout)
218		die("Couldn't open output file %s: %s\n",
219		    newname, strerror(errno));
220
221	while(yylex())
222		;
223}
224
225int main(int argc, char *argv[])
226{
227	int i;
228
229	if (argc < 2)
230		usage();
231
232	for (i = 1; i < argc; i++) {
233		fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]);
234		convert_file(argv[i]);
235	}
236
237	exit(0);
238}
239