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