File Index
Files and directories
Sign in
FILE

xe_gen_wa_oob.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/xe_gen_wa_oob.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2023 Intel Corporation
  4 */
  5
  6#define _GNU_SOURCE
  7#include <ctype.h>
  8#include <errno.h>
  9#include <stdbool.h>
 10#include <stdio.h>
 11#include <string.h>
 12
 13#define HEADER \
 14	"// SPDX-License-Identifier: MIT\n" \
 15	"\n" \
 16	"/*\n" \
 17	" * DO NOT MODIFY.\n" \
 18	" *\n" \
 19	" * This file was generated from rules: %s\n" \
 20	" */\n" \
 21	"#ifndef _GENERATED_%s_\n" \
 22	"#define _GENERATED_%s_\n" \
 23	"\n" \
 24	"enum {\n"
 25
 26#define FOOTER \
 27	"};\n" \
 28	"\n" \
 29	"#endif\n"
 30
 31static void print_usage(FILE *f, const char *progname)
 32{
 33	fprintf(f, "usage: %s <input-rule-file> <generated-c-source-file> <generated-c-header-file>\n",
 34		progname);
 35}
 36
 37static void print_parse_error(const char *err_msg, const char *line,
 38			      unsigned int lineno)
 39{
 40	fprintf(stderr, "ERROR: %s\nERROR: %u: %.60s\n",
 41		err_msg, lineno, line);
 42}
 43
 44static char *strip(char *line, size_t linelen)
 45{
 46	while (isspace(*(line + linelen)))
 47		linelen--;
 48
 49	line[linelen - 1] = '\0';
 50
 51	return  line + strspn(line, " \f\n\r\t\v");
 52}
 53
 54#define MAX_LINE_LEN 4096
 55static int parse(FILE *input, FILE *csource, FILE *cheader, char *prefix)
 56{
 57	char line[MAX_LINE_LEN + 1];
 58	char *name, *prev_name = NULL, *rules;
 59	unsigned int lineno = 0, idx = 0;
 60
 61	while (fgets(line, sizeof(line), input)) {
 62		size_t linelen;
 63		bool is_continuation;
 64
 65		if (line[0] == '\0' || line[0] == '#' || line[0] == '\n') {
 66			lineno++;
 67			continue;
 68		}
 69
 70		linelen = strlen(line);
 71		if (linelen == MAX_LINE_LEN) {
 72			print_parse_error("line too long", line, lineno);
 73			return -EINVAL;
 74		}
 75
 76		is_continuation = isspace(line[0]);
 77		name = strip(line, linelen);
 78
 79		if (!is_continuation) {
 80			name = strtok(name, " \t");
 81			rules = strtok(NULL, "");
 82		} else {
 83			if (!prev_name) {
 84				print_parse_error("invalid rule continuation",
 85						  line, lineno);
 86				return -EINVAL;
 87			}
 88
 89			rules = name;
 90			name = NULL;
 91		}
 92
 93		if (rules[0] == '\0') {
 94			print_parse_error("invalid empty rule\n", line, lineno);
 95			return -EINVAL;
 96		}
 97
 98		if (name) {
 99			fprintf(cheader, "\t%s_%s = %u,\n", prefix, name, idx);
100
101			/* Close previous entry before starting a new one */
102			if (idx)
103				fprintf(csource, ") },\n");
104
105			fprintf(csource, "{ XE_RTP_NAME(\"%s\"),\n  XE_RTP_RULES(%s",
106				name, rules);
107			idx++;
108		} else {
109			fprintf(csource, ", OR,\n\t%s", rules);
110		}
111
112		lineno++;
113		if (!is_continuation)
114			prev_name = name;
115	}
116
117	/* Close last entry */
118	if (idx)
119		fprintf(csource, ") },\n");
120
121	fprintf(cheader, "\t_%s_COUNT = %u\n", prefix, idx);
122
123	return 0;
124}
125
126/* Avoid GNU vs POSIX basename() discrepancy, just use our own */
127static const char *xbasename(const char *s)
128{
129	const char *p = strrchr(s, '/');
130
131	return p ? p + 1 : s;
132}
133
134static int fn_to_prefix(const char *fn, char *prefix, size_t size)
135{
136	size_t len;
137
138	fn = xbasename(fn);
139	len = strlen(fn);
140
141	if (len > size - 1)
142		return -ENAMETOOLONG;
143
144	memcpy(prefix, fn, len + 1);
145
146	for (char *p = prefix; *p; p++) {
147		switch (*p) {
148		case '.':
149			*p = '\0';
150			return 0;
151		default:
152			*p = toupper(*p);
153			break;
154		}
155	}
156
157	return 0;
158}
159
160int main(int argc, const char *argv[])
161{
162	enum {
163		ARGS_INPUT,
164		ARGS_CSOURCE,
165		ARGS_CHEADER,
166		_ARGS_COUNT
167	};
168	struct {
169		const char *fn;
170		const char *mode;
171		FILE *f;
172	} args[] = {
173		[ARGS_INPUT] = { .fn = argv[1], .mode = "r" },
174		[ARGS_CSOURCE] = { .fn = argv[2], .mode = "w" },
175		[ARGS_CHEADER] = { .fn = argv[3], .mode = "w" },
176	};
177	int ret = 1;
178	char prefix[128];
179
180	if (argc < 3) {
181		fprintf(stderr, "ERROR: wrong arguments\n");
182		print_usage(stderr, argv[0]);
183		return 1;
184	}
185
186	if (fn_to_prefix(args[ARGS_CHEADER].fn, prefix, sizeof(prefix)) < 0)
187		return 1;
188
189	for (int i = 0; i < _ARGS_COUNT; i++) {
190		args[i].f = fopen(args[i].fn, args[i].mode);
191		if (!args[i].f) {
192			fprintf(stderr, "ERROR: Can't open %s: %m\n",
193				args[i].fn);
194			goto err;
195		}
196	}
197
198	fprintf(args[ARGS_CHEADER].f, HEADER, args[ARGS_INPUT].fn, prefix, prefix);
199
200	ret = parse(args[ARGS_INPUT].f, args[ARGS_CSOURCE].f,
201		    args[ARGS_CHEADER].f, prefix);
202	if (!ret)
203		fprintf(args[ARGS_CHEADER].f, FOOTER);
204
205err:
206	for (int i = 0; i < _ARGS_COUNT; i++) {
207		if (args[i].f)
208			fclose(args[i].f);
209	}
210
211	return ret;
212}
~/ Read-only file preview.