blob: 082df4bc0c7ffbcf0d7f475821e2d97990de7ed9 [file] [log] [blame]
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001/* Copyright (c) 2012, Code Aurora Forum. 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 "a2xx_reg.h"
20
21/* Number of dwords of ringbuffer history to record */
22#define NUM_DWORDS_OF_RINGBUFFER_HISTORY 100
23
24/* Maintain a list of the objects we see during parsing */
25
26#define SNAPSHOT_OBJ_BUFSIZE 64
27
28#define SNAPSHOT_OBJ_TYPE_IB 0
29
Jordan Crouse9610b6b2012-03-16 14:53:42 -060030/* Keep track of how many bytes are frozen after a snapshot and tell the user */
31static int snapshot_frozen_objsize;
32
Jordan Crouse156cfbc2012-01-24 09:32:04 -070033static struct kgsl_snapshot_obj {
34 int type;
35 uint32_t gpuaddr;
36 uint32_t ptbase;
37 void *ptr;
38 int dwords;
39} objbuf[SNAPSHOT_OBJ_BUFSIZE];
40
41/* Pointer to the next open entry in the object list */
42static int objbufptr;
43
44/* Push a new buffer object onto the list */
45static void push_object(struct kgsl_device *device, int type, uint32_t ptbase,
46 uint32_t gpuaddr, int dwords)
47{
48 int index;
49 void *ptr;
50
Jordan Crousee9e91bf2012-02-21 09:48:36 -070051 /*
52 * Sometimes IBs can be reused in the same dump. Because we parse from
53 * oldest to newest, if we come across an IB that has already been used,
54 * assume that it has been reused and update the list with the newest
55 * size.
56 */
57
Jordan Crouse156cfbc2012-01-24 09:32:04 -070058 for (index = 0; index < objbufptr; index++) {
59 if (objbuf[index].gpuaddr == gpuaddr &&
Jordan Crousee9e91bf2012-02-21 09:48:36 -070060 objbuf[index].ptbase == ptbase) {
61 objbuf[index].dwords = dwords;
62 return;
63 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -070064 }
65
66 if (objbufptr == SNAPSHOT_OBJ_BUFSIZE) {
67 KGSL_DRV_ERR(device, "snapshot: too many snapshot objects\n");
68 return;
69 }
70
71 /*
72 * adreno_convertaddr verifies that the IB size is valid - at least in
73 * the context of it being smaller then the allocated memory space
74 */
75 ptr = adreno_convertaddr(device, ptbase, gpuaddr, dwords << 2);
76
77 if (ptr == NULL) {
78 KGSL_DRV_ERR(device,
79 "snapshot: Can't find GPU address for %x\n", gpuaddr);
80 return;
81 }
82
83 /* Put it on the list of things to parse */
84 objbuf[objbufptr].type = type;
85 objbuf[objbufptr].gpuaddr = gpuaddr;
86 objbuf[objbufptr].ptbase = ptbase;
87 objbuf[objbufptr].dwords = dwords;
88 objbuf[objbufptr++].ptr = ptr;
89}
90
Jordan Crousee9e91bf2012-02-21 09:48:36 -070091/*
92 * Return a 1 if the specified object is already on the list of buffers
93 * to be dumped
94 */
95
96static int find_object(int type, unsigned int gpuaddr, unsigned int ptbase)
97{
98 int index;
99
100 for (index = 0; index < objbufptr; index++) {
101 if (objbuf[index].gpuaddr == gpuaddr &&
102 objbuf[index].ptbase == ptbase &&
103 objbuf[index].type == type)
104 return 1;
105 }
106
107 return 0;
108}
109
Jordan Crouseea2c6382012-03-16 14:53:42 -0600110static void ib_parse_load_state(struct kgsl_device *device, unsigned int *pkt,
111 unsigned int ptbase)
112{
113 unsigned int block, source, type;
114
115 /*
116 * The object here is to find indirect shaders i.e - shaders loaded from
117 * GPU memory instead of directly in the command. These should be added
118 * to the list of memory objects to dump. So look at the load state
119 * call and see if 1) the shader block is a shader (block = 4, 5 or 6)
120 * 2) that the block is indirect (source = 4). If these all match then
121 * add the memory address to the list. The size of the object will
122 * differ depending on the type. Type 0 (instructions) are 8 dwords per
123 * unit and type 1 (constants) are 2 dwords per unit.
124 */
125
126 if (type3_pkt_size(pkt[0]) < 2)
127 return;
128
129 /*
130 * pkt[1] 18:16 - source
131 * pkt[1] 21:19 - state block
132 * pkt[1] 31:22 - size in units
133 * pkt[2] 0:1 - type
134 * pkt[2] 31:2 - GPU memory address
135 */
136
137 block = (pkt[1] >> 19) & 0x07;
138 source = (pkt[1] >> 16) & 0x07;
139 type = pkt[2] & 0x03;
140
141 if ((block == 4 || block == 5 || block == 6) && source == 4) {
142 int unitsize = (type == 0) ? 8 : 2;
143 int ret;
144
145 /* Freeze the GPU buffer containing the shader */
146
147 ret = kgsl_snapshot_get_object(device, ptbase,
148 pkt[2] & 0xFFFFFFFC,
149 (((pkt[1] >> 22) & 0x03FF) * unitsize) << 2,
150 SNAPSHOT_GPU_OBJECT_SHADER);
151 snapshot_frozen_objsize += ret;
152 }
153}
154
155/*
156 * Parse all the type3 opcode packets that may contain important information,
157 * such as additional GPU buffers to grab
158 */
159
160static void ib_parse_type3(struct kgsl_device *device, unsigned int *ptr,
161 unsigned int ptbase)
162{
163 switch (cp_type3_opcode(*ptr)) {
164 case CP_LOAD_STATE:
165 ib_parse_load_state(device, ptr, ptbase);
166 break;
167 }
168}
169
Jordan Crousef99f5a662012-03-16 14:53:43 -0600170/* Add an IB as a GPU object, but first, parse it to find more goodies within */
171
172static void ib_add_gpu_object(struct kgsl_device *device, unsigned int ptbase,
173 unsigned int gpuaddr, unsigned int dwords)
174{
175 int i, ret;
176 unsigned int *src = (unsigned int *) adreno_convertaddr(device, ptbase,
177 gpuaddr, dwords << 2);
178
179 if (src == NULL)
180 return;
181
182 for (i = 0; i < dwords; i++) {
183 if (pkt_is_type3(src[i])) {
184 if ((dwords - i) < type3_pkt_size(src[i]) + 1)
185 continue;
186
187 if (adreno_cmd_is_ib(src[i]))
188 ib_add_gpu_object(device, ptbase,
189 src[i + 1], src[i + 2]);
190 else
191 ib_parse_type3(device, &src[i], ptbase);
192 }
193 }
194
195 ret = kgsl_snapshot_get_object(device, ptbase, gpuaddr, dwords << 2,
196 SNAPSHOT_GPU_OBJECT_IB);
197
198 snapshot_frozen_objsize += ret;
199}
200
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700201/* Snapshot the istore memory */
202static int snapshot_istore(struct kgsl_device *device, void *snapshot,
203 int remain, void *priv)
204{
205 struct kgsl_snapshot_istore *header = snapshot;
206 unsigned int *data = snapshot + sizeof(*header);
207 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
208 int count, i;
209
Jordan Crousec6b3a992012-02-04 10:23:51 -0700210 count = adreno_dev->istore_size * adreno_dev->instruction_size;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700211
212 if (remain < (count * 4) + sizeof(*header)) {
213 KGSL_DRV_ERR(device,
214 "snapshot: Not enough memory for the istore section");
215 return 0;
216 }
217
218 header->count = adreno_dev->istore_size;
219
220 for (i = 0; i < count; i++)
221 kgsl_regread(device, ADRENO_ISTORE_START + i, &data[i]);
222
223 return (count * 4) + sizeof(*header);
224}
225
226/* Snapshot the ringbuffer memory */
227static int snapshot_rb(struct kgsl_device *device, void *snapshot,
228 int remain, void *priv)
229{
230 struct kgsl_snapshot_rb *header = snapshot;
231 unsigned int *data = snapshot + sizeof(*header);
232 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
233 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
Jordan Crousef99f5a662012-03-16 14:53:43 -0600234 unsigned int rbbase, ptbase, rptr, *rbptr, ibbase;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700235 int start, stop, index;
236 int numitems, size;
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700237 int parse_ibs = 0, ib_parse_start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700238
239 /* Get the GPU address of the ringbuffer */
240 kgsl_regread(device, REG_CP_RB_BASE, &rbbase);
241
242 /* Get the physical address of the MMU pagetable */
243 ptbase = kgsl_mmu_get_current_ptbase(device);
244
245 /* Get the current read pointers for the RB */
246 kgsl_regread(device, REG_CP_RB_RPTR, &rptr);
247
Jordan Crousef99f5a662012-03-16 14:53:43 -0600248 /*
249 * Get the address of the last executed IB1 so we can be sure to
250 * snapshot it
251 */
252
253 kgsl_regread(device, REG_CP_IB1_BASE, &ibbase);
254
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700255 /* start the dump at the rptr minus some history */
256 start = (int) rptr - NUM_DWORDS_OF_RINGBUFFER_HISTORY;
257 if (start < 0)
258 start += rb->sizedwords;
259
260 /*
261 * Stop the dump at the point where the software last wrote. Don't use
262 * the hardware value here on the chance that it didn't get properly
263 * updated
264 */
265
266 stop = (int) rb->wptr + 16;
267 if (stop > rb->sizedwords)
268 stop -= rb->sizedwords;
269
270 /* Set up the header for the section */
271
272 numitems = (stop > start) ? stop - start :
273 (rb->sizedwords - start) + stop;
274
275 size = (numitems << 2);
276
277 if (remain < size + sizeof(*header)) {
278 KGSL_DRV_ERR(device,
279 "snapshot: Not enough memory for the rb section");
280 return 0;
281 }
282
283 /* Write the sub-header for the section */
284 header->start = start;
285 header->end = stop;
286 header->wptr = rb->wptr;
287 header->rbsize = rb->sizedwords;
288 header->count = numitems;
289
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700290 /*
291 * We can only reliably dump IBs from the beginning of the context,
292 * and it turns out that for the vast majority of the time we really
293 * only care about the current context when it comes to diagnosing
294 * a hang. So, with an eye to limiting the buffer dumping to what is
295 * really useful find the beginning of the context and only dump
296 * IBs from that point
297 */
298
299 index = rptr;
300 ib_parse_start = start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700301 rbptr = rb->buffer_desc.hostptr;
302
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700303 while (index != start) {
304 index--;
305
306 if (index < 0) {
307 /*
308 * The marker we are looking for is 2 dwords long, so
309 * when wrapping, go back 2 from the end so we don't
310 * access out of range in the if statement below
311 */
312 index = rb->sizedwords - 2;
313
314 /*
315 * Account for the possibility that start might be at
316 * rb->sizedwords - 1
317 */
318
319 if (start == rb->sizedwords - 1)
320 break;
321 }
322
323 /*
324 * Look for a NOP packet with the context switch identifier in
325 * the second dword
326 */
327
328 if (rbptr[index] == cp_nop_packet(1) &&
329 rbptr[index + 1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
330 ib_parse_start = index;
331 break;
332 }
333 }
334
335 index = start;
336
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700337 /*
338 * Loop through the RB, copying the data and looking for indirect
339 * buffers and MMU pagetable changes
340 */
341
342 while (index != rb->wptr) {
343 *data = rbptr[index];
344
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700345 /* Only parse IBs between the context start and the rptr */
346
347 if (index == ib_parse_start)
348 parse_ibs = 1;
349
350 if (index == rptr)
351 parse_ibs = 0;
352
Jordan Crousef99f5a662012-03-16 14:53:43 -0600353 if (parse_ibs && adreno_cmd_is_ib(rbptr[index])) {
354 /*
355 * The IB from CP_IB1_BASE goes into the snapshot, all
356 * others get marked at GPU objects
357 */
358 if (rbptr[index + 1] == ibbase)
359 push_object(device, SNAPSHOT_OBJ_TYPE_IB,
360 ptbase, rbptr[index + 1],
361 rbptr[index + 2]);
362 else
363 ib_add_gpu_object(device, ptbase,
364 rbptr[index + 1], rbptr[index + 2]);
365 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700366
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700367 index = index + 1;
368
369 if (index == rb->sizedwords)
370 index = 0;
371
372 data++;
373 }
374
375 /* Dump 16 dwords past the wptr, but don't bother interpeting it */
376
377 while (index != stop) {
378 *data = rbptr[index];
379 index = index + 1;
380
381 if (index == rb->sizedwords)
382 index = 0;
383
384 data++;
385 }
386
387 /* Return the size of the section */
388 return size + sizeof(*header);
389}
390
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700391static int snapshot_ib(struct kgsl_device *device, void *snapshot,
392 int remain, void *priv)
393{
394 struct kgsl_snapshot_ib *header = snapshot;
395 struct kgsl_snapshot_obj *obj = priv;
396 unsigned int *src = obj->ptr;
397 unsigned int *dst = snapshot + sizeof(*header);
398 int i;
399
400 if (remain < (obj->dwords << 2) + sizeof(*header)) {
401 KGSL_DRV_ERR(device,
402 "snapshot: Not enough memory for the ib section");
403 return 0;
404 }
405
406 /* Write the sub-header for the section */
407 header->gpuaddr = obj->gpuaddr;
408 header->ptbase = obj->ptbase;
409 header->size = obj->dwords;
410
411 /* Write the contents of the ib */
Jordan Crouseea2c6382012-03-16 14:53:42 -0600412 for (i = 0; i < obj->dwords; i++, src++, dst++) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700413 *dst = *src;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700414
Jordan Crouseea2c6382012-03-16 14:53:42 -0600415 if (pkt_is_type3(*src)) {
416 if ((obj->dwords - i) < type3_pkt_size(*src) + 1)
417 continue;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700418
Jordan Crouseea2c6382012-03-16 14:53:42 -0600419 if (adreno_cmd_is_ib(*src))
420 push_object(device, SNAPSHOT_OBJ_TYPE_IB,
421 obj->ptbase, src[1], src[2]);
422 else
423 ib_parse_type3(device, src, obj->ptbase);
424 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700425 }
426
427 return (obj->dwords << 2) + sizeof(*header);
428}
429
430/* Dump another item on the current pending list */
431static void *dump_object(struct kgsl_device *device, int obj, void *snapshot,
432 int *remain)
433{
434 switch (objbuf[obj].type) {
435 case SNAPSHOT_OBJ_TYPE_IB:
436 snapshot = kgsl_snapshot_add_section(device,
437 KGSL_SNAPSHOT_SECTION_IB, snapshot, remain,
438 snapshot_ib, &objbuf[obj]);
439 break;
440 default:
441 KGSL_DRV_ERR(device,
442 "snapshot: Invalid snapshot object type: %d\n",
443 objbuf[obj].type);
444 break;
445 }
446
447 return snapshot;
448}
449
450/* adreno_snapshot - Snapshot the Adreno GPU state
451 * @device - KGSL device to snapshot
452 * @snapshot - Pointer to the start of memory to write into
453 * @remain - A pointer to how many bytes of memory are remaining in the snapshot
454 * @hang - set if this snapshot was automatically triggered by a GPU hang
455 * This is a hook function called by kgsl_snapshot to snapshot the
456 * Adreno specific information for the GPU snapshot. In turn, this function
457 * calls the GPU specific snapshot function to get core specific information.
458 */
459
460void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
461 int hang)
462{
463 int i;
464 uint32_t ptbase, ibbase, ibsize;
465 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
466
467 /* Reset the list of objects */
468 objbufptr = 0;
469
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600470 snapshot_frozen_objsize = 0;
471
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700472 /* Get the physical address of the MMU pagetable */
473 ptbase = kgsl_mmu_get_current_ptbase(device);
474
475 /* Dump the ringbuffer */
476 snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB,
477 snapshot, remain, snapshot_rb, NULL);
478
479 /*
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700480 * Make sure that the last IB1 that was being executed is dumped.
481 * Since this was the last IB1 that was processed, we should have
482 * already added it to the list during the ringbuffer parse but we
483 * want to be double plus sure.
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700484 */
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700485
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700486 kgsl_regread(device, REG_CP_IB1_BASE, &ibbase);
487 kgsl_regread(device, REG_CP_IB1_BUFSZ, &ibsize);
488
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700489 /*
490 * The problem is that IB size from the register is the unprocessed size
491 * of the buffer not the original size, so if we didn't catch this
492 * buffer being directly used in the RB, then we might not be able to
493 * dump the whle thing. Print a warning message so we can try to
494 * figure how often this really happens.
495 */
496
497 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700498 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
499 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700500 KGSL_DRV_ERR(device, "CP_IB1_BASE not found in the ringbuffer. "
501 "Dumping %x dwords of the buffer.\n", ibsize);
502 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700503
504 kgsl_regread(device, REG_CP_IB2_BASE, &ibbase);
505 kgsl_regread(device, REG_CP_IB2_BUFSZ, &ibsize);
506
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700507 /*
508 * Add the last parsed IB2 to the list. The IB2 should be found as we
509 * parse the objects below, but we try to add it to the list first, so
510 * it too can be parsed. Don't print an error message in this case - if
511 * the IB2 is found during parsing, the list will be updated with the
512 * correct size.
513 */
514
515 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700516 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
517 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700518 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700519
520 /*
521 * Go through the list of found objects and dump each one. As the IBs
522 * are parsed, more objects might be found, and objbufptr will increase
523 */
524 for (i = 0; i < objbufptr; i++)
525 snapshot = dump_object(device, i, snapshot, remain);
526
527 /*
528 * Only dump the istore on a hang - reading it on a running system
529 * has a non 0 chance of hanging the GPU
530 */
531
532 if (hang) {
533 snapshot = kgsl_snapshot_add_section(device,
534 KGSL_SNAPSHOT_SECTION_ISTORE, snapshot, remain,
535 snapshot_istore, NULL);
536 }
537
538 /* Add GPU specific sections - registers mainly, but other stuff too */
539 if (adreno_dev->gpudev->snapshot)
540 snapshot = adreno_dev->gpudev->snapshot(adreno_dev, snapshot,
541 remain, hang);
542
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600543 if (snapshot_frozen_objsize)
544 KGSL_DRV_ERR(device, "GPU snapshot froze %dKb of GPU buffers\n",
545 snapshot_frozen_objsize / 1024);
546
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700547 return snapshot;
548}