blob: fd05ad39e59e73f6d0fd0e09bdf581f5f69efffb [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
30static struct kgsl_snapshot_obj {
31 int type;
32 uint32_t gpuaddr;
33 uint32_t ptbase;
34 void *ptr;
35 int dwords;
36} objbuf[SNAPSHOT_OBJ_BUFSIZE];
37
38/* Pointer to the next open entry in the object list */
39static int objbufptr;
40
41/* Push a new buffer object onto the list */
42static void push_object(struct kgsl_device *device, int type, uint32_t ptbase,
43 uint32_t gpuaddr, int dwords)
44{
45 int index;
46 void *ptr;
47
Jordan Crousee9e91bf2012-02-21 09:48:36 -070048 /*
49 * Sometimes IBs can be reused in the same dump. Because we parse from
50 * oldest to newest, if we come across an IB that has already been used,
51 * assume that it has been reused and update the list with the newest
52 * size.
53 */
54
Jordan Crouse156cfbc2012-01-24 09:32:04 -070055 for (index = 0; index < objbufptr; index++) {
56 if (objbuf[index].gpuaddr == gpuaddr &&
Jordan Crousee9e91bf2012-02-21 09:48:36 -070057 objbuf[index].ptbase == ptbase) {
58 objbuf[index].dwords = dwords;
59 return;
60 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -070061 }
62
63 if (objbufptr == SNAPSHOT_OBJ_BUFSIZE) {
64 KGSL_DRV_ERR(device, "snapshot: too many snapshot objects\n");
65 return;
66 }
67
68 /*
69 * adreno_convertaddr verifies that the IB size is valid - at least in
70 * the context of it being smaller then the allocated memory space
71 */
72 ptr = adreno_convertaddr(device, ptbase, gpuaddr, dwords << 2);
73
74 if (ptr == NULL) {
75 KGSL_DRV_ERR(device,
76 "snapshot: Can't find GPU address for %x\n", gpuaddr);
77 return;
78 }
79
80 /* Put it on the list of things to parse */
81 objbuf[objbufptr].type = type;
82 objbuf[objbufptr].gpuaddr = gpuaddr;
83 objbuf[objbufptr].ptbase = ptbase;
84 objbuf[objbufptr].dwords = dwords;
85 objbuf[objbufptr++].ptr = ptr;
86}
87
Jordan Crousee9e91bf2012-02-21 09:48:36 -070088/*
89 * Return a 1 if the specified object is already on the list of buffers
90 * to be dumped
91 */
92
93static int find_object(int type, unsigned int gpuaddr, unsigned int ptbase)
94{
95 int index;
96
97 for (index = 0; index < objbufptr; index++) {
98 if (objbuf[index].gpuaddr == gpuaddr &&
99 objbuf[index].ptbase == ptbase &&
100 objbuf[index].type == type)
101 return 1;
102 }
103
104 return 0;
105}
106
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700107/* Snapshot the istore memory */
108static int snapshot_istore(struct kgsl_device *device, void *snapshot,
109 int remain, void *priv)
110{
111 struct kgsl_snapshot_istore *header = snapshot;
112 unsigned int *data = snapshot + sizeof(*header);
113 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
114 int count, i;
115
Jordan Crousec6b3a992012-02-04 10:23:51 -0700116 count = adreno_dev->istore_size * adreno_dev->instruction_size;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700117
118 if (remain < (count * 4) + sizeof(*header)) {
119 KGSL_DRV_ERR(device,
120 "snapshot: Not enough memory for the istore section");
121 return 0;
122 }
123
124 header->count = adreno_dev->istore_size;
125
126 for (i = 0; i < count; i++)
127 kgsl_regread(device, ADRENO_ISTORE_START + i, &data[i]);
128
129 return (count * 4) + sizeof(*header);
130}
131
132/* Snapshot the ringbuffer memory */
133static int snapshot_rb(struct kgsl_device *device, void *snapshot,
134 int remain, void *priv)
135{
136 struct kgsl_snapshot_rb *header = snapshot;
137 unsigned int *data = snapshot + sizeof(*header);
138 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
139 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
140 unsigned int rbbase, ptbase, rptr, *rbptr;
141 int start, stop, index;
142 int numitems, size;
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700143 int parse_ibs = 0, ib_parse_start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700144
145 /* Get the GPU address of the ringbuffer */
146 kgsl_regread(device, REG_CP_RB_BASE, &rbbase);
147
148 /* Get the physical address of the MMU pagetable */
149 ptbase = kgsl_mmu_get_current_ptbase(device);
150
151 /* Get the current read pointers for the RB */
152 kgsl_regread(device, REG_CP_RB_RPTR, &rptr);
153
154 /* start the dump at the rptr minus some history */
155 start = (int) rptr - NUM_DWORDS_OF_RINGBUFFER_HISTORY;
156 if (start < 0)
157 start += rb->sizedwords;
158
159 /*
160 * Stop the dump at the point where the software last wrote. Don't use
161 * the hardware value here on the chance that it didn't get properly
162 * updated
163 */
164
165 stop = (int) rb->wptr + 16;
166 if (stop > rb->sizedwords)
167 stop -= rb->sizedwords;
168
169 /* Set up the header for the section */
170
171 numitems = (stop > start) ? stop - start :
172 (rb->sizedwords - start) + stop;
173
174 size = (numitems << 2);
175
176 if (remain < size + sizeof(*header)) {
177 KGSL_DRV_ERR(device,
178 "snapshot: Not enough memory for the rb section");
179 return 0;
180 }
181
182 /* Write the sub-header for the section */
183 header->start = start;
184 header->end = stop;
185 header->wptr = rb->wptr;
186 header->rbsize = rb->sizedwords;
187 header->count = numitems;
188
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700189 /*
190 * We can only reliably dump IBs from the beginning of the context,
191 * and it turns out that for the vast majority of the time we really
192 * only care about the current context when it comes to diagnosing
193 * a hang. So, with an eye to limiting the buffer dumping to what is
194 * really useful find the beginning of the context and only dump
195 * IBs from that point
196 */
197
198 index = rptr;
199 ib_parse_start = start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700200 rbptr = rb->buffer_desc.hostptr;
201
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700202 while (index != start) {
203 index--;
204
205 if (index < 0) {
206 /*
207 * The marker we are looking for is 2 dwords long, so
208 * when wrapping, go back 2 from the end so we don't
209 * access out of range in the if statement below
210 */
211 index = rb->sizedwords - 2;
212
213 /*
214 * Account for the possibility that start might be at
215 * rb->sizedwords - 1
216 */
217
218 if (start == rb->sizedwords - 1)
219 break;
220 }
221
222 /*
223 * Look for a NOP packet with the context switch identifier in
224 * the second dword
225 */
226
227 if (rbptr[index] == cp_nop_packet(1) &&
228 rbptr[index + 1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
229 ib_parse_start = index;
230 break;
231 }
232 }
233
234 index = start;
235
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700236 /*
237 * Loop through the RB, copying the data and looking for indirect
238 * buffers and MMU pagetable changes
239 */
240
241 while (index != rb->wptr) {
242 *data = rbptr[index];
243
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700244 /* Only parse IBs between the context start and the rptr */
245
246 if (index == ib_parse_start)
247 parse_ibs = 1;
248
249 if (index == rptr)
250 parse_ibs = 0;
251
252 if (parse_ibs &&
253 rbptr[index] ==
254 cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2))
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700255 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
256 rbptr[index + 1], rbptr[index + 2]);
257
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700258 index = index + 1;
259
260 if (index == rb->sizedwords)
261 index = 0;
262
263 data++;
264 }
265
266 /* Dump 16 dwords past the wptr, but don't bother interpeting it */
267
268 while (index != stop) {
269 *data = rbptr[index];
270 index = index + 1;
271
272 if (index == rb->sizedwords)
273 index = 0;
274
275 data++;
276 }
277
278 /* Return the size of the section */
279 return size + sizeof(*header);
280}
281
282/* Snapshot the memory for an indirect buffer */
283static int snapshot_ib(struct kgsl_device *device, void *snapshot,
284 int remain, void *priv)
285{
286 struct kgsl_snapshot_ib *header = snapshot;
287 struct kgsl_snapshot_obj *obj = priv;
288 unsigned int *src = obj->ptr;
289 unsigned int *dst = snapshot + sizeof(*header);
290 int i;
291
292 if (remain < (obj->dwords << 2) + sizeof(*header)) {
293 KGSL_DRV_ERR(device,
294 "snapshot: Not enough memory for the ib section");
295 return 0;
296 }
297
298 /* Write the sub-header for the section */
299 header->gpuaddr = obj->gpuaddr;
300 header->ptbase = obj->ptbase;
301 header->size = obj->dwords;
302
303 /* Write the contents of the ib */
304 for (i = 0; i < obj->dwords; i++) {
305 *dst = *src;
306 /* If another IB is discovered, then push it on the list too */
307
308 if (*src == cp_type3_packet(CP_INDIRECT_BUFFER_PFD, 2)) {
309 push_object(device, SNAPSHOT_OBJ_TYPE_IB, obj->ptbase,
310 *(src + 1), *(src + 2));
311 }
312
313 src++;
314 dst++;
315 }
316
317 return (obj->dwords << 2) + sizeof(*header);
318}
319
320/* Dump another item on the current pending list */
321static void *dump_object(struct kgsl_device *device, int obj, void *snapshot,
322 int *remain)
323{
324 switch (objbuf[obj].type) {
325 case SNAPSHOT_OBJ_TYPE_IB:
326 snapshot = kgsl_snapshot_add_section(device,
327 KGSL_SNAPSHOT_SECTION_IB, snapshot, remain,
328 snapshot_ib, &objbuf[obj]);
329 break;
330 default:
331 KGSL_DRV_ERR(device,
332 "snapshot: Invalid snapshot object type: %d\n",
333 objbuf[obj].type);
334 break;
335 }
336
337 return snapshot;
338}
339
340/* adreno_snapshot - Snapshot the Adreno GPU state
341 * @device - KGSL device to snapshot
342 * @snapshot - Pointer to the start of memory to write into
343 * @remain - A pointer to how many bytes of memory are remaining in the snapshot
344 * @hang - set if this snapshot was automatically triggered by a GPU hang
345 * This is a hook function called by kgsl_snapshot to snapshot the
346 * Adreno specific information for the GPU snapshot. In turn, this function
347 * calls the GPU specific snapshot function to get core specific information.
348 */
349
350void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
351 int hang)
352{
353 int i;
354 uint32_t ptbase, ibbase, ibsize;
355 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
356
357 /* Reset the list of objects */
358 objbufptr = 0;
359
360 /* Get the physical address of the MMU pagetable */
361 ptbase = kgsl_mmu_get_current_ptbase(device);
362
363 /* Dump the ringbuffer */
364 snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB,
365 snapshot, remain, snapshot_rb, NULL);
366
367 /*
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700368 * Make sure that the last IB1 that was being executed is dumped.
369 * Since this was the last IB1 that was processed, we should have
370 * already added it to the list during the ringbuffer parse but we
371 * want to be double plus sure.
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700372 */
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700373
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700374 kgsl_regread(device, REG_CP_IB1_BASE, &ibbase);
375 kgsl_regread(device, REG_CP_IB1_BUFSZ, &ibsize);
376
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700377 /*
378 * The problem is that IB size from the register is the unprocessed size
379 * of the buffer not the original size, so if we didn't catch this
380 * buffer being directly used in the RB, then we might not be able to
381 * dump the whle thing. Print a warning message so we can try to
382 * figure how often this really happens.
383 */
384
385 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700386 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
387 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700388 KGSL_DRV_ERR(device, "CP_IB1_BASE not found in the ringbuffer. "
389 "Dumping %x dwords of the buffer.\n", ibsize);
390 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700391
392 kgsl_regread(device, REG_CP_IB2_BASE, &ibbase);
393 kgsl_regread(device, REG_CP_IB2_BUFSZ, &ibsize);
394
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700395 /*
396 * Add the last parsed IB2 to the list. The IB2 should be found as we
397 * parse the objects below, but we try to add it to the list first, so
398 * it too can be parsed. Don't print an error message in this case - if
399 * the IB2 is found during parsing, the list will be updated with the
400 * correct size.
401 */
402
403 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700404 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
405 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700406 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700407
408 /*
409 * Go through the list of found objects and dump each one. As the IBs
410 * are parsed, more objects might be found, and objbufptr will increase
411 */
412 for (i = 0; i < objbufptr; i++)
413 snapshot = dump_object(device, i, snapshot, remain);
414
415 /*
416 * Only dump the istore on a hang - reading it on a running system
417 * has a non 0 chance of hanging the GPU
418 */
419
420 if (hang) {
421 snapshot = kgsl_snapshot_add_section(device,
422 KGSL_SNAPSHOT_SECTION_ISTORE, snapshot, remain,
423 snapshot_istore, NULL);
424 }
425
426 /* Add GPU specific sections - registers mainly, but other stuff too */
427 if (adreno_dev->gpudev->snapshot)
428 snapshot = adreno_dev->gpudev->snapshot(adreno_dev, snapshot,
429 remain, hang);
430
431 return snapshot;
432}