Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0021  * SOFTWARE.
0022  *
0023  * Authors:
0024  *    Ke Yu
0025  *    Kevin Tian <kevin.tian@intel.com>
0026  *    Zhiyuan Lv <zhiyuan.lv@intel.com>
0027  *
0028  * Contributors:
0029  *    Min He <min.he@intel.com>
0030  *    Ping Gao <ping.a.gao@intel.com>
0031  *    Tina Zhang <tina.zhang@intel.com>
0032  *    Yulei Zhang <yulei.zhang@intel.com>
0033  *    Zhi Wang <zhi.a.wang@intel.com>
0034  *
0035  */
0036 
0037 #include <linux/slab.h>
0038 
0039 #include "i915_drv.h"
0040 #include "gt/intel_engine_regs.h"
0041 #include "gt/intel_gpu_commands.h"
0042 #include "gt/intel_gt_regs.h"
0043 #include "gt/intel_lrc.h"
0044 #include "gt/intel_ring.h"
0045 #include "gt/intel_gt_requests.h"
0046 #include "gt/shmem_utils.h"
0047 #include "gvt.h"
0048 #include "i915_pvinfo.h"
0049 #include "trace.h"
0050 
0051 #include "gem/i915_gem_context.h"
0052 #include "gem/i915_gem_pm.h"
0053 #include "gt/intel_context.h"
0054 
0055 #define INVALID_OP    (~0U)
0056 
0057 #define OP_LEN_MI           9
0058 #define OP_LEN_2D           10
0059 #define OP_LEN_3D_MEDIA     16
0060 #define OP_LEN_MFX_VC       16
0061 #define OP_LEN_VEBOX        16
0062 
0063 #define CMD_TYPE(cmd)   (((cmd) >> 29) & 7)
0064 
0065 struct sub_op_bits {
0066     int hi;
0067     int low;
0068 };
0069 struct decode_info {
0070     const char *name;
0071     int op_len;
0072     int nr_sub_op;
0073     const struct sub_op_bits *sub_op;
0074 };
0075 
0076 #define   MAX_CMD_BUDGET            0x7fffffff
0077 #define   MI_WAIT_FOR_PLANE_C_FLIP_PENDING      (1<<15)
0078 #define   MI_WAIT_FOR_PLANE_B_FLIP_PENDING      (1<<9)
0079 #define   MI_WAIT_FOR_PLANE_A_FLIP_PENDING      (1<<1)
0080 
0081 #define   MI_WAIT_FOR_SPRITE_C_FLIP_PENDING      (1<<20)
0082 #define   MI_WAIT_FOR_SPRITE_B_FLIP_PENDING      (1<<10)
0083 #define   MI_WAIT_FOR_SPRITE_A_FLIP_PENDING      (1<<2)
0084 
0085 /* Render Command Map */
0086 
0087 /* MI_* command Opcode (28:23) */
0088 #define OP_MI_NOOP                          0x0
0089 #define OP_MI_SET_PREDICATE                 0x1  /* HSW+ */
0090 #define OP_MI_USER_INTERRUPT                0x2
0091 #define OP_MI_WAIT_FOR_EVENT                0x3
0092 #define OP_MI_FLUSH                         0x4
0093 #define OP_MI_ARB_CHECK                     0x5
0094 #define OP_MI_RS_CONTROL                    0x6  /* HSW+ */
0095 #define OP_MI_REPORT_HEAD                   0x7
0096 #define OP_MI_ARB_ON_OFF                    0x8
0097 #define OP_MI_URB_ATOMIC_ALLOC              0x9  /* HSW+ */
0098 #define OP_MI_BATCH_BUFFER_END              0xA
0099 #define OP_MI_SUSPEND_FLUSH                 0xB
0100 #define OP_MI_PREDICATE                     0xC  /* IVB+ */
0101 #define OP_MI_TOPOLOGY_FILTER               0xD  /* IVB+ */
0102 #define OP_MI_SET_APPID                     0xE  /* IVB+ */
0103 #define OP_MI_RS_CONTEXT                    0xF  /* HSW+ */
0104 #define OP_MI_LOAD_SCAN_LINES_INCL          0x12 /* HSW+ */
0105 #define OP_MI_DISPLAY_FLIP                  0x14
0106 #define OP_MI_SEMAPHORE_MBOX                0x16
0107 #define OP_MI_SET_CONTEXT                   0x18
0108 #define OP_MI_MATH                          0x1A
0109 #define OP_MI_URB_CLEAR                     0x19
0110 #define OP_MI_SEMAPHORE_SIGNAL          0x1B  /* BDW+ */
0111 #define OP_MI_SEMAPHORE_WAIT            0x1C  /* BDW+ */
0112 
0113 #define OP_MI_STORE_DATA_IMM                0x20
0114 #define OP_MI_STORE_DATA_INDEX              0x21
0115 #define OP_MI_LOAD_REGISTER_IMM             0x22
0116 #define OP_MI_UPDATE_GTT                    0x23
0117 #define OP_MI_STORE_REGISTER_MEM            0x24
0118 #define OP_MI_FLUSH_DW                      0x26
0119 #define OP_MI_CLFLUSH                       0x27
0120 #define OP_MI_REPORT_PERF_COUNT             0x28
0121 #define OP_MI_LOAD_REGISTER_MEM             0x29  /* HSW+ */
0122 #define OP_MI_LOAD_REGISTER_REG             0x2A  /* HSW+ */
0123 #define OP_MI_RS_STORE_DATA_IMM             0x2B  /* HSW+ */
0124 #define OP_MI_LOAD_URB_MEM                  0x2C  /* HSW+ */
0125 #define OP_MI_STORE_URM_MEM                 0x2D  /* HSW+ */
0126 #define OP_MI_2E                0x2E  /* BDW+ */
0127 #define OP_MI_2F                0x2F  /* BDW+ */
0128 #define OP_MI_BATCH_BUFFER_START            0x31
0129 
0130 /* Bit definition for dword 0 */
0131 #define _CMDBIT_BB_START_IN_PPGTT   (1UL << 8)
0132 
0133 #define OP_MI_CONDITIONAL_BATCH_BUFFER_END  0x36
0134 
0135 #define BATCH_BUFFER_ADDR_MASK ((1UL << 32) - (1U << 2))
0136 #define BATCH_BUFFER_ADDR_HIGH_MASK ((1UL << 16) - (1U))
0137 #define BATCH_BUFFER_ADR_SPACE_BIT(x)   (((x) >> 8) & 1U)
0138 #define BATCH_BUFFER_2ND_LEVEL_BIT(x)   ((x) >> 22 & 1U)
0139 
0140 /* 2D command: Opcode (28:22) */
0141 #define OP_2D(x)    ((2<<7) | x)
0142 
0143 #define OP_XY_SETUP_BLT                             OP_2D(0x1)
0144 #define OP_XY_SETUP_CLIP_BLT                        OP_2D(0x3)
0145 #define OP_XY_SETUP_MONO_PATTERN_SL_BLT             OP_2D(0x11)
0146 #define OP_XY_PIXEL_BLT                             OP_2D(0x24)
0147 #define OP_XY_SCANLINES_BLT                         OP_2D(0x25)
0148 #define OP_XY_TEXT_BLT                              OP_2D(0x26)
0149 #define OP_XY_TEXT_IMMEDIATE_BLT                    OP_2D(0x31)
0150 #define OP_XY_COLOR_BLT                             OP_2D(0x50)
0151 #define OP_XY_PAT_BLT                               OP_2D(0x51)
0152 #define OP_XY_MONO_PAT_BLT                          OP_2D(0x52)
0153 #define OP_XY_SRC_COPY_BLT                          OP_2D(0x53)
0154 #define OP_XY_MONO_SRC_COPY_BLT                     OP_2D(0x54)
0155 #define OP_XY_FULL_BLT                              OP_2D(0x55)
0156 #define OP_XY_FULL_MONO_SRC_BLT                     OP_2D(0x56)
0157 #define OP_XY_FULL_MONO_PATTERN_BLT                 OP_2D(0x57)
0158 #define OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT        OP_2D(0x58)
0159 #define OP_XY_MONO_PAT_FIXED_BLT                    OP_2D(0x59)
0160 #define OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT           OP_2D(0x71)
0161 #define OP_XY_PAT_BLT_IMMEDIATE                     OP_2D(0x72)
0162 #define OP_XY_SRC_COPY_CHROMA_BLT                   OP_2D(0x73)
0163 #define OP_XY_FULL_IMMEDIATE_PATTERN_BLT            OP_2D(0x74)
0164 #define OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT   OP_2D(0x75)
0165 #define OP_XY_PAT_CHROMA_BLT                        OP_2D(0x76)
0166 #define OP_XY_PAT_CHROMA_BLT_IMMEDIATE              OP_2D(0x77)
0167 
0168 /* 3D/Media Command: Pipeline Type(28:27) Opcode(26:24) Sub Opcode(23:16) */
0169 #define OP_3D_MEDIA(sub_type, opcode, sub_opcode) \
0170     ((3 << 13) | ((sub_type) << 11) | ((opcode) << 8) | (sub_opcode))
0171 
0172 #define OP_STATE_PREFETCH                       OP_3D_MEDIA(0x0, 0x0, 0x03)
0173 
0174 #define OP_STATE_BASE_ADDRESS                   OP_3D_MEDIA(0x0, 0x1, 0x01)
0175 #define OP_STATE_SIP                            OP_3D_MEDIA(0x0, 0x1, 0x02)
0176 #define OP_3D_MEDIA_0_1_4           OP_3D_MEDIA(0x0, 0x1, 0x04)
0177 #define OP_SWTESS_BASE_ADDRESS          OP_3D_MEDIA(0x0, 0x1, 0x03)
0178 
0179 #define OP_3DSTATE_VF_STATISTICS_GM45           OP_3D_MEDIA(0x1, 0x0, 0x0B)
0180 
0181 #define OP_PIPELINE_SELECT                      OP_3D_MEDIA(0x1, 0x1, 0x04)
0182 
0183 #define OP_MEDIA_VFE_STATE                      OP_3D_MEDIA(0x2, 0x0, 0x0)
0184 #define OP_MEDIA_CURBE_LOAD                     OP_3D_MEDIA(0x2, 0x0, 0x1)
0185 #define OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD      OP_3D_MEDIA(0x2, 0x0, 0x2)
0186 #define OP_MEDIA_GATEWAY_STATE                  OP_3D_MEDIA(0x2, 0x0, 0x3)
0187 #define OP_MEDIA_STATE_FLUSH                    OP_3D_MEDIA(0x2, 0x0, 0x4)
0188 #define OP_MEDIA_POOL_STATE                     OP_3D_MEDIA(0x2, 0x0, 0x5)
0189 
0190 #define OP_MEDIA_OBJECT                         OP_3D_MEDIA(0x2, 0x1, 0x0)
0191 #define OP_MEDIA_OBJECT_PRT                     OP_3D_MEDIA(0x2, 0x1, 0x2)
0192 #define OP_MEDIA_OBJECT_WALKER                  OP_3D_MEDIA(0x2, 0x1, 0x3)
0193 #define OP_GPGPU_WALKER                         OP_3D_MEDIA(0x2, 0x1, 0x5)
0194 
0195 #define OP_3DSTATE_CLEAR_PARAMS                 OP_3D_MEDIA(0x3, 0x0, 0x04) /* IVB+ */
0196 #define OP_3DSTATE_DEPTH_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x05) /* IVB+ */
0197 #define OP_3DSTATE_STENCIL_BUFFER               OP_3D_MEDIA(0x3, 0x0, 0x06) /* IVB+ */
0198 #define OP_3DSTATE_HIER_DEPTH_BUFFER            OP_3D_MEDIA(0x3, 0x0, 0x07) /* IVB+ */
0199 #define OP_3DSTATE_VERTEX_BUFFERS               OP_3D_MEDIA(0x3, 0x0, 0x08)
0200 #define OP_3DSTATE_VERTEX_ELEMENTS              OP_3D_MEDIA(0x3, 0x0, 0x09)
0201 #define OP_3DSTATE_INDEX_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x0A)
0202 #define OP_3DSTATE_VF_STATISTICS                OP_3D_MEDIA(0x3, 0x0, 0x0B)
0203 #define OP_3DSTATE_VF                           OP_3D_MEDIA(0x3, 0x0, 0x0C)  /* HSW+ */
0204 #define OP_3DSTATE_CC_STATE_POINTERS            OP_3D_MEDIA(0x3, 0x0, 0x0E)
0205 #define OP_3DSTATE_SCISSOR_STATE_POINTERS       OP_3D_MEDIA(0x3, 0x0, 0x0F)
0206 #define OP_3DSTATE_VS                           OP_3D_MEDIA(0x3, 0x0, 0x10)
0207 #define OP_3DSTATE_GS                           OP_3D_MEDIA(0x3, 0x0, 0x11)
0208 #define OP_3DSTATE_CLIP                         OP_3D_MEDIA(0x3, 0x0, 0x12)
0209 #define OP_3DSTATE_SF                           OP_3D_MEDIA(0x3, 0x0, 0x13)
0210 #define OP_3DSTATE_WM                           OP_3D_MEDIA(0x3, 0x0, 0x14)
0211 #define OP_3DSTATE_CONSTANT_VS                  OP_3D_MEDIA(0x3, 0x0, 0x15)
0212 #define OP_3DSTATE_CONSTANT_GS                  OP_3D_MEDIA(0x3, 0x0, 0x16)
0213 #define OP_3DSTATE_CONSTANT_PS                  OP_3D_MEDIA(0x3, 0x0, 0x17)
0214 #define OP_3DSTATE_SAMPLE_MASK                  OP_3D_MEDIA(0x3, 0x0, 0x18)
0215 #define OP_3DSTATE_CONSTANT_HS                  OP_3D_MEDIA(0x3, 0x0, 0x19) /* IVB+ */
0216 #define OP_3DSTATE_CONSTANT_DS                  OP_3D_MEDIA(0x3, 0x0, 0x1A) /* IVB+ */
0217 #define OP_3DSTATE_HS                           OP_3D_MEDIA(0x3, 0x0, 0x1B) /* IVB+ */
0218 #define OP_3DSTATE_TE                           OP_3D_MEDIA(0x3, 0x0, 0x1C) /* IVB+ */
0219 #define OP_3DSTATE_DS                           OP_3D_MEDIA(0x3, 0x0, 0x1D) /* IVB+ */
0220 #define OP_3DSTATE_STREAMOUT                    OP_3D_MEDIA(0x3, 0x0, 0x1E) /* IVB+ */
0221 #define OP_3DSTATE_SBE                          OP_3D_MEDIA(0x3, 0x0, 0x1F) /* IVB+ */
0222 #define OP_3DSTATE_PS                           OP_3D_MEDIA(0x3, 0x0, 0x20) /* IVB+ */
0223 #define OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP OP_3D_MEDIA(0x3, 0x0, 0x21) /* IVB+ */
0224 #define OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC   OP_3D_MEDIA(0x3, 0x0, 0x23) /* IVB+ */
0225 #define OP_3DSTATE_BLEND_STATE_POINTERS         OP_3D_MEDIA(0x3, 0x0, 0x24) /* IVB+ */
0226 #define OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS OP_3D_MEDIA(0x3, 0x0, 0x25) /* IVB+ */
0227 #define OP_3DSTATE_BINDING_TABLE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x26) /* IVB+ */
0228 #define OP_3DSTATE_BINDING_TABLE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x27) /* IVB+ */
0229 #define OP_3DSTATE_BINDING_TABLE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x28) /* IVB+ */
0230 #define OP_3DSTATE_BINDING_TABLE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x29) /* IVB+ */
0231 #define OP_3DSTATE_BINDING_TABLE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2A) /* IVB+ */
0232 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x2B) /* IVB+ */
0233 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x2C) /* IVB+ */
0234 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x2D) /* IVB+ */
0235 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x2E) /* IVB+ */
0236 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2F) /* IVB+ */
0237 #define OP_3DSTATE_URB_VS                       OP_3D_MEDIA(0x3, 0x0, 0x30) /* IVB+ */
0238 #define OP_3DSTATE_URB_HS                       OP_3D_MEDIA(0x3, 0x0, 0x31) /* IVB+ */
0239 #define OP_3DSTATE_URB_DS                       OP_3D_MEDIA(0x3, 0x0, 0x32) /* IVB+ */
0240 #define OP_3DSTATE_URB_GS                       OP_3D_MEDIA(0x3, 0x0, 0x33) /* IVB+ */
0241 #define OP_3DSTATE_GATHER_CONSTANT_VS           OP_3D_MEDIA(0x3, 0x0, 0x34) /* HSW+ */
0242 #define OP_3DSTATE_GATHER_CONSTANT_GS           OP_3D_MEDIA(0x3, 0x0, 0x35) /* HSW+ */
0243 #define OP_3DSTATE_GATHER_CONSTANT_HS           OP_3D_MEDIA(0x3, 0x0, 0x36) /* HSW+ */
0244 #define OP_3DSTATE_GATHER_CONSTANT_DS           OP_3D_MEDIA(0x3, 0x0, 0x37) /* HSW+ */
0245 #define OP_3DSTATE_GATHER_CONSTANT_PS           OP_3D_MEDIA(0x3, 0x0, 0x38) /* HSW+ */
0246 #define OP_3DSTATE_DX9_CONSTANTF_VS             OP_3D_MEDIA(0x3, 0x0, 0x39) /* HSW+ */
0247 #define OP_3DSTATE_DX9_CONSTANTF_PS             OP_3D_MEDIA(0x3, 0x0, 0x3A) /* HSW+ */
0248 #define OP_3DSTATE_DX9_CONSTANTI_VS             OP_3D_MEDIA(0x3, 0x0, 0x3B) /* HSW+ */
0249 #define OP_3DSTATE_DX9_CONSTANTI_PS             OP_3D_MEDIA(0x3, 0x0, 0x3C) /* HSW+ */
0250 #define OP_3DSTATE_DX9_CONSTANTB_VS             OP_3D_MEDIA(0x3, 0x0, 0x3D) /* HSW+ */
0251 #define OP_3DSTATE_DX9_CONSTANTB_PS             OP_3D_MEDIA(0x3, 0x0, 0x3E) /* HSW+ */
0252 #define OP_3DSTATE_DX9_LOCAL_VALID_VS           OP_3D_MEDIA(0x3, 0x0, 0x3F) /* HSW+ */
0253 #define OP_3DSTATE_DX9_LOCAL_VALID_PS           OP_3D_MEDIA(0x3, 0x0, 0x40) /* HSW+ */
0254 #define OP_3DSTATE_DX9_GENERATE_ACTIVE_VS       OP_3D_MEDIA(0x3, 0x0, 0x41) /* HSW+ */
0255 #define OP_3DSTATE_DX9_GENERATE_ACTIVE_PS       OP_3D_MEDIA(0x3, 0x0, 0x42) /* HSW+ */
0256 #define OP_3DSTATE_BINDING_TABLE_EDIT_VS        OP_3D_MEDIA(0x3, 0x0, 0x43) /* HSW+ */
0257 #define OP_3DSTATE_BINDING_TABLE_EDIT_GS        OP_3D_MEDIA(0x3, 0x0, 0x44) /* HSW+ */
0258 #define OP_3DSTATE_BINDING_TABLE_EDIT_HS        OP_3D_MEDIA(0x3, 0x0, 0x45) /* HSW+ */
0259 #define OP_3DSTATE_BINDING_TABLE_EDIT_DS        OP_3D_MEDIA(0x3, 0x0, 0x46) /* HSW+ */
0260 #define OP_3DSTATE_BINDING_TABLE_EDIT_PS        OP_3D_MEDIA(0x3, 0x0, 0x47) /* HSW+ */
0261 
0262 #define OP_3DSTATE_VF_INSTANCING        OP_3D_MEDIA(0x3, 0x0, 0x49) /* BDW+ */
0263 #define OP_3DSTATE_VF_SGVS              OP_3D_MEDIA(0x3, 0x0, 0x4A) /* BDW+ */
0264 #define OP_3DSTATE_VF_TOPOLOGY          OP_3D_MEDIA(0x3, 0x0, 0x4B) /* BDW+ */
0265 #define OP_3DSTATE_WM_CHROMAKEY         OP_3D_MEDIA(0x3, 0x0, 0x4C) /* BDW+ */
0266 #define OP_3DSTATE_PS_BLEND             OP_3D_MEDIA(0x3, 0x0, 0x4D) /* BDW+ */
0267 #define OP_3DSTATE_WM_DEPTH_STENCIL         OP_3D_MEDIA(0x3, 0x0, 0x4E) /* BDW+ */
0268 #define OP_3DSTATE_PS_EXTRA             OP_3D_MEDIA(0x3, 0x0, 0x4F) /* BDW+ */
0269 #define OP_3DSTATE_RASTER               OP_3D_MEDIA(0x3, 0x0, 0x50) /* BDW+ */
0270 #define OP_3DSTATE_SBE_SWIZ             OP_3D_MEDIA(0x3, 0x0, 0x51) /* BDW+ */
0271 #define OP_3DSTATE_WM_HZ_OP             OP_3D_MEDIA(0x3, 0x0, 0x52) /* BDW+ */
0272 #define OP_3DSTATE_COMPONENT_PACKING        OP_3D_MEDIA(0x3, 0x0, 0x55) /* SKL+ */
0273 
0274 #define OP_3DSTATE_DRAWING_RECTANGLE            OP_3D_MEDIA(0x3, 0x1, 0x00)
0275 #define OP_3DSTATE_SAMPLER_PALETTE_LOAD0        OP_3D_MEDIA(0x3, 0x1, 0x02)
0276 #define OP_3DSTATE_CHROMA_KEY                   OP_3D_MEDIA(0x3, 0x1, 0x04)
0277 #define OP_SNB_3DSTATE_DEPTH_BUFFER             OP_3D_MEDIA(0x3, 0x1, 0x05)
0278 #define OP_3DSTATE_POLY_STIPPLE_OFFSET          OP_3D_MEDIA(0x3, 0x1, 0x06)
0279 #define OP_3DSTATE_POLY_STIPPLE_PATTERN         OP_3D_MEDIA(0x3, 0x1, 0x07)
0280 #define OP_3DSTATE_LINE_STIPPLE                 OP_3D_MEDIA(0x3, 0x1, 0x08)
0281 #define OP_3DSTATE_AA_LINE_PARAMS               OP_3D_MEDIA(0x3, 0x1, 0x0A)
0282 #define OP_3DSTATE_GS_SVB_INDEX                 OP_3D_MEDIA(0x3, 0x1, 0x0B)
0283 #define OP_3DSTATE_SAMPLER_PALETTE_LOAD1        OP_3D_MEDIA(0x3, 0x1, 0x0C)
0284 #define OP_3DSTATE_MULTISAMPLE_BDW      OP_3D_MEDIA(0x3, 0x0, 0x0D)
0285 #define OP_SNB_3DSTATE_STENCIL_BUFFER           OP_3D_MEDIA(0x3, 0x1, 0x0E)
0286 #define OP_SNB_3DSTATE_HIER_DEPTH_BUFFER        OP_3D_MEDIA(0x3, 0x1, 0x0F)
0287 #define OP_SNB_3DSTATE_CLEAR_PARAMS             OP_3D_MEDIA(0x3, 0x1, 0x10)
0288 #define OP_3DSTATE_MONOFILTER_SIZE              OP_3D_MEDIA(0x3, 0x1, 0x11)
0289 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS       OP_3D_MEDIA(0x3, 0x1, 0x12) /* IVB+ */
0290 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS       OP_3D_MEDIA(0x3, 0x1, 0x13) /* IVB+ */
0291 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS       OP_3D_MEDIA(0x3, 0x1, 0x14) /* IVB+ */
0292 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS       OP_3D_MEDIA(0x3, 0x1, 0x15) /* IVB+ */
0293 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS       OP_3D_MEDIA(0x3, 0x1, 0x16) /* IVB+ */
0294 #define OP_3DSTATE_SO_DECL_LIST                 OP_3D_MEDIA(0x3, 0x1, 0x17)
0295 #define OP_3DSTATE_SO_BUFFER                    OP_3D_MEDIA(0x3, 0x1, 0x18)
0296 #define OP_3DSTATE_BINDING_TABLE_POOL_ALLOC     OP_3D_MEDIA(0x3, 0x1, 0x19) /* HSW+ */
0297 #define OP_3DSTATE_GATHER_POOL_ALLOC            OP_3D_MEDIA(0x3, 0x1, 0x1A) /* HSW+ */
0298 #define OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC OP_3D_MEDIA(0x3, 0x1, 0x1B) /* HSW+ */
0299 #define OP_3DSTATE_SAMPLE_PATTERN               OP_3D_MEDIA(0x3, 0x1, 0x1C)
0300 #define OP_PIPE_CONTROL                         OP_3D_MEDIA(0x3, 0x2, 0x00)
0301 #define OP_3DPRIMITIVE                          OP_3D_MEDIA(0x3, 0x3, 0x00)
0302 
0303 /* VCCP Command Parser */
0304 
0305 /*
0306  * Below MFX and VBE cmd definition is from vaapi intel driver project (BSD License)
0307  * git://anongit.freedesktop.org/vaapi/intel-driver
0308  * src/i965_defines.h
0309  *
0310  */
0311 
0312 #define OP_MFX(pipeline, op, sub_opa, sub_opb)     \
0313     (3 << 13 | \
0314      (pipeline) << 11 | \
0315      (op) << 8 | \
0316      (sub_opa) << 5 | \
0317      (sub_opb))
0318 
0319 #define OP_MFX_PIPE_MODE_SELECT                    OP_MFX(2, 0, 0, 0)  /* ALL */
0320 #define OP_MFX_SURFACE_STATE                       OP_MFX(2, 0, 0, 1)  /* ALL */
0321 #define OP_MFX_PIPE_BUF_ADDR_STATE                 OP_MFX(2, 0, 0, 2)  /* ALL */
0322 #define OP_MFX_IND_OBJ_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 3)  /* ALL */
0323 #define OP_MFX_BSP_BUF_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 4)  /* ALL */
0324 #define OP_2_0_0_5                                 OP_MFX(2, 0, 0, 5)  /* ALL */
0325 #define OP_MFX_STATE_POINTER                       OP_MFX(2, 0, 0, 6)  /* ALL */
0326 #define OP_MFX_QM_STATE                            OP_MFX(2, 0, 0, 7)  /* IVB+ */
0327 #define OP_MFX_FQM_STATE                           OP_MFX(2, 0, 0, 8)  /* IVB+ */
0328 #define OP_MFX_PAK_INSERT_OBJECT                   OP_MFX(2, 0, 2, 8)  /* IVB+ */
0329 #define OP_MFX_STITCH_OBJECT                       OP_MFX(2, 0, 2, 0xA)  /* IVB+ */
0330 
0331 #define OP_MFD_IT_OBJECT                           OP_MFX(2, 0, 1, 9) /* ALL */
0332 
0333 #define OP_MFX_WAIT                                OP_MFX(1, 0, 0, 0) /* IVB+ */
0334 #define OP_MFX_AVC_IMG_STATE                       OP_MFX(2, 1, 0, 0) /* ALL */
0335 #define OP_MFX_AVC_QM_STATE                        OP_MFX(2, 1, 0, 1) /* ALL */
0336 #define OP_MFX_AVC_DIRECTMODE_STATE                OP_MFX(2, 1, 0, 2) /* ALL */
0337 #define OP_MFX_AVC_SLICE_STATE                     OP_MFX(2, 1, 0, 3) /* ALL */
0338 #define OP_MFX_AVC_REF_IDX_STATE                   OP_MFX(2, 1, 0, 4) /* ALL */
0339 #define OP_MFX_AVC_WEIGHTOFFSET_STATE              OP_MFX(2, 1, 0, 5) /* ALL */
0340 #define OP_MFD_AVC_PICID_STATE                     OP_MFX(2, 1, 1, 5) /* HSW+ */
0341 #define OP_MFD_AVC_DPB_STATE               OP_MFX(2, 1, 1, 6) /* IVB+ */
0342 #define OP_MFD_AVC_SLICEADDR                       OP_MFX(2, 1, 1, 7) /* IVB+ */
0343 #define OP_MFD_AVC_BSD_OBJECT                      OP_MFX(2, 1, 1, 8) /* ALL */
0344 #define OP_MFC_AVC_PAK_OBJECT                      OP_MFX(2, 1, 2, 9) /* ALL */
0345 
0346 #define OP_MFX_VC1_PRED_PIPE_STATE                 OP_MFX(2, 2, 0, 1) /* ALL */
0347 #define OP_MFX_VC1_DIRECTMODE_STATE                OP_MFX(2, 2, 0, 2) /* ALL */
0348 #define OP_MFD_VC1_SHORT_PIC_STATE                 OP_MFX(2, 2, 1, 0) /* IVB+ */
0349 #define OP_MFD_VC1_LONG_PIC_STATE                  OP_MFX(2, 2, 1, 1) /* IVB+ */
0350 #define OP_MFD_VC1_BSD_OBJECT                      OP_MFX(2, 2, 1, 8) /* ALL */
0351 
0352 #define OP_MFX_MPEG2_PIC_STATE                     OP_MFX(2, 3, 0, 0) /* ALL */
0353 #define OP_MFX_MPEG2_QM_STATE                      OP_MFX(2, 3, 0, 1) /* ALL */
0354 #define OP_MFD_MPEG2_BSD_OBJECT                    OP_MFX(2, 3, 1, 8) /* ALL */
0355 #define OP_MFC_MPEG2_SLICEGROUP_STATE              OP_MFX(2, 3, 2, 3) /* ALL */
0356 #define OP_MFC_MPEG2_PAK_OBJECT                    OP_MFX(2, 3, 2, 9) /* ALL */
0357 
0358 #define OP_MFX_2_6_0_0                             OP_MFX(2, 6, 0, 0) /* IVB+ */
0359 #define OP_MFX_2_6_0_8                             OP_MFX(2, 6, 0, 8) /* IVB+ */
0360 #define OP_MFX_2_6_0_9                             OP_MFX(2, 6, 0, 9) /* IVB+ */
0361 
0362 #define OP_MFX_JPEG_PIC_STATE                      OP_MFX(2, 7, 0, 0)
0363 #define OP_MFX_JPEG_HUFF_TABLE_STATE               OP_MFX(2, 7, 0, 2)
0364 #define OP_MFD_JPEG_BSD_OBJECT                     OP_MFX(2, 7, 1, 8)
0365 
0366 #define OP_VEB(pipeline, op, sub_opa, sub_opb) \
0367     (3 << 13 | \
0368      (pipeline) << 11 | \
0369      (op) << 8 | \
0370      (sub_opa) << 5 | \
0371      (sub_opb))
0372 
0373 #define OP_VEB_SURFACE_STATE                       OP_VEB(2, 4, 0, 0)
0374 #define OP_VEB_STATE                               OP_VEB(2, 4, 0, 2)
0375 #define OP_VEB_DNDI_IECP_STATE                     OP_VEB(2, 4, 0, 3)
0376 
0377 struct parser_exec_state;
0378 
0379 typedef int (*parser_cmd_handler)(struct parser_exec_state *s);
0380 
0381 #define GVT_CMD_HASH_BITS   7
0382 
0383 /* which DWords need address fix */
0384 #define ADDR_FIX_1(x1)          (1 << (x1))
0385 #define ADDR_FIX_2(x1, x2)      (ADDR_FIX_1(x1) | ADDR_FIX_1(x2))
0386 #define ADDR_FIX_3(x1, x2, x3)      (ADDR_FIX_1(x1) | ADDR_FIX_2(x2, x3))
0387 #define ADDR_FIX_4(x1, x2, x3, x4)  (ADDR_FIX_1(x1) | ADDR_FIX_3(x2, x3, x4))
0388 #define ADDR_FIX_5(x1, x2, x3, x4, x5)  (ADDR_FIX_1(x1) | ADDR_FIX_4(x2, x3, x4, x5))
0389 
0390 #define DWORD_FIELD(dword, end, start) \
0391     FIELD_GET(GENMASK(end, start), cmd_val(s, dword))
0392 
0393 #define OP_LENGTH_BIAS 2
0394 #define CMD_LEN(value)  (value + OP_LENGTH_BIAS)
0395 
0396 static int gvt_check_valid_cmd_length(int len, int valid_len)
0397 {
0398     if (valid_len != len) {
0399         gvt_err("len is not valid:  len=%u  valid_len=%u\n",
0400             len, valid_len);
0401         return -EFAULT;
0402     }
0403     return 0;
0404 }
0405 
0406 struct cmd_info {
0407     const char *name;
0408     u32 opcode;
0409 
0410 #define F_LEN_MASK  3U
0411 #define F_LEN_CONST  1U
0412 #define F_LEN_VAR    0U
0413 /* value is const although LEN maybe variable */
0414 #define F_LEN_VAR_FIXED    (1<<1)
0415 
0416 /*
0417  * command has its own ip advance logic
0418  * e.g. MI_BATCH_START, MI_BATCH_END
0419  */
0420 #define F_IP_ADVANCE_CUSTOM (1<<2)
0421     u32 flag;
0422 
0423 #define R_RCS   BIT(RCS0)
0424 #define R_VCS1  BIT(VCS0)
0425 #define R_VCS2  BIT(VCS1)
0426 #define R_VCS   (R_VCS1 | R_VCS2)
0427 #define R_BCS   BIT(BCS0)
0428 #define R_VECS  BIT(VECS0)
0429 #define R_ALL (R_RCS | R_VCS | R_BCS | R_VECS)
0430     /* rings that support this cmd: BLT/RCS/VCS/VECS */
0431     intel_engine_mask_t rings;
0432 
0433     /* devices that support this cmd: SNB/IVB/HSW/... */
0434     u16 devices;
0435 
0436     /* which DWords are address that need fix up.
0437      * bit 0 means a 32-bit non address operand in command
0438      * bit 1 means address operand, which could be 32-bit
0439      * or 64-bit depending on different architectures.(
0440      * defined by "gmadr_bytes_in_cmd" in intel_gvt.
0441      * No matter the address length, each address only takes
0442      * one bit in the bitmap.
0443      */
0444     u16 addr_bitmap;
0445 
0446     /* flag == F_LEN_CONST : command length
0447      * flag == F_LEN_VAR : length bias bits
0448      * Note: length is in DWord
0449      */
0450     u32 len;
0451 
0452     parser_cmd_handler handler;
0453 
0454     /* valid length in DWord */
0455     u32 valid_len;
0456 };
0457 
0458 struct cmd_entry {
0459     struct hlist_node hlist;
0460     const struct cmd_info *info;
0461 };
0462 
0463 enum {
0464     RING_BUFFER_INSTRUCTION,
0465     BATCH_BUFFER_INSTRUCTION,
0466     BATCH_BUFFER_2ND_LEVEL,
0467     RING_BUFFER_CTX,
0468 };
0469 
0470 enum {
0471     GTT_BUFFER,
0472     PPGTT_BUFFER
0473 };
0474 
0475 struct parser_exec_state {
0476     struct intel_vgpu *vgpu;
0477     const struct intel_engine_cs *engine;
0478 
0479     int buf_type;
0480 
0481     /* batch buffer address type */
0482     int buf_addr_type;
0483 
0484     /* graphics memory address of ring buffer start */
0485     unsigned long ring_start;
0486     unsigned long ring_size;
0487     unsigned long ring_head;
0488     unsigned long ring_tail;
0489 
0490     /* instruction graphics memory address */
0491     unsigned long ip_gma;
0492 
0493     /* mapped va of the instr_gma */
0494     void *ip_va;
0495     void *rb_va;
0496 
0497     void *ret_bb_va;
0498     /* next instruction when return from  batch buffer to ring buffer */
0499     unsigned long ret_ip_gma_ring;
0500 
0501     /* next instruction when return from 2nd batch buffer to batch buffer */
0502     unsigned long ret_ip_gma_bb;
0503 
0504     /* batch buffer address type (GTT or PPGTT)
0505      * used when ret from 2nd level batch buffer
0506      */
0507     int saved_buf_addr_type;
0508     bool is_ctx_wa;
0509     bool is_init_ctx;
0510 
0511     const struct cmd_info *info;
0512 
0513     struct intel_vgpu_workload *workload;
0514 };
0515 
0516 #define gmadr_dw_number(s)  \
0517     (s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
0518 
0519 static unsigned long bypass_scan_mask = 0;
0520 
0521 /* ring ALL, type = 0 */
0522 static const struct sub_op_bits sub_op_mi[] = {
0523     {31, 29},
0524     {28, 23},
0525 };
0526 
0527 static const struct decode_info decode_info_mi = {
0528     "MI",
0529     OP_LEN_MI,
0530     ARRAY_SIZE(sub_op_mi),
0531     sub_op_mi,
0532 };
0533 
0534 /* ring RCS, command type 2 */
0535 static const struct sub_op_bits sub_op_2d[] = {
0536     {31, 29},
0537     {28, 22},
0538 };
0539 
0540 static const struct decode_info decode_info_2d = {
0541     "2D",
0542     OP_LEN_2D,
0543     ARRAY_SIZE(sub_op_2d),
0544     sub_op_2d,
0545 };
0546 
0547 /* ring RCS, command type 3 */
0548 static const struct sub_op_bits sub_op_3d_media[] = {
0549     {31, 29},
0550     {28, 27},
0551     {26, 24},
0552     {23, 16},
0553 };
0554 
0555 static const struct decode_info decode_info_3d_media = {
0556     "3D_Media",
0557     OP_LEN_3D_MEDIA,
0558     ARRAY_SIZE(sub_op_3d_media),
0559     sub_op_3d_media,
0560 };
0561 
0562 /* ring VCS, command type 3 */
0563 static const struct sub_op_bits sub_op_mfx_vc[] = {
0564     {31, 29},
0565     {28, 27},
0566     {26, 24},
0567     {23, 21},
0568     {20, 16},
0569 };
0570 
0571 static const struct decode_info decode_info_mfx_vc = {
0572     "MFX_VC",
0573     OP_LEN_MFX_VC,
0574     ARRAY_SIZE(sub_op_mfx_vc),
0575     sub_op_mfx_vc,
0576 };
0577 
0578 /* ring VECS, command type 3 */
0579 static const struct sub_op_bits sub_op_vebox[] = {
0580     {31, 29},
0581     {28, 27},
0582     {26, 24},
0583     {23, 21},
0584     {20, 16},
0585 };
0586 
0587 static const struct decode_info decode_info_vebox = {
0588     "VEBOX",
0589     OP_LEN_VEBOX,
0590     ARRAY_SIZE(sub_op_vebox),
0591     sub_op_vebox,
0592 };
0593 
0594 static const struct decode_info *ring_decode_info[I915_NUM_ENGINES][8] = {
0595     [RCS0] = {
0596         &decode_info_mi,
0597         NULL,
0598         NULL,
0599         &decode_info_3d_media,
0600         NULL,
0601         NULL,
0602         NULL,
0603         NULL,
0604     },
0605 
0606     [VCS0] = {
0607         &decode_info_mi,
0608         NULL,
0609         NULL,
0610         &decode_info_mfx_vc,
0611         NULL,
0612         NULL,
0613         NULL,
0614         NULL,
0615     },
0616 
0617     [BCS0] = {
0618         &decode_info_mi,
0619         NULL,
0620         &decode_info_2d,
0621         NULL,
0622         NULL,
0623         NULL,
0624         NULL,
0625         NULL,
0626     },
0627 
0628     [VECS0] = {
0629         &decode_info_mi,
0630         NULL,
0631         NULL,
0632         &decode_info_vebox,
0633         NULL,
0634         NULL,
0635         NULL,
0636         NULL,
0637     },
0638 
0639     [VCS1] = {
0640         &decode_info_mi,
0641         NULL,
0642         NULL,
0643         &decode_info_mfx_vc,
0644         NULL,
0645         NULL,
0646         NULL,
0647         NULL,
0648     },
0649 };
0650 
0651 static inline u32 get_opcode(u32 cmd, const struct intel_engine_cs *engine)
0652 {
0653     const struct decode_info *d_info;
0654 
0655     d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
0656     if (d_info == NULL)
0657         return INVALID_OP;
0658 
0659     return cmd >> (32 - d_info->op_len);
0660 }
0661 
0662 static inline const struct cmd_info *
0663 find_cmd_entry(struct intel_gvt *gvt, unsigned int opcode,
0664            const struct intel_engine_cs *engine)
0665 {
0666     struct cmd_entry *e;
0667 
0668     hash_for_each_possible(gvt->cmd_table, e, hlist, opcode) {
0669         if (opcode == e->info->opcode &&
0670             e->info->rings & engine->mask)
0671             return e->info;
0672     }
0673     return NULL;
0674 }
0675 
0676 static inline const struct cmd_info *
0677 get_cmd_info(struct intel_gvt *gvt, u32 cmd,
0678          const struct intel_engine_cs *engine)
0679 {
0680     u32 opcode;
0681 
0682     opcode = get_opcode(cmd, engine);
0683     if (opcode == INVALID_OP)
0684         return NULL;
0685 
0686     return find_cmd_entry(gvt, opcode, engine);
0687 }
0688 
0689 static inline u32 sub_op_val(u32 cmd, u32 hi, u32 low)
0690 {
0691     return (cmd >> low) & ((1U << (hi - low + 1)) - 1);
0692 }
0693 
0694 static inline void print_opcode(u32 cmd, const struct intel_engine_cs *engine)
0695 {
0696     const struct decode_info *d_info;
0697     int i;
0698 
0699     d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
0700     if (d_info == NULL)
0701         return;
0702 
0703     gvt_dbg_cmd("opcode=0x%x %s sub_ops:",
0704             cmd >> (32 - d_info->op_len), d_info->name);
0705 
0706     for (i = 0; i < d_info->nr_sub_op; i++)
0707         pr_err("0x%x ", sub_op_val(cmd, d_info->sub_op[i].hi,
0708                     d_info->sub_op[i].low));
0709 
0710     pr_err("\n");
0711 }
0712 
0713 static inline u32 *cmd_ptr(struct parser_exec_state *s, int index)
0714 {
0715     return s->ip_va + (index << 2);
0716 }
0717 
0718 static inline u32 cmd_val(struct parser_exec_state *s, int index)
0719 {
0720     return *cmd_ptr(s, index);
0721 }
0722 
0723 static inline bool is_init_ctx(struct parser_exec_state *s)
0724 {
0725     return (s->buf_type == RING_BUFFER_CTX && s->is_init_ctx);
0726 }
0727 
0728 static void parser_exec_state_dump(struct parser_exec_state *s)
0729 {
0730     int cnt = 0;
0731     int i;
0732 
0733     gvt_dbg_cmd("  vgpu%d RING%s: ring_start(%08lx) ring_end(%08lx)"
0734             " ring_head(%08lx) ring_tail(%08lx)\n",
0735             s->vgpu->id, s->engine->name,
0736             s->ring_start, s->ring_start + s->ring_size,
0737             s->ring_head, s->ring_tail);
0738 
0739     gvt_dbg_cmd("  %s %s ip_gma(%08lx) ",
0740             s->buf_type == RING_BUFFER_INSTRUCTION ?
0741             "RING_BUFFER" : ((s->buf_type == RING_BUFFER_CTX) ?
0742                 "CTX_BUFFER" : "BATCH_BUFFER"),
0743             s->buf_addr_type == GTT_BUFFER ?
0744             "GTT" : "PPGTT", s->ip_gma);
0745 
0746     if (s->ip_va == NULL) {
0747         gvt_dbg_cmd(" ip_va(NULL)");
0748         return;
0749     }
0750 
0751     gvt_dbg_cmd("  ip_va=%p: %08x %08x %08x %08x\n",
0752             s->ip_va, cmd_val(s, 0), cmd_val(s, 1),
0753             cmd_val(s, 2), cmd_val(s, 3));
0754 
0755     print_opcode(cmd_val(s, 0), s->engine);
0756 
0757     s->ip_va = (u32 *)((((u64)s->ip_va) >> 12) << 12);
0758 
0759     while (cnt < 1024) {
0760         gvt_dbg_cmd("ip_va=%p: ", s->ip_va);
0761         for (i = 0; i < 8; i++)
0762             gvt_dbg_cmd("%08x ", cmd_val(s, i));
0763         gvt_dbg_cmd("\n");
0764 
0765         s->ip_va += 8 * sizeof(u32);
0766         cnt += 8;
0767     }
0768 }
0769 
0770 static inline void update_ip_va(struct parser_exec_state *s)
0771 {
0772     unsigned long len = 0;
0773 
0774     if (WARN_ON(s->ring_head == s->ring_tail))
0775         return;
0776 
0777     if (s->buf_type == RING_BUFFER_INSTRUCTION ||
0778             s->buf_type == RING_BUFFER_CTX) {
0779         unsigned long ring_top = s->ring_start + s->ring_size;
0780 
0781         if (s->ring_head > s->ring_tail) {
0782             if (s->ip_gma >= s->ring_head && s->ip_gma < ring_top)
0783                 len = (s->ip_gma - s->ring_head);
0784             else if (s->ip_gma >= s->ring_start &&
0785                     s->ip_gma <= s->ring_tail)
0786                 len = (ring_top - s->ring_head) +
0787                     (s->ip_gma - s->ring_start);
0788         } else
0789             len = (s->ip_gma - s->ring_head);
0790 
0791         s->ip_va = s->rb_va + len;
0792     } else {/* shadow batch buffer */
0793         s->ip_va = s->ret_bb_va;
0794     }
0795 }
0796 
0797 static inline int ip_gma_set(struct parser_exec_state *s,
0798         unsigned long ip_gma)
0799 {
0800     WARN_ON(!IS_ALIGNED(ip_gma, 4));
0801 
0802     s->ip_gma = ip_gma;
0803     update_ip_va(s);
0804     return 0;
0805 }
0806 
0807 static inline int ip_gma_advance(struct parser_exec_state *s,
0808         unsigned int dw_len)
0809 {
0810     s->ip_gma += (dw_len << 2);
0811 
0812     if (s->buf_type == RING_BUFFER_INSTRUCTION) {
0813         if (s->ip_gma >= s->ring_start + s->ring_size)
0814             s->ip_gma -= s->ring_size;
0815         update_ip_va(s);
0816     } else {
0817         s->ip_va += (dw_len << 2);
0818     }
0819 
0820     return 0;
0821 }
0822 
0823 static inline int get_cmd_length(const struct cmd_info *info, u32 cmd)
0824 {
0825     if ((info->flag & F_LEN_MASK) == F_LEN_CONST)
0826         return info->len;
0827     else
0828         return (cmd & ((1U << info->len) - 1)) + 2;
0829     return 0;
0830 }
0831 
0832 static inline int cmd_length(struct parser_exec_state *s)
0833 {
0834     return get_cmd_length(s->info, cmd_val(s, 0));
0835 }
0836 
0837 /* do not remove this, some platform may need clflush here */
0838 #define patch_value(s, addr, val) do { \
0839     *addr = val; \
0840 } while (0)
0841 
0842 static inline bool is_mocs_mmio(unsigned int offset)
0843 {
0844     return ((offset >= 0xc800) && (offset <= 0xcff8)) ||
0845         ((offset >= 0xb020) && (offset <= 0xb0a0));
0846 }
0847 
0848 static int is_cmd_update_pdps(unsigned int offset,
0849                   struct parser_exec_state *s)
0850 {
0851     u32 base = s->workload->engine->mmio_base;
0852     return i915_mmio_reg_equal(_MMIO(offset), GEN8_RING_PDP_UDW(base, 0));
0853 }
0854 
0855 static int cmd_pdp_mmio_update_handler(struct parser_exec_state *s,
0856                        unsigned int offset, unsigned int index)
0857 {
0858     struct intel_vgpu *vgpu = s->vgpu;
0859     struct intel_vgpu_mm *shadow_mm = s->workload->shadow_mm;
0860     struct intel_vgpu_mm *mm;
0861     u64 pdps[GEN8_3LVL_PDPES];
0862 
0863     if (shadow_mm->ppgtt_mm.root_entry_type ==
0864         GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
0865         pdps[0] = (u64)cmd_val(s, 2) << 32;
0866         pdps[0] |= cmd_val(s, 4);
0867 
0868         mm = intel_vgpu_find_ppgtt_mm(vgpu, pdps);
0869         if (!mm) {
0870             gvt_vgpu_err("failed to get the 4-level shadow vm\n");
0871             return -EINVAL;
0872         }
0873         intel_vgpu_mm_get(mm);
0874         list_add_tail(&mm->ppgtt_mm.link,
0875                   &s->workload->lri_shadow_mm);
0876         *cmd_ptr(s, 2) = upper_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
0877         *cmd_ptr(s, 4) = lower_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
0878     } else {
0879         /* Currently all guests use PML4 table and now can't
0880          * have a guest with 3-level table but uses LRI for
0881          * PPGTT update. So this is simply un-testable. */
0882         GEM_BUG_ON(1);
0883         gvt_vgpu_err("invalid shared shadow vm type\n");
0884         return -EINVAL;
0885     }
0886     return 0;
0887 }
0888 
0889 static int cmd_reg_handler(struct parser_exec_state *s,
0890     unsigned int offset, unsigned int index, char *cmd)
0891 {
0892     struct intel_vgpu *vgpu = s->vgpu;
0893     struct intel_gvt *gvt = vgpu->gvt;
0894     u32 ctx_sr_ctl;
0895     u32 *vreg, vreg_old;
0896 
0897     if (offset + 4 > gvt->device_info.mmio_size) {
0898         gvt_vgpu_err("%s access to (%x) outside of MMIO range\n",
0899                 cmd, offset);
0900         return -EFAULT;
0901     }
0902 
0903     if (is_init_ctx(s)) {
0904         struct intel_gvt_mmio_info *mmio_info;
0905 
0906         intel_gvt_mmio_set_cmd_accessible(gvt, offset);
0907         mmio_info = intel_gvt_find_mmio_info(gvt, offset);
0908         if (mmio_info && mmio_info->write)
0909             intel_gvt_mmio_set_cmd_write_patch(gvt, offset);
0910         return 0;
0911     }
0912 
0913     if (!intel_gvt_mmio_is_cmd_accessible(gvt, offset)) {
0914         gvt_vgpu_err("%s access to non-render register (%x)\n",
0915                 cmd, offset);
0916         return -EBADRQC;
0917     }
0918 
0919     if (!strncmp(cmd, "srm", 3) ||
0920             !strncmp(cmd, "lrm", 3)) {
0921         if (offset == i915_mmio_reg_offset(GEN8_L3SQCREG4) ||
0922             offset == 0x21f0 ||
0923             (IS_BROADWELL(gvt->gt->i915) &&
0924              offset == i915_mmio_reg_offset(INSTPM)))
0925             return 0;
0926         else {
0927             gvt_vgpu_err("%s access to register (%x)\n",
0928                     cmd, offset);
0929             return -EPERM;
0930         }
0931     }
0932 
0933     if (!strncmp(cmd, "lrr-src", 7) ||
0934             !strncmp(cmd, "lrr-dst", 7)) {
0935         if (IS_BROADWELL(gvt->gt->i915) && offset == 0x215c)
0936             return 0;
0937         else {
0938             gvt_vgpu_err("not allowed cmd %s reg (%x)\n", cmd, offset);
0939             return -EPERM;
0940         }
0941     }
0942 
0943     if (!strncmp(cmd, "pipe_ctrl", 9)) {
0944         /* TODO: add LRI POST logic here */
0945         return 0;
0946     }
0947 
0948     if (strncmp(cmd, "lri", 3))
0949         return -EPERM;
0950 
0951     /* below are all lri handlers */
0952     vreg = &vgpu_vreg(s->vgpu, offset);
0953 
0954     if (is_cmd_update_pdps(offset, s) &&
0955         cmd_pdp_mmio_update_handler(s, offset, index))
0956         return -EINVAL;
0957 
0958     if (offset == i915_mmio_reg_offset(DERRMR) ||
0959         offset == i915_mmio_reg_offset(FORCEWAKE_MT)) {
0960         /* Writing to HW VGT_PVINFO_PAGE offset will be discarded */
0961         patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE);
0962     }
0963 
0964     if (is_mocs_mmio(offset))
0965         *vreg = cmd_val(s, index + 1);
0966 
0967     vreg_old = *vreg;
0968 
0969     if (intel_gvt_mmio_is_cmd_write_patch(gvt, offset)) {
0970         u32 cmdval_new, cmdval;
0971         struct intel_gvt_mmio_info *mmio_info;
0972 
0973         cmdval = cmd_val(s, index + 1);
0974 
0975         mmio_info = intel_gvt_find_mmio_info(gvt, offset);
0976         if (!mmio_info) {
0977             cmdval_new = cmdval;
0978         } else {
0979             u64 ro_mask = mmio_info->ro_mask;
0980             int ret;
0981 
0982             if (likely(!ro_mask))
0983                 ret = mmio_info->write(s->vgpu, offset,
0984                         &cmdval, 4);
0985             else {
0986                 gvt_vgpu_err("try to write RO reg %x\n",
0987                         offset);
0988                 ret = -EBADRQC;
0989             }
0990             if (ret)
0991                 return ret;
0992             cmdval_new = *vreg;
0993         }
0994         if (cmdval_new != cmdval)
0995             patch_value(s, cmd_ptr(s, index+1), cmdval_new);
0996     }
0997 
0998     /* only patch cmd. restore vreg value if changed in mmio write handler*/
0999     *vreg = vreg_old;
1000 
1001     /* TODO
1002      * In order to let workload with inhibit context to generate
1003      * correct image data into memory, vregs values will be loaded to
1004      * hw via LRIs in the workload with inhibit context. But as
1005      * indirect context is loaded prior to LRIs in workload, we don't
1006      * want reg values specified in indirect context overwritten by
1007      * LRIs in workloads. So, when scanning an indirect context, we
1008      * update reg values in it into vregs, so LRIs in workload with
1009      * inhibit context will restore with correct values
1010      */
1011     if (GRAPHICS_VER(s->engine->i915) == 9 &&
1012         intel_gvt_mmio_is_sr_in_ctx(gvt, offset) &&
1013         !strncmp(cmd, "lri", 3)) {
1014         intel_gvt_read_gpa(s->vgpu,
1015             s->workload->ring_context_gpa + 12, &ctx_sr_ctl, 4);
1016         /* check inhibit context */
1017         if (ctx_sr_ctl & 1) {
1018             u32 data = cmd_val(s, index + 1);
1019 
1020             if (intel_gvt_mmio_has_mode_mask(s->vgpu->gvt, offset))
1021                 intel_vgpu_mask_mmio_write(vgpu,
1022                             offset, &data, 4);
1023             else
1024                 vgpu_vreg(vgpu, offset) = data;
1025         }
1026     }
1027 
1028     return 0;
1029 }
1030 
1031 #define cmd_reg(s, i) \
1032     (cmd_val(s, i) & GENMASK(22, 2))
1033 
1034 #define cmd_reg_inhibit(s, i) \
1035     (cmd_val(s, i) & GENMASK(22, 18))
1036 
1037 #define cmd_gma(s, i) \
1038     (cmd_val(s, i) & GENMASK(31, 2))
1039 
1040 #define cmd_gma_hi(s, i) \
1041     (cmd_val(s, i) & GENMASK(15, 0))
1042 
1043 static int cmd_handler_lri(struct parser_exec_state *s)
1044 {
1045     int i, ret = 0;
1046     int cmd_len = cmd_length(s);
1047 
1048     for (i = 1; i < cmd_len; i += 2) {
1049         if (IS_BROADWELL(s->engine->i915) && s->engine->id != RCS0) {
1050             if (s->engine->id == BCS0 &&
1051                 cmd_reg(s, i) == i915_mmio_reg_offset(DERRMR))
1052                 ret |= 0;
1053             else
1054                 ret |= cmd_reg_inhibit(s, i) ? -EBADRQC : 0;
1055         }
1056         if (ret)
1057             break;
1058         ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lri");
1059         if (ret)
1060             break;
1061     }
1062     return ret;
1063 }
1064 
1065 static int cmd_handler_lrr(struct parser_exec_state *s)
1066 {
1067     int i, ret = 0;
1068     int cmd_len = cmd_length(s);
1069 
1070     for (i = 1; i < cmd_len; i += 2) {
1071         if (IS_BROADWELL(s->engine->i915))
1072             ret |= ((cmd_reg_inhibit(s, i) ||
1073                  (cmd_reg_inhibit(s, i + 1)))) ?
1074                 -EBADRQC : 0;
1075         if (ret)
1076             break;
1077         ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrr-src");
1078         if (ret)
1079             break;
1080         ret |= cmd_reg_handler(s, cmd_reg(s, i + 1), i, "lrr-dst");
1081         if (ret)
1082             break;
1083     }
1084     return ret;
1085 }
1086 
1087 static inline int cmd_address_audit(struct parser_exec_state *s,
1088         unsigned long guest_gma, int op_size, bool index_mode);
1089 
1090 static int cmd_handler_lrm(struct parser_exec_state *s)
1091 {
1092     struct intel_gvt *gvt = s->vgpu->gvt;
1093     int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd;
1094     unsigned long gma;
1095     int i, ret = 0;
1096     int cmd_len = cmd_length(s);
1097 
1098     for (i = 1; i < cmd_len;) {
1099         if (IS_BROADWELL(s->engine->i915))
1100             ret |= (cmd_reg_inhibit(s, i)) ? -EBADRQC : 0;
1101         if (ret)
1102             break;
1103         ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrm");
1104         if (ret)
1105             break;
1106         if (cmd_val(s, 0) & (1 << 22)) {
1107             gma = cmd_gma(s, i + 1);
1108             if (gmadr_bytes == 8)
1109                 gma |= (cmd_gma_hi(s, i + 2)) << 32;
1110             ret |= cmd_address_audit(s, gma, sizeof(u32), false);
1111             if (ret)
1112                 break;
1113         }
1114         i += gmadr_dw_number(s) + 1;
1115     }
1116     return ret;
1117 }
1118 
1119 static int cmd_handler_srm(struct parser_exec_state *s)
1120 {
1121     int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1122     unsigned long gma;
1123     int i, ret = 0;
1124     int cmd_len = cmd_length(s);
1125 
1126     for (i = 1; i < cmd_len;) {
1127         ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "srm");
1128         if (ret)
1129             break;
1130         if (cmd_val(s, 0) & (1 << 22)) {
1131             gma = cmd_gma(s, i + 1);
1132             if (gmadr_bytes == 8)
1133                 gma |= (cmd_gma_hi(s, i + 2)) << 32;
1134             ret |= cmd_address_audit(s, gma, sizeof(u32), false);
1135             if (ret)
1136                 break;
1137         }
1138         i += gmadr_dw_number(s) + 1;
1139     }
1140     return ret;
1141 }
1142 
1143 struct cmd_interrupt_event {
1144     int pipe_control_notify;
1145     int mi_flush_dw;
1146     int mi_user_interrupt;
1147 };
1148 
1149 static const struct cmd_interrupt_event cmd_interrupt_events[] = {
1150     [RCS0] = {
1151         .pipe_control_notify = RCS_PIPE_CONTROL,
1152         .mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
1153         .mi_user_interrupt = RCS_MI_USER_INTERRUPT,
1154     },
1155     [BCS0] = {
1156         .pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1157         .mi_flush_dw = BCS_MI_FLUSH_DW,
1158         .mi_user_interrupt = BCS_MI_USER_INTERRUPT,
1159     },
1160     [VCS0] = {
1161         .pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1162         .mi_flush_dw = VCS_MI_FLUSH_DW,
1163         .mi_user_interrupt = VCS_MI_USER_INTERRUPT,
1164     },
1165     [VCS1] = {
1166         .pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1167         .mi_flush_dw = VCS2_MI_FLUSH_DW,
1168         .mi_user_interrupt = VCS2_MI_USER_INTERRUPT,
1169     },
1170     [VECS0] = {
1171         .pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
1172         .mi_flush_dw = VECS_MI_FLUSH_DW,
1173         .mi_user_interrupt = VECS_MI_USER_INTERRUPT,
1174     },
1175 };
1176 
1177 static int cmd_handler_pipe_control(struct parser_exec_state *s)
1178 {
1179     int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1180     unsigned long gma;
1181     bool index_mode = false;
1182     unsigned int post_sync;
1183     int ret = 0;
1184     u32 hws_pga, val;
1185 
1186     post_sync = (cmd_val(s, 1) & PIPE_CONTROL_POST_SYNC_OP_MASK) >> 14;
1187 
1188     /* LRI post sync */
1189     if (cmd_val(s, 1) & PIPE_CONTROL_MMIO_WRITE)
1190         ret = cmd_reg_handler(s, cmd_reg(s, 2), 1, "pipe_ctrl");
1191     /* post sync */
1192     else if (post_sync) {
1193         if (post_sync == 2)
1194             ret = cmd_reg_handler(s, 0x2350, 1, "pipe_ctrl");
1195         else if (post_sync == 3)
1196             ret = cmd_reg_handler(s, 0x2358, 1, "pipe_ctrl");
1197         else if (post_sync == 1) {
1198             /* check ggtt*/
1199             if ((cmd_val(s, 1) & PIPE_CONTROL_GLOBAL_GTT_IVB)) {
1200                 gma = cmd_val(s, 2) & GENMASK(31, 3);
1201                 if (gmadr_bytes == 8)
1202                     gma |= (cmd_gma_hi(s, 3)) << 32;
1203                 /* Store Data Index */
1204                 if (cmd_val(s, 1) & (1 << 21))
1205                     index_mode = true;
1206                 ret |= cmd_address_audit(s, gma, sizeof(u64),
1207                         index_mode);
1208                 if (ret)
1209                     return ret;
1210                 if (index_mode) {
1211                     hws_pga = s->vgpu->hws_pga[s->engine->id];
1212                     gma = hws_pga + gma;
1213                     patch_value(s, cmd_ptr(s, 2), gma);
1214                     val = cmd_val(s, 1) & (~(1 << 21));
1215                     patch_value(s, cmd_ptr(s, 1), val);
1216                 }
1217             }
1218         }
1219     }
1220 
1221     if (ret)
1222         return ret;
1223 
1224     if (cmd_val(s, 1) & PIPE_CONTROL_NOTIFY)
1225         set_bit(cmd_interrupt_events[s->engine->id].pipe_control_notify,
1226             s->workload->pending_events);
1227     return 0;
1228 }
1229 
1230 static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
1231 {
1232     set_bit(cmd_interrupt_events[s->engine->id].mi_user_interrupt,
1233         s->workload->pending_events);
1234     patch_value(s, cmd_ptr(s, 0), MI_NOOP);
1235     return 0;
1236 }
1237 
1238 static int cmd_advance_default(struct parser_exec_state *s)
1239 {
1240     return ip_gma_advance(s, cmd_length(s));
1241 }
1242 
1243 static int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
1244 {
1245     int ret;
1246 
1247     if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
1248         s->buf_type = BATCH_BUFFER_INSTRUCTION;
1249         ret = ip_gma_set(s, s->ret_ip_gma_bb);
1250         s->buf_addr_type = s->saved_buf_addr_type;
1251     } else if (s->buf_type == RING_BUFFER_CTX) {
1252         ret = ip_gma_set(s, s->ring_tail);
1253     } else {
1254         s->buf_type = RING_BUFFER_INSTRUCTION;
1255         s->buf_addr_type = GTT_BUFFER;
1256         if (s->ret_ip_gma_ring >= s->ring_start + s->ring_size)
1257             s->ret_ip_gma_ring -= s->ring_size;
1258         ret = ip_gma_set(s, s->ret_ip_gma_ring);
1259     }
1260     return ret;
1261 }
1262 
1263 struct mi_display_flip_command_info {
1264     int pipe;
1265     int plane;
1266     int event;
1267     i915_reg_t stride_reg;
1268     i915_reg_t ctrl_reg;
1269     i915_reg_t surf_reg;
1270     u64 stride_val;
1271     u64 tile_val;
1272     u64 surf_val;
1273     bool async_flip;
1274 };
1275 
1276 struct plane_code_mapping {
1277     int pipe;
1278     int plane;
1279     int event;
1280 };
1281 
1282 static int gen8_decode_mi_display_flip(struct parser_exec_state *s,
1283         struct mi_display_flip_command_info *info)
1284 {
1285     struct drm_i915_private *dev_priv = s->engine->i915;
1286     struct plane_code_mapping gen8_plane_code[] = {
1287         [0] = {PIPE_A, PLANE_A, PRIMARY_A_FLIP_DONE},
1288         [1] = {PIPE_B, PLANE_A, PRIMARY_B_FLIP_DONE},
1289         [2] = {PIPE_A, PLANE_B, SPRITE_A_FLIP_DONE},
1290         [3] = {PIPE_B, PLANE_B, SPRITE_B_FLIP_DONE},
1291         [4] = {PIPE_C, PLANE_A, PRIMARY_C_FLIP_DONE},
1292         [5] = {PIPE_C, PLANE_B, SPRITE_C_FLIP_DONE},
1293     };
1294     u32 dword0, dword1, dword2;
1295     u32 v;
1296 
1297     dword0 = cmd_val(s, 0);
1298     dword1 = cmd_val(s, 1);
1299     dword2 = cmd_val(s, 2);
1300 
1301     v = (dword0 & GENMASK(21, 19)) >> 19;
1302     if (drm_WARN_ON(&dev_priv->drm, v >= ARRAY_SIZE(gen8_plane_code)))
1303         return -EBADRQC;
1304 
1305     info->pipe = gen8_plane_code[v].pipe;
1306     info->plane = gen8_plane_code[v].plane;
1307     info->event = gen8_plane_code[v].event;
1308     info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
1309     info->tile_val = (dword1 & 0x1);
1310     info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
1311     info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
1312 
1313     if (info->plane == PLANE_A) {
1314         info->ctrl_reg = DSPCNTR(info->pipe);
1315         info->stride_reg = DSPSTRIDE(info->pipe);
1316         info->surf_reg = DSPSURF(info->pipe);
1317     } else if (info->plane == PLANE_B) {
1318         info->ctrl_reg = SPRCTL(info->pipe);
1319         info->stride_reg = SPRSTRIDE(info->pipe);
1320         info->surf_reg = SPRSURF(info->pipe);
1321     } else {
1322         drm_WARN_ON(&dev_priv->drm, 1);
1323         return -EBADRQC;
1324     }
1325     return 0;
1326 }
1327 
1328 static int skl_decode_mi_display_flip(struct parser_exec_state *s,
1329         struct mi_display_flip_command_info *info)
1330 {
1331     struct drm_i915_private *dev_priv = s->engine->i915;
1332     struct intel_vgpu *vgpu = s->vgpu;
1333     u32 dword0 = cmd_val(s, 0);
1334     u32 dword1 = cmd_val(s, 1);
1335     u32 dword2 = cmd_val(s, 2);
1336     u32 plane = (dword0 & GENMASK(12, 8)) >> 8;
1337 
1338     info->plane = PRIMARY_PLANE;
1339 
1340     switch (plane) {
1341     case MI_DISPLAY_FLIP_SKL_PLANE_1_A:
1342         info->pipe = PIPE_A;
1343         info->event = PRIMARY_A_FLIP_DONE;
1344         break;
1345     case MI_DISPLAY_FLIP_SKL_PLANE_1_B:
1346         info->pipe = PIPE_B;
1347         info->event = PRIMARY_B_FLIP_DONE;
1348         break;
1349     case MI_DISPLAY_FLIP_SKL_PLANE_1_C:
1350         info->pipe = PIPE_C;
1351         info->event = PRIMARY_C_FLIP_DONE;
1352         break;
1353 
1354     case MI_DISPLAY_FLIP_SKL_PLANE_2_A:
1355         info->pipe = PIPE_A;
1356         info->event = SPRITE_A_FLIP_DONE;
1357         info->plane = SPRITE_PLANE;
1358         break;
1359     case MI_DISPLAY_FLIP_SKL_PLANE_2_B:
1360         info->pipe = PIPE_B;
1361         info->event = SPRITE_B_FLIP_DONE;
1362         info->plane = SPRITE_PLANE;
1363         break;
1364     case MI_DISPLAY_FLIP_SKL_PLANE_2_C:
1365         info->pipe = PIPE_C;
1366         info->event = SPRITE_C_FLIP_DONE;
1367         info->plane = SPRITE_PLANE;
1368         break;
1369 
1370     default:
1371         gvt_vgpu_err("unknown plane code %d\n", plane);
1372         return -EBADRQC;
1373     }
1374 
1375     info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
1376     info->tile_val = (dword1 & GENMASK(2, 0));
1377     info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
1378     info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
1379 
1380     info->ctrl_reg = DSPCNTR(info->pipe);
1381     info->stride_reg = DSPSTRIDE(info->pipe);
1382     info->surf_reg = DSPSURF(info->pipe);
1383 
1384     return 0;
1385 }
1386 
1387 static int gen8_check_mi_display_flip(struct parser_exec_state *s,
1388         struct mi_display_flip_command_info *info)
1389 {
1390     u32 stride, tile;
1391 
1392     if (!info->async_flip)
1393         return 0;
1394 
1395     if (GRAPHICS_VER(s->engine->i915) >= 9) {
1396         stride = vgpu_vreg_t(s->vgpu, info->stride_reg) & GENMASK(9, 0);
1397         tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) &
1398                 GENMASK(12, 10)) >> 10;
1399     } else {
1400         stride = (vgpu_vreg_t(s->vgpu, info->stride_reg) &
1401                 GENMASK(15, 6)) >> 6;
1402         tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) & (1 << 10)) >> 10;
1403     }
1404 
1405     if (stride != info->stride_val)
1406         gvt_dbg_cmd("cannot change stride during async flip\n");
1407 
1408     if (tile != info->tile_val)
1409         gvt_dbg_cmd("cannot change tile during async flip\n");
1410 
1411     return 0;
1412 }
1413 
1414 static int gen8_update_plane_mmio_from_mi_display_flip(
1415         struct parser_exec_state *s,
1416         struct mi_display_flip_command_info *info)
1417 {
1418     struct drm_i915_private *dev_priv = s->engine->i915;
1419     struct intel_vgpu *vgpu = s->vgpu;
1420 
1421     set_mask_bits(&vgpu_vreg_t(vgpu, info->surf_reg), GENMASK(31, 12),
1422               info->surf_val << 12);
1423     if (GRAPHICS_VER(dev_priv) >= 9) {
1424         set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(9, 0),
1425                   info->stride_val);
1426         set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(12, 10),
1427                   info->tile_val << 10);
1428     } else {
1429         set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(15, 6),
1430                   info->stride_val << 6);
1431         set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(10, 10),
1432                   info->tile_val << 10);
1433     }
1434 
1435     if (info->plane == PLANE_PRIMARY)
1436         vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(info->pipe))++;
1437 
1438     if (info->async_flip)
1439         intel_vgpu_trigger_virtual_event(vgpu, info->event);
1440     else
1441         set_bit(info->event, vgpu->irq.flip_done_event[info->pipe]);
1442 
1443     return 0;
1444 }
1445 
1446 static int decode_mi_display_flip(struct parser_exec_state *s,
1447         struct mi_display_flip_command_info *info)
1448 {
1449     if (IS_BROADWELL(s->engine->i915))
1450         return gen8_decode_mi_display_flip(s, info);
1451     if (GRAPHICS_VER(s->engine->i915) >= 9)
1452         return skl_decode_mi_display_flip(s, info);
1453 
1454     return -ENODEV;
1455 }
1456 
1457 static int check_mi_display_flip(struct parser_exec_state *s,
1458         struct mi_display_flip_command_info *info)
1459 {
1460     return gen8_check_mi_display_flip(s, info);
1461 }
1462 
1463 static int update_plane_mmio_from_mi_display_flip(
1464         struct parser_exec_state *s,
1465         struct mi_display_flip_command_info *info)
1466 {
1467     return gen8_update_plane_mmio_from_mi_display_flip(s, info);
1468 }
1469 
1470 static int cmd_handler_mi_display_flip(struct parser_exec_state *s)
1471 {
1472     struct mi_display_flip_command_info info;
1473     struct intel_vgpu *vgpu = s->vgpu;
1474     int ret;
1475     int i;
1476     int len = cmd_length(s);
1477     u32 valid_len = CMD_LEN(1);
1478 
1479     /* Flip Type == Stereo 3D Flip */
1480     if (DWORD_FIELD(2, 1, 0) == 2)
1481         valid_len++;
1482     ret = gvt_check_valid_cmd_length(cmd_length(s),
1483             valid_len);
1484     if (ret)
1485         return ret;
1486 
1487     ret = decode_mi_display_flip(s, &info);
1488     if (ret) {
1489         gvt_vgpu_err("fail to decode MI display flip command\n");
1490         return ret;
1491     }
1492 
1493     ret = check_mi_display_flip(s, &info);
1494     if (ret) {
1495         gvt_vgpu_err("invalid MI display flip command\n");
1496         return ret;
1497     }
1498 
1499     ret = update_plane_mmio_from_mi_display_flip(s, &info);
1500     if (ret) {
1501         gvt_vgpu_err("fail to update plane mmio\n");
1502         return ret;
1503     }
1504 
1505     for (i = 0; i < len; i++)
1506         patch_value(s, cmd_ptr(s, i), MI_NOOP);
1507     return 0;
1508 }
1509 
1510 static bool is_wait_for_flip_pending(u32 cmd)
1511 {
1512     return cmd & (MI_WAIT_FOR_PLANE_A_FLIP_PENDING |
1513             MI_WAIT_FOR_PLANE_B_FLIP_PENDING |
1514             MI_WAIT_FOR_PLANE_C_FLIP_PENDING |
1515             MI_WAIT_FOR_SPRITE_A_FLIP_PENDING |
1516             MI_WAIT_FOR_SPRITE_B_FLIP_PENDING |
1517             MI_WAIT_FOR_SPRITE_C_FLIP_PENDING);
1518 }
1519 
1520 static int cmd_handler_mi_wait_for_event(struct parser_exec_state *s)
1521 {
1522     u32 cmd = cmd_val(s, 0);
1523 
1524     if (!is_wait_for_flip_pending(cmd))
1525         return 0;
1526 
1527     patch_value(s, cmd_ptr(s, 0), MI_NOOP);
1528     return 0;
1529 }
1530 
1531 static unsigned long get_gma_bb_from_cmd(struct parser_exec_state *s, int index)
1532 {
1533     unsigned long addr;
1534     unsigned long gma_high, gma_low;
1535     struct intel_vgpu *vgpu = s->vgpu;
1536     int gmadr_bytes = vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1537 
1538     if (WARN_ON(gmadr_bytes != 4 && gmadr_bytes != 8)) {
1539         gvt_vgpu_err("invalid gma bytes %d\n", gmadr_bytes);
1540         return INTEL_GVT_INVALID_ADDR;
1541     }
1542 
1543     gma_low = cmd_val(s, index) & BATCH_BUFFER_ADDR_MASK;
1544     if (gmadr_bytes == 4) {
1545         addr = gma_low;
1546     } else {
1547         gma_high = cmd_val(s, index + 1) & BATCH_BUFFER_ADDR_HIGH_MASK;
1548         addr = (((unsigned long)gma_high) << 32) | gma_low;
1549     }
1550     return addr;
1551 }
1552 
1553 static inline int cmd_address_audit(struct parser_exec_state *s,
1554         unsigned long guest_gma, int op_size, bool index_mode)
1555 {
1556     struct intel_vgpu *vgpu = s->vgpu;
1557     u32 max_surface_size = vgpu->gvt->device_info.max_surface_size;
1558     int i;
1559     int ret;
1560 
1561     if (op_size > max_surface_size) {
1562         gvt_vgpu_err("command address audit fail name %s\n",
1563             s->info->name);
1564         return -EFAULT;
1565     }
1566 
1567     if (index_mode) {
1568         if (guest_gma >= I915_GTT_PAGE_SIZE) {
1569             ret = -EFAULT;
1570             goto err;
1571         }
1572     } else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) {
1573         ret = -EFAULT;
1574         goto err;
1575     }
1576 
1577     return 0;
1578 
1579 err:
1580     gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
1581             s->info->name, guest_gma, op_size);
1582 
1583     pr_err("cmd dump: ");
1584     for (i = 0; i < cmd_length(s); i++) {
1585         if (!(i % 4))
1586             pr_err("\n%08x ", cmd_val(s, i));
1587         else
1588             pr_err("%08x ", cmd_val(s, i));
1589     }
1590     pr_err("\nvgpu%d: aperture 0x%llx - 0x%llx, hidden 0x%llx - 0x%llx\n",
1591             vgpu->id,
1592             vgpu_aperture_gmadr_base(vgpu),
1593             vgpu_aperture_gmadr_end(vgpu),
1594             vgpu_hidden_gmadr_base(vgpu),
1595             vgpu_hidden_gmadr_end(vgpu));
1596     return ret;
1597 }
1598 
1599 static int cmd_handler_mi_store_data_imm(struct parser_exec_state *s)
1600 {
1601     int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1602     int op_size = (cmd_length(s) - 3) * sizeof(u32);
1603     int core_id = (cmd_val(s, 2) & (1 << 0)) ? 1 : 0;
1604     unsigned long gma, gma_low, gma_high;
1605     u32 valid_len = CMD_LEN(2);
1606     int ret = 0;
1607 
1608     /* check ppggt */
1609     if (!(cmd_val(s, 0) & (1 << 22)))
1610         return 0;
1611 
1612     /* check if QWORD */
1613     if (DWORD_FIELD(0, 21, 21))
1614         valid_len++;
1615     ret = gvt_check_valid_cmd_length(cmd_length(s),
1616             valid_len);
1617     if (ret)
1618         return ret;
1619 
1620     gma = cmd_val(s, 2) & GENMASK(31, 2);
1621 
1622     if (gmadr_bytes == 8) {
1623         gma_low = cmd_val(s, 1) & GENMASK(31, 2);
1624         gma_high = cmd_val(s, 2) & GENMASK(15, 0);
1625         gma = (gma_high << 32) | gma_low;
1626         core_id = (cmd_val(s, 1) & (1 << 0)) ? 1 : 0;
1627     }
1628     ret = cmd_address_audit(s, gma + op_size * core_id, op_size, false);
1629     return ret;
1630 }
1631 
1632 static inline int unexpected_cmd(struct parser_exec_state *s)
1633 {
1634     struct intel_vgpu *vgpu = s->vgpu;
1635 
1636     gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name);
1637 
1638     return -EBADRQC;
1639 }
1640 
1641 static int cmd_handler_mi_semaphore_wait(struct parser_exec_state *s)
1642 {
1643     return unexpected_cmd(s);
1644 }
1645 
1646 static int cmd_handler_mi_report_perf_count(struct parser_exec_state *s)
1647 {
1648     return unexpected_cmd(s);
1649 }
1650 
1651 static int cmd_handler_mi_op_2e(struct parser_exec_state *s)
1652 {
1653     return unexpected_cmd(s);
1654 }
1655 
1656 static int cmd_handler_mi_op_2f(struct parser_exec_state *s)
1657 {
1658     int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1659     int op_size = (1 << ((cmd_val(s, 0) & GENMASK(20, 19)) >> 19)) *
1660             sizeof(u32);
1661     unsigned long gma, gma_high;
1662     u32 valid_len = CMD_LEN(1);
1663     int ret = 0;
1664 
1665     if (!(cmd_val(s, 0) & (1 << 22)))
1666         return ret;
1667 
1668     /* check inline data */
1669     if (cmd_val(s, 0) & BIT(18))
1670         valid_len = CMD_LEN(9);
1671     ret = gvt_check_valid_cmd_length(cmd_length(s),
1672             valid_len);
1673     if (ret)
1674         return ret;
1675 
1676     gma = cmd_val(s, 1) & GENMASK(31, 2);
1677     if (gmadr_bytes == 8) {
1678         gma_high = cmd_val(s, 2) & GENMASK(15, 0);
1679         gma = (gma_high << 32) | gma;
1680     }
1681     ret = cmd_address_audit(s, gma, op_size, false);
1682     return ret;
1683 }
1684 
1685 static int cmd_handler_mi_store_data_index(struct parser_exec_state *s)
1686 {
1687     return unexpected_cmd(s);
1688 }
1689 
1690 static int cmd_handler_mi_clflush(struct parser_exec_state *s)
1691 {
1692     return unexpected_cmd(s);
1693 }
1694 
1695 static int cmd_handler_mi_conditional_batch_buffer_end(
1696         struct parser_exec_state *s)
1697 {
1698     return unexpected_cmd(s);
1699 }
1700 
1701 static int cmd_handler_mi_update_gtt(struct parser_exec_state *s)
1702 {
1703     return unexpected_cmd(s);
1704 }
1705 
1706 static int cmd_handler_mi_flush_dw(struct parser_exec_state *s)
1707 {
1708     int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
1709     unsigned long gma;
1710     bool index_mode = false;
1711     int ret = 0;
1712     u32 hws_pga, val;
1713     u32 valid_len = CMD_LEN(2);
1714 
1715     ret = gvt_check_valid_cmd_length(cmd_length(s),
1716             valid_len);
1717     if (ret) {
1718         /* Check again for Qword */
1719         ret = gvt_check_valid_cmd_length(cmd_length(s),
1720             ++valid_len);
1721         return ret;
1722     }
1723 
1724     /* Check post-sync and ppgtt bit */
1725     if (((cmd_val(s, 0) >> 14) & 0x3) && (cmd_val(s, 1) & (1 << 2))) {
1726         gma = cmd_val(s, 1) & GENMASK(31, 3);
1727         if (gmadr_bytes == 8)
1728             gma |= (cmd_val(s, 2) & GENMASK(15, 0)) << 32;
1729         /* Store Data Index */
1730         if (cmd_val(s, 0) & (1 << 21))
1731             index_mode = true;
1732         ret = cmd_address_audit(s, gma, sizeof(u64), index_mode);
1733         if (ret)
1734             return ret;
1735         if (index_mode) {
1736             hws_pga = s->vgpu->hws_pga[s->engine->id];
1737             gma = hws_pga + gma;
1738             patch_value(s, cmd_ptr(s, 1), gma);
1739             val = cmd_val(s, 0) & (~(1 << 21));
1740             patch_value(s, cmd_ptr(s, 0), val);
1741         }
1742     }
1743     /* Check notify bit */
1744     if ((cmd_val(s, 0) & (1 << 8)))
1745         set_bit(cmd_interrupt_events[s->engine->id].mi_flush_dw,
1746             s->workload->pending_events);
1747     return ret;
1748 }
1749 
1750 static void addr_type_update_snb(struct parser_exec_state *s)
1751 {
1752     if ((s->buf_type == RING_BUFFER_INSTRUCTION) &&
1753             (BATCH_BUFFER_ADR_SPACE_BIT(cmd_val(s, 0)) == 1)) {
1754         s->buf_addr_type = PPGTT_BUFFER;
1755     }
1756 }
1757 
1758 
1759 static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
1760         unsigned long gma, unsigned long end_gma, void *va)
1761 {
1762     unsigned long copy_len, offset;
1763     unsigned long len = 0;
1764     unsigned long gpa;
1765 
1766     while (gma != end_gma) {
1767         gpa = intel_vgpu_gma_to_gpa(mm, gma);
1768         if (gpa == INTEL_GVT_INVALID_ADDR) {
1769             gvt_vgpu_err("invalid gma address: %lx\n", gma);
1770             return -EFAULT;
1771         }
1772 
1773         offset = gma & (I915_GTT_PAGE_SIZE - 1);
1774 
1775         copy_len = (end_gma - gma) >= (I915_GTT_PAGE_SIZE - offset) ?
1776             I915_GTT_PAGE_SIZE - offset : end_gma - gma;
1777 
1778         intel_gvt_read_gpa(vgpu, gpa, va + len, copy_len);
1779 
1780         len += copy_len;
1781         gma += copy_len;
1782     }
1783     return len;
1784 }
1785 
1786 
1787 /*
1788  * Check whether a batch buffer needs to be scanned. Currently
1789  * the only criteria is based on privilege.
1790  */
1791 static int batch_buffer_needs_scan(struct parser_exec_state *s)
1792 {
1793     /* Decide privilege based on address space */
1794     if (cmd_val(s, 0) & BIT(8) &&
1795         !(s->vgpu->scan_nonprivbb & s->engine->mask))
1796         return 0;
1797 
1798     return 1;
1799 }
1800 
1801 static const char *repr_addr_type(unsigned int type)
1802 {
1803     return type == PPGTT_BUFFER ? "ppgtt" : "ggtt";
1804 }
1805 
1806 static int find_bb_size(struct parser_exec_state *s,
1807             unsigned long *bb_size,
1808             unsigned long *bb_end_cmd_offset)
1809 {
1810     unsigned long gma = 0;
1811     const struct cmd_info *info;
1812     u32 cmd_len = 0;
1813     bool bb_end = false;
1814     struct intel_vgpu *vgpu = s->vgpu;
1815     u32 cmd;
1816     struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1817         s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1818 
1819     *bb_size = 0;
1820     *bb_end_cmd_offset = 0;
1821 
1822     /* get the start gm address of the batch buffer */
1823     gma = get_gma_bb_from_cmd(s, 1);
1824     if (gma == INTEL_GVT_INVALID_ADDR)
1825         return -EFAULT;
1826 
1827     cmd = cmd_val(s, 0);
1828     info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1829     if (info == NULL) {
1830         gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1831                  cmd, get_opcode(cmd, s->engine),
1832                  repr_addr_type(s->buf_addr_type),
1833                  s->engine->name, s->workload);
1834         return -EBADRQC;
1835     }
1836     do {
1837         if (copy_gma_to_hva(s->vgpu, mm,
1838                     gma, gma + 4, &cmd) < 0)
1839             return -EFAULT;
1840         info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1841         if (info == NULL) {
1842             gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1843                      cmd, get_opcode(cmd, s->engine),
1844                      repr_addr_type(s->buf_addr_type),
1845                      s->engine->name, s->workload);
1846             return -EBADRQC;
1847         }
1848 
1849         if (info->opcode == OP_MI_BATCH_BUFFER_END) {
1850             bb_end = true;
1851         } else if (info->opcode == OP_MI_BATCH_BUFFER_START) {
1852             if (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)
1853                 /* chained batch buffer */
1854                 bb_end = true;
1855         }
1856 
1857         if (bb_end)
1858             *bb_end_cmd_offset = *bb_size;
1859 
1860         cmd_len = get_cmd_length(info, cmd) << 2;
1861         *bb_size += cmd_len;
1862         gma += cmd_len;
1863     } while (!bb_end);
1864 
1865     return 0;
1866 }
1867 
1868 static int audit_bb_end(struct parser_exec_state *s, void *va)
1869 {
1870     struct intel_vgpu *vgpu = s->vgpu;
1871     u32 cmd = *(u32 *)va;
1872     const struct cmd_info *info;
1873 
1874     info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
1875     if (info == NULL) {
1876         gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
1877                  cmd, get_opcode(cmd, s->engine),
1878                  repr_addr_type(s->buf_addr_type),
1879                  s->engine->name, s->workload);
1880         return -EBADRQC;
1881     }
1882 
1883     if ((info->opcode == OP_MI_BATCH_BUFFER_END) ||
1884         ((info->opcode == OP_MI_BATCH_BUFFER_START) &&
1885          (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)))
1886         return 0;
1887 
1888     return -EBADRQC;
1889 }
1890 
1891 static int perform_bb_shadow(struct parser_exec_state *s)
1892 {
1893     struct intel_vgpu *vgpu = s->vgpu;
1894     struct intel_vgpu_shadow_bb *bb;
1895     unsigned long gma = 0;
1896     unsigned long bb_size;
1897     unsigned long bb_end_cmd_offset;
1898     int ret = 0;
1899     struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
1900         s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
1901     unsigned long start_offset = 0;
1902 
1903     /* get the start gm address of the batch buffer */
1904     gma = get_gma_bb_from_cmd(s, 1);
1905     if (gma == INTEL_GVT_INVALID_ADDR)
1906         return -EFAULT;
1907 
1908     ret = find_bb_size(s, &bb_size, &bb_end_cmd_offset);
1909     if (ret)
1910         return ret;
1911 
1912     bb = kzalloc(sizeof(*bb), GFP_KERNEL);
1913     if (!bb)
1914         return -ENOMEM;
1915 
1916     bb->ppgtt = (s->buf_addr_type == GTT_BUFFER) ? false : true;
1917 
1918     /* the start_offset stores the batch buffer's start gma's
1919      * offset relative to page boundary. so for non-privileged batch
1920      * buffer, the shadowed gem object holds exactly the same page
1921      * layout as original gem object. This is for the convience of
1922      * replacing the whole non-privilged batch buffer page to this
1923      * shadowed one in PPGTT at the same gma address. (this replacing
1924      * action is not implemented yet now, but may be necessary in
1925      * future).
1926      * for prileged batch buffer, we just change start gma address to
1927      * that of shadowed page.
1928      */
1929     if (bb->ppgtt)
1930         start_offset = gma & ~I915_GTT_PAGE_MASK;
1931 
1932     bb->obj = i915_gem_object_create_shmem(s->engine->i915,
1933                            round_up(bb_size + start_offset,
1934                             PAGE_SIZE));
1935     if (IS_ERR(bb->obj)) {
1936         ret = PTR_ERR(bb->obj);
1937         goto err_free_bb;
1938     }
1939 
1940     bb->va = i915_gem_object_pin_map(bb->obj, I915_MAP_WB);
1941     if (IS_ERR(bb->va)) {
1942         ret = PTR_ERR(bb->va);
1943         goto err_free_obj;
1944     }
1945 
1946     ret = copy_gma_to_hva(s->vgpu, mm,
1947                   gma, gma + bb_size,
1948                   bb->va + start_offset);
1949     if (ret < 0) {
1950         gvt_vgpu_err("fail to copy guest ring buffer\n");
1951         ret = -EFAULT;
1952         goto err_unmap;
1953     }
1954 
1955     ret = audit_bb_end(s, bb->va + start_offset + bb_end_cmd_offset);
1956     if (ret)
1957         goto err_unmap;
1958 
1959     i915_gem_object_unlock(bb->obj);
1960     INIT_LIST_HEAD(&bb->list);
1961     list_add(&bb->list, &s->workload->shadow_bb);
1962 
1963     bb->bb_start_cmd_va = s->ip_va;
1964 
1965     if ((s->buf_type == BATCH_BUFFER_INSTRUCTION) && (!s->is_ctx_wa))
1966         bb->bb_offset = s->ip_va - s->rb_va;
1967     else
1968         bb->bb_offset = 0;
1969 
1970     /*
1971      * ip_va saves the virtual address of the shadow batch buffer, while
1972      * ip_gma saves the graphics address of the original batch buffer.
1973      * As the shadow batch buffer is just a copy from the originial one,
1974      * it should be right to use shadow batch buffer'va and original batch
1975      * buffer's gma in pair. After all, we don't want to pin the shadow
1976      * buffer here (too early).
1977      */
1978     s->ip_va = bb->va + start_offset;
1979     s->ip_gma = gma;
1980     return 0;
1981 err_unmap:
1982     i915_gem_object_unpin_map(bb->obj);
1983 err_free_obj:
1984     i915_gem_object_put(bb->obj);
1985 err_free_bb:
1986     kfree(bb);
1987     return ret;
1988 }
1989 
1990 static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
1991 {
1992     bool second_level;
1993     int ret = 0;
1994     struct intel_vgpu *vgpu = s->vgpu;
1995 
1996     if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
1997         gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n");
1998         return -EFAULT;
1999     }
2000 
2001     second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1;
2002     if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) {
2003         gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n");
2004         return -EFAULT;
2005     }
2006 
2007     s->saved_buf_addr_type = s->buf_addr_type;
2008     addr_type_update_snb(s);
2009     if (s->buf_type == RING_BUFFER_INSTRUCTION) {
2010         s->ret_ip_gma_ring = s->ip_gma + cmd_length(s) * sizeof(u32);
2011         s->buf_type = BATCH_BUFFER_INSTRUCTION;
2012     } else if (second_level) {
2013         s->buf_type = BATCH_BUFFER_2ND_LEVEL;
2014         s->ret_ip_gma_bb = s->ip_gma + cmd_length(s) * sizeof(u32);
2015         s->ret_bb_va = s->ip_va + cmd_length(s) * sizeof(u32);
2016     }
2017 
2018     if (batch_buffer_needs_scan(s)) {
2019         ret = perform_bb_shadow(s);
2020         if (ret < 0)
2021             gvt_vgpu_err("invalid shadow batch buffer\n");
2022     } else {
2023         /* emulate a batch buffer end to do return right */
2024         ret = cmd_handler_mi_batch_buffer_end(s);
2025         if (ret < 0)
2026             return ret;
2027     }
2028     return ret;
2029 }
2030 
2031 static int mi_noop_index;
2032 
2033 static const struct cmd_info cmd_info[] = {
2034     {"MI_NOOP", OP_MI_NOOP, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2035 
2036     {"MI_SET_PREDICATE", OP_MI_SET_PREDICATE, F_LEN_CONST, R_ALL, D_ALL,
2037         0, 1, NULL},
2038 
2039     {"MI_USER_INTERRUPT", OP_MI_USER_INTERRUPT, F_LEN_CONST, R_ALL, D_ALL,
2040         0, 1, cmd_handler_mi_user_interrupt},
2041 
2042     {"MI_WAIT_FOR_EVENT", OP_MI_WAIT_FOR_EVENT, F_LEN_CONST, R_RCS | R_BCS,
2043         D_ALL, 0, 1, cmd_handler_mi_wait_for_event},
2044 
2045     {"MI_FLUSH", OP_MI_FLUSH, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2046 
2047     {"MI_ARB_CHECK", OP_MI_ARB_CHECK, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2048         NULL},
2049 
2050     {"MI_RS_CONTROL", OP_MI_RS_CONTROL, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2051         NULL},
2052 
2053     {"MI_REPORT_HEAD", OP_MI_REPORT_HEAD, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2054         NULL},
2055 
2056     {"MI_ARB_ON_OFF", OP_MI_ARB_ON_OFF, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2057         NULL},
2058 
2059     {"MI_URB_ATOMIC_ALLOC", OP_MI_URB_ATOMIC_ALLOC, F_LEN_CONST, R_RCS,
2060         D_ALL, 0, 1, NULL},
2061 
2062     {"MI_BATCH_BUFFER_END", OP_MI_BATCH_BUFFER_END,
2063         F_IP_ADVANCE_CUSTOM | F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2064         cmd_handler_mi_batch_buffer_end},
2065 
2066     {"MI_SUSPEND_FLUSH", OP_MI_SUSPEND_FLUSH, F_LEN_CONST, R_ALL, D_ALL,
2067         0, 1, NULL},
2068 
2069     {"MI_PREDICATE", OP_MI_PREDICATE, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2070         NULL},
2071 
2072     {"MI_TOPOLOGY_FILTER", OP_MI_TOPOLOGY_FILTER, F_LEN_CONST, R_ALL,
2073         D_ALL, 0, 1, NULL},
2074 
2075     {"MI_SET_APPID", OP_MI_SET_APPID, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
2076         NULL},
2077 
2078     {"MI_RS_CONTEXT", OP_MI_RS_CONTEXT, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
2079         NULL},
2080 
2081     {"MI_DISPLAY_FLIP", OP_MI_DISPLAY_FLIP, F_LEN_VAR,
2082         R_RCS | R_BCS, D_ALL, 0, 8, cmd_handler_mi_display_flip},
2083 
2084     {"MI_SEMAPHORE_MBOX", OP_MI_SEMAPHORE_MBOX, F_LEN_VAR | F_LEN_VAR_FIXED,
2085         R_ALL, D_ALL, 0, 8, NULL, CMD_LEN(1)},
2086 
2087     {"MI_MATH", OP_MI_MATH, F_LEN_VAR, R_ALL, D_ALL, 0, 8, NULL},
2088 
2089     {"MI_URB_CLEAR", OP_MI_URB_CLEAR, F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS,
2090         D_ALL, 0, 8, NULL, CMD_LEN(0)},
2091 
2092     {"MI_SEMAPHORE_SIGNAL", OP_MI_SEMAPHORE_SIGNAL,
2093         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, 0, 8,
2094         NULL, CMD_LEN(0)},
2095 
2096     {"MI_SEMAPHORE_WAIT", OP_MI_SEMAPHORE_WAIT,
2097         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, ADDR_FIX_1(2),
2098         8, cmd_handler_mi_semaphore_wait, CMD_LEN(2)},
2099 
2100     {"MI_STORE_DATA_IMM", OP_MI_STORE_DATA_IMM, F_LEN_VAR, R_ALL, D_BDW_PLUS,
2101         ADDR_FIX_1(1), 10, cmd_handler_mi_store_data_imm},
2102 
2103     {"MI_STORE_DATA_INDEX", OP_MI_STORE_DATA_INDEX, F_LEN_VAR, R_ALL, D_ALL,
2104         0, 8, cmd_handler_mi_store_data_index},
2105 
2106     {"MI_LOAD_REGISTER_IMM", OP_MI_LOAD_REGISTER_IMM, F_LEN_VAR, R_ALL,
2107         D_ALL, 0, 8, cmd_handler_lri},
2108 
2109     {"MI_UPDATE_GTT", OP_MI_UPDATE_GTT, F_LEN_VAR, R_ALL, D_BDW_PLUS, 0, 10,
2110         cmd_handler_mi_update_gtt},
2111 
2112     {"MI_STORE_REGISTER_MEM", OP_MI_STORE_REGISTER_MEM,
2113         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2114         cmd_handler_srm, CMD_LEN(2)},
2115 
2116     {"MI_FLUSH_DW", OP_MI_FLUSH_DW, F_LEN_VAR, R_ALL, D_ALL, 0, 6,
2117         cmd_handler_mi_flush_dw},
2118 
2119     {"MI_CLFLUSH", OP_MI_CLFLUSH, F_LEN_VAR, R_ALL, D_ALL, ADDR_FIX_1(1),
2120         10, cmd_handler_mi_clflush},
2121 
2122     {"MI_REPORT_PERF_COUNT", OP_MI_REPORT_PERF_COUNT,
2123         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(1), 6,
2124         cmd_handler_mi_report_perf_count, CMD_LEN(2)},
2125 
2126     {"MI_LOAD_REGISTER_MEM", OP_MI_LOAD_REGISTER_MEM,
2127         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2128         cmd_handler_lrm, CMD_LEN(2)},
2129 
2130     {"MI_LOAD_REGISTER_REG", OP_MI_LOAD_REGISTER_REG,
2131         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, 0, 8,
2132         cmd_handler_lrr, CMD_LEN(1)},
2133 
2134     {"MI_RS_STORE_DATA_IMM", OP_MI_RS_STORE_DATA_IMM,
2135         F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS, D_ALL, 0,
2136         8, NULL, CMD_LEN(2)},
2137 
2138     {"MI_LOAD_URB_MEM", OP_MI_LOAD_URB_MEM, F_LEN_VAR | F_LEN_VAR_FIXED,
2139         R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL, CMD_LEN(2)},
2140 
2141     {"MI_STORE_URM_MEM", OP_MI_STORE_URM_MEM, F_LEN_VAR, R_RCS, D_ALL,
2142         ADDR_FIX_1(2), 8, NULL},
2143 
2144     {"MI_OP_2E", OP_MI_2E, F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS,
2145         ADDR_FIX_2(1, 2), 8, cmd_handler_mi_op_2e, CMD_LEN(3)},
2146 
2147     {"MI_OP_2F", OP_MI_2F, F_LEN_VAR, R_ALL, D_BDW_PLUS, ADDR_FIX_1(1),
2148         8, cmd_handler_mi_op_2f},
2149 
2150     {"MI_BATCH_BUFFER_START", OP_MI_BATCH_BUFFER_START,
2151         F_IP_ADVANCE_CUSTOM, R_ALL, D_ALL, 0, 8,
2152         cmd_handler_mi_batch_buffer_start},
2153 
2154     {"MI_CONDITIONAL_BATCH_BUFFER_END", OP_MI_CONDITIONAL_BATCH_BUFFER_END,
2155         F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
2156         cmd_handler_mi_conditional_batch_buffer_end, CMD_LEN(2)},
2157 
2158     {"MI_LOAD_SCAN_LINES_INCL", OP_MI_LOAD_SCAN_LINES_INCL, F_LEN_CONST,
2159         R_RCS | R_BCS, D_ALL, 0, 2, NULL},
2160 
2161     {"XY_SETUP_BLT", OP_XY_SETUP_BLT, F_LEN_VAR, R_BCS, D_ALL,
2162         ADDR_FIX_2(4, 7), 8, NULL},
2163 
2164     {"XY_SETUP_CLIP_BLT", OP_XY_SETUP_CLIP_BLT, F_LEN_VAR, R_BCS, D_ALL,
2165         0, 8, NULL},
2166 
2167     {"XY_SETUP_MONO_PATTERN_SL_BLT", OP_XY_SETUP_MONO_PATTERN_SL_BLT,
2168         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2169 
2170     {"XY_PIXEL_BLT", OP_XY_PIXEL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
2171 
2172     {"XY_SCANLINES_BLT", OP_XY_SCANLINES_BLT, F_LEN_VAR, R_BCS, D_ALL,
2173         0, 8, NULL},
2174 
2175     {"XY_TEXT_BLT", OP_XY_TEXT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2176         ADDR_FIX_1(3), 8, NULL},
2177 
2178     {"XY_TEXT_IMMEDIATE_BLT", OP_XY_TEXT_IMMEDIATE_BLT, F_LEN_VAR, R_BCS,
2179         D_ALL, 0, 8, NULL},
2180 
2181     {"XY_COLOR_BLT", OP_XY_COLOR_BLT, F_LEN_VAR, R_BCS, D_ALL,
2182         ADDR_FIX_1(4), 8, NULL},
2183 
2184     {"XY_PAT_BLT", OP_XY_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2185         ADDR_FIX_2(4, 5), 8, NULL},
2186 
2187     {"XY_MONO_PAT_BLT", OP_XY_MONO_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
2188         ADDR_FIX_1(4), 8, NULL},
2189 
2190     {"XY_SRC_COPY_BLT", OP_XY_SRC_COPY_BLT, F_LEN_VAR, R_BCS, D_ALL,
2191         ADDR_FIX_2(4, 7), 8, NULL},
2192 
2193     {"XY_MONO_SRC_COPY_BLT", OP_XY_MONO_SRC_COPY_BLT, F_LEN_VAR, R_BCS,
2194         D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2195 
2196     {"XY_FULL_BLT", OP_XY_FULL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
2197 
2198     {"XY_FULL_MONO_SRC_BLT", OP_XY_FULL_MONO_SRC_BLT, F_LEN_VAR, R_BCS,
2199         D_ALL, ADDR_FIX_3(4, 5, 8), 8, NULL},
2200 
2201     {"XY_FULL_MONO_PATTERN_BLT", OP_XY_FULL_MONO_PATTERN_BLT, F_LEN_VAR,
2202         R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2203 
2204     {"XY_FULL_MONO_PATTERN_MONO_SRC_BLT",
2205         OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT,
2206         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2207 
2208     {"XY_MONO_PAT_FIXED_BLT", OP_XY_MONO_PAT_FIXED_BLT, F_LEN_VAR, R_BCS,
2209         D_ALL, ADDR_FIX_1(4), 8, NULL},
2210 
2211     {"XY_MONO_SRC_COPY_IMMEDIATE_BLT", OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT,
2212         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2213 
2214     {"XY_PAT_BLT_IMMEDIATE", OP_XY_PAT_BLT_IMMEDIATE, F_LEN_VAR, R_BCS,
2215         D_ALL, ADDR_FIX_1(4), 8, NULL},
2216 
2217     {"XY_SRC_COPY_CHROMA_BLT", OP_XY_SRC_COPY_CHROMA_BLT, F_LEN_VAR, R_BCS,
2218         D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2219 
2220     {"XY_FULL_IMMEDIATE_PATTERN_BLT", OP_XY_FULL_IMMEDIATE_PATTERN_BLT,
2221         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
2222 
2223     {"XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT",
2224         OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT,
2225         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
2226 
2227     {"XY_PAT_CHROMA_BLT", OP_XY_PAT_CHROMA_BLT, F_LEN_VAR, R_BCS, D_ALL,
2228         ADDR_FIX_2(4, 5), 8, NULL},
2229 
2230     {"XY_PAT_CHROMA_BLT_IMMEDIATE", OP_XY_PAT_CHROMA_BLT_IMMEDIATE,
2231         F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
2232 
2233     {"3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP",
2234         OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
2235         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2236 
2237     {"3DSTATE_VIEWPORT_STATE_POINTERS_CC",
2238         OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
2239         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2240 
2241     {"3DSTATE_BLEND_STATE_POINTERS",
2242         OP_3DSTATE_BLEND_STATE_POINTERS,
2243         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2244 
2245     {"3DSTATE_DEPTH_STENCIL_STATE_POINTERS",
2246         OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
2247         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2248 
2249     {"3DSTATE_BINDING_TABLE_POINTERS_VS",
2250         OP_3DSTATE_BINDING_TABLE_POINTERS_VS,
2251         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2252 
2253     {"3DSTATE_BINDING_TABLE_POINTERS_HS",
2254         OP_3DSTATE_BINDING_TABLE_POINTERS_HS,
2255         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2256 
2257     {"3DSTATE_BINDING_TABLE_POINTERS_DS",
2258         OP_3DSTATE_BINDING_TABLE_POINTERS_DS,
2259         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2260 
2261     {"3DSTATE_BINDING_TABLE_POINTERS_GS",
2262         OP_3DSTATE_BINDING_TABLE_POINTERS_GS,
2263         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2264 
2265     {"3DSTATE_BINDING_TABLE_POINTERS_PS",
2266         OP_3DSTATE_BINDING_TABLE_POINTERS_PS,
2267         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2268 
2269     {"3DSTATE_SAMPLER_STATE_POINTERS_VS",
2270         OP_3DSTATE_SAMPLER_STATE_POINTERS_VS,
2271         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2272 
2273     {"3DSTATE_SAMPLER_STATE_POINTERS_HS",
2274         OP_3DSTATE_SAMPLER_STATE_POINTERS_HS,
2275         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2276 
2277     {"3DSTATE_SAMPLER_STATE_POINTERS_DS",
2278         OP_3DSTATE_SAMPLER_STATE_POINTERS_DS,
2279         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2280 
2281     {"3DSTATE_SAMPLER_STATE_POINTERS_GS",
2282         OP_3DSTATE_SAMPLER_STATE_POINTERS_GS,
2283         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2284 
2285     {"3DSTATE_SAMPLER_STATE_POINTERS_PS",
2286         OP_3DSTATE_SAMPLER_STATE_POINTERS_PS,
2287         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2288 
2289     {"3DSTATE_URB_VS", OP_3DSTATE_URB_VS, F_LEN_VAR, R_RCS, D_ALL,
2290         0, 8, NULL},
2291 
2292     {"3DSTATE_URB_HS", OP_3DSTATE_URB_HS, F_LEN_VAR, R_RCS, D_ALL,
2293         0, 8, NULL},
2294 
2295     {"3DSTATE_URB_DS", OP_3DSTATE_URB_DS, F_LEN_VAR, R_RCS, D_ALL,
2296         0, 8, NULL},
2297 
2298     {"3DSTATE_URB_GS", OP_3DSTATE_URB_GS, F_LEN_VAR, R_RCS, D_ALL,
2299         0, 8, NULL},
2300 
2301     {"3DSTATE_GATHER_CONSTANT_VS", OP_3DSTATE_GATHER_CONSTANT_VS,
2302         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2303 
2304     {"3DSTATE_GATHER_CONSTANT_GS", OP_3DSTATE_GATHER_CONSTANT_GS,
2305         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2306 
2307     {"3DSTATE_GATHER_CONSTANT_HS", OP_3DSTATE_GATHER_CONSTANT_HS,
2308         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2309 
2310     {"3DSTATE_GATHER_CONSTANT_DS", OP_3DSTATE_GATHER_CONSTANT_DS,
2311         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2312 
2313     {"3DSTATE_GATHER_CONSTANT_PS", OP_3DSTATE_GATHER_CONSTANT_PS,
2314         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2315 
2316     {"3DSTATE_DX9_CONSTANTF_VS", OP_3DSTATE_DX9_CONSTANTF_VS,
2317         F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
2318 
2319     {"3DSTATE_DX9_CONSTANTF_PS", OP_3DSTATE_DX9_CONSTANTF_PS,
2320         F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
2321 
2322     {"3DSTATE_DX9_CONSTANTI_VS", OP_3DSTATE_DX9_CONSTANTI_VS,
2323         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2324 
2325     {"3DSTATE_DX9_CONSTANTI_PS", OP_3DSTATE_DX9_CONSTANTI_PS,
2326         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2327 
2328     {"3DSTATE_DX9_CONSTANTB_VS", OP_3DSTATE_DX9_CONSTANTB_VS,
2329         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2330 
2331     {"3DSTATE_DX9_CONSTANTB_PS", OP_3DSTATE_DX9_CONSTANTB_PS,
2332         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2333 
2334     {"3DSTATE_DX9_LOCAL_VALID_VS", OP_3DSTATE_DX9_LOCAL_VALID_VS,
2335         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2336 
2337     {"3DSTATE_DX9_LOCAL_VALID_PS", OP_3DSTATE_DX9_LOCAL_VALID_PS,
2338         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2339 
2340     {"3DSTATE_DX9_GENERATE_ACTIVE_VS", OP_3DSTATE_DX9_GENERATE_ACTIVE_VS,
2341         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2342 
2343     {"3DSTATE_DX9_GENERATE_ACTIVE_PS", OP_3DSTATE_DX9_GENERATE_ACTIVE_PS,
2344         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2345 
2346     {"3DSTATE_BINDING_TABLE_EDIT_VS", OP_3DSTATE_BINDING_TABLE_EDIT_VS,
2347         F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2348 
2349     {"3DSTATE_BINDING_TABLE_EDIT_GS", OP_3DSTATE_BINDING_TABLE_EDIT_GS,
2350         F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2351 
2352     {"3DSTATE_BINDING_TABLE_EDIT_HS", OP_3DSTATE_BINDING_TABLE_EDIT_HS,
2353         F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2354 
2355     {"3DSTATE_BINDING_TABLE_EDIT_DS", OP_3DSTATE_BINDING_TABLE_EDIT_DS,
2356         F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2357 
2358     {"3DSTATE_BINDING_TABLE_EDIT_PS", OP_3DSTATE_BINDING_TABLE_EDIT_PS,
2359         F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
2360 
2361     {"3DSTATE_VF_INSTANCING", OP_3DSTATE_VF_INSTANCING, F_LEN_VAR, R_RCS,
2362         D_BDW_PLUS, 0, 8, NULL},
2363 
2364     {"3DSTATE_VF_SGVS", OP_3DSTATE_VF_SGVS, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2365         NULL},
2366 
2367     {"3DSTATE_VF_TOPOLOGY", OP_3DSTATE_VF_TOPOLOGY, F_LEN_VAR, R_RCS,
2368         D_BDW_PLUS, 0, 8, NULL},
2369 
2370     {"3DSTATE_WM_CHROMAKEY", OP_3DSTATE_WM_CHROMAKEY, F_LEN_VAR, R_RCS,
2371         D_BDW_PLUS, 0, 8, NULL},
2372 
2373     {"3DSTATE_PS_BLEND", OP_3DSTATE_PS_BLEND, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
2374         8, NULL},
2375 
2376     {"3DSTATE_WM_DEPTH_STENCIL", OP_3DSTATE_WM_DEPTH_STENCIL, F_LEN_VAR,
2377         R_RCS, D_BDW_PLUS, 0, 8, NULL},
2378 
2379     {"3DSTATE_PS_EXTRA", OP_3DSTATE_PS_EXTRA, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
2380         8, NULL},
2381 
2382     {"3DSTATE_RASTER", OP_3DSTATE_RASTER, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2383         NULL},
2384 
2385     {"3DSTATE_SBE_SWIZ", OP_3DSTATE_SBE_SWIZ, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2386         NULL},
2387 
2388     {"3DSTATE_WM_HZ_OP", OP_3DSTATE_WM_HZ_OP, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
2389         NULL},
2390 
2391     {"3DSTATE_VERTEX_BUFFERS", OP_3DSTATE_VERTEX_BUFFERS, F_LEN_VAR, R_RCS,
2392         D_BDW_PLUS, 0, 8, NULL},
2393 
2394     {"3DSTATE_VERTEX_ELEMENTS", OP_3DSTATE_VERTEX_ELEMENTS, F_LEN_VAR,
2395         R_RCS, D_ALL, 0, 8, NULL},
2396 
2397     {"3DSTATE_INDEX_BUFFER", OP_3DSTATE_INDEX_BUFFER, F_LEN_VAR, R_RCS,
2398         D_BDW_PLUS, ADDR_FIX_1(2), 8, NULL},
2399 
2400     {"3DSTATE_VF_STATISTICS", OP_3DSTATE_VF_STATISTICS, F_LEN_CONST,
2401         R_RCS, D_ALL, 0, 1, NULL},
2402 
2403     {"3DSTATE_VF", OP_3DSTATE_VF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2404 
2405     {"3DSTATE_CC_STATE_POINTERS", OP_3DSTATE_CC_STATE_POINTERS, F_LEN_VAR,
2406         R_RCS, D_ALL, 0, 8, NULL},
2407 
2408     {"3DSTATE_SCISSOR_STATE_POINTERS", OP_3DSTATE_SCISSOR_STATE_POINTERS,
2409         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2410 
2411     {"3DSTATE_GS", OP_3DSTATE_GS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2412 
2413     {"3DSTATE_CLIP", OP_3DSTATE_CLIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2414 
2415     {"3DSTATE_WM", OP_3DSTATE_WM, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2416 
2417     {"3DSTATE_CONSTANT_GS", OP_3DSTATE_CONSTANT_GS, F_LEN_VAR, R_RCS,
2418         D_BDW_PLUS, 0, 8, NULL},
2419 
2420     {"3DSTATE_CONSTANT_PS", OP_3DSTATE_CONSTANT_PS, F_LEN_VAR, R_RCS,
2421         D_BDW_PLUS, 0, 8, NULL},
2422 
2423     {"3DSTATE_SAMPLE_MASK", OP_3DSTATE_SAMPLE_MASK, F_LEN_VAR, R_RCS,
2424         D_ALL, 0, 8, NULL},
2425 
2426     {"3DSTATE_CONSTANT_HS", OP_3DSTATE_CONSTANT_HS, F_LEN_VAR, R_RCS,
2427         D_BDW_PLUS, 0, 8, NULL},
2428 
2429     {"3DSTATE_CONSTANT_DS", OP_3DSTATE_CONSTANT_DS, F_LEN_VAR, R_RCS,
2430         D_BDW_PLUS, 0, 8, NULL},
2431 
2432     {"3DSTATE_HS", OP_3DSTATE_HS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2433 
2434     {"3DSTATE_TE", OP_3DSTATE_TE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2435 
2436     {"3DSTATE_DS", OP_3DSTATE_DS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2437 
2438     {"3DSTATE_STREAMOUT", OP_3DSTATE_STREAMOUT, F_LEN_VAR, R_RCS,
2439         D_ALL, 0, 8, NULL},
2440 
2441     {"3DSTATE_SBE", OP_3DSTATE_SBE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2442 
2443     {"3DSTATE_PS", OP_3DSTATE_PS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2444 
2445     {"3DSTATE_DRAWING_RECTANGLE", OP_3DSTATE_DRAWING_RECTANGLE, F_LEN_VAR,
2446         R_RCS, D_ALL, 0, 8, NULL},
2447 
2448     {"3DSTATE_SAMPLER_PALETTE_LOAD0", OP_3DSTATE_SAMPLER_PALETTE_LOAD0,
2449         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2450 
2451     {"3DSTATE_CHROMA_KEY", OP_3DSTATE_CHROMA_KEY, F_LEN_VAR, R_RCS, D_ALL,
2452         0, 8, NULL},
2453 
2454     {"3DSTATE_DEPTH_BUFFER", OP_3DSTATE_DEPTH_BUFFER, F_LEN_VAR, R_RCS,
2455         D_ALL, ADDR_FIX_1(2), 8, NULL},
2456 
2457     {"3DSTATE_POLY_STIPPLE_OFFSET", OP_3DSTATE_POLY_STIPPLE_OFFSET,
2458         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2459 
2460     {"3DSTATE_POLY_STIPPLE_PATTERN", OP_3DSTATE_POLY_STIPPLE_PATTERN,
2461         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2462 
2463     {"3DSTATE_LINE_STIPPLE", OP_3DSTATE_LINE_STIPPLE, F_LEN_VAR, R_RCS,
2464         D_ALL, 0, 8, NULL},
2465 
2466     {"3DSTATE_AA_LINE_PARAMS", OP_3DSTATE_AA_LINE_PARAMS, F_LEN_VAR, R_RCS,
2467         D_ALL, 0, 8, NULL},
2468 
2469     {"3DSTATE_GS_SVB_INDEX", OP_3DSTATE_GS_SVB_INDEX, F_LEN_VAR, R_RCS,
2470         D_ALL, 0, 8, NULL},
2471 
2472     {"3DSTATE_SAMPLER_PALETTE_LOAD1", OP_3DSTATE_SAMPLER_PALETTE_LOAD1,
2473         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2474 
2475     {"3DSTATE_MULTISAMPLE", OP_3DSTATE_MULTISAMPLE_BDW, F_LEN_VAR, R_RCS,
2476         D_BDW_PLUS, 0, 8, NULL},
2477 
2478     {"3DSTATE_STENCIL_BUFFER", OP_3DSTATE_STENCIL_BUFFER, F_LEN_VAR, R_RCS,
2479         D_ALL, ADDR_FIX_1(2), 8, NULL},
2480 
2481     {"3DSTATE_HIER_DEPTH_BUFFER", OP_3DSTATE_HIER_DEPTH_BUFFER, F_LEN_VAR,
2482         R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL},
2483 
2484     {"3DSTATE_CLEAR_PARAMS", OP_3DSTATE_CLEAR_PARAMS, F_LEN_VAR,
2485         R_RCS, D_ALL, 0, 8, NULL},
2486 
2487     {"3DSTATE_PUSH_CONSTANT_ALLOC_VS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
2488         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2489 
2490     {"3DSTATE_PUSH_CONSTANT_ALLOC_HS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS,
2491         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2492 
2493     {"3DSTATE_PUSH_CONSTANT_ALLOC_DS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS,
2494         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2495 
2496     {"3DSTATE_PUSH_CONSTANT_ALLOC_GS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
2497         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2498 
2499     {"3DSTATE_PUSH_CONSTANT_ALLOC_PS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
2500         F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2501 
2502     {"3DSTATE_MONOFILTER_SIZE", OP_3DSTATE_MONOFILTER_SIZE, F_LEN_VAR,
2503         R_RCS, D_ALL, 0, 8, NULL},
2504 
2505     {"3DSTATE_SO_DECL_LIST", OP_3DSTATE_SO_DECL_LIST, F_LEN_VAR, R_RCS,
2506         D_ALL, 0, 9, NULL},
2507 
2508     {"3DSTATE_SO_BUFFER", OP_3DSTATE_SO_BUFFER, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2509         ADDR_FIX_2(2, 4), 8, NULL},
2510 
2511     {"3DSTATE_BINDING_TABLE_POOL_ALLOC",
2512         OP_3DSTATE_BINDING_TABLE_POOL_ALLOC,
2513         F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2514 
2515     {"3DSTATE_GATHER_POOL_ALLOC", OP_3DSTATE_GATHER_POOL_ALLOC,
2516         F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2517 
2518     {"3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC",
2519         OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC,
2520         F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
2521 
2522     {"3DSTATE_SAMPLE_PATTERN", OP_3DSTATE_SAMPLE_PATTERN, F_LEN_VAR, R_RCS,
2523         D_BDW_PLUS, 0, 8, NULL},
2524 
2525     {"PIPE_CONTROL", OP_PIPE_CONTROL, F_LEN_VAR, R_RCS, D_ALL,
2526         ADDR_FIX_1(2), 8, cmd_handler_pipe_control},
2527 
2528     {"3DPRIMITIVE", OP_3DPRIMITIVE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2529 
2530     {"PIPELINE_SELECT", OP_PIPELINE_SELECT, F_LEN_CONST, R_RCS, D_ALL, 0,
2531         1, NULL},
2532 
2533     {"STATE_PREFETCH", OP_STATE_PREFETCH, F_LEN_VAR, R_RCS, D_ALL,
2534         ADDR_FIX_1(1), 8, NULL},
2535 
2536     {"STATE_SIP", OP_STATE_SIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2537 
2538     {"STATE_BASE_ADDRESS", OP_STATE_BASE_ADDRESS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2539         ADDR_FIX_5(1, 3, 4, 5, 6), 8, NULL},
2540 
2541     {"OP_3D_MEDIA_0_1_4", OP_3D_MEDIA_0_1_4, F_LEN_VAR, R_RCS, D_ALL,
2542         ADDR_FIX_1(1), 8, NULL},
2543 
2544     {"OP_SWTESS_BASE_ADDRESS", OP_SWTESS_BASE_ADDRESS,
2545         F_LEN_VAR, R_RCS, D_ALL, ADDR_FIX_2(1, 2), 3, NULL},
2546 
2547     {"3DSTATE_VS", OP_3DSTATE_VS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2548 
2549     {"3DSTATE_SF", OP_3DSTATE_SF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
2550 
2551     {"3DSTATE_CONSTANT_VS", OP_3DSTATE_CONSTANT_VS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
2552         0, 8, NULL},
2553 
2554     {"3DSTATE_COMPONENT_PACKING", OP_3DSTATE_COMPONENT_PACKING, F_LEN_VAR, R_RCS,
2555         D_SKL_PLUS, 0, 8, NULL},
2556 
2557     {"MEDIA_INTERFACE_DESCRIPTOR_LOAD", OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
2558         F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
2559 
2560     {"MEDIA_GATEWAY_STATE", OP_MEDIA_GATEWAY_STATE, F_LEN_VAR, R_RCS, D_ALL,
2561         0, 16, NULL},
2562 
2563     {"MEDIA_STATE_FLUSH", OP_MEDIA_STATE_FLUSH, F_LEN_VAR, R_RCS, D_ALL,
2564         0, 16, NULL},
2565 
2566     {"MEDIA_POOL_STATE", OP_MEDIA_POOL_STATE, F_LEN_VAR, R_RCS, D_ALL,
2567         0, 16, NULL},
2568 
2569     {"MEDIA_OBJECT", OP_MEDIA_OBJECT, F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
2570 
2571     {"MEDIA_CURBE_LOAD", OP_MEDIA_CURBE_LOAD, F_LEN_VAR, R_RCS, D_ALL,
2572         0, 16, NULL},
2573 
2574     {"MEDIA_OBJECT_PRT", OP_MEDIA_OBJECT_PRT, F_LEN_VAR, R_RCS, D_ALL,
2575         0, 16, NULL},
2576 
2577     {"MEDIA_OBJECT_WALKER", OP_MEDIA_OBJECT_WALKER, F_LEN_VAR, R_RCS, D_ALL,
2578         0, 16, NULL},
2579 
2580     {"GPGPU_WALKER", OP_GPGPU_WALKER, F_LEN_VAR, R_RCS, D_ALL,
2581         0, 8, NULL},
2582 
2583     {"MEDIA_VFE_STATE", OP_MEDIA_VFE_STATE, F_LEN_VAR, R_RCS, D_ALL, 0, 16,
2584         NULL},
2585 
2586     {"3DSTATE_VF_STATISTICS_GM45", OP_3DSTATE_VF_STATISTICS_GM45,
2587         F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
2588 
2589     {"MFX_PIPE_MODE_SELECT", OP_MFX_PIPE_MODE_SELECT, F_LEN_VAR,
2590         R_VCS, D_ALL, 0, 12, NULL},
2591 
2592     {"MFX_SURFACE_STATE", OP_MFX_SURFACE_STATE, F_LEN_VAR,
2593         R_VCS, D_ALL, 0, 12, NULL},
2594 
2595     {"MFX_PIPE_BUF_ADDR_STATE", OP_MFX_PIPE_BUF_ADDR_STATE, F_LEN_VAR,
2596         R_VCS, D_BDW_PLUS, 0, 12, NULL},
2597 
2598     {"MFX_IND_OBJ_BASE_ADDR_STATE", OP_MFX_IND_OBJ_BASE_ADDR_STATE,
2599         F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
2600 
2601     {"MFX_BSP_BUF_BASE_ADDR_STATE", OP_MFX_BSP_BUF_BASE_ADDR_STATE,
2602         F_LEN_VAR, R_VCS, D_BDW_PLUS, ADDR_FIX_3(1, 3, 5), 12, NULL},
2603 
2604     {"OP_2_0_0_5", OP_2_0_0_5, F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
2605 
2606     {"MFX_STATE_POINTER", OP_MFX_STATE_POINTER, F_LEN_VAR,
2607         R_VCS, D_ALL, 0, 12, NULL},
2608 
2609     {"MFX_QM_STATE", OP_MFX_QM_STATE, F_LEN_VAR,
2610         R_VCS, D_ALL, 0, 12, NULL},
2611 
2612     {"MFX_FQM_STATE", OP_MFX_FQM_STATE, F_LEN_VAR,
2613         R_VCS, D_ALL, 0, 12, NULL},
2614 
2615     {"MFX_PAK_INSERT_OBJECT", OP_MFX_PAK_INSERT_OBJECT, F_LEN_VAR,
2616         R_VCS, D_ALL, 0, 12, NULL},
2617 
2618     {"MFX_STITCH_OBJECT", OP_MFX_STITCH_OBJECT, F_LEN_VAR,
2619         R_VCS, D_ALL, 0, 12, NULL},
2620 
2621     {"MFD_IT_OBJECT", OP_MFD_IT_OBJECT, F_LEN_VAR,
2622         R_VCS, D_ALL, 0, 12, NULL},
2623 
2624     {"MFX_WAIT", OP_MFX_WAIT, F_LEN_VAR,
2625         R_VCS, D_ALL, 0, 6, NULL},
2626 
2627     {"MFX_AVC_IMG_STATE", OP_MFX_AVC_IMG_STATE, F_LEN_VAR,
2628         R_VCS, D_ALL, 0, 12, NULL},
2629 
2630     {"MFX_AVC_QM_STATE", OP_MFX_AVC_QM_STATE, F_LEN_VAR,
2631         R_VCS, D_ALL, 0, 12, NULL},
2632 
2633     {"MFX_AVC_DIRECTMODE_STATE", OP_MFX_AVC_DIRECTMODE_STATE, F_LEN_VAR,
2634         R_VCS, D_ALL, 0, 12, NULL},
2635 
2636     {"MFX_AVC_SLICE_STATE", OP_MFX_AVC_SLICE_STATE, F_LEN_VAR,
2637         R_VCS, D_ALL, 0, 12, NULL},
2638 
2639     {"MFX_AVC_REF_IDX_STATE", OP_MFX_AVC_REF_IDX_STATE, F_LEN_VAR,
2640         R_VCS, D_ALL, 0, 12, NULL},
2641 
2642     {"MFX_AVC_WEIGHTOFFSET_STATE", OP_MFX_AVC_WEIGHTOFFSET_STATE, F_LEN_VAR,
2643         R_VCS, D_ALL, 0, 12, NULL},
2644 
2645     {"MFD_AVC_PICID_STATE", OP_MFD_AVC_PICID_STATE, F_LEN_VAR,
2646         R_VCS, D_ALL, 0, 12, NULL},
2647     {"MFD_AVC_DPB_STATE", OP_MFD_AVC_DPB_STATE, F_LEN_VAR,
2648         R_VCS, D_ALL, 0, 12, NULL},
2649 
2650     {"MFD_AVC_BSD_OBJECT", OP_MFD_AVC_BSD_OBJECT, F_LEN_VAR,
2651         R_VCS, D_ALL, 0, 12, NULL},
2652 
2653     {"MFD_AVC_SLICEADDR", OP_MFD_AVC_SLICEADDR, F_LEN_VAR,
2654         R_VCS, D_ALL, ADDR_FIX_1(2), 12, NULL},
2655 
2656     {"MFC_AVC_PAK_OBJECT", OP_MFC_AVC_PAK_OBJECT, F_LEN_VAR,
2657         R_VCS, D_ALL, 0, 12, NULL},
2658 
2659     {"MFX_VC1_PRED_PIPE_STATE", OP_MFX_VC1_PRED_PIPE_STATE, F_LEN_VAR,
2660         R_VCS, D_ALL, 0, 12, NULL},
2661 
2662     {"MFX_VC1_DIRECTMODE_STATE", OP_MFX_VC1_DIRECTMODE_STATE, F_LEN_VAR,
2663         R_VCS, D_ALL, 0, 12, NULL},
2664 
2665     {"MFD_VC1_SHORT_PIC_STATE", OP_MFD_VC1_SHORT_PIC_STATE, F_LEN_VAR,
2666         R_VCS, D_ALL, 0, 12, NULL},
2667 
2668     {"MFD_VC1_LONG_PIC_STATE", OP_MFD_VC1_LONG_PIC_STATE, F_LEN_VAR,
2669         R_VCS, D_ALL, 0, 12, NULL},
2670 
2671     {"MFD_VC1_BSD_OBJECT", OP_MFD_VC1_BSD_OBJECT, F_LEN_VAR,
2672         R_VCS, D_ALL, 0, 12, NULL},
2673 
2674     {"MFC_MPEG2_SLICEGROUP_STATE", OP_MFC_MPEG2_SLICEGROUP_STATE, F_LEN_VAR,
2675         R_VCS, D_ALL, 0, 12, NULL},
2676 
2677     {"MFC_MPEG2_PAK_OBJECT", OP_MFC_MPEG2_PAK_OBJECT, F_LEN_VAR,
2678         R_VCS, D_ALL, 0, 12, NULL},
2679 
2680     {"MFX_MPEG2_PIC_STATE", OP_MFX_MPEG2_PIC_STATE, F_LEN_VAR,
2681         R_VCS, D_ALL, 0, 12, NULL},
2682 
2683     {"MFX_MPEG2_QM_STATE", OP_MFX_MPEG2_QM_STATE, F_LEN_VAR,
2684         R_VCS, D_ALL, 0, 12, NULL},
2685 
2686     {"MFD_MPEG2_BSD_OBJECT", OP_MFD_MPEG2_BSD_OBJECT, F_LEN_VAR,
2687         R_VCS, D_ALL, 0, 12, NULL},
2688 
2689     {"MFX_2_6_0_0", OP_MFX_2_6_0_0, F_LEN_VAR, R_VCS, D_ALL,
2690         0, 16, NULL},
2691 
2692     {"MFX_2_6_0_9", OP_MFX_2_6_0_9, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
2693 
2694     {"MFX_2_6_0_8", OP_MFX_2_6_0_8, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
2695 
2696     {"MFX_JPEG_PIC_STATE", OP_MFX_JPEG_PIC_STATE, F_LEN_VAR,
2697         R_VCS, D_ALL, 0, 12, NULL},
2698 
2699     {"MFX_JPEG_HUFF_TABLE_STATE", OP_MFX_JPEG_HUFF_TABLE_STATE, F_LEN_VAR,
2700         R_VCS, D_ALL, 0, 12, NULL},
2701 
2702     {"MFD_JPEG_BSD_OBJECT", OP_MFD_JPEG_BSD_OBJECT, F_LEN_VAR,
2703         R_VCS, D_ALL, 0, 12, NULL},
2704 
2705     {"VEBOX_STATE", OP_VEB_STATE, F_LEN_VAR, R_VECS, D_ALL, 0, 12, NULL},
2706 
2707     {"VEBOX_SURFACE_STATE", OP_VEB_SURFACE_STATE, F_LEN_VAR, R_VECS, D_ALL,
2708         0, 12, NULL},
2709 
2710     {"VEB_DI_IECP", OP_VEB_DNDI_IECP_STATE, F_LEN_VAR, R_VECS, D_BDW_PLUS,
2711         0, 12, NULL},
2712 };
2713 
2714 static void add_cmd_entry(struct intel_gvt *gvt, struct cmd_entry *e)
2715 {
2716     hash_add(gvt->cmd_table, &e->hlist, e->info->opcode);
2717 }
2718 
2719 /* call the cmd handler, and advance ip */
2720 static int cmd_parser_exec(struct parser_exec_state *s)
2721 {
2722     struct intel_vgpu *vgpu = s->vgpu;
2723     const struct cmd_info *info;
2724     u32 cmd;
2725     int ret = 0;
2726 
2727     cmd = cmd_val(s, 0);
2728 
2729     /* fastpath for MI_NOOP */
2730     if (cmd == MI_NOOP)
2731         info = &cmd_info[mi_noop_index];
2732     else
2733         info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
2734 
2735     if (info == NULL) {
2736         gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
2737                  cmd, get_opcode(cmd, s->engine),
2738                  repr_addr_type(s->buf_addr_type),
2739                  s->engine->name, s->workload);
2740         return -EBADRQC;
2741     }
2742 
2743     s->info = info;
2744 
2745     trace_gvt_command(vgpu->id, s->engine->id, s->ip_gma, s->ip_va,
2746               cmd_length(s), s->buf_type, s->buf_addr_type,
2747               s->workload, info->name);
2748 
2749     if ((info->flag & F_LEN_MASK) == F_LEN_VAR_FIXED) {
2750         ret = gvt_check_valid_cmd_length(cmd_length(s),
2751                          info->valid_len);
2752         if (ret)
2753             return ret;
2754     }
2755 
2756     if (info->handler) {
2757         ret = info->handler(s);
2758         if (ret < 0) {
2759             gvt_vgpu_err("%s handler error\n", info->name);
2760             return ret;
2761         }
2762     }
2763 
2764     if (!(info->flag & F_IP_ADVANCE_CUSTOM)) {
2765         ret = cmd_advance_default(s);
2766         if (ret) {
2767             gvt_vgpu_err("%s IP advance error\n", info->name);
2768             return ret;
2769         }
2770     }
2771     return 0;
2772 }
2773 
2774 static inline bool gma_out_of_range(unsigned long gma,
2775         unsigned long gma_head, unsigned int gma_tail)
2776 {
2777     if (gma_tail >= gma_head)
2778         return (gma < gma_head) || (gma > gma_tail);
2779     else
2780         return (gma > gma_tail) && (gma < gma_head);
2781 }
2782 
2783 /* Keep the consistent return type, e.g EBADRQC for unknown
2784  * cmd, EFAULT for invalid address, EPERM for nonpriv. later
2785  * works as the input of VM healthy status.
2786  */
2787 static int command_scan(struct parser_exec_state *s,
2788         unsigned long rb_head, unsigned long rb_tail,
2789         unsigned long rb_start, unsigned long rb_len)
2790 {
2791 
2792     unsigned long gma_head, gma_tail, gma_bottom;
2793     int ret = 0;
2794     struct intel_vgpu *vgpu = s->vgpu;
2795 
2796     gma_head = rb_start + rb_head;
2797     gma_tail = rb_start + rb_tail;
2798     gma_bottom = rb_start +  rb_len;
2799 
2800     while (s->ip_gma != gma_tail) {
2801         if (s->buf_type == RING_BUFFER_INSTRUCTION ||
2802                 s->buf_type == RING_BUFFER_CTX) {
2803             if (!(s->ip_gma >= rb_start) ||
2804                 !(s->ip_gma < gma_bottom)) {
2805                 gvt_vgpu_err("ip_gma %lx out of ring scope."
2806                     "(base:0x%lx, bottom: 0x%lx)\n",
2807                     s->ip_gma, rb_start,
2808                     gma_bottom);
2809                 parser_exec_state_dump(s);
2810                 return -EFAULT;
2811             }
2812             if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) {
2813                 gvt_vgpu_err("ip_gma %lx out of range."
2814                     "base 0x%lx head 0x%lx tail 0x%lx\n",
2815                     s->ip_gma, rb_start,
2816                     rb_head, rb_tail);
2817                 parser_exec_state_dump(s);
2818                 break;
2819             }
2820         }
2821         ret = cmd_parser_exec(s);
2822         if (ret) {
2823             gvt_vgpu_err("cmd parser error\n");
2824             parser_exec_state_dump(s);
2825             break;
2826         }
2827     }
2828 
2829     return ret;
2830 }
2831 
2832 static int scan_workload(struct intel_vgpu_workload *workload)
2833 {
2834     unsigned long gma_head, gma_tail, gma_bottom;
2835     struct parser_exec_state s;
2836     int ret = 0;
2837 
2838     /* ring base is page aligned */
2839     if (WARN_ON(!IS_ALIGNED(workload->rb_start, I915_GTT_PAGE_SIZE)))
2840         return -EINVAL;
2841 
2842     gma_head = workload->rb_start + workload->rb_head;
2843     gma_tail = workload->rb_start + workload->rb_tail;
2844     gma_bottom = workload->rb_start +  _RING_CTL_BUF_SIZE(workload->rb_ctl);
2845 
2846     s.buf_type = RING_BUFFER_INSTRUCTION;
2847     s.buf_addr_type = GTT_BUFFER;
2848     s.vgpu = workload->vgpu;
2849     s.engine = workload->engine;
2850     s.ring_start = workload->rb_start;
2851     s.ring_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
2852     s.ring_head = gma_head;
2853     s.ring_tail = gma_tail;
2854     s.rb_va = workload->shadow_ring_buffer_va;
2855     s.workload = workload;
2856     s.is_ctx_wa = false;
2857 
2858     if (bypass_scan_mask & workload->engine->mask || gma_head == gma_tail)
2859         return 0;
2860 
2861     ret = ip_gma_set(&s, gma_head);
2862     if (ret)
2863         goto out;
2864 
2865     ret = command_scan(&s, workload->rb_head, workload->rb_tail,
2866         workload->rb_start, _RING_CTL_BUF_SIZE(workload->rb_ctl));
2867 
2868 out:
2869     return ret;
2870 }
2871 
2872 static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
2873 {
2874 
2875     unsigned long gma_head, gma_tail, gma_bottom, ring_size, ring_tail;
2876     struct parser_exec_state s;
2877     int ret = 0;
2878     struct intel_vgpu_workload *workload = container_of(wa_ctx,
2879                 struct intel_vgpu_workload,
2880                 wa_ctx);
2881 
2882     /* ring base is page aligned */
2883     if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma,
2884                     I915_GTT_PAGE_SIZE)))
2885         return -EINVAL;
2886 
2887     ring_tail = wa_ctx->indirect_ctx.size + 3 * sizeof(u32);
2888     ring_size = round_up(wa_ctx->indirect_ctx.size + CACHELINE_BYTES,
2889             PAGE_SIZE);
2890     gma_head = wa_ctx->indirect_ctx.guest_gma;
2891     gma_tail = wa_ctx->indirect_ctx.guest_gma + ring_tail;
2892     gma_bottom = wa_ctx->indirect_ctx.guest_gma + ring_size;
2893 
2894     s.buf_type = RING_BUFFER_INSTRUCTION;
2895     s.buf_addr_type = GTT_BUFFER;
2896     s.vgpu = workload->vgpu;
2897     s.engine = workload->engine;
2898     s.ring_start = wa_ctx->indirect_ctx.guest_gma;
2899     s.ring_size = ring_size;
2900     s.ring_head = gma_head;
2901     s.ring_tail = gma_tail;
2902     s.rb_va = wa_ctx->indirect_ctx.shadow_va;
2903     s.workload = workload;
2904     s.is_ctx_wa = true;
2905 
2906     ret = ip_gma_set(&s, gma_head);
2907     if (ret)
2908         goto out;
2909 
2910     ret = command_scan(&s, 0, ring_tail,
2911         wa_ctx->indirect_ctx.guest_gma, ring_size);
2912 out:
2913     return ret;
2914 }
2915 
2916 static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
2917 {
2918     struct intel_vgpu *vgpu = workload->vgpu;
2919     struct intel_vgpu_submission *s = &vgpu->submission;
2920     unsigned long gma_head, gma_tail, gma_top, guest_rb_size;
2921     void *shadow_ring_buffer_va;
2922     int ret;
2923 
2924     guest_rb_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
2925 
2926     /* calculate workload ring buffer size */
2927     workload->rb_len = (workload->rb_tail + guest_rb_size -
2928             workload->rb_head) % guest_rb_size;
2929 
2930     gma_head = workload->rb_start + workload->rb_head;
2931     gma_tail = workload->rb_start + workload->rb_tail;
2932     gma_top = workload->rb_start + guest_rb_size;
2933 
2934     if (workload->rb_len > s->ring_scan_buffer_size[workload->engine->id]) {
2935         void *p;
2936 
2937         /* realloc the new ring buffer if needed */
2938         p = krealloc(s->ring_scan_buffer[workload->engine->id],
2939                  workload->rb_len, GFP_KERNEL);
2940         if (!p) {
2941             gvt_vgpu_err("fail to re-alloc ring scan buffer\n");
2942             return -ENOMEM;
2943         }
2944         s->ring_scan_buffer[workload->engine->id] = p;
2945         s->ring_scan_buffer_size[workload->engine->id] = workload->rb_len;
2946     }
2947 
2948     shadow_ring_buffer_va = s->ring_scan_buffer[workload->engine->id];
2949 
2950     /* get shadow ring buffer va */
2951     workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
2952 
2953     /* head > tail --> copy head <-> top */
2954     if (gma_head > gma_tail) {
2955         ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm,
2956                       gma_head, gma_top, shadow_ring_buffer_va);
2957         if (ret < 0) {
2958             gvt_vgpu_err("fail to copy guest ring buffer\n");
2959             return ret;
2960         }
2961         shadow_ring_buffer_va += ret;
2962         gma_head = workload->rb_start;
2963     }
2964 
2965     /* copy head or start <-> tail */
2966     ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, gma_head, gma_tail,
2967                 shadow_ring_buffer_va);
2968     if (ret < 0) {
2969         gvt_vgpu_err("fail to copy guest ring buffer\n");
2970         return ret;
2971     }
2972     return 0;
2973 }
2974 
2975 int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload)
2976 {
2977     int ret;
2978     struct intel_vgpu *vgpu = workload->vgpu;
2979 
2980     ret = shadow_workload_ring_buffer(workload);
2981     if (ret) {
2982         gvt_vgpu_err("fail to shadow workload ring_buffer\n");
2983         return ret;
2984     }
2985 
2986     ret = scan_workload(workload);
2987     if (ret) {
2988         gvt_vgpu_err("scan workload error\n");
2989         return ret;
2990     }
2991     return 0;
2992 }
2993 
2994 static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
2995 {
2996     int ctx_size = wa_ctx->indirect_ctx.size;
2997     unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
2998     struct intel_vgpu_workload *workload = container_of(wa_ctx,
2999                     struct intel_vgpu_workload,
3000                     wa_ctx);
3001     struct intel_vgpu *vgpu = workload->vgpu;
3002     struct drm_i915_gem_object *obj;
3003     int ret = 0;
3004     void *map;
3005 
3006     obj = i915_gem_object_create_shmem(workload->engine->i915,
3007                        roundup(ctx_size + CACHELINE_BYTES,
3008                            PAGE_SIZE));
3009     if (IS_ERR(obj))
3010         return PTR_ERR(obj);
3011 
3012     /* get the va of the shadow batch buffer */
3013     map = i915_gem_object_pin_map(obj, I915_MAP_WB);
3014     if (IS_ERR(map)) {
3015         gvt_vgpu_err("failed to vmap shadow indirect ctx\n");
3016         ret = PTR_ERR(map);
3017         goto put_obj;
3018     }
3019 
3020     i915_gem_object_lock(obj, NULL);
3021     ret = i915_gem_object_set_to_cpu_domain(obj, false);
3022     i915_gem_object_unlock(obj);
3023     if (ret) {
3024         gvt_vgpu_err("failed to set shadow indirect ctx to CPU\n");
3025         goto unmap_src;
3026     }
3027 
3028     ret = copy_gma_to_hva(workload->vgpu,
3029                 workload->vgpu->gtt.ggtt_mm,
3030                 guest_gma, guest_gma + ctx_size,
3031                 map);
3032     if (ret < 0) {
3033         gvt_vgpu_err("fail to copy guest indirect ctx\n");
3034         goto unmap_src;
3035     }
3036 
3037     wa_ctx->indirect_ctx.obj = obj;
3038     wa_ctx->indirect_ctx.shadow_va = map;
3039     return 0;
3040 
3041 unmap_src:
3042     i915_gem_object_unpin_map(obj);
3043 put_obj:
3044     i915_gem_object_put(obj);
3045     return ret;
3046 }
3047 
3048 static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
3049 {
3050     u32 per_ctx_start[CACHELINE_DWORDS] = {0};
3051     unsigned char *bb_start_sva;
3052 
3053     if (!wa_ctx->per_ctx.valid)
3054         return 0;
3055 
3056     per_ctx_start[0] = 0x18800001;
3057     per_ctx_start[1] = wa_ctx->per_ctx.guest_gma;
3058 
3059     bb_start_sva = (unsigned char *)wa_ctx->indirect_ctx.shadow_va +
3060                 wa_ctx->indirect_ctx.size;
3061 
3062     memcpy(bb_start_sva, per_ctx_start, CACHELINE_BYTES);
3063 
3064     return 0;
3065 }
3066 
3067 int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
3068 {
3069     int ret;
3070     struct intel_vgpu_workload *workload = container_of(wa_ctx,
3071                     struct intel_vgpu_workload,
3072                     wa_ctx);
3073     struct intel_vgpu *vgpu = workload->vgpu;
3074 
3075     if (wa_ctx->indirect_ctx.size == 0)
3076         return 0;
3077 
3078     ret = shadow_indirect_ctx(wa_ctx);
3079     if (ret) {
3080         gvt_vgpu_err("fail to shadow indirect ctx\n");
3081         return ret;
3082     }
3083 
3084     combine_wa_ctx(wa_ctx);
3085 
3086     ret = scan_wa_ctx(wa_ctx);
3087     if (ret) {
3088         gvt_vgpu_err("scan wa ctx error\n");
3089         return ret;
3090     }
3091 
3092     return 0;
3093 }
3094 
3095 /* generate dummy contexts by sending empty requests to HW, and let
3096  * the HW to fill Engine Contexts. This dummy contexts are used for
3097  * initialization purpose (update reg whitelist), so referred to as
3098  * init context here
3099  */
3100 void intel_gvt_update_reg_whitelist(struct intel_vgpu *vgpu)
3101 {
3102     const unsigned long start = LRC_STATE_PN * PAGE_SIZE;
3103     struct intel_gvt *gvt = vgpu->gvt;
3104     struct intel_engine_cs *engine;
3105     enum intel_engine_id id;
3106 
3107     if (gvt->is_reg_whitelist_updated)
3108         return;
3109 
3110     /* scan init ctx to update cmd accessible list */
3111     for_each_engine(engine, gvt->gt, id) {
3112         struct parser_exec_state s;
3113         void *vaddr;
3114         int ret;
3115 
3116         if (!engine->default_state)
3117             continue;
3118 
3119         vaddr = shmem_pin_map(engine->default_state);
3120         if (!vaddr) {
3121             gvt_err("failed to map %s->default state\n",
3122                 engine->name);
3123             return;
3124         }
3125 
3126         s.buf_type = RING_BUFFER_CTX;
3127         s.buf_addr_type = GTT_BUFFER;
3128         s.vgpu = vgpu;
3129         s.engine = engine;
3130         s.ring_start = 0;
3131         s.ring_size = engine->context_size - start;
3132         s.ring_head = 0;
3133         s.ring_tail = s.ring_size;
3134         s.rb_va = vaddr + start;
3135         s.workload = NULL;
3136         s.is_ctx_wa = false;
3137         s.is_init_ctx = true;
3138 
3139         /* skipping the first RING_CTX_SIZE(0x50) dwords */
3140         ret = ip_gma_set(&s, RING_CTX_SIZE);
3141         if (ret == 0) {
3142             ret = command_scan(&s, 0, s.ring_size, 0, s.ring_size);
3143             if (ret)
3144                 gvt_err("Scan init ctx error\n");
3145         }
3146 
3147         shmem_unpin_map(engine->default_state, vaddr);
3148         if (ret)
3149             return;
3150     }
3151 
3152     gvt->is_reg_whitelist_updated = true;
3153 }
3154 
3155 int intel_gvt_scan_engine_context(struct intel_vgpu_workload *workload)
3156 {
3157     struct intel_vgpu *vgpu = workload->vgpu;
3158     unsigned long gma_head, gma_tail, gma_start, ctx_size;
3159     struct parser_exec_state s;
3160     int ring_id = workload->engine->id;
3161     struct intel_context *ce = vgpu->submission.shadow[ring_id];
3162     int ret;
3163 
3164     GEM_BUG_ON(atomic_read(&ce->pin_count) < 0);
3165 
3166     ctx_size = workload->engine->context_size - PAGE_SIZE;
3167 
3168     /* Only ring contxt is loaded to HW for inhibit context, no need to
3169      * scan engine context
3170      */
3171     if (is_inhibit_context(ce))
3172         return 0;
3173 
3174     gma_start = i915_ggtt_offset(ce->state) + LRC_STATE_PN*PAGE_SIZE;
3175     gma_head = 0;
3176     gma_tail = ctx_size;
3177 
3178     s.buf_type = RING_BUFFER_CTX;
3179     s.buf_addr_type = GTT_BUFFER;
3180     s.vgpu = workload->vgpu;
3181     s.engine = workload->engine;
3182     s.ring_start = gma_start;
3183     s.ring_size = ctx_size;
3184     s.ring_head = gma_start + gma_head;
3185     s.ring_tail = gma_start + gma_tail;
3186     s.rb_va = ce->lrc_reg_state;
3187     s.workload = workload;
3188     s.is_ctx_wa = false;
3189     s.is_init_ctx = false;
3190 
3191     /* don't scan the first RING_CTX_SIZE(0x50) dwords, as it's ring
3192      * context
3193      */
3194     ret = ip_gma_set(&s, gma_start + gma_head + RING_CTX_SIZE);
3195     if (ret)
3196         goto out;
3197 
3198     ret = command_scan(&s, gma_head, gma_tail,
3199         gma_start, ctx_size);
3200 out:
3201     if (ret)
3202         gvt_vgpu_err("scan shadow ctx error\n");
3203 
3204     return ret;
3205 }
3206 
3207 static int init_cmd_table(struct intel_gvt *gvt)
3208 {
3209     unsigned int gen_type = intel_gvt_get_device_type(gvt);
3210     int i;
3211 
3212     for (i = 0; i < ARRAY_SIZE(cmd_info); i++) {
3213         struct cmd_entry *e;
3214 
3215         if (!(cmd_info[i].devices & gen_type))
3216             continue;
3217 
3218         e = kzalloc(sizeof(*e), GFP_KERNEL);
3219         if (!e)
3220             return -ENOMEM;
3221 
3222         e->info = &cmd_info[i];
3223         if (cmd_info[i].opcode == OP_MI_NOOP)
3224             mi_noop_index = i;
3225 
3226         INIT_HLIST_NODE(&e->hlist);
3227         add_cmd_entry(gvt, e);
3228         gvt_dbg_cmd("add %-30s op %04x flag %x devs %02x rings %02x\n",
3229                 e->info->name, e->info->opcode, e->info->flag,
3230                 e->info->devices, e->info->rings);
3231     }
3232 
3233     return 0;
3234 }
3235 
3236 static void clean_cmd_table(struct intel_gvt *gvt)
3237 {
3238     struct hlist_node *tmp;
3239     struct cmd_entry *e;
3240     int i;
3241 
3242     hash_for_each_safe(gvt->cmd_table, i, tmp, e, hlist)
3243         kfree(e);
3244 
3245     hash_init(gvt->cmd_table);
3246 }
3247 
3248 void intel_gvt_clean_cmd_parser(struct intel_gvt *gvt)
3249 {
3250     clean_cmd_table(gvt);
3251 }
3252 
3253 int intel_gvt_init_cmd_parser(struct intel_gvt *gvt)
3254 {
3255     int ret;
3256 
3257     ret = init_cmd_table(gvt);
3258     if (ret) {
3259         intel_gvt_clean_cmd_parser(gvt);
3260         return ret;
3261     }
3262     return 0;
3263 }