1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Igalia S.L.
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #include <assert.h>
7*61046927SAndroid Build Coastguard Worker #include <ctype.h>
8*61046927SAndroid Build Coastguard Worker #include <err.h>
9*61046927SAndroid Build Coastguard Worker #include <errno.h>
10*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
11*61046927SAndroid Build Coastguard Worker #include <getopt.h>
12*61046927SAndroid Build Coastguard Worker #include <signal.h>
13*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
14*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
15*61046927SAndroid Build Coastguard Worker #include <stdint.h>
16*61046927SAndroid Build Coastguard Worker #include <stdio.h>
17*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
18*61046927SAndroid Build Coastguard Worker #include <string.h>
19*61046927SAndroid Build Coastguard Worker #include <unistd.h>
20*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
21*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
22*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
23*61046927SAndroid Build Coastguard Worker #include <sys/wait.h>
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include "adreno_common.xml.h"
28*61046927SAndroid Build Coastguard Worker #include "adreno_pm4.xml.h"
29*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker #include "a6xx.xml.h"
32*61046927SAndroid Build Coastguard Worker #include "common/freedreno_dev_info.h"
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
35*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
36*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
37*61046927SAndroid Build Coastguard Worker #include "util/rb_tree.h"
38*61046927SAndroid Build Coastguard Worker #include "util/set.h"
39*61046927SAndroid Build Coastguard Worker #include "util/u_vector.h"
40*61046927SAndroid Build Coastguard Worker #include "buffers.h"
41*61046927SAndroid Build Coastguard Worker #include "cffdec.h"
42*61046927SAndroid Build Coastguard Worker #include "disasm.h"
43*61046927SAndroid Build Coastguard Worker #include "io.h"
44*61046927SAndroid Build Coastguard Worker #include "rdutil.h"
45*61046927SAndroid Build Coastguard Worker #include "redump.h"
46*61046927SAndroid Build Coastguard Worker #include "rnnutil.h"
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker /* Decompiles a single cmdstream from .rd into compilable C source.
49*61046927SAndroid Build Coastguard Worker * C source could be compiled using rdcompiler-meson.build as an example.
50*61046927SAndroid Build Coastguard Worker *
51*61046927SAndroid Build Coastguard Worker * For how-to see freedreno.rst
52*61046927SAndroid Build Coastguard Worker */
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker static int handle_file(const char *filename, uint32_t submit_to_decompile);
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker static const char *levels[] = {
57*61046927SAndroid Build Coastguard Worker "\t",
58*61046927SAndroid Build Coastguard Worker "\t\t",
59*61046927SAndroid Build Coastguard Worker "\t\t\t",
60*61046927SAndroid Build Coastguard Worker "\t\t\t\t",
61*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t",
62*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t",
63*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t",
64*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t\t",
65*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t\t\t",
66*61046927SAndroid Build Coastguard Worker };
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker static void
printlvl(int lvl,const char * fmt,...)69*61046927SAndroid Build Coastguard Worker printlvl(int lvl, const char *fmt, ...)
70*61046927SAndroid Build Coastguard Worker {
71*61046927SAndroid Build Coastguard Worker assert(lvl < ARRAY_SIZE(levels));
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker va_list args;
74*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
75*61046927SAndroid Build Coastguard Worker fputs(levels[lvl], stdout);
76*61046927SAndroid Build Coastguard Worker vprintf(fmt, args);
77*61046927SAndroid Build Coastguard Worker va_end(args);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker static void
print_usage(const char * name)81*61046927SAndroid Build Coastguard Worker print_usage(const char *name)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker /* clang-format off */
84*61046927SAndroid Build Coastguard Worker fprintf(stderr, "Usage:\n\n"
85*61046927SAndroid Build Coastguard Worker "\t%s [OPTIONS]... FILE...\n\n"
86*61046927SAndroid Build Coastguard Worker "Options:\n"
87*61046927SAndroid Build Coastguard Worker "\t-s, --submit=№ - № of the submit to decompile\n"
88*61046927SAndroid Build Coastguard Worker "\t--no-reg-bunch - Use pkt4 for each reg in CP_CONTEXT_REG_BUNCH\n"
89*61046927SAndroid Build Coastguard Worker "\t-h, --help - show this message\n"
90*61046927SAndroid Build Coastguard Worker , name);
91*61046927SAndroid Build Coastguard Worker /* clang-format on */
92*61046927SAndroid Build Coastguard Worker exit(2);
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker struct decompiler_options {
96*61046927SAndroid Build Coastguard Worker int no_reg_bunch;
97*61046927SAndroid Build Coastguard Worker };
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker static struct decompiler_options options = {};
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker /* clang-format off */
102*61046927SAndroid Build Coastguard Worker static const struct option opts[] = {
103*61046927SAndroid Build Coastguard Worker { "submit", required_argument, 0, 's' },
104*61046927SAndroid Build Coastguard Worker { "no-reg-bunch", no_argument, &options.no_reg_bunch, 1 },
105*61046927SAndroid Build Coastguard Worker { "help", no_argument, 0, 'h' },
106*61046927SAndroid Build Coastguard Worker };
107*61046927SAndroid Build Coastguard Worker /* clang-format on */
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker int
main(int argc,char ** argv)110*61046927SAndroid Build Coastguard Worker main(int argc, char **argv)
111*61046927SAndroid Build Coastguard Worker {
112*61046927SAndroid Build Coastguard Worker int ret = -1;
113*61046927SAndroid Build Coastguard Worker int c;
114*61046927SAndroid Build Coastguard Worker uint32_t submit_to_decompile = -1;
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker while ((c = getopt_long(argc, argv, "s:h", opts, NULL)) != -1) {
117*61046927SAndroid Build Coastguard Worker switch (c) {
118*61046927SAndroid Build Coastguard Worker case 0:
119*61046927SAndroid Build Coastguard Worker /* option that set a flag, nothing to do */
120*61046927SAndroid Build Coastguard Worker break;
121*61046927SAndroid Build Coastguard Worker case 's':
122*61046927SAndroid Build Coastguard Worker submit_to_decompile = strtoul(optarg, NULL, 0);
123*61046927SAndroid Build Coastguard Worker break;
124*61046927SAndroid Build Coastguard Worker case 'h':
125*61046927SAndroid Build Coastguard Worker default:
126*61046927SAndroid Build Coastguard Worker print_usage(argv[0]);
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker if (submit_to_decompile == -1) {
131*61046927SAndroid Build Coastguard Worker fprintf(stderr, "Submit to decompile has to be specified\n");
132*61046927SAndroid Build Coastguard Worker print_usage(argv[0]);
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker while (optind < argc) {
136*61046927SAndroid Build Coastguard Worker ret = handle_file(argv[optind], submit_to_decompile);
137*61046927SAndroid Build Coastguard Worker if (ret) {
138*61046927SAndroid Build Coastguard Worker fprintf(stderr, "error reading: %s\n", argv[optind]);
139*61046927SAndroid Build Coastguard Worker break;
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker optind++;
142*61046927SAndroid Build Coastguard Worker }
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker if (ret)
145*61046927SAndroid Build Coastguard Worker print_usage(argv[0]);
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker return ret;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker static struct rnn *rnn;
151*61046927SAndroid Build Coastguard Worker static struct fd_dev_id dev_id;
152*61046927SAndroid Build Coastguard Worker static void *mem_ctx;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker static struct set decompiled_shaders;
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker static void
init_rnn(const char * gpuname)157*61046927SAndroid Build Coastguard Worker init_rnn(const char *gpuname)
158*61046927SAndroid Build Coastguard Worker {
159*61046927SAndroid Build Coastguard Worker rnn = rnn_new(true);
160*61046927SAndroid Build Coastguard Worker rnn_load(rnn, gpuname);
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker const char *
pktname(unsigned opc)164*61046927SAndroid Build Coastguard Worker pktname(unsigned opc)
165*61046927SAndroid Build Coastguard Worker {
166*61046927SAndroid Build Coastguard Worker return rnn_enumname(rnn, "adreno_pm4_type3_packets", opc);
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_shader(const char * name,uint32_t regbase,uint32_t * dwords,int level)170*61046927SAndroid Build Coastguard Worker decompile_shader(const char *name, uint32_t regbase, uint32_t *dwords, int level)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker uint64_t gpuaddr = ((uint64_t)dwords[1] << 32) | dwords[0];
173*61046927SAndroid Build Coastguard Worker gpuaddr &= 0xfffffffffffffff0;
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker /* Shader's iova is referenced in two places, so we have to remember it. */
176*61046927SAndroid Build Coastguard Worker if (_mesa_set_search(&decompiled_shaders, &gpuaddr)) {
177*61046927SAndroid Build Coastguard Worker printlvl(level, "emit_shader_iova(&ctx, cs, 0x%" PRIx64 ");\n", gpuaddr);
178*61046927SAndroid Build Coastguard Worker } else {
179*61046927SAndroid Build Coastguard Worker uint64_t *key = ralloc(mem_ctx, uint64_t);
180*61046927SAndroid Build Coastguard Worker *key = gpuaddr;
181*61046927SAndroid Build Coastguard Worker _mesa_set_add(&decompiled_shaders, key);
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker void *buf = hostptr(gpuaddr);
184*61046927SAndroid Build Coastguard Worker assert(buf);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker uint32_t sizedwords = hostlen(gpuaddr) / 4;
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker char *stream_data = NULL;
189*61046927SAndroid Build Coastguard Worker size_t stream_size = 0;
190*61046927SAndroid Build Coastguard Worker FILE *stream = open_memstream(&stream_data, &stream_size);
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker try_disasm_a3xx(buf, sizedwords, 0, stream, fd_dev_gen(&dev_id) * 100);
193*61046927SAndroid Build Coastguard Worker fclose(stream);
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
196*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "const char *source = R\"(\n");
197*61046927SAndroid Build Coastguard Worker printf("%s", stream_data);
198*61046927SAndroid Build Coastguard Worker printlvl(level + 1, ")\";\n");
199*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "upload_shader(&ctx, 0x%" PRIx64 ", source);\n", gpuaddr);
200*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "emit_shader_iova(&ctx, cs, 0x%" PRIx64 ");\n", gpuaddr);
201*61046927SAndroid Build Coastguard Worker printlvl(level, "}\n");
202*61046927SAndroid Build Coastguard Worker free(stream_data);
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker return 2;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker static struct {
209*61046927SAndroid Build Coastguard Worker uint32_t regbase;
210*61046927SAndroid Build Coastguard Worker uint32_t (*fxn)(const char *name, uint32_t regbase, uint32_t *dwords, int level);
211*61046927SAndroid Build Coastguard Worker } reg_a6xx[] = {
212*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_VS_OBJ_START, decompile_shader},
213*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_HS_OBJ_START, decompile_shader},
214*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_DS_OBJ_START, decompile_shader},
215*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_GS_OBJ_START, decompile_shader},
216*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_FS_OBJ_START, decompile_shader},
217*61046927SAndroid Build Coastguard Worker {REG_A6XX_SP_CS_OBJ_START, decompile_shader},
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker {0, NULL},
220*61046927SAndroid Build Coastguard Worker }, *type0_reg;
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_register(uint32_t regbase,uint32_t * dwords,uint16_t cnt,int level)223*61046927SAndroid Build Coastguard Worker decompile_register(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
224*61046927SAndroid Build Coastguard Worker {
225*61046927SAndroid Build Coastguard Worker struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker for (unsigned idx = 0; type0_reg[idx].regbase; idx++) {
228*61046927SAndroid Build Coastguard Worker if (type0_reg[idx].regbase == regbase) {
229*61046927SAndroid Build Coastguard Worker return type0_reg[idx].fxn(info->name, regbase, dwords, level);
230*61046927SAndroid Build Coastguard Worker }
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker const uint32_t dword = *dwords;
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker if (info && info->typeinfo) {
236*61046927SAndroid Build Coastguard Worker char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, dword);
237*61046927SAndroid Build Coastguard Worker printlvl(level, "/* pkt4: %s = %s */\n", info->name, decoded);
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker if (cnt == 0) {
240*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dword);
241*61046927SAndroid Build Coastguard Worker } else {
242*61046927SAndroid Build Coastguard Worker #if 0
243*61046927SAndroid Build Coastguard Worker char reg_name[33];
244*61046927SAndroid Build Coastguard Worker char field_name[33];
245*61046927SAndroid Build Coastguard Worker char reg_idx[33];
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker /* reginfo doesn't return reg name in a compilable format, for now just
248*61046927SAndroid Build Coastguard Worker * parse it into a compilable reg name.
249*61046927SAndroid Build Coastguard Worker * TODO: Make RNN optionally return compilable reg name.
250*61046927SAndroid Build Coastguard Worker */
251*61046927SAndroid Build Coastguard Worker if (sscanf(info->name, "%32[A-Z0-6_][%32[x0-9]].%32s", reg_name,
252*61046927SAndroid Build Coastguard Worker reg_idx, field_name) != 3) {
253*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt4(cs, REG_%s_%s, (%u), %u);\n", rnn->variant,
254*61046927SAndroid Build Coastguard Worker info->name, cnt, dword);
255*61046927SAndroid Build Coastguard Worker } else {
256*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt4(cs, REG_%s_%s_%s(%s), (%u), %u);\n",
257*61046927SAndroid Build Coastguard Worker rnn->variant, reg_name, field_name, reg_idx, cnt, dword);
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker #else
260*61046927SAndroid Build Coastguard Worker /* TODO: We don't have easy way to get chip generation prefix,
261*61046927SAndroid Build Coastguard Worker * so just emit raw packet offset as a workaround.
262*61046927SAndroid Build Coastguard Worker */
263*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt4(cs, 0x%04x, (%u), 0x%x);\n", regbase, cnt, dword);
264*61046927SAndroid Build Coastguard Worker #endif
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker } else {
267*61046927SAndroid Build Coastguard Worker printlvl(level, "/* unknown pkt4 */\n");
268*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt4(cs, 0x%04x, (%u), 0x%x);\n", regbase, 1, dword);
269*61046927SAndroid Build Coastguard Worker }
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker rnn_reginfo_free(info);
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker return 1;
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker static uint32_t
decompile_register_reg_bunch(uint32_t regbase,uint32_t * dwords,uint16_t cnt,int level)277*61046927SAndroid Build Coastguard Worker decompile_register_reg_bunch(uint32_t regbase, uint32_t *dwords, uint16_t cnt, int level)
278*61046927SAndroid Build Coastguard Worker {
279*61046927SAndroid Build Coastguard Worker struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
280*61046927SAndroid Build Coastguard Worker const uint32_t dword = *dwords;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker if (info && info->typeinfo) {
283*61046927SAndroid Build Coastguard Worker char *decoded = rnndec_decodeval(rnn->vc, info->typeinfo, dword);
284*61046927SAndroid Build Coastguard Worker printlvl(level, "/* reg: %s = %s */\n", info->name, decoded);
285*61046927SAndroid Build Coastguard Worker } else {
286*61046927SAndroid Build Coastguard Worker printlvl(level, "/* unknown pkt4 */\n");
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%04x);\n", regbase);
290*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dword);
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker rnn_reginfo_free(info);
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker return 1;
295*61046927SAndroid Build Coastguard Worker }
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker static void
decompile_registers(uint32_t regbase,uint32_t * dwords,uint32_t sizedwords,int level)298*61046927SAndroid Build Coastguard Worker decompile_registers(uint32_t regbase, uint32_t *dwords, uint32_t sizedwords,
299*61046927SAndroid Build Coastguard Worker int level)
300*61046927SAndroid Build Coastguard Worker {
301*61046927SAndroid Build Coastguard Worker if (!sizedwords)
302*61046927SAndroid Build Coastguard Worker return;
303*61046927SAndroid Build Coastguard Worker uint32_t consumed = decompile_register(regbase, dwords, sizedwords, level);
304*61046927SAndroid Build Coastguard Worker sizedwords -= consumed;
305*61046927SAndroid Build Coastguard Worker while (sizedwords > 0) {
306*61046927SAndroid Build Coastguard Worker regbase += consumed;
307*61046927SAndroid Build Coastguard Worker dwords += consumed;
308*61046927SAndroid Build Coastguard Worker consumed = decompile_register(regbase, dwords, 0, level);
309*61046927SAndroid Build Coastguard Worker sizedwords -= consumed;
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker static void
decompile_domain(uint32_t pkt,uint32_t * dwords,uint32_t sizedwords,const char * dom_name,const char * packet_name,int level)314*61046927SAndroid Build Coastguard Worker decompile_domain(uint32_t pkt, uint32_t *dwords, uint32_t sizedwords,
315*61046927SAndroid Build Coastguard Worker const char *dom_name, const char *packet_name, int level)
316*61046927SAndroid Build Coastguard Worker {
317*61046927SAndroid Build Coastguard Worker struct rnndomain *dom;
318*61046927SAndroid Build Coastguard Worker int i;
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker dom = rnn_finddomain(rnn->db, dom_name);
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt7(cs, %s, %u);\n", packet_name, sizedwords);
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker if (pkt == CP_LOAD_STATE6_FRAG || pkt == CP_LOAD_STATE6_GEOM) {
325*61046927SAndroid Build Coastguard Worker enum a6xx_state_type state_type =
326*61046927SAndroid Build Coastguard Worker (dwords[0] & CP_LOAD_STATE6_0_STATE_TYPE__MASK) >>
327*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE__SHIFT;
328*61046927SAndroid Build Coastguard Worker enum a6xx_state_src state_src =
329*61046927SAndroid Build Coastguard Worker (dwords[0] & CP_LOAD_STATE6_0_STATE_SRC__MASK) >>
330*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC__SHIFT;
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker /* TODO: decompile all other state */
333*61046927SAndroid Build Coastguard Worker if (state_type == ST6_SHADER && state_src == SS6_INDIRECT) {
334*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dwords[0]);
335*61046927SAndroid Build Coastguard Worker decompile_shader(NULL, 0, dwords + 1, level);
336*61046927SAndroid Build Coastguard Worker return;
337*61046927SAndroid Build Coastguard Worker }
338*61046927SAndroid Build Coastguard Worker }
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker for (i = 0; i < sizedwords; i++) {
341*61046927SAndroid Build Coastguard Worker struct rnndecaddrinfo *info = NULL;
342*61046927SAndroid Build Coastguard Worker if (dom) {
343*61046927SAndroid Build Coastguard Worker info = rnndec_decodeaddr(rnn->vc, dom, i, 0);
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker char *decoded;
347*61046927SAndroid Build Coastguard Worker if (!(info && info->typeinfo)) {
348*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
349*61046927SAndroid Build Coastguard Worker continue;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker uint64_t value = dwords[i];
352*61046927SAndroid Build Coastguard Worker bool reg64 = info->typeinfo->high >= 32 && i < sizedwords - 1;
353*61046927SAndroid Build Coastguard Worker if (reg64) {
354*61046927SAndroid Build Coastguard Worker value |= (uint64_t)dwords[i + 1] << 32;
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker decoded = rnndec_decodeval(rnn->vc, info->typeinfo, value);
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker printlvl(level, "/* %s */\n", decoded);
359*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
360*61046927SAndroid Build Coastguard Worker if (reg64) {
361*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dwords[i + 1]);
362*61046927SAndroid Build Coastguard Worker i++;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker free(decoded);
366*61046927SAndroid Build Coastguard Worker free(info->name);
367*61046927SAndroid Build Coastguard Worker free(info);
368*61046927SAndroid Build Coastguard Worker }
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker static void
decompile_commands(uint32_t * dwords,uint32_t sizedwords,int level,uint32_t * cond_count)372*61046927SAndroid Build Coastguard Worker decompile_commands(uint32_t *dwords, uint32_t sizedwords, int level, uint32_t *cond_count)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker int dwords_left = sizedwords;
375*61046927SAndroid Build Coastguard Worker uint32_t count = 0; /* dword count including packet header */
376*61046927SAndroid Build Coastguard Worker uint32_t val;
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker if (!dwords) {
379*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NULL cmd buffer!\n");
380*61046927SAndroid Build Coastguard Worker return;
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker while (dwords_left > 0) {
384*61046927SAndroid Build Coastguard Worker if (pkt_is_regwrite(dwords[0], &val, &count)) {
385*61046927SAndroid Build Coastguard Worker assert(val < 0xffff);
386*61046927SAndroid Build Coastguard Worker decompile_registers(val, dwords + 1, count - 1, level);
387*61046927SAndroid Build Coastguard Worker } else if (pkt_is_opcode(dwords[0], &val, &count)) {
388*61046927SAndroid Build Coastguard Worker if (val == CP_INDIRECT_BUFFER) {
389*61046927SAndroid Build Coastguard Worker uint64_t ibaddr;
390*61046927SAndroid Build Coastguard Worker uint32_t ibsize;
391*61046927SAndroid Build Coastguard Worker ibaddr = dwords[1];
392*61046927SAndroid Build Coastguard Worker ibaddr |= ((uint64_t)dwords[2]) << 32;
393*61046927SAndroid Build Coastguard Worker ibsize = dwords[3];
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
396*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "begin_ib();\n");
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker uint32_t *ptr = hostptr(ibaddr);
399*61046927SAndroid Build Coastguard Worker decompile_commands(ptr, ibsize, level + 1, NULL);
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "end_ib();\n");
402*61046927SAndroid Build Coastguard Worker printlvl(level, "}\n");
403*61046927SAndroid Build Coastguard Worker } else if (val == CP_SET_DRAW_STATE) {
404*61046927SAndroid Build Coastguard Worker for (int i = 1; i < count; i += 3) {
405*61046927SAndroid Build Coastguard Worker uint32_t state_count = dwords[i] & 0xffff;
406*61046927SAndroid Build Coastguard Worker if (state_count != 0) {
407*61046927SAndroid Build Coastguard Worker uint32_t unchanged = dwords[i] & (~0xffff);
408*61046927SAndroid Build Coastguard Worker uint64_t ibaddr = dwords[i + 1];
409*61046927SAndroid Build Coastguard Worker ibaddr |= ((uint64_t)dwords[i + 2]) << 32;
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
412*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "begin_draw_state();\n");
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker uint32_t *ptr = hostptr(ibaddr);
415*61046927SAndroid Build Coastguard Worker decompile_commands(ptr, state_count, level + 1, NULL);
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "end_draw_state(%u);\n", unchanged);
418*61046927SAndroid Build Coastguard Worker printlvl(level, "}\n");
419*61046927SAndroid Build Coastguard Worker } else {
420*61046927SAndroid Build Coastguard Worker decompile_domain(val, dwords + i, 3, "CP_SET_DRAW_STATE",
421*61046927SAndroid Build Coastguard Worker "CP_SET_DRAW_STATE", level);
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker } else if (val == CP_CONTEXT_REG_BUNCH || val == CP_CONTEXT_REG_BUNCH2) {
425*61046927SAndroid Build Coastguard Worker uint32_t *dw = dwords + 1;
426*61046927SAndroid Build Coastguard Worker uint32_t cnt = count - 1;
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker if (val == CP_CONTEXT_REG_BUNCH2) {
429*61046927SAndroid Build Coastguard Worker if (options.no_reg_bunch) {
430*61046927SAndroid Build Coastguard Worker printlvl(level, "// CP_CONTEXT_REG_BUNCH2\n");
431*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
432*61046927SAndroid Build Coastguard Worker } else {
433*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH2", cnt);
434*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
435*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "pkt(cs, 0x%x);\n", dw[0]);
436*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "pkt(cs, 0x%x);\n", dw[1]);
437*61046927SAndroid Build Coastguard Worker }
438*61046927SAndroid Build Coastguard Worker
439*61046927SAndroid Build Coastguard Worker dw += 2;
440*61046927SAndroid Build Coastguard Worker cnt -= 2;
441*61046927SAndroid Build Coastguard Worker } else {
442*61046927SAndroid Build Coastguard Worker if (options.no_reg_bunch) {
443*61046927SAndroid Build Coastguard Worker printlvl(level, "// CP_CONTEXT_REG_BUNCH\n");
444*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
445*61046927SAndroid Build Coastguard Worker } else {
446*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt7(cs, %s, %u);\n", "CP_CONTEXT_REG_BUNCH", cnt);
447*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker }
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < cnt; i += 2) {
452*61046927SAndroid Build Coastguard Worker if (options.no_reg_bunch) {
453*61046927SAndroid Build Coastguard Worker decompile_register(dw[i], &dw[i + 1], 1, level + 1);
454*61046927SAndroid Build Coastguard Worker } else {
455*61046927SAndroid Build Coastguard Worker decompile_register_reg_bunch(dw[i], &dw[i + 1], 1, level + 1);
456*61046927SAndroid Build Coastguard Worker }
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker printlvl(level, "}\n");
459*61046927SAndroid Build Coastguard Worker } else if (val == CP_COND_REG_EXEC) {
460*61046927SAndroid Build Coastguard Worker const char *packet_name = pktname(val);
461*61046927SAndroid Build Coastguard Worker const char *dom_name = packet_name;
462*61046927SAndroid Build Coastguard Worker uint32_t cond_count = dwords[count - 1];
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name, level);
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker printlvl(level, "{\n");
467*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "/* BEGIN COND (%d DWORDS) */\n", cond_count);
468*61046927SAndroid Build Coastguard Worker
469*61046927SAndroid Build Coastguard Worker decompile_commands(dwords + count, cond_count, level + 1, &cond_count);
470*61046927SAndroid Build Coastguard Worker count += cond_count;
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker printlvl(level + 1, "/* END COND */\n");
473*61046927SAndroid Build Coastguard Worker printlvl(level, "}\n");
474*61046927SAndroid Build Coastguard Worker } else if (val == CP_NOP) {
475*61046927SAndroid Build Coastguard Worker /* Prop will often use NOP past the end of cond execs
476*61046927SAndroid Build Coastguard Worker * which basically create an else path for the cond exec
477*61046927SAndroid Build Coastguard Worker */
478*61046927SAndroid Build Coastguard Worker const char *packet_name = pktname(val);
479*61046927SAndroid Build Coastguard Worker const char *dom_name = packet_name;
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker if (count > dwords_left) {
482*61046927SAndroid Build Coastguard Worker int else_cond_count = count - dwords_left;
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker assert(cond_count);
485*61046927SAndroid Build Coastguard Worker *cond_count += else_cond_count;
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt7(cs, %s, %u);\n", packet_name, count - 1);
488*61046927SAndroid Build Coastguard Worker for (int i = 1; i < dwords_left; i++) {
489*61046927SAndroid Build Coastguard Worker printlvl(level, "pkt(cs, 0x%x);\n", dwords[i]);
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker printlvl(level, "/* TO ELSE COND */\n");
493*61046927SAndroid Build Coastguard Worker printlvl(level - 1, "}\n");
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker printlvl(level - 1, "{\n");
496*61046927SAndroid Build Coastguard Worker printlvl(level, "/* ELSE COND (%d DWORDS) */\n", else_cond_count);
497*61046927SAndroid Build Coastguard Worker decompile_commands(dwords + dwords_left, else_cond_count, level, NULL);
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker return;
500*61046927SAndroid Build Coastguard Worker } else {
501*61046927SAndroid Build Coastguard Worker decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name,
502*61046927SAndroid Build Coastguard Worker level);
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker } else {
505*61046927SAndroid Build Coastguard Worker const char *packet_name = pktname(val);
506*61046927SAndroid Build Coastguard Worker const char *dom_name = packet_name;
507*61046927SAndroid Build Coastguard Worker if (packet_name) {
508*61046927SAndroid Build Coastguard Worker /* special hack for two packets that decode the same way
509*61046927SAndroid Build Coastguard Worker * on a6xx:
510*61046927SAndroid Build Coastguard Worker */
511*61046927SAndroid Build Coastguard Worker if (!strcmp(packet_name, "CP_LOAD_STATE6_FRAG") ||
512*61046927SAndroid Build Coastguard Worker !strcmp(packet_name, "CP_LOAD_STATE6_GEOM"))
513*61046927SAndroid Build Coastguard Worker dom_name = "CP_LOAD_STATE6";
514*61046927SAndroid Build Coastguard Worker decompile_domain(val, dwords + 1, count - 1, dom_name, packet_name,
515*61046927SAndroid Build Coastguard Worker level);
516*61046927SAndroid Build Coastguard Worker } else {
517*61046927SAndroid Build Coastguard Worker errx(1, "unknown pkt7 %u", val);
518*61046927SAndroid Build Coastguard Worker }
519*61046927SAndroid Build Coastguard Worker }
520*61046927SAndroid Build Coastguard Worker } else {
521*61046927SAndroid Build Coastguard Worker errx(1, "unknown packet %u", dwords[0]);
522*61046927SAndroid Build Coastguard Worker }
523*61046927SAndroid Build Coastguard Worker
524*61046927SAndroid Build Coastguard Worker dwords += count;
525*61046927SAndroid Build Coastguard Worker dwords_left -= count;
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker if (dwords_left < 0)
529*61046927SAndroid Build Coastguard Worker fprintf(stderr, "**** this ain't right!! dwords_left=%d\n", dwords_left);
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker static void
emit_header()533*61046927SAndroid Build Coastguard Worker emit_header()
534*61046927SAndroid Build Coastguard Worker {
535*61046927SAndroid Build Coastguard Worker if (!dev_id.gpu_id && !dev_id.chip_id)
536*61046927SAndroid Build Coastguard Worker return;
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker static bool emitted = false;
539*61046927SAndroid Build Coastguard Worker if (emitted)
540*61046927SAndroid Build Coastguard Worker return;
541*61046927SAndroid Build Coastguard Worker emitted = true;
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker switch (fd_dev_gen(&dev_id)) {
544*61046927SAndroid Build Coastguard Worker case 6:
545*61046927SAndroid Build Coastguard Worker init_rnn("a6xx");
546*61046927SAndroid Build Coastguard Worker break;
547*61046927SAndroid Build Coastguard Worker case 7:
548*61046927SAndroid Build Coastguard Worker init_rnn("a7xx");
549*61046927SAndroid Build Coastguard Worker break;
550*61046927SAndroid Build Coastguard Worker default:
551*61046927SAndroid Build Coastguard Worker errx(-1, "unsupported gpu: %u", dev_id.gpu_id);
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker printf("#include \"decode/rdcompiler-utils.h\"\n"
555*61046927SAndroid Build Coastguard Worker "int main(int argc, char **argv)\n"
556*61046927SAndroid Build Coastguard Worker "{\n"
557*61046927SAndroid Build Coastguard Worker "\tstruct replay_context ctx;\n"
558*61046927SAndroid Build Coastguard Worker "\tstruct fd_dev_id dev_id = {%u, 0x%" PRIx64 "};\n"
559*61046927SAndroid Build Coastguard Worker "\treplay_context_init(&ctx, &dev_id, argc, argv);\n"
560*61046927SAndroid Build Coastguard Worker "\tstruct cmdstream *cs = ctx.submit_cs;\n\n",
561*61046927SAndroid Build Coastguard Worker dev_id.gpu_id, dev_id.chip_id);
562*61046927SAndroid Build Coastguard Worker }
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker static inline uint32_t
u64_hash(const void * key)565*61046927SAndroid Build Coastguard Worker u64_hash(const void *key)
566*61046927SAndroid Build Coastguard Worker {
567*61046927SAndroid Build Coastguard Worker return _mesa_hash_data(key, sizeof(uint64_t));
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker static inline bool
u64_compare(const void * key1,const void * key2)571*61046927SAndroid Build Coastguard Worker u64_compare(const void *key1, const void *key2)
572*61046927SAndroid Build Coastguard Worker {
573*61046927SAndroid Build Coastguard Worker return memcmp(key1, key2, sizeof(uint64_t)) == 0;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker static int
handle_file(const char * filename,uint32_t submit_to_decompile)577*61046927SAndroid Build Coastguard Worker handle_file(const char *filename, uint32_t submit_to_decompile)
578*61046927SAndroid Build Coastguard Worker {
579*61046927SAndroid Build Coastguard Worker struct io *io;
580*61046927SAndroid Build Coastguard Worker int submit = 0;
581*61046927SAndroid Build Coastguard Worker bool needs_reset = false;
582*61046927SAndroid Build Coastguard Worker struct rd_parsed_section ps = {0};
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker if (!strcmp(filename, "-"))
585*61046927SAndroid Build Coastguard Worker io = io_openfd(0);
586*61046927SAndroid Build Coastguard Worker else
587*61046927SAndroid Build Coastguard Worker io = io_open(filename);
588*61046927SAndroid Build Coastguard Worker
589*61046927SAndroid Build Coastguard Worker if (!io) {
590*61046927SAndroid Build Coastguard Worker fprintf(stderr, "could not open: %s\n", filename);
591*61046927SAndroid Build Coastguard Worker return -1;
592*61046927SAndroid Build Coastguard Worker }
593*61046927SAndroid Build Coastguard Worker
594*61046927SAndroid Build Coastguard Worker type0_reg = reg_a6xx;
595*61046927SAndroid Build Coastguard Worker mem_ctx = ralloc_context(NULL);
596*61046927SAndroid Build Coastguard Worker _mesa_set_init(&decompiled_shaders, mem_ctx, u64_hash, u64_compare);
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker struct {
599*61046927SAndroid Build Coastguard Worker unsigned int len;
600*61046927SAndroid Build Coastguard Worker uint64_t gpuaddr;
601*61046927SAndroid Build Coastguard Worker } gpuaddr = {0};
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker while (parse_rd_section(io, &ps)) {
604*61046927SAndroid Build Coastguard Worker switch (ps.type) {
605*61046927SAndroid Build Coastguard Worker case RD_TEST:
606*61046927SAndroid Build Coastguard Worker case RD_VERT_SHADER:
607*61046927SAndroid Build Coastguard Worker case RD_FRAG_SHADER:
608*61046927SAndroid Build Coastguard Worker case RD_CMD:
609*61046927SAndroid Build Coastguard Worker /* no-op */
610*61046927SAndroid Build Coastguard Worker break;
611*61046927SAndroid Build Coastguard Worker case RD_GPUADDR:
612*61046927SAndroid Build Coastguard Worker if (needs_reset) {
613*61046927SAndroid Build Coastguard Worker reset_buffers();
614*61046927SAndroid Build Coastguard Worker needs_reset = false;
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker parse_addr(ps.buf, ps.sz, &gpuaddr.len, &gpuaddr.gpuaddr);
618*61046927SAndroid Build Coastguard Worker break;
619*61046927SAndroid Build Coastguard Worker case RD_BUFFER_CONTENTS:
620*61046927SAndroid Build Coastguard Worker add_buffer(gpuaddr.gpuaddr, gpuaddr.len, ps.buf);
621*61046927SAndroid Build Coastguard Worker ps.buf = NULL;
622*61046927SAndroid Build Coastguard Worker break;
623*61046927SAndroid Build Coastguard Worker case RD_CMDSTREAM_ADDR: {
624*61046927SAndroid Build Coastguard Worker unsigned int sizedwords;
625*61046927SAndroid Build Coastguard Worker uint64_t gpuaddr;
626*61046927SAndroid Build Coastguard Worker parse_addr(ps.buf, ps.sz, &sizedwords, &gpuaddr);
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker if (submit == submit_to_decompile) {
629*61046927SAndroid Build Coastguard Worker decompile_commands(hostptr(gpuaddr), sizedwords, 0, NULL);
630*61046927SAndroid Build Coastguard Worker }
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker needs_reset = true;
633*61046927SAndroid Build Coastguard Worker submit++;
634*61046927SAndroid Build Coastguard Worker break;
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker case RD_GPU_ID: {
637*61046927SAndroid Build Coastguard Worker dev_id.gpu_id = parse_gpu_id(ps.buf);
638*61046927SAndroid Build Coastguard Worker if (fd_dev_info_raw(&dev_id))
639*61046927SAndroid Build Coastguard Worker emit_header();
640*61046927SAndroid Build Coastguard Worker break;
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker case RD_CHIP_ID: {
643*61046927SAndroid Build Coastguard Worker dev_id.chip_id = parse_chip_id(ps.buf);
644*61046927SAndroid Build Coastguard Worker if (fd_dev_info_raw(&dev_id))
645*61046927SAndroid Build Coastguard Worker emit_header();
646*61046927SAndroid Build Coastguard Worker break;
647*61046927SAndroid Build Coastguard Worker }
648*61046927SAndroid Build Coastguard Worker default:
649*61046927SAndroid Build Coastguard Worker break;
650*61046927SAndroid Build Coastguard Worker }
651*61046927SAndroid Build Coastguard Worker }
652*61046927SAndroid Build Coastguard Worker
653*61046927SAndroid Build Coastguard Worker printf("\treplay_context_finish(&ctx);\n}");
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker io_close(io);
656*61046927SAndroid Build Coastguard Worker fflush(stdout);
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker if (ps.ret < 0) {
659*61046927SAndroid Build Coastguard Worker fprintf(stderr, "corrupt file\n");
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker return 0;
662*61046927SAndroid Build Coastguard Worker }
663