1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Broadcom
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <stdio.h>
25*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
26*61046927SAndroid Build Coastguard Worker #include <string.h>
27*61046927SAndroid Build Coastguard Worker #include "drm-uapi/v3d_drm.h"
28*61046927SAndroid Build Coastguard Worker #include "clif_dump.h"
29*61046927SAndroid Build Coastguard Worker #include "clif_private.h"
30*61046927SAndroid Build Coastguard Worker #include "util/list.h"
31*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include "broadcom/cle/v3d_decoder.h"
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry *
clif_dump_add_address_to_worklist(struct clif_dump * clif,enum reloc_worklist_type type,uint32_t addr)36*61046927SAndroid Build Coastguard Worker clif_dump_add_address_to_worklist(struct clif_dump *clif,
37*61046927SAndroid Build Coastguard Worker enum reloc_worklist_type type,
38*61046927SAndroid Build Coastguard Worker uint32_t addr)
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry *entry =
41*61046927SAndroid Build Coastguard Worker rzalloc(clif, struct reloc_worklist_entry);
42*61046927SAndroid Build Coastguard Worker if (!entry)
43*61046927SAndroid Build Coastguard Worker return NULL;
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker entry->type = type;
46*61046927SAndroid Build Coastguard Worker entry->addr = addr;
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker list_addtail(&entry->link, &clif->worklist);
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker return entry;
51*61046927SAndroid Build Coastguard Worker }
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker struct clif_dump *
clif_dump_init(const struct v3d_device_info * devinfo,FILE * out,bool pretty,bool nobin)54*61046927SAndroid Build Coastguard Worker clif_dump_init(const struct v3d_device_info *devinfo,
55*61046927SAndroid Build Coastguard Worker FILE *out, bool pretty, bool nobin)
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker struct clif_dump *clif = rzalloc(NULL, struct clif_dump);
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker clif->devinfo = devinfo;
60*61046927SAndroid Build Coastguard Worker clif->out = out;
61*61046927SAndroid Build Coastguard Worker clif->spec = v3d_spec_load(devinfo);
62*61046927SAndroid Build Coastguard Worker clif->pretty = pretty;
63*61046927SAndroid Build Coastguard Worker clif->nobin = nobin;
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker list_inithead(&clif->worklist);
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker return clif;
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker void
clif_dump_destroy(struct clif_dump * clif)71*61046927SAndroid Build Coastguard Worker clif_dump_destroy(struct clif_dump *clif)
72*61046927SAndroid Build Coastguard Worker {
73*61046927SAndroid Build Coastguard Worker ralloc_free(clif);
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker struct clif_bo *
clif_lookup_bo(struct clif_dump * clif,uint32_t addr)77*61046927SAndroid Build Coastguard Worker clif_lookup_bo(struct clif_dump *clif, uint32_t addr)
78*61046927SAndroid Build Coastguard Worker {
79*61046927SAndroid Build Coastguard Worker for (int i = 0; i < clif->bo_count; i++) {
80*61046927SAndroid Build Coastguard Worker struct clif_bo *bo = &clif->bo[i];
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker if (addr >= bo->offset &&
83*61046927SAndroid Build Coastguard Worker addr < bo->offset + bo->size) {
84*61046927SAndroid Build Coastguard Worker return bo;
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker return NULL;
89*61046927SAndroid Build Coastguard Worker }
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker static bool
clif_lookup_vaddr(struct clif_dump * clif,uint32_t addr,void ** vaddr)92*61046927SAndroid Build Coastguard Worker clif_lookup_vaddr(struct clif_dump *clif, uint32_t addr, void **vaddr)
93*61046927SAndroid Build Coastguard Worker {
94*61046927SAndroid Build Coastguard Worker struct clif_bo *bo = clif_lookup_bo(clif, addr);
95*61046927SAndroid Build Coastguard Worker if (!bo)
96*61046927SAndroid Build Coastguard Worker return false;
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker *vaddr = bo->vaddr + addr - bo->offset;
99*61046927SAndroid Build Coastguard Worker return true;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker #define out_uint(_clif, field) out(_clif, " /* %s = */ %u\n", \
103*61046927SAndroid Build Coastguard Worker #field, values-> field);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker static bool
clif_dump_packet(struct clif_dump * clif,uint32_t offset,const uint8_t * cl,uint32_t * size,bool reloc_mode)106*61046927SAndroid Build Coastguard Worker clif_dump_packet(struct clif_dump *clif, uint32_t offset, const uint8_t *cl,
107*61046927SAndroid Build Coastguard Worker uint32_t *size, bool reloc_mode)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker switch (clif->devinfo->ver) {
111*61046927SAndroid Build Coastguard Worker case 42:
112*61046927SAndroid Build Coastguard Worker return v3d42_clif_dump_packet(clif, offset, cl, size, reloc_mode);
113*61046927SAndroid Build Coastguard Worker case 71:
114*61046927SAndroid Build Coastguard Worker return v3d71_clif_dump_packet(clif, offset, cl, size, reloc_mode);
115*61046927SAndroid Build Coastguard Worker default:
116*61046927SAndroid Build Coastguard Worker break;
117*61046927SAndroid Build Coastguard Worker };
118*61046927SAndroid Build Coastguard Worker unreachable("Unknown HW version");
119*61046927SAndroid Build Coastguard Worker }
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Worker static uint32_t
clif_dump_cl(struct clif_dump * clif,uint32_t start,uint32_t end,bool reloc_mode)122*61046927SAndroid Build Coastguard Worker clif_dump_cl(struct clif_dump *clif, uint32_t start, uint32_t end,
123*61046927SAndroid Build Coastguard Worker bool reloc_mode)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker struct clif_bo *bo = clif_lookup_bo(clif, start);
126*61046927SAndroid Build Coastguard Worker if (!bo) {
127*61046927SAndroid Build Coastguard Worker out(clif, "Failed to look up address 0x%08x\n",
128*61046927SAndroid Build Coastguard Worker start);
129*61046927SAndroid Build Coastguard Worker return 0;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker void *start_vaddr = bo->vaddr + start - bo->offset;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker /* The end address is optional (for example, a BRANCH instruction
135*61046927SAndroid Build Coastguard Worker * won't set an end), but is used for BCL/RCL termination.
136*61046927SAndroid Build Coastguard Worker */
137*61046927SAndroid Build Coastguard Worker void *end_vaddr = NULL;
138*61046927SAndroid Build Coastguard Worker if (end && !clif_lookup_vaddr(clif, end, &end_vaddr)) {
139*61046927SAndroid Build Coastguard Worker out(clif, "Failed to look up address 0x%08x\n",
140*61046927SAndroid Build Coastguard Worker end);
141*61046927SAndroid Build Coastguard Worker return 0;
142*61046927SAndroid Build Coastguard Worker }
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker if (!reloc_mode)
145*61046927SAndroid Build Coastguard Worker out(clif, "@format ctrllist /* [%s+0x%08x] */\n",
146*61046927SAndroid Build Coastguard Worker bo->name, start - bo->offset);
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker uint32_t size;
149*61046927SAndroid Build Coastguard Worker uint8_t *cl = start_vaddr;
150*61046927SAndroid Build Coastguard Worker while (clif_dump_packet(clif, start, cl, &size, reloc_mode)) {
151*61046927SAndroid Build Coastguard Worker cl += size;
152*61046927SAndroid Build Coastguard Worker start += size;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker if (cl == end_vaddr)
155*61046927SAndroid Build Coastguard Worker break;
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker return (void *)cl - bo->vaddr;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker /* Walks the worklist, parsing the relocs for any memory regions that might
162*61046927SAndroid Build Coastguard Worker * themselves have additional relocations.
163*61046927SAndroid Build Coastguard Worker */
164*61046927SAndroid Build Coastguard Worker static uint32_t
clif_dump_gl_shader_state_record(struct clif_dump * clif,struct reloc_worklist_entry * reloc,void * vaddr,bool including_gs)165*61046927SAndroid Build Coastguard Worker clif_dump_gl_shader_state_record(struct clif_dump *clif,
166*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry *reloc,
167*61046927SAndroid Build Coastguard Worker void *vaddr,
168*61046927SAndroid Build Coastguard Worker bool including_gs)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker struct v3d_group *state = v3d_spec_find_struct(clif->spec,
171*61046927SAndroid Build Coastguard Worker "GL Shader State Record");
172*61046927SAndroid Build Coastguard Worker struct v3d_group *attr = v3d_spec_find_struct(clif->spec,
173*61046927SAndroid Build Coastguard Worker "GL Shader State Attribute Record");
174*61046927SAndroid Build Coastguard Worker assert(state);
175*61046927SAndroid Build Coastguard Worker assert(attr);
176*61046927SAndroid Build Coastguard Worker uint32_t offset = 0;
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker if (including_gs) {
179*61046927SAndroid Build Coastguard Worker struct v3d_group *gs_state = v3d_spec_find_struct(clif->spec,
180*61046927SAndroid Build Coastguard Worker "Geometry Shader State Record");
181*61046927SAndroid Build Coastguard Worker assert(gs_state);
182*61046927SAndroid Build Coastguard Worker out(clif, "@format shadrec_gl_geom\n");
183*61046927SAndroid Build Coastguard Worker v3d_print_group(clif, gs_state, 0, vaddr + offset);
184*61046927SAndroid Build Coastguard Worker offset += v3d_group_get_length(gs_state);
185*61046927SAndroid Build Coastguard Worker /* Extra pad when geometry/tessellation shader is present */
186*61046927SAndroid Build Coastguard Worker offset += 20;
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker out(clif, "@format shadrec_gl_main\n");
189*61046927SAndroid Build Coastguard Worker v3d_print_group(clif, state, 0, vaddr + offset);
190*61046927SAndroid Build Coastguard Worker offset += v3d_group_get_length(state);
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker for (int i = 0; i < reloc->shader_state.num_attrs; i++) {
193*61046927SAndroid Build Coastguard Worker out(clif, "@format shadrec_gl_attr /* %d */\n", i);
194*61046927SAndroid Build Coastguard Worker v3d_print_group(clif, attr, 0, vaddr + offset);
195*61046927SAndroid Build Coastguard Worker offset += v3d_group_get_length(attr);
196*61046927SAndroid Build Coastguard Worker }
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker return offset;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker static void
clif_process_worklist(struct clif_dump * clif)202*61046927SAndroid Build Coastguard Worker clif_process_worklist(struct clif_dump *clif)
203*61046927SAndroid Build Coastguard Worker {
204*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe(struct reloc_worklist_entry, reloc,
205*61046927SAndroid Build Coastguard Worker &clif->worklist, link) {
206*61046927SAndroid Build Coastguard Worker void *vaddr;
207*61046927SAndroid Build Coastguard Worker if (!clif_lookup_vaddr(clif, reloc->addr, &vaddr)) {
208*61046927SAndroid Build Coastguard Worker out(clif, "Failed to look up address 0x%08x\n",
209*61046927SAndroid Build Coastguard Worker reloc->addr);
210*61046927SAndroid Build Coastguard Worker continue;
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker switch (reloc->type) {
214*61046927SAndroid Build Coastguard Worker case reloc_cl:
215*61046927SAndroid Build Coastguard Worker clif_dump_cl(clif, reloc->addr, reloc->cl.end, true);
216*61046927SAndroid Build Coastguard Worker break;
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker case reloc_gl_shader_state:
219*61046927SAndroid Build Coastguard Worker case reloc_gl_including_gs_shader_state:
220*61046927SAndroid Build Coastguard Worker break;
221*61046927SAndroid Build Coastguard Worker case reloc_generic_tile_list:
222*61046927SAndroid Build Coastguard Worker clif_dump_cl(clif, reloc->addr,
223*61046927SAndroid Build Coastguard Worker reloc->generic_tile_list.end, true);
224*61046927SAndroid Build Coastguard Worker break;
225*61046927SAndroid Build Coastguard Worker }
226*61046927SAndroid Build Coastguard Worker }
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker static int
worklist_entry_compare(const void * a,const void * b)230*61046927SAndroid Build Coastguard Worker worklist_entry_compare(const void *a, const void *b)
231*61046927SAndroid Build Coastguard Worker {
232*61046927SAndroid Build Coastguard Worker return ((*(struct reloc_worklist_entry **)a)->addr -
233*61046927SAndroid Build Coastguard Worker (*(struct reloc_worklist_entry **)b)->addr);
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker static bool
clif_dump_if_blank(struct clif_dump * clif,struct clif_bo * bo,uint32_t start,uint32_t end)237*61046927SAndroid Build Coastguard Worker clif_dump_if_blank(struct clif_dump *clif, struct clif_bo *bo,
238*61046927SAndroid Build Coastguard Worker uint32_t start, uint32_t end)
239*61046927SAndroid Build Coastguard Worker {
240*61046927SAndroid Build Coastguard Worker for (int i = start; i < end; i++) {
241*61046927SAndroid Build Coastguard Worker if (((uint8_t *)bo->vaddr)[i] != 0)
242*61046927SAndroid Build Coastguard Worker return false;
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker
245*61046927SAndroid Build Coastguard Worker out(clif, "\n");
246*61046927SAndroid Build Coastguard Worker out(clif, "@format blank %d /* [%s+0x%08x..0x%08x] */\n", end - start,
247*61046927SAndroid Build Coastguard Worker bo->name, start, end - 1);
248*61046927SAndroid Build Coastguard Worker return true;
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker /* Dumps the binary data in the BO from start to end (relative to the start of
252*61046927SAndroid Build Coastguard Worker * the BO).
253*61046927SAndroid Build Coastguard Worker */
254*61046927SAndroid Build Coastguard Worker static void
clif_dump_binary(struct clif_dump * clif,struct clif_bo * bo,uint32_t start,uint32_t end)255*61046927SAndroid Build Coastguard Worker clif_dump_binary(struct clif_dump *clif, struct clif_bo *bo,
256*61046927SAndroid Build Coastguard Worker uint32_t start, uint32_t end)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker if (clif->pretty && clif->nobin)
259*61046927SAndroid Build Coastguard Worker return;
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker if (start == end)
262*61046927SAndroid Build Coastguard Worker return;
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker if (clif_dump_if_blank(clif, bo, start, end))
265*61046927SAndroid Build Coastguard Worker return;
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker out(clif, "@format binary /* [%s+0x%08x] */\n",
268*61046927SAndroid Build Coastguard Worker bo->name, start);
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker uint32_t offset = start;
271*61046927SAndroid Build Coastguard Worker int dumped_in_line = 0;
272*61046927SAndroid Build Coastguard Worker while (offset < end) {
273*61046927SAndroid Build Coastguard Worker if (clif_dump_if_blank(clif, bo, offset, end))
274*61046927SAndroid Build Coastguard Worker return;
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker if (end - offset >= 4) {
277*61046927SAndroid Build Coastguard Worker out(clif, "0x%08x ", *(uint32_t *)(bo->vaddr + offset));
278*61046927SAndroid Build Coastguard Worker offset += 4;
279*61046927SAndroid Build Coastguard Worker } else {
280*61046927SAndroid Build Coastguard Worker out(clif, "0x%02x ", *(uint8_t *)(bo->vaddr + offset));
281*61046927SAndroid Build Coastguard Worker offset++;
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker if (++dumped_in_line == 8) {
285*61046927SAndroid Build Coastguard Worker out(clif, "\n");
286*61046927SAndroid Build Coastguard Worker dumped_in_line = 0;
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker if (dumped_in_line)
290*61046927SAndroid Build Coastguard Worker out(clif, "\n");
291*61046927SAndroid Build Coastguard Worker }
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker /* Walks the list of relocations, dumping each buffer's contents (using our
294*61046927SAndroid Build Coastguard Worker * codegenned dump routines for pretty printing, and most importantly proper
295*61046927SAndroid Build Coastguard Worker * address references so that the CLIF parser can relocate buffers).
296*61046927SAndroid Build Coastguard Worker */
297*61046927SAndroid Build Coastguard Worker static void
clif_dump_buffers(struct clif_dump * clif)298*61046927SAndroid Build Coastguard Worker clif_dump_buffers(struct clif_dump *clif)
299*61046927SAndroid Build Coastguard Worker {
300*61046927SAndroid Build Coastguard Worker int num_relocs = 0;
301*61046927SAndroid Build Coastguard Worker list_for_each_entry(struct reloc_worklist_entry, reloc,
302*61046927SAndroid Build Coastguard Worker &clif->worklist, link) {
303*61046927SAndroid Build Coastguard Worker num_relocs++;
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry **relocs =
306*61046927SAndroid Build Coastguard Worker ralloc_array(clif, struct reloc_worklist_entry *, num_relocs);
307*61046927SAndroid Build Coastguard Worker int i = 0;
308*61046927SAndroid Build Coastguard Worker list_for_each_entry(struct reloc_worklist_entry, reloc,
309*61046927SAndroid Build Coastguard Worker &clif->worklist, link) {
310*61046927SAndroid Build Coastguard Worker relocs[i++] = reloc;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker qsort(relocs, num_relocs, sizeof(*relocs), worklist_entry_compare);
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker struct clif_bo *bo = NULL;
315*61046927SAndroid Build Coastguard Worker uint32_t offset = 0;
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker for (i = 0; i < num_relocs; i++) {
318*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry *reloc = relocs[i];
319*61046927SAndroid Build Coastguard Worker struct clif_bo *new_bo = clif_lookup_bo(clif, reloc->addr);
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker if (!new_bo) {
322*61046927SAndroid Build Coastguard Worker out(clif, "Failed to look up address 0x%08x\n",
323*61046927SAndroid Build Coastguard Worker reloc->addr);
324*61046927SAndroid Build Coastguard Worker continue;
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker if (new_bo != bo) {
328*61046927SAndroid Build Coastguard Worker if (bo) {
329*61046927SAndroid Build Coastguard Worker /* Finish out the last of the last BO. */
330*61046927SAndroid Build Coastguard Worker clif_dump_binary(clif, bo,
331*61046927SAndroid Build Coastguard Worker offset,
332*61046927SAndroid Build Coastguard Worker bo->size);
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker out(clif, "\n");
336*61046927SAndroid Build Coastguard Worker out(clif, "@buffer %s\n", new_bo->name);
337*61046927SAndroid Build Coastguard Worker bo = new_bo;
338*61046927SAndroid Build Coastguard Worker offset = 0;
339*61046927SAndroid Build Coastguard Worker bo->dumped = true;
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker int reloc_offset = reloc->addr - bo->offset;
343*61046927SAndroid Build Coastguard Worker if (offset != reloc_offset)
344*61046927SAndroid Build Coastguard Worker clif_dump_binary(clif, bo, offset, reloc_offset);
345*61046927SAndroid Build Coastguard Worker offset = reloc_offset;
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker switch (reloc->type) {
348*61046927SAndroid Build Coastguard Worker case reloc_cl:
349*61046927SAndroid Build Coastguard Worker offset = clif_dump_cl(clif, reloc->addr, reloc->cl.end,
350*61046927SAndroid Build Coastguard Worker false);
351*61046927SAndroid Build Coastguard Worker out(clif, "\n");
352*61046927SAndroid Build Coastguard Worker break;
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker case reloc_gl_shader_state:
355*61046927SAndroid Build Coastguard Worker case reloc_gl_including_gs_shader_state:
356*61046927SAndroid Build Coastguard Worker offset += clif_dump_gl_shader_state_record(clif,
357*61046927SAndroid Build Coastguard Worker reloc,
358*61046927SAndroid Build Coastguard Worker bo->vaddr +
359*61046927SAndroid Build Coastguard Worker offset,
360*61046927SAndroid Build Coastguard Worker reloc->type == reloc_gl_including_gs_shader_state);
361*61046927SAndroid Build Coastguard Worker break;
362*61046927SAndroid Build Coastguard Worker case reloc_generic_tile_list:
363*61046927SAndroid Build Coastguard Worker offset = clif_dump_cl(clif, reloc->addr,
364*61046927SAndroid Build Coastguard Worker reloc->generic_tile_list.end,
365*61046927SAndroid Build Coastguard Worker false);
366*61046927SAndroid Build Coastguard Worker break;
367*61046927SAndroid Build Coastguard Worker }
368*61046927SAndroid Build Coastguard Worker out(clif, "\n");
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker if (bo) {
372*61046927SAndroid Build Coastguard Worker clif_dump_binary(clif, bo, offset, bo->size);
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker /* For any BOs that didn't have relocations, just dump them raw. */
376*61046927SAndroid Build Coastguard Worker for (int i = 0; i < clif->bo_count; i++) {
377*61046927SAndroid Build Coastguard Worker bo = &clif->bo[i];
378*61046927SAndroid Build Coastguard Worker if (bo->dumped)
379*61046927SAndroid Build Coastguard Worker continue;
380*61046927SAndroid Build Coastguard Worker out(clif, "@buffer %s\n", bo->name);
381*61046927SAndroid Build Coastguard Worker clif_dump_binary(clif, bo, 0, bo->size);
382*61046927SAndroid Build Coastguard Worker out(clif, "\n");
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker void
clif_dump_add_cl(struct clif_dump * clif,uint32_t start,uint32_t end)387*61046927SAndroid Build Coastguard Worker clif_dump_add_cl(struct clif_dump *clif, uint32_t start, uint32_t end)
388*61046927SAndroid Build Coastguard Worker {
389*61046927SAndroid Build Coastguard Worker struct reloc_worklist_entry *entry =
390*61046927SAndroid Build Coastguard Worker clif_dump_add_address_to_worklist(clif, reloc_cl, start);
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker entry->cl.end = end;
393*61046927SAndroid Build Coastguard Worker }
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker static int
clif_bo_offset_compare(const void * a,const void * b)396*61046927SAndroid Build Coastguard Worker clif_bo_offset_compare(const void *a, const void *b)
397*61046927SAndroid Build Coastguard Worker {
398*61046927SAndroid Build Coastguard Worker return ((struct clif_bo *)a)->offset - ((struct clif_bo *)b)->offset;
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker void
clif_dump(struct clif_dump * clif,const struct drm_v3d_submit_cl * submit)402*61046927SAndroid Build Coastguard Worker clif_dump(struct clif_dump *clif, const struct drm_v3d_submit_cl *submit)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker clif_dump_add_cl(clif, submit->bcl_start, submit->bcl_end);
405*61046927SAndroid Build Coastguard Worker clif_dump_add_cl(clif, submit->rcl_start, submit->rcl_end);
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker qsort(clif->bo, clif->bo_count, sizeof(clif->bo[0]),
408*61046927SAndroid Build Coastguard Worker clif_bo_offset_compare);
409*61046927SAndroid Build Coastguard Worker
410*61046927SAndroid Build Coastguard Worker /* A buffer needs to be defined before we can emit a CLIF address
411*61046927SAndroid Build Coastguard Worker * referencing it, so emit them all now.
412*61046927SAndroid Build Coastguard Worker */
413*61046927SAndroid Build Coastguard Worker for (int i = 0; i < clif->bo_count; i++) {
414*61046927SAndroid Build Coastguard Worker out(clif, "@createbuf_aligned 4096 %s\n", clif->bo[i].name);
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker /* Walk the worklist figuring out the locations of structs based on
418*61046927SAndroid Build Coastguard Worker * the CL contents.
419*61046927SAndroid Build Coastguard Worker */
420*61046927SAndroid Build Coastguard Worker clif_process_worklist(clif);
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker /* Dump the contents of the buffers using the relocations we found to
423*61046927SAndroid Build Coastguard Worker * pretty-print structures.
424*61046927SAndroid Build Coastguard Worker */
425*61046927SAndroid Build Coastguard Worker clif_dump_buffers(clif);
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker out(clif, "@add_bin 0\n ");
428*61046927SAndroid Build Coastguard Worker out_address(clif, submit->bcl_start);
429*61046927SAndroid Build Coastguard Worker out(clif, "\n ");
430*61046927SAndroid Build Coastguard Worker out_address(clif, submit->bcl_end);
431*61046927SAndroid Build Coastguard Worker out(clif, "\n ");
432*61046927SAndroid Build Coastguard Worker out_address(clif, submit->qma);
433*61046927SAndroid Build Coastguard Worker out(clif, "\n %d\n ", submit->qms);
434*61046927SAndroid Build Coastguard Worker out_address(clif, submit->qts);
435*61046927SAndroid Build Coastguard Worker out(clif, "\n");
436*61046927SAndroid Build Coastguard Worker out(clif, "@wait_bin_all_cores\n");
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker out(clif, "@add_render 0\n ");
439*61046927SAndroid Build Coastguard Worker out_address(clif, submit->rcl_start);
440*61046927SAndroid Build Coastguard Worker out(clif, "\n ");
441*61046927SAndroid Build Coastguard Worker out_address(clif, submit->rcl_end);
442*61046927SAndroid Build Coastguard Worker out(clif, "\n ");
443*61046927SAndroid Build Coastguard Worker out_address(clif, submit->qma);
444*61046927SAndroid Build Coastguard Worker out(clif, "\n");
445*61046927SAndroid Build Coastguard Worker out(clif, "@wait_render_all_cores\n");
446*61046927SAndroid Build Coastguard Worker }
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker void
clif_dump_add_bo(struct clif_dump * clif,const char * name,uint32_t offset,uint32_t size,void * vaddr)449*61046927SAndroid Build Coastguard Worker clif_dump_add_bo(struct clif_dump *clif, const char *name,
450*61046927SAndroid Build Coastguard Worker uint32_t offset, uint32_t size, void *vaddr)
451*61046927SAndroid Build Coastguard Worker {
452*61046927SAndroid Build Coastguard Worker if (clif->bo_count >= clif->bo_array_size) {
453*61046927SAndroid Build Coastguard Worker clif->bo_array_size = MAX2(4, clif->bo_array_size * 2);
454*61046927SAndroid Build Coastguard Worker clif->bo = reralloc(clif, clif->bo, struct clif_bo,
455*61046927SAndroid Build Coastguard Worker clif->bo_array_size);
456*61046927SAndroid Build Coastguard Worker }
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker /* CLIF relocs use the buffer name, so make sure they're unique. */
459*61046927SAndroid Build Coastguard Worker for (int i = 0; i < clif->bo_count; i++)
460*61046927SAndroid Build Coastguard Worker assert(strcmp(clif->bo[i].name, name) != 0);
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker clif->bo[clif->bo_count].name = ralloc_strdup(clif, name);
463*61046927SAndroid Build Coastguard Worker clif->bo[clif->bo_count].offset = offset;
464*61046927SAndroid Build Coastguard Worker clif->bo[clif->bo_count].size = size;
465*61046927SAndroid Build Coastguard Worker clif->bo[clif->bo_count].vaddr = vaddr;
466*61046927SAndroid Build Coastguard Worker clif->bo[clif->bo_count].dumped = false;
467*61046927SAndroid Build Coastguard Worker clif->bo_count++;
468*61046927SAndroid Build Coastguard Worker }
469