1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2012 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #ifndef __CFFDEC_H__
7*61046927SAndroid Build Coastguard Worker #define __CFFDEC_H__
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
12*61046927SAndroid Build Coastguard Worker #include "freedreno_dev_info.h"
13*61046927SAndroid Build Coastguard Worker
14*61046927SAndroid Build Coastguard Worker enum query_mode {
15*61046927SAndroid Build Coastguard Worker /* default mode, dump all queried regs on each draw: */
16*61046927SAndroid Build Coastguard Worker QUERY_ALL = 0,
17*61046927SAndroid Build Coastguard Worker
18*61046927SAndroid Build Coastguard Worker /* only dump if any of the queried regs were written
19*61046927SAndroid Build Coastguard Worker * since last draw:
20*61046927SAndroid Build Coastguard Worker */
21*61046927SAndroid Build Coastguard Worker QUERY_WRITTEN,
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker /* only dump if any of the queried regs changed since
24*61046927SAndroid Build Coastguard Worker * last draw:
25*61046927SAndroid Build Coastguard Worker */
26*61046927SAndroid Build Coastguard Worker QUERY_DELTA,
27*61046927SAndroid Build Coastguard Worker };
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker struct cffdec_options {
30*61046927SAndroid Build Coastguard Worker struct fd_dev_id dev_id;
31*61046927SAndroid Build Coastguard Worker const struct fd_dev_info *info;
32*61046927SAndroid Build Coastguard Worker int draw_filter;
33*61046927SAndroid Build Coastguard Worker int color;
34*61046927SAndroid Build Coastguard Worker int dump_shaders;
35*61046927SAndroid Build Coastguard Worker int summary;
36*61046927SAndroid Build Coastguard Worker int allregs;
37*61046927SAndroid Build Coastguard Worker int dump_textures;
38*61046927SAndroid Build Coastguard Worker int decode_markers;
39*61046927SAndroid Build Coastguard Worker char *script;
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker int query_compare; /* binning vs SYSMEM/GMEM compare mode */
42*61046927SAndroid Build Coastguard Worker int query_mode; /* enum query_mode */
43*61046927SAndroid Build Coastguard Worker char **querystrs;
44*61046927SAndroid Build Coastguard Worker int nquery;
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker /* In "once" mode, only decode a cmdstream buffer once (per draw
47*61046927SAndroid Build Coastguard Worker * mode, in the case of a6xx+ where a single cmdstream buffer can
48*61046927SAndroid Build Coastguard Worker * be used for both binning and draw pass), rather than each time
49*61046927SAndroid Build Coastguard Worker * encountered (ie. once per tile/bin in GMEM draw passes)
50*61046927SAndroid Build Coastguard Worker */
51*61046927SAndroid Build Coastguard Worker int once;
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker /* In unit_test mode, suppress pathnames in output so that we can have references
54*61046927SAndroid Build Coastguard Worker * independent of the build dir.
55*61046927SAndroid Build Coastguard Worker */
56*61046927SAndroid Build Coastguard Worker int unit_test;
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker /* for crashdec, where we know CP_IBx_REM_SIZE, we can use this
59*61046927SAndroid Build Coastguard Worker * to highlight the cmdstream not parsed yet, to make it easier
60*61046927SAndroid Build Coastguard Worker * to see how far along the CP is.
61*61046927SAndroid Build Coastguard Worker */
62*61046927SAndroid Build Coastguard Worker struct {
63*61046927SAndroid Build Coastguard Worker uint64_t base;
64*61046927SAndroid Build Coastguard Worker uint32_t rem;
65*61046927SAndroid Build Coastguard Worker bool crash_found : 1;
66*61046927SAndroid Build Coastguard Worker } ibs[4];
67*61046927SAndroid Build Coastguard Worker };
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker /**
70*61046927SAndroid Build Coastguard Worker * A helper to deal with 64b registers by accumulating the lo/hi 32b
71*61046927SAndroid Build Coastguard Worker * dwords. Example usage:
72*61046927SAndroid Build Coastguard Worker *
73*61046927SAndroid Build Coastguard Worker * struct regacc r = regacc(rnn);
74*61046927SAndroid Build Coastguard Worker *
75*61046927SAndroid Build Coastguard Worker * for (dword in dwords) {
76*61046927SAndroid Build Coastguard Worker * if (regacc_push(&r, regbase, dword)) {
77*61046927SAndroid Build Coastguard Worker * printf("\t%08x"PRIx64", r.value);
78*61046927SAndroid Build Coastguard Worker * dump_register_val(r.regbase, r.value, 0);
79*61046927SAndroid Build Coastguard Worker * }
80*61046927SAndroid Build Coastguard Worker * regbase++;
81*61046927SAndroid Build Coastguard Worker * }
82*61046927SAndroid Build Coastguard Worker *
83*61046927SAndroid Build Coastguard Worker * It is expected that 64b regs will come in pairs of <lo, hi>.
84*61046927SAndroid Build Coastguard Worker */
85*61046927SAndroid Build Coastguard Worker struct regacc {
86*61046927SAndroid Build Coastguard Worker uint32_t regbase;
87*61046927SAndroid Build Coastguard Worker uint64_t value;
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker /* private: */
90*61046927SAndroid Build Coastguard Worker struct rnn *rnn;
91*61046927SAndroid Build Coastguard Worker bool has_dword_lo;
92*61046927SAndroid Build Coastguard Worker };
93*61046927SAndroid Build Coastguard Worker struct regacc regacc(struct rnn *rnn);
94*61046927SAndroid Build Coastguard Worker bool regacc_push(struct regacc *regacc, uint32_t regbase, uint32_t dword);
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker void printl(int lvl, const char *fmt, ...);
97*61046927SAndroid Build Coastguard Worker const char *pktname(unsigned opc);
98*61046927SAndroid Build Coastguard Worker uint32_t regbase(const char *name);
99*61046927SAndroid Build Coastguard Worker const char *regname(uint32_t regbase, int color);
100*61046927SAndroid Build Coastguard Worker bool reg_written(uint32_t regbase);
101*61046927SAndroid Build Coastguard Worker uint32_t reg_lastval(uint32_t regbase);
102*61046927SAndroid Build Coastguard Worker uint32_t reg_val(uint32_t regbase);
103*61046927SAndroid Build Coastguard Worker void reg_set(uint32_t regbase, uint32_t val);
104*61046927SAndroid Build Coastguard Worker uint32_t * parse_cp_indirect(uint32_t *dwords, uint32_t sizedwords,
105*61046927SAndroid Build Coastguard Worker uint64_t *ibaddr, uint32_t *ibsize);
106*61046927SAndroid Build Coastguard Worker void reset_regs(void);
107*61046927SAndroid Build Coastguard Worker void cffdec_init(const struct cffdec_options *options);
108*61046927SAndroid Build Coastguard Worker void dump_register_val(struct regacc *r, int level);
109*61046927SAndroid Build Coastguard Worker void dump_commands(uint32_t *dwords, uint32_t sizedwords, int level);
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker /*
112*61046927SAndroid Build Coastguard Worker * Packets (mostly) fall into two categories, "write one or more registers"
113*61046927SAndroid Build Coastguard Worker * (type0 or type4 depending on generation) or "packet with opcode and
114*61046927SAndroid Build Coastguard Worker * opcode specific payload" (type3 or type7). These helpers deal with
115*61046927SAndroid Build Coastguard Worker * the type0+type3 vs type4+type7 differences (a2xx-a4xx vs a5xx+).
116*61046927SAndroid Build Coastguard Worker */
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker static inline bool
pkt_is_regwrite(uint32_t dword,uint32_t * offset,uint32_t * size)119*61046927SAndroid Build Coastguard Worker pkt_is_regwrite(uint32_t dword, uint32_t *offset, uint32_t *size)
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker if (pkt_is_type0(dword)) {
122*61046927SAndroid Build Coastguard Worker *size = type0_pkt_size(dword) + 1;
123*61046927SAndroid Build Coastguard Worker *offset = type0_pkt_offset(dword);
124*61046927SAndroid Build Coastguard Worker return true;
125*61046927SAndroid Build Coastguard Worker } if (pkt_is_type4(dword)) {
126*61046927SAndroid Build Coastguard Worker *size = type4_pkt_size(dword) + 1;
127*61046927SAndroid Build Coastguard Worker *offset = type4_pkt_offset(dword);
128*61046927SAndroid Build Coastguard Worker return true;
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker return false;
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker static inline bool
pkt_is_opcode(uint32_t dword,uint32_t * opcode,uint32_t * size)134*61046927SAndroid Build Coastguard Worker pkt_is_opcode(uint32_t dword, uint32_t *opcode, uint32_t *size)
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker if (pkt_is_type3(dword)) {
137*61046927SAndroid Build Coastguard Worker *size = type3_pkt_size(dword) + 1;
138*61046927SAndroid Build Coastguard Worker *opcode = cp_type3_opcode(dword);
139*61046927SAndroid Build Coastguard Worker return true;
140*61046927SAndroid Build Coastguard Worker } else if (pkt_is_type7(dword)) {
141*61046927SAndroid Build Coastguard Worker *size = type7_pkt_size(dword) + 1;
142*61046927SAndroid Build Coastguard Worker *opcode = cp_type7_opcode(dword);
143*61046927SAndroid Build Coastguard Worker return true;
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker return false;
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker /**
149*61046927SAndroid Build Coastguard Worker * For a5xx+ we can detect valid packet headers vs random other noise, and
150*61046927SAndroid Build Coastguard Worker * can use this to "re-sync" to the start of the next valid packet. So that
151*61046927SAndroid Build Coastguard Worker * the same cmdstream corruption that confused the GPU doesn't confuse us!
152*61046927SAndroid Build Coastguard Worker */
153*61046927SAndroid Build Coastguard Worker static inline uint32_t
find_next_packet(uint32_t * dwords,uint32_t sizedwords)154*61046927SAndroid Build Coastguard Worker find_next_packet(uint32_t *dwords, uint32_t sizedwords)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker for (uint32_t c = 0; c < sizedwords; c++) {
157*61046927SAndroid Build Coastguard Worker if (pkt_is_type7(dwords[c]) || pkt_is_type4(dwords[c]))
158*61046927SAndroid Build Coastguard Worker return c;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker return sizedwords;
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker #endif /* __CFFDEC_H__ */
165