blob: efc0868de394476799cffdfa15772de4600455ae [file] [log] [blame]
Shrenuj Bansala419c792016-10-20 14:05:11 -07001/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include "kgsl.h"
14#include "kgsl_sharedmem.h"
15#include "kgsl_snapshot.h"
16
17#include "adreno.h"
18#include "adreno_pm4types.h"
19#include "a3xx_reg.h"
20#include "adreno_cp_parser.h"
21
22#define MAX_IB_OBJS 1000
23#define NUM_SET_DRAW_GROUPS 32
24
25struct set_draw_state {
26 uint64_t cmd_stream_addr;
27 uint64_t cmd_stream_dwords;
28};
29
30/* List of variables used when parsing an IB */
31struct ib_parser_variables {
32 /* List of registers containing addresses and their sizes */
33 unsigned int cp_addr_regs[ADRENO_CP_ADDR_MAX];
34 /* 32 groups of command streams in set draw state packets */
35 struct set_draw_state set_draw_groups[NUM_SET_DRAW_GROUPS];
36};
37
38/*
39 * Used for locating shader objects. This array holds the unit size of shader
40 * objects based on type and block of shader. The type can be 0 or 1 hence there
41 * are 2 columns and block can be 0-7 hence 7 rows.
42 */
43static int load_state_unit_sizes[7][2] = {
44 { 2, 4 },
45 { 0, 1 },
46 { 2, 4 },
47 { 0, 1 },
48 { 8, 2 },
49 { 8, 2 },
50 { 8, 2 },
51};
52
53static int adreno_ib_find_objs(struct kgsl_device *device,
54 struct kgsl_process_private *process,
55 uint64_t gpuaddr, uint64_t dwords,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +053056 uint64_t ib2base, int obj_type,
Shrenuj Bansala419c792016-10-20 14:05:11 -070057 struct adreno_ib_object_list *ib_obj_list,
58 int ib_level);
59
60static int ib_parse_set_draw_state(struct kgsl_device *device,
61 unsigned int *ptr,
62 struct kgsl_process_private *process,
63 struct adreno_ib_object_list *ib_obj_list,
64 struct ib_parser_variables *ib_parse_vars);
65
66static int ib_parse_type7_set_draw_state(struct kgsl_device *device,
67 unsigned int *ptr,
68 struct kgsl_process_private *process,
69 struct adreno_ib_object_list *ib_obj_list);
70
71/*
72 * adreno_ib_merge_range() - Increases the address range tracked by an ib
73 * object
74 * @ib_obj: The ib object
75 * @gpuaddr: The start address which is to be merged
76 * @size: Size of the merging address
77 */
78static void adreno_ib_merge_range(struct adreno_ib_object *ib_obj,
79 uint64_t gpuaddr, uint64_t size)
80{
81 uint64_t addr_end1 = ib_obj->gpuaddr + ib_obj->size;
82 uint64_t addr_end2 = gpuaddr + size;
83
84 if (gpuaddr < ib_obj->gpuaddr)
85 ib_obj->gpuaddr = gpuaddr;
86 if (addr_end2 > addr_end1)
87 ib_obj->size = addr_end2 - ib_obj->gpuaddr;
88 else
89 ib_obj->size = addr_end1 - ib_obj->gpuaddr;
90}
91
92/*
93 * adreno_ib_check_overlap() - Checks if an address range overlap
94 * @gpuaddr: The start address range to check for overlap
95 * @size: Size of the address range
96 * @type: The type of address range
97 * @ib_obj_list: The list of address ranges to check for overlap
98 *
99 * Checks if an address range overlaps with a list of address ranges
100 * Returns the entry from list which overlaps else NULL
101 */
102static struct adreno_ib_object *adreno_ib_check_overlap(uint64_t gpuaddr,
103 uint64_t size, int type,
104 struct adreno_ib_object_list *ib_obj_list)
105{
106 struct adreno_ib_object *ib_obj;
107 int i;
108
109 for (i = 0; i < ib_obj_list->num_objs; i++) {
110 ib_obj = &(ib_obj_list->obj_list[i]);
111 if ((type == ib_obj->snapshot_obj_type) &&
112 kgsl_addr_range_overlap(ib_obj->gpuaddr, ib_obj->size,
113 gpuaddr, size))
114 /* regions overlap */
115 return ib_obj;
116 }
117 return NULL;
118}
119
120/*
121 * adreno_ib_add() - Add a gpuaddress range to list
122 * @process: Process in which the gpuaddress is mapped
123 * @type: The type of address range
124 * @ib_obj_list: List of the address ranges in which the given range is to be
125 * added
126 *
127 * Add a gpuaddress range as an ib object to a given list after checking if it
128 * overlaps with another entry on the list. If it conflicts then change the
129 * existing entry to incorporate this range
130 *
131 * Returns 0 on success else error code
132 */
133static int adreno_ib_add(struct kgsl_process_private *process,
134 uint64_t gpuaddr, int type,
135 struct adreno_ib_object_list *ib_obj_list)
136{
137 uint64_t size;
138 struct adreno_ib_object *ib_obj;
139 struct kgsl_mem_entry *entry;
140
141 if (ib_obj_list->num_objs >= MAX_IB_OBJS)
142 return -E2BIG;
143
144 entry = kgsl_sharedmem_find(process, gpuaddr);
145 if (!entry)
146 /*
147 * Do not fail if gpuaddr not found, we can continue
148 * to search for other objects even if few objects are
149 * not found
150 */
151 return 0;
152
153 size = entry->memdesc.size;
154 gpuaddr = entry->memdesc.gpuaddr;
155
156 ib_obj = adreno_ib_check_overlap(gpuaddr, size, type, ib_obj_list);
157 if (ib_obj) {
158 adreno_ib_merge_range(ib_obj, gpuaddr, size);
159 kgsl_mem_entry_put(entry);
160 } else {
161 adreno_ib_init_ib_obj(gpuaddr, size, type, entry,
162 &(ib_obj_list->obj_list[ib_obj_list->num_objs]));
163 ib_obj_list->num_objs++;
164 }
165 return 0;
166}
167
168/*
169 * ib_save_mip_addresses() - Find mip addresses
170 * @pkt: Pointer to the packet in IB
171 * @process: The process in which IB is mapped
172 * @ib_obj_list: List in which any objects found are added
173 *
174 * Returns 0 on success else error code
175 */
176static int ib_save_mip_addresses(unsigned int *pkt,
177 struct kgsl_process_private *process,
178 struct adreno_ib_object_list *ib_obj_list)
179{
180 int ret = 0;
181 int num_levels = (pkt[1] >> 22) & 0x03FF;
182 int i;
183 unsigned int *hostptr;
184 struct kgsl_mem_entry *ent;
185 unsigned int block, type;
186 int unitsize = 0;
187
188 block = (pkt[1] >> 19) & 0x07;
189 type = pkt[2] & 0x03;
190
191 if (type == 0)
192 unitsize = load_state_unit_sizes[block][0];
193 else
194 unitsize = load_state_unit_sizes[block][1];
195
196 if (3 == block && 1 == type) {
197 uint64_t gpuaddr = pkt[2] & 0xFFFFFFFC;
198 uint64_t size = (num_levels * unitsize) << 2;
199
200 ent = kgsl_sharedmem_find(process, gpuaddr);
201 if (ent == NULL)
202 return 0;
203
204 if (!kgsl_gpuaddr_in_memdesc(&ent->memdesc,
205 gpuaddr, size)) {
206 kgsl_mem_entry_put(ent);
207 return 0;
208 }
209
210 hostptr = kgsl_gpuaddr_to_vaddr(&ent->memdesc, gpuaddr);
211 if (hostptr != NULL) {
212 for (i = 0; i < num_levels; i++) {
213 ret = adreno_ib_add(process, hostptr[i],
214 SNAPSHOT_GPU_OBJECT_GENERIC,
215 ib_obj_list);
216 if (ret)
217 break;
218 }
219 }
220
221 kgsl_memdesc_unmap(&ent->memdesc);
222 kgsl_mem_entry_put(ent);
223 }
224 return ret;
225}
226
227/*
228 * ib_parse_load_state() - Parse load state packet
229 * @pkt: Pointer to the packet in IB
230 * @process: The pagetable in which the IB is mapped
231 * @ib_obj_list: List in which any objects found are added
232 * @ib_parse_vars: VAriable list that store temporary addressses
233 *
234 * Parse load state packet found in an IB and add any memory object found to
235 * a list
236 * Returns 0 on success else error code
237 */
238static int ib_parse_load_state(unsigned int *pkt,
239 struct kgsl_process_private *process,
240 struct adreno_ib_object_list *ib_obj_list,
241 struct ib_parser_variables *ib_parse_vars)
242{
243 int ret = 0;
244 int i;
245
246 /*
247 * The object here is to find indirect shaders i.e - shaders loaded from
248 * GPU memory instead of directly in the command. These should be added
249 * to the list of memory objects to dump. So look at the load state
250 * if the block is indirect (source = 4). If so then add the memory
251 * address to the list. The size of the object differs depending on the
252 * type per the load_state_unit_sizes array above.
253 */
254
255 if (type3_pkt_size(pkt[0]) < 2)
256 return 0;
257
258 /*
259 * Anything from 3rd ordinal onwards of packet can be a memory object,
260 * no need to be fancy about parsing it, just save it if it looks
261 * like memory
262 */
263 for (i = 0; i <= (type3_pkt_size(pkt[0]) - 2); i++) {
264 ret |= adreno_ib_add(process, pkt[2 + i] & 0xFFFFFFFC,
265 SNAPSHOT_GPU_OBJECT_GENERIC,
266 ib_obj_list);
267 if (ret)
268 break;
269 }
270 /* get the mip addresses */
271 if (!ret)
272 ret = ib_save_mip_addresses(pkt, process, ib_obj_list);
273 return ret;
274}
275
276/*
277 * This opcode sets the base addresses for the visibilty stream buffer and the
278 * visiblity stream size buffer.
279 */
280
281static int ib_parse_set_bin_data(unsigned int *pkt,
282 struct kgsl_process_private *process,
283 struct adreno_ib_object_list *ib_obj_list,
284 struct ib_parser_variables *ib_parse_vars)
285{
286 int ret = 0;
287
288 if (type3_pkt_size(pkt[0]) < 2)
289 return 0;
290
291 /* Visiblity stream buffer */
292 ret = adreno_ib_add(process, pkt[1],
293 SNAPSHOT_GPU_OBJECT_GENERIC, ib_obj_list);
294 if (ret)
295 return ret;
296
297 /* visiblity stream size buffer (fixed size 8 dwords) */
298 ret = adreno_ib_add(process, pkt[2],
299 SNAPSHOT_GPU_OBJECT_GENERIC, ib_obj_list);
300
301 return ret;
302}
303
304/*
305 * This opcode writes to GPU memory - if the buffer is written to, there is a
306 * good chance that it would be valuable to capture in the snapshot, so mark all
307 * buffers that are written to as frozen
308 */
309
310static int ib_parse_mem_write(unsigned int *pkt,
311 struct kgsl_process_private *process,
312 struct adreno_ib_object_list *ib_obj_list,
313 struct ib_parser_variables *ib_parse_vars)
314{
315 if (type3_pkt_size(pkt[0]) < 1)
316 return 0;
317
318 /*
319 * The address is where the data in the rest of this packet is written
320 * to, but since that might be an offset into the larger buffer we need
321 * to get the whole thing. Pass a size of 0 tocapture the entire buffer.
322 */
323
324 return adreno_ib_add(process, pkt[1] & 0xFFFFFFFC,
325 SNAPSHOT_GPU_OBJECT_GENERIC, ib_obj_list);
326}
327
328/*
329 * ib_add_type0_entries() - Add memory objects to list
330 * @device: The device on which the IB will execute
331 * @process: The process in which IB is mapped
332 * @ib_obj_list: The list of gpu objects
333 * @ib_parse_vars: addresses ranges found in type0 packets
334 *
335 * Add memory objects to given list that are found in type0 packets
336 * Returns 0 on success else 0
337 */
338static int ib_add_type0_entries(struct kgsl_device *device,
339 struct kgsl_process_private *process,
340 struct adreno_ib_object_list *ib_obj_list,
341 struct ib_parser_variables *ib_parse_vars)
342{
343 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
344 int ret = 0;
345 int i;
346 int vfd_end;
347 unsigned int mask;
348 /* First up the visiblity stream buffer */
349 if (adreno_is_a4xx(adreno_dev))
350 mask = 0xFFFFFFFC;
351 else
352 mask = 0xFFFFFFFF;
353 for (i = ADRENO_CP_ADDR_VSC_PIPE_DATA_ADDRESS_0;
354 i < ADRENO_CP_ADDR_VSC_PIPE_DATA_LENGTH_7; i++) {
355 if (ib_parse_vars->cp_addr_regs[i]) {
356 ret = adreno_ib_add(process,
357 ib_parse_vars->cp_addr_regs[i] & mask,
358 SNAPSHOT_GPU_OBJECT_GENERIC,
359 ib_obj_list);
360 if (ret)
361 return ret;
362 ib_parse_vars->cp_addr_regs[i] = 0;
363 ib_parse_vars->cp_addr_regs[i + 1] = 0;
364 i++;
365 }
366 }
367
368 vfd_end = adreno_is_a4xx(adreno_dev) ?
369 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_31 :
370 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_15;
371 for (i = ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_0;
372 i <= vfd_end; i++) {
373 if (ib_parse_vars->cp_addr_regs[i]) {
374 ret = adreno_ib_add(process,
375 ib_parse_vars->cp_addr_regs[i],
376 SNAPSHOT_GPU_OBJECT_GENERIC,
377 ib_obj_list);
378 if (ret)
379 return ret;
380 ib_parse_vars->cp_addr_regs[i] = 0;
381 }
382 }
383
384 if (ib_parse_vars->cp_addr_regs[ADRENO_CP_ADDR_VSC_SIZE_ADDRESS]) {
385 ret = adreno_ib_add(process,
386 ib_parse_vars->cp_addr_regs[
387 ADRENO_CP_ADDR_VSC_SIZE_ADDRESS] & mask,
388 SNAPSHOT_GPU_OBJECT_GENERIC, ib_obj_list);
389 if (ret)
390 return ret;
391 ib_parse_vars->cp_addr_regs[
392 ADRENO_CP_ADDR_VSC_SIZE_ADDRESS] = 0;
393 }
394 mask = 0xFFFFFFE0;
395 for (i = ADRENO_CP_ADDR_SP_VS_PVT_MEM_ADDR;
396 i <= ADRENO_CP_ADDR_SP_FS_OBJ_START_REG; i++) {
397 ret = adreno_ib_add(process,
398 ib_parse_vars->cp_addr_regs[i] & mask,
399 SNAPSHOT_GPU_OBJECT_GENERIC, ib_obj_list);
400 if (ret)
401 return ret;
402 ib_parse_vars->cp_addr_regs[i] = 0;
403 }
404 return ret;
405}
406/*
407 * The DRAW_INDX opcode sends a draw initator which starts a draw operation in
408 * the GPU, so this is the point where all the registers and buffers become
409 * "valid". The DRAW_INDX may also have an index buffer pointer that should be
410 * frozen with the others
411 */
412
413static int ib_parse_draw_indx(struct kgsl_device *device, unsigned int *pkt,
414 struct kgsl_process_private *process,
415 struct adreno_ib_object_list *ib_obj_list,
416 struct ib_parser_variables *ib_parse_vars)
417{
418 int ret = 0;
419 int i;
420 int opcode = cp_type3_opcode(pkt[0]);
421
422 switch (opcode) {
423 case CP_DRAW_INDX:
424 if (type3_pkt_size(pkt[0]) > 3) {
425 ret = adreno_ib_add(process,
426 pkt[4], SNAPSHOT_GPU_OBJECT_GENERIC,
427 ib_obj_list);
428 }
429 break;
430 case CP_DRAW_INDX_OFFSET:
431 if (type3_pkt_size(pkt[0]) == 6) {
432 ret = adreno_ib_add(process,
433 pkt[5], SNAPSHOT_GPU_OBJECT_GENERIC,
434 ib_obj_list);
435 }
436 break;
437 case CP_DRAW_INDIRECT:
438 if (type3_pkt_size(pkt[0]) == 2) {
439 ret = adreno_ib_add(process,
440 pkt[2], SNAPSHOT_GPU_OBJECT_GENERIC,
441 ib_obj_list);
442 }
443 break;
444 case CP_DRAW_INDX_INDIRECT:
445 if (type3_pkt_size(pkt[0]) == 4) {
446 ret = adreno_ib_add(process,
447 pkt[2], SNAPSHOT_GPU_OBJECT_GENERIC,
448 ib_obj_list);
449 if (ret)
450 break;
451 ret = adreno_ib_add(process,
452 pkt[4], SNAPSHOT_GPU_OBJECT_GENERIC,
453 ib_obj_list);
454 }
455 break;
456 case CP_DRAW_AUTO:
457 if (type3_pkt_size(pkt[0]) == 6) {
458 ret = adreno_ib_add(process,
459 pkt[3], SNAPSHOT_GPU_OBJECT_GENERIC,
460 ib_obj_list);
461 if (ret)
462 break;
463 ret = adreno_ib_add(process,
464 pkt[4], SNAPSHOT_GPU_OBJECT_GENERIC,
465 ib_obj_list);
466 }
467 break;
468 }
469
470 if (ret)
471 return ret;
472 /*
473 * All of the type0 writes are valid at a draw initiator, so freeze
474 * the various buffers that we are tracking
475 */
476 ret = ib_add_type0_entries(device, process, ib_obj_list,
477 ib_parse_vars);
478 if (ret)
479 return ret;
480 /* Process set draw state command streams if any */
481 for (i = 0; i < NUM_SET_DRAW_GROUPS; i++) {
482 if (!ib_parse_vars->set_draw_groups[i].cmd_stream_dwords)
483 continue;
484 ret = adreno_ib_find_objs(device, process,
485 ib_parse_vars->set_draw_groups[i].cmd_stream_addr,
486 ib_parse_vars->set_draw_groups[i].cmd_stream_dwords,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530487 0, SNAPSHOT_GPU_OBJECT_DRAW,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700488 ib_obj_list, 2);
489 if (ret)
490 break;
491 }
492 return ret;
493}
494
495/*
496 * Parse all the type7 opcode packets that may contain important information,
497 * such as additional GPU buffers to grab or a draw initator
498 */
499
500static int ib_parse_type7(struct kgsl_device *device, unsigned int *ptr,
501 struct kgsl_process_private *process,
502 struct adreno_ib_object_list *ib_obj_list,
503 struct ib_parser_variables *ib_parse_vars)
504{
505 int opcode = cp_type7_opcode(*ptr);
506
507 switch (opcode) {
508 case CP_SET_DRAW_STATE:
509 return ib_parse_type7_set_draw_state(device, ptr, process,
510 ib_obj_list);
511 }
512
513 return 0;
514}
515
516/*
517 * Parse all the type3 opcode packets that may contain important information,
518 * such as additional GPU buffers to grab or a draw initator
519 */
520
521static int ib_parse_type3(struct kgsl_device *device, unsigned int *ptr,
522 struct kgsl_process_private *process,
523 struct adreno_ib_object_list *ib_obj_list,
524 struct ib_parser_variables *ib_parse_vars)
525{
526 int opcode = cp_type3_opcode(*ptr);
527
528 switch (opcode) {
529 case CP_LOAD_STATE:
530 return ib_parse_load_state(ptr, process, ib_obj_list,
531 ib_parse_vars);
532 case CP_SET_BIN_DATA:
533 return ib_parse_set_bin_data(ptr, process, ib_obj_list,
534 ib_parse_vars);
535 case CP_MEM_WRITE:
536 return ib_parse_mem_write(ptr, process, ib_obj_list,
537 ib_parse_vars);
538 case CP_DRAW_INDX:
539 case CP_DRAW_INDX_OFFSET:
540 case CP_DRAW_INDIRECT:
541 case CP_DRAW_INDX_INDIRECT:
542 return ib_parse_draw_indx(device, ptr, process, ib_obj_list,
543 ib_parse_vars);
544 case CP_SET_DRAW_STATE:
545 return ib_parse_set_draw_state(device, ptr, process,
546 ib_obj_list, ib_parse_vars);
547 }
548
549 return 0;
550}
551
552/*
553 * Parse type0 packets found in the stream. Some of the registers that are
554 * written are clues for GPU buffers that we need to freeze. Register writes
555 * are considred valid when a draw initator is called, so just cache the values
556 * here and freeze them when a CP_DRAW_INDX is seen. This protects against
557 * needlessly caching buffers that won't be used during a draw call
558 */
559
560static int ib_parse_type0(struct kgsl_device *device, unsigned int *ptr,
561 struct kgsl_process_private *process,
562 struct adreno_ib_object_list *ib_obj_list,
563 struct ib_parser_variables *ib_parse_vars)
564{
565 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
566 int size = type0_pkt_size(*ptr);
567 int offset = type0_pkt_offset(*ptr);
568 int i;
569 int reg_index;
570 int ret = 0;
571
572 for (i = 0; i < size; i++, offset++) {
573 /* Visiblity stream buffer */
574 if (offset >= adreno_cp_parser_getreg(adreno_dev,
575 ADRENO_CP_ADDR_VSC_PIPE_DATA_ADDRESS_0) &&
576 offset <= adreno_cp_parser_getreg(adreno_dev,
577 ADRENO_CP_ADDR_VSC_PIPE_DATA_LENGTH_7)) {
578 reg_index = adreno_cp_parser_regindex(
579 adreno_dev, offset,
580 ADRENO_CP_ADDR_VSC_PIPE_DATA_ADDRESS_0,
581 ADRENO_CP_ADDR_VSC_PIPE_DATA_LENGTH_7);
582 if (reg_index >= 0)
583 ib_parse_vars->cp_addr_regs[reg_index] =
584 ptr[i + 1];
585 continue;
586 } else if ((offset >= adreno_cp_parser_getreg(adreno_dev,
587 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_0)) &&
588 (offset <= adreno_cp_parser_getreg(adreno_dev,
589 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_15))) {
590 reg_index = adreno_cp_parser_regindex(adreno_dev,
591 offset,
592 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_0,
593 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_15);
594 if (reg_index >= 0)
595 ib_parse_vars->cp_addr_regs[reg_index] =
596 ptr[i + 1];
597 continue;
598 } else if ((offset >= adreno_cp_parser_getreg(adreno_dev,
599 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_16)) &&
600 (offset <= adreno_cp_parser_getreg(adreno_dev,
601 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_31))) {
602 reg_index = adreno_cp_parser_regindex(adreno_dev,
603 offset,
604 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_16,
605 ADRENO_CP_ADDR_VFD_FETCH_INSTR_1_31);
606 if (reg_index >= 0)
607 ib_parse_vars->cp_addr_regs[reg_index] =
608 ptr[i + 1];
609 continue;
610 } else {
611 if (offset ==
612 adreno_cp_parser_getreg(adreno_dev,
613 ADRENO_CP_ADDR_VSC_SIZE_ADDRESS))
614 ib_parse_vars->cp_addr_regs[
615 ADRENO_CP_ADDR_VSC_SIZE_ADDRESS] =
616 ptr[i + 1];
617 else if (offset == adreno_cp_parser_getreg(adreno_dev,
618 ADRENO_CP_ADDR_SP_VS_PVT_MEM_ADDR))
619 ib_parse_vars->cp_addr_regs[
620 ADRENO_CP_ADDR_SP_VS_PVT_MEM_ADDR] =
621 ptr[i + 1];
622 else if (offset == adreno_cp_parser_getreg(adreno_dev,
623 ADRENO_CP_ADDR_SP_FS_PVT_MEM_ADDR))
624 ib_parse_vars->cp_addr_regs[
625 ADRENO_CP_ADDR_SP_FS_PVT_MEM_ADDR] =
626 ptr[i + 1];
627 else if (offset == adreno_cp_parser_getreg(adreno_dev,
628 ADRENO_CP_ADDR_SP_VS_OBJ_START_REG))
629 ib_parse_vars->cp_addr_regs[
630 ADRENO_CP_ADDR_SP_VS_OBJ_START_REG] =
631 ptr[i + 1];
632 else if (offset == adreno_cp_parser_getreg(adreno_dev,
633 ADRENO_CP_ADDR_SP_FS_OBJ_START_REG))
634 ib_parse_vars->cp_addr_regs[
635 ADRENO_CP_ADDR_SP_FS_OBJ_START_REG] =
636 ptr[i + 1];
637 else if ((offset == adreno_cp_parser_getreg(adreno_dev,
638 ADRENO_CP_UCHE_INVALIDATE0)) ||
639 (offset == adreno_cp_parser_getreg(adreno_dev,
640 ADRENO_CP_UCHE_INVALIDATE1))) {
641 ret = adreno_ib_add(process,
642 ptr[i + 1] & 0xFFFFFFC0,
643 SNAPSHOT_GPU_OBJECT_GENERIC,
644 ib_obj_list);
645 if (ret)
646 break;
647 }
648 }
649 }
650 return ret;
651}
652
653static int ib_parse_type7_set_draw_state(struct kgsl_device *device,
654 unsigned int *ptr,
655 struct kgsl_process_private *process,
656 struct adreno_ib_object_list *ib_obj_list)
657{
658 int size = type7_pkt_size(*ptr);
659 int i;
660 int grp_id;
661 int ret = 0;
662 int flags;
663 uint64_t cmd_stream_dwords;
664 uint64_t cmd_stream_addr;
665
666 /*
667 * size is the size of the packet that does not include the DWORD
668 * for the packet header, we only want to loop here through the
669 * packet parameters from ptr[1] till ptr[size] where ptr[0] is the
670 * packet header. In each loop we look at 3 DWORDS hence increment
671 * loop counter by 3 always
672 */
673 for (i = 1; i <= size; i += 3) {
674 grp_id = (ptr[i] & 0x1F000000) >> 24;
675 /* take action based on flags */
676 flags = (ptr[i] & 0x000F0000) >> 16;
677
678 /*
679 * dirty flag or no flags both mean we need to load it for
680 * next draw. No flags is used when the group is activated
681 * or initialized for the first time in the IB
682 */
683 if (flags & 0x1 || !flags) {
684 cmd_stream_dwords = ptr[i] & 0x0000FFFF;
685 cmd_stream_addr = ptr[i + 2];
686 cmd_stream_addr = cmd_stream_addr << 32 | ptr[i + 1];
687 if (cmd_stream_dwords)
688 ret = adreno_ib_find_objs(device, process,
689 cmd_stream_addr, cmd_stream_dwords,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530690 0, SNAPSHOT_GPU_OBJECT_DRAW,
691 ib_obj_list, 2);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700692 if (ret)
693 break;
694 continue;
695 }
696 /* load immediate */
697 if (flags & 0x8) {
698 uint64_t gpuaddr = ptr[i + 2];
699
700 gpuaddr = gpuaddr << 32 | ptr[i + 1];
701 ret = adreno_ib_find_objs(device, process,
702 gpuaddr, (ptr[i] & 0x0000FFFF),
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530703 0, SNAPSHOT_GPU_OBJECT_IB,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700704 ib_obj_list, 2);
705 if (ret)
706 break;
707 }
708 }
709 return ret;
710}
711
712static int ib_parse_set_draw_state(struct kgsl_device *device,
713 unsigned int *ptr,
714 struct kgsl_process_private *process,
715 struct adreno_ib_object_list *ib_obj_list,
716 struct ib_parser_variables *ib_parse_vars)
717{
718 int size = type0_pkt_size(*ptr);
719 int i;
720 int grp_id;
721 int ret = 0;
722 int flags;
723
724 /*
725 * size is the size of the packet that does not include the DWORD
726 * for the packet header, we only want to loop here through the
727 * packet parameters from ptr[1] till ptr[size] where ptr[0] is the
728 * packet header. In each loop we look at 2 DWORDS hence increment
729 * loop counter by 2 always
730 */
731 for (i = 1; i <= size; i += 2) {
732 grp_id = (ptr[i] & 0x1F000000) >> 24;
733 /* take action based on flags */
734 flags = (ptr[i] & 0x000F0000) >> 16;
735 /* Disable all groups */
736 if (flags & 0x4) {
737 int j;
738
739 for (j = 0; j < NUM_SET_DRAW_GROUPS; j++)
740 ib_parse_vars->set_draw_groups[j].
741 cmd_stream_dwords = 0;
742 continue;
743 }
744 /* disable flag */
745 if (flags & 0x2) {
746 ib_parse_vars->set_draw_groups[grp_id].
747 cmd_stream_dwords = 0;
748 continue;
749 }
750 /*
751 * dirty flag or no flags both mean we need to load it for
752 * next draw. No flags is used when the group is activated
753 * or initialized for the first time in the IB
754 */
755 if (flags & 0x1 || !flags) {
756 ib_parse_vars->set_draw_groups[grp_id].
757 cmd_stream_dwords = ptr[i] & 0x0000FFFF;
758 ib_parse_vars->set_draw_groups[grp_id].
759 cmd_stream_addr = ptr[i + 1];
760 continue;
761 }
762 /* load immediate */
763 if (flags & 0x8) {
764 ret = adreno_ib_find_objs(device, process,
765 ptr[i + 1], (ptr[i] & 0x0000FFFF),
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530766 0, SNAPSHOT_GPU_OBJECT_IB,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700767 ib_obj_list, 2);
768 if (ret)
769 break;
770 }
771 }
772 return ret;
773}
774
775/*
776 * adreno_cp_parse_ib2() - Wrapper function around IB2 parsing
777 * @device: Device pointer
778 * @process: Process in which the IB is allocated
779 * @gpuaddr: IB2 gpuaddr
780 * @dwords: IB2 size in dwords
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530781 * @ib2base: Base address of active IB2
Shrenuj Bansala419c792016-10-20 14:05:11 -0700782 * @ib_obj_list: List of objects found in IB
783 * @ib_level: The level from which function is called, either from IB1 or IB2
784 *
785 * Function does some checks to ensure that IB2 parsing is called from IB1
786 * and then calls the function to find objects in IB2.
787 */
788static int adreno_cp_parse_ib2(struct kgsl_device *device,
789 struct kgsl_process_private *process,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530790 uint64_t gpuaddr, uint64_t dwords, uint64_t ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700791 struct adreno_ib_object_list *ib_obj_list,
792 int ib_level)
793{
794 int i;
795
796 /*
797 * We can only expect an IB2 in IB1, if we are
798 * already processing an IB2 then return error
799 */
800 if (ib_level == 2)
801 return -EINVAL;
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530802
803 /* Save current IB2 statically */
804 if (ib2base == gpuaddr)
805 kgsl_snapshot_push_object(process, gpuaddr, dwords);
Shrenuj Bansala419c792016-10-20 14:05:11 -0700806 /*
807 * only try to find sub objects iff this IB has
808 * not been processed already
809 */
810 for (i = 0; i < ib_obj_list->num_objs; i++) {
811 struct adreno_ib_object *ib_obj = &(ib_obj_list->obj_list[i]);
812
813 if ((ib_obj->snapshot_obj_type == SNAPSHOT_GPU_OBJECT_IB) &&
814 (gpuaddr >= ib_obj->gpuaddr) &&
815 (gpuaddr + dwords * sizeof(unsigned int) <=
816 ib_obj->gpuaddr + ib_obj->size))
817 return 0;
818 }
819
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530820 return adreno_ib_find_objs(device, process, gpuaddr, dwords, ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700821 SNAPSHOT_GPU_OBJECT_IB, ib_obj_list, 2);
822}
823
824/*
825 * adreno_ib_find_objs() - Find all IB objects in a given IB
826 * @device: The device pointer on which the IB executes
827 * @process: The process in which the IB and all contained objects are mapped.
828 * @gpuaddr: The gpu address of the IB
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530829 * @ib2base: IB2 base address
Shrenuj Bansala419c792016-10-20 14:05:11 -0700830 * @dwords: Size of ib in dwords
831 * @obj_type: The object type can be either an IB or a draw state sequence
832 * @ib_obj_list: The list in which the IB and the objects in it are added.
833 * @ib_level: Indicates if IB1 or IB2 is being processed
834 *
835 * Finds all IB objects in a given IB and puts then in a list. Can be called
836 * recursively for the IB2's in the IB1's
837 * Returns 0 on success else error code
838 */
839static int adreno_ib_find_objs(struct kgsl_device *device,
840 struct kgsl_process_private *process,
841 uint64_t gpuaddr, uint64_t dwords,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530842 uint64_t ib2base, int obj_type,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700843 struct adreno_ib_object_list *ib_obj_list,
844 int ib_level)
845{
846 int ret = 0;
847 uint64_t rem = dwords;
848 int i;
849 struct ib_parser_variables ib_parse_vars;
850 unsigned int *src;
851 struct adreno_ib_object *ib_obj;
852 struct kgsl_mem_entry *entry;
853 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
854
855 /* check that this IB is not already on list */
856 for (i = 0; i < ib_obj_list->num_objs; i++) {
857 ib_obj = &(ib_obj_list->obj_list[i]);
858 if ((obj_type == ib_obj->snapshot_obj_type) &&
859 (ib_obj->gpuaddr <= gpuaddr) &&
860 ((ib_obj->gpuaddr + ib_obj->size) >=
861 (gpuaddr + (dwords << 2))))
862 return 0;
863 }
864
865 entry = kgsl_sharedmem_find(process, gpuaddr);
866 if (!entry)
867 return -EINVAL;
868
869 if (!kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, (dwords << 2))) {
870 kgsl_mem_entry_put(entry);
871 return -EINVAL;
872 }
873
874 src = kgsl_gpuaddr_to_vaddr(&entry->memdesc, gpuaddr);
875 if (!src) {
876 kgsl_mem_entry_put(entry);
877 return -EINVAL;
878 }
879
880 memset(&ib_parse_vars, 0, sizeof(struct ib_parser_variables));
881
882 ret = adreno_ib_add(process, gpuaddr, obj_type, ib_obj_list);
883 if (ret)
884 goto done;
885
886 for (i = 0; rem > 0; rem--, i++) {
887 int pktsize;
888
889 if (pkt_is_type0(src[i]))
890 pktsize = type0_pkt_size(src[i]);
891
892 else if (pkt_is_type3(src[i]))
893 pktsize = type3_pkt_size(src[i]);
894
895 else if (pkt_is_type4(src[i]))
896 pktsize = type4_pkt_size(src[i]);
897
898 else if (pkt_is_type7(src[i]))
899 pktsize = type7_pkt_size(src[i]);
900
901 /*
902 * If the packet isn't a type 1, type 3, type 4 or type 7 then
903 * don't bother parsing it - it is likely corrupted
904 */
905 else
906 break;
907
908 if (((pkt_is_type0(src[i]) || pkt_is_type3(src[i])) && !pktsize)
909 || ((pktsize + 1) > rem))
910 break;
911
912 if (pkt_is_type3(src[i])) {
913 if (adreno_cmd_is_ib(adreno_dev, src[i])) {
914 uint64_t gpuaddrib2 = src[i + 1];
915 uint64_t size = src[i + 2];
916
917 ret = adreno_cp_parse_ib2(device, process,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530918 gpuaddrib2, size, ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700919 ib_obj_list, ib_level);
920 if (ret)
921 goto done;
922 } else {
923 ret = ib_parse_type3(device, &src[i], process,
924 ib_obj_list,
925 &ib_parse_vars);
926 /*
927 * If the parse function failed (probably
928 * because of a bad decode) then bail out and
929 * just capture the binary IB data
930 */
931
932 if (ret)
933 goto done;
934 }
935 }
936
937 else if (pkt_is_type7(src[i])) {
938 if (adreno_cmd_is_ib(adreno_dev, src[i])) {
939 uint64_t size = src[i + 3];
940 uint64_t gpuaddrib2 = src[i + 2];
941
942 gpuaddrib2 = gpuaddrib2 << 32 | src[i + 1];
943
944 ret = adreno_cp_parse_ib2(device, process,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530945 gpuaddrib2, size, ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -0700946 ib_obj_list, ib_level);
947 if (ret)
948 goto done;
949 } else {
950 ret = ib_parse_type7(device, &src[i], process,
951 ib_obj_list,
952 &ib_parse_vars);
953 /*
954 * If the parse function failed (probably
955 * because of a bad decode) then bail out and
956 * just capture the binary IB data
957 */
958
959 if (ret)
960 goto done;
961 }
962 }
963
964 else if (pkt_is_type0(src[i])) {
965 ret = ib_parse_type0(device, &src[i], process,
966 ib_obj_list, &ib_parse_vars);
967 if (ret)
968 goto done;
969 }
970
971 i += pktsize;
972 rem -= pktsize;
973 }
974
975done:
976 /*
977 * For set draw objects there may not be a draw_indx packet at its end
978 * to signal that we need to save the found objects in it, so just save
979 * it here.
980 */
981 if (!ret && SNAPSHOT_GPU_OBJECT_DRAW == obj_type)
982 ret = ib_add_type0_entries(device, process, ib_obj_list,
983 &ib_parse_vars);
984
985 kgsl_memdesc_unmap(&entry->memdesc);
986 kgsl_mem_entry_put(entry);
987 return ret;
988}
989
990
991/*
992 * adreno_ib_create_object_list() - Find all the memory objects in IB
993 * @device: The device pointer on which the IB executes
994 * @process: The process in which the IB and all contained objects are mapped
995 * @gpuaddr: The gpu address of the IB
996 * @dwords: Size of ib in dwords
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +0530997 * @ib2base: Base address of active IB2
Shrenuj Bansala419c792016-10-20 14:05:11 -0700998 * @ib_obj_list: The list in which the IB and the objects in it are added.
999 *
1000 * Find all the memory objects that an IB needs for execution and place
1001 * them in a list including the IB.
1002 * Returns the ib object list. On success 0 is returned, on failure error
1003 * code is returned along with number of objects that was saved before
1004 * error occurred. If no objects found then the list pointer is set to
1005 * NULL.
1006 */
1007int adreno_ib_create_object_list(struct kgsl_device *device,
1008 struct kgsl_process_private *process,
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +05301009 uint64_t gpuaddr, uint64_t dwords, uint64_t ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -07001010 struct adreno_ib_object_list **out_ib_obj_list)
1011{
1012 int ret = 0;
1013 struct adreno_ib_object_list *ib_obj_list;
1014
1015 if (!out_ib_obj_list)
1016 return -EINVAL;
1017
1018 *out_ib_obj_list = NULL;
1019
1020 ib_obj_list = kzalloc(sizeof(*ib_obj_list), GFP_KERNEL);
1021 if (!ib_obj_list)
1022 return -ENOMEM;
1023
1024 ib_obj_list->obj_list = vmalloc(MAX_IB_OBJS *
1025 sizeof(struct adreno_ib_object));
1026
1027 if (!ib_obj_list->obj_list) {
1028 kfree(ib_obj_list);
1029 return -ENOMEM;
1030 }
1031
Hareesh Gundu9c6b1fa2017-01-06 15:37:09 +05301032 ret = adreno_ib_find_objs(device, process, gpuaddr, dwords, ib2base,
Shrenuj Bansala419c792016-10-20 14:05:11 -07001033 SNAPSHOT_GPU_OBJECT_IB, ib_obj_list, 1);
1034
1035 /* Even if there was an error return the remaining objects found */
1036 if (ib_obj_list->num_objs)
1037 *out_ib_obj_list = ib_obj_list;
1038
1039 return ret;
1040}
1041
1042/*
1043 * adreno_ib_destroy_obj_list() - Destroy an ib object list
1044 * @ib_obj_list: List to destroy
1045 *
1046 * Free up all resources used by an ib_obj_list
1047 */
1048void adreno_ib_destroy_obj_list(struct adreno_ib_object_list *ib_obj_list)
1049{
1050 int i;
1051
1052 if (!ib_obj_list)
1053 return;
1054
1055 for (i = 0; i < ib_obj_list->num_objs; i++) {
1056 if (ib_obj_list->obj_list[i].entry)
1057 kgsl_mem_entry_put(ib_obj_list->obj_list[i].entry);
1058 }
1059 vfree(ib_obj_list->obj_list);
1060 kfree(ib_obj_list);
1061}