summaryrefslogtreecommitdiff
path: root/readme.txt
blob: b701e638a7765dc0099499461c8981c2a6b90a7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
                   igdbg: i915 kernel driver tool

Content:
    1. Introduction
    2. Implementation overview
    3. Command summary
    4. Command details
    5. Reference


1. Introduction

igdbg is a standalone user mode tool that can run on a Linux system with
proper configuration. The primary purpose of this tool is to learn and 
understand i915 GPU driver which is in linux kernel "drivers/gpu/drm/i915"
folder. It might be also helpful for developers to check or dump GPU states.

The tool must be invoked by root. Usage: 
    igdbg [ -v -d <device name> -c <command> ]

    <device name> is the device that the tool uses to access GPU resources,
                  by default it is /dev/mem
    <command> is the command to be executed. Without it, the tool enters
              into interactive mode so that user can type a command later

The tool till now is only tested on a GEN8 based Android device. It only 
adds a few device IDs in the support list, thus it might not work or might
get different result on other devices.

2. Implementation overview

The tool opens /dev/mem to "mmap" device memory. The memory includes GPU
mmio space, gtt space and frame buffer. It is the way that the tool dumps
registers/gtt and frame buffer content. There are some GPU resources that
are in system memory including PPGTT tables, ring buffers, etc. For them,
the tool uses "read/write" to access them. 

There are two Linux kernel configurations that may forbid "mmap" and 
"read/write" on /dev/mem: CONFIG_X86_PAT and CONFIG_STRICT_DEVMEM. PAT can
be flagged on or off by "nopat" kernel boot parameter. Check bellow table
if there are some problems to run the tool:

CONFIG_STRICT_DEVMEM |          Y          |         N 
---------------------+---------------------+-------------------------
  Allow "mmap"       | Usually it is Yes, but may get issue on some
  on device memory?  | systems. Try to add "nopat" if it is the case
---------------------+---------------------+-------------------------
  Allow "read/write" |          No         |        Yes
  on system RAM?     |                     |
---------------------+---------------------+-------------------------

Sub-folder linux/imem.c is a kernel module of char device. It derives from linux
kernel "driver/char/mem.c". The difference is that it removes the restrictions
of CONFIG_STRICT_DEVMEM. When load it into kernel, it registers a char device
with major number 999. The tool can use this char device instead of /dev/mem to
"mmap" and "read/write" by command line parameter "-d <device name>". It is for the
people that don't want to rebuild the kernel to disable STRICT_DEVMEM configuration.  

3. Command summary
 
As mentioned above, "mmap" is used to access mmio/gtt space and frame buffer
content, and "read/write" is used to access the resources in system memory. From
this perspective, there are two types of commands:

A. Commands that are supported by "mmap" /dev/mem

 Command   | Introduction
-----------+---------------------------------------------------
 regread   | Read a register                
-----------+---------------------------------------------------
 regwrite  | Write a register                
-----------+---------------------------------------------------
 dumpgtt   | Dump GGTT mappings 
-----------+---------------------------------------------------
 stolen    | Dump stolen memory mappings
-----------+---------------------------------------------------
 dumpfb    | Dump frame buffer                
-----------+---------------------------------------------------
 dumpfbl   | Dump frame buffer with a fence register,
           | thus it is linear mode
-----------+---------------------------------------------------
 fillfb    | Fill frame buffer                
-----------+---------------------------------------------------
 fillfbl   | Fill frame buffer with a fence register,
           | thus it is linear mode
-----------+---------------------------------------------------
 irq       | Sample IRQ status              
-----------+---------------------------------------------------
 cstatus   | Sample execlist context status
-----------+---------------------------------------------------

B. Commands that are supported by "read/write" /dev/mem

 Command   | Introduction
-----------+---------------------------------------------------
 dumpstat  | Dump context stat
-----------+---------------------------------------------------
 dumppgtt  | Dump PPGTT mappins
-----------+---------------------------------------------------
 dumpring  | Dump ring buffer and the chained batch buffer 
-----------+---------------------------------------------------

4. Command details

4.1 regread/regwrite 

regread <register address>
regwrite <register address> <register value>

4.2 dumpgtt

GTT table usually shares the PCI BAR0 with mmio space. It locates at the
half bottom of the space. The real memory behind it actually resides in 
system RAM whose address can be read out from a register 

    dumpgtt <offset> <size>

Example:
    igdbg -c "dumpgtt 2<<20 40<<10"

>>>>>>
GTT size = 4096K (Can map 2048M memory), location at 0x7c900000 (1993M)
-----------------------------002M FB------------------------------
FB:0x0200000|002M+0000K|GTT offset:0x01000(entry 0x00200): 007cf00001
FB:0x0201000|002M+0004K|GTT offset:0x01008(entry 0x00201): 007cf01001
FB:0x0202000|002M+0008K|GTT offset:0x01010(entry 0x00202): 007cf02001
FB:0x0203000|002M+0012K|GTT offset:0x01018(entry 0x00203): 007cf03001
FB:0x0204000|002M+0016K|GTT offset:0x01020(entry 0x00204): 007cf04001
FB:0x0205000|002M+0020K|GTT offset:0x01028(entry 0x00205): 007cf05001
FB:0x0206000|002M+0024K|GTT offset:0x01030(entry 0x00206): 007cf06001
FB:0x0207000|002M+0028K|GTT offset:0x01038(entry 0x00207): 007cf07001
FB:0x0208000|002M+0032K|GTT offset:0x01040(entry 0x00208): 007cf08001
FB:0x0209000|002M+0036K|GTT offset:0x01048(entry 0x00209): 007cf09001
<<<<<<

It dumps the mapping of 40 pages (40K) starting from 2M of frame buffer.

4.3 stolen

Dump the mysterious stolen memory mappings in GTT
    stolen

Example:
    igdbg -c "stolen"

>>>>>>
Stolen size =32768K (physical base=[0x7cd00000~0x7ed00000](1997M~2029M))
-----------------------------000M+0000K FB------------------------------
FB:0x0000000|000M+0000K|GTT offset:0x00000(entry 0x00000): 007cd00001
FB:0x0001000|000M+0004K|GTT offset:0x00008(entry 0x00001): 007cd01001
FB:0x0002000|000M+0008K|GTT offset:0x00010(entry 0x00002): 007cd02001
......
-----------------------------022M+0088K FB------------------------------
FB:0x1616000|022M+0088K|GTT offset:0x0b0b0(entry 0x01616): 007d64c01b
FB:0x1617000|022M+0092K|GTT offset:0x0b0b8(entry 0x01617): 007d64d01b
......
-----------------------------092M+0512K FB------------------------------
FB:0x5c80000|092M+0512K|GTT offset:0x2e400(entry 0x05c80): 007d68e01b
FB:0x5c81000|092M+0516K|GTT offset:0x2e408(entry 0x05c81): 007d68f01b
-----------------------------160M+0492K FB------------------------------
FB:0xa07b000|160M+0492K|GTT offset:0x503d8(entry 0x0a07b): 007d71601b
FB:0xa07c000|160M+0496K|GTT offset:0x503e0(entry 0x0a07c): 007d71701b
......
<<<<<<

4.4 onscreen

Display onscreen frame buffer information. It might be from DSPASURF or DSPBSURF 
registers (Display Surface Base Address Register)
  
    onscreen

Example: 
    igdbg -c "onscreen"

>>>>>>
Plane A is enabled
DSPCNTR:value=0xb8000400(X-tiled(512x8), format 0xe(e:RGBX, f:RGBA))
         31  28  27  24  23  20  19  16  15  12  11  08  07  04  03  00
         |1011|  |1000|  |0000|  |0000|  |0000|  |0100|  |0000|  |0000|
           0xb     0x8     0x0     0x0     0x0     0x4     0x0     0x0
Offset of current display:0xac8f000(172M+572K), GTT offset at 353400
<<<<<<

From above, on-screen frame buffer is X-tiled, and the address is at 0xac8f000

4.5 dumpfb/fillfb

Access frame buffer through PCI BAR2 which is the "window" of the backing real
system RAM mapped by GTT. Another term of this "window" is aperture. 

    dumpfb <offset> <size>
    fillfb <offset> <size> <value>

Example:

Firstly get the onscreen frame buffer address:

    igdbg -c "onscree"

>>>>>>
Offset of current display:0xac8f000(172M+572K), GTT offset 353400 with 5 entries:
<<<<<<

Then dump it with an offset 480 (start from 0x0ac8f1e0):
    igdbg -c "dumpfb 0xac8f000+480 64"

>>>>>>
Dump frame buffer from offset 0xac8f1e0,size 128
0x0ac8f1e0:    0x65 0x71 0x16 0xff 0x64 0x70 0x14 0xff
0x0ac8f1e8:    0x63 0x6f 0x13 0xff 0x62 0x6e 0x11 0xff
0x0ac8f1f0:    0x62 0x6d 0x10 0xff 0x61 0x6e 0x10 0xff
0x0ac8f1f8:    0x62 0x6f 0x11 0xff 0x62 0x70 0x12 0xff
0x0ac8f200:    0x6d 0x74 0x28 0xff 0x6d 0x74 0x34 0xff
0x0ac8f208:    0x6e 0x74 0x41 0xff 0x6e 0x75 0x46 0xff
0x0ac8f210:    0x6e 0x75 0x44 0xff 0x6d 0x75 0x41 0xff
0x0ac8f218:    0x6c 0x75 0x42 0xff 0x6d 0x75 0x44 0xff
<<<<<<

4.6 dumpfbl/fillfbl

Same with above commands, but it will force a "fence" register for the accessed
range, thus it will get linear data if frame buffer is tiled format. It is a hack
way for the understanding of aperture/fence and tile/linear.

    dumpfbl <offset> <size>
    fillfbl <offset> <size> <value>

Example:

Dump the same onscreen buffer as above, but use dumpfbl
    igdbg -c "dumpfbl 0xac8f000+480 64"
>>>>>>
Force FENCE0 for linear access with stride 5120
Dump frame buffer from offset 0xac8f1e0,size 128
0x0ac8f1e0:    0x65 0x71 0x16 0xff 0x64 0x70 0x14 0xff
0x0ac8f1e8:    0x63 0x6f 0x13 0xff 0x62 0x6e 0x11 0xff
0x0ac8f1f0:    0x62 0x6d 0x10 0xff 0x61 0x6e 0x10 0xff
0x0ac8f1f8:    0x62 0x6f 0x11 0xff 0x62 0x70 0x12 0xff
0x0ac8f200:    0x61 0x71 0x12 0xff 0x60 0x70 0x13 0xff
0x0ac8f208:    0x5f 0x70 0x12 0xff 0x5e 0x70 0x11 0xff
0x0ac8f210:    0x5f 0x70 0x10 0xff 0x5f 0x70 0x10 0xff
0x0ac8f218:    0x5f 0x70 0x11 0xff 0x5e 0x71 0x11 0xff
Restore FENCE0
<<<<<<

Since the onscreen frame buffer is X-tile that the sub-tile block is 512x8,
the first 512 bytes from "dumpfb" and "dumpfbl" is same, but then the following
bytes will be different (start from 0x0ac8f200).

Similarly, use command:
    igdbg -c "fillfb 0xac8f000 4096 0xff"
    igdbg -c "fillfbl 0xac8f000 4096 0xff"

They will visually display the difference on screen. The first one will display
a 512x8 grey block on screen, and the second will display a grey line


4.7 irq

Sample IIR registers (interrupt identify register) to print a rough overview of 
IRQs. Also the sequence number associated with the command is printed out. It is
read out from an offset of Hardware Status Page. The command is for the purpose
to understand the engines that are used for a task (e.g. video encode)
    irq <seconds>

Example:
Run video encoding and igdbg at the same time
    va_encode -r 30 
    igdbg -c "irq 500"

>>>>>>
Sample IRQ for 500 seconds....It is not accurate, just rough view
Render HWS_PGA=0x008cd000, Video HWS_PGA=0x00904000

T1253.841:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010b3)
T1262.051:iir=0x00000001
        VCS:GT_USER_INTERRUPT (seqno=0x000010b7)
T1295.786:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010bb)
T1360.381:iir=0x00000100
        RCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c0)
T1361.176:iir=0x00000001
        VCS:GT_USER_INTERRUPT (seqno=0x000010c2)
T1361.260:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c3)
T1392.961:iir=0x00000100
        RCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c1)
T1394.567:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c3)
T1394.812:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010c7)
T1426.393:iir=0x00000001
        RCS:GT_USER_INTERRUPT (seqno=0x000010c8)
T1427.856:iir=0x00000100
        VCS:GT_CONTEXT_SWITCH_INTERRUPT (seqno=0x000010cb)
......
<<<<<<

4.8 dumpstat

On GEN8 and above, each context associates a state buffer for context save and restore.

    dumpstat <state bo>

State bo can get from /sys/kernel/debug/dri/0/i915_context_status

Example:

Firstly run a video encoding, and get the state buffer address
    va_encode -i #press one key to encode one frame
    cat /sys/kernel/debug/dri/0/i915_context_status
>>>>>>
HW context ir
render ring: ffff880024c4f5c0:   g       80KiB 01 01 0 0 0 uncached dirty (pinned x 0) (ggtt offset: 0c347000, size: 00014000) (ringbuffer, space: 128448, head: 0, tail: 384, last head: 352)
bsd ring: ffff88003f03d040:   g        8KiB 01 01 0 0 0 uncached dirty (pinned x 0) (ggtt offset: 0c37c000, size: 00002000) (ringbuffer, space: 128640, head: 0, tail: 224, last head: 192)
blitter ring:
video enhancement ring:
<<<<<<

Then:
    igdbg -c "dumpstat 0x0c347000"

>>>>>>
reg_state[CTX_LRI_HEADER_0]=0x1100101b
reg_state[CTX_CONTEXT_CONTROL]=0x2244
reg_state[CTX_CONTEXT_CONTROL+1]=0xffff0008
reg_state[CTX_RING_HEAD]=0x2034(mmio base+0x34)
reg_state[CTX_RING_HEAD+1]=0x178
reg_state[CTX_RING_TAIL]=0x2030(mmio base+0x30)
reg_state[CTX_RING_TAIL+1]=0x178
......

reg_state[CTX_RING_BUFFER_START+1] = 0xc35b000 (ring buffer gtt address)
reg_state[CTX_PDP0_LDW+1] = 0x30d4000 (page directory physical address)
<<<<<<

From the dump, the ring buffer address of the context is 0xc35b000, and the ppgtt
physical address is 0x30d4000

4.9 dumppgtt

On GEN8 and above, each context has a per-process gtt, thus don't need to put all
graphics memory mappings into global GTT

   dumppgtt <state bo>

Example:
Firstly, same above, get the state buffer address of a context, and then

    igdbg -c "dumpppgtt 0x0c347000"

>>>>>>
pde[0000]=0x05567003 (ppgtt offset range:0x00000000~0x00200000(0000M~0002M)
         pte[000] = 0x418bb01b(page no.=268475,  ppgtt addr 0x0(0000M+0000K))
         pte[001] = 0x418bc01b(page no.=268476,  ppgtt addr 0x1000(0000M+0004K))
         pte[002] = 0x418bd01b(page no.=268477,  ppgtt addr 0x2000(0000M+0008K))
         pte[003] = 0x418be01b(page no.=268478,  ppgtt addr 0x3000(0000M+0012K))
......
pde[0001]=0x720b7003 (ppgtt offset range:0x00200000~0x00400000(0002M~0004M)
         pte[000] = 0x274fa01b(page no.=161018,  ppgtt addr 0x200000(0002M+0000K))
         pte[001] = 0x274fb01b(page no.=161019,  ppgtt addr 0x201000(0002M+0004K))
         pte[002] = 0x275ec01b(page no.=161260,  ppgtt addr 0x202000(0002M+0008K))
         pte[003] = 0x275ed01b(page no.=161261,  ppgtt addr 0x203000(0002M+0012K))
......
<<<<<<


4.10 dumpring

On GEN8 and above, each context has a logical ring. "dumpring" can print the instructions
in the ring and the chained batch buffers:

   dumppgtt <state bo> <head> <tail>

Example:

Firstly, same above, get the state buffer address of a context and the head/tail of the 
ring, and then:

    igdbg -c "dumpring 0x0c347000 0 384"

>>>>>>
0x0000:0x7a000004 (PIPE_CONTROL)
	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
0x0004:0x00101001 (data)
0x0008:0x008cb080 (data)
0x000c:0x00000000 (data)
0x0010:0x00000000 (data)
0x0014:0x00000000 (data)

0x0018:0x11000005 (MI_LOAD_REGISTER_IMM)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |100010|  |000| |0000|  |0000|  |0000|  |0000|  |0101|  
0x001c:0x0000e4f0 (data)
0x0020:0x81208120 (data)
0x0024:0x00007300 (data)
0x0028:0x08100810 (data)
0x002c:0x00007004 (data)
0x0030:0x00400040 (data)

0x0034:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x0038:0x7a000004 (PIPE_CONTROL)
	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
0x003c:0x00101001 (data)
0x0040:0x008cb080 (data)
0x0044:0x00000000 (data)
0x0048:0x00000000 (data)
0x004c:0x00000000 (data)

0x0050:0x18800001 (MI_BATCH_BUFFER_START)(BB in GGTT)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |110001|  |000| |0000|  |0000|  |0000|  |0000|  |0001|  
0x0054:0x08ece000 (data)
0x0058:0x00000000 (data)

0x005c:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x0060:0x10400002 (MI_STORE_DATA_IMM)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |100000|  |100| |0000|  |0000|  |0000|  |0000|  |0010|  
0x0064:0x008cd080 (data)
0x0068:0x00000000 (data)
0x006c:0xfffff5ba (data)

0x0070:0x01000000 (MI_USER_INTERRUPT)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000010|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x0074:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x0078:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x007c:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x0080:0x7a000004 (PIPE_CONTROL)
	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
0x0084:0x01144c1c (data)
0x0088:0x008cb080 (data)
0x008c:0x00000000 (data)
0x0090:0x00000000 (data)
0x0094:0x00000000 (data)

0x0098:0x10800001 (MI_STORE_DATA_INDEX)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |100001|  |000| |0000|  |0000|  |0000|  |0000|  |0001|  
0x009c:0x00000084 (data)
0x00a0:0xfffff5bb (data)

0x00a4:0x00000000 (MI_NOOP)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |000000|  |000| |0000|  |0000|  |0000|  |0000|  |0000|  

0x00a8:0x18800101 (MI_BATCH_BUFFER_START)(BB in PPGTT)
	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	|000| |110001|  |000| |0000|  |0000|  |0001|  |0000|  |0001|  
0x00ac:0x0032f000 (data)
0x00b0:0x00000000 (data)

	BB-L1:  >>>>>>>>>>>>BB @ 0x0032f000 Begin>>>>>>>>>>>>>
	BB-L1:  0x0000:0x7a000004 (PIPE_CONTROL)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
	BB-L1:  0x0004:0x011018bc (data)
	BB-L1:  0x0008:0x00000000 (data)
	BB-L1:  0x000c:0x00000000 (data)
	BB-L1:  0x0010:0x00000000 (data)
	BB-L1:  0x0014:0x00000000 (data)

	BB-L1:  0x0018:0x7a000004 (PIPE_CONTROL)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
	BB-L1:  0x001c:0x0110189c (data)
	BB-L1:  0x0020:0x00000000 (data)
	BB-L1:  0x0024:0x00000000 (data)
	BB-L1:  0x0028:0x00000000 (data)
	BB-L1:  0x002c:0x00000000 (data)

	BB-L1:  0x0030:0x7a000004 (PIPE_CONTROL)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |11|  |010| |000|  |00000|  |0000|  |0000|  |0000|  |0100|  
	BB-L1:  0x0034:0x00104080 (data)
	BB-L1:  0x0038:0x00000068 (data)
	BB-L1:  0x003c:0x00000000 (data)
	BB-L1:  0x0040:0x00000001 (data)
	BB-L1:  0x0044:0x00000000 (data)

	BB-L1:  0x0048:0x11000001 (MI_LOAD_REGISTER_IMM)
	BB-L1:  	31 29 28    23  22 20 19  16  15  12  11  08  07  04  03  00
	BB-L1:  	|000| |100010|  |000| |0000|  |0000|  |0000|  |0000|  |0001|  
	BB-L1:  0x004c:0x00007034 (data)
	BB-L1:  0x0050:0x80000040 (data)

	BB-L1:  0x0054:0x69040001 (PIPELINE_SELECT)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |01|  |001| |000|  |00100|  |0000|  |0000|  |0000|  |0001|  

	BB-L1:  0x0058:0x6101000e (STATE_BASE_ADDRESS)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |00|  |001| |000|  |00001|  |0000|  |0000|  |0000|  |1110|  
	BB-L1:  0x005c:0x00000000 (data)
	BB-L1:  0x0060:0x00000000 (data)
	BB-L1:  0x0064:0x00000000 (data)
	BB-L1:  0x0068:0x00334001 (data)
	BB-L1:  0x006c:0x00000000 (data)
	BB-L1:  0x0070:0x0004b001 (data)
	BB-L1:  0x0074:0x00000000 (data)
	BB-L1:  0x0078:0x00000000 (data)
	BB-L1:  0x007c:0x00000000 (data)
	BB-L1:  0x0080:0x0004d001 (data)
	BB-L1:  0x0084:0x00000000 (data)
	BB-L1:  0x0088:0x00000000 (data)
	BB-L1:  0x008c:0x00002001 (data)
	BB-L1:  0x0090:0x00000000 (data)
	BB-L1:  0x0094:0x002c7001 (data)

	BB-L1:  0x0098:0x70000007 (MEDIA_VFE_STATE)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |10|  |000| |000|  |00000|  |0000|  |0000|  |0000|  |0111|  
	BB-L1:  0x009c:0x00000000 (data)
	BB-L1:  0x00a0:0x00000000 (data)
	BB-L1:  0x00a4:0x006f4000 (data)
	BB-L1:  0x00a8:0x00000000 (data)
	BB-L1:  0x00ac:0x00010004 (data)
	BB-L1:  0x00b0:0xc00000ff (data)
	BB-L1:  0x00b4:0xfff1f00f (data)
	BB-L1:  0x00b8:0xefe1e01f (data)

	BB-L1:  0x00bc:0x70010002 (MEDIA_CURBE_LOAD)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |10|  |000| |000|  |00001|  |0000|  |0000|  |0000|  |0010|  
	BB-L1:  0x00c0:0x00000000 (data)
	BB-L1:  0x00c4:0x00000080 (data)
	BB-L1:  0x00c8:0x00001f80 (data)

	BB-L1:  0x00cc:0x70020002 (MEDIA_INTERFACE_DESCRIPTOR_LOAD)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |10|  |000| |000|  |00010|  |0000|  |0000|  |0000|  |0010|  
	BB-L1:  0x00d0:0x00000000 (data)
	BB-L1:  0x00d4:0x00000040 (data)
	BB-L1:  0x00d8:0x00001f40 (data)

	BB-L1:  0x00dc:0x71000005 (MEDIA_OBJECT)
	BB-L1:  	31 29 28 27 26  24 23  21 20   16  15  12  11  08  07  04  03  00
	BB-L1:  	|011|  |10|  |001| |000|  |00000|  |0000|  |0000|  |0000|  |0101|  
	BB-L1:  0x00e0:0x00000000 (data)
	BB-L1:  0x00e4:0x00000000 (data)
	BB-L1:  0x00e8:0x00000000 (data)
	BB-L1:  0x00ec:0x00000000 (data)
	BB-L1:  0x00f0:0x00000000 (data)
	BB-L1:  0x00f4:0x00000000 (data)
......
<<<<<<

The driver may use two engines (thus two rings) for one task, e.g. in above example, the
encoding uses "render ring" and "bsd ring", and driver may use the same batch buffer for
the two rings. If the dump is at frame boundary, the instructions in the batch buffer of
render ring may be overwritten by the instructions of bsd, thus they may be lost and can
not dump correctly.


5. Reference

A. Linux graphics document: https://01.org/linuxgraphics/documentation
B. Intel video driver: http://cgit.freedesktop.org/vaapi/intel-driver/
C. i915 kernel driver: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/