blob: 905a36ac5cb5154999043be8414b996279b09e7a [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 Crouse156cfbc2012-01-24 09:32:04 -0700110/* Snapshot the istore memory */
111static int snapshot_istore(struct kgsl_device *device, void *snapshot,
112 int remain, void *priv)
113{
114 struct kgsl_snapshot_istore *header = snapshot;
115 unsigned int *data = snapshot + sizeof(*header);
116 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
117 int count, i;
118
Jordan Crousec6b3a992012-02-04 10:23:51 -0700119 count = adreno_dev->istore_size * adreno_dev->instruction_size;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700120
121 if (remain < (count * 4) + sizeof(*header)) {
122 KGSL_DRV_ERR(device,
123 "snapshot: Not enough memory for the istore section");
124 return 0;
125 }
126
127 header->count = adreno_dev->istore_size;
128
129 for (i = 0; i < count; i++)
130 kgsl_regread(device, ADRENO_ISTORE_START + i, &data[i]);
131
132 return (count * 4) + sizeof(*header);
133}
134
135/* Snapshot the ringbuffer memory */
136static int snapshot_rb(struct kgsl_device *device, void *snapshot,
137 int remain, void *priv)
138{
139 struct kgsl_snapshot_rb *header = snapshot;
140 unsigned int *data = snapshot + sizeof(*header);
141 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
142 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
143 unsigned int rbbase, ptbase, rptr, *rbptr;
144 int start, stop, index;
145 int numitems, size;
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700146 int parse_ibs = 0, ib_parse_start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700147
148 /* Get the GPU address of the ringbuffer */
149 kgsl_regread(device, REG_CP_RB_BASE, &rbbase);
150
151 /* Get the physical address of the MMU pagetable */
152 ptbase = kgsl_mmu_get_current_ptbase(device);
153
154 /* Get the current read pointers for the RB */
155 kgsl_regread(device, REG_CP_RB_RPTR, &rptr);
156
157 /* start the dump at the rptr minus some history */
158 start = (int) rptr - NUM_DWORDS_OF_RINGBUFFER_HISTORY;
159 if (start < 0)
160 start += rb->sizedwords;
161
162 /*
163 * Stop the dump at the point where the software last wrote. Don't use
164 * the hardware value here on the chance that it didn't get properly
165 * updated
166 */
167
168 stop = (int) rb->wptr + 16;
169 if (stop > rb->sizedwords)
170 stop -= rb->sizedwords;
171
172 /* Set up the header for the section */
173
174 numitems = (stop > start) ? stop - start :
175 (rb->sizedwords - start) + stop;
176
177 size = (numitems << 2);
178
179 if (remain < size + sizeof(*header)) {
180 KGSL_DRV_ERR(device,
181 "snapshot: Not enough memory for the rb section");
182 return 0;
183 }
184
185 /* Write the sub-header for the section */
186 header->start = start;
187 header->end = stop;
188 header->wptr = rb->wptr;
189 header->rbsize = rb->sizedwords;
190 header->count = numitems;
191
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700192 /*
193 * We can only reliably dump IBs from the beginning of the context,
194 * and it turns out that for the vast majority of the time we really
195 * only care about the current context when it comes to diagnosing
196 * a hang. So, with an eye to limiting the buffer dumping to what is
197 * really useful find the beginning of the context and only dump
198 * IBs from that point
199 */
200
201 index = rptr;
202 ib_parse_start = start;
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700203 rbptr = rb->buffer_desc.hostptr;
204
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700205 while (index != start) {
206 index--;
207
208 if (index < 0) {
209 /*
210 * The marker we are looking for is 2 dwords long, so
211 * when wrapping, go back 2 from the end so we don't
212 * access out of range in the if statement below
213 */
214 index = rb->sizedwords - 2;
215
216 /*
217 * Account for the possibility that start might be at
218 * rb->sizedwords - 1
219 */
220
221 if (start == rb->sizedwords - 1)
222 break;
223 }
224
225 /*
226 * Look for a NOP packet with the context switch identifier in
227 * the second dword
228 */
229
230 if (rbptr[index] == cp_nop_packet(1) &&
231 rbptr[index + 1] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
232 ib_parse_start = index;
233 break;
234 }
235 }
236
237 index = start;
238
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700239 /*
240 * Loop through the RB, copying the data and looking for indirect
241 * buffers and MMU pagetable changes
242 */
243
244 while (index != rb->wptr) {
245 *data = rbptr[index];
246
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700247 /* Only parse IBs between the context start and the rptr */
248
249 if (index == ib_parse_start)
250 parse_ibs = 1;
251
252 if (index == rptr)
253 parse_ibs = 0;
254
Jeremy Gebben6ca1d152012-03-05 14:19:01 -0700255 if (parse_ibs && adreno_cmd_is_ib(rbptr[index]))
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700256 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
257 rbptr[index + 1], rbptr[index + 2]);
258
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700259 index = index + 1;
260
261 if (index == rb->sizedwords)
262 index = 0;
263
264 data++;
265 }
266
267 /* Dump 16 dwords past the wptr, but don't bother interpeting it */
268
269 while (index != stop) {
270 *data = rbptr[index];
271 index = index + 1;
272
273 if (index == rb->sizedwords)
274 index = 0;
275
276 data++;
277 }
278
279 /* Return the size of the section */
280 return size + sizeof(*header);
281}
282
283/* Snapshot the memory for an indirect buffer */
284static int snapshot_ib(struct kgsl_device *device, void *snapshot,
285 int remain, void *priv)
286{
287 struct kgsl_snapshot_ib *header = snapshot;
288 struct kgsl_snapshot_obj *obj = priv;
289 unsigned int *src = obj->ptr;
290 unsigned int *dst = snapshot + sizeof(*header);
291 int i;
292
293 if (remain < (obj->dwords << 2) + sizeof(*header)) {
294 KGSL_DRV_ERR(device,
295 "snapshot: Not enough memory for the ib section");
296 return 0;
297 }
298
299 /* Write the sub-header for the section */
300 header->gpuaddr = obj->gpuaddr;
301 header->ptbase = obj->ptbase;
302 header->size = obj->dwords;
303
304 /* Write the contents of the ib */
305 for (i = 0; i < obj->dwords; i++) {
306 *dst = *src;
307 /* If another IB is discovered, then push it on the list too */
308
Jeremy Gebben6ca1d152012-03-05 14:19:01 -0700309 if (adreno_cmd_is_ib(*src))
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700310 push_object(device, SNAPSHOT_OBJ_TYPE_IB, obj->ptbase,
311 *(src + 1), *(src + 2));
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700312
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
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600360 snapshot_frozen_objsize = 0;
361
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700362 /* Get the physical address of the MMU pagetable */
363 ptbase = kgsl_mmu_get_current_ptbase(device);
364
365 /* Dump the ringbuffer */
366 snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB,
367 snapshot, remain, snapshot_rb, NULL);
368
369 /*
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700370 * Make sure that the last IB1 that was being executed is dumped.
371 * Since this was the last IB1 that was processed, we should have
372 * already added it to the list during the ringbuffer parse but we
373 * want to be double plus sure.
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700374 */
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700375
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700376 kgsl_regread(device, REG_CP_IB1_BASE, &ibbase);
377 kgsl_regread(device, REG_CP_IB1_BUFSZ, &ibsize);
378
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700379 /*
380 * The problem is that IB size from the register is the unprocessed size
381 * of the buffer not the original size, so if we didn't catch this
382 * buffer being directly used in the RB, then we might not be able to
383 * dump the whle thing. Print a warning message so we can try to
384 * figure how often this really happens.
385 */
386
387 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700388 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
389 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700390 KGSL_DRV_ERR(device, "CP_IB1_BASE not found in the ringbuffer. "
391 "Dumping %x dwords of the buffer.\n", ibsize);
392 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700393
394 kgsl_regread(device, REG_CP_IB2_BASE, &ibbase);
395 kgsl_regread(device, REG_CP_IB2_BUFSZ, &ibsize);
396
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700397 /*
398 * Add the last parsed IB2 to the list. The IB2 should be found as we
399 * parse the objects below, but we try to add it to the list first, so
400 * it too can be parsed. Don't print an error message in this case - if
401 * the IB2 is found during parsing, the list will be updated with the
402 * correct size.
403 */
404
405 if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ibbase, ptbase) && ibsize) {
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700406 push_object(device, SNAPSHOT_OBJ_TYPE_IB, ptbase,
407 ibbase, ibsize);
Jordan Crousee9e91bf2012-02-21 09:48:36 -0700408 }
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700409
410 /*
411 * Go through the list of found objects and dump each one. As the IBs
412 * are parsed, more objects might be found, and objbufptr will increase
413 */
414 for (i = 0; i < objbufptr; i++)
415 snapshot = dump_object(device, i, snapshot, remain);
416
417 /*
418 * Only dump the istore on a hang - reading it on a running system
419 * has a non 0 chance of hanging the GPU
420 */
421
422 if (hang) {
423 snapshot = kgsl_snapshot_add_section(device,
424 KGSL_SNAPSHOT_SECTION_ISTORE, snapshot, remain,
425 snapshot_istore, NULL);
426 }
427
428 /* Add GPU specific sections - registers mainly, but other stuff too */
429 if (adreno_dev->gpudev->snapshot)
430 snapshot = adreno_dev->gpudev->snapshot(adreno_dev, snapshot,
431 remain, hang);
432
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600433 if (snapshot_frozen_objsize)
434 KGSL_DRV_ERR(device, "GPU snapshot froze %dKb of GPU buffers\n",
435 snapshot_frozen_objsize / 1024);
436
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700437 return snapshot;
438}