0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
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
0086
0087
0088 #define OP_MI_NOOP 0x0
0089 #define OP_MI_SET_PREDICATE 0x1
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
0095 #define OP_MI_REPORT_HEAD 0x7
0096 #define OP_MI_ARB_ON_OFF 0x8
0097 #define OP_MI_URB_ATOMIC_ALLOC 0x9
0098 #define OP_MI_BATCH_BUFFER_END 0xA
0099 #define OP_MI_SUSPEND_FLUSH 0xB
0100 #define OP_MI_PREDICATE 0xC
0101 #define OP_MI_TOPOLOGY_FILTER 0xD
0102 #define OP_MI_SET_APPID 0xE
0103 #define OP_MI_RS_CONTEXT 0xF
0104 #define OP_MI_LOAD_SCAN_LINES_INCL 0x12
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
0111 #define OP_MI_SEMAPHORE_WAIT 0x1C
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
0122 #define OP_MI_LOAD_REGISTER_REG 0x2A
0123 #define OP_MI_RS_STORE_DATA_IMM 0x2B
0124 #define OP_MI_LOAD_URB_MEM 0x2C
0125 #define OP_MI_STORE_URM_MEM 0x2D
0126 #define OP_MI_2E 0x2E
0127 #define OP_MI_2F 0x2F
0128 #define OP_MI_BATCH_BUFFER_START 0x31
0129
0130
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
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
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)
0196 #define OP_3DSTATE_DEPTH_BUFFER OP_3D_MEDIA(0x3, 0x0, 0x05)
0197 #define OP_3DSTATE_STENCIL_BUFFER OP_3D_MEDIA(0x3, 0x0, 0x06)
0198 #define OP_3DSTATE_HIER_DEPTH_BUFFER OP_3D_MEDIA(0x3, 0x0, 0x07)
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)
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)
0216 #define OP_3DSTATE_CONSTANT_DS OP_3D_MEDIA(0x3, 0x0, 0x1A)
0217 #define OP_3DSTATE_HS OP_3D_MEDIA(0x3, 0x0, 0x1B)
0218 #define OP_3DSTATE_TE OP_3D_MEDIA(0x3, 0x0, 0x1C)
0219 #define OP_3DSTATE_DS OP_3D_MEDIA(0x3, 0x0, 0x1D)
0220 #define OP_3DSTATE_STREAMOUT OP_3D_MEDIA(0x3, 0x0, 0x1E)
0221 #define OP_3DSTATE_SBE OP_3D_MEDIA(0x3, 0x0, 0x1F)
0222 #define OP_3DSTATE_PS OP_3D_MEDIA(0x3, 0x0, 0x20)
0223 #define OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP OP_3D_MEDIA(0x3, 0x0, 0x21)
0224 #define OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC OP_3D_MEDIA(0x3, 0x0, 0x23)
0225 #define OP_3DSTATE_BLEND_STATE_POINTERS OP_3D_MEDIA(0x3, 0x0, 0x24)
0226 #define OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS OP_3D_MEDIA(0x3, 0x0, 0x25)
0227 #define OP_3DSTATE_BINDING_TABLE_POINTERS_VS OP_3D_MEDIA(0x3, 0x0, 0x26)
0228 #define OP_3DSTATE_BINDING_TABLE_POINTERS_HS OP_3D_MEDIA(0x3, 0x0, 0x27)
0229 #define OP_3DSTATE_BINDING_TABLE_POINTERS_DS OP_3D_MEDIA(0x3, 0x0, 0x28)
0230 #define OP_3DSTATE_BINDING_TABLE_POINTERS_GS OP_3D_MEDIA(0x3, 0x0, 0x29)
0231 #define OP_3DSTATE_BINDING_TABLE_POINTERS_PS OP_3D_MEDIA(0x3, 0x0, 0x2A)
0232 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_VS OP_3D_MEDIA(0x3, 0x0, 0x2B)
0233 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_HS OP_3D_MEDIA(0x3, 0x0, 0x2C)
0234 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_DS OP_3D_MEDIA(0x3, 0x0, 0x2D)
0235 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_GS OP_3D_MEDIA(0x3, 0x0, 0x2E)
0236 #define OP_3DSTATE_SAMPLER_STATE_POINTERS_PS OP_3D_MEDIA(0x3, 0x0, 0x2F)
0237 #define OP_3DSTATE_URB_VS OP_3D_MEDIA(0x3, 0x0, 0x30)
0238 #define OP_3DSTATE_URB_HS OP_3D_MEDIA(0x3, 0x0, 0x31)
0239 #define OP_3DSTATE_URB_DS OP_3D_MEDIA(0x3, 0x0, 0x32)
0240 #define OP_3DSTATE_URB_GS OP_3D_MEDIA(0x3, 0x0, 0x33)
0241 #define OP_3DSTATE_GATHER_CONSTANT_VS OP_3D_MEDIA(0x3, 0x0, 0x34)
0242 #define OP_3DSTATE_GATHER_CONSTANT_GS OP_3D_MEDIA(0x3, 0x0, 0x35)
0243 #define OP_3DSTATE_GATHER_CONSTANT_HS OP_3D_MEDIA(0x3, 0x0, 0x36)
0244 #define OP_3DSTATE_GATHER_CONSTANT_DS OP_3D_MEDIA(0x3, 0x0, 0x37)
0245 #define OP_3DSTATE_GATHER_CONSTANT_PS OP_3D_MEDIA(0x3, 0x0, 0x38)
0246 #define OP_3DSTATE_DX9_CONSTANTF_VS OP_3D_MEDIA(0x3, 0x0, 0x39)
0247 #define OP_3DSTATE_DX9_CONSTANTF_PS OP_3D_MEDIA(0x3, 0x0, 0x3A)
0248 #define OP_3DSTATE_DX9_CONSTANTI_VS OP_3D_MEDIA(0x3, 0x0, 0x3B)
0249 #define OP_3DSTATE_DX9_CONSTANTI_PS OP_3D_MEDIA(0x3, 0x0, 0x3C)
0250 #define OP_3DSTATE_DX9_CONSTANTB_VS OP_3D_MEDIA(0x3, 0x0, 0x3D)
0251 #define OP_3DSTATE_DX9_CONSTANTB_PS OP_3D_MEDIA(0x3, 0x0, 0x3E)
0252 #define OP_3DSTATE_DX9_LOCAL_VALID_VS OP_3D_MEDIA(0x3, 0x0, 0x3F)
0253 #define OP_3DSTATE_DX9_LOCAL_VALID_PS OP_3D_MEDIA(0x3, 0x0, 0x40)
0254 #define OP_3DSTATE_DX9_GENERATE_ACTIVE_VS OP_3D_MEDIA(0x3, 0x0, 0x41)
0255 #define OP_3DSTATE_DX9_GENERATE_ACTIVE_PS OP_3D_MEDIA(0x3, 0x0, 0x42)
0256 #define OP_3DSTATE_BINDING_TABLE_EDIT_VS OP_3D_MEDIA(0x3, 0x0, 0x43)
0257 #define OP_3DSTATE_BINDING_TABLE_EDIT_GS OP_3D_MEDIA(0x3, 0x0, 0x44)
0258 #define OP_3DSTATE_BINDING_TABLE_EDIT_HS OP_3D_MEDIA(0x3, 0x0, 0x45)
0259 #define OP_3DSTATE_BINDING_TABLE_EDIT_DS OP_3D_MEDIA(0x3, 0x0, 0x46)
0260 #define OP_3DSTATE_BINDING_TABLE_EDIT_PS OP_3D_MEDIA(0x3, 0x0, 0x47)
0261
0262 #define OP_3DSTATE_VF_INSTANCING OP_3D_MEDIA(0x3, 0x0, 0x49)
0263 #define OP_3DSTATE_VF_SGVS OP_3D_MEDIA(0x3, 0x0, 0x4A)
0264 #define OP_3DSTATE_VF_TOPOLOGY OP_3D_MEDIA(0x3, 0x0, 0x4B)
0265 #define OP_3DSTATE_WM_CHROMAKEY OP_3D_MEDIA(0x3, 0x0, 0x4C)
0266 #define OP_3DSTATE_PS_BLEND OP_3D_MEDIA(0x3, 0x0, 0x4D)
0267 #define OP_3DSTATE_WM_DEPTH_STENCIL OP_3D_MEDIA(0x3, 0x0, 0x4E)
0268 #define OP_3DSTATE_PS_EXTRA OP_3D_MEDIA(0x3, 0x0, 0x4F)
0269 #define OP_3DSTATE_RASTER OP_3D_MEDIA(0x3, 0x0, 0x50)
0270 #define OP_3DSTATE_SBE_SWIZ OP_3D_MEDIA(0x3, 0x0, 0x51)
0271 #define OP_3DSTATE_WM_HZ_OP OP_3D_MEDIA(0x3, 0x0, 0x52)
0272 #define OP_3DSTATE_COMPONENT_PACKING OP_3D_MEDIA(0x3, 0x0, 0x55)
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)
0290 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS OP_3D_MEDIA(0x3, 0x1, 0x13)
0291 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS OP_3D_MEDIA(0x3, 0x1, 0x14)
0292 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS OP_3D_MEDIA(0x3, 0x1, 0x15)
0293 #define OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS OP_3D_MEDIA(0x3, 0x1, 0x16)
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)
0297 #define OP_3DSTATE_GATHER_POOL_ALLOC OP_3D_MEDIA(0x3, 0x1, 0x1A)
0298 #define OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC OP_3D_MEDIA(0x3, 0x1, 0x1B)
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
0304
0305
0306
0307
0308
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)
0320 #define OP_MFX_SURFACE_STATE OP_MFX(2, 0, 0, 1)
0321 #define OP_MFX_PIPE_BUF_ADDR_STATE OP_MFX(2, 0, 0, 2)
0322 #define OP_MFX_IND_OBJ_BASE_ADDR_STATE OP_MFX(2, 0, 0, 3)
0323 #define OP_MFX_BSP_BUF_BASE_ADDR_STATE OP_MFX(2, 0, 0, 4)
0324 #define OP_2_0_0_5 OP_MFX(2, 0, 0, 5)
0325 #define OP_MFX_STATE_POINTER OP_MFX(2, 0, 0, 6)
0326 #define OP_MFX_QM_STATE OP_MFX(2, 0, 0, 7)
0327 #define OP_MFX_FQM_STATE OP_MFX(2, 0, 0, 8)
0328 #define OP_MFX_PAK_INSERT_OBJECT OP_MFX(2, 0, 2, 8)
0329 #define OP_MFX_STITCH_OBJECT OP_MFX(2, 0, 2, 0xA)
0330
0331 #define OP_MFD_IT_OBJECT OP_MFX(2, 0, 1, 9)
0332
0333 #define OP_MFX_WAIT OP_MFX(1, 0, 0, 0)
0334 #define OP_MFX_AVC_IMG_STATE OP_MFX(2, 1, 0, 0)
0335 #define OP_MFX_AVC_QM_STATE OP_MFX(2, 1, 0, 1)
0336 #define OP_MFX_AVC_DIRECTMODE_STATE OP_MFX(2, 1, 0, 2)
0337 #define OP_MFX_AVC_SLICE_STATE OP_MFX(2, 1, 0, 3)
0338 #define OP_MFX_AVC_REF_IDX_STATE OP_MFX(2, 1, 0, 4)
0339 #define OP_MFX_AVC_WEIGHTOFFSET_STATE OP_MFX(2, 1, 0, 5)
0340 #define OP_MFD_AVC_PICID_STATE OP_MFX(2, 1, 1, 5)
0341 #define OP_MFD_AVC_DPB_STATE OP_MFX(2, 1, 1, 6)
0342 #define OP_MFD_AVC_SLICEADDR OP_MFX(2, 1, 1, 7)
0343 #define OP_MFD_AVC_BSD_OBJECT OP_MFX(2, 1, 1, 8)
0344 #define OP_MFC_AVC_PAK_OBJECT OP_MFX(2, 1, 2, 9)
0345
0346 #define OP_MFX_VC1_PRED_PIPE_STATE OP_MFX(2, 2, 0, 1)
0347 #define OP_MFX_VC1_DIRECTMODE_STATE OP_MFX(2, 2, 0, 2)
0348 #define OP_MFD_VC1_SHORT_PIC_STATE OP_MFX(2, 2, 1, 0)
0349 #define OP_MFD_VC1_LONG_PIC_STATE OP_MFX(2, 2, 1, 1)
0350 #define OP_MFD_VC1_BSD_OBJECT OP_MFX(2, 2, 1, 8)
0351
0352 #define OP_MFX_MPEG2_PIC_STATE OP_MFX(2, 3, 0, 0)
0353 #define OP_MFX_MPEG2_QM_STATE OP_MFX(2, 3, 0, 1)
0354 #define OP_MFD_MPEG2_BSD_OBJECT OP_MFX(2, 3, 1, 8)
0355 #define OP_MFC_MPEG2_SLICEGROUP_STATE OP_MFX(2, 3, 2, 3)
0356 #define OP_MFC_MPEG2_PAK_OBJECT OP_MFX(2, 3, 2, 9)
0357
0358 #define OP_MFX_2_6_0_0 OP_MFX(2, 6, 0, 0)
0359 #define OP_MFX_2_6_0_8 OP_MFX(2, 6, 0, 8)
0360 #define OP_MFX_2_6_0_9 OP_MFX(2, 6, 0, 9)
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
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
0414 #define F_LEN_VAR_FIXED (1<<1)
0415
0416
0417
0418
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
0431 intel_engine_mask_t rings;
0432
0433
0434 u16 devices;
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444 u16 addr_bitmap;
0445
0446
0447
0448
0449
0450 u32 len;
0451
0452 parser_cmd_handler handler;
0453
0454
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
0482 int buf_addr_type;
0483
0484
0485 unsigned long ring_start;
0486 unsigned long ring_size;
0487 unsigned long ring_head;
0488 unsigned long ring_tail;
0489
0490
0491 unsigned long ip_gma;
0492
0493
0494 void *ip_va;
0495 void *rb_va;
0496
0497 void *ret_bb_va;
0498
0499 unsigned long ret_ip_gma_ring;
0500
0501
0502 unsigned long ret_ip_gma_bb;
0503
0504
0505
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
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
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
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
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
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 {
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
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
0880
0881
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
0945 return 0;
0946 }
0947
0948 if (strncmp(cmd, "lri", 3))
0949 return -EPERM;
0950
0951
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
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
0999 *vreg = vreg_old;
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
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
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
1189 if (cmd_val(s, 1) & PIPE_CONTROL_MMIO_WRITE)
1190 ret = cmd_reg_handler(s, cmd_reg(s, 2), 1, "pipe_ctrl");
1191
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
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
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
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
1609 if (!(cmd_val(s, 0) & (1 << 22)))
1610 return 0;
1611
1612
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
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
1719 ret = gvt_check_valid_cmd_length(cmd_length(s),
1720 ++valid_len);
1721 return ret;
1722 }
1723
1724
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
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
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
1789
1790
1791 static int batch_buffer_needs_scan(struct parser_exec_state *s)
1792 {
1793
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
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
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
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
1919
1920
1921
1922
1923
1924
1925
1926
1927
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
1972
1973
1974
1975
1976
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
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
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
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
2784
2785
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
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
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
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
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
2951 workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
2952
2953
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
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
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
3096
3097
3098
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
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
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
3169
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
3192
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 }