Linux Audio

Check our new training course

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