xref: /aosp_15_r20/external/mesa3d/src/broadcom/clif/clif_dump.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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