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 <errno.h>
25*d83cc019SAndroid Build Coastguard Worker #include <getopt.h>
26*d83cc019SAndroid Build Coastguard Worker #include <limits.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <string.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
33*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
34*d83cc019SAndroid Build Coastguard Worker
35*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
36*d83cc019SAndroid Build Coastguard Worker #include "igt_gt.h"
37*d83cc019SAndroid Build Coastguard Worker #include "intel_io.h"
38*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
39*d83cc019SAndroid Build Coastguard Worker
40*d83cc019SAndroid Build Coastguard Worker #include "intel_reg_spec.h"
41*d83cc019SAndroid Build Coastguard Worker
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker #ifdef HAVE_SYS_IO_H
44*d83cc019SAndroid Build Coastguard Worker #include <sys/io.h>
45*d83cc019SAndroid Build Coastguard Worker #else
46*d83cc019SAndroid Build Coastguard Worker
_not_supported(void)47*d83cc019SAndroid Build Coastguard Worker static inline int _not_supported(void)
48*d83cc019SAndroid Build Coastguard Worker {
49*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "portio-vga not supported\n");
50*d83cc019SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
51*d83cc019SAndroid Build Coastguard Worker }
52*d83cc019SAndroid Build Coastguard Worker #define inb(port) _not_supported()
53*d83cc019SAndroid Build Coastguard Worker #define outb(value, port) _not_supported()
54*d83cc019SAndroid Build Coastguard Worker #define iopl(level)
55*d83cc019SAndroid Build Coastguard Worker
56*d83cc019SAndroid Build Coastguard Worker #endif /* HAVE_SYS_IO_H */
57*d83cc019SAndroid Build Coastguard Worker
58*d83cc019SAndroid Build Coastguard Worker struct config {
59*d83cc019SAndroid Build Coastguard Worker struct pci_device *pci_dev;
60*d83cc019SAndroid Build Coastguard Worker char *mmiofile;
61*d83cc019SAndroid Build Coastguard Worker uint32_t devid;
62*d83cc019SAndroid Build Coastguard Worker
63*d83cc019SAndroid Build Coastguard Worker /* read: number of registers to read */
64*d83cc019SAndroid Build Coastguard Worker uint32_t count;
65*d83cc019SAndroid Build Coastguard Worker
66*d83cc019SAndroid Build Coastguard Worker /* write: do a posting read */
67*d83cc019SAndroid Build Coastguard Worker bool post;
68*d83cc019SAndroid Build Coastguard Worker
69*d83cc019SAndroid Build Coastguard Worker /* decode register for all platforms */
70*d83cc019SAndroid Build Coastguard Worker bool all_platforms;
71*d83cc019SAndroid Build Coastguard Worker
72*d83cc019SAndroid Build Coastguard Worker /* spread out bits for convenience */
73*d83cc019SAndroid Build Coastguard Worker bool binary;
74*d83cc019SAndroid Build Coastguard Worker
75*d83cc019SAndroid Build Coastguard Worker /* register spec */
76*d83cc019SAndroid Build Coastguard Worker char *specfile;
77*d83cc019SAndroid Build Coastguard Worker
78*d83cc019SAndroid Build Coastguard Worker /* fd for engine access avoiding reopens */
79*d83cc019SAndroid Build Coastguard Worker int fd;
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker struct reg *regs;
82*d83cc019SAndroid Build Coastguard Worker ssize_t regcount;
83*d83cc019SAndroid Build Coastguard Worker
84*d83cc019SAndroid Build Coastguard Worker int verbosity;
85*d83cc019SAndroid Build Coastguard Worker };
86*d83cc019SAndroid Build Coastguard Worker
87*d83cc019SAndroid Build Coastguard Worker /* port desc must have been set */
set_reg_by_addr(struct config * config,struct reg * reg,uint32_t addr)88*d83cc019SAndroid Build Coastguard Worker static int set_reg_by_addr(struct config *config, struct reg *reg,
89*d83cc019SAndroid Build Coastguard Worker uint32_t addr)
90*d83cc019SAndroid Build Coastguard Worker {
91*d83cc019SAndroid Build Coastguard Worker int i;
92*d83cc019SAndroid Build Coastguard Worker
93*d83cc019SAndroid Build Coastguard Worker reg->addr = addr;
94*d83cc019SAndroid Build Coastguard Worker if (reg->name)
95*d83cc019SAndroid Build Coastguard Worker free(reg->name);
96*d83cc019SAndroid Build Coastguard Worker reg->name = NULL;
97*d83cc019SAndroid Build Coastguard Worker
98*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < config->regcount; i++) {
99*d83cc019SAndroid Build Coastguard Worker struct reg *r = &config->regs[i];
100*d83cc019SAndroid Build Coastguard Worker
101*d83cc019SAndroid Build Coastguard Worker if (reg->port_desc.port != r->port_desc.port)
102*d83cc019SAndroid Build Coastguard Worker continue;
103*d83cc019SAndroid Build Coastguard Worker
104*d83cc019SAndroid Build Coastguard Worker /* ->mmio_offset should be 0 for non-MMIO ports. */
105*d83cc019SAndroid Build Coastguard Worker if (addr + reg->mmio_offset == r->addr + r->mmio_offset) {
106*d83cc019SAndroid Build Coastguard Worker /* Always output the "normalized" offset+addr. */
107*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = r->mmio_offset;
108*d83cc019SAndroid Build Coastguard Worker reg->addr = r->addr;
109*d83cc019SAndroid Build Coastguard Worker
110*d83cc019SAndroid Build Coastguard Worker reg->name = r->name ? strdup(r->name) : NULL;
111*d83cc019SAndroid Build Coastguard Worker break;
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker }
114*d83cc019SAndroid Build Coastguard Worker
115*d83cc019SAndroid Build Coastguard Worker return 0;
116*d83cc019SAndroid Build Coastguard Worker }
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker /* port desc must have been set */
set_reg_by_name(struct config * config,struct reg * reg,const char * name)119*d83cc019SAndroid Build Coastguard Worker static int set_reg_by_name(struct config *config, struct reg *reg,
120*d83cc019SAndroid Build Coastguard Worker const char *name)
121*d83cc019SAndroid Build Coastguard Worker {
122*d83cc019SAndroid Build Coastguard Worker int i;
123*d83cc019SAndroid Build Coastguard Worker
124*d83cc019SAndroid Build Coastguard Worker reg->name = strdup(name);
125*d83cc019SAndroid Build Coastguard Worker reg->addr = 0;
126*d83cc019SAndroid Build Coastguard Worker
127*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < config->regcount; i++) {
128*d83cc019SAndroid Build Coastguard Worker struct reg *r = &config->regs[i];
129*d83cc019SAndroid Build Coastguard Worker
130*d83cc019SAndroid Build Coastguard Worker if (reg->port_desc.port != r->port_desc.port)
131*d83cc019SAndroid Build Coastguard Worker continue;
132*d83cc019SAndroid Build Coastguard Worker
133*d83cc019SAndroid Build Coastguard Worker if (!r->name)
134*d83cc019SAndroid Build Coastguard Worker continue;
135*d83cc019SAndroid Build Coastguard Worker
136*d83cc019SAndroid Build Coastguard Worker if (strcasecmp(name, r->name) == 0) {
137*d83cc019SAndroid Build Coastguard Worker reg->addr = r->addr;
138*d83cc019SAndroid Build Coastguard Worker
139*d83cc019SAndroid Build Coastguard Worker /* Also get MMIO offset if not already specified. */
140*d83cc019SAndroid Build Coastguard Worker if (!reg->mmio_offset && r->mmio_offset)
141*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = r->mmio_offset;
142*d83cc019SAndroid Build Coastguard Worker
143*d83cc019SAndroid Build Coastguard Worker return 0;
144*d83cc019SAndroid Build Coastguard Worker }
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker
147*d83cc019SAndroid Build Coastguard Worker return -1;
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker
to_binary(char * buf,size_t buflen,uint32_t val)150*d83cc019SAndroid Build Coastguard Worker static void to_binary(char *buf, size_t buflen, uint32_t val)
151*d83cc019SAndroid Build Coastguard Worker {
152*d83cc019SAndroid Build Coastguard Worker int i;
153*d83cc019SAndroid Build Coastguard Worker
154*d83cc019SAndroid Build Coastguard Worker if (!buflen)
155*d83cc019SAndroid Build Coastguard Worker return;
156*d83cc019SAndroid Build Coastguard Worker
157*d83cc019SAndroid Build Coastguard Worker *buf = '\0';
158*d83cc019SAndroid Build Coastguard Worker
159*d83cc019SAndroid Build Coastguard Worker /* XXX: This quick and dirty implementation makes eyes hurt. */
160*d83cc019SAndroid Build Coastguard Worker for (i = 31; i >= 0; i--) {
161*d83cc019SAndroid Build Coastguard Worker if (i % 8 == 0)
162*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, " %2d", i);
163*d83cc019SAndroid Build Coastguard Worker else
164*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, " ");
165*d83cc019SAndroid Build Coastguard Worker buflen -= strlen(buf);
166*d83cc019SAndroid Build Coastguard Worker buf += strlen(buf);
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, "\n");
169*d83cc019SAndroid Build Coastguard Worker buflen -= strlen(buf);
170*d83cc019SAndroid Build Coastguard Worker buf += strlen(buf);
171*d83cc019SAndroid Build Coastguard Worker
172*d83cc019SAndroid Build Coastguard Worker for (i = 31; i >= 0; i--) {
173*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, " %s%d", i % 8 == 7 ? " " : "",
174*d83cc019SAndroid Build Coastguard Worker !!(val & (1 << i)));
175*d83cc019SAndroid Build Coastguard Worker buflen -= strlen(buf);
176*d83cc019SAndroid Build Coastguard Worker buf += strlen(buf);
177*d83cc019SAndroid Build Coastguard Worker }
178*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, "\n");
179*d83cc019SAndroid Build Coastguard Worker }
180*d83cc019SAndroid Build Coastguard Worker
dump_decode(struct config * config,struct reg * reg,uint32_t val)181*d83cc019SAndroid Build Coastguard Worker static void dump_decode(struct config *config, struct reg *reg, uint32_t val)
182*d83cc019SAndroid Build Coastguard Worker {
183*d83cc019SAndroid Build Coastguard Worker char decode[1300];
184*d83cc019SAndroid Build Coastguard Worker char tmp[1024];
185*d83cc019SAndroid Build Coastguard Worker char bin[200];
186*d83cc019SAndroid Build Coastguard Worker
187*d83cc019SAndroid Build Coastguard Worker if (config->binary)
188*d83cc019SAndroid Build Coastguard Worker to_binary(bin, sizeof(bin), val);
189*d83cc019SAndroid Build Coastguard Worker else
190*d83cc019SAndroid Build Coastguard Worker *bin = '\0';
191*d83cc019SAndroid Build Coastguard Worker
192*d83cc019SAndroid Build Coastguard Worker intel_reg_spec_decode(tmp, sizeof(tmp), reg, val,
193*d83cc019SAndroid Build Coastguard Worker config->all_platforms ? 0 : config->devid);
194*d83cc019SAndroid Build Coastguard Worker
195*d83cc019SAndroid Build Coastguard Worker if (*tmp) {
196*d83cc019SAndroid Build Coastguard Worker /* We have a decode result, and maybe binary decode. */
197*d83cc019SAndroid Build Coastguard Worker if (config->all_platforms)
198*d83cc019SAndroid Build Coastguard Worker snprintf(decode, sizeof(decode), "\n%s%s", tmp, bin);
199*d83cc019SAndroid Build Coastguard Worker else
200*d83cc019SAndroid Build Coastguard Worker snprintf(decode, sizeof(decode), " (%s)\n%s", tmp, bin);
201*d83cc019SAndroid Build Coastguard Worker } else if (*bin) {
202*d83cc019SAndroid Build Coastguard Worker /* No decode result, but binary decode. */
203*d83cc019SAndroid Build Coastguard Worker snprintf(decode, sizeof(decode), "\n%s", bin);
204*d83cc019SAndroid Build Coastguard Worker } else {
205*d83cc019SAndroid Build Coastguard Worker /* No decode nor binary decode. */
206*d83cc019SAndroid Build Coastguard Worker snprintf(decode, sizeof(decode), "\n");
207*d83cc019SAndroid Build Coastguard Worker }
208*d83cc019SAndroid Build Coastguard Worker
209*d83cc019SAndroid Build Coastguard Worker if (reg->port_desc.port == PORT_MMIO) {
210*d83cc019SAndroid Build Coastguard Worker /* Omit port name for MMIO, optionally include MMIO offset. */
211*d83cc019SAndroid Build Coastguard Worker if (reg->mmio_offset)
212*d83cc019SAndroid Build Coastguard Worker printf("%24s (0x%08x:0x%08x): 0x%08x%s",
213*d83cc019SAndroid Build Coastguard Worker reg->name ?: "",
214*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset, reg->addr,
215*d83cc019SAndroid Build Coastguard Worker val, decode);
216*d83cc019SAndroid Build Coastguard Worker else
217*d83cc019SAndroid Build Coastguard Worker printf("%35s (0x%08x): 0x%08x%s",
218*d83cc019SAndroid Build Coastguard Worker reg->name ?: "",
219*d83cc019SAndroid Build Coastguard Worker reg->addr,
220*d83cc019SAndroid Build Coastguard Worker val, decode);
221*d83cc019SAndroid Build Coastguard Worker } else {
222*d83cc019SAndroid Build Coastguard Worker char name[100], addr[100];
223*d83cc019SAndroid Build Coastguard Worker
224*d83cc019SAndroid Build Coastguard Worker /* If no name, use addr as name for easier copy pasting. */
225*d83cc019SAndroid Build Coastguard Worker if (reg->name)
226*d83cc019SAndroid Build Coastguard Worker snprintf(name, sizeof(name), "%s:%s",
227*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name, reg->name);
228*d83cc019SAndroid Build Coastguard Worker else
229*d83cc019SAndroid Build Coastguard Worker snprintf(name, sizeof(name), "%s:0x%08x",
230*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name, reg->addr);
231*d83cc019SAndroid Build Coastguard Worker
232*d83cc019SAndroid Build Coastguard Worker /* Negative port numbers are not real sideband ports. */
233*d83cc019SAndroid Build Coastguard Worker if (reg->port_desc.port > PORT_NONE)
234*d83cc019SAndroid Build Coastguard Worker snprintf(addr, sizeof(addr), "0x%02x:0x%08x",
235*d83cc019SAndroid Build Coastguard Worker reg->port_desc.port, reg->addr);
236*d83cc019SAndroid Build Coastguard Worker else
237*d83cc019SAndroid Build Coastguard Worker snprintf(addr, sizeof(addr), "%s:0x%08x",
238*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name, reg->addr);
239*d83cc019SAndroid Build Coastguard Worker
240*d83cc019SAndroid Build Coastguard Worker printf("%24s (%s): 0x%08x%s", name, addr, val, decode);
241*d83cc019SAndroid Build Coastguard Worker }
242*d83cc019SAndroid Build Coastguard Worker }
243*d83cc019SAndroid Build Coastguard Worker
find_engine(const char * name)244*d83cc019SAndroid Build Coastguard Worker static const struct intel_execution_engine2 *find_engine(const char *name)
245*d83cc019SAndroid Build Coastguard Worker {
246*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 *e;
247*d83cc019SAndroid Build Coastguard Worker
248*d83cc019SAndroid Build Coastguard Worker if (strlen(name) < 2)
249*d83cc019SAndroid Build Coastguard Worker return NULL;
250*d83cc019SAndroid Build Coastguard Worker
251*d83cc019SAndroid Build Coastguard Worker if (name[0] == '-')
252*d83cc019SAndroid Build Coastguard Worker name++;
253*d83cc019SAndroid Build Coastguard Worker
254*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines2; e->name; e++) {
255*d83cc019SAndroid Build Coastguard Worker if (!strcasecmp(e->name, name))
256*d83cc019SAndroid Build Coastguard Worker return e;
257*d83cc019SAndroid Build Coastguard Worker }
258*d83cc019SAndroid Build Coastguard Worker
259*d83cc019SAndroid Build Coastguard Worker return NULL;
260*d83cc019SAndroid Build Coastguard Worker }
261*d83cc019SAndroid Build Coastguard Worker
register_srm(struct config * config,struct reg * reg,uint32_t * val_in)262*d83cc019SAndroid Build Coastguard Worker static int register_srm(struct config *config, struct reg *reg,
263*d83cc019SAndroid Build Coastguard Worker uint32_t *val_in)
264*d83cc019SAndroid Build Coastguard Worker {
265*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(config->devid);
266*d83cc019SAndroid Build Coastguard Worker const bool r64b = gen >= 8;
267*d83cc019SAndroid Build Coastguard Worker const uint32_t ctx = 0;
268*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
269*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[1];
270*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
271*d83cc019SAndroid Build Coastguard Worker uint32_t *batch, *r;
272*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 *engine;
273*d83cc019SAndroid Build Coastguard Worker bool secure;
274*d83cc019SAndroid Build Coastguard Worker int fd, i;
275*d83cc019SAndroid Build Coastguard Worker uint32_t val;
276*d83cc019SAndroid Build Coastguard Worker
277*d83cc019SAndroid Build Coastguard Worker if (config->fd == -1) {
278*d83cc019SAndroid Build Coastguard Worker config->fd = __drm_open_driver(DRIVER_INTEL);
279*d83cc019SAndroid Build Coastguard Worker if (config->fd == -1) {
280*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error opening driver: %s",
281*d83cc019SAndroid Build Coastguard Worker strerror(errno));
282*d83cc019SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
283*d83cc019SAndroid Build Coastguard Worker }
284*d83cc019SAndroid Build Coastguard Worker }
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker fd = config->fd;
287*d83cc019SAndroid Build Coastguard Worker engine = find_engine(reg->engine);
288*d83cc019SAndroid Build Coastguard Worker if (engine == NULL)
289*d83cc019SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
290*d83cc019SAndroid Build Coastguard Worker
291*d83cc019SAndroid Build Coastguard Worker secure = reg->engine[0] != '-';
292*d83cc019SAndroid Build Coastguard Worker
293*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
294*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
295*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 4096);
296*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(reloc);
297*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 1;
298*d83cc019SAndroid Build Coastguard Worker
299*d83cc019SAndroid Build Coastguard Worker batch = gem_mmap__cpu(fd, obj[1].handle, 0, 4096, PROT_WRITE);
300*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[1].handle,
301*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
302*d83cc019SAndroid Build Coastguard Worker
303*d83cc019SAndroid Build Coastguard Worker i = 0;
304*d83cc019SAndroid Build Coastguard Worker if (val_in) {
305*d83cc019SAndroid Build Coastguard Worker batch[i++] = MI_NOOP;
306*d83cc019SAndroid Build Coastguard Worker batch[i++] = MI_NOOP;
307*d83cc019SAndroid Build Coastguard Worker
308*d83cc019SAndroid Build Coastguard Worker batch[i++] = MI_LOAD_REGISTER_IMM;
309*d83cc019SAndroid Build Coastguard Worker batch[i++] = reg->addr;
310*d83cc019SAndroid Build Coastguard Worker batch[i++] = *val_in;
311*d83cc019SAndroid Build Coastguard Worker batch[i++] = MI_NOOP;
312*d83cc019SAndroid Build Coastguard Worker }
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker batch[i++] = 0x24 << 23 | (1 + r64b); /* SRM */
315*d83cc019SAndroid Build Coastguard Worker batch[i++] = reg->addr;
316*d83cc019SAndroid Build Coastguard Worker reloc[0].target_handle = obj[0].handle;
317*d83cc019SAndroid Build Coastguard Worker reloc[0].presumed_offset = obj[0].offset;
318*d83cc019SAndroid Build Coastguard Worker reloc[0].offset = i * sizeof(uint32_t);
319*d83cc019SAndroid Build Coastguard Worker reloc[0].delta = 0;
320*d83cc019SAndroid Build Coastguard Worker reloc[0].read_domains = I915_GEM_DOMAIN_RENDER;
321*d83cc019SAndroid Build Coastguard Worker reloc[0].write_domain = I915_GEM_DOMAIN_RENDER;
322*d83cc019SAndroid Build Coastguard Worker batch[i++] = reloc[0].delta;
323*d83cc019SAndroid Build Coastguard Worker if (r64b)
324*d83cc019SAndroid Build Coastguard Worker batch[i++] = 0;
325*d83cc019SAndroid Build Coastguard Worker
326*d83cc019SAndroid Build Coastguard Worker batch[i++] = MI_BATCH_BUFFER_END;
327*d83cc019SAndroid Build Coastguard Worker munmap(batch, 4096);
328*d83cc019SAndroid Build Coastguard Worker
329*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
330*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
331*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
332*d83cc019SAndroid Build Coastguard Worker execbuf.flags = engine->flags;
333*d83cc019SAndroid Build Coastguard Worker if (secure)
334*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
335*d83cc019SAndroid Build Coastguard Worker
336*d83cc019SAndroid Build Coastguard Worker if (config->verbosity > 0)
337*d83cc019SAndroid Build Coastguard Worker printf("%s: using %sprivileged batch\n",
338*d83cc019SAndroid Build Coastguard Worker engine->name,
339*d83cc019SAndroid Build Coastguard Worker secure ? "" : "non-");
340*d83cc019SAndroid Build Coastguard Worker
341*d83cc019SAndroid Build Coastguard Worker execbuf.rsvd1 = ctx;
342*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
343*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker r = gem_mmap__cpu(fd, obj[0].handle, 0, 4096, PROT_READ);
346*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj[0].handle, I915_GEM_DOMAIN_CPU, 0);
347*d83cc019SAndroid Build Coastguard Worker
348*d83cc019SAndroid Build Coastguard Worker val = r[0];
349*d83cc019SAndroid Build Coastguard Worker munmap(r, 4096);
350*d83cc019SAndroid Build Coastguard Worker
351*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[0].handle);
352*d83cc019SAndroid Build Coastguard Worker
353*d83cc019SAndroid Build Coastguard Worker return val;
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker
read_register(struct config * config,struct reg * reg,uint32_t * valp)356*d83cc019SAndroid Build Coastguard Worker static int read_register(struct config *config, struct reg *reg, uint32_t *valp)
357*d83cc019SAndroid Build Coastguard Worker {
358*d83cc019SAndroid Build Coastguard Worker uint32_t val = 0;
359*d83cc019SAndroid Build Coastguard Worker
360*d83cc019SAndroid Build Coastguard Worker switch (reg->port_desc.port) {
361*d83cc019SAndroid Build Coastguard Worker case PORT_MMIO:
362*d83cc019SAndroid Build Coastguard Worker if (reg->engine)
363*d83cc019SAndroid Build Coastguard Worker val = register_srm(config, reg, NULL);
364*d83cc019SAndroid Build Coastguard Worker else
365*d83cc019SAndroid Build Coastguard Worker val = INREG(reg->mmio_offset + reg->addr);
366*d83cc019SAndroid Build Coastguard Worker break;
367*d83cc019SAndroid Build Coastguard Worker case PORT_PORTIO_VGA:
368*d83cc019SAndroid Build Coastguard Worker iopl(3);
369*d83cc019SAndroid Build Coastguard Worker val = inb(reg->addr);
370*d83cc019SAndroid Build Coastguard Worker iopl(0);
371*d83cc019SAndroid Build Coastguard Worker break;
372*d83cc019SAndroid Build Coastguard Worker case PORT_MMIO_VGA:
373*d83cc019SAndroid Build Coastguard Worker val = INREG8(reg->addr);
374*d83cc019SAndroid Build Coastguard Worker break;
375*d83cc019SAndroid Build Coastguard Worker case PORT_BUNIT:
376*d83cc019SAndroid Build Coastguard Worker case PORT_PUNIT:
377*d83cc019SAndroid Build Coastguard Worker case PORT_NC:
378*d83cc019SAndroid Build Coastguard Worker case PORT_DPIO:
379*d83cc019SAndroid Build Coastguard Worker case PORT_GPIO_NC:
380*d83cc019SAndroid Build Coastguard Worker case PORT_CCK:
381*d83cc019SAndroid Build Coastguard Worker case PORT_CCU:
382*d83cc019SAndroid Build Coastguard Worker case PORT_DPIO2:
383*d83cc019SAndroid Build Coastguard Worker case PORT_FLISDSI:
384*d83cc019SAndroid Build Coastguard Worker if (!IS_VALLEYVIEW(config->devid) &&
385*d83cc019SAndroid Build Coastguard Worker !IS_CHERRYVIEW(config->devid)) {
386*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "port %s only supported on vlv/chv\n",
387*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name);
388*d83cc019SAndroid Build Coastguard Worker return -1;
389*d83cc019SAndroid Build Coastguard Worker }
390*d83cc019SAndroid Build Coastguard Worker val = intel_iosf_sb_read(reg->port_desc.port, reg->addr);
391*d83cc019SAndroid Build Coastguard Worker break;
392*d83cc019SAndroid Build Coastguard Worker default:
393*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "port %d not supported\n", reg->port_desc.port);
394*d83cc019SAndroid Build Coastguard Worker return -1;
395*d83cc019SAndroid Build Coastguard Worker }
396*d83cc019SAndroid Build Coastguard Worker
397*d83cc019SAndroid Build Coastguard Worker if (valp)
398*d83cc019SAndroid Build Coastguard Worker *valp = val;
399*d83cc019SAndroid Build Coastguard Worker
400*d83cc019SAndroid Build Coastguard Worker return 0;
401*d83cc019SAndroid Build Coastguard Worker }
402*d83cc019SAndroid Build Coastguard Worker
dump_register(struct config * config,struct reg * reg)403*d83cc019SAndroid Build Coastguard Worker static void dump_register(struct config *config, struct reg *reg)
404*d83cc019SAndroid Build Coastguard Worker {
405*d83cc019SAndroid Build Coastguard Worker uint32_t val;
406*d83cc019SAndroid Build Coastguard Worker
407*d83cc019SAndroid Build Coastguard Worker if (read_register(config, reg, &val) == 0)
408*d83cc019SAndroid Build Coastguard Worker dump_decode(config, reg, val);
409*d83cc019SAndroid Build Coastguard Worker }
410*d83cc019SAndroid Build Coastguard Worker
write_register(struct config * config,struct reg * reg,uint32_t val)411*d83cc019SAndroid Build Coastguard Worker static int write_register(struct config *config, struct reg *reg, uint32_t val)
412*d83cc019SAndroid Build Coastguard Worker {
413*d83cc019SAndroid Build Coastguard Worker int ret = 0;
414*d83cc019SAndroid Build Coastguard Worker
415*d83cc019SAndroid Build Coastguard Worker if (config->verbosity > 0) {
416*d83cc019SAndroid Build Coastguard Worker printf("Before:\n");
417*d83cc019SAndroid Build Coastguard Worker dump_register(config, reg);
418*d83cc019SAndroid Build Coastguard Worker }
419*d83cc019SAndroid Build Coastguard Worker
420*d83cc019SAndroid Build Coastguard Worker switch (reg->port_desc.port) {
421*d83cc019SAndroid Build Coastguard Worker case PORT_MMIO:
422*d83cc019SAndroid Build Coastguard Worker if (reg->engine) {
423*d83cc019SAndroid Build Coastguard Worker register_srm(config, reg, &val);
424*d83cc019SAndroid Build Coastguard Worker } else {
425*d83cc019SAndroid Build Coastguard Worker OUTREG(reg->mmio_offset + reg->addr, val);
426*d83cc019SAndroid Build Coastguard Worker }
427*d83cc019SAndroid Build Coastguard Worker break;
428*d83cc019SAndroid Build Coastguard Worker case PORT_PORTIO_VGA:
429*d83cc019SAndroid Build Coastguard Worker if (val > 0xff) {
430*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "value 0x%08x out of range for port %s\n",
431*d83cc019SAndroid Build Coastguard Worker val, reg->port_desc.name);
432*d83cc019SAndroid Build Coastguard Worker return -1;
433*d83cc019SAndroid Build Coastguard Worker }
434*d83cc019SAndroid Build Coastguard Worker iopl(3);
435*d83cc019SAndroid Build Coastguard Worker outb(val, reg->addr);
436*d83cc019SAndroid Build Coastguard Worker iopl(0);
437*d83cc019SAndroid Build Coastguard Worker break;
438*d83cc019SAndroid Build Coastguard Worker case PORT_MMIO_VGA:
439*d83cc019SAndroid Build Coastguard Worker if (val > 0xff) {
440*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "value 0x%08x out of range for port %s\n",
441*d83cc019SAndroid Build Coastguard Worker val, reg->port_desc.name);
442*d83cc019SAndroid Build Coastguard Worker return -1;
443*d83cc019SAndroid Build Coastguard Worker }
444*d83cc019SAndroid Build Coastguard Worker OUTREG8(reg->addr, val);
445*d83cc019SAndroid Build Coastguard Worker break;
446*d83cc019SAndroid Build Coastguard Worker case PORT_BUNIT:
447*d83cc019SAndroid Build Coastguard Worker case PORT_PUNIT:
448*d83cc019SAndroid Build Coastguard Worker case PORT_NC:
449*d83cc019SAndroid Build Coastguard Worker case PORT_DPIO:
450*d83cc019SAndroid Build Coastguard Worker case PORT_GPIO_NC:
451*d83cc019SAndroid Build Coastguard Worker case PORT_CCK:
452*d83cc019SAndroid Build Coastguard Worker case PORT_CCU:
453*d83cc019SAndroid Build Coastguard Worker case PORT_DPIO2:
454*d83cc019SAndroid Build Coastguard Worker case PORT_FLISDSI:
455*d83cc019SAndroid Build Coastguard Worker if (!IS_VALLEYVIEW(config->devid) &&
456*d83cc019SAndroid Build Coastguard Worker !IS_CHERRYVIEW(config->devid)) {
457*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "port %s only supported on vlv/chv\n",
458*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name);
459*d83cc019SAndroid Build Coastguard Worker return -1;
460*d83cc019SAndroid Build Coastguard Worker }
461*d83cc019SAndroid Build Coastguard Worker intel_iosf_sb_write(reg->port_desc.port, reg->addr, val);
462*d83cc019SAndroid Build Coastguard Worker break;
463*d83cc019SAndroid Build Coastguard Worker default:
464*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "port %d not supported\n", reg->port_desc.port);
465*d83cc019SAndroid Build Coastguard Worker ret = -1;
466*d83cc019SAndroid Build Coastguard Worker }
467*d83cc019SAndroid Build Coastguard Worker
468*d83cc019SAndroid Build Coastguard Worker if (config->verbosity > 0) {
469*d83cc019SAndroid Build Coastguard Worker printf("After:\n");
470*d83cc019SAndroid Build Coastguard Worker dump_register(config, reg);
471*d83cc019SAndroid Build Coastguard Worker } else if (config->post) {
472*d83cc019SAndroid Build Coastguard Worker read_register(config, reg, NULL);
473*d83cc019SAndroid Build Coastguard Worker }
474*d83cc019SAndroid Build Coastguard Worker
475*d83cc019SAndroid Build Coastguard Worker return ret;
476*d83cc019SAndroid Build Coastguard Worker }
477*d83cc019SAndroid Build Coastguard Worker
parse_engine(struct reg * reg,const char * s)478*d83cc019SAndroid Build Coastguard Worker static int parse_engine(struct reg *reg, const char *s)
479*d83cc019SAndroid Build Coastguard Worker {
480*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 *e;
481*d83cc019SAndroid Build Coastguard Worker
482*d83cc019SAndroid Build Coastguard Worker e = find_engine(s);
483*d83cc019SAndroid Build Coastguard Worker if (e) {
484*d83cc019SAndroid Build Coastguard Worker reg->port_desc.port = PORT_MMIO;
485*d83cc019SAndroid Build Coastguard Worker reg->port_desc.name = strdup(s);
486*d83cc019SAndroid Build Coastguard Worker reg->port_desc.stride = 4;
487*d83cc019SAndroid Build Coastguard Worker reg->engine = strdup(s);
488*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = 0;
489*d83cc019SAndroid Build Coastguard Worker } else {
490*d83cc019SAndroid Build Coastguard Worker reg->engine = NULL;
491*d83cc019SAndroid Build Coastguard Worker }
492*d83cc019SAndroid Build Coastguard Worker
493*d83cc019SAndroid Build Coastguard Worker return reg->engine == NULL;
494*d83cc019SAndroid Build Coastguard Worker }
495*d83cc019SAndroid Build Coastguard Worker
496*d83cc019SAndroid Build Coastguard Worker /* s has [(PORTNAME|PORTNUM|ENGINE|MMIO-OFFSET):](REGNAME|REGADDR) */
parse_reg(struct config * config,struct reg * reg,const char * s)497*d83cc019SAndroid Build Coastguard Worker static int parse_reg(struct config *config, struct reg *reg, const char *s)
498*d83cc019SAndroid Build Coastguard Worker {
499*d83cc019SAndroid Build Coastguard Worker unsigned long addr;
500*d83cc019SAndroid Build Coastguard Worker char *endp;
501*d83cc019SAndroid Build Coastguard Worker const char *p;
502*d83cc019SAndroid Build Coastguard Worker int ret;
503*d83cc019SAndroid Build Coastguard Worker
504*d83cc019SAndroid Build Coastguard Worker memset(reg, 0, sizeof(*reg));
505*d83cc019SAndroid Build Coastguard Worker
506*d83cc019SAndroid Build Coastguard Worker p = strchr(s, ':');
507*d83cc019SAndroid Build Coastguard Worker if (p == s) {
508*d83cc019SAndroid Build Coastguard Worker ret = -1;
509*d83cc019SAndroid Build Coastguard Worker } else if (p) {
510*d83cc019SAndroid Build Coastguard Worker char *port_name = strndup(s, p - s);
511*d83cc019SAndroid Build Coastguard Worker
512*d83cc019SAndroid Build Coastguard Worker ret = parse_engine(reg, port_name);
513*d83cc019SAndroid Build Coastguard Worker if (ret)
514*d83cc019SAndroid Build Coastguard Worker ret = parse_port_desc(reg, port_name);
515*d83cc019SAndroid Build Coastguard Worker
516*d83cc019SAndroid Build Coastguard Worker free(port_name);
517*d83cc019SAndroid Build Coastguard Worker p++;
518*d83cc019SAndroid Build Coastguard Worker } else {
519*d83cc019SAndroid Build Coastguard Worker /*
520*d83cc019SAndroid Build Coastguard Worker * XXX: If port is not specified in input, see if the register
521*d83cc019SAndroid Build Coastguard Worker * matches by name, and initialize port desc based on that.
522*d83cc019SAndroid Build Coastguard Worker */
523*d83cc019SAndroid Build Coastguard Worker ret = parse_port_desc(reg, NULL);
524*d83cc019SAndroid Build Coastguard Worker p = s;
525*d83cc019SAndroid Build Coastguard Worker }
526*d83cc019SAndroid Build Coastguard Worker
527*d83cc019SAndroid Build Coastguard Worker if (ret) {
528*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "invalid port in '%s'\n", s);
529*d83cc019SAndroid Build Coastguard Worker return ret;
530*d83cc019SAndroid Build Coastguard Worker }
531*d83cc019SAndroid Build Coastguard Worker
532*d83cc019SAndroid Build Coastguard Worker addr = strtoul(p, &endp, 16);
533*d83cc019SAndroid Build Coastguard Worker if (endp > p && *endp == 0) {
534*d83cc019SAndroid Build Coastguard Worker /* It's a number. */
535*d83cc019SAndroid Build Coastguard Worker ret = set_reg_by_addr(config, reg, addr);
536*d83cc019SAndroid Build Coastguard Worker } else {
537*d83cc019SAndroid Build Coastguard Worker /* Not a number, it's a name. */
538*d83cc019SAndroid Build Coastguard Worker ret = set_reg_by_name(config, reg, p);
539*d83cc019SAndroid Build Coastguard Worker }
540*d83cc019SAndroid Build Coastguard Worker
541*d83cc019SAndroid Build Coastguard Worker return ret;
542*d83cc019SAndroid Build Coastguard Worker }
543*d83cc019SAndroid Build Coastguard Worker
544*d83cc019SAndroid Build Coastguard Worker /* XXX: add support for register ranges, maybe REGISTER..REGISTER */
intel_reg_read(struct config * config,int argc,char * argv[])545*d83cc019SAndroid Build Coastguard Worker static int intel_reg_read(struct config *config, int argc, char *argv[])
546*d83cc019SAndroid Build Coastguard Worker {
547*d83cc019SAndroid Build Coastguard Worker int i, j;
548*d83cc019SAndroid Build Coastguard Worker
549*d83cc019SAndroid Build Coastguard Worker if (argc == 1) {
550*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "read: no registers specified\n");
551*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
552*d83cc019SAndroid Build Coastguard Worker }
553*d83cc019SAndroid Build Coastguard Worker
554*d83cc019SAndroid Build Coastguard Worker if (config->mmiofile)
555*d83cc019SAndroid Build Coastguard Worker intel_mmio_use_dump_file(config->mmiofile);
556*d83cc019SAndroid Build Coastguard Worker else
557*d83cc019SAndroid Build Coastguard Worker intel_register_access_init(config->pci_dev, 0, -1);
558*d83cc019SAndroid Build Coastguard Worker
559*d83cc019SAndroid Build Coastguard Worker for (i = 1; i < argc; i++) {
560*d83cc019SAndroid Build Coastguard Worker struct reg reg;
561*d83cc019SAndroid Build Coastguard Worker
562*d83cc019SAndroid Build Coastguard Worker if (parse_reg(config, ®, argv[i]))
563*d83cc019SAndroid Build Coastguard Worker continue;
564*d83cc019SAndroid Build Coastguard Worker
565*d83cc019SAndroid Build Coastguard Worker for (j = 0; j < config->count; j++) {
566*d83cc019SAndroid Build Coastguard Worker dump_register(config, ®);
567*d83cc019SAndroid Build Coastguard Worker /* Update addr and name. */
568*d83cc019SAndroid Build Coastguard Worker set_reg_by_addr(config, ®,
569*d83cc019SAndroid Build Coastguard Worker reg.addr + reg.port_desc.stride);
570*d83cc019SAndroid Build Coastguard Worker }
571*d83cc019SAndroid Build Coastguard Worker }
572*d83cc019SAndroid Build Coastguard Worker
573*d83cc019SAndroid Build Coastguard Worker intel_register_access_fini();
574*d83cc019SAndroid Build Coastguard Worker
575*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
576*d83cc019SAndroid Build Coastguard Worker }
577*d83cc019SAndroid Build Coastguard Worker
intel_reg_write(struct config * config,int argc,char * argv[])578*d83cc019SAndroid Build Coastguard Worker static int intel_reg_write(struct config *config, int argc, char *argv[])
579*d83cc019SAndroid Build Coastguard Worker {
580*d83cc019SAndroid Build Coastguard Worker int i;
581*d83cc019SAndroid Build Coastguard Worker
582*d83cc019SAndroid Build Coastguard Worker if (argc == 1) {
583*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "write: no registers specified\n");
584*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
585*d83cc019SAndroid Build Coastguard Worker }
586*d83cc019SAndroid Build Coastguard Worker
587*d83cc019SAndroid Build Coastguard Worker intel_register_access_init(config->pci_dev, 0, -1);
588*d83cc019SAndroid Build Coastguard Worker
589*d83cc019SAndroid Build Coastguard Worker for (i = 1; i < argc; i += 2) {
590*d83cc019SAndroid Build Coastguard Worker struct reg reg;
591*d83cc019SAndroid Build Coastguard Worker uint32_t val;
592*d83cc019SAndroid Build Coastguard Worker char *endp;
593*d83cc019SAndroid Build Coastguard Worker
594*d83cc019SAndroid Build Coastguard Worker if (parse_reg(config, ®, argv[i]))
595*d83cc019SAndroid Build Coastguard Worker continue;
596*d83cc019SAndroid Build Coastguard Worker
597*d83cc019SAndroid Build Coastguard Worker if (i + 1 == argc) {
598*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "write: no value\n");
599*d83cc019SAndroid Build Coastguard Worker break;
600*d83cc019SAndroid Build Coastguard Worker }
601*d83cc019SAndroid Build Coastguard Worker
602*d83cc019SAndroid Build Coastguard Worker val = strtoul(argv[i + 1], &endp, 16);
603*d83cc019SAndroid Build Coastguard Worker if (endp == argv[i + 1] || *endp) {
604*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "write: invalid value '%s'\n",
605*d83cc019SAndroid Build Coastguard Worker argv[i + 1]);
606*d83cc019SAndroid Build Coastguard Worker continue;
607*d83cc019SAndroid Build Coastguard Worker }
608*d83cc019SAndroid Build Coastguard Worker
609*d83cc019SAndroid Build Coastguard Worker write_register(config, ®, val);
610*d83cc019SAndroid Build Coastguard Worker }
611*d83cc019SAndroid Build Coastguard Worker
612*d83cc019SAndroid Build Coastguard Worker intel_register_access_fini();
613*d83cc019SAndroid Build Coastguard Worker
614*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
615*d83cc019SAndroid Build Coastguard Worker }
616*d83cc019SAndroid Build Coastguard Worker
intel_reg_dump(struct config * config,int argc,char * argv[])617*d83cc019SAndroid Build Coastguard Worker static int intel_reg_dump(struct config *config, int argc, char *argv[])
618*d83cc019SAndroid Build Coastguard Worker {
619*d83cc019SAndroid Build Coastguard Worker struct reg *reg;
620*d83cc019SAndroid Build Coastguard Worker int i;
621*d83cc019SAndroid Build Coastguard Worker
622*d83cc019SAndroid Build Coastguard Worker if (config->mmiofile)
623*d83cc019SAndroid Build Coastguard Worker intel_mmio_use_dump_file(config->mmiofile);
624*d83cc019SAndroid Build Coastguard Worker else
625*d83cc019SAndroid Build Coastguard Worker intel_register_access_init(config->pci_dev, 0, -1);
626*d83cc019SAndroid Build Coastguard Worker
627*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < config->regcount; i++) {
628*d83cc019SAndroid Build Coastguard Worker reg = &config->regs[i];
629*d83cc019SAndroid Build Coastguard Worker
630*d83cc019SAndroid Build Coastguard Worker /* can't dump sideband with mmiofile */
631*d83cc019SAndroid Build Coastguard Worker if (config->mmiofile && reg->port_desc.port != PORT_MMIO)
632*d83cc019SAndroid Build Coastguard Worker continue;
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker dump_register(config, &config->regs[i]);
635*d83cc019SAndroid Build Coastguard Worker }
636*d83cc019SAndroid Build Coastguard Worker
637*d83cc019SAndroid Build Coastguard Worker intel_register_access_fini();
638*d83cc019SAndroid Build Coastguard Worker
639*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
640*d83cc019SAndroid Build Coastguard Worker }
641*d83cc019SAndroid Build Coastguard Worker
intel_reg_snapshot(struct config * config,int argc,char * argv[])642*d83cc019SAndroid Build Coastguard Worker static int intel_reg_snapshot(struct config *config, int argc, char *argv[])
643*d83cc019SAndroid Build Coastguard Worker {
644*d83cc019SAndroid Build Coastguard Worker int mmio_bar = IS_GEN2(config->devid) ? 1 : 0;
645*d83cc019SAndroid Build Coastguard Worker
646*d83cc019SAndroid Build Coastguard Worker if (config->mmiofile) {
647*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "specifying --mmio=FILE is not compatible\n");
648*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
649*d83cc019SAndroid Build Coastguard Worker }
650*d83cc019SAndroid Build Coastguard Worker
651*d83cc019SAndroid Build Coastguard Worker intel_mmio_use_pci_bar(config->pci_dev);
652*d83cc019SAndroid Build Coastguard Worker
653*d83cc019SAndroid Build Coastguard Worker /* XXX: error handling */
654*d83cc019SAndroid Build Coastguard Worker if (write(1, igt_global_mmio, config->pci_dev->regions[mmio_bar].size) == -1)
655*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error writing snapshot: %s", strerror(errno));
656*d83cc019SAndroid Build Coastguard Worker
657*d83cc019SAndroid Build Coastguard Worker if (config->verbosity > 0)
658*d83cc019SAndroid Build Coastguard Worker printf("use this with --mmio=FILE --devid=0x%04X\n",
659*d83cc019SAndroid Build Coastguard Worker config->devid);
660*d83cc019SAndroid Build Coastguard Worker
661*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
662*d83cc019SAndroid Build Coastguard Worker }
663*d83cc019SAndroid Build Coastguard Worker
664*d83cc019SAndroid Build Coastguard Worker /* XXX: add support for reading and re-decoding a previously done dump */
intel_reg_decode(struct config * config,int argc,char * argv[])665*d83cc019SAndroid Build Coastguard Worker static int intel_reg_decode(struct config *config, int argc, char *argv[])
666*d83cc019SAndroid Build Coastguard Worker {
667*d83cc019SAndroid Build Coastguard Worker int i;
668*d83cc019SAndroid Build Coastguard Worker
669*d83cc019SAndroid Build Coastguard Worker if (argc == 1) {
670*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "decode: no registers specified\n");
671*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
672*d83cc019SAndroid Build Coastguard Worker }
673*d83cc019SAndroid Build Coastguard Worker
674*d83cc019SAndroid Build Coastguard Worker for (i = 1; i < argc; i += 2) {
675*d83cc019SAndroid Build Coastguard Worker struct reg reg;
676*d83cc019SAndroid Build Coastguard Worker uint32_t val;
677*d83cc019SAndroid Build Coastguard Worker char *endp;
678*d83cc019SAndroid Build Coastguard Worker
679*d83cc019SAndroid Build Coastguard Worker if (parse_reg(config, ®, argv[i]))
680*d83cc019SAndroid Build Coastguard Worker continue;
681*d83cc019SAndroid Build Coastguard Worker
682*d83cc019SAndroid Build Coastguard Worker if (i + 1 == argc) {
683*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "decode: no value\n");
684*d83cc019SAndroid Build Coastguard Worker break;
685*d83cc019SAndroid Build Coastguard Worker }
686*d83cc019SAndroid Build Coastguard Worker
687*d83cc019SAndroid Build Coastguard Worker val = strtoul(argv[i + 1], &endp, 16);
688*d83cc019SAndroid Build Coastguard Worker if (endp == argv[i + 1] || *endp) {
689*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "decode: invalid value '%s'\n",
690*d83cc019SAndroid Build Coastguard Worker argv[i + 1]);
691*d83cc019SAndroid Build Coastguard Worker continue;
692*d83cc019SAndroid Build Coastguard Worker }
693*d83cc019SAndroid Build Coastguard Worker
694*d83cc019SAndroid Build Coastguard Worker dump_decode(config, ®, val);
695*d83cc019SAndroid Build Coastguard Worker }
696*d83cc019SAndroid Build Coastguard Worker
697*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
698*d83cc019SAndroid Build Coastguard Worker }
699*d83cc019SAndroid Build Coastguard Worker
intel_reg_list(struct config * config,int argc,char * argv[])700*d83cc019SAndroid Build Coastguard Worker static int intel_reg_list(struct config *config, int argc, char *argv[])
701*d83cc019SAndroid Build Coastguard Worker {
702*d83cc019SAndroid Build Coastguard Worker int i;
703*d83cc019SAndroid Build Coastguard Worker
704*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < config->regcount; i++) {
705*d83cc019SAndroid Build Coastguard Worker printf("%s\n", config->regs[i].name);
706*d83cc019SAndroid Build Coastguard Worker }
707*d83cc019SAndroid Build Coastguard Worker
708*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
709*d83cc019SAndroid Build Coastguard Worker }
710*d83cc019SAndroid Build Coastguard Worker
711*d83cc019SAndroid Build Coastguard Worker static int intel_reg_help(struct config *config, int argc, char *argv[]);
712*d83cc019SAndroid Build Coastguard Worker
713*d83cc019SAndroid Build Coastguard Worker struct command {
714*d83cc019SAndroid Build Coastguard Worker const char *name;
715*d83cc019SAndroid Build Coastguard Worker const char *description;
716*d83cc019SAndroid Build Coastguard Worker const char *synopsis;
717*d83cc019SAndroid Build Coastguard Worker int (*function)(struct config *config, int argc, char *argv[]);
718*d83cc019SAndroid Build Coastguard Worker };
719*d83cc019SAndroid Build Coastguard Worker
720*d83cc019SAndroid Build Coastguard Worker static const struct command commands[] = {
721*d83cc019SAndroid Build Coastguard Worker {
722*d83cc019SAndroid Build Coastguard Worker .name = "read",
723*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_read,
724*d83cc019SAndroid Build Coastguard Worker .synopsis = "[--count=N] REGISTER [...]",
725*d83cc019SAndroid Build Coastguard Worker .description = "read and decode specified register(s)",
726*d83cc019SAndroid Build Coastguard Worker },
727*d83cc019SAndroid Build Coastguard Worker {
728*d83cc019SAndroid Build Coastguard Worker .name = "write",
729*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_write,
730*d83cc019SAndroid Build Coastguard Worker .synopsis = "[--post] REGISTER VALUE [REGISTER VALUE ...]",
731*d83cc019SAndroid Build Coastguard Worker .description = "write value(s) to specified register(s)",
732*d83cc019SAndroid Build Coastguard Worker },
733*d83cc019SAndroid Build Coastguard Worker {
734*d83cc019SAndroid Build Coastguard Worker .name = "dump",
735*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_dump,
736*d83cc019SAndroid Build Coastguard Worker .description = "dump all known registers",
737*d83cc019SAndroid Build Coastguard Worker },
738*d83cc019SAndroid Build Coastguard Worker {
739*d83cc019SAndroid Build Coastguard Worker .name = "decode",
740*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_decode,
741*d83cc019SAndroid Build Coastguard Worker .synopsis = "REGISTER VALUE [REGISTER VALUE ...]",
742*d83cc019SAndroid Build Coastguard Worker .description = "decode value(s) for specified register(s)",
743*d83cc019SAndroid Build Coastguard Worker },
744*d83cc019SAndroid Build Coastguard Worker {
745*d83cc019SAndroid Build Coastguard Worker .name = "snapshot",
746*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_snapshot,
747*d83cc019SAndroid Build Coastguard Worker .description = "create a snapshot of the MMIO bar to stdout",
748*d83cc019SAndroid Build Coastguard Worker },
749*d83cc019SAndroid Build Coastguard Worker {
750*d83cc019SAndroid Build Coastguard Worker .name = "list",
751*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_list,
752*d83cc019SAndroid Build Coastguard Worker .description = "list all known register names",
753*d83cc019SAndroid Build Coastguard Worker },
754*d83cc019SAndroid Build Coastguard Worker {
755*d83cc019SAndroid Build Coastguard Worker .name = "help",
756*d83cc019SAndroid Build Coastguard Worker .function = intel_reg_help,
757*d83cc019SAndroid Build Coastguard Worker .description = "show this help",
758*d83cc019SAndroid Build Coastguard Worker },
759*d83cc019SAndroid Build Coastguard Worker };
760*d83cc019SAndroid Build Coastguard Worker
intel_reg_help(struct config * config,int argc,char * argv[])761*d83cc019SAndroid Build Coastguard Worker static int intel_reg_help(struct config *config, int argc, char *argv[])
762*d83cc019SAndroid Build Coastguard Worker {
763*d83cc019SAndroid Build Coastguard Worker const struct intel_execution_engine2 *e;
764*d83cc019SAndroid Build Coastguard Worker int i;
765*d83cc019SAndroid Build Coastguard Worker
766*d83cc019SAndroid Build Coastguard Worker printf("Intel graphics register multitool\n\n");
767*d83cc019SAndroid Build Coastguard Worker printf("Usage: intel_reg [OPTION ...] COMMAND\n\n");
768*d83cc019SAndroid Build Coastguard Worker printf("COMMAND is one of:\n");
769*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(commands); i++) {
770*d83cc019SAndroid Build Coastguard Worker printf(" %-14s%s\n", commands[i].name,
771*d83cc019SAndroid Build Coastguard Worker commands[i].synopsis ?: "");
772*d83cc019SAndroid Build Coastguard Worker printf(" %-14s%s\n", "", commands[i].description);
773*d83cc019SAndroid Build Coastguard Worker }
774*d83cc019SAndroid Build Coastguard Worker
775*d83cc019SAndroid Build Coastguard Worker printf("\n");
776*d83cc019SAndroid Build Coastguard Worker printf("REGISTER is defined as:\n");
777*d83cc019SAndroid Build Coastguard Worker printf(" [(PORTNAME|PORTNUM|ENGINE|MMIO-OFFSET):](REGNAME|REGADDR)\n");
778*d83cc019SAndroid Build Coastguard Worker
779*d83cc019SAndroid Build Coastguard Worker printf("\n");
780*d83cc019SAndroid Build Coastguard Worker printf("PORTNAME is one of:\n");
781*d83cc019SAndroid Build Coastguard Worker intel_reg_spec_print_ports();
782*d83cc019SAndroid Build Coastguard Worker printf("\n\n");
783*d83cc019SAndroid Build Coastguard Worker
784*d83cc019SAndroid Build Coastguard Worker printf("ENGINE is one of:\n");
785*d83cc019SAndroid Build Coastguard Worker for (e = intel_execution_engines2; e->name; e++)
786*d83cc019SAndroid Build Coastguard Worker printf("%s -%s ", e->name, e->name);
787*d83cc019SAndroid Build Coastguard Worker printf("\n\n");
788*d83cc019SAndroid Build Coastguard Worker
789*d83cc019SAndroid Build Coastguard Worker printf("OPTIONS common to most COMMANDS:\n");
790*d83cc019SAndroid Build Coastguard Worker printf(" --spec=PATH Read register spec from directory or file\n");
791*d83cc019SAndroid Build Coastguard Worker printf(" --mmio=FILE Use an MMIO snapshot\n");
792*d83cc019SAndroid Build Coastguard Worker printf(" --devid=DEVID Specify PCI device ID for --mmio=FILE\n");
793*d83cc019SAndroid Build Coastguard Worker printf(" --all Decode registers for all known platforms\n");
794*d83cc019SAndroid Build Coastguard Worker printf(" --binary Binary dump registers\n");
795*d83cc019SAndroid Build Coastguard Worker printf(" --verbose Increase verbosity\n");
796*d83cc019SAndroid Build Coastguard Worker printf(" --quiet Reduce verbosity\n");
797*d83cc019SAndroid Build Coastguard Worker
798*d83cc019SAndroid Build Coastguard Worker printf("\n");
799*d83cc019SAndroid Build Coastguard Worker printf("Environment variables:\n");
800*d83cc019SAndroid Build Coastguard Worker printf(" INTEL_REG_SPEC Read register spec from directory or file\n");
801*d83cc019SAndroid Build Coastguard Worker
802*d83cc019SAndroid Build Coastguard Worker return EXIT_SUCCESS;
803*d83cc019SAndroid Build Coastguard Worker }
804*d83cc019SAndroid Build Coastguard Worker
805*d83cc019SAndroid Build Coastguard Worker /*
806*d83cc019SAndroid Build Coastguard Worker * Get codename for a gen5+ platform to be used for finding register spec file.
807*d83cc019SAndroid Build Coastguard Worker */
get_codename(uint32_t devid)808*d83cc019SAndroid Build Coastguard Worker static const char *get_codename(uint32_t devid)
809*d83cc019SAndroid Build Coastguard Worker {
810*d83cc019SAndroid Build Coastguard Worker return intel_get_device_info(devid)->codename;
811*d83cc019SAndroid Build Coastguard Worker }
812*d83cc019SAndroid Build Coastguard Worker
813*d83cc019SAndroid Build Coastguard Worker /*
814*d83cc019SAndroid Build Coastguard Worker * Get register definitions filename for devid in dir. Return 0 if found,
815*d83cc019SAndroid Build Coastguard Worker * negative error code otherwise.
816*d83cc019SAndroid Build Coastguard Worker */
get_reg_spec_file(char * buf,size_t buflen,const char * dir,uint32_t devid)817*d83cc019SAndroid Build Coastguard Worker static int get_reg_spec_file(char *buf, size_t buflen, const char *dir,
818*d83cc019SAndroid Build Coastguard Worker uint32_t devid)
819*d83cc019SAndroid Build Coastguard Worker {
820*d83cc019SAndroid Build Coastguard Worker const char *codename;
821*d83cc019SAndroid Build Coastguard Worker
822*d83cc019SAndroid Build Coastguard Worker /* First, try file named after devid, e.g. "0412" for Haswell GT2. */
823*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, "%s/%04x", dir, devid);
824*d83cc019SAndroid Build Coastguard Worker if (!access(buf, F_OK))
825*d83cc019SAndroid Build Coastguard Worker return 0;
826*d83cc019SAndroid Build Coastguard Worker
827*d83cc019SAndroid Build Coastguard Worker /*
828*d83cc019SAndroid Build Coastguard Worker * Second, for gen5+, try file named after codename, e.g. "haswell" for
829*d83cc019SAndroid Build Coastguard Worker * Haswell.
830*d83cc019SAndroid Build Coastguard Worker */
831*d83cc019SAndroid Build Coastguard Worker codename = get_codename(devid);
832*d83cc019SAndroid Build Coastguard Worker if (codename) {
833*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, "%s/%s", dir, codename);
834*d83cc019SAndroid Build Coastguard Worker if (!access(buf, F_OK))
835*d83cc019SAndroid Build Coastguard Worker return 0;
836*d83cc019SAndroid Build Coastguard Worker }
837*d83cc019SAndroid Build Coastguard Worker
838*d83cc019SAndroid Build Coastguard Worker /*
839*d83cc019SAndroid Build Coastguard Worker * Third, try file named after gen, e.g. "gen7" for Haswell (which is
840*d83cc019SAndroid Build Coastguard Worker * technically 7.5 but this is how it works).
841*d83cc019SAndroid Build Coastguard Worker */
842*d83cc019SAndroid Build Coastguard Worker snprintf(buf, buflen, "%s/gen%d", dir, intel_gen(devid));
843*d83cc019SAndroid Build Coastguard Worker if (!access(buf, F_OK))
844*d83cc019SAndroid Build Coastguard Worker return 0;
845*d83cc019SAndroid Build Coastguard Worker
846*d83cc019SAndroid Build Coastguard Worker return -ENOENT;
847*d83cc019SAndroid Build Coastguard Worker }
848*d83cc019SAndroid Build Coastguard Worker
849*d83cc019SAndroid Build Coastguard Worker /*
850*d83cc019SAndroid Build Coastguard Worker * Read register spec.
851*d83cc019SAndroid Build Coastguard Worker */
read_reg_spec(struct config * config)852*d83cc019SAndroid Build Coastguard Worker static int read_reg_spec(struct config *config)
853*d83cc019SAndroid Build Coastguard Worker {
854*d83cc019SAndroid Build Coastguard Worker char buf[PATH_MAX];
855*d83cc019SAndroid Build Coastguard Worker const char *path;
856*d83cc019SAndroid Build Coastguard Worker struct stat st;
857*d83cc019SAndroid Build Coastguard Worker int r;
858*d83cc019SAndroid Build Coastguard Worker
859*d83cc019SAndroid Build Coastguard Worker path = config->specfile;
860*d83cc019SAndroid Build Coastguard Worker if (!path)
861*d83cc019SAndroid Build Coastguard Worker path = getenv("INTEL_REG_SPEC");
862*d83cc019SAndroid Build Coastguard Worker
863*d83cc019SAndroid Build Coastguard Worker if (!path)
864*d83cc019SAndroid Build Coastguard Worker path = IGT_DATADIR"/registers";
865*d83cc019SAndroid Build Coastguard Worker
866*d83cc019SAndroid Build Coastguard Worker r = stat(path, &st);
867*d83cc019SAndroid Build Coastguard Worker if (r) {
868*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Warning: stat '%s' failed: %s. "
869*d83cc019SAndroid Build Coastguard Worker "Using builtin register spec.\n",
870*d83cc019SAndroid Build Coastguard Worker path, strerror(errno));
871*d83cc019SAndroid Build Coastguard Worker goto builtin;
872*d83cc019SAndroid Build Coastguard Worker }
873*d83cc019SAndroid Build Coastguard Worker
874*d83cc019SAndroid Build Coastguard Worker if (S_ISDIR(st.st_mode)) {
875*d83cc019SAndroid Build Coastguard Worker r = get_reg_spec_file(buf, sizeof(buf), path, config->devid);
876*d83cc019SAndroid Build Coastguard Worker if (r) {
877*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Warning: register spec not found in "
878*d83cc019SAndroid Build Coastguard Worker "'%s'. Using builtin register spec.\n", path);
879*d83cc019SAndroid Build Coastguard Worker goto builtin;
880*d83cc019SAndroid Build Coastguard Worker }
881*d83cc019SAndroid Build Coastguard Worker path = buf;
882*d83cc019SAndroid Build Coastguard Worker }
883*d83cc019SAndroid Build Coastguard Worker
884*d83cc019SAndroid Build Coastguard Worker config->regcount = intel_reg_spec_file(&config->regs, path);
885*d83cc019SAndroid Build Coastguard Worker if (config->regcount <= 0) {
886*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Warning: reading '%s' failed. "
887*d83cc019SAndroid Build Coastguard Worker "Using builtin register spec.\n", path);
888*d83cc019SAndroid Build Coastguard Worker goto builtin;
889*d83cc019SAndroid Build Coastguard Worker }
890*d83cc019SAndroid Build Coastguard Worker
891*d83cc019SAndroid Build Coastguard Worker return config->regcount;
892*d83cc019SAndroid Build Coastguard Worker
893*d83cc019SAndroid Build Coastguard Worker builtin:
894*d83cc019SAndroid Build Coastguard Worker /* Fallback to builtin register spec. */
895*d83cc019SAndroid Build Coastguard Worker config->regcount = intel_reg_spec_builtin(&config->regs, config->devid);
896*d83cc019SAndroid Build Coastguard Worker
897*d83cc019SAndroid Build Coastguard Worker return config->regcount;
898*d83cc019SAndroid Build Coastguard Worker }
899*d83cc019SAndroid Build Coastguard Worker
900*d83cc019SAndroid Build Coastguard Worker enum opt {
901*d83cc019SAndroid Build Coastguard Worker OPT_UNKNOWN = '?',
902*d83cc019SAndroid Build Coastguard Worker OPT_END = -1,
903*d83cc019SAndroid Build Coastguard Worker OPT_MMIO,
904*d83cc019SAndroid Build Coastguard Worker OPT_DEVID,
905*d83cc019SAndroid Build Coastguard Worker OPT_COUNT,
906*d83cc019SAndroid Build Coastguard Worker OPT_POST,
907*d83cc019SAndroid Build Coastguard Worker OPT_ALL,
908*d83cc019SAndroid Build Coastguard Worker OPT_BINARY,
909*d83cc019SAndroid Build Coastguard Worker OPT_SPEC,
910*d83cc019SAndroid Build Coastguard Worker OPT_VERBOSE,
911*d83cc019SAndroid Build Coastguard Worker OPT_QUIET,
912*d83cc019SAndroid Build Coastguard Worker OPT_HELP,
913*d83cc019SAndroid Build Coastguard Worker };
914*d83cc019SAndroid Build Coastguard Worker
main(int argc,char * argv[])915*d83cc019SAndroid Build Coastguard Worker int main(int argc, char *argv[])
916*d83cc019SAndroid Build Coastguard Worker {
917*d83cc019SAndroid Build Coastguard Worker int ret, i, index;
918*d83cc019SAndroid Build Coastguard Worker char *endp;
919*d83cc019SAndroid Build Coastguard Worker enum opt opt;
920*d83cc019SAndroid Build Coastguard Worker const struct command *command = NULL;
921*d83cc019SAndroid Build Coastguard Worker struct config config = {
922*d83cc019SAndroid Build Coastguard Worker .count = 1,
923*d83cc019SAndroid Build Coastguard Worker .fd = -1,
924*d83cc019SAndroid Build Coastguard Worker };
925*d83cc019SAndroid Build Coastguard Worker bool help = false;
926*d83cc019SAndroid Build Coastguard Worker
927*d83cc019SAndroid Build Coastguard Worker static struct option options[] = {
928*d83cc019SAndroid Build Coastguard Worker /* global options */
929*d83cc019SAndroid Build Coastguard Worker { "spec", required_argument, NULL, OPT_SPEC },
930*d83cc019SAndroid Build Coastguard Worker { "verbose", no_argument, NULL, OPT_VERBOSE },
931*d83cc019SAndroid Build Coastguard Worker { "quiet", no_argument, NULL, OPT_QUIET },
932*d83cc019SAndroid Build Coastguard Worker { "help", no_argument, NULL, OPT_HELP },
933*d83cc019SAndroid Build Coastguard Worker /* options specific to read and dump */
934*d83cc019SAndroid Build Coastguard Worker { "mmio", required_argument, NULL, OPT_MMIO },
935*d83cc019SAndroid Build Coastguard Worker { "devid", required_argument, NULL, OPT_DEVID },
936*d83cc019SAndroid Build Coastguard Worker /* options specific to read */
937*d83cc019SAndroid Build Coastguard Worker { "count", required_argument, NULL, OPT_COUNT },
938*d83cc019SAndroid Build Coastguard Worker /* options specific to write */
939*d83cc019SAndroid Build Coastguard Worker { "post", no_argument, NULL, OPT_POST },
940*d83cc019SAndroid Build Coastguard Worker /* options specific to read, dump and decode */
941*d83cc019SAndroid Build Coastguard Worker { "all", no_argument, NULL, OPT_ALL },
942*d83cc019SAndroid Build Coastguard Worker { "binary", no_argument, NULL, OPT_BINARY },
943*d83cc019SAndroid Build Coastguard Worker { 0 }
944*d83cc019SAndroid Build Coastguard Worker };
945*d83cc019SAndroid Build Coastguard Worker
946*d83cc019SAndroid Build Coastguard Worker for (opt = 0; opt != OPT_END; ) {
947*d83cc019SAndroid Build Coastguard Worker opt = getopt_long(argc, argv, "", options, &index);
948*d83cc019SAndroid Build Coastguard Worker
949*d83cc019SAndroid Build Coastguard Worker switch (opt) {
950*d83cc019SAndroid Build Coastguard Worker case OPT_MMIO:
951*d83cc019SAndroid Build Coastguard Worker config.mmiofile = strdup(optarg);
952*d83cc019SAndroid Build Coastguard Worker if (!config.mmiofile) {
953*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "strdup: %s\n",
954*d83cc019SAndroid Build Coastguard Worker strerror(errno));
955*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
956*d83cc019SAndroid Build Coastguard Worker }
957*d83cc019SAndroid Build Coastguard Worker break;
958*d83cc019SAndroid Build Coastguard Worker case OPT_DEVID:
959*d83cc019SAndroid Build Coastguard Worker config.devid = strtoul(optarg, &endp, 16);
960*d83cc019SAndroid Build Coastguard Worker if (*endp) {
961*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "invalid devid '%s'\n", optarg);
962*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
963*d83cc019SAndroid Build Coastguard Worker }
964*d83cc019SAndroid Build Coastguard Worker break;
965*d83cc019SAndroid Build Coastguard Worker case OPT_COUNT:
966*d83cc019SAndroid Build Coastguard Worker config.count = strtol(optarg, &endp, 10);
967*d83cc019SAndroid Build Coastguard Worker if (*endp) {
968*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "invalid count '%s'\n", optarg);
969*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
970*d83cc019SAndroid Build Coastguard Worker }
971*d83cc019SAndroid Build Coastguard Worker break;
972*d83cc019SAndroid Build Coastguard Worker case OPT_POST:
973*d83cc019SAndroid Build Coastguard Worker config.post = true;
974*d83cc019SAndroid Build Coastguard Worker break;
975*d83cc019SAndroid Build Coastguard Worker case OPT_SPEC:
976*d83cc019SAndroid Build Coastguard Worker config.specfile = strdup(optarg);
977*d83cc019SAndroid Build Coastguard Worker if (!config.specfile) {
978*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "strdup: %s\n",
979*d83cc019SAndroid Build Coastguard Worker strerror(errno));
980*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
981*d83cc019SAndroid Build Coastguard Worker }
982*d83cc019SAndroid Build Coastguard Worker break;
983*d83cc019SAndroid Build Coastguard Worker case OPT_ALL:
984*d83cc019SAndroid Build Coastguard Worker config.all_platforms = true;
985*d83cc019SAndroid Build Coastguard Worker break;
986*d83cc019SAndroid Build Coastguard Worker case OPT_BINARY:
987*d83cc019SAndroid Build Coastguard Worker config.binary = true;
988*d83cc019SAndroid Build Coastguard Worker break;
989*d83cc019SAndroid Build Coastguard Worker case OPT_VERBOSE:
990*d83cc019SAndroid Build Coastguard Worker config.verbosity++;
991*d83cc019SAndroid Build Coastguard Worker break;
992*d83cc019SAndroid Build Coastguard Worker case OPT_QUIET:
993*d83cc019SAndroid Build Coastguard Worker config.verbosity--;
994*d83cc019SAndroid Build Coastguard Worker break;
995*d83cc019SAndroid Build Coastguard Worker case OPT_HELP:
996*d83cc019SAndroid Build Coastguard Worker help = true;
997*d83cc019SAndroid Build Coastguard Worker break;
998*d83cc019SAndroid Build Coastguard Worker case OPT_END:
999*d83cc019SAndroid Build Coastguard Worker break;
1000*d83cc019SAndroid Build Coastguard Worker case OPT_UNKNOWN:
1001*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1002*d83cc019SAndroid Build Coastguard Worker }
1003*d83cc019SAndroid Build Coastguard Worker }
1004*d83cc019SAndroid Build Coastguard Worker
1005*d83cc019SAndroid Build Coastguard Worker argc -= optind;
1006*d83cc019SAndroid Build Coastguard Worker argv += optind;
1007*d83cc019SAndroid Build Coastguard Worker
1008*d83cc019SAndroid Build Coastguard Worker if (help || (argc > 0 && strcmp(argv[0], "help") == 0))
1009*d83cc019SAndroid Build Coastguard Worker return intel_reg_help(&config, argc, argv);
1010*d83cc019SAndroid Build Coastguard Worker
1011*d83cc019SAndroid Build Coastguard Worker if (argc == 0) {
1012*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Command missing. Try intel_reg help.\n");
1013*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1014*d83cc019SAndroid Build Coastguard Worker }
1015*d83cc019SAndroid Build Coastguard Worker
1016*d83cc019SAndroid Build Coastguard Worker if (config.mmiofile) {
1017*d83cc019SAndroid Build Coastguard Worker if (!config.devid) {
1018*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "--mmio requires --devid\n");
1019*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1020*d83cc019SAndroid Build Coastguard Worker }
1021*d83cc019SAndroid Build Coastguard Worker } else {
1022*d83cc019SAndroid Build Coastguard Worker /* XXX: devid without --mmio could be useful for decode. */
1023*d83cc019SAndroid Build Coastguard Worker if (config.devid) {
1024*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "--devid without --mmio\n");
1025*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1026*d83cc019SAndroid Build Coastguard Worker }
1027*d83cc019SAndroid Build Coastguard Worker config.pci_dev = intel_get_pci_device();
1028*d83cc019SAndroid Build Coastguard Worker config.devid = config.pci_dev->device_id;
1029*d83cc019SAndroid Build Coastguard Worker }
1030*d83cc019SAndroid Build Coastguard Worker
1031*d83cc019SAndroid Build Coastguard Worker if (read_reg_spec(&config) < 0) {
1032*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1033*d83cc019SAndroid Build Coastguard Worker }
1034*d83cc019SAndroid Build Coastguard Worker
1035*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(commands); i++) {
1036*d83cc019SAndroid Build Coastguard Worker if (strcmp(argv[0], commands[i].name) == 0) {
1037*d83cc019SAndroid Build Coastguard Worker command = &commands[i];
1038*d83cc019SAndroid Build Coastguard Worker break;
1039*d83cc019SAndroid Build Coastguard Worker }
1040*d83cc019SAndroid Build Coastguard Worker }
1041*d83cc019SAndroid Build Coastguard Worker
1042*d83cc019SAndroid Build Coastguard Worker if (!command) {
1043*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "'%s' is not an intel-reg command\n", argv[0]);
1044*d83cc019SAndroid Build Coastguard Worker return EXIT_FAILURE;
1045*d83cc019SAndroid Build Coastguard Worker }
1046*d83cc019SAndroid Build Coastguard Worker
1047*d83cc019SAndroid Build Coastguard Worker ret = command->function(&config, argc, argv);
1048*d83cc019SAndroid Build Coastguard Worker
1049*d83cc019SAndroid Build Coastguard Worker free(config.mmiofile);
1050*d83cc019SAndroid Build Coastguard Worker
1051*d83cc019SAndroid Build Coastguard Worker if (config.fd >= 0)
1052*d83cc019SAndroid Build Coastguard Worker close(config.fd);
1053*d83cc019SAndroid Build Coastguard Worker
1054*d83cc019SAndroid Build Coastguard Worker return ret;
1055*d83cc019SAndroid Build Coastguard Worker }
1056