File Index
Files and directories
Sign in
FILE

cmd_parser.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/gvt/cmd_parser.c C
   1/*
   2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 * SOFTWARE.
  22 *
  23 * Authors:
  24 *    Ke Yu
  25 *    Kevin Tian <kevin.tian@intel.com>
  26 *    Zhiyuan Lv <zhiyuan.lv@intel.com>
  27 *
  28 * Contributors:
  29 *    Min He <min.he@intel.com>
  30 *    Ping Gao <ping.a.gao@intel.com>
  31 *    Tina Zhang <tina.zhang@intel.com>
  32 *    Yulei Zhang <yulei.zhang@intel.com>
  33 *    Zhi Wang <zhi.a.wang@intel.com>
  34 *
  35 */
  36
  37#include <linux/slab.h>
  38
  39#include <drm/drm_print.h>
  40
  41#include "i915_drv.h"
  42#include "i915_reg.h"
  43#include "display/intel_display_regs.h"
  44#include "gt/intel_engine_regs.h"
  45#include "gt/intel_gpu_commands.h"
  46#include "gt/intel_gt_regs.h"
  47#include "gt/intel_lrc.h"
  48#include "gt/intel_ring.h"
  49#include "gt/intel_gt_requests.h"
  50#include "gt/shmem_utils.h"
  51#include "gvt.h"
  52#include "i915_pvinfo.h"
  53#include "trace.h"
  54
  55#include "display/i9xx_plane_regs.h"
  56#include "display/intel_display_core.h"
  57#include "display/intel_sprite_regs.h"
  58#include "gem/i915_gem_context.h"
  59#include "gem/i915_gem_pm.h"
  60#include "gt/intel_context.h"
  61
  62#define INVALID_OP    (~0U)
  63
  64#define OP_LEN_MI           9
  65#define OP_LEN_2D           10
  66#define OP_LEN_3D_MEDIA     16
  67#define OP_LEN_MFX_VC       16
  68#define OP_LEN_VEBOX	    16
  69
  70#define CMD_TYPE(cmd)	(((cmd) >> 29) & 7)
  71
  72struct sub_op_bits {
  73	int hi;
  74	int low;
  75};
  76struct decode_info {
  77	const char *name;
  78	int op_len;
  79	int nr_sub_op;
  80	const struct sub_op_bits *sub_op;
  81};
  82
  83#define   MAX_CMD_BUDGET			0x7fffffff
  84#define   MI_WAIT_FOR_PLANE_C_FLIP_PENDING      (1<<15)
  85#define   MI_WAIT_FOR_PLANE_B_FLIP_PENDING      (1<<9)
  86#define   MI_WAIT_FOR_PLANE_A_FLIP_PENDING      (1<<1)
  87
  88#define   MI_WAIT_FOR_SPRITE_C_FLIP_PENDING      (1<<20)
  89#define   MI_WAIT_FOR_SPRITE_B_FLIP_PENDING      (1<<10)
  90#define   MI_WAIT_FOR_SPRITE_A_FLIP_PENDING      (1<<2)
  91
  92/* Render Command Map */
  93
  94/* MI_* command Opcode (28:23) */
  95#define OP_MI_NOOP                          0x0
  96#define OP_MI_SET_PREDICATE                 0x1  /* HSW+ */
  97#define OP_MI_USER_INTERRUPT                0x2
  98#define OP_MI_WAIT_FOR_EVENT                0x3
  99#define OP_MI_FLUSH                         0x4
 100#define OP_MI_ARB_CHECK                     0x5
 101#define OP_MI_RS_CONTROL                    0x6  /* HSW+ */
 102#define OP_MI_REPORT_HEAD                   0x7
 103#define OP_MI_ARB_ON_OFF                    0x8
 104#define OP_MI_URB_ATOMIC_ALLOC              0x9  /* HSW+ */
 105#define OP_MI_BATCH_BUFFER_END              0xA
 106#define OP_MI_SUSPEND_FLUSH                 0xB
 107#define OP_MI_PREDICATE                     0xC  /* IVB+ */
 108#define OP_MI_TOPOLOGY_FILTER               0xD  /* IVB+ */
 109#define OP_MI_SET_APPID                     0xE  /* IVB+ */
 110#define OP_MI_RS_CONTEXT                    0xF  /* HSW+ */
 111#define OP_MI_LOAD_SCAN_LINES_INCL          0x12 /* HSW+ */
 112#define OP_MI_DISPLAY_FLIP                  0x14
 113#define OP_MI_SEMAPHORE_MBOX                0x16
 114#define OP_MI_SET_CONTEXT                   0x18
 115#define OP_MI_MATH                          0x1A
 116#define OP_MI_URB_CLEAR                     0x19
 117#define OP_MI_SEMAPHORE_SIGNAL		    0x1B  /* BDW+ */
 118#define OP_MI_SEMAPHORE_WAIT		    0x1C  /* BDW+ */
 119
 120#define OP_MI_STORE_DATA_IMM                0x20
 121#define OP_MI_STORE_DATA_INDEX              0x21
 122#define OP_MI_LOAD_REGISTER_IMM             0x22
 123#define OP_MI_UPDATE_GTT                    0x23
 124#define OP_MI_STORE_REGISTER_MEM            0x24
 125#define OP_MI_FLUSH_DW                      0x26
 126#define OP_MI_CLFLUSH                       0x27
 127#define OP_MI_REPORT_PERF_COUNT             0x28
 128#define OP_MI_LOAD_REGISTER_MEM             0x29  /* HSW+ */
 129#define OP_MI_LOAD_REGISTER_REG             0x2A  /* HSW+ */
 130#define OP_MI_RS_STORE_DATA_IMM             0x2B  /* HSW+ */
 131#define OP_MI_LOAD_URB_MEM                  0x2C  /* HSW+ */
 132#define OP_MI_STORE_URM_MEM                 0x2D  /* HSW+ */
 133#define OP_MI_2E			    0x2E  /* BDW+ */
 134#define OP_MI_2F			    0x2F  /* BDW+ */
 135#define OP_MI_BATCH_BUFFER_START            0x31
 136
 137/* Bit definition for dword 0 */
 138#define _CMDBIT_BB_START_IN_PPGTT	(1UL << 8)
 139
 140#define OP_MI_CONDITIONAL_BATCH_BUFFER_END  0x36
 141
 142#define BATCH_BUFFER_ADDR_MASK ((1UL << 32) - (1U << 2))
 143#define BATCH_BUFFER_ADDR_HIGH_MASK ((1UL << 16) - (1U))
 144#define BATCH_BUFFER_ADR_SPACE_BIT(x)	(((x) >> 8) & 1U)
 145#define BATCH_BUFFER_2ND_LEVEL_BIT(x)   ((x) >> 22 & 1U)
 146
 147/* 2D command: Opcode (28:22) */
 148#define OP_2D(x)    ((2<<7) | x)
 149
 150#define OP_XY_SETUP_BLT                             OP_2D(0x1)
 151#define OP_XY_SETUP_CLIP_BLT                        OP_2D(0x3)
 152#define OP_XY_SETUP_MONO_PATTERN_SL_BLT             OP_2D(0x11)
 153#define OP_XY_PIXEL_BLT                             OP_2D(0x24)
 154#define OP_XY_SCANLINES_BLT                         OP_2D(0x25)
 155#define OP_XY_TEXT_BLT                              OP_2D(0x26)
 156#define OP_XY_TEXT_IMMEDIATE_BLT                    OP_2D(0x31)
 157#define OP_XY_COLOR_BLT                             OP_2D(0x50)
 158#define OP_XY_PAT_BLT                               OP_2D(0x51)
 159#define OP_XY_MONO_PAT_BLT                          OP_2D(0x52)
 160#define OP_XY_SRC_COPY_BLT                          OP_2D(0x53)
 161#define OP_XY_MONO_SRC_COPY_BLT                     OP_2D(0x54)
 162#define OP_XY_FULL_BLT                              OP_2D(0x55)
 163#define OP_XY_FULL_MONO_SRC_BLT                     OP_2D(0x56)
 164#define OP_XY_FULL_MONO_PATTERN_BLT                 OP_2D(0x57)
 165#define OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT        OP_2D(0x58)
 166#define OP_XY_MONO_PAT_FIXED_BLT                    OP_2D(0x59)
 167#define OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT           OP_2D(0x71)
 168#define OP_XY_PAT_BLT_IMMEDIATE                     OP_2D(0x72)
 169#define OP_XY_SRC_COPY_CHROMA_BLT                   OP_2D(0x73)
 170#define OP_XY_FULL_IMMEDIATE_PATTERN_BLT            OP_2D(0x74)
 171#define OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT   OP_2D(0x75)
 172#define OP_XY_PAT_CHROMA_BLT                        OP_2D(0x76)
 173#define OP_XY_PAT_CHROMA_BLT_IMMEDIATE              OP_2D(0x77)
 174
 175/* 3D/Media Command: Pipeline Type(28:27) Opcode(26:24) Sub Opcode(23:16) */
 176#define OP_3D_MEDIA(sub_type, opcode, sub_opcode) \
 177	((3 << 13) | ((sub_type) << 11) | ((opcode) << 8) | (sub_opcode))
 178
 179#define OP_STATE_PREFETCH                       OP_3D_MEDIA(0x0, 0x0, 0x03)
 180
 181#define OP_STATE_BASE_ADDRESS                   OP_3D_MEDIA(0x0, 0x1, 0x01)
 182#define OP_STATE_SIP                            OP_3D_MEDIA(0x0, 0x1, 0x02)
 183#define OP_3D_MEDIA_0_1_4			OP_3D_MEDIA(0x0, 0x1, 0x04)
 184#define OP_SWTESS_BASE_ADDRESS			OP_3D_MEDIA(0x0, 0x1, 0x03)
 185
 186#define OP_3DSTATE_VF_STATISTICS_GM45           OP_3D_MEDIA(0x1, 0x0, 0x0B)
 187
 188#define OP_PIPELINE_SELECT                      OP_3D_MEDIA(0x1, 0x1, 0x04)
 189
 190#define OP_MEDIA_VFE_STATE                      OP_3D_MEDIA(0x2, 0x0, 0x0)
 191#define OP_MEDIA_CURBE_LOAD                     OP_3D_MEDIA(0x2, 0x0, 0x1)
 192#define OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD      OP_3D_MEDIA(0x2, 0x0, 0x2)
 193#define OP_MEDIA_GATEWAY_STATE                  OP_3D_MEDIA(0x2, 0x0, 0x3)
 194#define OP_MEDIA_STATE_FLUSH                    OP_3D_MEDIA(0x2, 0x0, 0x4)
 195#define OP_MEDIA_POOL_STATE                     OP_3D_MEDIA(0x2, 0x0, 0x5)
 196
 197#define OP_MEDIA_OBJECT                         OP_3D_MEDIA(0x2, 0x1, 0x0)
 198#define OP_MEDIA_OBJECT_PRT                     OP_3D_MEDIA(0x2, 0x1, 0x2)
 199#define OP_MEDIA_OBJECT_WALKER                  OP_3D_MEDIA(0x2, 0x1, 0x3)
 200#define OP_GPGPU_WALKER                         OP_3D_MEDIA(0x2, 0x1, 0x5)
 201
 202#define OP_3DSTATE_CLEAR_PARAMS                 OP_3D_MEDIA(0x3, 0x0, 0x04) /* IVB+ */
 203#define OP_3DSTATE_DEPTH_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x05) /* IVB+ */
 204#define OP_3DSTATE_STENCIL_BUFFER               OP_3D_MEDIA(0x3, 0x0, 0x06) /* IVB+ */
 205#define OP_3DSTATE_HIER_DEPTH_BUFFER            OP_3D_MEDIA(0x3, 0x0, 0x07) /* IVB+ */
 206#define OP_3DSTATE_VERTEX_BUFFERS               OP_3D_MEDIA(0x3, 0x0, 0x08)
 207#define OP_3DSTATE_VERTEX_ELEMENTS              OP_3D_MEDIA(0x3, 0x0, 0x09)
 208#define OP_3DSTATE_INDEX_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x0A)
 209#define OP_3DSTATE_VF_STATISTICS                OP_3D_MEDIA(0x3, 0x0, 0x0B)
 210#define OP_3DSTATE_VF                           OP_3D_MEDIA(0x3, 0x0, 0x0C)  /* HSW+ */
 211#define OP_3DSTATE_CC_STATE_POINTERS            OP_3D_MEDIA(0x3, 0x0, 0x0E)
 212#define OP_3DSTATE_SCISSOR_STATE_POINTERS       OP_3D_MEDIA(0x3, 0x0, 0x0F)
 213#define OP_3DSTATE_VS                           OP_3D_MEDIA(0x3, 0x0, 0x10)
 214#define OP_3DSTATE_GS                           OP_3D_MEDIA(0x3, 0x0, 0x11)
 215#define OP_3DSTATE_CLIP                         OP_3D_MEDIA(0x3, 0x0, 0x12)
 216#define OP_3DSTATE_SF                           OP_3D_MEDIA(0x3, 0x0, 0x13)
 217#define OP_3DSTATE_WM                           OP_3D_MEDIA(0x3, 0x0, 0x14)
 218#define OP_3DSTATE_CONSTANT_VS                  OP_3D_MEDIA(0x3, 0x0, 0x15)
 219#define OP_3DSTATE_CONSTANT_GS                  OP_3D_MEDIA(0x3, 0x0, 0x16)
 220#define OP_3DSTATE_CONSTANT_PS                  OP_3D_MEDIA(0x3, 0x0, 0x17)
 221#define OP_3DSTATE_SAMPLE_MASK                  OP_3D_MEDIA(0x3, 0x0, 0x18)
 222#define OP_3DSTATE_CONSTANT_HS                  OP_3D_MEDIA(0x3, 0x0, 0x19) /* IVB+ */
 223#define OP_3DSTATE_CONSTANT_DS                  OP_3D_MEDIA(0x3, 0x0, 0x1A) /* IVB+ */
 224#define OP_3DSTATE_HS                           OP_3D_MEDIA(0x3, 0x0, 0x1B) /* IVB+ */
 225#define OP_3DSTATE_TE                           OP_3D_MEDIA(0x3, 0x0, 0x1C) /* IVB+ */
 226#define OP_3DSTATE_DS                           OP_3D_MEDIA(0x3, 0x0, 0x1D) /* IVB+ */
 227#define OP_3DSTATE_STREAMOUT                    OP_3D_MEDIA(0x3, 0x0, 0x1E) /* IVB+ */
 228#define OP_3DSTATE_SBE                          OP_3D_MEDIA(0x3, 0x0, 0x1F) /* IVB+ */
 229#define OP_3DSTATE_PS                           OP_3D_MEDIA(0x3, 0x0, 0x20) /* IVB+ */
 230#define OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP OP_3D_MEDIA(0x3, 0x0, 0x21) /* IVB+ */
 231#define OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC   OP_3D_MEDIA(0x3, 0x0, 0x23) /* IVB+ */
 232#define OP_3DSTATE_BLEND_STATE_POINTERS         OP_3D_MEDIA(0x3, 0x0, 0x24) /* IVB+ */
 233#define OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS OP_3D_MEDIA(0x3, 0x0, 0x25) /* IVB+ */
 234#define OP_3DSTATE_BINDING_TABLE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x26) /* IVB+ */
 235#define OP_3DSTATE_BINDING_TABLE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x27) /* IVB+ */
 236#define OP_3DSTATE_BINDING_TABLE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x28) /* IVB+ */
 237#define OP_3DSTATE_BINDING_TABLE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x29) /* IVB+ */
 238#define OP_3DSTATE_BINDING_TABLE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2A) /* IVB+ */
 239#define OP_3DSTATE_SAMPLER_STATE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x2B) /* IVB+ */
 240#define OP_3DSTATE_SAMPLER_STATE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x2C) /* IVB+ */
 241#define OP_3DSTATE_SAMPLER_STATE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x2D) /* IVB+ */
 242#define OP_3DSTATE_SAMPLER_STATE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x2E) /* IVB+ */
 243#define OP_3DSTATE_SAMPLER_STATE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2F) /* IVB+ */
 244#define OP_3DSTATE_URB_VS                       OP_3D_MEDIA(0x3, 0x0, 0x30) /* IVB+ */
 245#define OP_3DSTATE_URB_HS                       OP_3D_MEDIA(0x3, 0x0, 0x31) /* IVB+ */
 246#define OP_3DSTATE_URB_DS                       OP_3D_MEDIA(0x3, 0x0, 0x32) /* IVB+ */
 247#define OP_3DSTATE_URB_GS                       OP_3D_MEDIA(0x3, 0x0, 0x33) /* IVB+ */
 248#define OP_3DSTATE_GATHER_CONSTANT_VS           OP_3D_MEDIA(0x3, 0x0, 0x34) /* HSW+ */
 249#define OP_3DSTATE_GATHER_CONSTANT_GS           OP_3D_MEDIA(0x3, 0x0, 0x35) /* HSW+ */
 250#define OP_3DSTATE_GATHER_CONSTANT_HS           OP_3D_MEDIA(0x3, 0x0, 0x36) /* HSW+ */
 251#define OP_3DSTATE_GATHER_CONSTANT_DS           OP_3D_MEDIA(0x3, 0x0, 0x37) /* HSW+ */
 252#define OP_3DSTATE_GATHER_CONSTANT_PS           OP_3D_MEDIA(0x3, 0x0, 0x38) /* HSW+ */
 253#define OP_3DSTATE_DX9_CONSTANTF_VS             OP_3D_MEDIA(0x3, 0x0, 0x39) /* HSW+ */
 254#define OP_3DSTATE_DX9_CONSTANTF_PS             OP_3D_MEDIA(0x3, 0x0, 0x3A) /* HSW+ */
 255#define OP_3DSTATE_DX9_CONSTANTI_VS             OP_3D_MEDIA(0x3, 0x0, 0x3B) /* HSW+ */
 256#define OP_3DSTATE_DX9_CONSTANTI_PS             OP_3D_MEDIA(0x3, 0x0, 0x3C) /* HSW+ */
 257#define OP_3DSTATE_DX9_CONSTANTB_VS             OP_3D_MEDIA(0x3, 0x0, 0x3D) /* HSW+ */
 258#define OP_3DSTATE_DX9_CONSTANTB_PS             OP_3D_MEDIA(0x3, 0x0, 0x3E) /* HSW+ */
 259#define OP_3DSTATE_DX9_LOCAL_VALID_VS           OP_3D_MEDIA(0x3, 0x0, 0x3F) /* HSW+ */
 260#define OP_3DSTATE_DX9_LOCAL_VALID_PS           OP_3D_MEDIA(0x3, 0x0, 0x40) /* HSW+ */
 261#define OP_3DSTATE_DX9_GENERATE_ACTIVE_VS       OP_3D_MEDIA(0x3, 0x0, 0x41) /* HSW+ */
 262#define OP_3DSTATE_DX9_GENERATE_ACTIVE_PS       OP_3D_MEDIA(0x3, 0x0, 0x42) /* HSW+ */
 263#define OP_3DSTATE_BINDING_TABLE_EDIT_VS        OP_3D_MEDIA(0x3, 0x0, 0x43) /* HSW+ */
 264#define OP_3DSTATE_BINDING_TABLE_EDIT_GS        OP_3D_MEDIA(0x3, 0x0, 0x44) /* HSW+ */
 265#define OP_3DSTATE_BINDING_TABLE_EDIT_HS        OP_3D_MEDIA(0x3, 0x0, 0x45) /* HSW+ */
 266#define OP_3DSTATE_BINDING_TABLE_EDIT_DS        OP_3D_MEDIA(0x3, 0x0, 0x46) /* HSW+ */
 267#define OP_3DSTATE_BINDING_TABLE_EDIT_PS        OP_3D_MEDIA(0x3, 0x0, 0x47) /* HSW+ */
 268
 269#define OP_3DSTATE_VF_INSTANCING 		OP_3D_MEDIA(0x3, 0x0, 0x49) /* BDW+ */
 270#define OP_3DSTATE_VF_SGVS  			OP_3D_MEDIA(0x3, 0x0, 0x4A) /* BDW+ */
 271#define OP_3DSTATE_VF_TOPOLOGY   		OP_3D_MEDIA(0x3, 0x0, 0x4B) /* BDW+ */
 272#define OP_3DSTATE_WM_CHROMAKEY   		OP_3D_MEDIA(0x3, 0x0, 0x4C) /* BDW+ */
 273#define OP_3DSTATE_PS_BLEND   			OP_3D_MEDIA(0x3, 0x0, 0x4D) /* BDW+ */
 274#define OP_3DSTATE_WM_DEPTH_STENCIL   		OP_3D_MEDIA(0x3, 0x0, 0x4E) /* BDW+ */
 275#define OP_3DSTATE_PS_EXTRA   			OP_3D_MEDIA(0x3, 0x0, 0x4F) /* BDW+ */
 276#define OP_3DSTATE_RASTER   			OP_3D_MEDIA(0x3, 0x0, 0x50) /* BDW+ */
 277#define OP_3DSTATE_SBE_SWIZ   			OP_3D_MEDIA(0x3, 0x0, 0x51) /* BDW+ */
 278#define OP_3DSTATE_WM_HZ_OP   			OP_3D_MEDIA(0x3, 0x0, 0x52) /* BDW+ */
 279#define OP_3DSTATE_COMPONENT_PACKING		OP_3D_MEDIA(0x3, 0x0, 0x55) /* SKL+ */
 280
 281#define OP_3DSTATE_DRAWING_RECTANGLE            OP_3D_MEDIA(0x3, 0x1, 0x00)
 282#define OP_3DSTATE_SAMPLER_PALETTE_LOAD0        OP_3D_MEDIA(0x3, 0x1, 0x02)
 283#define OP_3DSTATE_CHROMA_KEY                   OP_3D_MEDIA(0x3, 0x1, 0x04)
 284#define OP_SNB_3DSTATE_DEPTH_BUFFER             OP_3D_MEDIA(0x3, 0x1, 0x05)
 285#define OP_3DSTATE_POLY_STIPPLE_OFFSET          OP_3D_MEDIA(0x3, 0x1, 0x06)
 286#define OP_3DSTATE_POLY_STIPPLE_PATTERN         OP_3D_MEDIA(0x3, 0x1, 0x07)
 287#define OP_3DSTATE_LINE_STIPPLE                 OP_3D_MEDIA(0x3, 0x1, 0x08)
 288#define OP_3DSTATE_AA_LINE_PARAMS               OP_3D_MEDIA(0x3, 0x1, 0x0A)
 289#define OP_3DSTATE_GS_SVB_INDEX                 OP_3D_MEDIA(0x3, 0x1, 0x0B)
 290#define OP_3DSTATE_SAMPLER_PALETTE_LOAD1        OP_3D_MEDIA(0x3, 0x1, 0x0C)
 291#define OP_3DSTATE_MULTISAMPLE_BDW		OP_3D_MEDIA(0x3, 0x0, 0x0D)
 292#define OP_SNB_3DSTATE_STENCIL_BUFFER           OP_3D_MEDIA(0x3, 0x1, 0x0E)
 293#define OP_SNB_3DSTATE_HIER_DEPTH_BUFFER        OP_3D_MEDIA(0x3, 0x1, 0x0F)
 294#define OP_SNB_3DSTATE_CLEAR_PARAMS             OP_3D_MEDIA(0x3, 0x1, 0x10)
 295#define OP_3DSTATE_MONOFILTER_SIZE              OP_3D_MEDIA(0x3, 0x1, 0x11)
 296#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS       OP_3D_MEDIA(0x3, 0x1, 0x12) /* IVB+ */
 297#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS       OP_3D_MEDIA(0x3, 0x1, 0x13) /* IVB+ */
 298#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS       OP_3D_MEDIA(0x3, 0x1, 0x14) /* IVB+ */
 299#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS       OP_3D_MEDIA(0x3, 0x1, 0x15) /* IVB+ */
 300#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS       OP_3D_MEDIA(0x3, 0x1, 0x16) /* IVB+ */
 301#define OP_3DSTATE_SO_DECL_LIST                 OP_3D_MEDIA(0x3, 0x1, 0x17)
 302#define OP_3DSTATE_SO_BUFFER                    OP_3D_MEDIA(0x3, 0x1, 0x18)
 303#define OP_3DSTATE_BINDING_TABLE_POOL_ALLOC     OP_3D_MEDIA(0x3, 0x1, 0x19) /* HSW+ */
 304#define OP_3DSTATE_GATHER_POOL_ALLOC            OP_3D_MEDIA(0x3, 0x1, 0x1A) /* HSW+ */
 305#define OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC OP_3D_MEDIA(0x3, 0x1, 0x1B) /* HSW+ */
 306#define OP_3DSTATE_SAMPLE_PATTERN               OP_3D_MEDIA(0x3, 0x1, 0x1C)
 307#define OP_PIPE_CONTROL                         OP_3D_MEDIA(0x3, 0x2, 0x00)
 308#define OP_3DPRIMITIVE                          OP_3D_MEDIA(0x3, 0x3, 0x00)
 309
 310/* VCCP Command Parser */
 311
 312/*
 313 * Below MFX and VBE cmd definition is from vaapi intel driver project (BSD License)
 314 * git://anongit.freedesktop.org/vaapi/intel-driver
 315 * src/i965_defines.h
 316 *
 317 */
 318
 319#define OP_MFX(pipeline, op, sub_opa, sub_opb)     \
 320	(3 << 13 | \
 321	 (pipeline) << 11 | \
 322	 (op) << 8 | \
 323	 (sub_opa) << 5 | \
 324	 (sub_opb))
 325
 326#define OP_MFX_PIPE_MODE_SELECT                    OP_MFX(2, 0, 0, 0)  /* ALL */
 327#define OP_MFX_SURFACE_STATE                       OP_MFX(2, 0, 0, 1)  /* ALL */
 328#define OP_MFX_PIPE_BUF_ADDR_STATE                 OP_MFX(2, 0, 0, 2)  /* ALL */
 329#define OP_MFX_IND_OBJ_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 3)  /* ALL */
 330#define OP_MFX_BSP_BUF_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 4)  /* ALL */
 331#define OP_2_0_0_5                                 OP_MFX(2, 0, 0, 5)  /* ALL */
 332#define OP_MFX_STATE_POINTER                       OP_MFX(2, 0, 0, 6)  /* ALL */
 333#define OP_MFX_QM_STATE                            OP_MFX(2, 0, 0, 7)  /* IVB+ */
 334#define OP_MFX_FQM_STATE                           OP_MFX(2, 0, 0, 8)  /* IVB+ */
 335#define OP_MFX_PAK_INSERT_OBJECT                   OP_MFX(2, 0, 2, 8)  /* IVB+ */
 336#define OP_MFX_STITCH_OBJECT                       OP_MFX(2, 0, 2, 0xA)  /* IVB+ */
 337
 338#define OP_MFD_IT_OBJECT                           OP_MFX(2, 0, 1, 9) /* ALL */
 339
 340#define OP_MFX_WAIT                                OP_MFX(1, 0, 0, 0) /* IVB+ */
 341#define OP_MFX_AVC_IMG_STATE                       OP_MFX(2, 1, 0, 0) /* ALL */
 342#define OP_MFX_AVC_QM_STATE                        OP_MFX(2, 1, 0, 1) /* ALL */
 343#define OP_MFX_AVC_DIRECTMODE_STATE                OP_MFX(2, 1, 0, 2) /* ALL */
 344#define OP_MFX_AVC_SLICE_STATE                     OP_MFX(2, 1, 0, 3) /* ALL */
 345#define OP_MFX_AVC_REF_IDX_STATE                   OP_MFX(2, 1, 0, 4) /* ALL */
 346#define OP_MFX_AVC_WEIGHTOFFSET_STATE              OP_MFX(2, 1, 0, 5) /* ALL */
 347#define OP_MFD_AVC_PICID_STATE                     OP_MFX(2, 1, 1, 5) /* HSW+ */
 348#define OP_MFD_AVC_DPB_STATE			   OP_MFX(2, 1, 1, 6) /* IVB+ */
 349#define OP_MFD_AVC_SLICEADDR                       OP_MFX(2, 1, 1, 7) /* IVB+ */
 350#define OP_MFD_AVC_BSD_OBJECT                      OP_MFX(2, 1, 1, 8) /* ALL */
 351#define OP_MFC_AVC_PAK_OBJECT                      OP_MFX(2, 1, 2, 9) /* ALL */
 352
 353#define OP_MFX_VC1_PRED_PIPE_STATE                 OP_MFX(2, 2, 0, 1) /* ALL */
 354#define OP_MFX_VC1_DIRECTMODE_STATE                OP_MFX(2, 2, 0, 2) /* ALL */
 355#define OP_MFD_VC1_SHORT_PIC_STATE                 OP_MFX(2, 2, 1, 0) /* IVB+ */
 356#define OP_MFD_VC1_LONG_PIC_STATE                  OP_MFX(2, 2, 1, 1) /* IVB+ */
 357#define OP_MFD_VC1_BSD_OBJECT                      OP_MFX(2, 2, 1, 8) /* ALL */
 358
 359#define OP_MFX_MPEG2_PIC_STATE                     OP_MFX(2, 3, 0, 0) /* ALL */
 360#define OP_MFX_MPEG2_QM_STATE                      OP_MFX(2, 3, 0, 1) /* ALL */
 361#define OP_MFD_MPEG2_BSD_OBJECT                    OP_MFX(2, 3, 1, 8) /* ALL */
 362#define OP_MFC_MPEG2_SLICEGROUP_STATE              OP_MFX(2, 3, 2, 3) /* ALL */
 363#define OP_MFC_MPEG2_PAK_OBJECT                    OP_MFX(2, 3, 2, 9) /* ALL */
 364
 365#define OP_MFX_2_6_0_0                             OP_MFX(2, 6, 0, 0) /* IVB+ */
 366#define OP_MFX_2_6_0_8                             OP_MFX(2, 6, 0, 8) /* IVB+ */
 367#define OP_MFX_2_6_0_9                             OP_MFX(2, 6, 0, 9) /* IVB+ */
 368
 369#define OP_MFX_JPEG_PIC_STATE                      OP_MFX(2, 7, 0, 0)
 370#define OP_MFX_JPEG_HUFF_TABLE_STATE               OP_MFX(2, 7, 0, 2)
 371#define OP_MFD_JPEG_BSD_OBJECT                     OP_MFX(2, 7, 1, 8)
 372
 373#define OP_VEB(pipeline, op, sub_opa, sub_opb) \
 374	(3 << 13 | \
 375	 (pipeline) << 11 | \
 376	 (op) << 8 | \
 377	 (sub_opa) << 5 | \
 378	 (sub_opb))
 379
 380#define OP_VEB_SURFACE_STATE                       OP_VEB(2, 4, 0, 0)
 381#define OP_VEB_STATE                               OP_VEB(2, 4, 0, 2)
 382#define OP_VEB_DNDI_IECP_STATE                     OP_VEB(2, 4, 0, 3)
 383
 384struct parser_exec_state;
 385
 386typedef int (*parser_cmd_handler)(struct parser_exec_state *s);
 387
 388#define GVT_CMD_HASH_BITS   7
 389
 390/* which DWords need address fix */
 391#define ADDR_FIX_1(x1)			(1 << (x1))
 392#define ADDR_FIX_2(x1, x2)		(ADDR_FIX_1(x1) | ADDR_FIX_1(x2))
 393#define ADDR_FIX_3(x1, x2, x3)		(ADDR_FIX_1(x1) | ADDR_FIX_2(x2, x3))
 394#define ADDR_FIX_4(x1, x2, x3, x4)	(ADDR_FIX_1(x1) | ADDR_FIX_3(x2, x3, x4))
 395#define ADDR_FIX_5(x1, x2, x3, x4, x5)  (ADDR_FIX_1(x1) | ADDR_FIX_4(x2, x3, x4, x5))
 396
 397#define DWORD_FIELD(dword, end, start) \
 398	FIELD_GET(GENMASK(end, start), cmd_val(s, dword))
 399
 400#define OP_LENGTH_BIAS 2
 401#define CMD_LEN(value)  (value + OP_LENGTH_BIAS)
 402
 403static int gvt_check_valid_cmd_length(int len, int valid_len)
 404{
 405	if (valid_len != len) {
 406		gvt_err("len is not valid:  len=%u  valid_len=%u\n",
 407			len, valid_len);
 408		return -EFAULT;
 409	}
 410	return 0;
 411}
 412
 413struct cmd_info {
 414	const char *name;
 415	u32 opcode;
 416
 417#define F_LEN_MASK	3U
 418#define F_LEN_CONST  1U
 419#define F_LEN_VAR    0U
 420/* value is const although LEN maybe variable */
 421#define F_LEN_VAR_FIXED    (1<<1)
 422
 423/*
 424 * command has its own ip advance logic
 425 * e.g. MI_BATCH_START, MI_BATCH_END
 426 */
 427#define F_IP_ADVANCE_CUSTOM (1<<2)
 428	u32 flag;
 429
 430#define R_RCS	BIT(RCS0)
 431#define R_VCS1  BIT(VCS0)
 432#define R_VCS2  BIT(VCS1)
 433#define R_VCS	(R_VCS1 | R_VCS2)
 434#define R_BCS	BIT(BCS0)
 435#define R_VECS	BIT(VECS0)
 436#define R_ALL (R_RCS | R_VCS | R_BCS | R_VECS)
 437	/* rings that support this cmd: BLT/RCS/VCS/VECS */
 438	intel_engine_mask_t rings;
 439
 440	/* devices that support this cmd: SNB/IVB/HSW/... */
 441	u16 devices;
 442
 443	/* which DWords are address that need fix up.
 444	 * bit 0 means a 32-bit non address operand in command
 445	 * bit 1 means address operand, which could be 32-bit
 446	 * or 64-bit depending on different architectures.(
 447	 * defined by "gmadr_bytes_in_cmd" in intel_gvt.
 448	 * No matter the address length, each address only takes
 449	 * one bit in the bitmap.
 450	 */
 451	u16 addr_bitmap;
 452
 453	/* flag == F_LEN_CONST : command length
 454	 * flag == F_LEN_VAR : length bias bits
 455	 * Note: length is in DWord
 456	 */
 457	u32 len;
 458
 459	parser_cmd_handler handler;
 460
 461	/* valid length in DWord */
 462	u32 valid_len;
 463};
 464
 465struct cmd_entry {
 466	struct hlist_node hlist;
 467	const struct cmd_info *info;
 468};
 469
 470enum {
 471	RING_BUFFER_INSTRUCTION,
 472	BATCH_BUFFER_INSTRUCTION,
 473	BATCH_BUFFER_2ND_LEVEL,
 474	RING_BUFFER_CTX,
 475};
 476
 477enum {
 478	GTT_BUFFER,
 479	PPGTT_BUFFER
 480};
 481
 482struct parser_exec_state {
 483	struct intel_vgpu *vgpu;
 484	const struct intel_engine_cs *engine;
 485
 486	int buf_type;
 487
 488	/* batch buffer address type */
 489	int buf_addr_type;
 490
 491	/* graphics memory address of ring buffer start */
 492	unsigned long ring_start;
 493	unsigned long ring_size;
 494	unsigned long ring_head;
 495	unsigned long ring_tail;
 496
 497	/* instruction graphics memory address */
 498	unsigned long ip_gma;
 499
 500	/* mapped va of the instr_gma */
 501	void *ip_va;
 502	void *rb_va;
 503
 504	void *ret_bb_va;
 505	/* next instruction when return from  batch buffer to ring buffer */
 506	unsigned long ret_ip_gma_ring;
 507
 508	/* next instruction when return from 2nd batch buffer to batch buffer */
 509	unsigned long ret_ip_gma_bb;
 510
 511	/* batch buffer address type (GTT or PPGTT)
 512	 * used when ret from 2nd level batch buffer
 513	 */
 514	int saved_buf_addr_type;
 515	bool is_ctx_wa;
 516	bool is_init_ctx;
 517
 518	const struct cmd_info *info;
 519
 520	struct intel_vgpu_workload *workload;
 521};
 522
 523#define gmadr_dw_number(s)	\
 524	(s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
 525
 526static unsigned long bypass_scan_mask = 0;
 527
 528/* ring ALL, type = 0 */
 529static const struct sub_op_bits sub_op_mi[] = {
 530	{31, 29},
 531	{28, 23},
 532};
 533
 534static const struct decode_info decode_info_mi = {
 535	"MI",
 536	OP_LEN_MI,
 537	ARRAY_SIZE(sub_op_mi),
 538	sub_op_mi,
 539};
 540
 541/* ring RCS, command type 2 */
 542static const struct sub_op_bits sub_op_2d[] = {
 543	{31, 29},
 544	{28, 22},
 545};
 546
 547static const struct decode_info decode_info_2d = {
 548	"2D",
 549	OP_LEN_2D,
 550	ARRAY_SIZE(sub_op_2d),
 551	sub_op_2d,
 552};
 553
 554/* ring RCS, command type 3 */
 555static const struct sub_op_bits sub_op_3d_media[] = {
 556	{31, 29},
 557	{28, 27},
 558	{26, 24},
 559	{23, 16},
 560};
 561
 562static const struct decode_info decode_info_3d_media = {
 563	"3D_Media",
 564	OP_LEN_3D_MEDIA,
 565	ARRAY_SIZE(sub_op_3d_media),
 566	sub_op_3d_media,
 567};
 568
 569/* ring VCS, command type 3 */
 570static const struct sub_op_bits sub_op_mfx_vc[] = {
 571	{31, 29},
 572	{28, 27},
 573	{26, 24},
 574	{23, 21},
 575	{20, 16},
 576};
 577
 578static const struct decode_info decode_info_mfx_vc = {
 579	"MFX_VC",
 580	OP_LEN_MFX_VC,
 581	ARRAY_SIZE(sub_op_mfx_vc),
 582	sub_op_mfx_vc,
 583};
 584
 585/* ring VECS, command type 3 */
 586static const struct sub_op_bits sub_op_vebox[] = {
 587	{31, 29},
 588	{28, 27},
 589	{26, 24},
 590	{23, 21},
 591	{20, 16},
 592};
 593
 594static const struct decode_info decode_info_vebox = {
 595	"VEBOX",
 596	OP_LEN_VEBOX,
 597	ARRAY_SIZE(sub_op_vebox),
 598	sub_op_vebox,
 599};
 600
 601static const struct decode_info *ring_decode_info[I915_NUM_ENGINES][8] = {
 602	[RCS0] = {
 603		&decode_info_mi,
 604		NULL,
 605		NULL,
 606		&decode_info_3d_media,
 607		NULL,
 608		NULL,
 609		NULL,
 610		NULL,
 611	},
 612
 613	[VCS0] = {
 614		&decode_info_mi,
 615		NULL,
 616		NULL,
 617		&decode_info_mfx_vc,
 618		NULL,
 619		NULL,
 620		NULL,
 621		NULL,
 622	},
 623
 624	[BCS0] = {
 625		&decode_info_mi,
 626		NULL,
 627		&decode_info_2d,
 628		NULL,
 629		NULL,
 630		NULL,
 631		NULL,
 632		NULL,
 633	},
 634
 635	[VECS0] = {
 636		&decode_info_mi,
 637		NULL,
 638		NULL,
 639		&decode_info_vebox,
 640		NULL,
 641		NULL,
 642		NULL,
 643		NULL,
 644	},
 645
 646	[VCS1] = {
 647		&decode_info_mi,
 648		NULL,
 649		NULL,
 650		&decode_info_mfx_vc,
 651		NULL,
 652		NULL,
 653		NULL,
 654		NULL,
 655	},
 656};
 657
 658static inline u32 get_opcode(u32 cmd, const struct intel_engine_cs *engine)
 659{
 660	const struct decode_info *d_info;
 661
 662	d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
 663	if (d_info == NULL)
 664		return INVALID_OP;
 665
 666	return cmd >> (32 - d_info->op_len);
 667}
 668
 669static inline const struct cmd_info *
 670find_cmd_entry(struct intel_gvt *gvt, unsigned int opcode,
 671	       const struct intel_engine_cs *engine)
 672{
 673	struct cmd_entry *e;
 674
 675	hash_for_each_possible(gvt->cmd_table, e, hlist, opcode) {
 676		if (opcode == e->info->opcode &&
 677		    e->info->rings & engine->mask)
 678			return e->info;
 679	}
 680	return NULL;
 681}
 682
 683static inline const struct cmd_info *
 684get_cmd_info(struct intel_gvt *gvt, u32 cmd,
 685	     const struct intel_engine_cs *engine)
 686{
 687	u32 opcode;
 688
 689	opcode = get_opcode(cmd, engine);
 690	if (opcode == INVALID_OP)
 691		return NULL;
 692
 693	return find_cmd_entry(gvt, opcode, engine);
 694}
 695
 696static inline u32 sub_op_val(u32 cmd, u32 hi, u32 low)
 697{
 698	return (cmd >> low) & ((1U << (hi - low + 1)) - 1);
 699}
 700
 701static inline void print_opcode(u32 cmd, const struct intel_engine_cs *engine)
 702{
 703	const struct decode_info *d_info;
 704	int i;
 705
 706	d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
 707	if (d_info == NULL)
 708		return;
 709
 710	gvt_dbg_cmd("opcode=0x%x %s sub_ops:",
 711			cmd >> (32 - d_info->op_len), d_info->name);
 712
 713	for (i = 0; i < d_info->nr_sub_op; i++)
 714		pr_err("0x%x ", sub_op_val(cmd, d_info->sub_op[i].hi,
 715					d_info->sub_op[i].low));
 716
 717	pr_err("\n");
 718}
 719
 720static inline u32 *cmd_ptr(struct parser_exec_state *s, int index)
 721{
 722	return s->ip_va + (index << 2);
 723}
 724
 725static inline u32 cmd_val(struct parser_exec_state *s, int index)
 726{
 727	return *cmd_ptr(s, index);
 728}
 729
 730static inline bool is_init_ctx(struct parser_exec_state *s)
 731{
 732	return (s->buf_type == RING_BUFFER_CTX && s->is_init_ctx);
 733}
 734
 735static void parser_exec_state_dump(struct parser_exec_state *s)
 736{
 737	int cnt = 0;
 738	int i;
 739
 740	gvt_dbg_cmd("  vgpu%d RING%s: ring_start(%08lx) ring_end(%08lx)"
 741		    " ring_head(%08lx) ring_tail(%08lx)\n",
 742		    s->vgpu->id, s->engine->name,
 743		    s->ring_start, s->ring_start + s->ring_size,
 744		    s->ring_head, s->ring_tail);
 745
 746	gvt_dbg_cmd("  %s %s ip_gma(%08lx) ",
 747			s->buf_type == RING_BUFFER_INSTRUCTION ?
 748			"RING_BUFFER" : ((s->buf_type == RING_BUFFER_CTX) ?
 749				"CTX_BUFFER" : "BATCH_BUFFER"),
 750			s->buf_addr_type == GTT_BUFFER ?
 751			"GTT" : "PPGTT", s->ip_gma);
 752
 753	if (s->ip_va == NULL) {
 754		gvt_dbg_cmd(" ip_va(NULL)");
 755		return;
 756	}
 757
 758	gvt_dbg_cmd("  ip_va=%p: %08x %08x %08x %08x\n",
 759			s->ip_va, cmd_val(s, 0), cmd_val(s, 1),
 760			cmd_val(s, 2), cmd_val(s, 3));
 761
 762	print_opcode(cmd_val(s, 0), s->engine);
 763
 764	s->ip_va = (u32 *)((((u64)s->ip_va) >> 12) << 12);
 765
 766	while (cnt < 1024) {
 767		gvt_dbg_cmd("ip_va=%p: ", s->ip_va);
 768		for (i = 0; i < 8; i++)
 769			gvt_dbg_cmd("%08x ", cmd_val(s, i));
 770		gvt_dbg_cmd("\n");
 771
 772		s->ip_va += 8 * sizeof(u32);
 773		cnt += 8;
 774	}
 775}
 776
 777static inline void update_ip_va(struct parser_exec_state *s)
 778{
 779	unsigned long len = 0;
 780
 781	if (WARN_ON(s->ring_head == s->ring_tail))
 782		return;
 783
 784	if (s->buf_type == RING_BUFFER_INSTRUCTION ||
 785			s->buf_type == RING_BUFFER_CTX) {
 786		unsigned long ring_top = s->ring_start + s->ring_size;
 787
 788		if (s->ring_head > s->ring_tail) {
 789			if (s->ip_gma >= s->ring_head && s->ip_gma < ring_top)
 790				len = (s->ip_gma - s->ring_head);
 791			else if (s->ip_gma >= s->ring_start &&
 792					s->ip_gma <= s->ring_tail)
 793				len = (ring_top - s->ring_head) +
 794					(s->ip_gma - s->ring_start);
 795		} else
 796			len = (s->ip_gma - s->ring_head);
 797
 798		s->ip_va = s->rb_va + len;
 799	} else {/* shadow batch buffer */
 800		s->ip_va = s->ret_bb_va;
 801	}
 802}
 803
 804static inline int ip_gma_set(struct parser_exec_state *s,
 805		unsigned long ip_gma)
 806{
 807	WARN_ON(!IS_ALIGNED(ip_gma, 4));
 808
 809	s->ip_gma = ip_gma;
 810	update_ip_va(s);
 811	return 0;
 812}
 813
 814static inline int ip_gma_advance(struct parser_exec_state *s,
 815		unsigned int dw_len)
 816{
 817	s->ip_gma += (dw_len << 2);
 818
 819	if (s->buf_type == RING_BUFFER_INSTRUCTION) {
 820		if (s->ip_gma >= s->ring_start + s->ring_size)
 821			s->ip_gma -= s->ring_size;
 822		update_ip_va(s);
 823	} else {
 824		s->ip_va += (dw_len << 2);
 825	}
 826
 827	return 0;
 828}
 829
 830static inline int get_cmd_length(const struct cmd_info *info, u32 cmd)
 831{
 832	if ((info->flag & F_LEN_MASK) == F_LEN_CONST)
 833		return info->len;
 834	else
 835		return (cmd & ((1U << info->len) - 1)) + 2;
 836	return 0;
 837}
 838
 839static inline int cmd_length(struct parser_exec_state *s)
 840{
 841	return get_cmd_length(s->info, cmd_val(s, 0));
 842}
 843
 844/* do not remove this, some platform may need clflush here */
 845#define patch_value(s, addr, val) do { \
 846	*addr = val; \
 847} while (0)
 848
 849static inline bool is_mocs_mmio(unsigned int offset)
 850{
 851	return ((offset >= 0xc800) && (offset <= 0xcff8)) ||
 852		((offset >= 0xb020) && (offset <= 0xb0a0));
 853}
 854
 855static int is_cmd_update_pdps(unsigned int offset,
 856			      struct parser_exec_state *s)
 857{
 858	u32 base = s->workload->engine->mmio_base;
 859	return i915_mmio_reg_equal(_MMIO(offset), GEN8_RING_PDP_UDW(base, 0));
 860}
 861
 862static int cmd_pdp_mmio_update_handler(struct parser_exec_state *s,
 863				       unsigned int offset, unsigned int index)
 864{
 865	struct intel_vgpu *vgpu = s->vgpu;
 866	struct intel_vgpu_mm *shadow_mm = s->workload->shadow_mm;
 867	struct intel_vgpu_mm *mm;
 868	u64 pdps[GEN8_3LVL_PDPES];
 869
 870	if (shadow_mm->ppgtt_mm.root_entry_type ==
 871	    GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
 872		pdps[0] = (u64)cmd_val(s, 2) << 32;
 873		pdps[0] |= cmd_val(s, 4);
 874
 875		mm = intel_vgpu_find_ppgtt_mm(vgpu, pdps);
 876		if (!mm) {
 877			gvt_vgpu_err("failed to get the 4-level shadow vm\n");
 878			return -EINVAL;
 879		}
 880		intel_vgpu_mm_get(mm);
 881		list_add_tail(&mm->ppgtt_mm.link,
 882			      &s->workload->lri_shadow_mm);
 883		*cmd_ptr(s, 2) = upper_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
 884		*cmd_ptr(s, 4) = lower_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
 885	} else {
 886		/* Currently all guests use PML4 table and now can't
 887		 * have a guest with 3-level table but uses LRI for
 888		 * PPGTT update. So this is simply un-testable. */
 889		GEM_BUG_ON(1);
 890		gvt_vgpu_err("invalid shared shadow vm type\n");
 891		return -EINVAL;
 892	}
 893	return 0;
 894}
 895
 896static int cmd_reg_handler(struct parser_exec_state *s,
 897	unsigned int offset, unsigned int index, char *cmd)
 898{
 899	struct intel_vgpu *vgpu = s->vgpu;
 900	struct intel_gvt *gvt = vgpu->gvt;
 901	u32 ctx_sr_ctl;
 902	u32 *vreg, vreg_old;
 903
 904	if (offset + 4 > gvt->device_info.mmio_size) {
 905		gvt_vgpu_err("%s access to (%x) outside of MMIO range\n",
 906				cmd, offset);
 907		return -EFAULT;
 908	}
 909
 910	if (is_init_ctx(s)) {
 911		struct intel_gvt_mmio_info *mmio_info;
 912
 913		intel_gvt_mmio_set_cmd_accessible(gvt, offset);
 914		mmio_info = intel_gvt_find_mmio_info(gvt, offset);
 915		if (mmio_info && mmio_info->write)
 916			intel_gvt_mmio_set_cmd_write_patch(gvt, offset);
 917		return 0;
 918	}
 919
 920	if (!intel_gvt_mmio_is_cmd_accessible(gvt, offset)) {
 921		gvt_vgpu_err("%s access to non-render register (%x)\n",
 922				cmd, offset);
 923		return -EBADRQC;
 924	}
 925
 926	if (!strncmp(cmd, "srm", 3) ||
 927			!strncmp(cmd, "lrm", 3)) {
 928		if (offset == i915_mmio_reg_offset(GEN8_L3SQCREG4) ||
 929		    offset == 0x21f0 ||
 930		    (IS_BROADWELL(gvt->gt->i915) &&
 931		     offset == i915_mmio_reg_offset(INSTPM)))
 932			return 0;
 933		else {
 934			gvt_vgpu_err("%s access to register (%x)\n",
 935					cmd, offset);
 936			return -EPERM;
 937		}
 938	}
 939
 940	if (!strncmp(cmd, "lrr-src", 7) ||
 941			!strncmp(cmd, "lrr-dst", 7)) {
 942		if (IS_BROADWELL(gvt->gt->i915) && offset == 0x215c)
 943			return 0;
 944		else {
 945			gvt_vgpu_err("not allowed cmd %s reg (%x)\n", cmd, offset);
 946			return -EPERM;
 947		}
 948	}
 949
 950	if (!strncmp(cmd, "pipe_ctrl", 9)) {
 951		/* TODO: add LRI POST logic here */
 952		return 0;
 953	}
 954
 955	if (strncmp(cmd, "lri", 3))
 956		return -EPERM;
 957
 958	/* below are all lri handlers */
 959	vreg = &vgpu_vreg(s->vgpu, offset);
 960
 961	if (is_cmd_update_pdps(offset, s) &&
 962	    cmd_pdp_mmio_update_handler(s, offset, index))
 963		return -EINVAL;
 964
 965	if (offset == i915_mmio_reg_offset(DERRMR) ||
 966		offset == i915_mmio_reg_offset(FORCEWAKE_MT)) {
 967		/* Writing to HW VGT_PVINFO_PAGE offset will be discarded */
 968		patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE);
 969	}
 970
 971	if (is_mocs_mmio(offset))
 972		*vreg = cmd_val(s, index + 1);
 973
 974	vreg_old = *vreg;
 975
 976	if (intel_gvt_mmio_is_cmd_write_patch(gvt, offset)) {
 977		u32 cmdval_new, cmdval;
 978		struct intel_gvt_mmio_info *mmio_info;
 979
 980		cmdval = cmd_val(s, index + 1);
 981
 982		mmio_info = intel_gvt_find_mmio_info(gvt, offset);
 983		if (!mmio_info) {
 984			cmdval_new = cmdval;
 985		} else {
 986			u64 ro_mask = mmio_info->ro_mask;
 987			int ret;
 988
 989			if (likely(!ro_mask))
 990				ret = mmio_info->write(s->vgpu, offset,
 991						&cmdval, 4);
 992			else {
 993				gvt_vgpu_err("try to write RO reg %x\n",
 994						offset);
 995				ret = -EBADRQC;
 996			}
 997			if (ret)
 998				return ret;
 999			cmdval_new = *vreg;
1000		}
1001		if (cmdval_new != cmdval)
1002			patch_value(s, cmd_ptr(s, index+1), cmdval_new);
1003	}
1004
1005	/* only patch cmd. restore vreg value if changed in mmio write handler*/
1006	*vreg = vreg_old;
1007
1008	/* TODO
1009	 * In order to let workload with inhibit context to generate
1010	 * correct image data into memory, vregs values will be loaded to
1011	 * hw via LRIs in the workload with inhibit context. But as
1012	 * indirect context is loaded prior to LRIs in workload, we don't
1013	 * want reg values specified in indirect context overwritten by
1014	 * LRIs in workloads. So, when scanning an indirect context, we
1015	 * update reg values in it into vregs, so LRIs in workload with
1016	 * inhibit context will restore with correct values
1017	 */
1018	if (GRAPHICS_VER(s->engine->i915) == 9 &&
1019	    intel_gvt_mmio_is_sr_in_ctx(gvt, offset) &&
1020	    !strncmp(cmd, "lri", 3)) {
1021		intel_gvt_read_gpa(s->vgpu,
1022			s->workload->ring_context_gpa + 12, &ctx_sr_ctl, 4);
1023		/* check inhibit context */
1024		if (ctx_sr_ctl & 1) {
1025			u32 data = cmd_val(s, index + 1);
1026
1027			if (intel_gvt_mmio_has_mode_mask(s->vgpu->gvt, offset))
1028				intel_vgpu_mask_mmio_write(vgpu,
1029							offset, &data, 4);
1030			else
1031				vgpu_vreg(vgpu, offset) = data;
1032		}
1033	}
1034
1035	return 0;
1036}
1037
1038#define cmd_reg(s, i) \
1039	(cmd_val(s, i) & GENMASK(22, 2))
1040
1041#define cmd_reg_inhibit(s, i) \
1042	(cmd_val(s, i) & GENMASK(22, 18))
1043
1044#define cmd_gma(s, i) \
1045	(cmd_val(s, i) & GENMASK(31, 2))
1046
1047#define cmd_gma_hi(s, i) \
1048	(cmd_val(s, i) & GENMASK(15, 0))
1049
1050static int cmd_handler_lri(struct parser_exec_state *s)
1051{
1052	int i, ret = 0;
1053	int cmd_len = cmd_length(s);
1054
1055	for (i = 1; i < cmd_len; i += 2) {
1056		if (IS_BROADWELL(s->engine->i915) && s->engine->id != RCS0) {
1057			if (s->engine->id == BCS0 &&
1058			    cmd_reg(s, i) == i915_mmio_reg_offset(DERRMR))
1059				ret |= 0;
1060			else
1061				ret |= cmd_reg_inhibit(s, i) ? -EBADRQC : 0;
1062		}
1063		if (ret)
1064			break;
1065		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lri");
1066		if (ret)
1067			break;
1068	}
1069	return ret;
1070}
1071
1072static int cmd_handler_lrr(struct parser_exec_state *s)
1073{
1074	int i, ret = 0;
1075	int cmd_len = cmd_length(s);
1076
1077	for (i = 1; i < cmd_len; i += 2) {
1078		if (IS_BROADWELL(s->engine->i915))
1079			ret |= ((cmd_reg_inhibit(s, i) ||
1080				 (cmd_reg_inhibit(s, i + 1)))) ?
1081				-EBADRQC : 0;
1082		if (ret)
1083			break;
1084		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrr-src");
1085		if (ret)
1086			break;
1087		ret |= cmd_reg_handler(s, cmd_reg(s, i + 1), i, "lrr-dst");
1088		if (ret)
1089			break;
1090	}
1091	return ret;
1092}
1093
1094static inline int cmd_address_audit(struct parser_exec_state *s,
1095		unsigned long guest_gma, int op_size, bool index_mode);
1096
1097static int cmd_handler_lrm(struct parser_exec_state *s)
1098{
1099	struct intel_gvt *gvt = s->vgpu->gvt;
1100	int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd;
1101	unsigned long gma;
1102	int i, ret = 0;
1103	int cmd_len = cmd_length(s);
1104
1105	for (i = 1; i < cmd_len;) {
1106		if (IS_BROADWELL(s->engine->i915))
1107			ret |= (cmd_reg_inhibit(s, i)) ? -EBADRQC : 0;
1108		if (ret)
1109			break;
1110		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrm");
1111		if (ret)
1112			break;
1113		if (cmd_val(s, 0) & (1 << 22)) {
1114			gma = cmd_gma(s, i + 1);
1115			if (gmadr_bytes == 8)
1116				gma |= (cmd_gma_hi(s, i + 2)) << 32;
1117			ret |= cmd_address_audit(s, gma, sizeof(u32), false);
1118			if (ret)
1119				break;
1120		}
1121		i += gmadr_dw_number(s) + 1;
1122	}
1123	return ret;
1124}
1125
1126static int cmd_handler_srm(struct parser_exec_state *s)
1127{
1128	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1129	unsigned long gma;
1130	int i, ret = 0;
1131	int cmd_len = cmd_length(s);
1132
1133	for (i = 1; i < cmd_len;) {
1134		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "srm");
1135		if (ret)
1136			break;
1137		if (cmd_val(s, 0) & (1 << 22)) {
1138			gma = cmd_gma(s, i + 1);
1139			if (gmadr_bytes == 8)
1140				gma |= (cmd_gma_hi(s, i + 2)) << 32;
1141			ret |= cmd_address_audit(s, gma, sizeof(u32), false);
1142			if (ret)
1143				break;
1144		}
1145		i += gmadr_dw_number(s) + 1;
1146	}
1147	return ret;
1148}
1149
1150struct cmd_interrupt_event {
1151	int pipe_control_notify;
1152	int mi_flush_dw;
1153	int mi_user_interrupt;
1154};
1155
1156static const struct cmd_interrupt_event cmd_interrupt_events[] = {
1157	[RCS0] = {
1158		.pipe_control_notify = RCS_PIPE_CONTROL,
1159		.mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
1160		.mi_user_interrupt = RCS_MI_USER_INTERRUPT,
1161	},
1162	[BCS0] = {
1163		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1164		.mi_flush_dw = BCS_MI_FLUSH_DW,
1165		.mi_user_interrupt = BCS_MI_USER_INTERRUPT,
1166	},
1167	[VCS0] = {
1168		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1169		.mi_flush_dw = VCS_MI_FLUSH_DW,
1170		.mi_user_interrupt = VCS_MI_USER_INTERRUPT,
1171	},
1172	[VCS1] = {
1173		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1174		.mi_flush_dw = VCS2_MI_FLUSH_DW,
1175		.mi_user_interrupt = VCS2_MI_USER_INTERRUPT,
1176	},
1177	[VECS0] = {
1178		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1179		.mi_flush_dw = VECS_MI_FLUSH_DW,
1180		.mi_user_interrupt = VECS_MI_USER_INTERRUPT,
1181	},
1182};
1183
1184static int cmd_handler_pipe_control(struct parser_exec_state *s)
1185{
1186	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1187	unsigned long gma;
1188	bool index_mode = false;
1189	unsigned int post_sync;
1190	int ret = 0;
1191	u32 hws_pga, val;
1192
1193	post_sync = (cmd_val(s, 1) & PIPE_CONTROL_POST_SYNC_OP_MASK) >> 14;
1194
1195	/* LRI post sync */
1196	if (cmd_val(s, 1) & PIPE_CONTROL_MMIO_WRITE)
1197		ret = cmd_reg_handler(s, cmd_reg(s, 2), 1, "pipe_ctrl");
1198	/* post sync */
1199	else if (post_sync) {
1200		if (post_sync == 2)
1201			ret = cmd_reg_handler(s, 0x2350, 1, "pipe_ctrl");
1202		else if (post_sync == 3)
1203			ret = cmd_reg_handler(s, 0x2358, 1, "pipe_ctrl");
1204		else if (post_sync == 1) {
1205			/* check ggtt*/
1206			if ((cmd_val(s, 1) & PIPE_CONTROL_GLOBAL_GTT_IVB)) {
1207				gma = cmd_val(s, 2) & GENMASK(31, 3);
1208				if (gmadr_bytes == 8)
1209					gma |= (cmd_gma_hi(s, 3)) << 32;
1210				/* Store Data Index */
1211				if (cmd_val(s, 1) & (1 << 21))
1212					index_mode = true;
1213				ret |= cmd_address_audit(s, gma, sizeof(u64),
1214						index_mode);
1215				if (ret)
1216					return ret;
1217				if (index_mode) {
1218					hws_pga = s->vgpu->hws_pga[s->engine->id];
1219					gma = hws_pga + gma;
1220					patch_value(s, cmd_ptr(s, 2), gma);
1221					val = cmd_val(s, 1) & (~(1 << 21));
1222					patch_value(s, cmd_ptr(s, 1), val);
1223				}
1224			}
1225		}
1226	}
1227
1228	if (ret)
1229		return ret;
1230
1231	if (cmd_val(s, 1) & PIPE_CONTROL_NOTIFY)
1232		set_bit(cmd_interrupt_events[s->engine->id].pipe_control_notify,
1233			s->workload->pending_events);
1234	return 0;
1235}
1236
1237static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
1238{
1239	set_bit(cmd_interrupt_events[s->engine->id].mi_user_interrupt,
1240		s->workload->pending_events);
1241	patch_value(s, cmd_ptr(s, 0), MI_NOOP);
1242	return 0;
1243}
1244
1245static int cmd_advance_default(struct parser_exec_state *s)
1246{
1247	return ip_gma_advance(s, cmd_length(s));
1248}
1249
1250static int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
1251{
1252	int ret;
1253
1254	if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
1255		s->buf_type = BATCH_BUFFER_INSTRUCTION;
1256		ret = ip_gma_set(s, s->ret_ip_gma_bb);
1257		s->buf_addr_type = s->saved_buf_addr_type;
1258	} else if (s->buf_type == RING_BUFFER_CTX) {
1259		ret = ip_gma_set(s, s->ring_tail);
1260	} else {
1261		s->buf_type = RING_BUFFER_INSTRUCTION;
1262		s->buf_addr_type = GTT_BUFFER;
1263		if (s->ret_ip_gma_ring >= s->ring_start + s->ring_size)
1264			s->ret_ip_gma_ring -= s->ring_size;
1265		ret = ip_gma_set(s, s->ret_ip_gma_ring);
1266	}
1267	return ret;
1268}
1269
1270struct mi_display_flip_command_info {
1271	int pipe;
1272	int plane;
1273	int event;
1274	i915_reg_t stride_reg;
1275	i915_reg_t ctrl_reg;
1276	i915_reg_t surf_reg;
1277	u64 stride_val;
1278	u64 tile_val;
1279	u64 surf_val;
1280	bool async_flip;
1281};
1282
1283struct plane_code_mapping {
1284	int pipe;
1285	int plane;
1286	int event;
1287};
1288
1289static int gen8_decode_mi_display_flip(struct parser_exec_state *s,
1290		struct mi_display_flip_command_info *info)
1291{
1292	struct drm_i915_private *dev_priv = s->engine->i915;
1293	struct intel_display *display = dev_priv->display;
1294	struct plane_code_mapping gen8_plane_code[] = {
1295		[0] = {PIPE_A, PLANE_A, PRIMARY_A_FLIP_DONE},
1296		[1] = {PIPE_B, PLANE_A, PRIMARY_B_FLIP_DONE},
1297		[2] = {PIPE_A, PLANE_B, SPRITE_A_FLIP_DONE},
1298		[3] = {PIPE_B, PLANE_B, SPRITE_B_FLIP_DONE},
1299		[4] = {PIPE_C, PLANE_A, PRIMARY_C_FLIP_DONE},
1300		[5] = {PIPE_C, PLANE_B, SPRITE_C_FLIP_DONE},
1301	};
1302	u32 dword0, dword1, dword2;
1303	u32 v;
1304
1305	dword0 = cmd_val(s, 0);
1306	dword1 = cmd_val(s, 1);
1307	dword2 = cmd_val(s, 2);
1308
1309	v = (dword0 & GENMASK(21, 19)) >> 19;
1310	if (drm_WARN_ON(&dev_priv->drm, v >= ARRAY_SIZE(gen8_plane_code)))
1311		return -EBADRQC;
1312
1313	info->pipe = gen8_plane_code[v].pipe;
1314	info->plane = gen8_plane_code[v].plane;
1315	info->event = gen8_plane_code[v].event;
1316	info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
1317	info->tile_val = (dword1 & 0x1);
1318	info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
1319	info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
1320
1321	if (info->plane == PLANE_A) {
1322		info->ctrl_reg = DSPCNTR(display, info->pipe);
1323		info->stride_reg = DSPSTRIDE(display, info->pipe);
1324		info->surf_reg = DSPSURF(display, info->pipe);
1325	} else if (info->plane == PLANE_B) {
1326		info->ctrl_reg = SPRCTL(info->pipe);
1327		info->stride_reg = SPRSTRIDE(info->pipe);
1328		info->surf_reg = SPRSURF(info->pipe);
1329	} else {
1330		drm_WARN_ON(&dev_priv->drm, 1);
1331		return -EBADRQC;
1332	}
1333	return 0;
1334}
1335
1336static int skl_decode_mi_display_flip(struct parser_exec_state *s,
1337		struct mi_display_flip_command_info *info)
1338{
1339	struct drm_i915_private *dev_priv = s->engine->i915;
1340	struct intel_display *display = dev_priv->display;
1341	struct intel_vgpu *vgpu = s->vgpu;
1342	u32 dword0 = cmd_val(s, 0);
1343	u32 dword1 = cmd_val(s, 1);
1344	u32 dword2 = cmd_val(s, 2);
1345	u32 plane = (dword0 & GENMASK(12, 8)) >> 8;
1346
1347	info->plane = PRIMARY_PLANE;
1348
1349	switch (plane) {
1350	case MI_DISPLAY_FLIP_SKL_PLANE_1_A:
1351		info->pipe = PIPE_A;
1352		info->event = PRIMARY_A_FLIP_DONE;
1353		break;
1354	case MI_DISPLAY_FLIP_SKL_PLANE_1_B:
1355		info->pipe = PIPE_B;
1356		info->event = PRIMARY_B_FLIP_DONE;
1357		break;
1358	case MI_DISPLAY_FLIP_SKL_PLANE_1_C:
1359		info->pipe = PIPE_C;
1360		info->event = PRIMARY_C_FLIP_DONE;
1361		break;
1362
1363	case MI_DISPLAY_FLIP_SKL_PLANE_2_A:
1364		info->pipe = PIPE_A;
1365		info->event = SPRITE_A_FLIP_DONE;
1366		info->plane = SPRITE_PLANE;
1367		break;
1368	case MI_DISPLAY_FLIP_SKL_PLANE_2_B:
1369		info->pipe = PIPE_B;
1370		info->event = SPRITE_B_FLIP_DONE;
1371		info->plane = SPRITE_PLANE;
1372		break;
1373	case MI_DISPLAY_FLIP_SKL_PLANE_2_C:
1374		info->pipe = PIPE_C;
1375		info->event = SPRITE_C_FLIP_DONE;
1376		info->plane = SPRITE_PLANE;
1377		break;
1378
1379	default:
1380		gvt_vgpu_err("unknown plane code %d\n", plane);
1381		return -EBADRQC;
1382	}
1383
1384	info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
1385	info->tile_val = (dword1 & GENMASK(2, 0));
1386	info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
1387	info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
1388
1389	info->ctrl_reg = DSPCNTR(display, info->pipe);
1390	info->stride_reg = DSPSTRIDE(display, info->pipe);
1391	info->surf_reg = DSPSURF(display, info->pipe);
1392
1393	return 0;
1394}
1395
1396static int gen8_check_mi_display_flip(struct parser_exec_state *s,
1397		struct mi_display_flip_command_info *info)
1398{
1399	u32 stride, tile;
1400
1401	if (!info->async_flip)
1402		return 0;
1403
1404	if (GRAPHICS_VER(s->engine->i915) >= 9) {
1405		stride = vgpu_vreg_t(s->vgpu, info->stride_reg) & GENMASK(9, 0);
1406		tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) &
1407				GENMASK(12, 10)) >> 10;
1408	} else {
1409		stride = (vgpu_vreg_t(s->vgpu, info->stride_reg) &
1410				GENMASK(15, 6)) >> 6;
1411		tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) & (1 << 10)) >> 10;
1412	}
1413
1414	if (stride != info->stride_val)
1415		gvt_dbg_cmd("cannot change stride during async flip\n");
1416
1417	if (tile != info->tile_val)
1418		gvt_dbg_cmd("cannot change tile during async flip\n");
1419
1420	return 0;
1421}
1422
1423static int gen8_update_plane_mmio_from_mi_display_flip(
1424		struct parser_exec_state *s,
1425		struct mi_display_flip_command_info *info)
1426{
1427	struct drm_i915_private *dev_priv = s->engine->i915;
1428	struct intel_display *display = dev_priv->display;
1429	struct intel_vgpu *vgpu = s->vgpu;
1430
1431	set_mask_bits(&vgpu_vreg_t(vgpu, info->surf_reg), GENMASK(31, 12),
1432		      info->surf_val << 12);
1433	if (GRAPHICS_VER(dev_priv) >= 9) {
1434		set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(9, 0),
1435			      info->stride_val);
1436		set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(12, 10),
1437			      info->tile_val << 10);
1438	} else {
1439		set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(15, 6),
1440			      info->stride_val << 6);
1441		set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(10, 10),
1442			      info->tile_val << 10);
1443	}
1444
1445	if (info->plane == PLANE_PRIMARY)
1446		vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(display, info->pipe))++;
1447
1448	if (info->async_flip)
1449		intel_vgpu_trigger_virtual_event(vgpu, info->event);
1450	else
1451		set_bit(info->event, vgpu->irq.flip_done_event[info->pipe]);
1452
1453	return 0;
1454}
1455
1456static int decode_mi_display_flip(struct parser_exec_state *s,
1457		struct mi_display_flip_command_info *info)
1458{
1459	if (IS_BROADWELL(s->engine->i915))
1460		return gen8_decode_mi_display_flip(s, info);
1461	if (GRAPHICS_VER(s->engine->i915) >= 9)
1462		return skl_decode_mi_display_flip(s, info);
1463
1464	return -ENODEV;
1465}
1466
1467static int check_mi_display_flip(struct parser_exec_state *s,
1468		struct mi_display_flip_command_info *info)
1469{
1470	return gen8_check_mi_display_flip(s, info);
1471}
1472
1473static int update_plane_mmio_from_mi_display_flip(
1474		struct parser_exec_state *s,
1475		struct mi_display_flip_command_info *info)
1476{
1477	return gen8_update_plane_mmio_from_mi_display_flip(s, info);
1478}
1479
1480static int cmd_handler_mi_display_flip(struct parser_exec_state *s)
1481{
1482	struct mi_display_flip_command_info info;
1483	struct intel_vgpu *vgpu = s->vgpu;
1484	int ret;
1485	int i;
1486	int len = cmd_length(s);
1487	u32 valid_len = CMD_LEN(1);
1488
1489	/* Flip Type == Stereo 3D Flip */
1490	if (DWORD_FIELD(2, 1, 0) == 2)
1491		valid_len++;
1492	ret = gvt_check_valid_cmd_length(cmd_length(s),
1493			valid_len);
1494	if (ret)
1495		return ret;
1496
1497	ret = decode_mi_display_flip(s, &info);
1498	if (ret) {
1499		gvt_vgpu_err("fail to decode MI display flip command\n");
1500		return ret;
1501	}
1502
1503	ret = check_mi_display_flip(s, &info);
1504	if (ret) {
1505		gvt_vgpu_err("invalid MI display flip command\n");
1506		return ret;
1507	}
1508
1509	ret = update_plane_mmio_from_mi_display_flip(s, &info);
1510	if (ret) {
1511		gvt_vgpu_err("fail to update plane mmio\n");
1512		return ret;
1513	}
1514
1515	for (i = 0; i < len; i++)
1516		patch_value(s, cmd_ptr(s, i), MI_NOOP);
1517	return 0;
1518}
1519
1520static bool is_wait_for_flip_pending(u32 cmd)
1521{
1522	return cmd & (MI_WAIT_FOR_PLANE_A_FLIP_PENDING |
1523			MI_WAIT_FOR_PLANE_B_FLIP_PENDING |
1524			MI_WAIT_FOR_PLANE_C_FLIP_PENDING |
1525			MI_WAIT_FOR_SPRITE_A_FLIP_PENDING |
1526			MI_WAIT_FOR_SPRITE_B_FLIP_PENDING |
1527			MI_WAIT_FOR_SPRITE_C_FLIP_PENDING);
1528}
1529
1530static int cmd_handler_mi_wait_for_event(struct parser_exec_state *s)
1531{
1532	u32 cmd = cmd_val(s, 0);
1533
1534	if (!is_wait_for_flip_pending(cmd))
1535		return 0;
1536
1537	patch_value(s, cmd_ptr(s, 0), MI_NOOP);
1538	return 0;
1539}
1540
1541static unsigned long get_gma_bb_from_cmd(struct parser_exec_state *s, int index)
1542{
1543	unsigned long addr;
1544	unsigned long gma_high, gma_low;
1545	struct intel_vgpu *vgpu = s->vgpu;
1546	int gmadr_bytes = vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1547
1548	if (WARN_ON(gmadr_bytes != 4 && gmadr_bytes != 8)) {
1549		gvt_vgpu_err("invalid gma bytes %d\n", gmadr_bytes);
1550		return INTEL_GVT_INVALID_ADDR;
1551	}
1552
1553	gma_low = cmd_val(s, index) & BATCH_BUFFER_ADDR_MASK;
1554	if (gmadr_bytes == 4) {
1555		addr = gma_low;
1556	} else {
1557		gma_high = cmd_val(s, index + 1) & BATCH_BUFFER_ADDR_HIGH_MASK;
1558		addr = (((unsigned long)gma_high) << 32) | gma_low;
1559	}
1560	return addr;
1561}
1562
1563static inline int cmd_address_audit(struct parser_exec_state *s,
1564		unsigned long guest_gma, int op_size, bool index_mode)
1565{
1566	struct intel_vgpu *vgpu = s->vgpu;
1567	u32 max_surface_size = vgpu->gvt->device_info.max_surface_size;
1568	int i;
1569	int ret;
1570
1571	if (op_size > max_surface_size) {
1572		gvt_vgpu_err("command address audit fail name %s\n",
1573			s->info->name);
1574		return -EFAULT;
1575	}
1576
1577	if (index_mode)	{
1578		if (guest_gma >= I915_GTT_PAGE_SIZE) {
1579			ret = -EFAULT;
1580			goto err;
1581		}
1582	} else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) {
1583		ret = -EFAULT;
1584		goto err;
1585	}
1586
1587	return 0;
1588
1589err:
1590	gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
1591			s->info->name, guest_gma, op_size);
1592
1593	pr_err("cmd dump: ");
1594	for (i = 0; i < cmd_length(s); i++) {
1595		if (!(i % 4))
1596			pr_err("\n%08x ", cmd_val(s, i));
1597		else
1598			pr_err("%08x ", cmd_val(s, i));
1599	}
1600	pr_err("\nvgpu%d: aperture 0x%llx - 0x%llx, hidden 0x%llx - 0x%llx\n",
1601			vgpu->id,
1602			vgpu_aperture_gmadr_base(vgpu),
1603			vgpu_aperture_gmadr_end(vgpu),
1604			vgpu_hidden_gmadr_base(vgpu),
1605			vgpu_hidden_gmadr_end(vgpu));
1606	return ret;
1607}
1608
1609static int cmd_handler_mi_store_data_imm(struct parser_exec_state *s)
1610{
1611	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1612	int op_size = (cmd_length(s) - 3) * sizeof(u32);
1613	int core_id = (cmd_val(s, 2) & (1 << 0)) ? 1 : 0;
1614	unsigned long gma, gma_low, gma_high;
1615	u32 valid_len = CMD_LEN(2);
1616	int ret = 0;
1617
1618	/* check ppggt */
1619	if (!(cmd_val(s, 0) & (1 << 22)))
1620		return 0;
1621
1622	/* check if QWORD */
1623	if (DWORD_FIELD(0, 21, 21))
1624		valid_len++;
1625	ret = gvt_check_valid_cmd_length(cmd_length(s),
1626			valid_len);
1627	if (ret)
1628		return ret;
1629
1630	gma = cmd_val(s, 2) & GENMASK(31, 2);
1631
1632	if (gmadr_bytes == 8) {
1633		gma_low = cmd_val(s, 1) & GENMASK(31, 2);
1634		gma_high = cmd_val(s, 2) & GENMASK(15, 0);
1635		gma = (gma_high << 32) | gma_low;
1636		core_id = (cmd_val(s, 1) & (1 << 0)) ? 1 : 0;
1637	}
1638	ret = cmd_address_audit(s, gma + op_size * core_id, op_size, false);
1639	return ret;
1640}
1641
1642static inline int unexpected_cmd(struct parser_exec_state *s)
1643{
1644	struct intel_vgpu *vgpu = s->vgpu;
1645
1646	gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name);
1647
1648	return -EBADRQC;
1649}
1650
1651static int cmd_handler_mi_semaphore_wait(struct parser_exec_state *s)
1652{
1653	return unexpected_cmd(s);
1654}
1655
1656static int cmd_handler_mi_report_perf_count(struct parser_exec_state *s)
1657{
1658	return unexpected_cmd(s);
1659}
1660
1661static int cmd_handler_mi_op_2e(struct parser_exec_state *s)
1662{
1663	return unexpected_cmd(s);
1664}
1665
1666static int cmd_handler_mi_op_2f(struct parser_exec_state *s)
1667{
1668	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1669	int op_size = (1 << ((cmd_val(s, 0) & GENMASK(20, 19)) >> 19)) *
1670			sizeof(u32);
1671	unsigned long gma, gma_high;
1672	u32 valid_len = CMD_LEN(1);
1673	int ret = 0;
1674
1675	if (!(cmd_val(s, 0) & (1 << 22)))
1676		return ret;
1677
1678	/* check inline data */
1679	if (cmd_val(s, 0) & BIT(18))
1680		valid_len = CMD_LEN(9);
1681	ret = gvt_check_valid_cmd_length(cmd_length(s),
1682			valid_len);
1683	if (ret)
1684		return ret;
1685
1686	gma = cmd_val(s, 1) & GENMASK(31, 2);
1687	if (gmadr_bytes == 8) {
1688		gma_high = cmd_val(s, 2) & GENMASK(15, 0);
1689		gma = (gma_high << 32) | gma;
1690	}
1691	ret = cmd_address_audit(s, gma, op_size, false);
1692	return ret;
1693}
1694
1695static int cmd_handler_mi_store_data_index(struct parser_exec_state *s)
1696{
1697	return unexpected_cmd(s);
1698}
1699
1700static int cmd_handler_mi_clflush(struct parser_exec_state *s)
1701{
1702	return unexpected_cmd(s);
1703}
1704
1705static int cmd_handler_mi_conditional_batch_buffer_end(
1706		struct parser_exec_state *s)
1707{
1708	return unexpected_cmd(s);
1709}
1710
1711static int cmd_handler_mi_update_gtt(struct parser_exec_state *s)
1712{
1713	return unexpected_cmd(s);
1714}
1715
1716static int cmd_handler_mi_flush_dw(struct parser_exec_state *s)
1717{
1718	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1719	unsigned long gma;
1720	bool index_mode = false;
1721	int ret = 0;
1722	u32 hws_pga, val;
1723	u32 valid_len = CMD_LEN(2);
1724
1725	ret = gvt_check_valid_cmd_length(cmd_length(s),
1726			valid_len);
1727	if (ret) {
1728		/* Check again for Qword */
1729		ret = gvt_check_valid_cmd_length(cmd_length(s),
1730			++valid_len);
1731		return ret;
1732	}
1733
1734	/* Check post-sync and ppgtt bit */
1735	if (((cmd_val(s, 0) >> 14) & 0x3) && (cmd_val(s, 1) & (1 << 2))) {
1736		gma = cmd_val(s, 1) & GENMASK(31, 3);
1737		if (gmadr_bytes == 8)
1738			gma |= (cmd_val(s, 2) & GENMASK(15, 0)) << 32;
1739		/* Store Data Index */
1740		if (cmd_val(s, 0) & (1 << 21))
1741			index_mode = true;
1742		ret = cmd_address_audit(s, gma, sizeof(u64), index_mode);
1743		if (ret)
1744			return ret;
1745		if (index_mode) {
1746			hws_pga = s->vgpu->hws_pga[s->engine->id];
1747			gma = hws_pga + gma;
1748			patch_value(s, cmd_ptr(s, 1), gma);
1749			val = cmd_val(s, 0) & (~(1 << 21));
1750			patch_value(s, cmd_ptr(s, 0), val);
1751		}
1752	}
1753	/* Check notify bit */
1754	if ((cmd_val(s, 0) & (1 << 8)))
1755		set_bit(cmd_interrupt_events[s->engine->id].mi_flush_dw,
1756			s->workload->pending_events);
1757	return ret;
1758}
1759
1760static void addr_type_update_snb(struct parser_exec_state *s)
1761{
1762	if ((s->buf_type == RING_BUFFER_INSTRUCTION) &&
1763			(BATCH_BUFFER_ADR_SPACE_BIT(cmd_val(s, 0)) == 1)) {
1764		s->buf_addr_type = PPGTT_BUFFER;
1765	}
1766}
1767
1768
1769static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
1770		unsigned long gma, unsigned long end_gma, void *va)
1771{
1772	unsigned long copy_len, offset;
1773	unsigned long len = 0;
1774	unsigned long gpa;
1775
1776	while (gma != end_gma) {
1777		gpa = intel_vgpu_gma_to_gpa(mm, gma);
1778		if (gpa == INTEL_GVT_INVALID_ADDR) {
1779			gvt_vgpu_err("invalid gma address: %lx\n", gma);
1780			return -EFAULT;
1781		}
1782
1783		offset = gma & (I915_GTT_PAGE_SIZE - 1);
1784
1785		copy_len = (end_gma - gma) >= (I915_GTT_PAGE_SIZE - offset) ?
1786			I915_GTT_PAGE_SIZE - offset : end_gma - gma;
1787
1788		intel_gvt_read_gpa(vgpu, gpa, va + len, copy_len);
1789
1790		len += copy_len;
1791		gma += copy_len;
1792	}
1793	return len;
1794}
1795
1796
1797/*
1798 * Check whether a batch buffer needs to be scanned. Currently
1799 * the only criteria is based on privilege.
1800 */
1801static int batch_buffer_needs_scan(struct parser_exec_state *s)
1802{
1803	/* Decide privilege based on address space */
1804	if (cmd_val(s, 0) & BIT(8) &&
1805	    !(s->vgpu->scan_nonprivbb & s->engine->mask))
1806		return 0;
1807
1808	return 1;
1809}
1810
1811static const char *repr_addr_type(unsigned int type)
1812{
1813	return type == PPGTT_BUFFER ? "ppgtt" : "ggtt";
1814}
1815
1816static int find_bb_size(struct parser_exec_state *s,
1817			unsigned long *bb_size,
1818			unsigned long *bb_end_cmd_offset)
1819{
1820	unsigned long gma = 0;
1821	const struct cmd_info *info;
1822	u32 cmd_len = 0;
1823	bool bb_end = false;
1824	struct intel_vgpu *vgpu = s->vgpu;
1825	u32 cmd;
1826	struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1827		s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1828
1829	*bb_size = 0;
1830	*bb_end_cmd_offset = 0;
1831
1832	/* get the start gm address of the batch buffer */
1833	gma = get_gma_bb_from_cmd(s, 1);
1834	if (gma == INTEL_GVT_INVALID_ADDR)
1835		return -EFAULT;
1836
1837	cmd = cmd_val(s, 0);
1838	info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1839	if (info == NULL) {
1840		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1841			     cmd, get_opcode(cmd, s->engine),
1842			     repr_addr_type(s->buf_addr_type),
1843			     s->engine->name, s->workload);
1844		return -EBADRQC;
1845	}
1846	do {
1847		if (copy_gma_to_hva(s->vgpu, mm,
1848				    gma, gma + 4, &cmd) < 0)
1849			return -EFAULT;
1850		info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1851		if (info == NULL) {
1852			gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1853				     cmd, get_opcode(cmd, s->engine),
1854				     repr_addr_type(s->buf_addr_type),
1855				     s->engine->name, s->workload);
1856			return -EBADRQC;
1857		}
1858
1859		if (info->opcode == OP_MI_BATCH_BUFFER_END) {
1860			bb_end = true;
1861		} else if (info->opcode == OP_MI_BATCH_BUFFER_START) {
1862			if (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)
1863				/* chained batch buffer */
1864				bb_end = true;
1865		}
1866
1867		if (bb_end)
1868			*bb_end_cmd_offset = *bb_size;
1869
1870		cmd_len = get_cmd_length(info, cmd) << 2;
1871		*bb_size += cmd_len;
1872		gma += cmd_len;
1873	} while (!bb_end);
1874
1875	return 0;
1876}
1877
1878static int audit_bb_end(struct parser_exec_state *s, void *va)
1879{
1880	struct intel_vgpu *vgpu = s->vgpu;
1881	u32 cmd = *(u32 *)va;
1882	const struct cmd_info *info;
1883
1884	info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1885	if (info == NULL) {
1886		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1887			     cmd, get_opcode(cmd, s->engine),
1888			     repr_addr_type(s->buf_addr_type),
1889			     s->engine->name, s->workload);
1890		return -EBADRQC;
1891	}
1892
1893	if ((info->opcode == OP_MI_BATCH_BUFFER_END) ||
1894	    ((info->opcode == OP_MI_BATCH_BUFFER_START) &&
1895	     (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)))
1896		return 0;
1897
1898	return -EBADRQC;
1899}
1900
1901static int perform_bb_shadow(struct parser_exec_state *s)
1902{
1903	struct intel_vgpu *vgpu = s->vgpu;
1904	struct intel_vgpu_shadow_bb *bb;
1905	unsigned long gma = 0;
1906	unsigned long bb_size;
1907	unsigned long bb_end_cmd_offset;
1908	int ret = 0;
1909	struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1910		s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1911	unsigned long start_offset = 0;
1912
1913	/* Get the start gm address of the batch buffer */
1914	gma = get_gma_bb_from_cmd(s, 1);
1915	if (gma == INTEL_GVT_INVALID_ADDR)
1916		return -EFAULT;
1917
1918	ret = find_bb_size(s, &bb_size, &bb_end_cmd_offset);
1919	if (ret)
1920		return ret;
1921
1922	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
1923	if (!bb)
1924		return -ENOMEM;
1925
1926	bb->ppgtt = s->buf_addr_type != GTT_BUFFER;
1927
1928	/*
1929	 * The start_offset stores the batch buffer's start gma's
1930	 * offset relative to page boundary. So for non-privileged batch
1931	 * buffer, the shadowed gem object holds exactly the same page
1932	 * layout as original gem object. This is for the convenience of
1933	 * replacing the whole non-privilged batch buffer page to this
1934	 * shadowed one in PPGTT at the same gma address. (This replacing
1935	 * action is not implemented yet now, but may be necessary in
1936	 * future).
1937	 * For prileged batch buffer, we just change start gma address to
1938	 * that of shadowed page.
1939	 */
1940	if (bb->ppgtt)
1941		start_offset = gma & ~I915_GTT_PAGE_MASK;
1942
1943	bb->obj = i915_gem_object_create_shmem(s->engine->i915,
1944					       round_up(bb_size + start_offset,
1945							PAGE_SIZE));
1946	if (IS_ERR(bb->obj)) {
1947		ret = PTR_ERR(bb->obj);
1948		goto err_free_bb;
1949	}
1950
1951	bb->va = i915_gem_object_pin_map(bb->obj, I915_MAP_WB);
1952	if (IS_ERR(bb->va)) {
1953		ret = PTR_ERR(bb->va);
1954		goto err_free_obj;
1955	}
1956
1957	ret = copy_gma_to_hva(s->vgpu, mm,
1958			      gma, gma + bb_size,
1959			      bb->va + start_offset);
1960	if (ret < 0) {
1961		gvt_vgpu_err("fail to copy guest ring buffer\n");
1962		ret = -EFAULT;
1963		goto err_unmap;
1964	}
1965
1966	ret = audit_bb_end(s, bb->va + start_offset + bb_end_cmd_offset);
1967	if (ret)
1968		goto err_unmap;
1969
1970	i915_gem_object_unlock(bb->obj);
1971	INIT_LIST_HEAD(&bb->list);
1972	list_add(&bb->list, &s->workload->shadow_bb);
1973
1974	bb->bb_start_cmd_va = s->ip_va;
1975
1976	if ((s->buf_type == BATCH_BUFFER_INSTRUCTION) && (!s->is_ctx_wa))
1977		bb->bb_offset = s->ip_va - s->rb_va;
1978	else
1979		bb->bb_offset = 0;
1980
1981	/*
1982	 * ip_va saves the virtual address of the shadow batch buffer, while
1983	 * ip_gma saves the graphics address of the original batch buffer.
1984	 * As the shadow batch buffer is just a copy from the original one,
1985	 * it should be right to use shadow batch buffer'va and original batch
1986	 * buffer's gma in pair. After all, we don't want to pin the shadow
1987	 * buffer here (too early).
1988	 */
1989	s->ip_va = bb->va + start_offset;
1990	s->ip_gma = gma;
1991	return 0;
1992err_unmap:
1993	i915_gem_object_unpin_map(bb->obj);
1994err_free_obj:
1995	i915_gem_object_put(bb->obj);
1996err_free_bb:
1997	kfree(bb);
1998	return ret;
1999}
2000
2001static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
2002{
2003	bool second_level;
2004	int ret = 0;
2005	struct intel_vgpu *vgpu = s->vgpu;
2006
2007	if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
2008		gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n");
2009		return -EFAULT;
2010	}
2011
2012	second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1;
2013	if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) {
2014		gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n");
2015		return -EFAULT;
2016	}
2017
2018	s->saved_buf_addr_type = s->buf_addr_type;
2019	addr_type_update_snb(s);
2020	if (s->buf_type == RING_BUFFER_INSTRUCTION) {
2021		s->ret_ip_gma_ring = s->ip_gma + cmd_length(s) * sizeof(u32);
2022		s->buf_type = BATCH_BUFFER_INSTRUCTION;
2023	} else if (second_level) {
2024		s->buf_type = BATCH_BUFFER_2ND_LEVEL;
2025		s->ret_ip_gma_bb = s->ip_gma + cmd_length(s) * sizeof(u32);
2026		s->ret_bb_va = s->ip_va + cmd_length(s) * sizeof(u32);
2027	}
2028
2029	if (batch_buffer_needs_scan(s)) {
2030		ret = perform_bb_shadow(s);
2031		if (ret < 0)
2032			gvt_vgpu_err("invalid shadow batch buffer\n");
2033	} else {
2034		/* emulate a batch buffer end to do return right */
2035		ret = cmd_handler_mi_batch_buffer_end(s);
2036		if (ret < 0)
2037			return ret;
2038	}
2039	return ret;
2040}
2041
2042static int mi_noop_index;
2043
2044static const struct cmd_info cmd_info[] = {
2045	{"MI_NOOP", OP_MI_NOOP, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2046
2047	{"MI_SET_PREDICATE", OP_MI_SET_PREDICATE, F_LEN_CONST, R_ALL, D_ALL,
2048		0, 1, NULL},
2049
2050	{"MI_USER_INTERRUPT", OP_MI_USER_INTERRUPT, F_LEN_CONST, R_ALL, D_ALL,
2051		0, 1, cmd_handler_mi_user_interrupt},
2052
2053	{"MI_WAIT_FOR_EVENT", OP_MI_WAIT_FOR_EVENT, F_LEN_CONST, R_RCS | R_BCS,
2054		D_ALL, 0, 1, cmd_handler_mi_wait_for_event},
2055
2056	{"MI_FLUSH", OP_MI_FLUSH, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2057
2058	{"MI_ARB_CHECK", OP_MI_ARB_CHECK, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2059		NULL},
2060
2061	{"MI_RS_CONTROL", OP_MI_RS_CONTROL, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2062		NULL},
2063
2064	{"MI_REPORT_HEAD", OP_MI_REPORT_HEAD, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2065		NULL},
2066
2067	{"MI_ARB_ON_OFF", OP_MI_ARB_ON_OFF, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2068		NULL},
2069
2070	{"MI_URB_ATOMIC_ALLOC", OP_MI_URB_ATOMIC_ALLOC, F_LEN_CONST, R_RCS,
2071		D_ALL, 0, 1, NULL},
2072
2073	{"MI_BATCH_BUFFER_END", OP_MI_BATCH_BUFFER_END,
2074		F_IP_ADVANCE_CUSTOM | F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2075		cmd_handler_mi_batch_buffer_end},
2076
2077	{"MI_SUSPEND_FLUSH", OP_MI_SUSPEND_FLUSH, F_LEN_CONST, R_ALL, D_ALL,
2078		0, 1, NULL},
2079
2080	{"MI_PREDICATE", OP_MI_PREDICATE, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2081		NULL},
2082
2083	{"MI_TOPOLOGY_FILTER", OP_MI_TOPOLOGY_FILTER, F_LEN_CONST, R_ALL,
2084		D_ALL, 0, 1, NULL},
2085
2086	{"MI_SET_APPID", OP_MI_SET_APPID, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2087		NULL},
2088
2089	{"MI_RS_CONTEXT", OP_MI_RS_CONTEXT, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2090		NULL},
2091
2092	{"MI_DISPLAY_FLIP", OP_MI_DISPLAY_FLIP, F_LEN_VAR,
2093		R_RCS | R_BCS, D_ALL, 0, 8, cmd_handler_mi_display_flip},
2094
2095	{"MI_SEMAPHORE_MBOX", OP_MI_SEMAPHORE_MBOX, F_LEN_VAR | F_LEN_VAR_FIXED,
2096		R_ALL, D_ALL, 0, 8, NULL, CMD_LEN(1)},
2097
2098	{"MI_MATH", OP_MI_MATH, F_LEN_VAR, R_ALL, D_ALL, 0, 8, NULL},
2099
2100	{"MI_URB_CLEAR", OP_MI_URB_CLEAR, F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS,
2101		D_ALL, 0, 8, NULL, CMD_LEN(0)},
2102
2103	{"MI_SEMAPHORE_SIGNAL", OP_MI_SEMAPHORE_SIGNAL,
2104		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, 0, 8,
2105		NULL, CMD_LEN(0)},
2106
2107	{"MI_SEMAPHORE_WAIT", OP_MI_SEMAPHORE_WAIT,
2108		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, ADDR_FIX_1(2),
2109		8, cmd_handler_mi_semaphore_wait, CMD_LEN(2)},
2110
2111	{"MI_STORE_DATA_IMM", OP_MI_STORE_DATA_IMM, F_LEN_VAR, R_ALL, D_BDW_PLUS,
2112		ADDR_FIX_1(1), 10, cmd_handler_mi_store_data_imm},
2113
2114	{"MI_STORE_DATA_INDEX", OP_MI_STORE_DATA_INDEX, F_LEN_VAR, R_ALL, D_ALL,
2115		0, 8, cmd_handler_mi_store_data_index},
2116
2117	{"MI_LOAD_REGISTER_IMM", OP_MI_LOAD_REGISTER_IMM, F_LEN_VAR, R_ALL,
2118		D_ALL, 0, 8, cmd_handler_lri},
2119
2120	{"MI_UPDATE_GTT", OP_MI_UPDATE_GTT, F_LEN_VAR, R_ALL, D_BDW_PLUS, 0, 10,
2121		cmd_handler_mi_update_gtt},
2122
2123	{"MI_STORE_REGISTER_MEM", OP_MI_STORE_REGISTER_MEM,
2124		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2125		cmd_handler_srm, CMD_LEN(2)},
2126
2127	{"MI_FLUSH_DW", OP_MI_FLUSH_DW, F_LEN_VAR, R_ALL, D_ALL, 0, 6,
2128		cmd_handler_mi_flush_dw},
2129
2130	{"MI_CLFLUSH", OP_MI_CLFLUSH, F_LEN_VAR, R_ALL, D_ALL, ADDR_FIX_1(1),
2131		10, cmd_handler_mi_clflush},
2132
2133	{"MI_REPORT_PERF_COUNT", OP_MI_REPORT_PERF_COUNT,
2134		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(1), 6,
2135		cmd_handler_mi_report_perf_count, CMD_LEN(2)},
2136
2137	{"MI_LOAD_REGISTER_MEM", OP_MI_LOAD_REGISTER_MEM,
2138		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2139		cmd_handler_lrm, CMD_LEN(2)},
2140
2141	{"MI_LOAD_REGISTER_REG", OP_MI_LOAD_REGISTER_REG,
2142		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, 0, 8,
2143		cmd_handler_lrr, CMD_LEN(1)},
2144
2145	{"MI_RS_STORE_DATA_IMM", OP_MI_RS_STORE_DATA_IMM,
2146		F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS, D_ALL, 0,
2147		8, NULL, CMD_LEN(2)},
2148
2149	{"MI_LOAD_URB_MEM", OP_MI_LOAD_URB_MEM, F_LEN_VAR | F_LEN_VAR_FIXED,
2150		R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL, CMD_LEN(2)},
2151
2152	{"MI_STORE_URM_MEM", OP_MI_STORE_URM_MEM, F_LEN_VAR, R_RCS, D_ALL,
2153		ADDR_FIX_1(2), 8, NULL},
2154
2155	{"MI_OP_2E", OP_MI_2E, F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS,
2156		ADDR_FIX_2(1, 2), 8, cmd_handler_mi_op_2e, CMD_LEN(3)},
2157
2158	{"MI_OP_2F", OP_MI_2F, F_LEN_VAR, R_ALL, D_BDW_PLUS, ADDR_FIX_1(1),
2159		8, cmd_handler_mi_op_2f},
2160
2161	{"MI_BATCH_BUFFER_START", OP_MI_BATCH_BUFFER_START,
2162		F_IP_ADVANCE_CUSTOM, R_ALL, D_ALL, 0, 8,
2163		cmd_handler_mi_batch_buffer_start},
2164
2165	{"MI_CONDITIONAL_BATCH_BUFFER_END", OP_MI_CONDITIONAL_BATCH_BUFFER_END,
2166		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2167		cmd_handler_mi_conditional_batch_buffer_end, CMD_LEN(2)},
2168
2169	{"MI_LOAD_SCAN_LINES_INCL", OP_MI_LOAD_SCAN_LINES_INCL, F_LEN_CONST,
2170		R_RCS | R_BCS, D_ALL, 0, 2, NULL},
2171
2172	{"XY_SETUP_BLT", OP_XY_SETUP_BLT, F_LEN_VAR, R_BCS, D_ALL,
2173		ADDR_FIX_2(4, 7), 8, NULL},
2174
2175	{"XY_SETUP_CLIP_BLT", OP_XY_SETUP_CLIP_BLT, F_LEN_VAR, R_BCS, D_ALL,
2176		0, 8, NULL},
2177
2178	{"XY_SETUP_MONO_PATTERN_SL_BLT", OP_XY_SETUP_MONO_PATTERN_SL_BLT,
2179		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2180
2181	{"XY_PIXEL_BLT", OP_XY_PIXEL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
2182
2183	{"XY_SCANLINES_BLT", OP_XY_SCANLINES_BLT, F_LEN_VAR, R_BCS, D_ALL,
2184		0, 8, NULL},
2185
2186	{"XY_TEXT_BLT", OP_XY_TEXT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2187		ADDR_FIX_1(3), 8, NULL},
2188
2189	{"XY_TEXT_IMMEDIATE_BLT", OP_XY_TEXT_IMMEDIATE_BLT, F_LEN_VAR, R_BCS,
2190		D_ALL, 0, 8, NULL},
2191
2192	{"XY_COLOR_BLT", OP_XY_COLOR_BLT, F_LEN_VAR, R_BCS, D_ALL,
2193		ADDR_FIX_1(4), 8, NULL},
2194
2195	{"XY_PAT_BLT", OP_XY_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2196		ADDR_FIX_2(4, 5), 8, NULL},
2197
2198	{"XY_MONO_PAT_BLT", OP_XY_MONO_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2199		ADDR_FIX_1(4), 8, NULL},
2200
2201	{"XY_SRC_COPY_BLT", OP_XY_SRC_COPY_BLT, F_LEN_VAR, R_BCS, D_ALL,
2202		ADDR_FIX_2(4, 7), 8, NULL},
2203
2204	{"XY_MONO_SRC_COPY_BLT", OP_XY_MONO_SRC_COPY_BLT, F_LEN_VAR, R_BCS,
2205		D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2206
2207	{"XY_FULL_BLT", OP_XY_FULL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
2208
2209	{"XY_FULL_MONO_SRC_BLT", OP_XY_FULL_MONO_SRC_BLT, F_LEN_VAR, R_BCS,
2210		D_ALL, ADDR_FIX_3(4, 5, 8), 8, NULL},
2211
2212	{"XY_FULL_MONO_PATTERN_BLT", OP_XY_FULL_MONO_PATTERN_BLT, F_LEN_VAR,
2213		R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2214
2215	{"XY_FULL_MONO_PATTERN_MONO_SRC_BLT",
2216		OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT,
2217		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2218
2219	{"XY_MONO_PAT_FIXED_BLT", OP_XY_MONO_PAT_FIXED_BLT, F_LEN_VAR, R_BCS,
2220		D_ALL, ADDR_FIX_1(4), 8, NULL},
2221
2222	{"XY_MONO_SRC_COPY_IMMEDIATE_BLT", OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT,
2223		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2224
2225	{"XY_PAT_BLT_IMMEDIATE", OP_XY_PAT_BLT_IMMEDIATE, F_LEN_VAR, R_BCS,
2226		D_ALL, ADDR_FIX_1(4), 8, NULL},
2227
2228	{"XY_SRC_COPY_CHROMA_BLT", OP_XY_SRC_COPY_CHROMA_BLT, F_LEN_VAR, R_BCS,
2229		D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2230
2231	{"XY_FULL_IMMEDIATE_PATTERN_BLT", OP_XY_FULL_IMMEDIATE_PATTERN_BLT,
2232		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2233
2234	{"XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT",
2235		OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT,
2236		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2237
2238	{"XY_PAT_CHROMA_BLT", OP_XY_PAT_CHROMA_BLT, F_LEN_VAR, R_BCS, D_ALL,
2239		ADDR_FIX_2(4, 5), 8, NULL},
2240
2241	{"XY_PAT_CHROMA_BLT_IMMEDIATE", OP_XY_PAT_CHROMA_BLT_IMMEDIATE,
2242		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2243
2244	{"3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP",
2245		OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
2246		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2247
2248	{"3DSTATE_VIEWPORT_STATE_POINTERS_CC",
2249		OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
2250		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2251
2252	{"3DSTATE_BLEND_STATE_POINTERS",
2253		OP_3DSTATE_BLEND_STATE_POINTERS,
2254		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2255
2256	{"3DSTATE_DEPTH_STENCIL_STATE_POINTERS",
2257		OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
2258		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2259
2260	{"3DSTATE_BINDING_TABLE_POINTERS_VS",
2261		OP_3DSTATE_BINDING_TABLE_POINTERS_VS,
2262		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2263
2264	{"3DSTATE_BINDING_TABLE_POINTERS_HS",
2265		OP_3DSTATE_BINDING_TABLE_POINTERS_HS,
2266		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2267
2268	{"3DSTATE_BINDING_TABLE_POINTERS_DS",
2269		OP_3DSTATE_BINDING_TABLE_POINTERS_DS,
2270		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2271
2272	{"3DSTATE_BINDING_TABLE_POINTERS_GS",
2273		OP_3DSTATE_BINDING_TABLE_POINTERS_GS,
2274		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2275
2276	{"3DSTATE_BINDING_TABLE_POINTERS_PS",
2277		OP_3DSTATE_BINDING_TABLE_POINTERS_PS,
2278		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2279
2280	{"3DSTATE_SAMPLER_STATE_POINTERS_VS",
2281		OP_3DSTATE_SAMPLER_STATE_POINTERS_VS,
2282		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2283
2284	{"3DSTATE_SAMPLER_STATE_POINTERS_HS",
2285		OP_3DSTATE_SAMPLER_STATE_POINTERS_HS,
2286		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2287
2288	{"3DSTATE_SAMPLER_STATE_POINTERS_DS",
2289		OP_3DSTATE_SAMPLER_STATE_POINTERS_DS,
2290		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2291
2292	{"3DSTATE_SAMPLER_STATE_POINTERS_GS",
2293		OP_3DSTATE_SAMPLER_STATE_POINTERS_GS,
2294		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2295
2296	{"3DSTATE_SAMPLER_STATE_POINTERS_PS",
2297		OP_3DSTATE_SAMPLER_STATE_POINTERS_PS,
2298		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2299
2300	{"3DSTATE_URB_VS", OP_3DSTATE_URB_VS, F_LEN_VAR, R_RCS, D_ALL,
2301		0, 8, NULL},
2302
2303	{"3DSTATE_URB_HS", OP_3DSTATE_URB_HS, F_LEN_VAR, R_RCS, D_ALL,
2304		0, 8, NULL},
2305
2306	{"3DSTATE_URB_DS", OP_3DSTATE_URB_DS, F_LEN_VAR, R_RCS, D_ALL,
2307		0, 8, NULL},
2308
2309	{"3DSTATE_URB_GS", OP_3DSTATE_URB_GS, F_LEN_VAR, R_RCS, D_ALL,
2310		0, 8, NULL},
2311
2312	{"3DSTATE_GATHER_CONSTANT_VS", OP_3DSTATE_GATHER_CONSTANT_VS,
2313		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2314
2315	{"3DSTATE_GATHER_CONSTANT_GS", OP_3DSTATE_GATHER_CONSTANT_GS,
2316		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2317
2318	{"3DSTATE_GATHER_CONSTANT_HS", OP_3DSTATE_GATHER_CONSTANT_HS,
2319		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2320
2321	{"3DSTATE_GATHER_CONSTANT_DS", OP_3DSTATE_GATHER_CONSTANT_DS,
2322		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2323
2324	{"3DSTATE_GATHER_CONSTANT_PS", OP_3DSTATE_GATHER_CONSTANT_PS,
2325		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2326
2327	{"3DSTATE_DX9_CONSTANTF_VS", OP_3DSTATE_DX9_CONSTANTF_VS,
2328		F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
2329
2330	{"3DSTATE_DX9_CONSTANTF_PS", OP_3DSTATE_DX9_CONSTANTF_PS,
2331		F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
2332
2333	{"3DSTATE_DX9_CONSTANTI_VS", OP_3DSTATE_DX9_CONSTANTI_VS,
2334		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2335
2336	{"3DSTATE_DX9_CONSTANTI_PS", OP_3DSTATE_DX9_CONSTANTI_PS,
2337		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2338
2339	{"3DSTATE_DX9_CONSTANTB_VS", OP_3DSTATE_DX9_CONSTANTB_VS,
2340		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2341
2342	{"3DSTATE_DX9_CONSTANTB_PS", OP_3DSTATE_DX9_CONSTANTB_PS,
2343		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2344
2345	{"3DSTATE_DX9_LOCAL_VALID_VS", OP_3DSTATE_DX9_LOCAL_VALID_VS,
2346		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2347
2348	{"3DSTATE_DX9_LOCAL_VALID_PS", OP_3DSTATE_DX9_LOCAL_VALID_PS,
2349		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2350
2351	{"3DSTATE_DX9_GENERATE_ACTIVE_VS", OP_3DSTATE_DX9_GENERATE_ACTIVE_VS,
2352		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2353
2354	{"3DSTATE_DX9_GENERATE_ACTIVE_PS", OP_3DSTATE_DX9_GENERATE_ACTIVE_PS,
2355		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2356
2357	{"3DSTATE_BINDING_TABLE_EDIT_VS", OP_3DSTATE_BINDING_TABLE_EDIT_VS,
2358		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2359
2360	{"3DSTATE_BINDING_TABLE_EDIT_GS", OP_3DSTATE_BINDING_TABLE_EDIT_GS,
2361		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2362
2363	{"3DSTATE_BINDING_TABLE_EDIT_HS", OP_3DSTATE_BINDING_TABLE_EDIT_HS,
2364		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2365
2366	{"3DSTATE_BINDING_TABLE_EDIT_DS", OP_3DSTATE_BINDING_TABLE_EDIT_DS,
2367		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2368
2369	{"3DSTATE_BINDING_TABLE_EDIT_PS", OP_3DSTATE_BINDING_TABLE_EDIT_PS,
2370		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2371
2372	{"3DSTATE_VF_INSTANCING", OP_3DSTATE_VF_INSTANCING, F_LEN_VAR, R_RCS,
2373		D_BDW_PLUS, 0, 8, NULL},
2374
2375	{"3DSTATE_VF_SGVS", OP_3DSTATE_VF_SGVS, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2376		NULL},
2377
2378	{"3DSTATE_VF_TOPOLOGY", OP_3DSTATE_VF_TOPOLOGY, F_LEN_VAR, R_RCS,
2379		D_BDW_PLUS, 0, 8, NULL},
2380
2381	{"3DSTATE_WM_CHROMAKEY", OP_3DSTATE_WM_CHROMAKEY, F_LEN_VAR, R_RCS,
2382		D_BDW_PLUS, 0, 8, NULL},
2383
2384	{"3DSTATE_PS_BLEND", OP_3DSTATE_PS_BLEND, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
2385		8, NULL},
2386
2387	{"3DSTATE_WM_DEPTH_STENCIL", OP_3DSTATE_WM_DEPTH_STENCIL, F_LEN_VAR,
2388		R_RCS, D_BDW_PLUS, 0, 8, NULL},
2389
2390	{"3DSTATE_PS_EXTRA", OP_3DSTATE_PS_EXTRA, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
2391		8, NULL},
2392
2393	{"3DSTATE_RASTER", OP_3DSTATE_RASTER, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2394		NULL},
2395
2396	{"3DSTATE_SBE_SWIZ", OP_3DSTATE_SBE_SWIZ, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2397		NULL},
2398
2399	{"3DSTATE_WM_HZ_OP", OP_3DSTATE_WM_HZ_OP, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2400		NULL},
2401
2402	{"3DSTATE_VERTEX_BUFFERS", OP_3DSTATE_VERTEX_BUFFERS, F_LEN_VAR, R_RCS,
2403		D_BDW_PLUS, 0, 8, NULL},
2404
2405	{"3DSTATE_VERTEX_ELEMENTS", OP_3DSTATE_VERTEX_ELEMENTS, F_LEN_VAR,
2406		R_RCS, D_ALL, 0, 8, NULL},
2407
2408	{"3DSTATE_INDEX_BUFFER", OP_3DSTATE_INDEX_BUFFER, F_LEN_VAR, R_RCS,
2409		D_BDW_PLUS, ADDR_FIX_1(2), 8, NULL},
2410
2411	{"3DSTATE_VF_STATISTICS", OP_3DSTATE_VF_STATISTICS, F_LEN_CONST,
2412		R_RCS, D_ALL, 0, 1, NULL},
2413
2414	{"3DSTATE_VF", OP_3DSTATE_VF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2415
2416	{"3DSTATE_CC_STATE_POINTERS", OP_3DSTATE_CC_STATE_POINTERS, F_LEN_VAR,
2417		R_RCS, D_ALL, 0, 8, NULL},
2418
2419	{"3DSTATE_SCISSOR_STATE_POINTERS", OP_3DSTATE_SCISSOR_STATE_POINTERS,
2420		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2421
2422	{"3DSTATE_GS", OP_3DSTATE_GS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2423
2424	{"3DSTATE_CLIP", OP_3DSTATE_CLIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2425
2426	{"3DSTATE_WM", OP_3DSTATE_WM, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2427
2428	{"3DSTATE_CONSTANT_GS", OP_3DSTATE_CONSTANT_GS, F_LEN_VAR, R_RCS,
2429		D_BDW_PLUS, 0, 8, NULL},
2430
2431	{"3DSTATE_CONSTANT_PS", OP_3DSTATE_CONSTANT_PS, F_LEN_VAR, R_RCS,
2432		D_BDW_PLUS, 0, 8, NULL},
2433
2434	{"3DSTATE_SAMPLE_MASK", OP_3DSTATE_SAMPLE_MASK, F_LEN_VAR, R_RCS,
2435		D_ALL, 0, 8, NULL},
2436
2437	{"3DSTATE_CONSTANT_HS", OP_3DSTATE_CONSTANT_HS, F_LEN_VAR, R_RCS,
2438		D_BDW_PLUS, 0, 8, NULL},
2439
2440	{"3DSTATE_CONSTANT_DS", OP_3DSTATE_CONSTANT_DS, F_LEN_VAR, R_RCS,
2441		D_BDW_PLUS, 0, 8, NULL},
2442
2443	{"3DSTATE_HS", OP_3DSTATE_HS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2444
2445	{"3DSTATE_TE", OP_3DSTATE_TE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2446
2447	{"3DSTATE_DS", OP_3DSTATE_DS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2448
2449	{"3DSTATE_STREAMOUT", OP_3DSTATE_STREAMOUT, F_LEN_VAR, R_RCS,
2450		D_ALL, 0, 8, NULL},
2451
2452	{"3DSTATE_SBE", OP_3DSTATE_SBE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2453
2454	{"3DSTATE_PS", OP_3DSTATE_PS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2455
2456	{"3DSTATE_DRAWING_RECTANGLE", OP_3DSTATE_DRAWING_RECTANGLE, F_LEN_VAR,
2457		R_RCS, D_ALL, 0, 8, NULL},
2458
2459	{"3DSTATE_SAMPLER_PALETTE_LOAD0", OP_3DSTATE_SAMPLER_PALETTE_LOAD0,
2460		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2461
2462	{"3DSTATE_CHROMA_KEY", OP_3DSTATE_CHROMA_KEY, F_LEN_VAR, R_RCS, D_ALL,
2463		0, 8, NULL},
2464
2465	{"3DSTATE_DEPTH_BUFFER", OP_3DSTATE_DEPTH_BUFFER, F_LEN_VAR, R_RCS,
2466		D_ALL, ADDR_FIX_1(2), 8, NULL},
2467
2468	{"3DSTATE_POLY_STIPPLE_OFFSET", OP_3DSTATE_POLY_STIPPLE_OFFSET,
2469		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2470
2471	{"3DSTATE_POLY_STIPPLE_PATTERN", OP_3DSTATE_POLY_STIPPLE_PATTERN,
2472		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2473
2474	{"3DSTATE_LINE_STIPPLE", OP_3DSTATE_LINE_STIPPLE, F_LEN_VAR, R_RCS,
2475		D_ALL, 0, 8, NULL},
2476
2477	{"3DSTATE_AA_LINE_PARAMS", OP_3DSTATE_AA_LINE_PARAMS, F_LEN_VAR, R_RCS,
2478		D_ALL, 0, 8, NULL},
2479
2480	{"3DSTATE_GS_SVB_INDEX", OP_3DSTATE_GS_SVB_INDEX, F_LEN_VAR, R_RCS,
2481		D_ALL, 0, 8, NULL},
2482
2483	{"3DSTATE_SAMPLER_PALETTE_LOAD1", OP_3DSTATE_SAMPLER_PALETTE_LOAD1,
2484		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2485
2486	{"3DSTATE_MULTISAMPLE", OP_3DSTATE_MULTISAMPLE_BDW, F_LEN_VAR, R_RCS,
2487		D_BDW_PLUS, 0, 8, NULL},
2488
2489	{"3DSTATE_STENCIL_BUFFER", OP_3DSTATE_STENCIL_BUFFER, F_LEN_VAR, R_RCS,
2490		D_ALL, ADDR_FIX_1(2), 8, NULL},
2491
2492	{"3DSTATE_HIER_DEPTH_BUFFER", OP_3DSTATE_HIER_DEPTH_BUFFER, F_LEN_VAR,
2493		R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL},
2494
2495	{"3DSTATE_CLEAR_PARAMS", OP_3DSTATE_CLEAR_PARAMS, F_LEN_VAR,
2496		R_RCS, D_ALL, 0, 8, NULL},
2497
2498	{"3DSTATE_PUSH_CONSTANT_ALLOC_VS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
2499		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2500
2501	{"3DSTATE_PUSH_CONSTANT_ALLOC_HS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS,
2502		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2503
2504	{"3DSTATE_PUSH_CONSTANT_ALLOC_DS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS,
2505		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2506
2507	{"3DSTATE_PUSH_CONSTANT_ALLOC_GS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
2508		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2509
2510	{"3DSTATE_PUSH_CONSTANT_ALLOC_PS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
2511		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2512
2513	{"3DSTATE_MONOFILTER_SIZE", OP_3DSTATE_MONOFILTER_SIZE, F_LEN_VAR,
2514		R_RCS, D_ALL, 0, 8, NULL},
2515
2516	{"3DSTATE_SO_DECL_LIST", OP_3DSTATE_SO_DECL_LIST, F_LEN_VAR, R_RCS,
2517		D_ALL, 0, 9, NULL},
2518
2519	{"3DSTATE_SO_BUFFER", OP_3DSTATE_SO_BUFFER, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2520		ADDR_FIX_2(2, 4), 8, NULL},
2521
2522	{"3DSTATE_BINDING_TABLE_POOL_ALLOC",
2523		OP_3DSTATE_BINDING_TABLE_POOL_ALLOC,
2524		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2525
2526	{"3DSTATE_GATHER_POOL_ALLOC", OP_3DSTATE_GATHER_POOL_ALLOC,
2527		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2528
2529	{"3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC",
2530		OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC,
2531		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2532
2533	{"3DSTATE_SAMPLE_PATTERN", OP_3DSTATE_SAMPLE_PATTERN, F_LEN_VAR, R_RCS,
2534		D_BDW_PLUS, 0, 8, NULL},
2535
2536	{"PIPE_CONTROL", OP_PIPE_CONTROL, F_LEN_VAR, R_RCS, D_ALL,
2537		ADDR_FIX_1(2), 8, cmd_handler_pipe_control},
2538
2539	{"3DPRIMITIVE", OP_3DPRIMITIVE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2540
2541	{"PIPELINE_SELECT", OP_PIPELINE_SELECT, F_LEN_CONST, R_RCS, D_ALL, 0,
2542		1, NULL},
2543
2544	{"STATE_PREFETCH", OP_STATE_PREFETCH, F_LEN_VAR, R_RCS, D_ALL,
2545		ADDR_FIX_1(1), 8, NULL},
2546
2547	{"STATE_SIP", OP_STATE_SIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2548
2549	{"STATE_BASE_ADDRESS", OP_STATE_BASE_ADDRESS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2550		ADDR_FIX_5(1, 3, 4, 5, 6), 8, NULL},
2551
2552	{"OP_3D_MEDIA_0_1_4", OP_3D_MEDIA_0_1_4, F_LEN_VAR, R_RCS, D_ALL,
2553		ADDR_FIX_1(1), 8, NULL},
2554
2555	{"OP_SWTESS_BASE_ADDRESS", OP_SWTESS_BASE_ADDRESS,
2556		F_LEN_VAR, R_RCS, D_ALL, ADDR_FIX_2(1, 2), 3, NULL},
2557
2558	{"3DSTATE_VS", OP_3DSTATE_VS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2559
2560	{"3DSTATE_SF", OP_3DSTATE_SF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2561
2562	{"3DSTATE_CONSTANT_VS", OP_3DSTATE_CONSTANT_VS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2563		0, 8, NULL},
2564
2565	{"3DSTATE_COMPONENT_PACKING", OP_3DSTATE_COMPONENT_PACKING, F_LEN_VAR, R_RCS,
2566		D_SKL_PLUS, 0, 8, NULL},
2567
2568	{"MEDIA_INTERFACE_DESCRIPTOR_LOAD", OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
2569		F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
2570
2571	{"MEDIA_GATEWAY_STATE", OP_MEDIA_GATEWAY_STATE, F_LEN_VAR, R_RCS, D_ALL,
2572		0, 16, NULL},
2573
2574	{"MEDIA_STATE_FLUSH", OP_MEDIA_STATE_FLUSH, F_LEN_VAR, R_RCS, D_ALL,
2575		0, 16, NULL},
2576
2577	{"MEDIA_POOL_STATE", OP_MEDIA_POOL_STATE, F_LEN_VAR, R_RCS, D_ALL,
2578		0, 16, NULL},
2579
2580	{"MEDIA_OBJECT", OP_MEDIA_OBJECT, F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
2581
2582	{"MEDIA_CURBE_LOAD", OP_MEDIA_CURBE_LOAD, F_LEN_VAR, R_RCS, D_ALL,
2583		0, 16, NULL},
2584
2585	{"MEDIA_OBJECT_PRT", OP_MEDIA_OBJECT_PRT, F_LEN_VAR, R_RCS, D_ALL,
2586		0, 16, NULL},
2587
2588	{"MEDIA_OBJECT_WALKER", OP_MEDIA_OBJECT_WALKER, F_LEN_VAR, R_RCS, D_ALL,
2589		0, 16, NULL},
2590
2591	{"GPGPU_WALKER", OP_GPGPU_WALKER, F_LEN_VAR, R_RCS, D_ALL,
2592		0, 8, NULL},
2593
2594	{"MEDIA_VFE_STATE", OP_MEDIA_VFE_STATE, F_LEN_VAR, R_RCS, D_ALL, 0, 16,
2595		NULL},
2596
2597	{"3DSTATE_VF_STATISTICS_GM45", OP_3DSTATE_VF_STATISTICS_GM45,
2598		F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2599
2600	{"MFX_PIPE_MODE_SELECT", OP_MFX_PIPE_MODE_SELECT, F_LEN_VAR,
2601		R_VCS, D_ALL, 0, 12, NULL},
2602
2603	{"MFX_SURFACE_STATE", OP_MFX_SURFACE_STATE, F_LEN_VAR,
2604		R_VCS, D_ALL, 0, 12, NULL},
2605
2606	{"MFX_PIPE_BUF_ADDR_STATE", OP_MFX_PIPE_BUF_ADDR_STATE, F_LEN_VAR,
2607		R_VCS, D_BDW_PLUS, 0, 12, NULL},
2608
2609	{"MFX_IND_OBJ_BASE_ADDR_STATE", OP_MFX_IND_OBJ_BASE_ADDR_STATE,
2610		F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
2611
2612	{"MFX_BSP_BUF_BASE_ADDR_STATE", OP_MFX_BSP_BUF_BASE_ADDR_STATE,
2613		F_LEN_VAR, R_VCS, D_BDW_PLUS, ADDR_FIX_3(1, 3, 5), 12, NULL},
2614
2615	{"OP_2_0_0_5", OP_2_0_0_5, F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
2616
2617	{"MFX_STATE_POINTER", OP_MFX_STATE_POINTER, F_LEN_VAR,
2618		R_VCS, D_ALL, 0, 12, NULL},
2619
2620	{"MFX_QM_STATE", OP_MFX_QM_STATE, F_LEN_VAR,
2621		R_VCS, D_ALL, 0, 12, NULL},
2622
2623	{"MFX_FQM_STATE", OP_MFX_FQM_STATE, F_LEN_VAR,
2624		R_VCS, D_ALL, 0, 12, NULL},
2625
2626	{"MFX_PAK_INSERT_OBJECT", OP_MFX_PAK_INSERT_OBJECT, F_LEN_VAR,
2627		R_VCS, D_ALL, 0, 12, NULL},
2628
2629	{"MFX_STITCH_OBJECT", OP_MFX_STITCH_OBJECT, F_LEN_VAR,
2630		R_VCS, D_ALL, 0, 12, NULL},
2631
2632	{"MFD_IT_OBJECT", OP_MFD_IT_OBJECT, F_LEN_VAR,
2633		R_VCS, D_ALL, 0, 12, NULL},
2634
2635	{"MFX_WAIT", OP_MFX_WAIT, F_LEN_VAR,
2636		R_VCS, D_ALL, 0, 6, NULL},
2637
2638	{"MFX_AVC_IMG_STATE", OP_MFX_AVC_IMG_STATE, F_LEN_VAR,
2639		R_VCS, D_ALL, 0, 12, NULL},
2640
2641	{"MFX_AVC_QM_STATE", OP_MFX_AVC_QM_STATE, F_LEN_VAR,
2642		R_VCS, D_ALL, 0, 12, NULL},
2643
2644	{"MFX_AVC_DIRECTMODE_STATE", OP_MFX_AVC_DIRECTMODE_STATE, F_LEN_VAR,
2645		R_VCS, D_ALL, 0, 12, NULL},
2646
2647	{"MFX_AVC_SLICE_STATE", OP_MFX_AVC_SLICE_STATE, F_LEN_VAR,
2648		R_VCS, D_ALL, 0, 12, NULL},
2649
2650	{"MFX_AVC_REF_IDX_STATE", OP_MFX_AVC_REF_IDX_STATE, F_LEN_VAR,
2651		R_VCS, D_ALL, 0, 12, NULL},
2652
2653	{"MFX_AVC_WEIGHTOFFSET_STATE", OP_MFX_AVC_WEIGHTOFFSET_STATE, F_LEN_VAR,
2654		R_VCS, D_ALL, 0, 12, NULL},
2655
2656	{"MFD_AVC_PICID_STATE", OP_MFD_AVC_PICID_STATE, F_LEN_VAR,
2657		R_VCS, D_ALL, 0, 12, NULL},
2658	{"MFD_AVC_DPB_STATE", OP_MFD_AVC_DPB_STATE, F_LEN_VAR,
2659		R_VCS, D_ALL, 0, 12, NULL},
2660
2661	{"MFD_AVC_BSD_OBJECT", OP_MFD_AVC_BSD_OBJECT, F_LEN_VAR,
2662		R_VCS, D_ALL, 0, 12, NULL},
2663
2664	{"MFD_AVC_SLICEADDR", OP_MFD_AVC_SLICEADDR, F_LEN_VAR,
2665		R_VCS, D_ALL, ADDR_FIX_1(2), 12, NULL},
2666
2667	{"MFC_AVC_PAK_OBJECT", OP_MFC_AVC_PAK_OBJECT, F_LEN_VAR,
2668		R_VCS, D_ALL, 0, 12, NULL},
2669
2670	{"MFX_VC1_PRED_PIPE_STATE", OP_MFX_VC1_PRED_PIPE_STATE, F_LEN_VAR,
2671		R_VCS, D_ALL, 0, 12, NULL},
2672
2673	{"MFX_VC1_DIRECTMODE_STATE", OP_MFX_VC1_DIRECTMODE_STATE, F_LEN_VAR,
2674		R_VCS, D_ALL, 0, 12, NULL},
2675
2676	{"MFD_VC1_SHORT_PIC_STATE", OP_MFD_VC1_SHORT_PIC_STATE, F_LEN_VAR,
2677		R_VCS, D_ALL, 0, 12, NULL},
2678
2679	{"MFD_VC1_LONG_PIC_STATE", OP_MFD_VC1_LONG_PIC_STATE, F_LEN_VAR,
2680		R_VCS, D_ALL, 0, 12, NULL},
2681
2682	{"MFD_VC1_BSD_OBJECT", OP_MFD_VC1_BSD_OBJECT, F_LEN_VAR,
2683		R_VCS, D_ALL, 0, 12, NULL},
2684
2685	{"MFC_MPEG2_SLICEGROUP_STATE", OP_MFC_MPEG2_SLICEGROUP_STATE, F_LEN_VAR,
2686		R_VCS, D_ALL, 0, 12, NULL},
2687
2688	{"MFC_MPEG2_PAK_OBJECT", OP_MFC_MPEG2_PAK_OBJECT, F_LEN_VAR,
2689		R_VCS, D_ALL, 0, 12, NULL},
2690
2691	{"MFX_MPEG2_PIC_STATE", OP_MFX_MPEG2_PIC_STATE, F_LEN_VAR,
2692		R_VCS, D_ALL, 0, 12, NULL},
2693
2694	{"MFX_MPEG2_QM_STATE", OP_MFX_MPEG2_QM_STATE, F_LEN_VAR,
2695		R_VCS, D_ALL, 0, 12, NULL},
2696
2697	{"MFD_MPEG2_BSD_OBJECT", OP_MFD_MPEG2_BSD_OBJECT, F_LEN_VAR,
2698		R_VCS, D_ALL, 0, 12, NULL},
2699
2700	{"MFX_2_6_0_0", OP_MFX_2_6_0_0, F_LEN_VAR, R_VCS, D_ALL,
2701		0, 16, NULL},
2702
2703	{"MFX_2_6_0_9", OP_MFX_2_6_0_9, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
2704
2705	{"MFX_2_6_0_8", OP_MFX_2_6_0_8, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
2706
2707	{"MFX_JPEG_PIC_STATE", OP_MFX_JPEG_PIC_STATE, F_LEN_VAR,
2708		R_VCS, D_ALL, 0, 12, NULL},
2709
2710	{"MFX_JPEG_HUFF_TABLE_STATE", OP_MFX_JPEG_HUFF_TABLE_STATE, F_LEN_VAR,
2711		R_VCS, D_ALL, 0, 12, NULL},
2712
2713	{"MFD_JPEG_BSD_OBJECT", OP_MFD_JPEG_BSD_OBJECT, F_LEN_VAR,
2714		R_VCS, D_ALL, 0, 12, NULL},
2715
2716	{"VEBOX_STATE", OP_VEB_STATE, F_LEN_VAR, R_VECS, D_ALL, 0, 12, NULL},
2717
2718	{"VEBOX_SURFACE_STATE", OP_VEB_SURFACE_STATE, F_LEN_VAR, R_VECS, D_ALL,
2719		0, 12, NULL},
2720
2721	{"VEB_DI_IECP", OP_VEB_DNDI_IECP_STATE, F_LEN_VAR, R_VECS, D_BDW_PLUS,
2722		0, 12, NULL},
2723};
2724
2725static void add_cmd_entry(struct intel_gvt *gvt, struct cmd_entry *e)
2726{
2727	hash_add(gvt->cmd_table, &e->hlist, e->info->opcode);
2728}
2729
2730/* call the cmd handler, and advance ip */
2731static int cmd_parser_exec(struct parser_exec_state *s)
2732{
2733	struct intel_vgpu *vgpu = s->vgpu;
2734	const struct cmd_info *info;
2735	u32 cmd;
2736	int ret = 0;
2737
2738	cmd = cmd_val(s, 0);
2739
2740	/* fastpath for MI_NOOP */
2741	if (cmd == MI_NOOP)
2742		info = &cmd_info[mi_noop_index];
2743	else
2744		info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
2745
2746	if (info == NULL) {
2747		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
2748			     cmd, get_opcode(cmd, s->engine),
2749			     repr_addr_type(s->buf_addr_type),
2750			     s->engine->name, s->workload);
2751		return -EBADRQC;
2752	}
2753
2754	s->info = info;
2755
2756	trace_gvt_command(vgpu->id, s->engine->id, s->ip_gma, s->ip_va,
2757			  cmd_length(s), s->buf_type, s->buf_addr_type,
2758			  s->workload, info->name);
2759
2760	if ((info->flag & F_LEN_MASK) == F_LEN_VAR_FIXED) {
2761		ret = gvt_check_valid_cmd_length(cmd_length(s),
2762						 info->valid_len);
2763		if (ret)
2764			return ret;
2765	}
2766
2767	if (info->handler) {
2768		ret = info->handler(s);
2769		if (ret < 0) {
2770			gvt_vgpu_err("%s handler error\n", info->name);
2771			return ret;
2772		}
2773	}
2774
2775	if (!(info->flag & F_IP_ADVANCE_CUSTOM)) {
2776		ret = cmd_advance_default(s);
2777		if (ret) {
2778			gvt_vgpu_err("%s IP advance error\n", info->name);
2779			return ret;
2780		}
2781	}
2782	return 0;
2783}
2784
2785static inline bool gma_out_of_range(unsigned long gma,
2786		unsigned long gma_head, unsigned int gma_tail)
2787{
2788	if (gma_tail >= gma_head)
2789		return (gma < gma_head) || (gma > gma_tail);
2790	else
2791		return (gma > gma_tail) && (gma < gma_head);
2792}
2793
2794/* Keep the consistent return type, e.g EBADRQC for unknown
2795 * cmd, EFAULT for invalid address, EPERM for nonpriv. later
2796 * works as the input of VM healthy status.
2797 */
2798static int command_scan(struct parser_exec_state *s,
2799		unsigned long rb_head, unsigned long rb_tail,
2800		unsigned long rb_start, unsigned long rb_len)
2801{
2802
2803	unsigned long gma_head, gma_tail, gma_bottom;
2804	int ret = 0;
2805	struct intel_vgpu *vgpu = s->vgpu;
2806
2807	gma_head = rb_start + rb_head;
2808	gma_tail = rb_start + rb_tail;
2809	gma_bottom = rb_start +  rb_len;
2810
2811	while (s->ip_gma != gma_tail) {
2812		if (s->buf_type == RING_BUFFER_INSTRUCTION ||
2813				s->buf_type == RING_BUFFER_CTX) {
2814			if (!(s->ip_gma >= rb_start) ||
2815				!(s->ip_gma < gma_bottom)) {
2816				gvt_vgpu_err("ip_gma %lx out of ring scope."
2817					"(base:0x%lx, bottom: 0x%lx)\n",
2818					s->ip_gma, rb_start,
2819					gma_bottom);
2820				parser_exec_state_dump(s);
2821				return -EFAULT;
2822			}
2823			if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) {
2824				gvt_vgpu_err("ip_gma %lx out of range."
2825					"base 0x%lx head 0x%lx tail 0x%lx\n",
2826					s->ip_gma, rb_start,
2827					rb_head, rb_tail);
2828				parser_exec_state_dump(s);
2829				break;
2830			}
2831		}
2832		ret = cmd_parser_exec(s);
2833		if (ret) {
2834			gvt_vgpu_err("cmd parser error\n");
2835			parser_exec_state_dump(s);
2836			break;
2837		}
2838	}
2839
2840	return ret;
2841}
2842
2843static int scan_workload(struct intel_vgpu_workload *workload)
2844{
2845	unsigned long gma_head, gma_tail;
2846	struct parser_exec_state s;
2847	int ret = 0;
2848
2849	/* ring base is page aligned */
2850	if (WARN_ON(!IS_ALIGNED(workload->rb_start, I915_GTT_PAGE_SIZE)))
2851		return -EINVAL;
2852
2853	gma_head = workload->rb_start + workload->rb_head;
2854	gma_tail = workload->rb_start + workload->rb_tail;
2855
2856	s.buf_type = RING_BUFFER_INSTRUCTION;
2857	s.buf_addr_type = GTT_BUFFER;
2858	s.vgpu = workload->vgpu;
2859	s.engine = workload->engine;
2860	s.ring_start = workload->rb_start;
2861	s.ring_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
2862	s.ring_head = gma_head;
2863	s.ring_tail = gma_tail;
2864	s.rb_va = workload->shadow_ring_buffer_va;
2865	s.workload = workload;
2866	s.is_ctx_wa = false;
2867
2868	if (bypass_scan_mask & workload->engine->mask || gma_head == gma_tail)
2869		return 0;
2870
2871	ret = ip_gma_set(&s, gma_head);
2872	if (ret)
2873		goto out;
2874
2875	ret = command_scan(&s, workload->rb_head, workload->rb_tail,
2876		workload->rb_start, _RING_CTL_BUF_SIZE(workload->rb_ctl));
2877
2878out:
2879	return ret;
2880}
2881
2882static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
2883{
2884
2885	unsigned long gma_head, gma_tail, ring_size, ring_tail;
2886	struct parser_exec_state s;
2887	int ret = 0;
2888	struct intel_vgpu_workload *workload = container_of(wa_ctx,
2889				struct intel_vgpu_workload,
2890				wa_ctx);
2891
2892	/* ring base is page aligned */
2893	if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma,
2894					I915_GTT_PAGE_SIZE)))
2895		return -EINVAL;
2896
2897	ring_tail = wa_ctx->indirect_ctx.size + 3 * sizeof(u32);
2898	ring_size = round_up(wa_ctx->indirect_ctx.size + CACHELINE_BYTES,
2899			PAGE_SIZE);
2900	gma_head = wa_ctx->indirect_ctx.guest_gma;
2901	gma_tail = wa_ctx->indirect_ctx.guest_gma + ring_tail;
2902
2903	s.buf_type = RING_BUFFER_INSTRUCTION;
2904	s.buf_addr_type = GTT_BUFFER;
2905	s.vgpu = workload->vgpu;
2906	s.engine = workload->engine;
2907	s.ring_start = wa_ctx->indirect_ctx.guest_gma;
2908	s.ring_size = ring_size;
2909	s.ring_head = gma_head;
2910	s.ring_tail = gma_tail;
2911	s.rb_va = wa_ctx->indirect_ctx.shadow_va;
2912	s.workload = workload;
2913	s.is_ctx_wa = true;
2914
2915	ret = ip_gma_set(&s, gma_head);
2916	if (ret)
2917		goto out;
2918
2919	ret = command_scan(&s, 0, ring_tail,
2920		wa_ctx->indirect_ctx.guest_gma, ring_size);
2921out:
2922	return ret;
2923}
2924
2925static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
2926{
2927	struct intel_vgpu *vgpu = workload->vgpu;
2928	struct intel_vgpu_submission *s = &vgpu->submission;
2929	unsigned long gma_head, gma_tail, gma_top, guest_rb_size;
2930	void *shadow_ring_buffer_va;
2931	int ret;
2932
2933	guest_rb_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
2934
2935	/* calculate workload ring buffer size */
2936	workload->rb_len = (workload->rb_tail + guest_rb_size -
2937			workload->rb_head) % guest_rb_size;
2938
2939	gma_head = workload->rb_start + workload->rb_head;
2940	gma_tail = workload->rb_start + workload->rb_tail;
2941	gma_top = workload->rb_start + guest_rb_size;
2942
2943	if (workload->rb_len > s->ring_scan_buffer_size[workload->engine->id]) {
2944		void *p;
2945
2946		/* realloc the new ring buffer if needed */
2947		p = krealloc(s->ring_scan_buffer[workload->engine->id],
2948			     workload->rb_len, GFP_KERNEL);
2949		if (!p) {
2950			gvt_vgpu_err("fail to re-alloc ring scan buffer\n");
2951			return -ENOMEM;
2952		}
2953		s->ring_scan_buffer[workload->engine->id] = p;
2954		s->ring_scan_buffer_size[workload->engine->id] = workload->rb_len;
2955	}
2956
2957	shadow_ring_buffer_va = s->ring_scan_buffer[workload->engine->id];
2958
2959	/* get shadow ring buffer va */
2960	workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
2961
2962	/* head > tail --> copy head <-> top */
2963	if (gma_head > gma_tail) {
2964		ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm,
2965				      gma_head, gma_top, shadow_ring_buffer_va);
2966		if (ret < 0) {
2967			gvt_vgpu_err("fail to copy guest ring buffer\n");
2968			return ret;
2969		}
2970		shadow_ring_buffer_va += ret;
2971		gma_head = workload->rb_start;
2972	}
2973
2974	/* copy head or start <-> tail */
2975	ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, gma_head, gma_tail,
2976				shadow_ring_buffer_va);
2977	if (ret < 0) {
2978		gvt_vgpu_err("fail to copy guest ring buffer\n");
2979		return ret;
2980	}
2981	return 0;
2982}
2983
2984int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload)
2985{
2986	int ret;
2987	struct intel_vgpu *vgpu = workload->vgpu;
2988
2989	ret = shadow_workload_ring_buffer(workload);
2990	if (ret) {
2991		gvt_vgpu_err("fail to shadow workload ring_buffer\n");
2992		return ret;
2993	}
2994
2995	ret = scan_workload(workload);
2996	if (ret) {
2997		gvt_vgpu_err("scan workload error\n");
2998		return ret;
2999	}
3000	return 0;
3001}
3002
3003static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
3004{
3005	int ctx_size = wa_ctx->indirect_ctx.size;
3006	unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
3007	struct intel_vgpu_workload *workload = container_of(wa_ctx,
3008					struct intel_vgpu_workload,
3009					wa_ctx);
3010	struct intel_vgpu *vgpu = workload->vgpu;
3011	struct drm_i915_gem_object *obj;
3012	int ret = 0;
3013	void *map;
3014
3015	obj = i915_gem_object_create_shmem(workload->engine->i915,
3016					   roundup(ctx_size + CACHELINE_BYTES,
3017						   PAGE_SIZE));
3018	if (IS_ERR(obj))
3019		return PTR_ERR(obj);
3020
3021	/* get the va of the shadow batch buffer */
3022	map = i915_gem_object_pin_map(obj, I915_MAP_WB);
3023	if (IS_ERR(map)) {
3024		gvt_vgpu_err("failed to vmap shadow indirect ctx\n");
3025		ret = PTR_ERR(map);
3026		goto put_obj;
3027	}
3028
3029	i915_gem_object_lock(obj, NULL);
3030	ret = i915_gem_object_set_to_cpu_domain(obj, false);
3031	i915_gem_object_unlock(obj);
3032	if (ret) {
3033		gvt_vgpu_err("failed to set shadow indirect ctx to CPU\n");
3034		goto unmap_src;
3035	}
3036
3037	ret = copy_gma_to_hva(workload->vgpu,
3038				workload->vgpu->gtt.ggtt_mm,
3039				guest_gma, guest_gma + ctx_size,
3040				map);
3041	if (ret < 0) {
3042		gvt_vgpu_err("fail to copy guest indirect ctx\n");
3043		goto unmap_src;
3044	}
3045
3046	wa_ctx->indirect_ctx.obj = obj;
3047	wa_ctx->indirect_ctx.shadow_va = map;
3048	return 0;
3049
3050unmap_src:
3051	i915_gem_object_unpin_map(obj);
3052put_obj:
3053	i915_gem_object_put(obj);
3054	return ret;
3055}
3056
3057static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
3058{
3059	u32 per_ctx_start[CACHELINE_DWORDS] = {};
3060	unsigned char *bb_start_sva;
3061
3062	if (!wa_ctx->per_ctx.valid)
3063		return 0;
3064
3065	per_ctx_start[0] = 0x18800001;
3066	per_ctx_start[1] = wa_ctx->per_ctx.guest_gma;
3067
3068	bb_start_sva = (unsigned char *)wa_ctx->indirect_ctx.shadow_va +
3069				wa_ctx->indirect_ctx.size;
3070
3071	memcpy(bb_start_sva, per_ctx_start, CACHELINE_BYTES);
3072
3073	return 0;
3074}
3075
3076int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
3077{
3078	int ret;
3079	struct intel_vgpu_workload *workload = container_of(wa_ctx,
3080					struct intel_vgpu_workload,
3081					wa_ctx);
3082	struct intel_vgpu *vgpu = workload->vgpu;
3083
3084	if (wa_ctx->indirect_ctx.size == 0)
3085		return 0;
3086
3087	ret = shadow_indirect_ctx(wa_ctx);
3088	if (ret) {
3089		gvt_vgpu_err("fail to shadow indirect ctx\n");
3090		return ret;
3091	}
3092
3093	combine_wa_ctx(wa_ctx);
3094
3095	ret = scan_wa_ctx(wa_ctx);
3096	if (ret) {
3097		gvt_vgpu_err("scan wa ctx error\n");
3098		return ret;
3099	}
3100
3101	return 0;
3102}
3103
3104/* generate dummy contexts by sending empty requests to HW, and let
3105 * the HW to fill Engine Contexts. This dummy contexts are used for
3106 * initialization purpose (update reg whitelist), so referred to as
3107 * init context here
3108 */
3109void intel_gvt_update_reg_whitelist(struct intel_vgpu *vgpu)
3110{
3111	const unsigned long start = LRC_STATE_PN * PAGE_SIZE;
3112	struct intel_gvt *gvt = vgpu->gvt;
3113	struct intel_engine_cs *engine;
3114	enum intel_engine_id id;
3115
3116	if (gvt->is_reg_whitelist_updated)
3117		return;
3118
3119	/* scan init ctx to update cmd accessible list */
3120	for_each_engine(engine, gvt->gt, id) {
3121		struct parser_exec_state s;
3122		void *vaddr;
3123		int ret;
3124
3125		if (!engine->default_state)
3126			continue;
3127
3128		vaddr = shmem_pin_map(engine->default_state);
3129		if (!vaddr) {
3130			gvt_err("failed to map %s->default state\n",
3131				engine->name);
3132			return;
3133		}
3134
3135		s.buf_type = RING_BUFFER_CTX;
3136		s.buf_addr_type = GTT_BUFFER;
3137		s.vgpu = vgpu;
3138		s.engine = engine;
3139		s.ring_start = 0;
3140		s.ring_size = engine->context_size - start;
3141		s.ring_head = 0;
3142		s.ring_tail = s.ring_size;
3143		s.rb_va = vaddr + start;
3144		s.workload = NULL;
3145		s.is_ctx_wa = false;
3146		s.is_init_ctx = true;
3147
3148		/* skipping the first RING_CTX_SIZE(0x50) dwords */
3149		ret = ip_gma_set(&s, RING_CTX_SIZE);
3150		if (ret == 0) {
3151			ret = command_scan(&s, 0, s.ring_size, 0, s.ring_size);
3152			if (ret)
3153				gvt_err("Scan init ctx error\n");
3154		}
3155
3156		shmem_unpin_map(engine->default_state, vaddr);
3157		if (ret)
3158			return;
3159	}
3160
3161	gvt->is_reg_whitelist_updated = true;
3162}
3163
3164int intel_gvt_scan_engine_context(struct intel_vgpu_workload *workload)
3165{
3166	struct intel_vgpu *vgpu = workload->vgpu;
3167	unsigned long gma_head, gma_tail, gma_start, ctx_size;
3168	struct parser_exec_state s;
3169	int ring_id = workload->engine->id;
3170	struct intel_context *ce = vgpu->submission.shadow[ring_id];
3171	int ret;
3172
3173	GEM_BUG_ON(atomic_read(&ce->pin_count) < 0);
3174
3175	ctx_size = workload->engine->context_size - PAGE_SIZE;
3176
3177	/* Only ring contxt is loaded to HW for inhibit context, no need to
3178	 * scan engine context
3179	 */
3180	if (is_inhibit_context(ce))
3181		return 0;
3182
3183	gma_start = i915_ggtt_offset(ce->state) + LRC_STATE_PN*PAGE_SIZE;
3184	gma_head = 0;
3185	gma_tail = ctx_size;
3186
3187	s.buf_type = RING_BUFFER_CTX;
3188	s.buf_addr_type = GTT_BUFFER;
3189	s.vgpu = workload->vgpu;
3190	s.engine = workload->engine;
3191	s.ring_start = gma_start;
3192	s.ring_size = ctx_size;
3193	s.ring_head = gma_start + gma_head;
3194	s.ring_tail = gma_start + gma_tail;
3195	s.rb_va = ce->lrc_reg_state;
3196	s.workload = workload;
3197	s.is_ctx_wa = false;
3198	s.is_init_ctx = false;
3199
3200	/* don't scan the first RING_CTX_SIZE(0x50) dwords, as it's ring
3201	 * context
3202	 */
3203	ret = ip_gma_set(&s, gma_start + gma_head + RING_CTX_SIZE);
3204	if (ret)
3205		goto out;
3206
3207	ret = command_scan(&s, gma_head, gma_tail,
3208		gma_start, ctx_size);
3209out:
3210	if (ret)
3211		gvt_vgpu_err("scan shadow ctx error\n");
3212
3213	return ret;
3214}
3215
3216static int init_cmd_table(struct intel_gvt *gvt)
3217{
3218	unsigned int gen_type = intel_gvt_get_device_type(gvt);
3219	int i;
3220
3221	for (i = 0; i < ARRAY_SIZE(cmd_info); i++) {
3222		struct cmd_entry *e;
3223
3224		if (!(cmd_info[i].devices & gen_type))
3225			continue;
3226
3227		e = kzalloc(sizeof(*e), GFP_KERNEL);
3228		if (!e)
3229			return -ENOMEM;
3230
3231		e->info = &cmd_info[i];
3232		if (cmd_info[i].opcode == OP_MI_NOOP)
3233			mi_noop_index = i;
3234
3235		INIT_HLIST_NODE(&e->hlist);
3236		add_cmd_entry(gvt, e);
3237		gvt_dbg_cmd("add %-30s op %04x flag %x devs %02x rings %02x\n",
3238			    e->info->name, e->info->opcode, e->info->flag,
3239			    e->info->devices, e->info->rings);
3240	}
3241
3242	return 0;
3243}
3244
3245static void clean_cmd_table(struct intel_gvt *gvt)
3246{
3247	struct hlist_node *tmp;
3248	struct cmd_entry *e;
3249	int i;
3250
3251	hash_for_each_safe(gvt->cmd_table, i, tmp, e, hlist)
3252		kfree(e);
3253
3254	hash_init(gvt->cmd_table);
3255}
3256
3257void intel_gvt_clean_cmd_parser(struct intel_gvt *gvt)
3258{
3259	clean_cmd_table(gvt);
3260}
3261
3262int intel_gvt_init_cmd_parser(struct intel_gvt *gvt)
3263{
3264	int ret;
3265
3266	ret = init_cmd_table(gvt);
3267	if (ret) {
3268		intel_gvt_clean_cmd_parser(gvt);
3269		return ret;
3270	}
3271	return 0;
3272}
~/ Read-only file preview.