1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Chris Wilson <chris@chris-wilson.co.uk>
25  *
26  */
27 
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <getopt.h>
36 
37 #include <intel_bufmgr.h>
38 
39 struct drm_intel_decode *ctx;
40 
41 static void
read_bin_file(const char * filename)42 read_bin_file(const char * filename)
43 {
44 	uint32_t buf[16384];
45 	int fd, offset, ret;
46 
47 	if (!strcmp(filename, "-"))
48 		fd = fileno(stdin);
49 	else
50 		fd = open (filename, O_RDONLY);
51 	if (fd < 0) {
52 		fprintf (stderr, "Failed to open %s: %s\n",
53 			 filename, strerror (errno));
54 		exit (1);
55 	}
56 
57 	drm_intel_decode_set_dump_past_end(ctx, 1);
58 
59 	offset = 0;
60 	while ((ret = read (fd, buf, sizeof(buf))) > 0) {
61 		drm_intel_decode_set_batch_pointer(ctx, buf, offset, ret/4);
62 		drm_intel_decode(ctx);
63 		offset += ret;
64 	}
65 	close (fd);
66 }
67 
68 static void
read_data_file(const char * filename)69 read_data_file(const char * filename)
70 {
71     FILE *file;
72     uint32_t *data = NULL;
73     int data_size = 0, count = 0, line_number = 0, matched;
74     char *line = NULL;
75     size_t line_size;
76     uint32_t offset, value;
77     uint32_t gtt_offset = 0;
78 
79 	if (!strcmp(filename, "-"))
80 		file = stdin;
81 	else
82 		file = fopen (filename, "r");
83 
84     if (file == NULL) {
85 	fprintf (stderr, "Failed to open %s: %s\n",
86 		 filename, strerror (errno));
87 	exit (1);
88     }
89 
90     while (getline (&line, &line_size, file) > 0) {
91 	line_number++;
92 
93 	matched = sscanf (line, "%08x : %08x", &offset, &value);
94 	if (matched != 2) {
95 	    printf("ignoring line %s", line);
96 
97 	    continue;
98 	}
99 
100 	count++;
101 
102 	if (count > data_size) {
103 	    data_size = data_size ? data_size * 2 : 1024;
104 	    data = realloc (data, data_size * sizeof (uint32_t));
105 	    if (data == NULL) {
106 		fprintf (stderr, "Out of memory.\n");
107 		exit (1);
108 	    }
109 	}
110 
111 	data[count-1] = value;
112     }
113 
114     if (count) {
115 	drm_intel_decode_set_batch_pointer(ctx, data, gtt_offset, count);
116 	drm_intel_decode(ctx);
117     }
118 
119     free (data);
120     free (line);
121 
122     fclose (file);
123 }
124 
125 static void
read_autodetect_file(const char * filename)126 read_autodetect_file(const char * filename)
127 {
128 	int binary = 0, c;
129 	FILE *file;
130 
131 	file = fopen (filename, "r");
132 	if (file == NULL) {
133 		fprintf (stderr, "Failed to open %s: %s\n",
134 			 filename, strerror (errno));
135 		exit (1);
136 	}
137 
138 	while ((c = fgetc(file)) != EOF) {
139 		/* totally lazy binary detector */
140 		if (c < 10) {
141 			binary = 1;
142 			break;
143 		}
144 	}
145 
146 	fclose(file);
147 
148 	if (binary == 1)
149 		read_bin_file(filename);
150 	else
151 		read_data_file(filename);
152 
153 }
154 
155 
156 int
main(int argc,char * argv[])157 main (int argc, char *argv[])
158 {
159 	uint32_t devid = 0xa011;
160 	char *devid_str = NULL;
161 	int i, c;
162 	int option_index = 0;
163 	int binary = -1;
164 
165 	static struct option long_options[] = {
166 		{"devid", 1, 0, 'd'},
167 		{"ascii", 0, 0, 'a'},
168 		{"binary", 0, 0, 'b'},
169 		{ 0 }
170 	};
171 
172 	devid_str = getenv("INTEL_DEVID_OVERRIDE");
173 
174 	while((c = getopt_long(argc, argv, "ad:b",
175 			       long_options, &option_index)) != -1) {
176 		switch(c) {
177 		case 'd':
178 			devid_str = optarg;
179 			break;
180 		case 'b':
181 			binary = 1;
182 			break;
183 		case 'a':
184 			binary = 0;
185 			break;
186 		default:
187 			printf("unkown command options\n");
188 			break;
189 		}
190 	}
191 
192 	if (devid_str)
193 		devid = strtoul(devid_str, NULL, 0);
194 
195 	ctx = drm_intel_decode_context_alloc(devid);
196 
197 	if (optind == argc) {
198 		fprintf(stderr, "no input file given\n");
199 		exit(-1);
200 	}
201 
202 	for (i = optind; i < argc; i++) {
203 		/* For stdin input, let's read as data file */
204 		if (!strcmp(argv[i], "-")) {
205 			read_data_file(argv[i]);
206 			continue;
207 		}
208 		if (binary == 1)
209 			read_bin_file(argv[i]);
210 		else if (binary == 0)
211 			read_data_file(argv[i]);
212 		else
213 			read_autodetect_file(argv[i]);
214 	}
215 
216 	return 0;
217 }
218