xref: /aosp_15_r20/external/igt-gpu-tools/tools/intel_reg_spec.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*d83cc019SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*d83cc019SAndroid Build Coastguard Worker  * SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  */
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker #include <ctype.h>
25*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
26*d83cc019SAndroid Build Coastguard Worker #include <regex.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker #include "intel_reg_spec.h"
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker static const struct port_desc port_descs[] = {
36*d83cc019SAndroid Build Coastguard Worker 	{
37*d83cc019SAndroid Build Coastguard Worker 		.name = "mmio",
38*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_MMIO,
39*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
40*d83cc019SAndroid Build Coastguard Worker 	},
41*d83cc019SAndroid Build Coastguard Worker 	{
42*d83cc019SAndroid Build Coastguard Worker 		.name = "portio-vga",
43*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_PORTIO_VGA,
44*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
45*d83cc019SAndroid Build Coastguard Worker 	},
46*d83cc019SAndroid Build Coastguard Worker 	{
47*d83cc019SAndroid Build Coastguard Worker 		.name = "mmio-vga",
48*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_MMIO_VGA,
49*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
50*d83cc019SAndroid Build Coastguard Worker 	},
51*d83cc019SAndroid Build Coastguard Worker 	{
52*d83cc019SAndroid Build Coastguard Worker 		.name = "bunit",
53*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_BUNIT,
54*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
55*d83cc019SAndroid Build Coastguard Worker 	},
56*d83cc019SAndroid Build Coastguard Worker 	{
57*d83cc019SAndroid Build Coastguard Worker 		.name = "punit",
58*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_PUNIT,
59*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
60*d83cc019SAndroid Build Coastguard Worker 	},
61*d83cc019SAndroid Build Coastguard Worker 	{
62*d83cc019SAndroid Build Coastguard Worker 		.name = "nc",
63*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_NC,
64*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
65*d83cc019SAndroid Build Coastguard Worker 	},
66*d83cc019SAndroid Build Coastguard Worker 	{
67*d83cc019SAndroid Build Coastguard Worker 		.name = "dpio",
68*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_DPIO,
69*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
70*d83cc019SAndroid Build Coastguard Worker 	},
71*d83cc019SAndroid Build Coastguard Worker 	{
72*d83cc019SAndroid Build Coastguard Worker 		.name = "gpio-nc",
73*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_GPIO_NC,
74*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
75*d83cc019SAndroid Build Coastguard Worker 	},
76*d83cc019SAndroid Build Coastguard Worker 	{
77*d83cc019SAndroid Build Coastguard Worker 		.name = "gpio_nc",
78*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_GPIO_NC,
79*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
80*d83cc019SAndroid Build Coastguard Worker 	},
81*d83cc019SAndroid Build Coastguard Worker 	{
82*d83cc019SAndroid Build Coastguard Worker 		.name = "cck",
83*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_CCK,
84*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
85*d83cc019SAndroid Build Coastguard Worker 	},
86*d83cc019SAndroid Build Coastguard Worker 	{
87*d83cc019SAndroid Build Coastguard Worker 		.name = "ccu",
88*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_CCU,
89*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
90*d83cc019SAndroid Build Coastguard Worker 	},
91*d83cc019SAndroid Build Coastguard Worker 	{
92*d83cc019SAndroid Build Coastguard Worker 		.name = "dpio2",
93*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_DPIO2,
94*d83cc019SAndroid Build Coastguard Worker 		.stride = 4,
95*d83cc019SAndroid Build Coastguard Worker 	},
96*d83cc019SAndroid Build Coastguard Worker 	{
97*d83cc019SAndroid Build Coastguard Worker 		.name = "flisdsi",
98*d83cc019SAndroid Build Coastguard Worker 		.port = PORT_FLISDSI,
99*d83cc019SAndroid Build Coastguard Worker 		.stride = 1,
100*d83cc019SAndroid Build Coastguard Worker 	},
101*d83cc019SAndroid Build Coastguard Worker };
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker /*
104*d83cc019SAndroid Build Coastguard Worker  * Parse port desc of the form (PORTNAME|PORTNUM|MMIO-OFFSET) into reg. NULL or
105*d83cc019SAndroid Build Coastguard Worker  * zero length s is regarded as MMIO.
106*d83cc019SAndroid Build Coastguard Worker  */
parse_port_desc(struct reg * reg,const char * s)107*d83cc019SAndroid Build Coastguard Worker int parse_port_desc(struct reg *reg, const char *s)
108*d83cc019SAndroid Build Coastguard Worker {
109*d83cc019SAndroid Build Coastguard Worker 	enum port_addr port = PORT_NONE;
110*d83cc019SAndroid Build Coastguard Worker 	int i;
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	if (s && *s) {
113*d83cc019SAndroid Build Coastguard Worker 		/* See if port is specified by number. */
114*d83cc019SAndroid Build Coastguard Worker 		char *endp;
115*d83cc019SAndroid Build Coastguard Worker 		unsigned long n = strtoul(s, &endp, 16);
116*d83cc019SAndroid Build Coastguard Worker 		if (endp > s && *endp == 0) {
117*d83cc019SAndroid Build Coastguard Worker 			if (n > PORT_MAX) {
118*d83cc019SAndroid Build Coastguard Worker 				/* Not a sideband port, assume MMIO offset. */
119*d83cc019SAndroid Build Coastguard Worker 				port = PORT_MMIO;
120*d83cc019SAndroid Build Coastguard Worker 				reg->mmio_offset = n;
121*d83cc019SAndroid Build Coastguard Worker 			} else {
122*d83cc019SAndroid Build Coastguard Worker 				port = n;
123*d83cc019SAndroid Build Coastguard Worker 				reg->mmio_offset = 0;
124*d83cc019SAndroid Build Coastguard Worker 			}
125*d83cc019SAndroid Build Coastguard Worker 		} else {
126*d83cc019SAndroid Build Coastguard Worker 			reg->mmio_offset = 0;
127*d83cc019SAndroid Build Coastguard Worker 		}
128*d83cc019SAndroid Build Coastguard Worker 	} else {
129*d83cc019SAndroid Build Coastguard Worker 		/* No port, default to searching for MMIO. */
130*d83cc019SAndroid Build Coastguard Worker 		port = PORT_MMIO;
131*d83cc019SAndroid Build Coastguard Worker 		reg->mmio_offset = 0;
132*d83cc019SAndroid Build Coastguard Worker 	}
133*d83cc019SAndroid Build Coastguard Worker 
134*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(port_descs); i++) {
135*d83cc019SAndroid Build Coastguard Worker 		if ((port != PORT_NONE && port_descs[i].port == port) ||
136*d83cc019SAndroid Build Coastguard Worker 		    (s && strcasecmp(s, port_descs[i].name) == 0)) {
137*d83cc019SAndroid Build Coastguard Worker 			reg->port_desc = port_descs[i];
138*d83cc019SAndroid Build Coastguard Worker 			return 0;
139*d83cc019SAndroid Build Coastguard Worker 		}
140*d83cc019SAndroid Build Coastguard Worker 	}
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	return -1;
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker 
skip_space(const char * line)145*d83cc019SAndroid Build Coastguard Worker static const char *skip_space(const char *line)
146*d83cc019SAndroid Build Coastguard Worker {
147*d83cc019SAndroid Build Coastguard Worker 	while (*line && isspace(*line))
148*d83cc019SAndroid Build Coastguard Worker 		line++;
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker 	return line;
151*d83cc019SAndroid Build Coastguard Worker }
152*d83cc019SAndroid Build Coastguard Worker 
ignore_line(const char * line)153*d83cc019SAndroid Build Coastguard Worker static bool ignore_line(const char *line)
154*d83cc019SAndroid Build Coastguard Worker {
155*d83cc019SAndroid Build Coastguard Worker 	line = skip_space(line);
156*d83cc019SAndroid Build Coastguard Worker 
157*d83cc019SAndroid Build Coastguard Worker 	switch (*line) {
158*d83cc019SAndroid Build Coastguard Worker 	case '\0':
159*d83cc019SAndroid Build Coastguard Worker 	case '#':
160*d83cc019SAndroid Build Coastguard Worker 	case ';':
161*d83cc019SAndroid Build Coastguard Worker 		return true;
162*d83cc019SAndroid Build Coastguard Worker 	case '/':
163*d83cc019SAndroid Build Coastguard Worker 		return *(line + 1) == '/';
164*d83cc019SAndroid Build Coastguard Worker 	}
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	return false;
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker 
include_file(const char * line,const char * source)169*d83cc019SAndroid Build Coastguard Worker static char *include_file(const char *line, const char *source)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker 	char *filename, *p;
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker 	line = skip_space(line);
174*d83cc019SAndroid Build Coastguard Worker 	if (*line == '(')
175*d83cc019SAndroid Build Coastguard Worker 		return NULL;
176*d83cc019SAndroid Build Coastguard Worker 
177*d83cc019SAndroid Build Coastguard Worker 	/* this'll be plenty */
178*d83cc019SAndroid Build Coastguard Worker 	filename = malloc(strlen(source) + strlen(line) + 1);
179*d83cc019SAndroid Build Coastguard Worker 	if (!filename)
180*d83cc019SAndroid Build Coastguard Worker 		return NULL;
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	p = strrchr(source, '/');
183*d83cc019SAndroid Build Coastguard Worker 	if (p && *line != '/') {
184*d83cc019SAndroid Build Coastguard Worker 		int len = p - source + 1;
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 		memcpy(filename, source, len);
187*d83cc019SAndroid Build Coastguard Worker 		strcpy(filename + len, line);
188*d83cc019SAndroid Build Coastguard Worker 	} else {
189*d83cc019SAndroid Build Coastguard Worker 		strcpy(filename, line);
190*d83cc019SAndroid Build Coastguard Worker 	}
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	p = strchr(filename, '\n');
193*d83cc019SAndroid Build Coastguard Worker 	if (p)
194*d83cc019SAndroid Build Coastguard Worker 		*p = '\0';
195*d83cc019SAndroid Build Coastguard Worker 
196*d83cc019SAndroid Build Coastguard Worker 	return filename;
197*d83cc019SAndroid Build Coastguard Worker }
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker #define SPC	"[[:space:]]*"
200*d83cc019SAndroid Build Coastguard Worker #define SEP	SPC "," SPC
201*d83cc019SAndroid Build Coastguard Worker #define BEG	"^" SPC "\\(" SPC
202*d83cc019SAndroid Build Coastguard Worker #define END	SPC "\\)" SPC "$"
203*d83cc019SAndroid Build Coastguard Worker #define VALUE	"([[:print:]]*)"
204*d83cc019SAndroid Build Coastguard Worker #define QVALUE	"'" VALUE "'"
205*d83cc019SAndroid Build Coastguard Worker #define REGEXP	BEG QVALUE SEP QVALUE SEP QVALUE END
206*d83cc019SAndroid Build Coastguard Worker 
parse_line(struct reg * reg,const char * line)207*d83cc019SAndroid Build Coastguard Worker static int parse_line(struct reg *reg, const char *line)
208*d83cc019SAndroid Build Coastguard Worker {
209*d83cc019SAndroid Build Coastguard Worker 	static regex_t regex;
210*d83cc019SAndroid Build Coastguard Worker 	static bool initialized = false;
211*d83cc019SAndroid Build Coastguard Worker 	regmatch_t match[4];
212*d83cc019SAndroid Build Coastguard Worker 	int i, ret;
213*d83cc019SAndroid Build Coastguard Worker 
214*d83cc019SAndroid Build Coastguard Worker 	if (!initialized) {
215*d83cc019SAndroid Build Coastguard Worker 		if (regcomp (&regex, REGEXP, REG_EXTENDED)) {
216*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "regcomp %s\n", REGEXP);
217*d83cc019SAndroid Build Coastguard Worker 			return -1;
218*d83cc019SAndroid Build Coastguard Worker 		}
219*d83cc019SAndroid Build Coastguard Worker 		initialized = true;
220*d83cc019SAndroid Build Coastguard Worker 	}
221*d83cc019SAndroid Build Coastguard Worker 
222*d83cc019SAndroid Build Coastguard Worker 	ret = regexec(&regex, line, ARRAY_SIZE(match), match, 0);
223*d83cc019SAndroid Build Coastguard Worker 	if (ret)
224*d83cc019SAndroid Build Coastguard Worker 		ret = -1;
225*d83cc019SAndroid Build Coastguard Worker 
226*d83cc019SAndroid Build Coastguard Worker 	for (i = 1; i < ARRAY_SIZE(match) && ret == 0; i++) {
227*d83cc019SAndroid Build Coastguard Worker 		char *p, *e;
228*d83cc019SAndroid Build Coastguard Worker 
229*d83cc019SAndroid Build Coastguard Worker 		p = strndup(line + match[i].rm_so,
230*d83cc019SAndroid Build Coastguard Worker 			    match[i].rm_eo - match[i].rm_so);
231*d83cc019SAndroid Build Coastguard Worker 
232*d83cc019SAndroid Build Coastguard Worker 		if (i == 1) {
233*d83cc019SAndroid Build Coastguard Worker 			reg->name = p;
234*d83cc019SAndroid Build Coastguard Worker 		} else if (i == 2) {
235*d83cc019SAndroid Build Coastguard Worker 			reg->addr = strtoul(p, &e, 16);
236*d83cc019SAndroid Build Coastguard Worker 			free(p);
237*d83cc019SAndroid Build Coastguard Worker 			if (*e)
238*d83cc019SAndroid Build Coastguard Worker 				ret = -1;
239*d83cc019SAndroid Build Coastguard Worker 		} else if (i == 3) {
240*d83cc019SAndroid Build Coastguard Worker 			ret = parse_port_desc(reg, p);
241*d83cc019SAndroid Build Coastguard Worker 			free(p);
242*d83cc019SAndroid Build Coastguard Worker 		}
243*d83cc019SAndroid Build Coastguard Worker 	}
244*d83cc019SAndroid Build Coastguard Worker 
245*d83cc019SAndroid Build Coastguard Worker 	if (ret)
246*d83cc019SAndroid Build Coastguard Worker 		free(reg->name);
247*d83cc019SAndroid Build Coastguard Worker 
248*d83cc019SAndroid Build Coastguard Worker 	return ret;
249*d83cc019SAndroid Build Coastguard Worker }
250*d83cc019SAndroid Build Coastguard Worker 
parse_file(struct reg ** regs,size_t * nregs,ssize_t index,const char * filename)251*d83cc019SAndroid Build Coastguard Worker static ssize_t parse_file(struct reg **regs, size_t *nregs,
252*d83cc019SAndroid Build Coastguard Worker 			  ssize_t index, const char *filename)
253*d83cc019SAndroid Build Coastguard Worker {
254*d83cc019SAndroid Build Coastguard Worker 	FILE *file;
255*d83cc019SAndroid Build Coastguard Worker 	char *line = NULL, *include;
256*d83cc019SAndroid Build Coastguard Worker 	size_t linesize = 0;
257*d83cc019SAndroid Build Coastguard Worker 	int lineno = 0, r;
258*d83cc019SAndroid Build Coastguard Worker 	ssize_t ret = -1;
259*d83cc019SAndroid Build Coastguard Worker 
260*d83cc019SAndroid Build Coastguard Worker 	file = fopen(filename, "r");
261*d83cc019SAndroid Build Coastguard Worker 	if (!file) {
262*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "Error: fopen '%s': %s\n",
263*d83cc019SAndroid Build Coastguard Worker 			filename, strerror(errno));
264*d83cc019SAndroid Build Coastguard Worker 		return -1;
265*d83cc019SAndroid Build Coastguard Worker 	}
266*d83cc019SAndroid Build Coastguard Worker 
267*d83cc019SAndroid Build Coastguard Worker 	while (getline(&line, &linesize, file) != -1) {
268*d83cc019SAndroid Build Coastguard Worker 		struct reg reg = {};
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 		lineno++;
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 		if (ignore_line(line))
273*d83cc019SAndroid Build Coastguard Worker 			continue;
274*d83cc019SAndroid Build Coastguard Worker 
275*d83cc019SAndroid Build Coastguard Worker 		include = include_file(line, filename);
276*d83cc019SAndroid Build Coastguard Worker 		if (include) {
277*d83cc019SAndroid Build Coastguard Worker 			index = parse_file(regs, nregs, index, include);
278*d83cc019SAndroid Build Coastguard Worker 			free(include);
279*d83cc019SAndroid Build Coastguard Worker 			if (index < 0) {
280*d83cc019SAndroid Build Coastguard Worker 				fprintf(stderr, "Error: %s:%d: %s",
281*d83cc019SAndroid Build Coastguard Worker 					filename, lineno, line);
282*d83cc019SAndroid Build Coastguard Worker 				goto out;
283*d83cc019SAndroid Build Coastguard Worker 			}
284*d83cc019SAndroid Build Coastguard Worker 			continue;
285*d83cc019SAndroid Build Coastguard Worker 		}
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 		r = parse_line(&reg, line);
288*d83cc019SAndroid Build Coastguard Worker 		if (r < 0) {
289*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "Error: %s:%d: %s",
290*d83cc019SAndroid Build Coastguard Worker 				filename, lineno, line);
291*d83cc019SAndroid Build Coastguard Worker 			goto out;
292*d83cc019SAndroid Build Coastguard Worker 		} else if (r) {
293*d83cc019SAndroid Build Coastguard Worker 			continue;
294*d83cc019SAndroid Build Coastguard Worker 		}
295*d83cc019SAndroid Build Coastguard Worker 
296*d83cc019SAndroid Build Coastguard Worker 		if (!*regs || index >= *nregs) {
297*d83cc019SAndroid Build Coastguard Worker 			if (!*regs)
298*d83cc019SAndroid Build Coastguard Worker 				*nregs = 64;
299*d83cc019SAndroid Build Coastguard Worker 			else
300*d83cc019SAndroid Build Coastguard Worker 				*nregs *= 2;
301*d83cc019SAndroid Build Coastguard Worker 
302*d83cc019SAndroid Build Coastguard Worker 			*regs = recalloc(*regs, *nregs, sizeof(**regs));
303*d83cc019SAndroid Build Coastguard Worker 			if (!*regs) {
304*d83cc019SAndroid Build Coastguard Worker 				fprintf(stderr, "Error: %s\n", strerror(ENOMEM));
305*d83cc019SAndroid Build Coastguard Worker 				goto out;
306*d83cc019SAndroid Build Coastguard Worker 			}
307*d83cc019SAndroid Build Coastguard Worker 		}
308*d83cc019SAndroid Build Coastguard Worker 
309*d83cc019SAndroid Build Coastguard Worker 		(*regs)[index++] = reg;
310*d83cc019SAndroid Build Coastguard Worker 	}
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	ret = index;
313*d83cc019SAndroid Build Coastguard Worker 
314*d83cc019SAndroid Build Coastguard Worker out:
315*d83cc019SAndroid Build Coastguard Worker 	free(line);
316*d83cc019SAndroid Build Coastguard Worker 	fclose(file);
317*d83cc019SAndroid Build Coastguard Worker 
318*d83cc019SAndroid Build Coastguard Worker 	return ret;
319*d83cc019SAndroid Build Coastguard Worker }
320*d83cc019SAndroid Build Coastguard Worker 
321*d83cc019SAndroid Build Coastguard Worker /*
322*d83cc019SAndroid Build Coastguard Worker  * Get register definitions from file.
323*d83cc019SAndroid Build Coastguard Worker  */
intel_reg_spec_file(struct reg ** regs,const char * file)324*d83cc019SAndroid Build Coastguard Worker ssize_t intel_reg_spec_file(struct reg **regs, const char *file)
325*d83cc019SAndroid Build Coastguard Worker {
326*d83cc019SAndroid Build Coastguard Worker 	size_t nregs = 0;
327*d83cc019SAndroid Build Coastguard Worker 	*regs = NULL;
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	return parse_file(regs, &nregs, 0, file);
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker 
332*d83cc019SAndroid Build Coastguard Worker /*
333*d83cc019SAndroid Build Coastguard Worker  * Free the memory allocated for register definitions.
334*d83cc019SAndroid Build Coastguard Worker  */
intel_reg_spec_free(struct reg * regs,size_t n)335*d83cc019SAndroid Build Coastguard Worker void intel_reg_spec_free(struct reg *regs, size_t n)
336*d83cc019SAndroid Build Coastguard Worker {
337*d83cc019SAndroid Build Coastguard Worker 	size_t i;
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < n; i++) {
340*d83cc019SAndroid Build Coastguard Worker 		free(regs[i].name);
341*d83cc019SAndroid Build Coastguard Worker 	}
342*d83cc019SAndroid Build Coastguard Worker 	free(regs);
343*d83cc019SAndroid Build Coastguard Worker }
344*d83cc019SAndroid Build Coastguard Worker 
intel_reg_spec_print_ports(void)345*d83cc019SAndroid Build Coastguard Worker void intel_reg_spec_print_ports(void)
346*d83cc019SAndroid Build Coastguard Worker {
347*d83cc019SAndroid Build Coastguard Worker 	int i;
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(port_descs); i++)
350*d83cc019SAndroid Build Coastguard Worker 		printf("%s%s", i == 0 ? "" : ", ", port_descs[i].name);
351*d83cc019SAndroid Build Coastguard Worker }
352