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