blob: 98360430080c08237685e282528becce3280f999 [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
Jeremy Gebben6ca1d152012-03-05 14:19:01 -0700252 if (parse_ibs && adreno_cmd_is_ib(rbptr[index]))
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700253 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
254 rbptr[index + 1], rbptr[index + 2]);
255
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700256 index = index + 1;
257
258 if (index == rb->sizedwords)
259 index = 0;
260
261 data++;
262 }
263
264 /* Dump 16 dwords past the wptr, but don't bother interpeting it */
265
266 while (index != stop) {
267 *data = rbptr[index];
268 index = index + 1;
269
270 if (index == rb->sizedwords)
271 index = 0;
272
273 data++;
274 }
275
276 /* Return the size of the section */
277 return size + sizeof(*header);
278}
279
280/* Snapshot the memory for an indirect buffer */
281static int snapshot_ib(struct kgsl_device *device, void *snapshot,
282 int remain, void *priv)
283{
284 struct kgsl_snapshot_ib *header = snapshot;
285 struct kgsl_snapshot_obj *obj = priv;
286 unsigned int *src = obj->ptr;
287 unsigned int *dst = snapshot + sizeof(*header);
288 int i;
289
290 if (remain < (obj->dwords << 2) + sizeof(*header)) {
291 KGSL_DRV_ERR(device,
292 "snapshot: Not enough memory for the ib section");
293 return 0;
294 }
295
296 /* Write the sub-header for the section */
297 header->gpuaddr = obj->gpuaddr;
298 header->ptbase = obj->ptbase;
299 header->size = obj->dwords;
300
301 /* Write the contents of the ib */
302 for (i = 0; i < obj->dwords; i++) {
303 *dst = *src;
304 /* If another IB is discovered, then push it on the list too */
305
Jeremy Gebben6ca1d152012-03-05 14:19:01 -0700306 if (adreno_cmd_is_ib(*src))
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700307 push_object(device, SNAPSHOT_OBJ_TYPE_IB, obj->ptbase,
308 *(src + 1), *(src + 2));
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700309
310 src++;
311 dst++;
312 }
313
314 return (obj->dwords << 2) + sizeof(*header);
315}
316
317/* Dump another item on the current pending list */
318static void *dump_object(struct kgsl_device *device, int obj, void *snapshot,
319 int *remain)
320{
321 switch (objbuf[obj].type) {
322 case SNAPSHOT_OBJ_TYPE_IB:
323 snapshot = kgsl_snapshot_add_section(device,
324 KGSL_SNAPSHOT_SECTION_IB, snapshot, remain,
325 snapshot_ib, &objbuf[obj]);
326 break;
327 default:
328 KGSL_DRV_ERR(device,
329 "snapshot: Invalid snapshot object type: %d\n",
330 objbuf[obj].type);
331 break;
332 }
333
334 return snapshot;
335}
336
337/* adreno_snapshot - Snapshot the Adreno GPU state
338 * @device - KGSL device to snapshot
339 * @snapshot - Pointer to the start of memory to write into
340 * @remain - A pointer to how many bytes of memory are remaining in the snapshot
341 * @hang - set if this snapshot was automatically triggered by a GPU hang
342 * This is a hook function called by kgsl_snapshot to snapshot the
343 * Adreno specific information for the GPU snapshot. In turn, this function
344 * calls the GPU specific snapshot function to get core specific information.
345 */
346
347void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
348 int hang)
349{
350 int i;
351 uint32_t ptbase, ibbase, ibsize;
352 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
353
354 /* Reset the list of objects */
355 objbufptr = 0;
356
357 /* Get the physical address of the MMU pagetable */
358 ptbase = kgsl_mmu_get_current_ptbase(device);
359
360 /* Dump the ringbuffer */
361 snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB,
362 snapshot, remain, snapshot_rb, NULL);
363
364 /*
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700365 * Make sure that the last IB1 that was being executed is dumped.
366 * Since this was the last IB1 that was processed, we should have
367 * already added it to the list during the ringbuffer parse but we
368 * want to be double plus sure.
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700369 */
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700370
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700371 kgsl_regread(device, REG_CP_IB1_BASE, &ibbase);
372 kgsl_regread(device, REG_CP_IB1_BUFSZ, &ibsize);
373
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700374 /*
375 * The problem is that IB size from the register is the unprocessed size
376 * of the buffer not the original size, so if we didn't catch this
377 * buffer being directly used in the RB, then we might not be able to
378 * dump the whle thing. Print a warning message so we can try to
379 * figure how often this really happens.
380 */
381
382 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700383 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
384 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700385 KGSL_DRV_ERR(device, "CP_IB1_BASE not found in the ringbuffer. "
386 "Dumping %x dwords of the buffer.\n", ibsize);
387 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700388
389 kgsl_regread(device, REG_CP_IB2_BASE, &ibbase);
390 kgsl_regread(device, REG_CP_IB2_BUFSZ, &ibsize);
391
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700392 /*
393 * Add the last parsed IB2 to the list. The IB2 should be found as we
394 * parse the objects below, but we try to add it to the list first, so
395 * it too can be parsed. Don't print an error message in this case - if
396 * the IB2 is found during parsing, the list will be updated with the
397 * correct size.
398 */
399
400 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700401 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
402 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700403 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700404
405 /*
406 * Go through the list of found objects and dump each one. As the IBs
407 * are parsed, more objects might be found, and objbufptr will increase
408 */
409 for (i = 0; i < objbufptr; i++)
410 snapshot = dump_object(device, i, snapshot, remain);
411
412 /*
413 * Only dump the istore on a hang - reading it on a running system
414 * has a non 0 chance of hanging the GPU
415 */
416
417 if (hang) {
418 snapshot = kgsl_snapshot_add_section(device,
419 KGSL_SNAPSHOT_SECTION_ISTORE, snapshot, remain,
420 snapshot_istore, NULL);
421 }
422
423 /* Add GPU specific sections - registers mainly, but other stuff too */
424 if (adreno_dev->gpudev->snapshot)
425 snapshot = adreno_dev->gpudev->snapshot(adreno_dev, snapshot,
426 remain, hang);
427
428 return snapshot;
429}