1204431Sraj/*
2204431Sraj * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005, 2008.
3204431Sraj *
4204431Sraj * This program is free software; you can redistribute it and/or
5204431Sraj * modify it under the terms of the GNU General Public License as
6204431Sraj * published by the Free Software Foundation; either version 2 of the
7204431Sraj * License, or (at your option) any later version.
8204431Sraj *
9204431Sraj *  This program is distributed in the hope that it will be useful,
10204431Sraj *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11204431Sraj *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12204431Sraj *  General Public License for more details.
13204431Sraj *
14204431Sraj *  You should have received a copy of the GNU General Public License
15204431Sraj *  along with this program; if not, write to the Free Software
16204431Sraj *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
17204431Sraj *                                                                   USA
18204431Sraj */
19204431Sraj
20204433Sraj%option noyywrap nounput noinput
21204431Sraj
22204431Sraj%x INCLUDE
23204431Sraj%x BYTESTRING
24204431Sraj%x PROPNODENAME
25204431Sraj
26204431SrajPROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
27204431SrajPATHCHAR	({PROPNODECHAR}|[/])
28204431SrajLABEL		[a-zA-Z_][a-zA-Z0-9_]*
29204431SrajSTRING		\"([^\\"]|\\.)*\"
30204431SrajWS		[[:space:]]
31204431SrajCOMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
32204431SrajLINECOMMENT	"//".*\n
33204431SrajGAP		({WS}|{COMMENT}|{LINECOMMENT})*
34204431Sraj
35204431Sraj%{
36204431Sraj#include <string.h>
37204431Sraj#include <stdlib.h>
38204431Sraj#include <stdarg.h>
39204431Sraj
40204431Sraj#include <errno.h>
41204431Sraj#include <assert.h>
42204431Sraj#include <fnmatch.h>
43204431Sraj
44204431Sraj#include "srcpos.h"
45204433Sraj#include "util.h"
46204431Sraj
47204431Srajstatic int v1_tagged; /* = 0 */
48204431Srajstatic int cbase = 16;
49204431Srajstatic int saw_hyphen; /* = 0 */
50204431Srajstatic unsigned long long last_val;
51204431Srajstatic char *last_name; /* = NULL */
52204431Sraj
53204431Sraj#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
54204431Sraj
55204431Srajconst struct {
56204431Sraj	const char *pattern;
57204431Sraj	int obase, width;
58204431Sraj} guess_table[] = {
59204431Sraj	{ "*-frequency", 10, 0 },
60204431Sraj	{ "num-*", 10, 0 },
61204431Sraj	{ "#*-cells", 10, 0 },
62204431Sraj	{ "*cache-line-size", 10, 0 },
63204431Sraj	{ "*cache-block-size", 10, 0 },
64204431Sraj	{ "*cache-size", 10, 0 },
65204431Sraj	{ "*cache-sets", 10, 0 },
66204431Sraj	{ "cell-index", 10, 0 },
67204431Sraj	{ "bank-width", 10, 0 },
68204431Sraj	{ "*-fifo-size", 10, 0 },
69204431Sraj	{ "*-frame-size", 10, 0 },
70204431Sraj	{ "*-channel", 10, 0 },
71204431Sraj	{ "current-speed", 10, 0 },
72204431Sraj	{ "phy-map", 16, 8 },
73204431Sraj	{ "dcr-reg", 16, 3 },
74204431Sraj	{ "reg", 16, 8 },
75204431Sraj	{ "ranges", 16, 8},
76204431Sraj};
77204431Sraj%}
78204431Sraj
79204431Sraj%%
80204431Sraj<*>"/include/"{GAP}{STRING}	ECHO;
81204431Sraj
82204431Sraj<*>\"([^\\"]|\\.)*\"	ECHO;
83204431Sraj
84204431Sraj<*>"/dts-v1/"	{
85204431Sraj			die("Input dts file is already version 1\n");
86204431Sraj		}
87204431Sraj
88204431Sraj<*>"/memreserve/"	{
89204431Sraj			if (!v1_tagged) {
90204431Sraj				fprintf(yyout, "/dts-v1/;\n\n");
91204431Sraj				v1_tagged = 1;
92204431Sraj			}
93204431Sraj
94204431Sraj			ECHO;
95204431Sraj			BEGIN(INITIAL);
96204431Sraj		}
97204431Sraj
98204431Sraj<*>{LABEL}:		ECHO;
99204431Sraj
100204431Sraj<INITIAL>[bodh]# {
101204431Sraj			if (*yytext == 'b')
102204431Sraj				cbase = 2;
103204431Sraj			else if (*yytext == 'o')
104204431Sraj				cbase = 8;
105204431Sraj			else if (*yytext == 'd')
106204431Sraj				cbase = 10;
107204431Sraj			else
108204431Sraj				cbase = 16;
109204431Sraj		}
110204431Sraj
111204431Sraj<INITIAL>[0-9a-fA-F]+	{
112204431Sraj			unsigned long long val;
113204431Sraj			int obase = 16, width = 0;
114204431Sraj			int i;
115204431Sraj
116204431Sraj			val = strtoull(yytext, NULL, cbase);
117204431Sraj
118204431Sraj			if (saw_hyphen)
119204431Sraj				val = val - last_val + 1;
120204431Sraj
121204431Sraj			if (last_name) {
122204431Sraj				for (i = 0; i < ARRAY_SIZE(guess_table); i++)
123204431Sraj					if (fnmatch(guess_table[i].pattern,
124204431Sraj					    last_name, 0) == 0) {
125204431Sraj						obase = guess_table[i].obase;
126204431Sraj						width = guess_table[i].width;
127204431Sraj					}
128204431Sraj			} else {
129204431Sraj				obase = 16;
130204431Sraj				width = 16;
131204431Sraj			}
132204431Sraj
133204431Sraj			if (cbase != 16)
134204431Sraj				obase = cbase;
135204431Sraj
136204431Sraj			switch (obase) {
137204431Sraj			case 2:
138204431Sraj			case 16:
139204431Sraj				fprintf(yyout, "0x%0*llx", width, val);
140204431Sraj				break;
141204431Sraj			case 8:
142204431Sraj				fprintf(yyout, "0%0*llo", width, val);
143204431Sraj				break;
144204431Sraj			case 10:
145204431Sraj				fprintf(yyout, "%*llu", width, val);
146204431Sraj				break;
147204431Sraj			}
148204431Sraj
149204431Sraj			cbase = 16;
150204431Sraj			last_val = val;
151204431Sraj			saw_hyphen = 0;
152204431Sraj		}
153204431Sraj
154204431Sraj\&{LABEL}		ECHO;
155204431Sraj
156204431Sraj"&{/"{PATHCHAR}+\}	ECHO;
157204431Sraj
158204431Sraj<INITIAL>"&/"{PATHCHAR}+ fprintf(yyout, "&{/%s}", yytext + 2);
159204431Sraj
160204431Sraj<BYTESTRING>[0-9a-fA-F]{2} ECHO;
161204431Sraj
162204431Sraj<BYTESTRING>"]"	{
163204431Sraj			ECHO;
164204431Sraj			BEGIN(INITIAL);
165204431Sraj		}
166204431Sraj
167204431Sraj<PROPNODENAME>{PROPNODECHAR}+ {
168204431Sraj			ECHO;
169204433Sraj			last_name = xstrdup(yytext);
170204431Sraj			BEGIN(INITIAL);
171204431Sraj		}
172204431Sraj
173204431Sraj<*>{GAP}	ECHO;
174204431Sraj
175204431Sraj<*>-		{	/* Hack to convert old style memreserves */
176204431Sraj			saw_hyphen = 1;
177204431Sraj			fprintf(yyout, " ");
178204431Sraj		}
179204431Sraj
180204431Sraj<*>.		{
181204431Sraj			if (!v1_tagged) {
182204431Sraj				fprintf(yyout, "/dts-v1/;\n\n");
183204431Sraj				v1_tagged = 1;
184204431Sraj			}
185204431Sraj
186204431Sraj			ECHO;
187204431Sraj			if (yytext[0] == '[') {
188204431Sraj				BEGIN(BYTESTRING);
189204431Sraj			}
190204431Sraj			if ((yytext[0] == '{')
191204431Sraj			    || (yytext[0] == ';')) {
192204431Sraj				BEGIN(PROPNODENAME);
193204431Sraj			}
194204431Sraj		}
195204431Sraj
196204431Sraj%%
197204431Srajstatic void usage(void)
198204431Sraj{
199204431Sraj	fprintf(stderr, "convert-dtsv0 <v0 dts file>...\n");
200204431Sraj	exit(3);
201204431Sraj}
202204431Sraj
203204431Srajstatic void convert_file(const char *fname)
204204431Sraj{
205204431Sraj	const char suffix[] = "v1";
206204431Sraj	int len = strlen(fname);
207204431Sraj	char *newname;
208204431Sraj
209204431Sraj	newname = xmalloc(len + sizeof(suffix));
210204431Sraj	memcpy(newname, fname, len);
211204431Sraj	memcpy(newname + len, suffix, sizeof(suffix));
212204431Sraj
213204431Sraj	srcpos_file = dtc_open_file(fname, NULL);
214204431Sraj	yyin = srcpos_file->file;
215204431Sraj
216204431Sraj	yyout = fopen(newname, "w");
217204431Sraj	if (!yyout)
218204431Sraj		die("Couldn't open output file %s: %s\n",
219204431Sraj		    newname, strerror(errno));
220204431Sraj
221204431Sraj	while(yylex())
222204431Sraj		;
223204431Sraj}
224204431Sraj
225204431Srajint main(int argc, char *argv[])
226204431Sraj{
227204431Sraj	int i;
228204431Sraj
229204431Sraj	if (argc < 2)
230204431Sraj		usage();
231204431Sraj
232204431Sraj	for (i = 1; i < argc; i++) {
233204431Sraj		fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]);
234204431Sraj		convert_file(argv[i]);
235204431Sraj	}
236204431Sraj
237204431Sraj	exit(0);
238204431Sraj}
239