diff options
Diffstat (limited to 'ring.c')
-rw-r--r-- | ring.c | 770 |
1 files changed, 770 insertions, 0 deletions
@@ -0,0 +1,770 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdint.h> +#include "main.h" + +/* from Linux kernel file: intel_lrc.c */ +#define CTX_LRI_HEADER_0 0x01 +#define CTX_CONTEXT_CONTROL 0x02 +#define CTX_RING_HEAD 0x04 +#define CTX_RING_TAIL 0x06 +#define CTX_RING_BUFFER_START 0x08 +#define CTX_RING_BUFFER_CONTROL 0x0a +#define CTX_BB_HEAD_U 0x0c +#define CTX_BB_HEAD_L 0x0e +#define CTX_BB_STATE 0x10 +#define CTX_SECOND_BB_HEAD_U 0x12 +#define CTX_SECOND_BB_HEAD_L 0x14 +#define CTX_SECOND_BB_STATE 0x16 +#define CTX_BB_PER_CTX_PTR 0x18 +#define CTX_RCS_INDIRECT_CTX 0x1a +#define CTX_RCS_INDIRECT_CTX_OFFSET 0x1c +#define CTX_LRI_HEADER_1 0x21 +#define CTX_CTX_TIMESTAMP 0x22 +#define CTX_PDP3_UDW 0x24 +#define CTX_PDP3_LDW 0x26 +#define CTX_PDP2_UDW 0x28 +#define CTX_PDP2_LDW 0x2a +#define CTX_PDP1_UDW 0x2c +#define CTX_PDP1_LDW 0x2e +#define CTX_PDP0_UDW 0x30 +#define CTX_PDP0_LDW 0x32 +#define CTX_LRI_HEADER_2 0x41 +#define CTX_R_PWR_CLK_STATE 0x42 +#define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 + + +static int process_dumpbb(int indent, unsigned int stat_addr, unsigned int bb_addr, int id); +static int process_dumpbb2(int indent, unsigned int stat_addr, unsigned int bb_addr, int id); + +static char *uint_to_char(uint32_t tmp) +{ + static char uint_char_buf[33]; + uint32_t i=0, n=tmp; + + memset(uint_char_buf,(int)'0',32); + uint_char_buf[32]='\0'; + do { + uint_char_buf[i++] = (n&1)+'0'; + n/=2; + } while(n); + + return uint_char_buf; +} + +#define printf_indent(indent, format, args...) \ + do { \ + int abc; \ + for (abc=0; abc<indent; abc++) \ + printf("\t"); \ + if (indent != 0) \ + printf("BB-L%d: ", indent); \ + printf(format, ##args); \ + } while (0) + +static int print_inst_mi(int indent, unsigned int stat_addr, uint32_t cmd_header, + int offset, uint32_t *cmd_ptr, int render_cs) +{ + int i, size; + unsigned int opcode = (cmd_header>>23) & 0x3f; + char *buf = uint_to_char(cmd_header); + int dump_bb = 0; + struct mi_inst { + uint32_t opcode; + uint32_t size; + const char *name; + } mi_insts[] = { + {0x00, 1, "MI_NOOP"}, + {0x01, 1, "MI_SET_PREDICATE"}, + {0x02, 1, "MI_USER_INTERRUPT"}, + {0x03, 1, "MI_WAIT_FOR_EVENT"}, + {0x05, 1, "MI_ARB_CHECK"}, + {0x06, 1, "MI_RS_CONTROL"}, + {0x07, 1, "MI_REPORT_HEAD"}, + {0x08, 1, "MI_ARB_ON_OFF"}, + {0x09, 1, "MI_URB_ATOMIC_ALLOC"}, + {0x0A, 1, "MI_BATCH_BUFFER_END"}, + {0x0B, 1, "MI_SUSPEND_FLUSH"}, + {0x0C, 1, "MI_PREDICATE"}, + {0x0D, 1, "MI_TOPOLOGY_FILTER"}, + {0x0E, 1, "MI_SET_APPID"}, + {0x0F, 1, "MI_RS_CONTEXT"}, + //2+ DWord + {0x10, 0, "Reserved"}, + {0x14, 0, "MI_DISPLAY_FLIP"}, + {0x15, 0, "Reserved"}, + {0x16, 0, "MI_SEMAPHORE_MBOX"}, + {0x17, 0, "Reserved"}, + {0x18, 0, "MI_SET_CONTEXT"}, + {0x19, 0, "MI_URB_CLEAR"}, + {0x1A, 0, "MI_MATH"}, + {0x1B, 0, "MI_SEMAPHORE_SIGNAL"}, + {0x1C, 0, "MI_SEMAPHORE_WAIT"}, + //Store "Data" + {0x20, 0, "MI_STORE_DATA_IMM"}, + {0x21, 0, "MI_STORE_DATA_INDEX"}, + {0x22, 0, "MI_LOAD_REGISTER_IMM"}, + {0x23, 0, "MI_UPDATE_GTT"}, + {0x24, 0, "MI_STORE_REGISTER_MEM"}, + {0x26, 0, "MI_FLUSH_DW"}, + {0x27, 0, "MI_CLFLUSH"}, + {0x28, 0, "MI_REPORT_PERF_COUNT"}, + {0x29, 0, "MI_LOAD_REGISTER_MEM"}, + {0x2A, 0, "MI_LOAD_REGISTER_REG"}, + {0x2B, 0, "MI_RS_STORE_DATA_IMM"}, + {0x2C, 0, "MI_LOAD_URB_MEM"}, + {0x2D, 0, "MI_STORE_URB_MEM"}, + {0x2E, 0, "MI_MEM_TO_MEM"}, + {0x2F, 0, "MI_ATOMIC"}, + {0x30, 0, "Reserved"}, + //Ring/batch buffer + {0x31, 3, "MI_BATCH_BUFFER_START"}, + {0x36, 1, "MI_CONDITIONAL_BATCH_BUFFER_END"}, + {0xff, 0, "TBD"}, + }, *mi_current = NULL; + + int mi_size = sizeof(mi_insts) / sizeof(mi_insts[0]); + + for (i=0; i<mi_size; i++) { + if (opcode == mi_insts[i].opcode) + break; + } + if (i==mi_size) + mi_current = &mi_insts[mi_size -1]; + else + mi_current = &mi_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)", offset, cmd_header, mi_current->name); + if (strcmp(mi_current->name, "MI_BATCH_BUFFER_START") == 0) { + if ((cmd_header & 0x100) != 0) { + dump_bb = 1; + printf("(BB in PPGTT)\n"); + } else { + /* the instructions in GGTT is the initialization code filled in Kernel */ + dump_bb = 0; + printf("(BB in GGTT)\n"); + } + } else + printf("\n"); + + printf_indent(indent,"\t"); + printf("31 29 28 23 22 20 19 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c%c%c%c%c| ",buf[28],buf[27],buf[26],buf[25],buf[24],buf[23]); + printf("|%c%c%c| ",buf[22],buf[21],buf[20]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=19;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + + //if ((opcode == 0x20) ||(opcode == 0x21)||(opcode == 0x22)) + if (mi_current->size == 0) + size = (cmd_header & 0x3f) + 2; + else if (opcode == 0x0a) /* MI_BATCH_BUFFER_END */ + size = 0; + else + size = mi_current->size; + + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + if (dump_bb == 0) + return size; + + uint32_t bb_addr = *(cmd_ptr+1); + + indent++; + printf_indent(indent,">>>>>>>>>>>>BB @ 0x%08x Begin>>>>>>>>>>>>>\n", bb_addr); + if (dump_bb == 1) { + if (render_cs) + process_dumpbb(indent, stat_addr, bb_addr, RCS); + else + process_dumpbb(indent, stat_addr, bb_addr, VCS); + } else if (dump_bb == 2) { + if (render_cs) + process_dumpbb2(indent, stat_addr, bb_addr, RCS); + else + process_dumpbb2(indent, stat_addr, bb_addr, VCS); + } + printf_indent(indent,"<<<<<<<<<<<BB @ 0x%08x End<<<<<<<<<<<<<<<<<\n\n", bb_addr); + + return size; +} + + +static int print_inst_rendercs(int indent, uint32_t cmd_header, int offset, uint32_t *cmd_ptr) +{ + int i, size; + unsigned int opcode_bit28_27 = (cmd_header>>27) & 0x3; + unsigned int opcode_bit26_24 = (cmd_header>>24) & 0x7; + unsigned int opcode_bit23_16 = (cmd_header>>16) & 0xff; + char *buf = uint_to_char(cmd_header); + struct render_inst { + uint32_t opcode_bit28_27; + uint32_t opcode_bit26_24; + uint32_t opcode_bit23_16; + uint32_t size; + const char *name; + } render_insts[] = { + { 0, 1, 0x1, 0, "STATE_BASE_ADDRESS" }, + { 1, 1, 0x4, 1, "PIPELINE_SELECT"}, + + { 2, 0, 0x0, 0, "MEDIA_VFE_STATE" }, + { 2, 0, 0x1, 0, "MEDIA_CURBE_LOAD" }, + { 2, 0, 0x2, 0, "MEDIA_INTERFACE_DESCRIPTOR_LOAD" }, + { 2, 0, 0x3, 0, "CMD_MEDIA_GATEWAY_STATE" }, + { 2, 0, 0x4, 0, "MEDIA_STATE_FLUSH" }, + { 2, 1, 0x0, 0, "MEDIA_OBJECT" }, + { 2, 1, 0x2, 0, "MEDIA_OBJECT_PTR" }, + { 2, 1, 0x3, 0, "MEDIA_OBJECT_WALKER" }, + + { 3, 0, 0x04, 0, "3DSTATE_CLEAR_PARAMS" }, + { 3, 0, 0x05, 0, "3DSTATE_DEPTH_BUFFER" }, + { 3, 0, 0x06, 0, "3DSTATE_STENCIL_BUFFER" }, + { 3, 0, 0x07, 0, "3DSTATE_HIER_DEPTH_BUFFER" }, + { 3, 0, 0x08, 0, "3DSTATE_VERTEX_BUFFERS" }, + { 3, 0, 0x09, 0, "3DSTATE_VERTEX_ELEMENTS" }, + { 3, 0, 0x0A, 0, "3DSTATE_INDEX_BUFFER" }, + { 3, 0, 0x0B, 0, "3DSTATE_VF_STATISTICS" }, + { 3, 0, 0x0D, 0, "3DSTATE_VIEWPORT_STATE_POINTERS" }, + { 3, 0, 0x0E, 0, "3DSTATE_CC_STATE_POINTERS" }, + { 3, 0, 0x10, 0, "3DSTATE_VS" }, + { 3, 0, 0x11, 0, "3DSTATE_GS" }, + { 3, 0, 0x12, 0, "3DSTATE_CLIP" }, + { 3, 0, 0x13, 0, "3DSTATE_SF" }, + { 3, 0, 0x14, 0, "3DSTATE_WM" }, + { 3, 0, 0x15, 0, "3DSTATE_CONSTANT_VS" }, + { 3, 0, 0x16, 0, "3DSTATE_CONSTANT_GS" }, + { 3, 0, 0x17, 0, "3DSTATE_CONSTANT_PS" }, + { 3, 0, 0x18, 0, "3DSTATE_SAMPLE_MASK" }, + { 3, 0, 0x19, 0, "3DSTATE_CONSTANT_HS" }, + { 3, 0, 0x1A, 0, "3DSTATE_CONSTANT_DS" }, + { 3, 0, 0x1B, 0, "3DSTATE_HS" }, + { 3, 0, 0x1C, 0, "3DSTATE_TE" }, + { 3, 0, 0x1D, 0, "3DSTATE_DS" }, + { 3, 0, 0x1E, 0, "3DSTATE_STREAMOUT" }, + { 3, 0, 0x1F, 0, "3DSTATE_SBE" }, + { 3, 0, 0x20, 0, "3DSTATE_PS" }, + { 3, 0, 0x21, 0, "3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP" }, + { 3, 0, 0x23, 0, "3DSTATE_VIEWPORT_STATE_POINTERS_CC" }, + { 3, 0, 0x24, 0, "3DSTATE_BLEND_STATE_POINTERS" }, + { 3, 0, 0x25, 0, "3DSTATE_DEPTH_STENCIL_STATE_POINTERS" }, + { 3, 0, 0x26, 0, "3DSTATE_BINDING_TABLE_POINTERS_VS" }, + { 3, 0, 0x27, 0, "3DSTATE_BINDING_TABLE_POINTERS_HS" }, + { 3, 0, 0x28, 0, "3DSTATE_BINDING_TABLE_POINTERS_DS" }, + { 3, 0, 0x29, 0, "3DSTATE_BINDING_TABLE_POINTERS_GS" }, + { 3, 0, 0x2A, 0, "3DSTATE_BINDING_TABLE_POINTERS_PS" }, + { 3, 0, 0x2B, 0, "3DSTATE_SAMPLER_STATE_POINTERS_VS" }, + { 3, 0, 0x2C, 0, "3DSTATE_SAMPLER_STATE_POINTERS_HS" }, + { 3, 0, 0x2D, 0, "3DSTATE_SAMPLER_STATE_POINTERS_DS" }, + { 3, 0, 0x2E, 0, "3DSTATE_SAMPLER_STATE_POINTERS_GS" }, + { 3, 0, 0x30, 0, "3DSTATE_URB_VS" }, + { 3, 0, 0x31, 0, "3DSTATE_URB_HS" }, + { 3, 0, 0x32, 0, "3DSTATE_URB_DS" }, + { 3, 0, 0x33, 0, "3DSTATE_URB_GS" }, + { 3, 0, 0x34, 0, "3DSTATE_GATHER_CONSTANT_VS" }, + { 3, 0, 0x35, 0, "3DSTATE_GATHER_CONSTANT_GS" }, + { 3, 0, 0x36, 0, "3DSTATE_GATHER_CONSTANT_HS" }, + { 3, 0, 0x37, 0, "3DSTATE_GATHER_CONSTANT_DS" }, + { 3, 0, 0x38, 0, "3DSTATE_GATHER_CONSTANT_PS" }, + { 3, 0, 0x39, 0, "3DSTATE_DX9_CONSTANTF_VS" }, + { 3, 0, 0x3A, 0, "3DSTATE_DX9_CONSTANTF_PS" }, + { 3, 0, 0x3B, 0, "3DSTATE_DX9_CONSTANTI_VS" }, + { 3, 0, 0x3C, 0, "3DSTATE_DX9_CONSTANTI_PS" }, + { 3, 0, 0x3D, 0, "3DSTATE_DX9_CONSTANTB_VS" }, + { 3, 0, 0x3E, 0, "3DSTATE_DX9_CONSTANTB_PS" }, + { 3, 0, 0x3F, 0, "3DSTATE_DX9_LOCAL_VALID_VS" }, + { 3, 0, 0x40, 0, "3DSTATE_DX9_LOCAL_VALID_PS" }, + { 3, 0, 0x41, 0, "3DSTATE_DX9_GENERATE_ACTIVE_VS" }, + { 3, 0, 0x42, 0, "3DSTATE_DX9_GENERATE_ACTIVE_PS" }, + { 3, 0, 0x43, 0, "3DSTATE_BINDING_TABLE_EDIT_VS" }, + { 3, 0, 0x44, 0, "3DSTATE_BINDING_TABLE_EDIT_GS" }, + { 3, 0, 0x45, 0, "3DSTATE_BINDING_TABLE_EDIT_HS" }, + { 3, 0, 0x46, 0, "3DSTATE_BINDING_TABLE_EDIT_DS" }, + { 3, 0, 0x47, 0, "3DSTATE_BINDING_TABLE_EDIT_PS" }, + { 3, 0, 0x48, 0, "3DSTATE_VF_HASHING" }, + { 3, 0, 0x49, 0, "3DSTATE_VF_INSTANCING" }, + { 3, 0, 0x4A, 0, "3DSTATE_VF_SGVS" }, + { 3, 0, 0x4B, 0, "3DSTATE_VF_TOPOLOGY" }, + { 3, 0, 0x4C, 0, "3DSTATE_WM_CHROMA_KEY" }, + { 3, 0, 0x4D, 0, "3DSTATE_PS_BLEND" }, + { 3, 0, 0x4E, 0, "3DSTATE_WM_DEPTH_STENCIL" }, + { 3, 0, 0x4F, 0, "3DSTATE_PS_EXTRA" }, + { 3, 0, 0x50, 0, "3DSTATE_RASTER" }, + { 3, 0, 0x51, 0, "3DSTATE_SBE_SWIZ" }, + { 3, 0, 0x52, 0, "3DSTATE_WM_HZ_OP" }, + { 3, 0, 0x53, 0, "3DSTATE_INT" }, + { 3, 1, 0x00, 0, "3DSTATE_DRAWING_RECTANGLE" }, + { 3, 1, 0x02, 0, "3DSTATE_SAMPLER_PALETTE_LOAD0" }, + { 3, 1, 0x04, 0, "3DSTATE_CHROMA_KEY" }, + { 3, 1, 0x06, 0, "3DSTATE_POLY_STIPPLE_OFFSET" }, + { 3, 1, 0x07, 0, "3DSTATE_POLY_STIPPLE_PATTERN" }, + { 3, 1, 0x08, 0, "3DSTATE_LINE_STIPPLE" }, + { 3, 1, 0x0A, 0, "3DSTATE_AA_LINE_PARAMS" }, + { 3, 1, 0x0B, 0, "3DSTATE_GS_SVB_INDEX" }, + { 3, 1, 0x0C, 0, "3DSTATE_SAMPLER_PALETTE_LOAD1" }, + { 3, 1, 0x0D, 0, "3DSTATE_MULTISAMPLE" }, + { 3, 1, 0x0E, 0, "3DSTATE_STENCIL_BUFFER" }, + { 3, 1, 0x0F, 0, "3DSTATE_HIER_DEPTH_BUFFER" }, + { 3, 1, 0x10, 0, "3DSTATE_CLEAR_PARAMS" }, + { 3, 1, 0x11, 0, "3DSTATE_MONOFILTER_SIZE" }, + { 3, 1, 0x12, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_VS" }, + { 3, 1, 0x13, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_HS" }, + { 3, 1, 0x14, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_DS" }, + { 3, 1, 0x15, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_GS" }, + { 3, 1, 0x16, 0, "3DSTATE_PUSH_CONSTANT_ALLOC_PS" }, + { 3, 1, 0x17, 0, "3DSTATE_SO_DECL_LIST" }, + { 3, 1, 0x18, 0, "3DSTATE_SO_BUFFER" }, + { 3, 1, 0x19, 0, "3DSTATE_BINDING_TABLE_POOL_ALLOC" }, + { 3, 1, 0x1A, 0, "3DSTATE_GATHER_POOL_ALLOC" }, + { 3, 1, 0x1B, 0, "3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC" }, + { 3, 1, 0x1C, 0, "3DSTATE_SAMPLE_PATTERN" }, + { 3, 1, 0x1D, 0, "3DSTATE_URB_CLEAR" }, + { 3, 2, 0x00, 0, "PIPE_CONTROL" }, + { 3, 3, 0x00, 0, "3DPRIMITIVE" }, + { 3, 7, 0xff, 0, "TBD"}, + }, *render_current = NULL; + + int render_size = sizeof(render_insts) / sizeof(render_insts[0]); + + for (i=0; i<render_size; i++) { + if ((opcode_bit28_27 == render_insts[i].opcode_bit28_27) + && (opcode_bit26_24 == render_insts[i].opcode_bit26_24) + && (opcode_bit23_16 == render_insts[i].opcode_bit23_16)) + break; + } + if (i==render_size) + render_current = &render_insts[render_size -1]; + else + render_current = &render_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)\n", offset, cmd_header, render_current->name); + + printf_indent(indent,"\t"); + printf("31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c| ",buf[28],buf[27]); + printf("|%c%c%c| ", buf[26],buf[25],buf[24]); + printf("|%c%c%c| ", buf[23],buf[22],buf[21]); + printf("|%c%c%c%c%c| ", buf[20],buf[19],buf[18],buf[17],buf[16]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=15;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + /* + if ((strcmp(render_current->name, "MFX_PIPE_MODE_SELECT") == 0) + || (strcmp(render_current->name, "MFX_SURFACE_STATE") == 0) + || (strcmp(render_current->name, "MFX_PIPE_BUF_ADDR_STATE") == 0)) + */ + if (render_current->size == 0) + size = (cmd_header & 0xfff) + 2; + else + size = render_current->size; + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + return size; +} + + +static int print_inst_mfxcs(int indent, uint32_t cmd_header, int offset, uint32_t *cmd_ptr) +{ + int i, size; + unsigned int opcode_bit28_27 = (cmd_header>>27) & 0x3; + unsigned int opcode_bit26_24 = (cmd_header>>24) & 0x7; + unsigned int opcode_bit23_21 = (cmd_header>>21) & 0x7; + unsigned int opcode_bit20_16 = (cmd_header>>16) & 0x1f; + char *buf = uint_to_char(cmd_header); + struct mfx_inst { + uint32_t opcode_bit28_27; + uint32_t opcode_bit26_24; + uint32_t opcode_bit23_21; + uint32_t opcode_bit20_16; + uint32_t size; + const char *name; + } mfx_insts[] = { + {1, 0, 0, 0, 1, "MFX_WAIT"}, + {2, 0, 0, 0, 0, "MFX_PIPE_MODE_SELECT"}, + {2, 0, 0, 1, 0, "MFX_SURFACE_STATE"}, + {2, 0, 0, 2, 0, "MFX_PIPE_BUF_ADDR_STATE"}, + {2, 0, 0, 3, 0, "MFX_IND_OBJ_BASE_ADDR_STATE"}, + {2, 0, 0, 4, 0, "MFX_BSP_BUF_BASE_ADDR_STATE"}, + {2, 0, 0, 5, 0, "MFX_AES_STATE"}, + {2, 0, 0, 6, 0, "MFX_STATE_POINTER"}, + {2, 0, 0, 7, 0, "MFX_QM_STATE"}, + {2, 0, 0, 8, 0, "MFX_FQM_STATE"}, + {2, 0, 1, 9, 0, "MFD_IT_OBJECT"}, + {2, 0, 2, 8, 0, "MFX_INSERT_OBJECT"}, + {2, 1, 0, 0, 0, "MFX_AVC_IMG_STATE"}, + {2, 1, 0, 1, 0, "MFX_AVC_QM_STATE"}, + {2, 1, 0, 2, 0, "MFX_AVC_DIRECTMODE_STATE"}, + {2, 1, 0, 3, 0, "MFX_AVC_SLICE_STATE"}, + {2, 1, 0, 4, 0, "MFX_AVC_REF_IDX_STATE"}, + {2, 1, 0, 5, 0, "MFX_AVC_WEIGHTOFFSET_STATE"}, + {2, 1, 1, 5, 0, "MFD_AVC_PICID_STATE"}, + {2, 1, 1, 8, 0, "MFD_AVC_BSD_OBJECT"}, + {2, 1, 2, 2, 0, "MFC_AVC_FQM_STATE"}, + {2, 1, 2, 8, 0, "MFC_AVC_PAK_INSERT_OBJECT"}, + {2, 1, 2, 9, 0, "MFC_AVC_PAK_OBJECT"}, + {2, 2, 0, 0, 0, "MFX_VC1_PIC_STATE"}, + {2, 2, 0, 1, 0, "MFX_VC1_PRED_PIPE_STATE"}, + {2, 2, 0, 2, 0, "MFX_VC1_DIRECTMODE_STATE"}, + {2, 2, 1, 0, 0, "MFD_VC1_SHORT_PIC_STATE"}, + {2, 2, 1, 1, 0, "MFD_VC1_LONG_PIC_STATE"}, + {2, 2, 1, 8, 0, "MFD_VC1_BSD_OBJECT"}, + {2, 3, 0, 0, 0, "MFX_MPEG2_PIC_STATE"}, + {2, 3, 0, 1, 0, "MFX_MPEG2_QM_STATE"}, + {2, 3, 1, 8, 0, "MFD_MPEG2_BSD_OBJECT"}, + {2, 3, 2, 3, 0, "MFC_MPEG2_PAK_OBJECT"}, + {2, 3, 2, 9, 0, "MFC_MPEG2_SLICEGROUP_STATE"}, + {2, 4, 0, 0, 0, "MFX_VP8_PIC_STATE"}, + {2, 4, 1, 8, 0, "MFD_VP8_BSD_OBJECT"}, + {2, 4, 2, 1, 0, "MFX_VP8_ENCODER_CFG"}, + {2, 4, 2, 3, 0, "MFX_VP8_BSP_BUF_BASE_ADDR_STATE"}, + {2, 4, 2, 9, 0, "MFX_VP8_PAK_OBJECT"}, + {2, 7, 0, 0, 0, "MFX_JPEG_PIC_STATE"}, + {2, 7, 0, 2, 0, "MFX_JPEG_HUFF_TABLE_STATE"}, + {2, 7, 0, 0, 0, "MFX_JPEG_PIC_STATE"}, + {2, 7, 0, 2, 0, "MFX_JPEG_HUFF_TABLE_STATE"}, + {2, 7, 1, 8, 0, "MFD_JPEG_BSD_OBJECT"}, + {2, 7, 2, 9, 0, "MFC_JPEG_SCAN_OBJECT"}, + {2, 7, 2, 3, 0, "MFC_JPEG_HUFF_TABLE_STATE"}, + {3, 4, 0, 0, 0, "VEB_SURFACE_STATE"}, + {3, 4, 0, 2, 0, "VEB_STATE"}, + {3, 4, 0, 3, 0, "VEB_DNDI_IECP_STATE"}, + {3, 2, 7, 0, 0, "HCP_PIPE_MODE_SELECT"}, + {3, 2, 7, 1, 0, "HCP_SURFACE_STATE"}, + + {2, 7, 7, 0x1f, 0, "TBD"}, + }, *mfx_current = NULL; + + int mfx_size = sizeof(mfx_insts) / sizeof(mfx_insts[0]); + + for (i=0; i<mfx_size; i++) { + if ((opcode_bit28_27 == mfx_insts[i].opcode_bit28_27) + && (opcode_bit26_24 == mfx_insts[i].opcode_bit26_24) + && (opcode_bit23_21 == mfx_insts[i].opcode_bit23_21) + && (opcode_bit20_16 == mfx_insts[i].opcode_bit20_16)) + break; + } + if (i==mfx_size) + mfx_current = &mfx_insts[mfx_size -1]; + else + mfx_current = &mfx_insts[i]; + + printf_indent(indent,"0x%04x:0x%08x (%s)\n", offset, cmd_header, mfx_current->name); + + printf_indent(indent,"\t"); + printf("31 29 28 27 26 24 23 21 20 16 15 12 11 08 07 04 03 00\n"); + printf_indent(indent,"\t"); + printf("|%c%c%c| ",buf[31],buf[30],buf[29]); + printf("|%c%c| ",buf[28],buf[27]); + printf("|%c%c%c| ", buf[26],buf[25],buf[24]); + printf("|%c%c%c| ", buf[23],buf[22],buf[21]); + printf("|%c%c%c%c%c| ", buf[20],buf[19],buf[18],buf[17],buf[16]); +#define print_four_bits(from) printf("|%c%c%c%c| ",buf[from],buf[from-1],buf[from-2],buf[from-3]) + for (i=15;i>=3;i=i-4) + print_four_bits(i); + + printf("\n"); + if (mfx_current->size == 0) + size = (cmd_header & 0xfff) + 2; + else + size = mfx_current->size; + for (i=1; i<size; i++) + printf_indent(indent,"0x%04x:0x%08x (data)\n", offset+i*4, *(cmd_ptr+i)); + + printf("\n"); + + return size; +} + +int process_dumpring(char *cmdhdr,unsigned int stat_addr, unsigned int head, unsigned int tail) +{ + uint32_t *ring_ptr, i, dw_count; + uint32_t ring_addr; + /* render CS has PIPE_CONTROL, use it to differentiate render and video... */ + int render_cs = 0; + + if (is_gen7) { + printf("Execlist/Logica ring is not supported on GEN7\n"); + return 0; + } + CHECK_STRICT_DEVMEM; + + if (tail <= head) { + printf("Invalid tail=%d/head=%d\n", tail, head); + return 0; + } + ring_addr = get_ring(stat_addr); + + dw_count = (tail - head)/4; + printf("Ring buffer address 0x%08x(%dM+%dK), head =%d(0x%x), tail=%d(0x%x), %d instructions \n", + ring_addr, ring_addr>>20, (ring_addr>>10) & 0x3ff, + head, head, tail, tail, dw_count); + + printf("************************************************************************\n"); + + ring_ptr = (uint32_t *)((unsigned char *)linear_fb + ring_addr + head); + for (i=0; i<dw_count;) { + uint32_t cmd_header = *ring_ptr; + uint32_t type = (cmd_header>>29)&0x7; + uint32_t dw_cmdpkg = 1; + + if (type == 0) + dw_cmdpkg = print_inst_mi(0, stat_addr, cmd_header, head+i*4, ring_ptr, render_cs); + else if (type == 3) { + render_cs = 1; + dw_cmdpkg = print_inst_rendercs(0, cmd_header, head+i*4, ring_ptr); + } else + printf("Unknow instructions 0x%08x\n", cmd_header); + + ring_ptr += dw_cmdpkg; + + i = i + dw_cmdpkg; + } + + return 0; +} + +#define BB_MAX_PAGE 10 +#define BB_MAX_CMDS (BB_MAX_PAGE*4096/4) +static int dumpbb_help(int indent, unsigned int stat_addr, uint32_t *bb_ptr, int id) +{ + uint32_t cmd_header, type; + uint32_t dw_count, dw_cmdpkg=0; + + /* Parse all BB commands */ + dw_count = 0; + while (1) { + cmd_header = *bb_ptr; + type = (cmd_header>>29)&0x7; + + if (type == 0) + dw_cmdpkg = print_inst_mi(indent, stat_addr, cmd_header, dw_count*4, bb_ptr, id == RCS); + else if (type == 3) { + if (id == RCS) + dw_cmdpkg = print_inst_rendercs(indent, cmd_header, dw_count*4, bb_ptr); + else if (id == VCS) + dw_cmdpkg = print_inst_mfxcs(indent, cmd_header, dw_count*4, bb_ptr); + } else { + printf_indent(indent,"Unknow instructions 0x%08x\n", cmd_header); + print_bin_fmt(cmd_header, 8); + + dw_cmdpkg = 1; + } + + if (dw_cmdpkg == 0) /*MI_BATCH_BUFFER_END*/ + break; + + dw_count = dw_count + dw_cmdpkg; + bb_ptr += dw_cmdpkg; + + if (dw_count >= BB_MAX_CMDS) { + printf_indent(indent,"The batch buffer is still not ended, bugs? Break the loop\n"); + break; + } + } + + return 0; +} + +static int process_dumpbb2(int indent, unsigned int stat_addr, unsigned int bb_addr, int id) +{ + uint32_t *bb_ptr; + + /* + printf("Render ring batch buffer address in GGTT 0x%08x(%dM+%dK, offset in page %d)\n", + bb_addr, bb_addr>>20, (bb_addr>>10) & 0x3ff, bb_addr & 0xfff); + */ + + /* Parse all BB commands */ + bb_ptr = (uint32_t *)((unsigned char *)linear_fb + bb_addr); + dumpbb_help(indent, stat_addr, bb_ptr, id); + + return 0; +} + +static int process_dumpbb(int indent, unsigned int stat_addr, unsigned int bb_addr, int id) +{ + uint32_t bb_addr_aligned, bb_addr_offset; + uint32_t i, *bb_ptr; + unsigned char *ten_pages; + + uint32_t ppgtt_addr = get_ppgtt(stat_addr); + + bb_addr_aligned = bb_addr & 0xfffff000;; + bb_addr_offset = bb_addr & 0xfff; + + /* + printf("Render ring batch buffer address in PPGTT 0x%08x(%dM+%dK, offset in page %d)\n", + bb_addr, bb_addr>>20, (bb_addr>>10) & 0x3ff, bb_addr_offset); + printf("Read ten pages from PPGTT mapping (physical address 0x%08x)\n", ppgtt_addr); + */ + /* Read maximum pages to avoid one command package + * wrapping on two pages. It is for simplicity + */ + ten_pages = malloc(BB_MAX_PAGE * 4096); + for (i=0; i<BB_MAX_PAGE; i++) + get_ppgtt_page(ppgtt_addr, bb_addr_aligned + i * 4096, ten_pages + i * 4096); + + /* Parse all BB commands */ + bb_ptr = (uint32_t *)(ten_pages + bb_addr_offset); + dumpbb_help(indent, stat_addr, bb_ptr, id); + + return 0; +} + +uint32_t get_ppgtt(unsigned int stat_addr) +{ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + + /* + printf("Stat buffer: reg_state[CTX_PDP0_LDW+1] = 0x%x (page directory physical address)\n", + reg_state[CTX_PDP0_LDW+1]); + */ + return reg_state[CTX_PDP0_LDW+1]; +} + +uint32_t get_ring(unsigned int stat_addr) +{ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + + /* + printf("Stat buffer: reg_state[CTX_RING_BUFFER_START+1] = 0x%x (ring address)\n", + reg_state[CTX_RING_BUFFER_START+1]); + */ + return reg_state[CTX_RING_BUFFER_START+1]; +} + + +int process_dumpstat(char *cmdhdr,unsigned int stat_addr) +{ + /* The second page of the context object contains some fields which must + * be set up prior to the first execution. + */ + uint32_t *reg_state = (uint32_t *)(linear_fb+stat_addr + 4096); + int id = RCS; /* ignore it currently */ + + if (is_gen7) { + printf("Execlist/logical ring is not supported on GEN7\n"); + return 0; + } + CHECK_STRICT_DEVMEM; + + /* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM + * commands followed by (reg, value) pairs. The values we are setting here are + * only for the first context restore: on a subsequent save, the GPU will + * recreate this batchbuffer with new values (including all the missing + * MI_LOAD_REGISTER_IMM commands that we are not initializing here). */ + printf("reg_state[CTX_LRI_HEADER_0]=0x%x\n", reg_state[CTX_LRI_HEADER_0]); + printf("reg_state[CTX_CONTEXT_CONTROL]=0x%x\n", reg_state[CTX_CONTEXT_CONTROL]); + printf("reg_state[CTX_CONTEXT_CONTROL+1]=0x%x\n", reg_state[CTX_CONTEXT_CONTROL+1]); + printf("reg_state[CTX_RING_HEAD]=0x%x(mmio base+0x34)\n", reg_state[CTX_RING_HEAD]); + printf("reg_state[CTX_RING_HEAD+1]=0x%x\n", reg_state[CTX_RING_HEAD+1]); + printf("reg_state[CTX_RING_TAIL]=0x%x(mmio base+0x30)\n", reg_state[CTX_RING_TAIL]); + printf("reg_state[CTX_RING_TAIL+1]=0x%x\n", reg_state[CTX_RING_TAIL+1]); + /* Ring buffer start address is not known until the buffer is pinned. + * It is written to the context image in execlists_update_context() + */ + printf("reg_state[CTX_RING_BUFFER_START]=0x%x(mmio base+0x38)\n", reg_state[CTX_RING_BUFFER_START]); + printf("reg_state[CTX_RING_BUFFER_START+1]=0x%x(mmio base+0x38+4)\n", reg_state[CTX_RING_BUFFER_START+1]); + printf("reg_state[CTX_RING_BUFFER_CONTROL]=0x%x(mmio base+0x3c)\n", reg_state[CTX_RING_BUFFER_CONTROL]); + printf("reg_state[CTX_RING_BUFFER_CONTROL+1]=0x%x\n", reg_state[CTX_RING_BUFFER_CONTROL+1]); + printf("reg_state[CTX_BB_HEAD_U]=0x%x(mmio base+0x168)\n", reg_state[CTX_BB_HEAD_U]); + printf("reg_state[CTX_BB_HEAD_U+1]=0x%x\n", reg_state[CTX_BB_HEAD_U+1]); + printf("reg_state[CTX_BB_HEAD_L]=0x%x(mmio base+0x140)\n", reg_state[CTX_BB_HEAD_L]); + printf("reg_state[CTX_BB_HEAD_L+1]=0x%x\n", reg_state[CTX_BB_HEAD_L+1]); + printf("reg_state[CTX_BB_STATE]=0x%x(mmio base+0x110)\n", reg_state[CTX_BB_STATE]); + printf("reg_state[CTX_BB_STATE+1]=0x%x\n", reg_state[CTX_BB_STATE+1]); + printf("reg_state[CTX_SECOND_BB_HEAD_U]=0x%x(mmio base+0x11c)\n", reg_state[CTX_SECOND_BB_HEAD_U]); + printf("reg_state[CTX_SECOND_BB_HEAD_U+1]=0x%x\n", reg_state[CTX_SECOND_BB_HEAD_U+1]); + printf("reg_state[CTX_SECOND_BB_HEAD_L]=0x%x(mmio base+0x114)\n", reg_state[CTX_SECOND_BB_HEAD_L]); + printf("reg_state[CTX_SECOND_BB_HEAD_L+1]=0x%x\n", reg_state[CTX_SECOND_BB_HEAD_L+1]); + printf("reg_state[CTX_SECOND_BB_STATE]=0x%x(mmio base+0x118)\n", reg_state[CTX_SECOND_BB_STATE]); + printf("reg_state[CTX_SECOND_BB_STATE+1]=0x%x\n", reg_state[CTX_SECOND_BB_STATE+1]); + + if (id == RCS) { + printf("reg_state[CTX_BB_PER_CTX_PTR]=0x%x\n", reg_state[CTX_BB_PER_CTX_PTR]); + printf("reg_state[CTX_BB_PER_CTX_PTR+1]=0x%x\n", reg_state[CTX_BB_PER_CTX_PTR+1]); + printf("reg_state[CTX_RCS_INDIRECT_CTX]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX]); + printf("reg_state[CTX_RCS_INDIRECT_CTX+1]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX+1]); + printf("reg_state[CTX_RCS_INDIRECT_CTX_OFFSET]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX_OFFSET]); + printf("reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1]=0x%x\n", reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1]); + } + + printf("reg_state[CTX_LRI_HEADER_1]=0x%x\n", reg_state[CTX_LRI_HEADER_1]); + printf("reg_state[CTX_LRI_HEADER_1]=0x%x\n", reg_state[CTX_LRI_HEADER_1]); + printf("reg_state[CTX_CTX_TIMESTAMP]=0x%x\n", reg_state[CTX_CTX_TIMESTAMP]); + printf("reg_state[CTX_CTX_TIMESTAMP+1]=0x%x\n", reg_state[CTX_CTX_TIMESTAMP+1]); + printf("reg_state[CTX_PDP3_UDW]=0x%x(mmio base+0x270+(3*8)+4)\n", reg_state[CTX_PDP3_UDW]); + printf("reg_state[CTX_PDP3_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP3_LDW]); + printf("reg_state[CTX_PDP2_UDW]=0x%x(mmio base+0x270+(2*8)+4)\n", reg_state[CTX_PDP2_UDW]); + printf("reg_state[CTX_PDP2_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP2_LDW]); + printf("reg_state[CTX_PDP1_UDW]=0x%x(mmio base+0x270+(1*8)+4)\n", reg_state[CTX_PDP1_UDW]); + printf("reg_state[CTX_PDP1_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP1_LDW]); + printf("reg_state[CTX_PDP0_UDW]=0x%x(mmio base+0x270+(0*8)+4)\n", reg_state[CTX_PDP0_UDW]); + printf("reg_state[CTX_PDP0_LDW]=0x%x(mmio base+0x270+(3*8))\n", reg_state[CTX_PDP0_LDW]); + printf("reg_state[CTX_PDP3_UDW+1]=0x%x\n", reg_state[CTX_PDP3_UDW+1]); + printf("reg_state[CTX_PDP3_LDW+1]=0x%x(pd 3 phyaddr)\n", reg_state[CTX_PDP3_LDW+1]); + printf("reg_state[CTX_PDP2_UDW+1]=0x%x\n", reg_state[CTX_PDP2_UDW+1]); + printf("reg_state[CTX_PDP2_LDW+1]=0x%x(pd 2 phyaddr)\n", reg_state[CTX_PDP2_LDW+1]); + printf("reg_state[CTX_PDP1_UDW+1]=0x%x\n", reg_state[CTX_PDP1_UDW+1]); + printf("reg_state[CTX_PDP1_LDW+1]=0x%x(pd 1 phyaddr)\n", reg_state[CTX_PDP1_LDW+1]); + printf("reg_state[CTX_PDP0_UDW+1]=0x%x\n", reg_state[CTX_PDP0_UDW+1]); + printf("reg_state[CTX_PDP0_LDW+1]=0x%x(pd 0 phyaddr)\n", reg_state[CTX_PDP0_LDW+1]); + + if (id == RCS) { + printf("reg_state[CTX_LRI_HEADER_2]=0x%x\n", reg_state[CTX_LRI_HEADER_2]); + printf("reg_state[CTX_R_PWR_CLK_STATE]=0x%x\n", reg_state[CTX_R_PWR_CLK_STATE]); + printf("reg_state[CTX_R_PWR_CLK_STATE+1]=0x%x\n", reg_state[CTX_R_PWR_CLK_STATE+1]); + } + + printf("*****************************************************************\n"); + printf("reg_state[CTX_RING_BUFFER_START+1] = 0x%x (ring buffer gtt address)\n", + reg_state[CTX_RING_BUFFER_START+1]); + printf("reg_state[CTX_PDP0_LDW+1] = 0x%x (page directory physical address)\n", + reg_state[CTX_PDP0_LDW+1]); + //printf("Render Ring [%d..%d); Video Ring [%d..%d)\n", + // INREG(linear_mmio, 0x2034), INREG(linear_mmio, 0x2030), + // INREG(linear_mmio, 0x12034), INREG(linear_mmio, 0x12030)); + printf("*****************************************************************\n"); + + return 0; +} |