18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next
128c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
138c2ecf20Sopenharmony_ci * Software.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
188c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
208c2ecf20Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
218c2ecf20Sopenharmony_ci * SOFTWARE.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * Authors:
248c2ecf20Sopenharmony_ci *    Ke Yu
258c2ecf20Sopenharmony_ci *    Kevin Tian <kevin.tian@intel.com>
268c2ecf20Sopenharmony_ci *    Zhiyuan Lv <zhiyuan.lv@intel.com>
278c2ecf20Sopenharmony_ci *
288c2ecf20Sopenharmony_ci * Contributors:
298c2ecf20Sopenharmony_ci *    Min He <min.he@intel.com>
308c2ecf20Sopenharmony_ci *    Ping Gao <ping.a.gao@intel.com>
318c2ecf20Sopenharmony_ci *    Tina Zhang <tina.zhang@intel.com>
328c2ecf20Sopenharmony_ci *    Yulei Zhang <yulei.zhang@intel.com>
338c2ecf20Sopenharmony_ci *    Zhi Wang <zhi.a.wang@intel.com>
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <linux/slab.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#include "i915_drv.h"
408c2ecf20Sopenharmony_ci#include "gt/intel_ring.h"
418c2ecf20Sopenharmony_ci#include "gvt.h"
428c2ecf20Sopenharmony_ci#include "i915_pvinfo.h"
438c2ecf20Sopenharmony_ci#include "trace.h"
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define INVALID_OP    (~0U)
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define OP_LEN_MI           9
488c2ecf20Sopenharmony_ci#define OP_LEN_2D           10
498c2ecf20Sopenharmony_ci#define OP_LEN_3D_MEDIA     16
508c2ecf20Sopenharmony_ci#define OP_LEN_MFX_VC       16
518c2ecf20Sopenharmony_ci#define OP_LEN_VEBOX	    16
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define CMD_TYPE(cmd)	(((cmd) >> 29) & 7)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistruct sub_op_bits {
568c2ecf20Sopenharmony_ci	int hi;
578c2ecf20Sopenharmony_ci	int low;
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_cistruct decode_info {
608c2ecf20Sopenharmony_ci	const char *name;
618c2ecf20Sopenharmony_ci	int op_len;
628c2ecf20Sopenharmony_ci	int nr_sub_op;
638c2ecf20Sopenharmony_ci	const struct sub_op_bits *sub_op;
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define   MAX_CMD_BUDGET			0x7fffffff
678c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_PLANE_C_FLIP_PENDING      (1<<15)
688c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_PLANE_B_FLIP_PENDING      (1<<9)
698c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_PLANE_A_FLIP_PENDING      (1<<1)
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_SPRITE_C_FLIP_PENDING      (1<<20)
728c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_SPRITE_B_FLIP_PENDING      (1<<10)
738c2ecf20Sopenharmony_ci#define   MI_WAIT_FOR_SPRITE_A_FLIP_PENDING      (1<<2)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/* Render Command Map */
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci/* MI_* command Opcode (28:23) */
788c2ecf20Sopenharmony_ci#define OP_MI_NOOP                          0x0
798c2ecf20Sopenharmony_ci#define OP_MI_SET_PREDICATE                 0x1  /* HSW+ */
808c2ecf20Sopenharmony_ci#define OP_MI_USER_INTERRUPT                0x2
818c2ecf20Sopenharmony_ci#define OP_MI_WAIT_FOR_EVENT                0x3
828c2ecf20Sopenharmony_ci#define OP_MI_FLUSH                         0x4
838c2ecf20Sopenharmony_ci#define OP_MI_ARB_CHECK                     0x5
848c2ecf20Sopenharmony_ci#define OP_MI_RS_CONTROL                    0x6  /* HSW+ */
858c2ecf20Sopenharmony_ci#define OP_MI_REPORT_HEAD                   0x7
868c2ecf20Sopenharmony_ci#define OP_MI_ARB_ON_OFF                    0x8
878c2ecf20Sopenharmony_ci#define OP_MI_URB_ATOMIC_ALLOC              0x9  /* HSW+ */
888c2ecf20Sopenharmony_ci#define OP_MI_BATCH_BUFFER_END              0xA
898c2ecf20Sopenharmony_ci#define OP_MI_SUSPEND_FLUSH                 0xB
908c2ecf20Sopenharmony_ci#define OP_MI_PREDICATE                     0xC  /* IVB+ */
918c2ecf20Sopenharmony_ci#define OP_MI_TOPOLOGY_FILTER               0xD  /* IVB+ */
928c2ecf20Sopenharmony_ci#define OP_MI_SET_APPID                     0xE  /* IVB+ */
938c2ecf20Sopenharmony_ci#define OP_MI_RS_CONTEXT                    0xF  /* HSW+ */
948c2ecf20Sopenharmony_ci#define OP_MI_LOAD_SCAN_LINES_INCL          0x12 /* HSW+ */
958c2ecf20Sopenharmony_ci#define OP_MI_DISPLAY_FLIP                  0x14
968c2ecf20Sopenharmony_ci#define OP_MI_SEMAPHORE_MBOX                0x16
978c2ecf20Sopenharmony_ci#define OP_MI_SET_CONTEXT                   0x18
988c2ecf20Sopenharmony_ci#define OP_MI_MATH                          0x1A
998c2ecf20Sopenharmony_ci#define OP_MI_URB_CLEAR                     0x19
1008c2ecf20Sopenharmony_ci#define OP_MI_SEMAPHORE_SIGNAL		    0x1B  /* BDW+ */
1018c2ecf20Sopenharmony_ci#define OP_MI_SEMAPHORE_WAIT		    0x1C  /* BDW+ */
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#define OP_MI_STORE_DATA_IMM                0x20
1048c2ecf20Sopenharmony_ci#define OP_MI_STORE_DATA_INDEX              0x21
1058c2ecf20Sopenharmony_ci#define OP_MI_LOAD_REGISTER_IMM             0x22
1068c2ecf20Sopenharmony_ci#define OP_MI_UPDATE_GTT                    0x23
1078c2ecf20Sopenharmony_ci#define OP_MI_STORE_REGISTER_MEM            0x24
1088c2ecf20Sopenharmony_ci#define OP_MI_FLUSH_DW                      0x26
1098c2ecf20Sopenharmony_ci#define OP_MI_CLFLUSH                       0x27
1108c2ecf20Sopenharmony_ci#define OP_MI_REPORT_PERF_COUNT             0x28
1118c2ecf20Sopenharmony_ci#define OP_MI_LOAD_REGISTER_MEM             0x29  /* HSW+ */
1128c2ecf20Sopenharmony_ci#define OP_MI_LOAD_REGISTER_REG             0x2A  /* HSW+ */
1138c2ecf20Sopenharmony_ci#define OP_MI_RS_STORE_DATA_IMM             0x2B  /* HSW+ */
1148c2ecf20Sopenharmony_ci#define OP_MI_LOAD_URB_MEM                  0x2C  /* HSW+ */
1158c2ecf20Sopenharmony_ci#define OP_MI_STORE_URM_MEM                 0x2D  /* HSW+ */
1168c2ecf20Sopenharmony_ci#define OP_MI_2E			    0x2E  /* BDW+ */
1178c2ecf20Sopenharmony_ci#define OP_MI_2F			    0x2F  /* BDW+ */
1188c2ecf20Sopenharmony_ci#define OP_MI_BATCH_BUFFER_START            0x31
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/* Bit definition for dword 0 */
1218c2ecf20Sopenharmony_ci#define _CMDBIT_BB_START_IN_PPGTT	(1UL << 8)
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci#define OP_MI_CONDITIONAL_BATCH_BUFFER_END  0x36
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci#define BATCH_BUFFER_ADDR_MASK ((1UL << 32) - (1U << 2))
1268c2ecf20Sopenharmony_ci#define BATCH_BUFFER_ADDR_HIGH_MASK ((1UL << 16) - (1U))
1278c2ecf20Sopenharmony_ci#define BATCH_BUFFER_ADR_SPACE_BIT(x)	(((x) >> 8) & 1U)
1288c2ecf20Sopenharmony_ci#define BATCH_BUFFER_2ND_LEVEL_BIT(x)   ((x) >> 22 & 1U)
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci/* 2D command: Opcode (28:22) */
1318c2ecf20Sopenharmony_ci#define OP_2D(x)    ((2<<7) | x)
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#define OP_XY_SETUP_BLT                             OP_2D(0x1)
1348c2ecf20Sopenharmony_ci#define OP_XY_SETUP_CLIP_BLT                        OP_2D(0x3)
1358c2ecf20Sopenharmony_ci#define OP_XY_SETUP_MONO_PATTERN_SL_BLT             OP_2D(0x11)
1368c2ecf20Sopenharmony_ci#define OP_XY_PIXEL_BLT                             OP_2D(0x24)
1378c2ecf20Sopenharmony_ci#define OP_XY_SCANLINES_BLT                         OP_2D(0x25)
1388c2ecf20Sopenharmony_ci#define OP_XY_TEXT_BLT                              OP_2D(0x26)
1398c2ecf20Sopenharmony_ci#define OP_XY_TEXT_IMMEDIATE_BLT                    OP_2D(0x31)
1408c2ecf20Sopenharmony_ci#define OP_XY_COLOR_BLT                             OP_2D(0x50)
1418c2ecf20Sopenharmony_ci#define OP_XY_PAT_BLT                               OP_2D(0x51)
1428c2ecf20Sopenharmony_ci#define OP_XY_MONO_PAT_BLT                          OP_2D(0x52)
1438c2ecf20Sopenharmony_ci#define OP_XY_SRC_COPY_BLT                          OP_2D(0x53)
1448c2ecf20Sopenharmony_ci#define OP_XY_MONO_SRC_COPY_BLT                     OP_2D(0x54)
1458c2ecf20Sopenharmony_ci#define OP_XY_FULL_BLT                              OP_2D(0x55)
1468c2ecf20Sopenharmony_ci#define OP_XY_FULL_MONO_SRC_BLT                     OP_2D(0x56)
1478c2ecf20Sopenharmony_ci#define OP_XY_FULL_MONO_PATTERN_BLT                 OP_2D(0x57)
1488c2ecf20Sopenharmony_ci#define OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT        OP_2D(0x58)
1498c2ecf20Sopenharmony_ci#define OP_XY_MONO_PAT_FIXED_BLT                    OP_2D(0x59)
1508c2ecf20Sopenharmony_ci#define OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT           OP_2D(0x71)
1518c2ecf20Sopenharmony_ci#define OP_XY_PAT_BLT_IMMEDIATE                     OP_2D(0x72)
1528c2ecf20Sopenharmony_ci#define OP_XY_SRC_COPY_CHROMA_BLT                   OP_2D(0x73)
1538c2ecf20Sopenharmony_ci#define OP_XY_FULL_IMMEDIATE_PATTERN_BLT            OP_2D(0x74)
1548c2ecf20Sopenharmony_ci#define OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT   OP_2D(0x75)
1558c2ecf20Sopenharmony_ci#define OP_XY_PAT_CHROMA_BLT                        OP_2D(0x76)
1568c2ecf20Sopenharmony_ci#define OP_XY_PAT_CHROMA_BLT_IMMEDIATE              OP_2D(0x77)
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/* 3D/Media Command: Pipeline Type(28:27) Opcode(26:24) Sub Opcode(23:16) */
1598c2ecf20Sopenharmony_ci#define OP_3D_MEDIA(sub_type, opcode, sub_opcode) \
1608c2ecf20Sopenharmony_ci	((3 << 13) | ((sub_type) << 11) | ((opcode) << 8) | (sub_opcode))
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci#define OP_STATE_PREFETCH                       OP_3D_MEDIA(0x0, 0x0, 0x03)
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci#define OP_STATE_BASE_ADDRESS                   OP_3D_MEDIA(0x0, 0x1, 0x01)
1658c2ecf20Sopenharmony_ci#define OP_STATE_SIP                            OP_3D_MEDIA(0x0, 0x1, 0x02)
1668c2ecf20Sopenharmony_ci#define OP_3D_MEDIA_0_1_4			OP_3D_MEDIA(0x0, 0x1, 0x04)
1678c2ecf20Sopenharmony_ci#define OP_SWTESS_BASE_ADDRESS			OP_3D_MEDIA(0x0, 0x1, 0x03)
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF_STATISTICS_GM45           OP_3D_MEDIA(0x1, 0x0, 0x0B)
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci#define OP_PIPELINE_SELECT                      OP_3D_MEDIA(0x1, 0x1, 0x04)
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci#define OP_MEDIA_VFE_STATE                      OP_3D_MEDIA(0x2, 0x0, 0x0)
1748c2ecf20Sopenharmony_ci#define OP_MEDIA_CURBE_LOAD                     OP_3D_MEDIA(0x2, 0x0, 0x1)
1758c2ecf20Sopenharmony_ci#define OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD      OP_3D_MEDIA(0x2, 0x0, 0x2)
1768c2ecf20Sopenharmony_ci#define OP_MEDIA_GATEWAY_STATE                  OP_3D_MEDIA(0x2, 0x0, 0x3)
1778c2ecf20Sopenharmony_ci#define OP_MEDIA_STATE_FLUSH                    OP_3D_MEDIA(0x2, 0x0, 0x4)
1788c2ecf20Sopenharmony_ci#define OP_MEDIA_POOL_STATE                     OP_3D_MEDIA(0x2, 0x0, 0x5)
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci#define OP_MEDIA_OBJECT                         OP_3D_MEDIA(0x2, 0x1, 0x0)
1818c2ecf20Sopenharmony_ci#define OP_MEDIA_OBJECT_PRT                     OP_3D_MEDIA(0x2, 0x1, 0x2)
1828c2ecf20Sopenharmony_ci#define OP_MEDIA_OBJECT_WALKER                  OP_3D_MEDIA(0x2, 0x1, 0x3)
1838c2ecf20Sopenharmony_ci#define OP_GPGPU_WALKER                         OP_3D_MEDIA(0x2, 0x1, 0x5)
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci#define OP_3DSTATE_CLEAR_PARAMS                 OP_3D_MEDIA(0x3, 0x0, 0x04) /* IVB+ */
1868c2ecf20Sopenharmony_ci#define OP_3DSTATE_DEPTH_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x05) /* IVB+ */
1878c2ecf20Sopenharmony_ci#define OP_3DSTATE_STENCIL_BUFFER               OP_3D_MEDIA(0x3, 0x0, 0x06) /* IVB+ */
1888c2ecf20Sopenharmony_ci#define OP_3DSTATE_HIER_DEPTH_BUFFER            OP_3D_MEDIA(0x3, 0x0, 0x07) /* IVB+ */
1898c2ecf20Sopenharmony_ci#define OP_3DSTATE_VERTEX_BUFFERS               OP_3D_MEDIA(0x3, 0x0, 0x08)
1908c2ecf20Sopenharmony_ci#define OP_3DSTATE_VERTEX_ELEMENTS              OP_3D_MEDIA(0x3, 0x0, 0x09)
1918c2ecf20Sopenharmony_ci#define OP_3DSTATE_INDEX_BUFFER                 OP_3D_MEDIA(0x3, 0x0, 0x0A)
1928c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF_STATISTICS                OP_3D_MEDIA(0x3, 0x0, 0x0B)
1938c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF                           OP_3D_MEDIA(0x3, 0x0, 0x0C)  /* HSW+ */
1948c2ecf20Sopenharmony_ci#define OP_3DSTATE_CC_STATE_POINTERS            OP_3D_MEDIA(0x3, 0x0, 0x0E)
1958c2ecf20Sopenharmony_ci#define OP_3DSTATE_SCISSOR_STATE_POINTERS       OP_3D_MEDIA(0x3, 0x0, 0x0F)
1968c2ecf20Sopenharmony_ci#define OP_3DSTATE_VS                           OP_3D_MEDIA(0x3, 0x0, 0x10)
1978c2ecf20Sopenharmony_ci#define OP_3DSTATE_GS                           OP_3D_MEDIA(0x3, 0x0, 0x11)
1988c2ecf20Sopenharmony_ci#define OP_3DSTATE_CLIP                         OP_3D_MEDIA(0x3, 0x0, 0x12)
1998c2ecf20Sopenharmony_ci#define OP_3DSTATE_SF                           OP_3D_MEDIA(0x3, 0x0, 0x13)
2008c2ecf20Sopenharmony_ci#define OP_3DSTATE_WM                           OP_3D_MEDIA(0x3, 0x0, 0x14)
2018c2ecf20Sopenharmony_ci#define OP_3DSTATE_CONSTANT_VS                  OP_3D_MEDIA(0x3, 0x0, 0x15)
2028c2ecf20Sopenharmony_ci#define OP_3DSTATE_CONSTANT_GS                  OP_3D_MEDIA(0x3, 0x0, 0x16)
2038c2ecf20Sopenharmony_ci#define OP_3DSTATE_CONSTANT_PS                  OP_3D_MEDIA(0x3, 0x0, 0x17)
2048c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLE_MASK                  OP_3D_MEDIA(0x3, 0x0, 0x18)
2058c2ecf20Sopenharmony_ci#define OP_3DSTATE_CONSTANT_HS                  OP_3D_MEDIA(0x3, 0x0, 0x19) /* IVB+ */
2068c2ecf20Sopenharmony_ci#define OP_3DSTATE_CONSTANT_DS                  OP_3D_MEDIA(0x3, 0x0, 0x1A) /* IVB+ */
2078c2ecf20Sopenharmony_ci#define OP_3DSTATE_HS                           OP_3D_MEDIA(0x3, 0x0, 0x1B) /* IVB+ */
2088c2ecf20Sopenharmony_ci#define OP_3DSTATE_TE                           OP_3D_MEDIA(0x3, 0x0, 0x1C) /* IVB+ */
2098c2ecf20Sopenharmony_ci#define OP_3DSTATE_DS                           OP_3D_MEDIA(0x3, 0x0, 0x1D) /* IVB+ */
2108c2ecf20Sopenharmony_ci#define OP_3DSTATE_STREAMOUT                    OP_3D_MEDIA(0x3, 0x0, 0x1E) /* IVB+ */
2118c2ecf20Sopenharmony_ci#define OP_3DSTATE_SBE                          OP_3D_MEDIA(0x3, 0x0, 0x1F) /* IVB+ */
2128c2ecf20Sopenharmony_ci#define OP_3DSTATE_PS                           OP_3D_MEDIA(0x3, 0x0, 0x20) /* IVB+ */
2138c2ecf20Sopenharmony_ci#define OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP OP_3D_MEDIA(0x3, 0x0, 0x21) /* IVB+ */
2148c2ecf20Sopenharmony_ci#define OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC   OP_3D_MEDIA(0x3, 0x0, 0x23) /* IVB+ */
2158c2ecf20Sopenharmony_ci#define OP_3DSTATE_BLEND_STATE_POINTERS         OP_3D_MEDIA(0x3, 0x0, 0x24) /* IVB+ */
2168c2ecf20Sopenharmony_ci#define OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS OP_3D_MEDIA(0x3, 0x0, 0x25) /* IVB+ */
2178c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x26) /* IVB+ */
2188c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x27) /* IVB+ */
2198c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x28) /* IVB+ */
2208c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x29) /* IVB+ */
2218c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2A) /* IVB+ */
2228c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_STATE_POINTERS_VS    OP_3D_MEDIA(0x3, 0x0, 0x2B) /* IVB+ */
2238c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_STATE_POINTERS_HS    OP_3D_MEDIA(0x3, 0x0, 0x2C) /* IVB+ */
2248c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_STATE_POINTERS_DS    OP_3D_MEDIA(0x3, 0x0, 0x2D) /* IVB+ */
2258c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_STATE_POINTERS_GS    OP_3D_MEDIA(0x3, 0x0, 0x2E) /* IVB+ */
2268c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_STATE_POINTERS_PS    OP_3D_MEDIA(0x3, 0x0, 0x2F) /* IVB+ */
2278c2ecf20Sopenharmony_ci#define OP_3DSTATE_URB_VS                       OP_3D_MEDIA(0x3, 0x0, 0x30) /* IVB+ */
2288c2ecf20Sopenharmony_ci#define OP_3DSTATE_URB_HS                       OP_3D_MEDIA(0x3, 0x0, 0x31) /* IVB+ */
2298c2ecf20Sopenharmony_ci#define OP_3DSTATE_URB_DS                       OP_3D_MEDIA(0x3, 0x0, 0x32) /* IVB+ */
2308c2ecf20Sopenharmony_ci#define OP_3DSTATE_URB_GS                       OP_3D_MEDIA(0x3, 0x0, 0x33) /* IVB+ */
2318c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_CONSTANT_VS           OP_3D_MEDIA(0x3, 0x0, 0x34) /* HSW+ */
2328c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_CONSTANT_GS           OP_3D_MEDIA(0x3, 0x0, 0x35) /* HSW+ */
2338c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_CONSTANT_HS           OP_3D_MEDIA(0x3, 0x0, 0x36) /* HSW+ */
2348c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_CONSTANT_DS           OP_3D_MEDIA(0x3, 0x0, 0x37) /* HSW+ */
2358c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_CONSTANT_PS           OP_3D_MEDIA(0x3, 0x0, 0x38) /* HSW+ */
2368c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTF_VS             OP_3D_MEDIA(0x3, 0x0, 0x39) /* HSW+ */
2378c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTF_PS             OP_3D_MEDIA(0x3, 0x0, 0x3A) /* HSW+ */
2388c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTI_VS             OP_3D_MEDIA(0x3, 0x0, 0x3B) /* HSW+ */
2398c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTI_PS             OP_3D_MEDIA(0x3, 0x0, 0x3C) /* HSW+ */
2408c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTB_VS             OP_3D_MEDIA(0x3, 0x0, 0x3D) /* HSW+ */
2418c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANTB_PS             OP_3D_MEDIA(0x3, 0x0, 0x3E) /* HSW+ */
2428c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_LOCAL_VALID_VS           OP_3D_MEDIA(0x3, 0x0, 0x3F) /* HSW+ */
2438c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_LOCAL_VALID_PS           OP_3D_MEDIA(0x3, 0x0, 0x40) /* HSW+ */
2448c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_GENERATE_ACTIVE_VS       OP_3D_MEDIA(0x3, 0x0, 0x41) /* HSW+ */
2458c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_GENERATE_ACTIVE_PS       OP_3D_MEDIA(0x3, 0x0, 0x42) /* HSW+ */
2468c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_EDIT_VS        OP_3D_MEDIA(0x3, 0x0, 0x43) /* HSW+ */
2478c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_EDIT_GS        OP_3D_MEDIA(0x3, 0x0, 0x44) /* HSW+ */
2488c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_EDIT_HS        OP_3D_MEDIA(0x3, 0x0, 0x45) /* HSW+ */
2498c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_EDIT_DS        OP_3D_MEDIA(0x3, 0x0, 0x46) /* HSW+ */
2508c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_EDIT_PS        OP_3D_MEDIA(0x3, 0x0, 0x47) /* HSW+ */
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF_INSTANCING 		OP_3D_MEDIA(0x3, 0x0, 0x49) /* BDW+ */
2538c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF_SGVS  			OP_3D_MEDIA(0x3, 0x0, 0x4A) /* BDW+ */
2548c2ecf20Sopenharmony_ci#define OP_3DSTATE_VF_TOPOLOGY   		OP_3D_MEDIA(0x3, 0x0, 0x4B) /* BDW+ */
2558c2ecf20Sopenharmony_ci#define OP_3DSTATE_WM_CHROMAKEY   		OP_3D_MEDIA(0x3, 0x0, 0x4C) /* BDW+ */
2568c2ecf20Sopenharmony_ci#define OP_3DSTATE_PS_BLEND   			OP_3D_MEDIA(0x3, 0x0, 0x4D) /* BDW+ */
2578c2ecf20Sopenharmony_ci#define OP_3DSTATE_WM_DEPTH_STENCIL   		OP_3D_MEDIA(0x3, 0x0, 0x4E) /* BDW+ */
2588c2ecf20Sopenharmony_ci#define OP_3DSTATE_PS_EXTRA   			OP_3D_MEDIA(0x3, 0x0, 0x4F) /* BDW+ */
2598c2ecf20Sopenharmony_ci#define OP_3DSTATE_RASTER   			OP_3D_MEDIA(0x3, 0x0, 0x50) /* BDW+ */
2608c2ecf20Sopenharmony_ci#define OP_3DSTATE_SBE_SWIZ   			OP_3D_MEDIA(0x3, 0x0, 0x51) /* BDW+ */
2618c2ecf20Sopenharmony_ci#define OP_3DSTATE_WM_HZ_OP   			OP_3D_MEDIA(0x3, 0x0, 0x52) /* BDW+ */
2628c2ecf20Sopenharmony_ci#define OP_3DSTATE_COMPONENT_PACKING		OP_3D_MEDIA(0x3, 0x0, 0x55) /* SKL+ */
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci#define OP_3DSTATE_DRAWING_RECTANGLE            OP_3D_MEDIA(0x3, 0x1, 0x00)
2658c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_PALETTE_LOAD0        OP_3D_MEDIA(0x3, 0x1, 0x02)
2668c2ecf20Sopenharmony_ci#define OP_3DSTATE_CHROMA_KEY                   OP_3D_MEDIA(0x3, 0x1, 0x04)
2678c2ecf20Sopenharmony_ci#define OP_SNB_3DSTATE_DEPTH_BUFFER             OP_3D_MEDIA(0x3, 0x1, 0x05)
2688c2ecf20Sopenharmony_ci#define OP_3DSTATE_POLY_STIPPLE_OFFSET          OP_3D_MEDIA(0x3, 0x1, 0x06)
2698c2ecf20Sopenharmony_ci#define OP_3DSTATE_POLY_STIPPLE_PATTERN         OP_3D_MEDIA(0x3, 0x1, 0x07)
2708c2ecf20Sopenharmony_ci#define OP_3DSTATE_LINE_STIPPLE                 OP_3D_MEDIA(0x3, 0x1, 0x08)
2718c2ecf20Sopenharmony_ci#define OP_3DSTATE_AA_LINE_PARAMS               OP_3D_MEDIA(0x3, 0x1, 0x0A)
2728c2ecf20Sopenharmony_ci#define OP_3DSTATE_GS_SVB_INDEX                 OP_3D_MEDIA(0x3, 0x1, 0x0B)
2738c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLER_PALETTE_LOAD1        OP_3D_MEDIA(0x3, 0x1, 0x0C)
2748c2ecf20Sopenharmony_ci#define OP_3DSTATE_MULTISAMPLE_BDW		OP_3D_MEDIA(0x3, 0x0, 0x0D)
2758c2ecf20Sopenharmony_ci#define OP_SNB_3DSTATE_STENCIL_BUFFER           OP_3D_MEDIA(0x3, 0x1, 0x0E)
2768c2ecf20Sopenharmony_ci#define OP_SNB_3DSTATE_HIER_DEPTH_BUFFER        OP_3D_MEDIA(0x3, 0x1, 0x0F)
2778c2ecf20Sopenharmony_ci#define OP_SNB_3DSTATE_CLEAR_PARAMS             OP_3D_MEDIA(0x3, 0x1, 0x10)
2788c2ecf20Sopenharmony_ci#define OP_3DSTATE_MONOFILTER_SIZE              OP_3D_MEDIA(0x3, 0x1, 0x11)
2798c2ecf20Sopenharmony_ci#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS       OP_3D_MEDIA(0x3, 0x1, 0x12) /* IVB+ */
2808c2ecf20Sopenharmony_ci#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS       OP_3D_MEDIA(0x3, 0x1, 0x13) /* IVB+ */
2818c2ecf20Sopenharmony_ci#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS       OP_3D_MEDIA(0x3, 0x1, 0x14) /* IVB+ */
2828c2ecf20Sopenharmony_ci#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS       OP_3D_MEDIA(0x3, 0x1, 0x15) /* IVB+ */
2838c2ecf20Sopenharmony_ci#define OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS       OP_3D_MEDIA(0x3, 0x1, 0x16) /* IVB+ */
2848c2ecf20Sopenharmony_ci#define OP_3DSTATE_SO_DECL_LIST                 OP_3D_MEDIA(0x3, 0x1, 0x17)
2858c2ecf20Sopenharmony_ci#define OP_3DSTATE_SO_BUFFER                    OP_3D_MEDIA(0x3, 0x1, 0x18)
2868c2ecf20Sopenharmony_ci#define OP_3DSTATE_BINDING_TABLE_POOL_ALLOC     OP_3D_MEDIA(0x3, 0x1, 0x19) /* HSW+ */
2878c2ecf20Sopenharmony_ci#define OP_3DSTATE_GATHER_POOL_ALLOC            OP_3D_MEDIA(0x3, 0x1, 0x1A) /* HSW+ */
2888c2ecf20Sopenharmony_ci#define OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC OP_3D_MEDIA(0x3, 0x1, 0x1B) /* HSW+ */
2898c2ecf20Sopenharmony_ci#define OP_3DSTATE_SAMPLE_PATTERN               OP_3D_MEDIA(0x3, 0x1, 0x1C)
2908c2ecf20Sopenharmony_ci#define OP_PIPE_CONTROL                         OP_3D_MEDIA(0x3, 0x2, 0x00)
2918c2ecf20Sopenharmony_ci#define OP_3DPRIMITIVE                          OP_3D_MEDIA(0x3, 0x3, 0x00)
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci/* VCCP Command Parser */
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci/*
2968c2ecf20Sopenharmony_ci * Below MFX and VBE cmd definition is from vaapi intel driver project (BSD License)
2978c2ecf20Sopenharmony_ci * git://anongit.freedesktop.org/vaapi/intel-driver
2988c2ecf20Sopenharmony_ci * src/i965_defines.h
2998c2ecf20Sopenharmony_ci *
3008c2ecf20Sopenharmony_ci */
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci#define OP_MFX(pipeline, op, sub_opa, sub_opb)     \
3038c2ecf20Sopenharmony_ci	(3 << 13 | \
3048c2ecf20Sopenharmony_ci	 (pipeline) << 11 | \
3058c2ecf20Sopenharmony_ci	 (op) << 8 | \
3068c2ecf20Sopenharmony_ci	 (sub_opa) << 5 | \
3078c2ecf20Sopenharmony_ci	 (sub_opb))
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci#define OP_MFX_PIPE_MODE_SELECT                    OP_MFX(2, 0, 0, 0)  /* ALL */
3108c2ecf20Sopenharmony_ci#define OP_MFX_SURFACE_STATE                       OP_MFX(2, 0, 0, 1)  /* ALL */
3118c2ecf20Sopenharmony_ci#define OP_MFX_PIPE_BUF_ADDR_STATE                 OP_MFX(2, 0, 0, 2)  /* ALL */
3128c2ecf20Sopenharmony_ci#define OP_MFX_IND_OBJ_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 3)  /* ALL */
3138c2ecf20Sopenharmony_ci#define OP_MFX_BSP_BUF_BASE_ADDR_STATE             OP_MFX(2, 0, 0, 4)  /* ALL */
3148c2ecf20Sopenharmony_ci#define OP_2_0_0_5                                 OP_MFX(2, 0, 0, 5)  /* ALL */
3158c2ecf20Sopenharmony_ci#define OP_MFX_STATE_POINTER                       OP_MFX(2, 0, 0, 6)  /* ALL */
3168c2ecf20Sopenharmony_ci#define OP_MFX_QM_STATE                            OP_MFX(2, 0, 0, 7)  /* IVB+ */
3178c2ecf20Sopenharmony_ci#define OP_MFX_FQM_STATE                           OP_MFX(2, 0, 0, 8)  /* IVB+ */
3188c2ecf20Sopenharmony_ci#define OP_MFX_PAK_INSERT_OBJECT                   OP_MFX(2, 0, 2, 8)  /* IVB+ */
3198c2ecf20Sopenharmony_ci#define OP_MFX_STITCH_OBJECT                       OP_MFX(2, 0, 2, 0xA)  /* IVB+ */
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci#define OP_MFD_IT_OBJECT                           OP_MFX(2, 0, 1, 9) /* ALL */
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci#define OP_MFX_WAIT                                OP_MFX(1, 0, 0, 0) /* IVB+ */
3248c2ecf20Sopenharmony_ci#define OP_MFX_AVC_IMG_STATE                       OP_MFX(2, 1, 0, 0) /* ALL */
3258c2ecf20Sopenharmony_ci#define OP_MFX_AVC_QM_STATE                        OP_MFX(2, 1, 0, 1) /* ALL */
3268c2ecf20Sopenharmony_ci#define OP_MFX_AVC_DIRECTMODE_STATE                OP_MFX(2, 1, 0, 2) /* ALL */
3278c2ecf20Sopenharmony_ci#define OP_MFX_AVC_SLICE_STATE                     OP_MFX(2, 1, 0, 3) /* ALL */
3288c2ecf20Sopenharmony_ci#define OP_MFX_AVC_REF_IDX_STATE                   OP_MFX(2, 1, 0, 4) /* ALL */
3298c2ecf20Sopenharmony_ci#define OP_MFX_AVC_WEIGHTOFFSET_STATE              OP_MFX(2, 1, 0, 5) /* ALL */
3308c2ecf20Sopenharmony_ci#define OP_MFD_AVC_PICID_STATE                     OP_MFX(2, 1, 1, 5) /* HSW+ */
3318c2ecf20Sopenharmony_ci#define OP_MFD_AVC_DPB_STATE			   OP_MFX(2, 1, 1, 6) /* IVB+ */
3328c2ecf20Sopenharmony_ci#define OP_MFD_AVC_SLICEADDR                       OP_MFX(2, 1, 1, 7) /* IVB+ */
3338c2ecf20Sopenharmony_ci#define OP_MFD_AVC_BSD_OBJECT                      OP_MFX(2, 1, 1, 8) /* ALL */
3348c2ecf20Sopenharmony_ci#define OP_MFC_AVC_PAK_OBJECT                      OP_MFX(2, 1, 2, 9) /* ALL */
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci#define OP_MFX_VC1_PRED_PIPE_STATE                 OP_MFX(2, 2, 0, 1) /* ALL */
3378c2ecf20Sopenharmony_ci#define OP_MFX_VC1_DIRECTMODE_STATE                OP_MFX(2, 2, 0, 2) /* ALL */
3388c2ecf20Sopenharmony_ci#define OP_MFD_VC1_SHORT_PIC_STATE                 OP_MFX(2, 2, 1, 0) /* IVB+ */
3398c2ecf20Sopenharmony_ci#define OP_MFD_VC1_LONG_PIC_STATE                  OP_MFX(2, 2, 1, 1) /* IVB+ */
3408c2ecf20Sopenharmony_ci#define OP_MFD_VC1_BSD_OBJECT                      OP_MFX(2, 2, 1, 8) /* ALL */
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci#define OP_MFX_MPEG2_PIC_STATE                     OP_MFX(2, 3, 0, 0) /* ALL */
3438c2ecf20Sopenharmony_ci#define OP_MFX_MPEG2_QM_STATE                      OP_MFX(2, 3, 0, 1) /* ALL */
3448c2ecf20Sopenharmony_ci#define OP_MFD_MPEG2_BSD_OBJECT                    OP_MFX(2, 3, 1, 8) /* ALL */
3458c2ecf20Sopenharmony_ci#define OP_MFC_MPEG2_SLICEGROUP_STATE              OP_MFX(2, 3, 2, 3) /* ALL */
3468c2ecf20Sopenharmony_ci#define OP_MFC_MPEG2_PAK_OBJECT                    OP_MFX(2, 3, 2, 9) /* ALL */
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci#define OP_MFX_2_6_0_0                             OP_MFX(2, 6, 0, 0) /* IVB+ */
3498c2ecf20Sopenharmony_ci#define OP_MFX_2_6_0_8                             OP_MFX(2, 6, 0, 8) /* IVB+ */
3508c2ecf20Sopenharmony_ci#define OP_MFX_2_6_0_9                             OP_MFX(2, 6, 0, 9) /* IVB+ */
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci#define OP_MFX_JPEG_PIC_STATE                      OP_MFX(2, 7, 0, 0)
3538c2ecf20Sopenharmony_ci#define OP_MFX_JPEG_HUFF_TABLE_STATE               OP_MFX(2, 7, 0, 2)
3548c2ecf20Sopenharmony_ci#define OP_MFD_JPEG_BSD_OBJECT                     OP_MFX(2, 7, 1, 8)
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci#define OP_VEB(pipeline, op, sub_opa, sub_opb) \
3578c2ecf20Sopenharmony_ci	(3 << 13 | \
3588c2ecf20Sopenharmony_ci	 (pipeline) << 11 | \
3598c2ecf20Sopenharmony_ci	 (op) << 8 | \
3608c2ecf20Sopenharmony_ci	 (sub_opa) << 5 | \
3618c2ecf20Sopenharmony_ci	 (sub_opb))
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci#define OP_VEB_SURFACE_STATE                       OP_VEB(2, 4, 0, 0)
3648c2ecf20Sopenharmony_ci#define OP_VEB_STATE                               OP_VEB(2, 4, 0, 2)
3658c2ecf20Sopenharmony_ci#define OP_VEB_DNDI_IECP_STATE                     OP_VEB(2, 4, 0, 3)
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_cistruct parser_exec_state;
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_citypedef int (*parser_cmd_handler)(struct parser_exec_state *s);
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci#define GVT_CMD_HASH_BITS   7
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci/* which DWords need address fix */
3748c2ecf20Sopenharmony_ci#define ADDR_FIX_1(x1)			(1 << (x1))
3758c2ecf20Sopenharmony_ci#define ADDR_FIX_2(x1, x2)		(ADDR_FIX_1(x1) | ADDR_FIX_1(x2))
3768c2ecf20Sopenharmony_ci#define ADDR_FIX_3(x1, x2, x3)		(ADDR_FIX_1(x1) | ADDR_FIX_2(x2, x3))
3778c2ecf20Sopenharmony_ci#define ADDR_FIX_4(x1, x2, x3, x4)	(ADDR_FIX_1(x1) | ADDR_FIX_3(x2, x3, x4))
3788c2ecf20Sopenharmony_ci#define ADDR_FIX_5(x1, x2, x3, x4, x5)  (ADDR_FIX_1(x1) | ADDR_FIX_4(x2, x3, x4, x5))
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci#define DWORD_FIELD(dword, end, start) \
3818c2ecf20Sopenharmony_ci	FIELD_GET(GENMASK(end, start), cmd_val(s, dword))
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci#define OP_LENGTH_BIAS 2
3848c2ecf20Sopenharmony_ci#define CMD_LEN(value)  (value + OP_LENGTH_BIAS)
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_cistatic int gvt_check_valid_cmd_length(int len, int valid_len)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	if (valid_len != len) {
3898c2ecf20Sopenharmony_ci		gvt_err("len is not valid:  len=%u  valid_len=%u\n",
3908c2ecf20Sopenharmony_ci			len, valid_len);
3918c2ecf20Sopenharmony_ci		return -EFAULT;
3928c2ecf20Sopenharmony_ci	}
3938c2ecf20Sopenharmony_ci	return 0;
3948c2ecf20Sopenharmony_ci}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistruct cmd_info {
3978c2ecf20Sopenharmony_ci	const char *name;
3988c2ecf20Sopenharmony_ci	u32 opcode;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci#define F_LEN_MASK	3U
4018c2ecf20Sopenharmony_ci#define F_LEN_CONST  1U
4028c2ecf20Sopenharmony_ci#define F_LEN_VAR    0U
4038c2ecf20Sopenharmony_ci/* value is const although LEN maybe variable */
4048c2ecf20Sopenharmony_ci#define F_LEN_VAR_FIXED    (1<<1)
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci/*
4078c2ecf20Sopenharmony_ci * command has its own ip advance logic
4088c2ecf20Sopenharmony_ci * e.g. MI_BATCH_START, MI_BATCH_END
4098c2ecf20Sopenharmony_ci */
4108c2ecf20Sopenharmony_ci#define F_IP_ADVANCE_CUSTOM (1<<2)
4118c2ecf20Sopenharmony_ci	u32 flag;
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci#define R_RCS	BIT(RCS0)
4148c2ecf20Sopenharmony_ci#define R_VCS1  BIT(VCS0)
4158c2ecf20Sopenharmony_ci#define R_VCS2  BIT(VCS1)
4168c2ecf20Sopenharmony_ci#define R_VCS	(R_VCS1 | R_VCS2)
4178c2ecf20Sopenharmony_ci#define R_BCS	BIT(BCS0)
4188c2ecf20Sopenharmony_ci#define R_VECS	BIT(VECS0)
4198c2ecf20Sopenharmony_ci#define R_ALL (R_RCS | R_VCS | R_BCS | R_VECS)
4208c2ecf20Sopenharmony_ci	/* rings that support this cmd: BLT/RCS/VCS/VECS */
4218c2ecf20Sopenharmony_ci	u16 rings;
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	/* devices that support this cmd: SNB/IVB/HSW/... */
4248c2ecf20Sopenharmony_ci	u16 devices;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	/* which DWords are address that need fix up.
4278c2ecf20Sopenharmony_ci	 * bit 0 means a 32-bit non address operand in command
4288c2ecf20Sopenharmony_ci	 * bit 1 means address operand, which could be 32-bit
4298c2ecf20Sopenharmony_ci	 * or 64-bit depending on different architectures.(
4308c2ecf20Sopenharmony_ci	 * defined by "gmadr_bytes_in_cmd" in intel_gvt.
4318c2ecf20Sopenharmony_ci	 * No matter the address length, each address only takes
4328c2ecf20Sopenharmony_ci	 * one bit in the bitmap.
4338c2ecf20Sopenharmony_ci	 */
4348c2ecf20Sopenharmony_ci	u16 addr_bitmap;
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	/* flag == F_LEN_CONST : command length
4378c2ecf20Sopenharmony_ci	 * flag == F_LEN_VAR : length bias bits
4388c2ecf20Sopenharmony_ci	 * Note: length is in DWord
4398c2ecf20Sopenharmony_ci	 */
4408c2ecf20Sopenharmony_ci	u32 len;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	parser_cmd_handler handler;
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	/* valid length in DWord */
4458c2ecf20Sopenharmony_ci	u32 valid_len;
4468c2ecf20Sopenharmony_ci};
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_cistruct cmd_entry {
4498c2ecf20Sopenharmony_ci	struct hlist_node hlist;
4508c2ecf20Sopenharmony_ci	const struct cmd_info *info;
4518c2ecf20Sopenharmony_ci};
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_cienum {
4548c2ecf20Sopenharmony_ci	RING_BUFFER_INSTRUCTION,
4558c2ecf20Sopenharmony_ci	BATCH_BUFFER_INSTRUCTION,
4568c2ecf20Sopenharmony_ci	BATCH_BUFFER_2ND_LEVEL,
4578c2ecf20Sopenharmony_ci};
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_cienum {
4608c2ecf20Sopenharmony_ci	GTT_BUFFER,
4618c2ecf20Sopenharmony_ci	PPGTT_BUFFER
4628c2ecf20Sopenharmony_ci};
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_cistruct parser_exec_state {
4658c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu;
4668c2ecf20Sopenharmony_ci	const struct intel_engine_cs *engine;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	int buf_type;
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	/* batch buffer address type */
4718c2ecf20Sopenharmony_ci	int buf_addr_type;
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	/* graphics memory address of ring buffer start */
4748c2ecf20Sopenharmony_ci	unsigned long ring_start;
4758c2ecf20Sopenharmony_ci	unsigned long ring_size;
4768c2ecf20Sopenharmony_ci	unsigned long ring_head;
4778c2ecf20Sopenharmony_ci	unsigned long ring_tail;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	/* instruction graphics memory address */
4808c2ecf20Sopenharmony_ci	unsigned long ip_gma;
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	/* mapped va of the instr_gma */
4838c2ecf20Sopenharmony_ci	void *ip_va;
4848c2ecf20Sopenharmony_ci	void *rb_va;
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	void *ret_bb_va;
4878c2ecf20Sopenharmony_ci	/* next instruction when return from  batch buffer to ring buffer */
4888c2ecf20Sopenharmony_ci	unsigned long ret_ip_gma_ring;
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci	/* next instruction when return from 2nd batch buffer to batch buffer */
4918c2ecf20Sopenharmony_ci	unsigned long ret_ip_gma_bb;
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	/* batch buffer address type (GTT or PPGTT)
4948c2ecf20Sopenharmony_ci	 * used when ret from 2nd level batch buffer
4958c2ecf20Sopenharmony_ci	 */
4968c2ecf20Sopenharmony_ci	int saved_buf_addr_type;
4978c2ecf20Sopenharmony_ci	bool is_ctx_wa;
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci	const struct cmd_info *info;
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	struct intel_vgpu_workload *workload;
5028c2ecf20Sopenharmony_ci};
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci#define gmadr_dw_number(s)	\
5058c2ecf20Sopenharmony_ci	(s->vgpu->gvt->device_info.gmadr_bytes_in_cmd >> 2)
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_cistatic unsigned long bypass_scan_mask = 0;
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci/* ring ALL, type = 0 */
5108c2ecf20Sopenharmony_cistatic const struct sub_op_bits sub_op_mi[] = {
5118c2ecf20Sopenharmony_ci	{31, 29},
5128c2ecf20Sopenharmony_ci	{28, 23},
5138c2ecf20Sopenharmony_ci};
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_cistatic const struct decode_info decode_info_mi = {
5168c2ecf20Sopenharmony_ci	"MI",
5178c2ecf20Sopenharmony_ci	OP_LEN_MI,
5188c2ecf20Sopenharmony_ci	ARRAY_SIZE(sub_op_mi),
5198c2ecf20Sopenharmony_ci	sub_op_mi,
5208c2ecf20Sopenharmony_ci};
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci/* ring RCS, command type 2 */
5238c2ecf20Sopenharmony_cistatic const struct sub_op_bits sub_op_2d[] = {
5248c2ecf20Sopenharmony_ci	{31, 29},
5258c2ecf20Sopenharmony_ci	{28, 22},
5268c2ecf20Sopenharmony_ci};
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_cistatic const struct decode_info decode_info_2d = {
5298c2ecf20Sopenharmony_ci	"2D",
5308c2ecf20Sopenharmony_ci	OP_LEN_2D,
5318c2ecf20Sopenharmony_ci	ARRAY_SIZE(sub_op_2d),
5328c2ecf20Sopenharmony_ci	sub_op_2d,
5338c2ecf20Sopenharmony_ci};
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci/* ring RCS, command type 3 */
5368c2ecf20Sopenharmony_cistatic const struct sub_op_bits sub_op_3d_media[] = {
5378c2ecf20Sopenharmony_ci	{31, 29},
5388c2ecf20Sopenharmony_ci	{28, 27},
5398c2ecf20Sopenharmony_ci	{26, 24},
5408c2ecf20Sopenharmony_ci	{23, 16},
5418c2ecf20Sopenharmony_ci};
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_cistatic const struct decode_info decode_info_3d_media = {
5448c2ecf20Sopenharmony_ci	"3D_Media",
5458c2ecf20Sopenharmony_ci	OP_LEN_3D_MEDIA,
5468c2ecf20Sopenharmony_ci	ARRAY_SIZE(sub_op_3d_media),
5478c2ecf20Sopenharmony_ci	sub_op_3d_media,
5488c2ecf20Sopenharmony_ci};
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci/* ring VCS, command type 3 */
5518c2ecf20Sopenharmony_cistatic const struct sub_op_bits sub_op_mfx_vc[] = {
5528c2ecf20Sopenharmony_ci	{31, 29},
5538c2ecf20Sopenharmony_ci	{28, 27},
5548c2ecf20Sopenharmony_ci	{26, 24},
5558c2ecf20Sopenharmony_ci	{23, 21},
5568c2ecf20Sopenharmony_ci	{20, 16},
5578c2ecf20Sopenharmony_ci};
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_cistatic const struct decode_info decode_info_mfx_vc = {
5608c2ecf20Sopenharmony_ci	"MFX_VC",
5618c2ecf20Sopenharmony_ci	OP_LEN_MFX_VC,
5628c2ecf20Sopenharmony_ci	ARRAY_SIZE(sub_op_mfx_vc),
5638c2ecf20Sopenharmony_ci	sub_op_mfx_vc,
5648c2ecf20Sopenharmony_ci};
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci/* ring VECS, command type 3 */
5678c2ecf20Sopenharmony_cistatic const struct sub_op_bits sub_op_vebox[] = {
5688c2ecf20Sopenharmony_ci	{31, 29},
5698c2ecf20Sopenharmony_ci	{28, 27},
5708c2ecf20Sopenharmony_ci	{26, 24},
5718c2ecf20Sopenharmony_ci	{23, 21},
5728c2ecf20Sopenharmony_ci	{20, 16},
5738c2ecf20Sopenharmony_ci};
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_cistatic const struct decode_info decode_info_vebox = {
5768c2ecf20Sopenharmony_ci	"VEBOX",
5778c2ecf20Sopenharmony_ci	OP_LEN_VEBOX,
5788c2ecf20Sopenharmony_ci	ARRAY_SIZE(sub_op_vebox),
5798c2ecf20Sopenharmony_ci	sub_op_vebox,
5808c2ecf20Sopenharmony_ci};
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_cistatic const struct decode_info *ring_decode_info[I915_NUM_ENGINES][8] = {
5838c2ecf20Sopenharmony_ci	[RCS0] = {
5848c2ecf20Sopenharmony_ci		&decode_info_mi,
5858c2ecf20Sopenharmony_ci		NULL,
5868c2ecf20Sopenharmony_ci		NULL,
5878c2ecf20Sopenharmony_ci		&decode_info_3d_media,
5888c2ecf20Sopenharmony_ci		NULL,
5898c2ecf20Sopenharmony_ci		NULL,
5908c2ecf20Sopenharmony_ci		NULL,
5918c2ecf20Sopenharmony_ci		NULL,
5928c2ecf20Sopenharmony_ci	},
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci	[VCS0] = {
5958c2ecf20Sopenharmony_ci		&decode_info_mi,
5968c2ecf20Sopenharmony_ci		NULL,
5978c2ecf20Sopenharmony_ci		NULL,
5988c2ecf20Sopenharmony_ci		&decode_info_mfx_vc,
5998c2ecf20Sopenharmony_ci		NULL,
6008c2ecf20Sopenharmony_ci		NULL,
6018c2ecf20Sopenharmony_ci		NULL,
6028c2ecf20Sopenharmony_ci		NULL,
6038c2ecf20Sopenharmony_ci	},
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci	[BCS0] = {
6068c2ecf20Sopenharmony_ci		&decode_info_mi,
6078c2ecf20Sopenharmony_ci		NULL,
6088c2ecf20Sopenharmony_ci		&decode_info_2d,
6098c2ecf20Sopenharmony_ci		NULL,
6108c2ecf20Sopenharmony_ci		NULL,
6118c2ecf20Sopenharmony_ci		NULL,
6128c2ecf20Sopenharmony_ci		NULL,
6138c2ecf20Sopenharmony_ci		NULL,
6148c2ecf20Sopenharmony_ci	},
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci	[VECS0] = {
6178c2ecf20Sopenharmony_ci		&decode_info_mi,
6188c2ecf20Sopenharmony_ci		NULL,
6198c2ecf20Sopenharmony_ci		NULL,
6208c2ecf20Sopenharmony_ci		&decode_info_vebox,
6218c2ecf20Sopenharmony_ci		NULL,
6228c2ecf20Sopenharmony_ci		NULL,
6238c2ecf20Sopenharmony_ci		NULL,
6248c2ecf20Sopenharmony_ci		NULL,
6258c2ecf20Sopenharmony_ci	},
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci	[VCS1] = {
6288c2ecf20Sopenharmony_ci		&decode_info_mi,
6298c2ecf20Sopenharmony_ci		NULL,
6308c2ecf20Sopenharmony_ci		NULL,
6318c2ecf20Sopenharmony_ci		&decode_info_mfx_vc,
6328c2ecf20Sopenharmony_ci		NULL,
6338c2ecf20Sopenharmony_ci		NULL,
6348c2ecf20Sopenharmony_ci		NULL,
6358c2ecf20Sopenharmony_ci		NULL,
6368c2ecf20Sopenharmony_ci	},
6378c2ecf20Sopenharmony_ci};
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_cistatic inline u32 get_opcode(u32 cmd, const struct intel_engine_cs *engine)
6408c2ecf20Sopenharmony_ci{
6418c2ecf20Sopenharmony_ci	const struct decode_info *d_info;
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
6448c2ecf20Sopenharmony_ci	if (d_info == NULL)
6458c2ecf20Sopenharmony_ci		return INVALID_OP;
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	return cmd >> (32 - d_info->op_len);
6488c2ecf20Sopenharmony_ci}
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_cistatic inline const struct cmd_info *
6518c2ecf20Sopenharmony_cifind_cmd_entry(struct intel_gvt *gvt, unsigned int opcode,
6528c2ecf20Sopenharmony_ci	       const struct intel_engine_cs *engine)
6538c2ecf20Sopenharmony_ci{
6548c2ecf20Sopenharmony_ci	struct cmd_entry *e;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	hash_for_each_possible(gvt->cmd_table, e, hlist, opcode) {
6578c2ecf20Sopenharmony_ci		if (opcode == e->info->opcode &&
6588c2ecf20Sopenharmony_ci		    e->info->rings & engine->mask)
6598c2ecf20Sopenharmony_ci			return e->info;
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci	return NULL;
6628c2ecf20Sopenharmony_ci}
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_cistatic inline const struct cmd_info *
6658c2ecf20Sopenharmony_ciget_cmd_info(struct intel_gvt *gvt, u32 cmd,
6668c2ecf20Sopenharmony_ci	     const struct intel_engine_cs *engine)
6678c2ecf20Sopenharmony_ci{
6688c2ecf20Sopenharmony_ci	u32 opcode;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	opcode = get_opcode(cmd, engine);
6718c2ecf20Sopenharmony_ci	if (opcode == INVALID_OP)
6728c2ecf20Sopenharmony_ci		return NULL;
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci	return find_cmd_entry(gvt, opcode, engine);
6758c2ecf20Sopenharmony_ci}
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_cistatic inline u32 sub_op_val(u32 cmd, u32 hi, u32 low)
6788c2ecf20Sopenharmony_ci{
6798c2ecf20Sopenharmony_ci	return (cmd >> low) & ((1U << (hi - low + 1)) - 1);
6808c2ecf20Sopenharmony_ci}
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_cistatic inline void print_opcode(u32 cmd, const struct intel_engine_cs *engine)
6838c2ecf20Sopenharmony_ci{
6848c2ecf20Sopenharmony_ci	const struct decode_info *d_info;
6858c2ecf20Sopenharmony_ci	int i;
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	d_info = ring_decode_info[engine->id][CMD_TYPE(cmd)];
6888c2ecf20Sopenharmony_ci	if (d_info == NULL)
6898c2ecf20Sopenharmony_ci		return;
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	gvt_dbg_cmd("opcode=0x%x %s sub_ops:",
6928c2ecf20Sopenharmony_ci			cmd >> (32 - d_info->op_len), d_info->name);
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	for (i = 0; i < d_info->nr_sub_op; i++)
6958c2ecf20Sopenharmony_ci		pr_err("0x%x ", sub_op_val(cmd, d_info->sub_op[i].hi,
6968c2ecf20Sopenharmony_ci					d_info->sub_op[i].low));
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	pr_err("\n");
6998c2ecf20Sopenharmony_ci}
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_cistatic inline u32 *cmd_ptr(struct parser_exec_state *s, int index)
7028c2ecf20Sopenharmony_ci{
7038c2ecf20Sopenharmony_ci	return s->ip_va + (index << 2);
7048c2ecf20Sopenharmony_ci}
7058c2ecf20Sopenharmony_ci
7068c2ecf20Sopenharmony_cistatic inline u32 cmd_val(struct parser_exec_state *s, int index)
7078c2ecf20Sopenharmony_ci{
7088c2ecf20Sopenharmony_ci	return *cmd_ptr(s, index);
7098c2ecf20Sopenharmony_ci}
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_cistatic void parser_exec_state_dump(struct parser_exec_state *s)
7128c2ecf20Sopenharmony_ci{
7138c2ecf20Sopenharmony_ci	int cnt = 0;
7148c2ecf20Sopenharmony_ci	int i;
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_ci	gvt_dbg_cmd("  vgpu%d RING%s: ring_start(%08lx) ring_end(%08lx)"
7178c2ecf20Sopenharmony_ci		    " ring_head(%08lx) ring_tail(%08lx)\n",
7188c2ecf20Sopenharmony_ci		    s->vgpu->id, s->engine->name,
7198c2ecf20Sopenharmony_ci		    s->ring_start, s->ring_start + s->ring_size,
7208c2ecf20Sopenharmony_ci		    s->ring_head, s->ring_tail);
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_ci	gvt_dbg_cmd("  %s %s ip_gma(%08lx) ",
7238c2ecf20Sopenharmony_ci			s->buf_type == RING_BUFFER_INSTRUCTION ?
7248c2ecf20Sopenharmony_ci			"RING_BUFFER" : "BATCH_BUFFER",
7258c2ecf20Sopenharmony_ci			s->buf_addr_type == GTT_BUFFER ?
7268c2ecf20Sopenharmony_ci			"GTT" : "PPGTT", s->ip_gma);
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci	if (s->ip_va == NULL) {
7298c2ecf20Sopenharmony_ci		gvt_dbg_cmd(" ip_va(NULL)");
7308c2ecf20Sopenharmony_ci		return;
7318c2ecf20Sopenharmony_ci	}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci	gvt_dbg_cmd("  ip_va=%p: %08x %08x %08x %08x\n",
7348c2ecf20Sopenharmony_ci			s->ip_va, cmd_val(s, 0), cmd_val(s, 1),
7358c2ecf20Sopenharmony_ci			cmd_val(s, 2), cmd_val(s, 3));
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	print_opcode(cmd_val(s, 0), s->engine);
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_ci	s->ip_va = (u32 *)((((u64)s->ip_va) >> 12) << 12);
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_ci	while (cnt < 1024) {
7428c2ecf20Sopenharmony_ci		gvt_dbg_cmd("ip_va=%p: ", s->ip_va);
7438c2ecf20Sopenharmony_ci		for (i = 0; i < 8; i++)
7448c2ecf20Sopenharmony_ci			gvt_dbg_cmd("%08x ", cmd_val(s, i));
7458c2ecf20Sopenharmony_ci		gvt_dbg_cmd("\n");
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci		s->ip_va += 8 * sizeof(u32);
7488c2ecf20Sopenharmony_ci		cnt += 8;
7498c2ecf20Sopenharmony_ci	}
7508c2ecf20Sopenharmony_ci}
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_cistatic inline void update_ip_va(struct parser_exec_state *s)
7538c2ecf20Sopenharmony_ci{
7548c2ecf20Sopenharmony_ci	unsigned long len = 0;
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci	if (WARN_ON(s->ring_head == s->ring_tail))
7578c2ecf20Sopenharmony_ci		return;
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ci	if (s->buf_type == RING_BUFFER_INSTRUCTION) {
7608c2ecf20Sopenharmony_ci		unsigned long ring_top = s->ring_start + s->ring_size;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci		if (s->ring_head > s->ring_tail) {
7638c2ecf20Sopenharmony_ci			if (s->ip_gma >= s->ring_head && s->ip_gma < ring_top)
7648c2ecf20Sopenharmony_ci				len = (s->ip_gma - s->ring_head);
7658c2ecf20Sopenharmony_ci			else if (s->ip_gma >= s->ring_start &&
7668c2ecf20Sopenharmony_ci					s->ip_gma <= s->ring_tail)
7678c2ecf20Sopenharmony_ci				len = (ring_top - s->ring_head) +
7688c2ecf20Sopenharmony_ci					(s->ip_gma - s->ring_start);
7698c2ecf20Sopenharmony_ci		} else
7708c2ecf20Sopenharmony_ci			len = (s->ip_gma - s->ring_head);
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci		s->ip_va = s->rb_va + len;
7738c2ecf20Sopenharmony_ci	} else {/* shadow batch buffer */
7748c2ecf20Sopenharmony_ci		s->ip_va = s->ret_bb_va;
7758c2ecf20Sopenharmony_ci	}
7768c2ecf20Sopenharmony_ci}
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_cistatic inline int ip_gma_set(struct parser_exec_state *s,
7798c2ecf20Sopenharmony_ci		unsigned long ip_gma)
7808c2ecf20Sopenharmony_ci{
7818c2ecf20Sopenharmony_ci	WARN_ON(!IS_ALIGNED(ip_gma, 4));
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	s->ip_gma = ip_gma;
7848c2ecf20Sopenharmony_ci	update_ip_va(s);
7858c2ecf20Sopenharmony_ci	return 0;
7868c2ecf20Sopenharmony_ci}
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_cistatic inline int ip_gma_advance(struct parser_exec_state *s,
7898c2ecf20Sopenharmony_ci		unsigned int dw_len)
7908c2ecf20Sopenharmony_ci{
7918c2ecf20Sopenharmony_ci	s->ip_gma += (dw_len << 2);
7928c2ecf20Sopenharmony_ci
7938c2ecf20Sopenharmony_ci	if (s->buf_type == RING_BUFFER_INSTRUCTION) {
7948c2ecf20Sopenharmony_ci		if (s->ip_gma >= s->ring_start + s->ring_size)
7958c2ecf20Sopenharmony_ci			s->ip_gma -= s->ring_size;
7968c2ecf20Sopenharmony_ci		update_ip_va(s);
7978c2ecf20Sopenharmony_ci	} else {
7988c2ecf20Sopenharmony_ci		s->ip_va += (dw_len << 2);
7998c2ecf20Sopenharmony_ci	}
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_ci	return 0;
8028c2ecf20Sopenharmony_ci}
8038c2ecf20Sopenharmony_ci
8048c2ecf20Sopenharmony_cistatic inline int get_cmd_length(const struct cmd_info *info, u32 cmd)
8058c2ecf20Sopenharmony_ci{
8068c2ecf20Sopenharmony_ci	if ((info->flag & F_LEN_MASK) == F_LEN_CONST)
8078c2ecf20Sopenharmony_ci		return info->len;
8088c2ecf20Sopenharmony_ci	else
8098c2ecf20Sopenharmony_ci		return (cmd & ((1U << info->len) - 1)) + 2;
8108c2ecf20Sopenharmony_ci	return 0;
8118c2ecf20Sopenharmony_ci}
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_cistatic inline int cmd_length(struct parser_exec_state *s)
8148c2ecf20Sopenharmony_ci{
8158c2ecf20Sopenharmony_ci	return get_cmd_length(s->info, cmd_val(s, 0));
8168c2ecf20Sopenharmony_ci}
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci/* do not remove this, some platform may need clflush here */
8198c2ecf20Sopenharmony_ci#define patch_value(s, addr, val) do { \
8208c2ecf20Sopenharmony_ci	*addr = val; \
8218c2ecf20Sopenharmony_ci} while (0)
8228c2ecf20Sopenharmony_ci
8238c2ecf20Sopenharmony_cistatic bool is_shadowed_mmio(unsigned int offset)
8248c2ecf20Sopenharmony_ci{
8258c2ecf20Sopenharmony_ci	bool ret = false;
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci	if ((offset == 0x2168) || /*BB current head register UDW */
8288c2ecf20Sopenharmony_ci	    (offset == 0x2140) || /*BB current header register */
8298c2ecf20Sopenharmony_ci	    (offset == 0x211c) || /*second BB header register UDW */
8308c2ecf20Sopenharmony_ci	    (offset == 0x2114)) { /*second BB header register UDW */
8318c2ecf20Sopenharmony_ci		ret = true;
8328c2ecf20Sopenharmony_ci	}
8338c2ecf20Sopenharmony_ci	return ret;
8348c2ecf20Sopenharmony_ci}
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_cistatic inline bool is_force_nonpriv_mmio(unsigned int offset)
8378c2ecf20Sopenharmony_ci{
8388c2ecf20Sopenharmony_ci	return (offset >= 0x24d0 && offset < 0x2500);
8398c2ecf20Sopenharmony_ci}
8408c2ecf20Sopenharmony_ci
8418c2ecf20Sopenharmony_cistatic int force_nonpriv_reg_handler(struct parser_exec_state *s,
8428c2ecf20Sopenharmony_ci		unsigned int offset, unsigned int index, char *cmd)
8438c2ecf20Sopenharmony_ci{
8448c2ecf20Sopenharmony_ci	struct intel_gvt *gvt = s->vgpu->gvt;
8458c2ecf20Sopenharmony_ci	unsigned int data;
8468c2ecf20Sopenharmony_ci	u32 ring_base;
8478c2ecf20Sopenharmony_ci	u32 nopid;
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_ci	if (!strcmp(cmd, "lri"))
8508c2ecf20Sopenharmony_ci		data = cmd_val(s, index + 1);
8518c2ecf20Sopenharmony_ci	else {
8528c2ecf20Sopenharmony_ci		gvt_err("Unexpected forcenonpriv 0x%x write from cmd %s\n",
8538c2ecf20Sopenharmony_ci			offset, cmd);
8548c2ecf20Sopenharmony_ci		return -EINVAL;
8558c2ecf20Sopenharmony_ci	}
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	ring_base = s->engine->mmio_base;
8588c2ecf20Sopenharmony_ci	nopid = i915_mmio_reg_offset(RING_NOPID(ring_base));
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci	if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data) &&
8618c2ecf20Sopenharmony_ci			data != nopid) {
8628c2ecf20Sopenharmony_ci		gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n",
8638c2ecf20Sopenharmony_ci			offset, data);
8648c2ecf20Sopenharmony_ci		patch_value(s, cmd_ptr(s, index), nopid);
8658c2ecf20Sopenharmony_ci		return 0;
8668c2ecf20Sopenharmony_ci	}
8678c2ecf20Sopenharmony_ci	return 0;
8688c2ecf20Sopenharmony_ci}
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_cistatic inline bool is_mocs_mmio(unsigned int offset)
8718c2ecf20Sopenharmony_ci{
8728c2ecf20Sopenharmony_ci	return ((offset >= 0xc800) && (offset <= 0xcff8)) ||
8738c2ecf20Sopenharmony_ci		((offset >= 0xb020) && (offset <= 0xb0a0));
8748c2ecf20Sopenharmony_ci}
8758c2ecf20Sopenharmony_ci
8768c2ecf20Sopenharmony_cistatic int mocs_cmd_reg_handler(struct parser_exec_state *s,
8778c2ecf20Sopenharmony_ci				unsigned int offset, unsigned int index)
8788c2ecf20Sopenharmony_ci{
8798c2ecf20Sopenharmony_ci	if (!is_mocs_mmio(offset))
8808c2ecf20Sopenharmony_ci		return -EINVAL;
8818c2ecf20Sopenharmony_ci	vgpu_vreg(s->vgpu, offset) = cmd_val(s, index + 1);
8828c2ecf20Sopenharmony_ci	return 0;
8838c2ecf20Sopenharmony_ci}
8848c2ecf20Sopenharmony_ci
8858c2ecf20Sopenharmony_cistatic int is_cmd_update_pdps(unsigned int offset,
8868c2ecf20Sopenharmony_ci			      struct parser_exec_state *s)
8878c2ecf20Sopenharmony_ci{
8888c2ecf20Sopenharmony_ci	u32 base = s->workload->engine->mmio_base;
8898c2ecf20Sopenharmony_ci	return i915_mmio_reg_equal(_MMIO(offset), GEN8_RING_PDP_UDW(base, 0));
8908c2ecf20Sopenharmony_ci}
8918c2ecf20Sopenharmony_ci
8928c2ecf20Sopenharmony_cistatic int cmd_pdp_mmio_update_handler(struct parser_exec_state *s,
8938c2ecf20Sopenharmony_ci				       unsigned int offset, unsigned int index)
8948c2ecf20Sopenharmony_ci{
8958c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
8968c2ecf20Sopenharmony_ci	struct intel_vgpu_mm *shadow_mm = s->workload->shadow_mm;
8978c2ecf20Sopenharmony_ci	struct intel_vgpu_mm *mm;
8988c2ecf20Sopenharmony_ci	u64 pdps[GEN8_3LVL_PDPES];
8998c2ecf20Sopenharmony_ci
9008c2ecf20Sopenharmony_ci	if (shadow_mm->ppgtt_mm.root_entry_type ==
9018c2ecf20Sopenharmony_ci	    GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
9028c2ecf20Sopenharmony_ci		pdps[0] = (u64)cmd_val(s, 2) << 32;
9038c2ecf20Sopenharmony_ci		pdps[0] |= cmd_val(s, 4);
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_ci		mm = intel_vgpu_find_ppgtt_mm(vgpu, pdps);
9068c2ecf20Sopenharmony_ci		if (!mm) {
9078c2ecf20Sopenharmony_ci			gvt_vgpu_err("failed to get the 4-level shadow vm\n");
9088c2ecf20Sopenharmony_ci			return -EINVAL;
9098c2ecf20Sopenharmony_ci		}
9108c2ecf20Sopenharmony_ci		intel_vgpu_mm_get(mm);
9118c2ecf20Sopenharmony_ci		list_add_tail(&mm->ppgtt_mm.link,
9128c2ecf20Sopenharmony_ci			      &s->workload->lri_shadow_mm);
9138c2ecf20Sopenharmony_ci		*cmd_ptr(s, 2) = upper_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
9148c2ecf20Sopenharmony_ci		*cmd_ptr(s, 4) = lower_32_bits(mm->ppgtt_mm.shadow_pdps[0]);
9158c2ecf20Sopenharmony_ci	} else {
9168c2ecf20Sopenharmony_ci		/* Currently all guests use PML4 table and now can't
9178c2ecf20Sopenharmony_ci		 * have a guest with 3-level table but uses LRI for
9188c2ecf20Sopenharmony_ci		 * PPGTT update. So this is simply un-testable. */
9198c2ecf20Sopenharmony_ci		GEM_BUG_ON(1);
9208c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid shared shadow vm type\n");
9218c2ecf20Sopenharmony_ci		return -EINVAL;
9228c2ecf20Sopenharmony_ci	}
9238c2ecf20Sopenharmony_ci	return 0;
9248c2ecf20Sopenharmony_ci}
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_cistatic int cmd_reg_handler(struct parser_exec_state *s,
9278c2ecf20Sopenharmony_ci	unsigned int offset, unsigned int index, char *cmd)
9288c2ecf20Sopenharmony_ci{
9298c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
9308c2ecf20Sopenharmony_ci	struct intel_gvt *gvt = vgpu->gvt;
9318c2ecf20Sopenharmony_ci	u32 ctx_sr_ctl;
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	if (offset + 4 > gvt->device_info.mmio_size) {
9348c2ecf20Sopenharmony_ci		gvt_vgpu_err("%s access to (%x) outside of MMIO range\n",
9358c2ecf20Sopenharmony_ci				cmd, offset);
9368c2ecf20Sopenharmony_ci		return -EFAULT;
9378c2ecf20Sopenharmony_ci	}
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci	if (!intel_gvt_mmio_is_cmd_accessible(gvt, offset)) {
9408c2ecf20Sopenharmony_ci		gvt_vgpu_err("%s access to non-render register (%x)\n",
9418c2ecf20Sopenharmony_ci				cmd, offset);
9428c2ecf20Sopenharmony_ci		return -EBADRQC;
9438c2ecf20Sopenharmony_ci	}
9448c2ecf20Sopenharmony_ci
9458c2ecf20Sopenharmony_ci	if (is_shadowed_mmio(offset)) {
9468c2ecf20Sopenharmony_ci		gvt_vgpu_err("found access of shadowed MMIO %x\n", offset);
9478c2ecf20Sopenharmony_ci		return 0;
9488c2ecf20Sopenharmony_ci	}
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	if (is_mocs_mmio(offset) &&
9518c2ecf20Sopenharmony_ci	    mocs_cmd_reg_handler(s, offset, index))
9528c2ecf20Sopenharmony_ci		return -EINVAL;
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci	if (is_force_nonpriv_mmio(offset) &&
9558c2ecf20Sopenharmony_ci		force_nonpriv_reg_handler(s, offset, index, cmd))
9568c2ecf20Sopenharmony_ci		return -EPERM;
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci	if (offset == i915_mmio_reg_offset(DERRMR) ||
9598c2ecf20Sopenharmony_ci		offset == i915_mmio_reg_offset(FORCEWAKE_MT)) {
9608c2ecf20Sopenharmony_ci		/* Writing to HW VGT_PVINFO_PAGE offset will be discarded */
9618c2ecf20Sopenharmony_ci		patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE);
9628c2ecf20Sopenharmony_ci	}
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	if (is_cmd_update_pdps(offset, s) &&
9658c2ecf20Sopenharmony_ci	    cmd_pdp_mmio_update_handler(s, offset, index))
9668c2ecf20Sopenharmony_ci		return -EINVAL;
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	/* TODO
9698c2ecf20Sopenharmony_ci	 * In order to let workload with inhibit context to generate
9708c2ecf20Sopenharmony_ci	 * correct image data into memory, vregs values will be loaded to
9718c2ecf20Sopenharmony_ci	 * hw via LRIs in the workload with inhibit context. But as
9728c2ecf20Sopenharmony_ci	 * indirect context is loaded prior to LRIs in workload, we don't
9738c2ecf20Sopenharmony_ci	 * want reg values specified in indirect context overwritten by
9748c2ecf20Sopenharmony_ci	 * LRIs in workloads. So, when scanning an indirect context, we
9758c2ecf20Sopenharmony_ci	 * update reg values in it into vregs, so LRIs in workload with
9768c2ecf20Sopenharmony_ci	 * inhibit context will restore with correct values
9778c2ecf20Sopenharmony_ci	 */
9788c2ecf20Sopenharmony_ci	if (IS_GEN(s->engine->i915, 9) &&
9798c2ecf20Sopenharmony_ci	    intel_gvt_mmio_is_sr_in_ctx(gvt, offset) &&
9808c2ecf20Sopenharmony_ci	    !strncmp(cmd, "lri", 3)) {
9818c2ecf20Sopenharmony_ci		intel_gvt_hypervisor_read_gpa(s->vgpu,
9828c2ecf20Sopenharmony_ci			s->workload->ring_context_gpa + 12, &ctx_sr_ctl, 4);
9838c2ecf20Sopenharmony_ci		/* check inhibit context */
9848c2ecf20Sopenharmony_ci		if (ctx_sr_ctl & 1) {
9858c2ecf20Sopenharmony_ci			u32 data = cmd_val(s, index + 1);
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci			if (intel_gvt_mmio_has_mode_mask(s->vgpu->gvt, offset))
9888c2ecf20Sopenharmony_ci				intel_vgpu_mask_mmio_write(vgpu,
9898c2ecf20Sopenharmony_ci							offset, &data, 4);
9908c2ecf20Sopenharmony_ci			else
9918c2ecf20Sopenharmony_ci				vgpu_vreg(vgpu, offset) = data;
9928c2ecf20Sopenharmony_ci		}
9938c2ecf20Sopenharmony_ci	}
9948c2ecf20Sopenharmony_ci
9958c2ecf20Sopenharmony_ci	return 0;
9968c2ecf20Sopenharmony_ci}
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci#define cmd_reg(s, i) \
9998c2ecf20Sopenharmony_ci	(cmd_val(s, i) & GENMASK(22, 2))
10008c2ecf20Sopenharmony_ci
10018c2ecf20Sopenharmony_ci#define cmd_reg_inhibit(s, i) \
10028c2ecf20Sopenharmony_ci	(cmd_val(s, i) & GENMASK(22, 18))
10038c2ecf20Sopenharmony_ci
10048c2ecf20Sopenharmony_ci#define cmd_gma(s, i) \
10058c2ecf20Sopenharmony_ci	(cmd_val(s, i) & GENMASK(31, 2))
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci#define cmd_gma_hi(s, i) \
10088c2ecf20Sopenharmony_ci	(cmd_val(s, i) & GENMASK(15, 0))
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_cistatic int cmd_handler_lri(struct parser_exec_state *s)
10118c2ecf20Sopenharmony_ci{
10128c2ecf20Sopenharmony_ci	int i, ret = 0;
10138c2ecf20Sopenharmony_ci	int cmd_len = cmd_length(s);
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci	for (i = 1; i < cmd_len; i += 2) {
10168c2ecf20Sopenharmony_ci		if (IS_BROADWELL(s->engine->i915) && s->engine->id != RCS0) {
10178c2ecf20Sopenharmony_ci			if (s->engine->id == BCS0 &&
10188c2ecf20Sopenharmony_ci			    cmd_reg(s, i) == i915_mmio_reg_offset(DERRMR))
10198c2ecf20Sopenharmony_ci				ret |= 0;
10208c2ecf20Sopenharmony_ci			else
10218c2ecf20Sopenharmony_ci				ret |= cmd_reg_inhibit(s, i) ? -EBADRQC : 0;
10228c2ecf20Sopenharmony_ci		}
10238c2ecf20Sopenharmony_ci		if (ret)
10248c2ecf20Sopenharmony_ci			break;
10258c2ecf20Sopenharmony_ci		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lri");
10268c2ecf20Sopenharmony_ci		if (ret)
10278c2ecf20Sopenharmony_ci			break;
10288c2ecf20Sopenharmony_ci	}
10298c2ecf20Sopenharmony_ci	return ret;
10308c2ecf20Sopenharmony_ci}
10318c2ecf20Sopenharmony_ci
10328c2ecf20Sopenharmony_cistatic int cmd_handler_lrr(struct parser_exec_state *s)
10338c2ecf20Sopenharmony_ci{
10348c2ecf20Sopenharmony_ci	int i, ret = 0;
10358c2ecf20Sopenharmony_ci	int cmd_len = cmd_length(s);
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	for (i = 1; i < cmd_len; i += 2) {
10388c2ecf20Sopenharmony_ci		if (IS_BROADWELL(s->engine->i915))
10398c2ecf20Sopenharmony_ci			ret |= ((cmd_reg_inhibit(s, i) ||
10408c2ecf20Sopenharmony_ci				 (cmd_reg_inhibit(s, i + 1)))) ?
10418c2ecf20Sopenharmony_ci				-EBADRQC : 0;
10428c2ecf20Sopenharmony_ci		if (ret)
10438c2ecf20Sopenharmony_ci			break;
10448c2ecf20Sopenharmony_ci		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrr-src");
10458c2ecf20Sopenharmony_ci		if (ret)
10468c2ecf20Sopenharmony_ci			break;
10478c2ecf20Sopenharmony_ci		ret |= cmd_reg_handler(s, cmd_reg(s, i + 1), i, "lrr-dst");
10488c2ecf20Sopenharmony_ci		if (ret)
10498c2ecf20Sopenharmony_ci			break;
10508c2ecf20Sopenharmony_ci	}
10518c2ecf20Sopenharmony_ci	return ret;
10528c2ecf20Sopenharmony_ci}
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_cistatic inline int cmd_address_audit(struct parser_exec_state *s,
10558c2ecf20Sopenharmony_ci		unsigned long guest_gma, int op_size, bool index_mode);
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_cistatic int cmd_handler_lrm(struct parser_exec_state *s)
10588c2ecf20Sopenharmony_ci{
10598c2ecf20Sopenharmony_ci	struct intel_gvt *gvt = s->vgpu->gvt;
10608c2ecf20Sopenharmony_ci	int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd;
10618c2ecf20Sopenharmony_ci	unsigned long gma;
10628c2ecf20Sopenharmony_ci	int i, ret = 0;
10638c2ecf20Sopenharmony_ci	int cmd_len = cmd_length(s);
10648c2ecf20Sopenharmony_ci
10658c2ecf20Sopenharmony_ci	for (i = 1; i < cmd_len;) {
10668c2ecf20Sopenharmony_ci		if (IS_BROADWELL(s->engine->i915))
10678c2ecf20Sopenharmony_ci			ret |= (cmd_reg_inhibit(s, i)) ? -EBADRQC : 0;
10688c2ecf20Sopenharmony_ci		if (ret)
10698c2ecf20Sopenharmony_ci			break;
10708c2ecf20Sopenharmony_ci		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrm");
10718c2ecf20Sopenharmony_ci		if (ret)
10728c2ecf20Sopenharmony_ci			break;
10738c2ecf20Sopenharmony_ci		if (cmd_val(s, 0) & (1 << 22)) {
10748c2ecf20Sopenharmony_ci			gma = cmd_gma(s, i + 1);
10758c2ecf20Sopenharmony_ci			if (gmadr_bytes == 8)
10768c2ecf20Sopenharmony_ci				gma |= (cmd_gma_hi(s, i + 2)) << 32;
10778c2ecf20Sopenharmony_ci			ret |= cmd_address_audit(s, gma, sizeof(u32), false);
10788c2ecf20Sopenharmony_ci			if (ret)
10798c2ecf20Sopenharmony_ci				break;
10808c2ecf20Sopenharmony_ci		}
10818c2ecf20Sopenharmony_ci		i += gmadr_dw_number(s) + 1;
10828c2ecf20Sopenharmony_ci	}
10838c2ecf20Sopenharmony_ci	return ret;
10848c2ecf20Sopenharmony_ci}
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_cistatic int cmd_handler_srm(struct parser_exec_state *s)
10878c2ecf20Sopenharmony_ci{
10888c2ecf20Sopenharmony_ci	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
10898c2ecf20Sopenharmony_ci	unsigned long gma;
10908c2ecf20Sopenharmony_ci	int i, ret = 0;
10918c2ecf20Sopenharmony_ci	int cmd_len = cmd_length(s);
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_ci	for (i = 1; i < cmd_len;) {
10948c2ecf20Sopenharmony_ci		ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "srm");
10958c2ecf20Sopenharmony_ci		if (ret)
10968c2ecf20Sopenharmony_ci			break;
10978c2ecf20Sopenharmony_ci		if (cmd_val(s, 0) & (1 << 22)) {
10988c2ecf20Sopenharmony_ci			gma = cmd_gma(s, i + 1);
10998c2ecf20Sopenharmony_ci			if (gmadr_bytes == 8)
11008c2ecf20Sopenharmony_ci				gma |= (cmd_gma_hi(s, i + 2)) << 32;
11018c2ecf20Sopenharmony_ci			ret |= cmd_address_audit(s, gma, sizeof(u32), false);
11028c2ecf20Sopenharmony_ci			if (ret)
11038c2ecf20Sopenharmony_ci				break;
11048c2ecf20Sopenharmony_ci		}
11058c2ecf20Sopenharmony_ci		i += gmadr_dw_number(s) + 1;
11068c2ecf20Sopenharmony_ci	}
11078c2ecf20Sopenharmony_ci	return ret;
11088c2ecf20Sopenharmony_ci}
11098c2ecf20Sopenharmony_ci
11108c2ecf20Sopenharmony_cistruct cmd_interrupt_event {
11118c2ecf20Sopenharmony_ci	int pipe_control_notify;
11128c2ecf20Sopenharmony_ci	int mi_flush_dw;
11138c2ecf20Sopenharmony_ci	int mi_user_interrupt;
11148c2ecf20Sopenharmony_ci};
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_cistatic struct cmd_interrupt_event cmd_interrupt_events[] = {
11178c2ecf20Sopenharmony_ci	[RCS0] = {
11188c2ecf20Sopenharmony_ci		.pipe_control_notify = RCS_PIPE_CONTROL,
11198c2ecf20Sopenharmony_ci		.mi_flush_dw = INTEL_GVT_EVENT_RESERVED,
11208c2ecf20Sopenharmony_ci		.mi_user_interrupt = RCS_MI_USER_INTERRUPT,
11218c2ecf20Sopenharmony_ci	},
11228c2ecf20Sopenharmony_ci	[BCS0] = {
11238c2ecf20Sopenharmony_ci		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
11248c2ecf20Sopenharmony_ci		.mi_flush_dw = BCS_MI_FLUSH_DW,
11258c2ecf20Sopenharmony_ci		.mi_user_interrupt = BCS_MI_USER_INTERRUPT,
11268c2ecf20Sopenharmony_ci	},
11278c2ecf20Sopenharmony_ci	[VCS0] = {
11288c2ecf20Sopenharmony_ci		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
11298c2ecf20Sopenharmony_ci		.mi_flush_dw = VCS_MI_FLUSH_DW,
11308c2ecf20Sopenharmony_ci		.mi_user_interrupt = VCS_MI_USER_INTERRUPT,
11318c2ecf20Sopenharmony_ci	},
11328c2ecf20Sopenharmony_ci	[VCS1] = {
11338c2ecf20Sopenharmony_ci		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
11348c2ecf20Sopenharmony_ci		.mi_flush_dw = VCS2_MI_FLUSH_DW,
11358c2ecf20Sopenharmony_ci		.mi_user_interrupt = VCS2_MI_USER_INTERRUPT,
11368c2ecf20Sopenharmony_ci	},
11378c2ecf20Sopenharmony_ci	[VECS0] = {
11388c2ecf20Sopenharmony_ci		.pipe_control_notify = INTEL_GVT_EVENT_RESERVED,
11398c2ecf20Sopenharmony_ci		.mi_flush_dw = VECS_MI_FLUSH_DW,
11408c2ecf20Sopenharmony_ci		.mi_user_interrupt = VECS_MI_USER_INTERRUPT,
11418c2ecf20Sopenharmony_ci	},
11428c2ecf20Sopenharmony_ci};
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_cistatic int cmd_handler_pipe_control(struct parser_exec_state *s)
11458c2ecf20Sopenharmony_ci{
11468c2ecf20Sopenharmony_ci	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
11478c2ecf20Sopenharmony_ci	unsigned long gma;
11488c2ecf20Sopenharmony_ci	bool index_mode = false;
11498c2ecf20Sopenharmony_ci	unsigned int post_sync;
11508c2ecf20Sopenharmony_ci	int ret = 0;
11518c2ecf20Sopenharmony_ci	u32 hws_pga, val;
11528c2ecf20Sopenharmony_ci
11538c2ecf20Sopenharmony_ci	post_sync = (cmd_val(s, 1) & PIPE_CONTROL_POST_SYNC_OP_MASK) >> 14;
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ci	/* LRI post sync */
11568c2ecf20Sopenharmony_ci	if (cmd_val(s, 1) & PIPE_CONTROL_MMIO_WRITE)
11578c2ecf20Sopenharmony_ci		ret = cmd_reg_handler(s, cmd_reg(s, 2), 1, "pipe_ctrl");
11588c2ecf20Sopenharmony_ci	/* post sync */
11598c2ecf20Sopenharmony_ci	else if (post_sync) {
11608c2ecf20Sopenharmony_ci		if (post_sync == 2)
11618c2ecf20Sopenharmony_ci			ret = cmd_reg_handler(s, 0x2350, 1, "pipe_ctrl");
11628c2ecf20Sopenharmony_ci		else if (post_sync == 3)
11638c2ecf20Sopenharmony_ci			ret = cmd_reg_handler(s, 0x2358, 1, "pipe_ctrl");
11648c2ecf20Sopenharmony_ci		else if (post_sync == 1) {
11658c2ecf20Sopenharmony_ci			/* check ggtt*/
11668c2ecf20Sopenharmony_ci			if ((cmd_val(s, 1) & PIPE_CONTROL_GLOBAL_GTT_IVB)) {
11678c2ecf20Sopenharmony_ci				gma = cmd_val(s, 2) & GENMASK(31, 3);
11688c2ecf20Sopenharmony_ci				if (gmadr_bytes == 8)
11698c2ecf20Sopenharmony_ci					gma |= (cmd_gma_hi(s, 3)) << 32;
11708c2ecf20Sopenharmony_ci				/* Store Data Index */
11718c2ecf20Sopenharmony_ci				if (cmd_val(s, 1) & (1 << 21))
11728c2ecf20Sopenharmony_ci					index_mode = true;
11738c2ecf20Sopenharmony_ci				ret |= cmd_address_audit(s, gma, sizeof(u64),
11748c2ecf20Sopenharmony_ci						index_mode);
11758c2ecf20Sopenharmony_ci				if (ret)
11768c2ecf20Sopenharmony_ci					return ret;
11778c2ecf20Sopenharmony_ci				if (index_mode) {
11788c2ecf20Sopenharmony_ci					hws_pga = s->vgpu->hws_pga[s->engine->id];
11798c2ecf20Sopenharmony_ci					gma = hws_pga + gma;
11808c2ecf20Sopenharmony_ci					patch_value(s, cmd_ptr(s, 2), gma);
11818c2ecf20Sopenharmony_ci					val = cmd_val(s, 1) & (~(1 << 21));
11828c2ecf20Sopenharmony_ci					patch_value(s, cmd_ptr(s, 1), val);
11838c2ecf20Sopenharmony_ci				}
11848c2ecf20Sopenharmony_ci			}
11858c2ecf20Sopenharmony_ci		}
11868c2ecf20Sopenharmony_ci	}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_ci	if (ret)
11898c2ecf20Sopenharmony_ci		return ret;
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci	if (cmd_val(s, 1) & PIPE_CONTROL_NOTIFY)
11928c2ecf20Sopenharmony_ci		set_bit(cmd_interrupt_events[s->engine->id].pipe_control_notify,
11938c2ecf20Sopenharmony_ci			s->workload->pending_events);
11948c2ecf20Sopenharmony_ci	return 0;
11958c2ecf20Sopenharmony_ci}
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_cistatic int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
11988c2ecf20Sopenharmony_ci{
11998c2ecf20Sopenharmony_ci	set_bit(cmd_interrupt_events[s->engine->id].mi_user_interrupt,
12008c2ecf20Sopenharmony_ci		s->workload->pending_events);
12018c2ecf20Sopenharmony_ci	patch_value(s, cmd_ptr(s, 0), MI_NOOP);
12028c2ecf20Sopenharmony_ci	return 0;
12038c2ecf20Sopenharmony_ci}
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_cistatic int cmd_advance_default(struct parser_exec_state *s)
12068c2ecf20Sopenharmony_ci{
12078c2ecf20Sopenharmony_ci	return ip_gma_advance(s, cmd_length(s));
12088c2ecf20Sopenharmony_ci}
12098c2ecf20Sopenharmony_ci
12108c2ecf20Sopenharmony_cistatic int cmd_handler_mi_batch_buffer_end(struct parser_exec_state *s)
12118c2ecf20Sopenharmony_ci{
12128c2ecf20Sopenharmony_ci	int ret;
12138c2ecf20Sopenharmony_ci
12148c2ecf20Sopenharmony_ci	if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
12158c2ecf20Sopenharmony_ci		s->buf_type = BATCH_BUFFER_INSTRUCTION;
12168c2ecf20Sopenharmony_ci		ret = ip_gma_set(s, s->ret_ip_gma_bb);
12178c2ecf20Sopenharmony_ci		s->buf_addr_type = s->saved_buf_addr_type;
12188c2ecf20Sopenharmony_ci	} else {
12198c2ecf20Sopenharmony_ci		s->buf_type = RING_BUFFER_INSTRUCTION;
12208c2ecf20Sopenharmony_ci		s->buf_addr_type = GTT_BUFFER;
12218c2ecf20Sopenharmony_ci		if (s->ret_ip_gma_ring >= s->ring_start + s->ring_size)
12228c2ecf20Sopenharmony_ci			s->ret_ip_gma_ring -= s->ring_size;
12238c2ecf20Sopenharmony_ci		ret = ip_gma_set(s, s->ret_ip_gma_ring);
12248c2ecf20Sopenharmony_ci	}
12258c2ecf20Sopenharmony_ci	return ret;
12268c2ecf20Sopenharmony_ci}
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_cistruct mi_display_flip_command_info {
12298c2ecf20Sopenharmony_ci	int pipe;
12308c2ecf20Sopenharmony_ci	int plane;
12318c2ecf20Sopenharmony_ci	int event;
12328c2ecf20Sopenharmony_ci	i915_reg_t stride_reg;
12338c2ecf20Sopenharmony_ci	i915_reg_t ctrl_reg;
12348c2ecf20Sopenharmony_ci	i915_reg_t surf_reg;
12358c2ecf20Sopenharmony_ci	u64 stride_val;
12368c2ecf20Sopenharmony_ci	u64 tile_val;
12378c2ecf20Sopenharmony_ci	u64 surf_val;
12388c2ecf20Sopenharmony_ci	bool async_flip;
12398c2ecf20Sopenharmony_ci};
12408c2ecf20Sopenharmony_ci
12418c2ecf20Sopenharmony_cistruct plane_code_mapping {
12428c2ecf20Sopenharmony_ci	int pipe;
12438c2ecf20Sopenharmony_ci	int plane;
12448c2ecf20Sopenharmony_ci	int event;
12458c2ecf20Sopenharmony_ci};
12468c2ecf20Sopenharmony_ci
12478c2ecf20Sopenharmony_cistatic int gen8_decode_mi_display_flip(struct parser_exec_state *s,
12488c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
12498c2ecf20Sopenharmony_ci{
12508c2ecf20Sopenharmony_ci	struct drm_i915_private *dev_priv = s->engine->i915;
12518c2ecf20Sopenharmony_ci	struct plane_code_mapping gen8_plane_code[] = {
12528c2ecf20Sopenharmony_ci		[0] = {PIPE_A, PLANE_A, PRIMARY_A_FLIP_DONE},
12538c2ecf20Sopenharmony_ci		[1] = {PIPE_B, PLANE_A, PRIMARY_B_FLIP_DONE},
12548c2ecf20Sopenharmony_ci		[2] = {PIPE_A, PLANE_B, SPRITE_A_FLIP_DONE},
12558c2ecf20Sopenharmony_ci		[3] = {PIPE_B, PLANE_B, SPRITE_B_FLIP_DONE},
12568c2ecf20Sopenharmony_ci		[4] = {PIPE_C, PLANE_A, PRIMARY_C_FLIP_DONE},
12578c2ecf20Sopenharmony_ci		[5] = {PIPE_C, PLANE_B, SPRITE_C_FLIP_DONE},
12588c2ecf20Sopenharmony_ci	};
12598c2ecf20Sopenharmony_ci	u32 dword0, dword1, dword2;
12608c2ecf20Sopenharmony_ci	u32 v;
12618c2ecf20Sopenharmony_ci
12628c2ecf20Sopenharmony_ci	dword0 = cmd_val(s, 0);
12638c2ecf20Sopenharmony_ci	dword1 = cmd_val(s, 1);
12648c2ecf20Sopenharmony_ci	dword2 = cmd_val(s, 2);
12658c2ecf20Sopenharmony_ci
12668c2ecf20Sopenharmony_ci	v = (dword0 & GENMASK(21, 19)) >> 19;
12678c2ecf20Sopenharmony_ci	if (drm_WARN_ON(&dev_priv->drm, v >= ARRAY_SIZE(gen8_plane_code)))
12688c2ecf20Sopenharmony_ci		return -EBADRQC;
12698c2ecf20Sopenharmony_ci
12708c2ecf20Sopenharmony_ci	info->pipe = gen8_plane_code[v].pipe;
12718c2ecf20Sopenharmony_ci	info->plane = gen8_plane_code[v].plane;
12728c2ecf20Sopenharmony_ci	info->event = gen8_plane_code[v].event;
12738c2ecf20Sopenharmony_ci	info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
12748c2ecf20Sopenharmony_ci	info->tile_val = (dword1 & 0x1);
12758c2ecf20Sopenharmony_ci	info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
12768c2ecf20Sopenharmony_ci	info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ci	if (info->plane == PLANE_A) {
12798c2ecf20Sopenharmony_ci		info->ctrl_reg = DSPCNTR(info->pipe);
12808c2ecf20Sopenharmony_ci		info->stride_reg = DSPSTRIDE(info->pipe);
12818c2ecf20Sopenharmony_ci		info->surf_reg = DSPSURF(info->pipe);
12828c2ecf20Sopenharmony_ci	} else if (info->plane == PLANE_B) {
12838c2ecf20Sopenharmony_ci		info->ctrl_reg = SPRCTL(info->pipe);
12848c2ecf20Sopenharmony_ci		info->stride_reg = SPRSTRIDE(info->pipe);
12858c2ecf20Sopenharmony_ci		info->surf_reg = SPRSURF(info->pipe);
12868c2ecf20Sopenharmony_ci	} else {
12878c2ecf20Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, 1);
12888c2ecf20Sopenharmony_ci		return -EBADRQC;
12898c2ecf20Sopenharmony_ci	}
12908c2ecf20Sopenharmony_ci	return 0;
12918c2ecf20Sopenharmony_ci}
12928c2ecf20Sopenharmony_ci
12938c2ecf20Sopenharmony_cistatic int skl_decode_mi_display_flip(struct parser_exec_state *s,
12948c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
12958c2ecf20Sopenharmony_ci{
12968c2ecf20Sopenharmony_ci	struct drm_i915_private *dev_priv = s->engine->i915;
12978c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
12988c2ecf20Sopenharmony_ci	u32 dword0 = cmd_val(s, 0);
12998c2ecf20Sopenharmony_ci	u32 dword1 = cmd_val(s, 1);
13008c2ecf20Sopenharmony_ci	u32 dword2 = cmd_val(s, 2);
13018c2ecf20Sopenharmony_ci	u32 plane = (dword0 & GENMASK(12, 8)) >> 8;
13028c2ecf20Sopenharmony_ci
13038c2ecf20Sopenharmony_ci	info->plane = PRIMARY_PLANE;
13048c2ecf20Sopenharmony_ci
13058c2ecf20Sopenharmony_ci	switch (plane) {
13068c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_1_A:
13078c2ecf20Sopenharmony_ci		info->pipe = PIPE_A;
13088c2ecf20Sopenharmony_ci		info->event = PRIMARY_A_FLIP_DONE;
13098c2ecf20Sopenharmony_ci		break;
13108c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_1_B:
13118c2ecf20Sopenharmony_ci		info->pipe = PIPE_B;
13128c2ecf20Sopenharmony_ci		info->event = PRIMARY_B_FLIP_DONE;
13138c2ecf20Sopenharmony_ci		break;
13148c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_1_C:
13158c2ecf20Sopenharmony_ci		info->pipe = PIPE_C;
13168c2ecf20Sopenharmony_ci		info->event = PRIMARY_C_FLIP_DONE;
13178c2ecf20Sopenharmony_ci		break;
13188c2ecf20Sopenharmony_ci
13198c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_2_A:
13208c2ecf20Sopenharmony_ci		info->pipe = PIPE_A;
13218c2ecf20Sopenharmony_ci		info->event = SPRITE_A_FLIP_DONE;
13228c2ecf20Sopenharmony_ci		info->plane = SPRITE_PLANE;
13238c2ecf20Sopenharmony_ci		break;
13248c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_2_B:
13258c2ecf20Sopenharmony_ci		info->pipe = PIPE_B;
13268c2ecf20Sopenharmony_ci		info->event = SPRITE_B_FLIP_DONE;
13278c2ecf20Sopenharmony_ci		info->plane = SPRITE_PLANE;
13288c2ecf20Sopenharmony_ci		break;
13298c2ecf20Sopenharmony_ci	case MI_DISPLAY_FLIP_SKL_PLANE_2_C:
13308c2ecf20Sopenharmony_ci		info->pipe = PIPE_C;
13318c2ecf20Sopenharmony_ci		info->event = SPRITE_C_FLIP_DONE;
13328c2ecf20Sopenharmony_ci		info->plane = SPRITE_PLANE;
13338c2ecf20Sopenharmony_ci		break;
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci	default:
13368c2ecf20Sopenharmony_ci		gvt_vgpu_err("unknown plane code %d\n", plane);
13378c2ecf20Sopenharmony_ci		return -EBADRQC;
13388c2ecf20Sopenharmony_ci	}
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci	info->stride_val = (dword1 & GENMASK(15, 6)) >> 6;
13418c2ecf20Sopenharmony_ci	info->tile_val = (dword1 & GENMASK(2, 0));
13428c2ecf20Sopenharmony_ci	info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
13438c2ecf20Sopenharmony_ci	info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_ci	info->ctrl_reg = DSPCNTR(info->pipe);
13468c2ecf20Sopenharmony_ci	info->stride_reg = DSPSTRIDE(info->pipe);
13478c2ecf20Sopenharmony_ci	info->surf_reg = DSPSURF(info->pipe);
13488c2ecf20Sopenharmony_ci
13498c2ecf20Sopenharmony_ci	return 0;
13508c2ecf20Sopenharmony_ci}
13518c2ecf20Sopenharmony_ci
13528c2ecf20Sopenharmony_cistatic int gen8_check_mi_display_flip(struct parser_exec_state *s,
13538c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
13548c2ecf20Sopenharmony_ci{
13558c2ecf20Sopenharmony_ci	u32 stride, tile;
13568c2ecf20Sopenharmony_ci
13578c2ecf20Sopenharmony_ci	if (!info->async_flip)
13588c2ecf20Sopenharmony_ci		return 0;
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci	if (INTEL_GEN(s->engine->i915) >= 9) {
13618c2ecf20Sopenharmony_ci		stride = vgpu_vreg_t(s->vgpu, info->stride_reg) & GENMASK(9, 0);
13628c2ecf20Sopenharmony_ci		tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) &
13638c2ecf20Sopenharmony_ci				GENMASK(12, 10)) >> 10;
13648c2ecf20Sopenharmony_ci	} else {
13658c2ecf20Sopenharmony_ci		stride = (vgpu_vreg_t(s->vgpu, info->stride_reg) &
13668c2ecf20Sopenharmony_ci				GENMASK(15, 6)) >> 6;
13678c2ecf20Sopenharmony_ci		tile = (vgpu_vreg_t(s->vgpu, info->ctrl_reg) & (1 << 10)) >> 10;
13688c2ecf20Sopenharmony_ci	}
13698c2ecf20Sopenharmony_ci
13708c2ecf20Sopenharmony_ci	if (stride != info->stride_val)
13718c2ecf20Sopenharmony_ci		gvt_dbg_cmd("cannot change stride during async flip\n");
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_ci	if (tile != info->tile_val)
13748c2ecf20Sopenharmony_ci		gvt_dbg_cmd("cannot change tile during async flip\n");
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_ci	return 0;
13778c2ecf20Sopenharmony_ci}
13788c2ecf20Sopenharmony_ci
13798c2ecf20Sopenharmony_cistatic int gen8_update_plane_mmio_from_mi_display_flip(
13808c2ecf20Sopenharmony_ci		struct parser_exec_state *s,
13818c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
13828c2ecf20Sopenharmony_ci{
13838c2ecf20Sopenharmony_ci	struct drm_i915_private *dev_priv = s->engine->i915;
13848c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
13858c2ecf20Sopenharmony_ci
13868c2ecf20Sopenharmony_ci	set_mask_bits(&vgpu_vreg_t(vgpu, info->surf_reg), GENMASK(31, 12),
13878c2ecf20Sopenharmony_ci		      info->surf_val << 12);
13888c2ecf20Sopenharmony_ci	if (INTEL_GEN(dev_priv) >= 9) {
13898c2ecf20Sopenharmony_ci		set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(9, 0),
13908c2ecf20Sopenharmony_ci			      info->stride_val);
13918c2ecf20Sopenharmony_ci		set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(12, 10),
13928c2ecf20Sopenharmony_ci			      info->tile_val << 10);
13938c2ecf20Sopenharmony_ci	} else {
13948c2ecf20Sopenharmony_ci		set_mask_bits(&vgpu_vreg_t(vgpu, info->stride_reg), GENMASK(15, 6),
13958c2ecf20Sopenharmony_ci			      info->stride_val << 6);
13968c2ecf20Sopenharmony_ci		set_mask_bits(&vgpu_vreg_t(vgpu, info->ctrl_reg), GENMASK(10, 10),
13978c2ecf20Sopenharmony_ci			      info->tile_val << 10);
13988c2ecf20Sopenharmony_ci	}
13998c2ecf20Sopenharmony_ci
14008c2ecf20Sopenharmony_ci	if (info->plane == PLANE_PRIMARY)
14018c2ecf20Sopenharmony_ci		vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(info->pipe))++;
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	if (info->async_flip)
14048c2ecf20Sopenharmony_ci		intel_vgpu_trigger_virtual_event(vgpu, info->event);
14058c2ecf20Sopenharmony_ci	else
14068c2ecf20Sopenharmony_ci		set_bit(info->event, vgpu->irq.flip_done_event[info->pipe]);
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	return 0;
14098c2ecf20Sopenharmony_ci}
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_cistatic int decode_mi_display_flip(struct parser_exec_state *s,
14128c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
14138c2ecf20Sopenharmony_ci{
14148c2ecf20Sopenharmony_ci	if (IS_BROADWELL(s->engine->i915))
14158c2ecf20Sopenharmony_ci		return gen8_decode_mi_display_flip(s, info);
14168c2ecf20Sopenharmony_ci	if (INTEL_GEN(s->engine->i915) >= 9)
14178c2ecf20Sopenharmony_ci		return skl_decode_mi_display_flip(s, info);
14188c2ecf20Sopenharmony_ci
14198c2ecf20Sopenharmony_ci	return -ENODEV;
14208c2ecf20Sopenharmony_ci}
14218c2ecf20Sopenharmony_ci
14228c2ecf20Sopenharmony_cistatic int check_mi_display_flip(struct parser_exec_state *s,
14238c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
14248c2ecf20Sopenharmony_ci{
14258c2ecf20Sopenharmony_ci	return gen8_check_mi_display_flip(s, info);
14268c2ecf20Sopenharmony_ci}
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_cistatic int update_plane_mmio_from_mi_display_flip(
14298c2ecf20Sopenharmony_ci		struct parser_exec_state *s,
14308c2ecf20Sopenharmony_ci		struct mi_display_flip_command_info *info)
14318c2ecf20Sopenharmony_ci{
14328c2ecf20Sopenharmony_ci	return gen8_update_plane_mmio_from_mi_display_flip(s, info);
14338c2ecf20Sopenharmony_ci}
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_cistatic int cmd_handler_mi_display_flip(struct parser_exec_state *s)
14368c2ecf20Sopenharmony_ci{
14378c2ecf20Sopenharmony_ci	struct mi_display_flip_command_info info;
14388c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
14398c2ecf20Sopenharmony_ci	int ret;
14408c2ecf20Sopenharmony_ci	int i;
14418c2ecf20Sopenharmony_ci	int len = cmd_length(s);
14428c2ecf20Sopenharmony_ci	u32 valid_len = CMD_LEN(1);
14438c2ecf20Sopenharmony_ci
14448c2ecf20Sopenharmony_ci	/* Flip Type == Stereo 3D Flip */
14458c2ecf20Sopenharmony_ci	if (DWORD_FIELD(2, 1, 0) == 2)
14468c2ecf20Sopenharmony_ci		valid_len++;
14478c2ecf20Sopenharmony_ci	ret = gvt_check_valid_cmd_length(cmd_length(s),
14488c2ecf20Sopenharmony_ci			valid_len);
14498c2ecf20Sopenharmony_ci	if (ret)
14508c2ecf20Sopenharmony_ci		return ret;
14518c2ecf20Sopenharmony_ci
14528c2ecf20Sopenharmony_ci	ret = decode_mi_display_flip(s, &info);
14538c2ecf20Sopenharmony_ci	if (ret) {
14548c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to decode MI display flip command\n");
14558c2ecf20Sopenharmony_ci		return ret;
14568c2ecf20Sopenharmony_ci	}
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci	ret = check_mi_display_flip(s, &info);
14598c2ecf20Sopenharmony_ci	if (ret) {
14608c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid MI display flip command\n");
14618c2ecf20Sopenharmony_ci		return ret;
14628c2ecf20Sopenharmony_ci	}
14638c2ecf20Sopenharmony_ci
14648c2ecf20Sopenharmony_ci	ret = update_plane_mmio_from_mi_display_flip(s, &info);
14658c2ecf20Sopenharmony_ci	if (ret) {
14668c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to update plane mmio\n");
14678c2ecf20Sopenharmony_ci		return ret;
14688c2ecf20Sopenharmony_ci	}
14698c2ecf20Sopenharmony_ci
14708c2ecf20Sopenharmony_ci	for (i = 0; i < len; i++)
14718c2ecf20Sopenharmony_ci		patch_value(s, cmd_ptr(s, i), MI_NOOP);
14728c2ecf20Sopenharmony_ci	return 0;
14738c2ecf20Sopenharmony_ci}
14748c2ecf20Sopenharmony_ci
14758c2ecf20Sopenharmony_cistatic bool is_wait_for_flip_pending(u32 cmd)
14768c2ecf20Sopenharmony_ci{
14778c2ecf20Sopenharmony_ci	return cmd & (MI_WAIT_FOR_PLANE_A_FLIP_PENDING |
14788c2ecf20Sopenharmony_ci			MI_WAIT_FOR_PLANE_B_FLIP_PENDING |
14798c2ecf20Sopenharmony_ci			MI_WAIT_FOR_PLANE_C_FLIP_PENDING |
14808c2ecf20Sopenharmony_ci			MI_WAIT_FOR_SPRITE_A_FLIP_PENDING |
14818c2ecf20Sopenharmony_ci			MI_WAIT_FOR_SPRITE_B_FLIP_PENDING |
14828c2ecf20Sopenharmony_ci			MI_WAIT_FOR_SPRITE_C_FLIP_PENDING);
14838c2ecf20Sopenharmony_ci}
14848c2ecf20Sopenharmony_ci
14858c2ecf20Sopenharmony_cistatic int cmd_handler_mi_wait_for_event(struct parser_exec_state *s)
14868c2ecf20Sopenharmony_ci{
14878c2ecf20Sopenharmony_ci	u32 cmd = cmd_val(s, 0);
14888c2ecf20Sopenharmony_ci
14898c2ecf20Sopenharmony_ci	if (!is_wait_for_flip_pending(cmd))
14908c2ecf20Sopenharmony_ci		return 0;
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	patch_value(s, cmd_ptr(s, 0), MI_NOOP);
14938c2ecf20Sopenharmony_ci	return 0;
14948c2ecf20Sopenharmony_ci}
14958c2ecf20Sopenharmony_ci
14968c2ecf20Sopenharmony_cistatic unsigned long get_gma_bb_from_cmd(struct parser_exec_state *s, int index)
14978c2ecf20Sopenharmony_ci{
14988c2ecf20Sopenharmony_ci	unsigned long addr;
14998c2ecf20Sopenharmony_ci	unsigned long gma_high, gma_low;
15008c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
15018c2ecf20Sopenharmony_ci	int gmadr_bytes = vgpu->gvt->device_info.gmadr_bytes_in_cmd;
15028c2ecf20Sopenharmony_ci
15038c2ecf20Sopenharmony_ci	if (WARN_ON(gmadr_bytes != 4 && gmadr_bytes != 8)) {
15048c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid gma bytes %d\n", gmadr_bytes);
15058c2ecf20Sopenharmony_ci		return INTEL_GVT_INVALID_ADDR;
15068c2ecf20Sopenharmony_ci	}
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_ci	gma_low = cmd_val(s, index) & BATCH_BUFFER_ADDR_MASK;
15098c2ecf20Sopenharmony_ci	if (gmadr_bytes == 4) {
15108c2ecf20Sopenharmony_ci		addr = gma_low;
15118c2ecf20Sopenharmony_ci	} else {
15128c2ecf20Sopenharmony_ci		gma_high = cmd_val(s, index + 1) & BATCH_BUFFER_ADDR_HIGH_MASK;
15138c2ecf20Sopenharmony_ci		addr = (((unsigned long)gma_high) << 32) | gma_low;
15148c2ecf20Sopenharmony_ci	}
15158c2ecf20Sopenharmony_ci	return addr;
15168c2ecf20Sopenharmony_ci}
15178c2ecf20Sopenharmony_ci
15188c2ecf20Sopenharmony_cistatic inline int cmd_address_audit(struct parser_exec_state *s,
15198c2ecf20Sopenharmony_ci		unsigned long guest_gma, int op_size, bool index_mode)
15208c2ecf20Sopenharmony_ci{
15218c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
15228c2ecf20Sopenharmony_ci	u32 max_surface_size = vgpu->gvt->device_info.max_surface_size;
15238c2ecf20Sopenharmony_ci	int i;
15248c2ecf20Sopenharmony_ci	int ret;
15258c2ecf20Sopenharmony_ci
15268c2ecf20Sopenharmony_ci	if (op_size > max_surface_size) {
15278c2ecf20Sopenharmony_ci		gvt_vgpu_err("command address audit fail name %s\n",
15288c2ecf20Sopenharmony_ci			s->info->name);
15298c2ecf20Sopenharmony_ci		return -EFAULT;
15308c2ecf20Sopenharmony_ci	}
15318c2ecf20Sopenharmony_ci
15328c2ecf20Sopenharmony_ci	if (index_mode)	{
15338c2ecf20Sopenharmony_ci		if (guest_gma >= I915_GTT_PAGE_SIZE) {
15348c2ecf20Sopenharmony_ci			ret = -EFAULT;
15358c2ecf20Sopenharmony_ci			goto err;
15368c2ecf20Sopenharmony_ci		}
15378c2ecf20Sopenharmony_ci	} else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) {
15388c2ecf20Sopenharmony_ci		ret = -EFAULT;
15398c2ecf20Sopenharmony_ci		goto err;
15408c2ecf20Sopenharmony_ci	}
15418c2ecf20Sopenharmony_ci
15428c2ecf20Sopenharmony_ci	return 0;
15438c2ecf20Sopenharmony_ci
15448c2ecf20Sopenharmony_cierr:
15458c2ecf20Sopenharmony_ci	gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
15468c2ecf20Sopenharmony_ci			s->info->name, guest_gma, op_size);
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci	pr_err("cmd dump: ");
15498c2ecf20Sopenharmony_ci	for (i = 0; i < cmd_length(s); i++) {
15508c2ecf20Sopenharmony_ci		if (!(i % 4))
15518c2ecf20Sopenharmony_ci			pr_err("\n%08x ", cmd_val(s, i));
15528c2ecf20Sopenharmony_ci		else
15538c2ecf20Sopenharmony_ci			pr_err("%08x ", cmd_val(s, i));
15548c2ecf20Sopenharmony_ci	}
15558c2ecf20Sopenharmony_ci	pr_err("\nvgpu%d: aperture 0x%llx - 0x%llx, hidden 0x%llx - 0x%llx\n",
15568c2ecf20Sopenharmony_ci			vgpu->id,
15578c2ecf20Sopenharmony_ci			vgpu_aperture_gmadr_base(vgpu),
15588c2ecf20Sopenharmony_ci			vgpu_aperture_gmadr_end(vgpu),
15598c2ecf20Sopenharmony_ci			vgpu_hidden_gmadr_base(vgpu),
15608c2ecf20Sopenharmony_ci			vgpu_hidden_gmadr_end(vgpu));
15618c2ecf20Sopenharmony_ci	return ret;
15628c2ecf20Sopenharmony_ci}
15638c2ecf20Sopenharmony_ci
15648c2ecf20Sopenharmony_cistatic int cmd_handler_mi_store_data_imm(struct parser_exec_state *s)
15658c2ecf20Sopenharmony_ci{
15668c2ecf20Sopenharmony_ci	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
15678c2ecf20Sopenharmony_ci	int op_size = (cmd_length(s) - 3) * sizeof(u32);
15688c2ecf20Sopenharmony_ci	int core_id = (cmd_val(s, 2) & (1 << 0)) ? 1 : 0;
15698c2ecf20Sopenharmony_ci	unsigned long gma, gma_low, gma_high;
15708c2ecf20Sopenharmony_ci	u32 valid_len = CMD_LEN(2);
15718c2ecf20Sopenharmony_ci	int ret = 0;
15728c2ecf20Sopenharmony_ci
15738c2ecf20Sopenharmony_ci	/* check ppggt */
15748c2ecf20Sopenharmony_ci	if (!(cmd_val(s, 0) & (1 << 22)))
15758c2ecf20Sopenharmony_ci		return 0;
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_ci	/* check if QWORD */
15788c2ecf20Sopenharmony_ci	if (DWORD_FIELD(0, 21, 21))
15798c2ecf20Sopenharmony_ci		valid_len++;
15808c2ecf20Sopenharmony_ci	ret = gvt_check_valid_cmd_length(cmd_length(s),
15818c2ecf20Sopenharmony_ci			valid_len);
15828c2ecf20Sopenharmony_ci	if (ret)
15838c2ecf20Sopenharmony_ci		return ret;
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	gma = cmd_val(s, 2) & GENMASK(31, 2);
15868c2ecf20Sopenharmony_ci
15878c2ecf20Sopenharmony_ci	if (gmadr_bytes == 8) {
15888c2ecf20Sopenharmony_ci		gma_low = cmd_val(s, 1) & GENMASK(31, 2);
15898c2ecf20Sopenharmony_ci		gma_high = cmd_val(s, 2) & GENMASK(15, 0);
15908c2ecf20Sopenharmony_ci		gma = (gma_high << 32) | gma_low;
15918c2ecf20Sopenharmony_ci		core_id = (cmd_val(s, 1) & (1 << 0)) ? 1 : 0;
15928c2ecf20Sopenharmony_ci	}
15938c2ecf20Sopenharmony_ci	ret = cmd_address_audit(s, gma + op_size * core_id, op_size, false);
15948c2ecf20Sopenharmony_ci	return ret;
15958c2ecf20Sopenharmony_ci}
15968c2ecf20Sopenharmony_ci
15978c2ecf20Sopenharmony_cistatic inline int unexpected_cmd(struct parser_exec_state *s)
15988c2ecf20Sopenharmony_ci{
15998c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
16008c2ecf20Sopenharmony_ci
16018c2ecf20Sopenharmony_ci	gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name);
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci	return -EBADRQC;
16048c2ecf20Sopenharmony_ci}
16058c2ecf20Sopenharmony_ci
16068c2ecf20Sopenharmony_cistatic int cmd_handler_mi_semaphore_wait(struct parser_exec_state *s)
16078c2ecf20Sopenharmony_ci{
16088c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16098c2ecf20Sopenharmony_ci}
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_cistatic int cmd_handler_mi_report_perf_count(struct parser_exec_state *s)
16128c2ecf20Sopenharmony_ci{
16138c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16148c2ecf20Sopenharmony_ci}
16158c2ecf20Sopenharmony_ci
16168c2ecf20Sopenharmony_cistatic int cmd_handler_mi_op_2e(struct parser_exec_state *s)
16178c2ecf20Sopenharmony_ci{
16188c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16198c2ecf20Sopenharmony_ci}
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_cistatic int cmd_handler_mi_op_2f(struct parser_exec_state *s)
16228c2ecf20Sopenharmony_ci{
16238c2ecf20Sopenharmony_ci	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
16248c2ecf20Sopenharmony_ci	int op_size = (1 << ((cmd_val(s, 0) & GENMASK(20, 19)) >> 19)) *
16258c2ecf20Sopenharmony_ci			sizeof(u32);
16268c2ecf20Sopenharmony_ci	unsigned long gma, gma_high;
16278c2ecf20Sopenharmony_ci	u32 valid_len = CMD_LEN(1);
16288c2ecf20Sopenharmony_ci	int ret = 0;
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci	if (!(cmd_val(s, 0) & (1 << 22)))
16318c2ecf20Sopenharmony_ci		return ret;
16328c2ecf20Sopenharmony_ci
16338c2ecf20Sopenharmony_ci	/* check inline data */
16348c2ecf20Sopenharmony_ci	if (cmd_val(s, 0) & BIT(18))
16358c2ecf20Sopenharmony_ci		valid_len = CMD_LEN(9);
16368c2ecf20Sopenharmony_ci	ret = gvt_check_valid_cmd_length(cmd_length(s),
16378c2ecf20Sopenharmony_ci			valid_len);
16388c2ecf20Sopenharmony_ci	if (ret)
16398c2ecf20Sopenharmony_ci		return ret;
16408c2ecf20Sopenharmony_ci
16418c2ecf20Sopenharmony_ci	gma = cmd_val(s, 1) & GENMASK(31, 2);
16428c2ecf20Sopenharmony_ci	if (gmadr_bytes == 8) {
16438c2ecf20Sopenharmony_ci		gma_high = cmd_val(s, 2) & GENMASK(15, 0);
16448c2ecf20Sopenharmony_ci		gma = (gma_high << 32) | gma;
16458c2ecf20Sopenharmony_ci	}
16468c2ecf20Sopenharmony_ci	ret = cmd_address_audit(s, gma, op_size, false);
16478c2ecf20Sopenharmony_ci	return ret;
16488c2ecf20Sopenharmony_ci}
16498c2ecf20Sopenharmony_ci
16508c2ecf20Sopenharmony_cistatic int cmd_handler_mi_store_data_index(struct parser_exec_state *s)
16518c2ecf20Sopenharmony_ci{
16528c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16538c2ecf20Sopenharmony_ci}
16548c2ecf20Sopenharmony_ci
16558c2ecf20Sopenharmony_cistatic int cmd_handler_mi_clflush(struct parser_exec_state *s)
16568c2ecf20Sopenharmony_ci{
16578c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16588c2ecf20Sopenharmony_ci}
16598c2ecf20Sopenharmony_ci
16608c2ecf20Sopenharmony_cistatic int cmd_handler_mi_conditional_batch_buffer_end(
16618c2ecf20Sopenharmony_ci		struct parser_exec_state *s)
16628c2ecf20Sopenharmony_ci{
16638c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16648c2ecf20Sopenharmony_ci}
16658c2ecf20Sopenharmony_ci
16668c2ecf20Sopenharmony_cistatic int cmd_handler_mi_update_gtt(struct parser_exec_state *s)
16678c2ecf20Sopenharmony_ci{
16688c2ecf20Sopenharmony_ci	return unexpected_cmd(s);
16698c2ecf20Sopenharmony_ci}
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_cistatic int cmd_handler_mi_flush_dw(struct parser_exec_state *s)
16728c2ecf20Sopenharmony_ci{
16738c2ecf20Sopenharmony_ci	int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd;
16748c2ecf20Sopenharmony_ci	unsigned long gma;
16758c2ecf20Sopenharmony_ci	bool index_mode = false;
16768c2ecf20Sopenharmony_ci	int ret = 0;
16778c2ecf20Sopenharmony_ci	u32 hws_pga, val;
16788c2ecf20Sopenharmony_ci	u32 valid_len = CMD_LEN(2);
16798c2ecf20Sopenharmony_ci
16808c2ecf20Sopenharmony_ci	ret = gvt_check_valid_cmd_length(cmd_length(s),
16818c2ecf20Sopenharmony_ci			valid_len);
16828c2ecf20Sopenharmony_ci	if (ret) {
16838c2ecf20Sopenharmony_ci		/* Check again for Qword */
16848c2ecf20Sopenharmony_ci		ret = gvt_check_valid_cmd_length(cmd_length(s),
16858c2ecf20Sopenharmony_ci			++valid_len);
16868c2ecf20Sopenharmony_ci		return ret;
16878c2ecf20Sopenharmony_ci	}
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_ci	/* Check post-sync and ppgtt bit */
16908c2ecf20Sopenharmony_ci	if (((cmd_val(s, 0) >> 14) & 0x3) && (cmd_val(s, 1) & (1 << 2))) {
16918c2ecf20Sopenharmony_ci		gma = cmd_val(s, 1) & GENMASK(31, 3);
16928c2ecf20Sopenharmony_ci		if (gmadr_bytes == 8)
16938c2ecf20Sopenharmony_ci			gma |= (cmd_val(s, 2) & GENMASK(15, 0)) << 32;
16948c2ecf20Sopenharmony_ci		/* Store Data Index */
16958c2ecf20Sopenharmony_ci		if (cmd_val(s, 0) & (1 << 21))
16968c2ecf20Sopenharmony_ci			index_mode = true;
16978c2ecf20Sopenharmony_ci		ret = cmd_address_audit(s, gma, sizeof(u64), index_mode);
16988c2ecf20Sopenharmony_ci		if (ret)
16998c2ecf20Sopenharmony_ci			return ret;
17008c2ecf20Sopenharmony_ci		if (index_mode) {
17018c2ecf20Sopenharmony_ci			hws_pga = s->vgpu->hws_pga[s->engine->id];
17028c2ecf20Sopenharmony_ci			gma = hws_pga + gma;
17038c2ecf20Sopenharmony_ci			patch_value(s, cmd_ptr(s, 1), gma);
17048c2ecf20Sopenharmony_ci			val = cmd_val(s, 0) & (~(1 << 21));
17058c2ecf20Sopenharmony_ci			patch_value(s, cmd_ptr(s, 0), val);
17068c2ecf20Sopenharmony_ci		}
17078c2ecf20Sopenharmony_ci	}
17088c2ecf20Sopenharmony_ci	/* Check notify bit */
17098c2ecf20Sopenharmony_ci	if ((cmd_val(s, 0) & (1 << 8)))
17108c2ecf20Sopenharmony_ci		set_bit(cmd_interrupt_events[s->engine->id].mi_flush_dw,
17118c2ecf20Sopenharmony_ci			s->workload->pending_events);
17128c2ecf20Sopenharmony_ci	return ret;
17138c2ecf20Sopenharmony_ci}
17148c2ecf20Sopenharmony_ci
17158c2ecf20Sopenharmony_cistatic void addr_type_update_snb(struct parser_exec_state *s)
17168c2ecf20Sopenharmony_ci{
17178c2ecf20Sopenharmony_ci	if ((s->buf_type == RING_BUFFER_INSTRUCTION) &&
17188c2ecf20Sopenharmony_ci			(BATCH_BUFFER_ADR_SPACE_BIT(cmd_val(s, 0)) == 1)) {
17198c2ecf20Sopenharmony_ci		s->buf_addr_type = PPGTT_BUFFER;
17208c2ecf20Sopenharmony_ci	}
17218c2ecf20Sopenharmony_ci}
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci
17248c2ecf20Sopenharmony_cistatic int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
17258c2ecf20Sopenharmony_ci		unsigned long gma, unsigned long end_gma, void *va)
17268c2ecf20Sopenharmony_ci{
17278c2ecf20Sopenharmony_ci	unsigned long copy_len, offset;
17288c2ecf20Sopenharmony_ci	unsigned long len = 0;
17298c2ecf20Sopenharmony_ci	unsigned long gpa;
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ci	while (gma != end_gma) {
17328c2ecf20Sopenharmony_ci		gpa = intel_vgpu_gma_to_gpa(mm, gma);
17338c2ecf20Sopenharmony_ci		if (gpa == INTEL_GVT_INVALID_ADDR) {
17348c2ecf20Sopenharmony_ci			gvt_vgpu_err("invalid gma address: %lx\n", gma);
17358c2ecf20Sopenharmony_ci			return -EFAULT;
17368c2ecf20Sopenharmony_ci		}
17378c2ecf20Sopenharmony_ci
17388c2ecf20Sopenharmony_ci		offset = gma & (I915_GTT_PAGE_SIZE - 1);
17398c2ecf20Sopenharmony_ci
17408c2ecf20Sopenharmony_ci		copy_len = (end_gma - gma) >= (I915_GTT_PAGE_SIZE - offset) ?
17418c2ecf20Sopenharmony_ci			I915_GTT_PAGE_SIZE - offset : end_gma - gma;
17428c2ecf20Sopenharmony_ci
17438c2ecf20Sopenharmony_ci		intel_gvt_hypervisor_read_gpa(vgpu, gpa, va + len, copy_len);
17448c2ecf20Sopenharmony_ci
17458c2ecf20Sopenharmony_ci		len += copy_len;
17468c2ecf20Sopenharmony_ci		gma += copy_len;
17478c2ecf20Sopenharmony_ci	}
17488c2ecf20Sopenharmony_ci	return len;
17498c2ecf20Sopenharmony_ci}
17508c2ecf20Sopenharmony_ci
17518c2ecf20Sopenharmony_ci
17528c2ecf20Sopenharmony_ci/*
17538c2ecf20Sopenharmony_ci * Check whether a batch buffer needs to be scanned. Currently
17548c2ecf20Sopenharmony_ci * the only criteria is based on privilege.
17558c2ecf20Sopenharmony_ci */
17568c2ecf20Sopenharmony_cistatic int batch_buffer_needs_scan(struct parser_exec_state *s)
17578c2ecf20Sopenharmony_ci{
17588c2ecf20Sopenharmony_ci	/* Decide privilege based on address space */
17598c2ecf20Sopenharmony_ci	if (cmd_val(s, 0) & BIT(8) &&
17608c2ecf20Sopenharmony_ci	    !(s->vgpu->scan_nonprivbb & s->engine->mask))
17618c2ecf20Sopenharmony_ci		return 0;
17628c2ecf20Sopenharmony_ci
17638c2ecf20Sopenharmony_ci	return 1;
17648c2ecf20Sopenharmony_ci}
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_cistatic const char *repr_addr_type(unsigned int type)
17678c2ecf20Sopenharmony_ci{
17688c2ecf20Sopenharmony_ci	return type == PPGTT_BUFFER ? "ppgtt" : "ggtt";
17698c2ecf20Sopenharmony_ci}
17708c2ecf20Sopenharmony_ci
17718c2ecf20Sopenharmony_cistatic int find_bb_size(struct parser_exec_state *s,
17728c2ecf20Sopenharmony_ci			unsigned long *bb_size,
17738c2ecf20Sopenharmony_ci			unsigned long *bb_end_cmd_offset)
17748c2ecf20Sopenharmony_ci{
17758c2ecf20Sopenharmony_ci	unsigned long gma = 0;
17768c2ecf20Sopenharmony_ci	const struct cmd_info *info;
17778c2ecf20Sopenharmony_ci	u32 cmd_len = 0;
17788c2ecf20Sopenharmony_ci	bool bb_end = false;
17798c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
17808c2ecf20Sopenharmony_ci	u32 cmd;
17818c2ecf20Sopenharmony_ci	struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
17828c2ecf20Sopenharmony_ci		s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_ci	*bb_size = 0;
17858c2ecf20Sopenharmony_ci	*bb_end_cmd_offset = 0;
17868c2ecf20Sopenharmony_ci
17878c2ecf20Sopenharmony_ci	/* get the start gm address of the batch buffer */
17888c2ecf20Sopenharmony_ci	gma = get_gma_bb_from_cmd(s, 1);
17898c2ecf20Sopenharmony_ci	if (gma == INTEL_GVT_INVALID_ADDR)
17908c2ecf20Sopenharmony_ci		return -EFAULT;
17918c2ecf20Sopenharmony_ci
17928c2ecf20Sopenharmony_ci	cmd = cmd_val(s, 0);
17938c2ecf20Sopenharmony_ci	info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
17948c2ecf20Sopenharmony_ci	if (info == NULL) {
17958c2ecf20Sopenharmony_ci		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
17968c2ecf20Sopenharmony_ci			     cmd, get_opcode(cmd, s->engine),
17978c2ecf20Sopenharmony_ci			     repr_addr_type(s->buf_addr_type),
17988c2ecf20Sopenharmony_ci			     s->engine->name, s->workload);
17998c2ecf20Sopenharmony_ci		return -EBADRQC;
18008c2ecf20Sopenharmony_ci	}
18018c2ecf20Sopenharmony_ci	do {
18028c2ecf20Sopenharmony_ci		if (copy_gma_to_hva(s->vgpu, mm,
18038c2ecf20Sopenharmony_ci				    gma, gma + 4, &cmd) < 0)
18048c2ecf20Sopenharmony_ci			return -EFAULT;
18058c2ecf20Sopenharmony_ci		info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
18068c2ecf20Sopenharmony_ci		if (info == NULL) {
18078c2ecf20Sopenharmony_ci			gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
18088c2ecf20Sopenharmony_ci				     cmd, get_opcode(cmd, s->engine),
18098c2ecf20Sopenharmony_ci				     repr_addr_type(s->buf_addr_type),
18108c2ecf20Sopenharmony_ci				     s->engine->name, s->workload);
18118c2ecf20Sopenharmony_ci			return -EBADRQC;
18128c2ecf20Sopenharmony_ci		}
18138c2ecf20Sopenharmony_ci
18148c2ecf20Sopenharmony_ci		if (info->opcode == OP_MI_BATCH_BUFFER_END) {
18158c2ecf20Sopenharmony_ci			bb_end = true;
18168c2ecf20Sopenharmony_ci		} else if (info->opcode == OP_MI_BATCH_BUFFER_START) {
18178c2ecf20Sopenharmony_ci			if (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)
18188c2ecf20Sopenharmony_ci				/* chained batch buffer */
18198c2ecf20Sopenharmony_ci				bb_end = true;
18208c2ecf20Sopenharmony_ci		}
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci		if (bb_end)
18238c2ecf20Sopenharmony_ci			*bb_end_cmd_offset = *bb_size;
18248c2ecf20Sopenharmony_ci
18258c2ecf20Sopenharmony_ci		cmd_len = get_cmd_length(info, cmd) << 2;
18268c2ecf20Sopenharmony_ci		*bb_size += cmd_len;
18278c2ecf20Sopenharmony_ci		gma += cmd_len;
18288c2ecf20Sopenharmony_ci	} while (!bb_end);
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_ci	return 0;
18318c2ecf20Sopenharmony_ci}
18328c2ecf20Sopenharmony_ci
18338c2ecf20Sopenharmony_cistatic int audit_bb_end(struct parser_exec_state *s, void *va)
18348c2ecf20Sopenharmony_ci{
18358c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
18368c2ecf20Sopenharmony_ci	u32 cmd = *(u32 *)va;
18378c2ecf20Sopenharmony_ci	const struct cmd_info *info;
18388c2ecf20Sopenharmony_ci
18398c2ecf20Sopenharmony_ci	info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
18408c2ecf20Sopenharmony_ci	if (info == NULL) {
18418c2ecf20Sopenharmony_ci		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
18428c2ecf20Sopenharmony_ci			     cmd, get_opcode(cmd, s->engine),
18438c2ecf20Sopenharmony_ci			     repr_addr_type(s->buf_addr_type),
18448c2ecf20Sopenharmony_ci			     s->engine->name, s->workload);
18458c2ecf20Sopenharmony_ci		return -EBADRQC;
18468c2ecf20Sopenharmony_ci	}
18478c2ecf20Sopenharmony_ci
18488c2ecf20Sopenharmony_ci	if ((info->opcode == OP_MI_BATCH_BUFFER_END) ||
18498c2ecf20Sopenharmony_ci	    ((info->opcode == OP_MI_BATCH_BUFFER_START) &&
18508c2ecf20Sopenharmony_ci	     (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0)))
18518c2ecf20Sopenharmony_ci		return 0;
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci	return -EBADRQC;
18548c2ecf20Sopenharmony_ci}
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_cistatic int perform_bb_shadow(struct parser_exec_state *s)
18578c2ecf20Sopenharmony_ci{
18588c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
18598c2ecf20Sopenharmony_ci	struct intel_vgpu_shadow_bb *bb;
18608c2ecf20Sopenharmony_ci	unsigned long gma = 0;
18618c2ecf20Sopenharmony_ci	unsigned long bb_size;
18628c2ecf20Sopenharmony_ci	unsigned long bb_end_cmd_offset;
18638c2ecf20Sopenharmony_ci	int ret = 0;
18648c2ecf20Sopenharmony_ci	struct intel_vgpu_mm *mm = (s->buf_addr_type == GTT_BUFFER) ?
18658c2ecf20Sopenharmony_ci		s->vgpu->gtt.ggtt_mm : s->workload->shadow_mm;
18668c2ecf20Sopenharmony_ci	unsigned long start_offset = 0;
18678c2ecf20Sopenharmony_ci
18688c2ecf20Sopenharmony_ci	/* get the start gm address of the batch buffer */
18698c2ecf20Sopenharmony_ci	gma = get_gma_bb_from_cmd(s, 1);
18708c2ecf20Sopenharmony_ci	if (gma == INTEL_GVT_INVALID_ADDR)
18718c2ecf20Sopenharmony_ci		return -EFAULT;
18728c2ecf20Sopenharmony_ci
18738c2ecf20Sopenharmony_ci	ret = find_bb_size(s, &bb_size, &bb_end_cmd_offset);
18748c2ecf20Sopenharmony_ci	if (ret)
18758c2ecf20Sopenharmony_ci		return ret;
18768c2ecf20Sopenharmony_ci
18778c2ecf20Sopenharmony_ci	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
18788c2ecf20Sopenharmony_ci	if (!bb)
18798c2ecf20Sopenharmony_ci		return -ENOMEM;
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci	bb->ppgtt = (s->buf_addr_type == GTT_BUFFER) ? false : true;
18828c2ecf20Sopenharmony_ci
18838c2ecf20Sopenharmony_ci	/* the start_offset stores the batch buffer's start gma's
18848c2ecf20Sopenharmony_ci	 * offset relative to page boundary. so for non-privileged batch
18858c2ecf20Sopenharmony_ci	 * buffer, the shadowed gem object holds exactly the same page
18868c2ecf20Sopenharmony_ci	 * layout as original gem object. This is for the convience of
18878c2ecf20Sopenharmony_ci	 * replacing the whole non-privilged batch buffer page to this
18888c2ecf20Sopenharmony_ci	 * shadowed one in PPGTT at the same gma address. (this replacing
18898c2ecf20Sopenharmony_ci	 * action is not implemented yet now, but may be necessary in
18908c2ecf20Sopenharmony_ci	 * future).
18918c2ecf20Sopenharmony_ci	 * for prileged batch buffer, we just change start gma address to
18928c2ecf20Sopenharmony_ci	 * that of shadowed page.
18938c2ecf20Sopenharmony_ci	 */
18948c2ecf20Sopenharmony_ci	if (bb->ppgtt)
18958c2ecf20Sopenharmony_ci		start_offset = gma & ~I915_GTT_PAGE_MASK;
18968c2ecf20Sopenharmony_ci
18978c2ecf20Sopenharmony_ci	bb->obj = i915_gem_object_create_shmem(s->engine->i915,
18988c2ecf20Sopenharmony_ci					       round_up(bb_size + start_offset,
18998c2ecf20Sopenharmony_ci							PAGE_SIZE));
19008c2ecf20Sopenharmony_ci	if (IS_ERR(bb->obj)) {
19018c2ecf20Sopenharmony_ci		ret = PTR_ERR(bb->obj);
19028c2ecf20Sopenharmony_ci		goto err_free_bb;
19038c2ecf20Sopenharmony_ci	}
19048c2ecf20Sopenharmony_ci
19058c2ecf20Sopenharmony_ci	bb->va = i915_gem_object_pin_map(bb->obj, I915_MAP_WB);
19068c2ecf20Sopenharmony_ci	if (IS_ERR(bb->va)) {
19078c2ecf20Sopenharmony_ci		ret = PTR_ERR(bb->va);
19088c2ecf20Sopenharmony_ci		goto err_free_obj;
19098c2ecf20Sopenharmony_ci	}
19108c2ecf20Sopenharmony_ci
19118c2ecf20Sopenharmony_ci	ret = copy_gma_to_hva(s->vgpu, mm,
19128c2ecf20Sopenharmony_ci			      gma, gma + bb_size,
19138c2ecf20Sopenharmony_ci			      bb->va + start_offset);
19148c2ecf20Sopenharmony_ci	if (ret < 0) {
19158c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to copy guest ring buffer\n");
19168c2ecf20Sopenharmony_ci		ret = -EFAULT;
19178c2ecf20Sopenharmony_ci		goto err_unmap;
19188c2ecf20Sopenharmony_ci	}
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ci	ret = audit_bb_end(s, bb->va + start_offset + bb_end_cmd_offset);
19218c2ecf20Sopenharmony_ci	if (ret)
19228c2ecf20Sopenharmony_ci		goto err_unmap;
19238c2ecf20Sopenharmony_ci
19248c2ecf20Sopenharmony_ci	i915_gem_object_unlock(bb->obj);
19258c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&bb->list);
19268c2ecf20Sopenharmony_ci	list_add(&bb->list, &s->workload->shadow_bb);
19278c2ecf20Sopenharmony_ci
19288c2ecf20Sopenharmony_ci	bb->bb_start_cmd_va = s->ip_va;
19298c2ecf20Sopenharmony_ci
19308c2ecf20Sopenharmony_ci	if ((s->buf_type == BATCH_BUFFER_INSTRUCTION) && (!s->is_ctx_wa))
19318c2ecf20Sopenharmony_ci		bb->bb_offset = s->ip_va - s->rb_va;
19328c2ecf20Sopenharmony_ci	else
19338c2ecf20Sopenharmony_ci		bb->bb_offset = 0;
19348c2ecf20Sopenharmony_ci
19358c2ecf20Sopenharmony_ci	/*
19368c2ecf20Sopenharmony_ci	 * ip_va saves the virtual address of the shadow batch buffer, while
19378c2ecf20Sopenharmony_ci	 * ip_gma saves the graphics address of the original batch buffer.
19388c2ecf20Sopenharmony_ci	 * As the shadow batch buffer is just a copy from the originial one,
19398c2ecf20Sopenharmony_ci	 * it should be right to use shadow batch buffer'va and original batch
19408c2ecf20Sopenharmony_ci	 * buffer's gma in pair. After all, we don't want to pin the shadow
19418c2ecf20Sopenharmony_ci	 * buffer here (too early).
19428c2ecf20Sopenharmony_ci	 */
19438c2ecf20Sopenharmony_ci	s->ip_va = bb->va + start_offset;
19448c2ecf20Sopenharmony_ci	s->ip_gma = gma;
19458c2ecf20Sopenharmony_ci	return 0;
19468c2ecf20Sopenharmony_cierr_unmap:
19478c2ecf20Sopenharmony_ci	i915_gem_object_unpin_map(bb->obj);
19488c2ecf20Sopenharmony_cierr_free_obj:
19498c2ecf20Sopenharmony_ci	i915_gem_object_put(bb->obj);
19508c2ecf20Sopenharmony_cierr_free_bb:
19518c2ecf20Sopenharmony_ci	kfree(bb);
19528c2ecf20Sopenharmony_ci	return ret;
19538c2ecf20Sopenharmony_ci}
19548c2ecf20Sopenharmony_ci
19558c2ecf20Sopenharmony_cistatic int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s)
19568c2ecf20Sopenharmony_ci{
19578c2ecf20Sopenharmony_ci	bool second_level;
19588c2ecf20Sopenharmony_ci	int ret = 0;
19598c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
19608c2ecf20Sopenharmony_ci
19618c2ecf20Sopenharmony_ci	if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) {
19628c2ecf20Sopenharmony_ci		gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n");
19638c2ecf20Sopenharmony_ci		return -EFAULT;
19648c2ecf20Sopenharmony_ci	}
19658c2ecf20Sopenharmony_ci
19668c2ecf20Sopenharmony_ci	second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1;
19678c2ecf20Sopenharmony_ci	if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) {
19688c2ecf20Sopenharmony_ci		gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n");
19698c2ecf20Sopenharmony_ci		return -EFAULT;
19708c2ecf20Sopenharmony_ci	}
19718c2ecf20Sopenharmony_ci
19728c2ecf20Sopenharmony_ci	s->saved_buf_addr_type = s->buf_addr_type;
19738c2ecf20Sopenharmony_ci	addr_type_update_snb(s);
19748c2ecf20Sopenharmony_ci	if (s->buf_type == RING_BUFFER_INSTRUCTION) {
19758c2ecf20Sopenharmony_ci		s->ret_ip_gma_ring = s->ip_gma + cmd_length(s) * sizeof(u32);
19768c2ecf20Sopenharmony_ci		s->buf_type = BATCH_BUFFER_INSTRUCTION;
19778c2ecf20Sopenharmony_ci	} else if (second_level) {
19788c2ecf20Sopenharmony_ci		s->buf_type = BATCH_BUFFER_2ND_LEVEL;
19798c2ecf20Sopenharmony_ci		s->ret_ip_gma_bb = s->ip_gma + cmd_length(s) * sizeof(u32);
19808c2ecf20Sopenharmony_ci		s->ret_bb_va = s->ip_va + cmd_length(s) * sizeof(u32);
19818c2ecf20Sopenharmony_ci	}
19828c2ecf20Sopenharmony_ci
19838c2ecf20Sopenharmony_ci	if (batch_buffer_needs_scan(s)) {
19848c2ecf20Sopenharmony_ci		ret = perform_bb_shadow(s);
19858c2ecf20Sopenharmony_ci		if (ret < 0)
19868c2ecf20Sopenharmony_ci			gvt_vgpu_err("invalid shadow batch buffer\n");
19878c2ecf20Sopenharmony_ci	} else {
19888c2ecf20Sopenharmony_ci		/* emulate a batch buffer end to do return right */
19898c2ecf20Sopenharmony_ci		ret = cmd_handler_mi_batch_buffer_end(s);
19908c2ecf20Sopenharmony_ci		if (ret < 0)
19918c2ecf20Sopenharmony_ci			return ret;
19928c2ecf20Sopenharmony_ci	}
19938c2ecf20Sopenharmony_ci	return ret;
19948c2ecf20Sopenharmony_ci}
19958c2ecf20Sopenharmony_ci
19968c2ecf20Sopenharmony_cistatic int mi_noop_index;
19978c2ecf20Sopenharmony_ci
19988c2ecf20Sopenharmony_cistatic const struct cmd_info cmd_info[] = {
19998c2ecf20Sopenharmony_ci	{"MI_NOOP", OP_MI_NOOP, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
20008c2ecf20Sopenharmony_ci
20018c2ecf20Sopenharmony_ci	{"MI_SET_PREDICATE", OP_MI_SET_PREDICATE, F_LEN_CONST, R_ALL, D_ALL,
20028c2ecf20Sopenharmony_ci		0, 1, NULL},
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	{"MI_USER_INTERRUPT", OP_MI_USER_INTERRUPT, F_LEN_CONST, R_ALL, D_ALL,
20058c2ecf20Sopenharmony_ci		0, 1, cmd_handler_mi_user_interrupt},
20068c2ecf20Sopenharmony_ci
20078c2ecf20Sopenharmony_ci	{"MI_WAIT_FOR_EVENT", OP_MI_WAIT_FOR_EVENT, F_LEN_CONST, R_RCS | R_BCS,
20088c2ecf20Sopenharmony_ci		D_ALL, 0, 1, cmd_handler_mi_wait_for_event},
20098c2ecf20Sopenharmony_ci
20108c2ecf20Sopenharmony_ci	{"MI_FLUSH", OP_MI_FLUSH, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
20118c2ecf20Sopenharmony_ci
20128c2ecf20Sopenharmony_ci	{"MI_ARB_CHECK", OP_MI_ARB_CHECK, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
20138c2ecf20Sopenharmony_ci		NULL},
20148c2ecf20Sopenharmony_ci
20158c2ecf20Sopenharmony_ci	{"MI_RS_CONTROL", OP_MI_RS_CONTROL, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
20168c2ecf20Sopenharmony_ci		NULL},
20178c2ecf20Sopenharmony_ci
20188c2ecf20Sopenharmony_ci	{"MI_REPORT_HEAD", OP_MI_REPORT_HEAD, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
20198c2ecf20Sopenharmony_ci		NULL},
20208c2ecf20Sopenharmony_ci
20218c2ecf20Sopenharmony_ci	{"MI_ARB_ON_OFF", OP_MI_ARB_ON_OFF, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
20228c2ecf20Sopenharmony_ci		NULL},
20238c2ecf20Sopenharmony_ci
20248c2ecf20Sopenharmony_ci	{"MI_URB_ATOMIC_ALLOC", OP_MI_URB_ATOMIC_ALLOC, F_LEN_CONST, R_RCS,
20258c2ecf20Sopenharmony_ci		D_ALL, 0, 1, NULL},
20268c2ecf20Sopenharmony_ci
20278c2ecf20Sopenharmony_ci	{"MI_BATCH_BUFFER_END", OP_MI_BATCH_BUFFER_END,
20288c2ecf20Sopenharmony_ci		F_IP_ADVANCE_CUSTOM | F_LEN_CONST, R_ALL, D_ALL, 0, 1,
20298c2ecf20Sopenharmony_ci		cmd_handler_mi_batch_buffer_end},
20308c2ecf20Sopenharmony_ci
20318c2ecf20Sopenharmony_ci	{"MI_SUSPEND_FLUSH", OP_MI_SUSPEND_FLUSH, F_LEN_CONST, R_ALL, D_ALL,
20328c2ecf20Sopenharmony_ci		0, 1, NULL},
20338c2ecf20Sopenharmony_ci
20348c2ecf20Sopenharmony_ci	{"MI_PREDICATE", OP_MI_PREDICATE, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
20358c2ecf20Sopenharmony_ci		NULL},
20368c2ecf20Sopenharmony_ci
20378c2ecf20Sopenharmony_ci	{"MI_TOPOLOGY_FILTER", OP_MI_TOPOLOGY_FILTER, F_LEN_CONST, R_ALL,
20388c2ecf20Sopenharmony_ci		D_ALL, 0, 1, NULL},
20398c2ecf20Sopenharmony_ci
20408c2ecf20Sopenharmony_ci	{"MI_SET_APPID", OP_MI_SET_APPID, F_LEN_CONST, R_ALL, D_ALL, 0, 1,
20418c2ecf20Sopenharmony_ci		NULL},
20428c2ecf20Sopenharmony_ci
20438c2ecf20Sopenharmony_ci	{"MI_RS_CONTEXT", OP_MI_RS_CONTEXT, F_LEN_CONST, R_RCS, D_ALL, 0, 1,
20448c2ecf20Sopenharmony_ci		NULL},
20458c2ecf20Sopenharmony_ci
20468c2ecf20Sopenharmony_ci	{"MI_DISPLAY_FLIP", OP_MI_DISPLAY_FLIP, F_LEN_VAR,
20478c2ecf20Sopenharmony_ci		R_RCS | R_BCS, D_ALL, 0, 8, cmd_handler_mi_display_flip},
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_ci	{"MI_SEMAPHORE_MBOX", OP_MI_SEMAPHORE_MBOX, F_LEN_VAR | F_LEN_VAR_FIXED,
20508c2ecf20Sopenharmony_ci		R_ALL, D_ALL, 0, 8, NULL, CMD_LEN(1)},
20518c2ecf20Sopenharmony_ci
20528c2ecf20Sopenharmony_ci	{"MI_MATH", OP_MI_MATH, F_LEN_VAR, R_ALL, D_ALL, 0, 8, NULL},
20538c2ecf20Sopenharmony_ci
20548c2ecf20Sopenharmony_ci	{"MI_URB_CLEAR", OP_MI_URB_CLEAR, F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS,
20558c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL, CMD_LEN(0)},
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci	{"MI_SEMAPHORE_SIGNAL", OP_MI_SEMAPHORE_SIGNAL,
20588c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, 0, 8,
20598c2ecf20Sopenharmony_ci		NULL, CMD_LEN(0)},
20608c2ecf20Sopenharmony_ci
20618c2ecf20Sopenharmony_ci	{"MI_SEMAPHORE_WAIT", OP_MI_SEMAPHORE_WAIT,
20628c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS, ADDR_FIX_1(2),
20638c2ecf20Sopenharmony_ci		8, cmd_handler_mi_semaphore_wait, CMD_LEN(2)},
20648c2ecf20Sopenharmony_ci
20658c2ecf20Sopenharmony_ci	{"MI_STORE_DATA_IMM", OP_MI_STORE_DATA_IMM, F_LEN_VAR, R_ALL, D_BDW_PLUS,
20668c2ecf20Sopenharmony_ci		ADDR_FIX_1(1), 10, cmd_handler_mi_store_data_imm},
20678c2ecf20Sopenharmony_ci
20688c2ecf20Sopenharmony_ci	{"MI_STORE_DATA_INDEX", OP_MI_STORE_DATA_INDEX, F_LEN_VAR, R_ALL, D_ALL,
20698c2ecf20Sopenharmony_ci		0, 8, cmd_handler_mi_store_data_index},
20708c2ecf20Sopenharmony_ci
20718c2ecf20Sopenharmony_ci	{"MI_LOAD_REGISTER_IMM", OP_MI_LOAD_REGISTER_IMM, F_LEN_VAR, R_ALL,
20728c2ecf20Sopenharmony_ci		D_ALL, 0, 8, cmd_handler_lri},
20738c2ecf20Sopenharmony_ci
20748c2ecf20Sopenharmony_ci	{"MI_UPDATE_GTT", OP_MI_UPDATE_GTT, F_LEN_VAR, R_ALL, D_BDW_PLUS, 0, 10,
20758c2ecf20Sopenharmony_ci		cmd_handler_mi_update_gtt},
20768c2ecf20Sopenharmony_ci
20778c2ecf20Sopenharmony_ci	{"MI_STORE_REGISTER_MEM", OP_MI_STORE_REGISTER_MEM,
20788c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
20798c2ecf20Sopenharmony_ci		cmd_handler_srm, CMD_LEN(2)},
20808c2ecf20Sopenharmony_ci
20818c2ecf20Sopenharmony_ci	{"MI_FLUSH_DW", OP_MI_FLUSH_DW, F_LEN_VAR, R_ALL, D_ALL, 0, 6,
20828c2ecf20Sopenharmony_ci		cmd_handler_mi_flush_dw},
20838c2ecf20Sopenharmony_ci
20848c2ecf20Sopenharmony_ci	{"MI_CLFLUSH", OP_MI_CLFLUSH, F_LEN_VAR, R_ALL, D_ALL, ADDR_FIX_1(1),
20858c2ecf20Sopenharmony_ci		10, cmd_handler_mi_clflush},
20868c2ecf20Sopenharmony_ci
20878c2ecf20Sopenharmony_ci	{"MI_REPORT_PERF_COUNT", OP_MI_REPORT_PERF_COUNT,
20888c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(1), 6,
20898c2ecf20Sopenharmony_ci		cmd_handler_mi_report_perf_count, CMD_LEN(2)},
20908c2ecf20Sopenharmony_ci
20918c2ecf20Sopenharmony_ci	{"MI_LOAD_REGISTER_MEM", OP_MI_LOAD_REGISTER_MEM,
20928c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
20938c2ecf20Sopenharmony_ci		cmd_handler_lrm, CMD_LEN(2)},
20948c2ecf20Sopenharmony_ci
20958c2ecf20Sopenharmony_ci	{"MI_LOAD_REGISTER_REG", OP_MI_LOAD_REGISTER_REG,
20968c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, 0, 8,
20978c2ecf20Sopenharmony_ci		cmd_handler_lrr, CMD_LEN(1)},
20988c2ecf20Sopenharmony_ci
20998c2ecf20Sopenharmony_ci	{"MI_RS_STORE_DATA_IMM", OP_MI_RS_STORE_DATA_IMM,
21008c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_RCS, D_ALL, 0,
21018c2ecf20Sopenharmony_ci		8, NULL, CMD_LEN(2)},
21028c2ecf20Sopenharmony_ci
21038c2ecf20Sopenharmony_ci	{"MI_LOAD_URB_MEM", OP_MI_LOAD_URB_MEM, F_LEN_VAR | F_LEN_VAR_FIXED,
21048c2ecf20Sopenharmony_ci		R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL, CMD_LEN(2)},
21058c2ecf20Sopenharmony_ci
21068c2ecf20Sopenharmony_ci	{"MI_STORE_URM_MEM", OP_MI_STORE_URM_MEM, F_LEN_VAR, R_RCS, D_ALL,
21078c2ecf20Sopenharmony_ci		ADDR_FIX_1(2), 8, NULL},
21088c2ecf20Sopenharmony_ci
21098c2ecf20Sopenharmony_ci	{"MI_OP_2E", OP_MI_2E, F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_BDW_PLUS,
21108c2ecf20Sopenharmony_ci		ADDR_FIX_2(1, 2), 8, cmd_handler_mi_op_2e, CMD_LEN(3)},
21118c2ecf20Sopenharmony_ci
21128c2ecf20Sopenharmony_ci	{"MI_OP_2F", OP_MI_2F, F_LEN_VAR, R_ALL, D_BDW_PLUS, ADDR_FIX_1(1),
21138c2ecf20Sopenharmony_ci		8, cmd_handler_mi_op_2f},
21148c2ecf20Sopenharmony_ci
21158c2ecf20Sopenharmony_ci	{"MI_BATCH_BUFFER_START", OP_MI_BATCH_BUFFER_START,
21168c2ecf20Sopenharmony_ci		F_IP_ADVANCE_CUSTOM, R_ALL, D_ALL, 0, 8,
21178c2ecf20Sopenharmony_ci		cmd_handler_mi_batch_buffer_start},
21188c2ecf20Sopenharmony_ci
21198c2ecf20Sopenharmony_ci	{"MI_CONDITIONAL_BATCH_BUFFER_END", OP_MI_CONDITIONAL_BATCH_BUFFER_END,
21208c2ecf20Sopenharmony_ci		F_LEN_VAR | F_LEN_VAR_FIXED, R_ALL, D_ALL, ADDR_FIX_1(2), 8,
21218c2ecf20Sopenharmony_ci		cmd_handler_mi_conditional_batch_buffer_end, CMD_LEN(2)},
21228c2ecf20Sopenharmony_ci
21238c2ecf20Sopenharmony_ci	{"MI_LOAD_SCAN_LINES_INCL", OP_MI_LOAD_SCAN_LINES_INCL, F_LEN_CONST,
21248c2ecf20Sopenharmony_ci		R_RCS | R_BCS, D_ALL, 0, 2, NULL},
21258c2ecf20Sopenharmony_ci
21268c2ecf20Sopenharmony_ci	{"XY_SETUP_BLT", OP_XY_SETUP_BLT, F_LEN_VAR, R_BCS, D_ALL,
21278c2ecf20Sopenharmony_ci		ADDR_FIX_2(4, 7), 8, NULL},
21288c2ecf20Sopenharmony_ci
21298c2ecf20Sopenharmony_ci	{"XY_SETUP_CLIP_BLT", OP_XY_SETUP_CLIP_BLT, F_LEN_VAR, R_BCS, D_ALL,
21308c2ecf20Sopenharmony_ci		0, 8, NULL},
21318c2ecf20Sopenharmony_ci
21328c2ecf20Sopenharmony_ci	{"XY_SETUP_MONO_PATTERN_SL_BLT", OP_XY_SETUP_MONO_PATTERN_SL_BLT,
21338c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
21348c2ecf20Sopenharmony_ci
21358c2ecf20Sopenharmony_ci	{"XY_PIXEL_BLT", OP_XY_PIXEL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
21368c2ecf20Sopenharmony_ci
21378c2ecf20Sopenharmony_ci	{"XY_SCANLINES_BLT", OP_XY_SCANLINES_BLT, F_LEN_VAR, R_BCS, D_ALL,
21388c2ecf20Sopenharmony_ci		0, 8, NULL},
21398c2ecf20Sopenharmony_ci
21408c2ecf20Sopenharmony_ci	{"XY_TEXT_BLT", OP_XY_TEXT_BLT, F_LEN_VAR, R_BCS, D_ALL,
21418c2ecf20Sopenharmony_ci		ADDR_FIX_1(3), 8, NULL},
21428c2ecf20Sopenharmony_ci
21438c2ecf20Sopenharmony_ci	{"XY_TEXT_IMMEDIATE_BLT", OP_XY_TEXT_IMMEDIATE_BLT, F_LEN_VAR, R_BCS,
21448c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
21458c2ecf20Sopenharmony_ci
21468c2ecf20Sopenharmony_ci	{"XY_COLOR_BLT", OP_XY_COLOR_BLT, F_LEN_VAR, R_BCS, D_ALL,
21478c2ecf20Sopenharmony_ci		ADDR_FIX_1(4), 8, NULL},
21488c2ecf20Sopenharmony_ci
21498c2ecf20Sopenharmony_ci	{"XY_PAT_BLT", OP_XY_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
21508c2ecf20Sopenharmony_ci		ADDR_FIX_2(4, 5), 8, NULL},
21518c2ecf20Sopenharmony_ci
21528c2ecf20Sopenharmony_ci	{"XY_MONO_PAT_BLT", OP_XY_MONO_PAT_BLT, F_LEN_VAR, R_BCS, D_ALL,
21538c2ecf20Sopenharmony_ci		ADDR_FIX_1(4), 8, NULL},
21548c2ecf20Sopenharmony_ci
21558c2ecf20Sopenharmony_ci	{"XY_SRC_COPY_BLT", OP_XY_SRC_COPY_BLT, F_LEN_VAR, R_BCS, D_ALL,
21568c2ecf20Sopenharmony_ci		ADDR_FIX_2(4, 7), 8, NULL},
21578c2ecf20Sopenharmony_ci
21588c2ecf20Sopenharmony_ci	{"XY_MONO_SRC_COPY_BLT", OP_XY_MONO_SRC_COPY_BLT, F_LEN_VAR, R_BCS,
21598c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
21608c2ecf20Sopenharmony_ci
21618c2ecf20Sopenharmony_ci	{"XY_FULL_BLT", OP_XY_FULL_BLT, F_LEN_VAR, R_BCS, D_ALL, 0, 8, NULL},
21628c2ecf20Sopenharmony_ci
21638c2ecf20Sopenharmony_ci	{"XY_FULL_MONO_SRC_BLT", OP_XY_FULL_MONO_SRC_BLT, F_LEN_VAR, R_BCS,
21648c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_3(4, 5, 8), 8, NULL},
21658c2ecf20Sopenharmony_ci
21668c2ecf20Sopenharmony_ci	{"XY_FULL_MONO_PATTERN_BLT", OP_XY_FULL_MONO_PATTERN_BLT, F_LEN_VAR,
21678c2ecf20Sopenharmony_ci		R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_ci	{"XY_FULL_MONO_PATTERN_MONO_SRC_BLT",
21708c2ecf20Sopenharmony_ci		OP_XY_FULL_MONO_PATTERN_MONO_SRC_BLT,
21718c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
21728c2ecf20Sopenharmony_ci
21738c2ecf20Sopenharmony_ci	{"XY_MONO_PAT_FIXED_BLT", OP_XY_MONO_PAT_FIXED_BLT, F_LEN_VAR, R_BCS,
21748c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_1(4), 8, NULL},
21758c2ecf20Sopenharmony_ci
21768c2ecf20Sopenharmony_ci	{"XY_MONO_SRC_COPY_IMMEDIATE_BLT", OP_XY_MONO_SRC_COPY_IMMEDIATE_BLT,
21778c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
21788c2ecf20Sopenharmony_ci
21798c2ecf20Sopenharmony_ci	{"XY_PAT_BLT_IMMEDIATE", OP_XY_PAT_BLT_IMMEDIATE, F_LEN_VAR, R_BCS,
21808c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_1(4), 8, NULL},
21818c2ecf20Sopenharmony_ci
21828c2ecf20Sopenharmony_ci	{"XY_SRC_COPY_CHROMA_BLT", OP_XY_SRC_COPY_CHROMA_BLT, F_LEN_VAR, R_BCS,
21838c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
21848c2ecf20Sopenharmony_ci
21858c2ecf20Sopenharmony_ci	{"XY_FULL_IMMEDIATE_PATTERN_BLT", OP_XY_FULL_IMMEDIATE_PATTERN_BLT,
21868c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 7), 8, NULL},
21878c2ecf20Sopenharmony_ci
21888c2ecf20Sopenharmony_ci	{"XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT",
21898c2ecf20Sopenharmony_ci		OP_XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT,
21908c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_2(4, 5), 8, NULL},
21918c2ecf20Sopenharmony_ci
21928c2ecf20Sopenharmony_ci	{"XY_PAT_CHROMA_BLT", OP_XY_PAT_CHROMA_BLT, F_LEN_VAR, R_BCS, D_ALL,
21938c2ecf20Sopenharmony_ci		ADDR_FIX_2(4, 5), 8, NULL},
21948c2ecf20Sopenharmony_ci
21958c2ecf20Sopenharmony_ci	{"XY_PAT_CHROMA_BLT_IMMEDIATE", OP_XY_PAT_CHROMA_BLT_IMMEDIATE,
21968c2ecf20Sopenharmony_ci		F_LEN_VAR, R_BCS, D_ALL, ADDR_FIX_1(4), 8, NULL},
21978c2ecf20Sopenharmony_ci
21988c2ecf20Sopenharmony_ci	{"3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP",
21998c2ecf20Sopenharmony_ci		OP_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
22008c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22018c2ecf20Sopenharmony_ci
22028c2ecf20Sopenharmony_ci	{"3DSTATE_VIEWPORT_STATE_POINTERS_CC",
22038c2ecf20Sopenharmony_ci		OP_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
22048c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22058c2ecf20Sopenharmony_ci
22068c2ecf20Sopenharmony_ci	{"3DSTATE_BLEND_STATE_POINTERS",
22078c2ecf20Sopenharmony_ci		OP_3DSTATE_BLEND_STATE_POINTERS,
22088c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22098c2ecf20Sopenharmony_ci
22108c2ecf20Sopenharmony_ci	{"3DSTATE_DEPTH_STENCIL_STATE_POINTERS",
22118c2ecf20Sopenharmony_ci		OP_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
22128c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22138c2ecf20Sopenharmony_ci
22148c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POINTERS_VS",
22158c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POINTERS_VS,
22168c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22178c2ecf20Sopenharmony_ci
22188c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POINTERS_HS",
22198c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POINTERS_HS,
22208c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22218c2ecf20Sopenharmony_ci
22228c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POINTERS_DS",
22238c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POINTERS_DS,
22248c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22258c2ecf20Sopenharmony_ci
22268c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POINTERS_GS",
22278c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POINTERS_GS,
22288c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22298c2ecf20Sopenharmony_ci
22308c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POINTERS_PS",
22318c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POINTERS_PS,
22328c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_STATE_POINTERS_VS",
22358c2ecf20Sopenharmony_ci		OP_3DSTATE_SAMPLER_STATE_POINTERS_VS,
22368c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_STATE_POINTERS_HS",
22398c2ecf20Sopenharmony_ci		OP_3DSTATE_SAMPLER_STATE_POINTERS_HS,
22408c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22418c2ecf20Sopenharmony_ci
22428c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_STATE_POINTERS_DS",
22438c2ecf20Sopenharmony_ci		OP_3DSTATE_SAMPLER_STATE_POINTERS_DS,
22448c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22458c2ecf20Sopenharmony_ci
22468c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_STATE_POINTERS_GS",
22478c2ecf20Sopenharmony_ci		OP_3DSTATE_SAMPLER_STATE_POINTERS_GS,
22488c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22498c2ecf20Sopenharmony_ci
22508c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_STATE_POINTERS_PS",
22518c2ecf20Sopenharmony_ci		OP_3DSTATE_SAMPLER_STATE_POINTERS_PS,
22528c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22538c2ecf20Sopenharmony_ci
22548c2ecf20Sopenharmony_ci	{"3DSTATE_URB_VS", OP_3DSTATE_URB_VS, F_LEN_VAR, R_RCS, D_ALL,
22558c2ecf20Sopenharmony_ci		0, 8, NULL},
22568c2ecf20Sopenharmony_ci
22578c2ecf20Sopenharmony_ci	{"3DSTATE_URB_HS", OP_3DSTATE_URB_HS, F_LEN_VAR, R_RCS, D_ALL,
22588c2ecf20Sopenharmony_ci		0, 8, NULL},
22598c2ecf20Sopenharmony_ci
22608c2ecf20Sopenharmony_ci	{"3DSTATE_URB_DS", OP_3DSTATE_URB_DS, F_LEN_VAR, R_RCS, D_ALL,
22618c2ecf20Sopenharmony_ci		0, 8, NULL},
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_ci	{"3DSTATE_URB_GS", OP_3DSTATE_URB_GS, F_LEN_VAR, R_RCS, D_ALL,
22648c2ecf20Sopenharmony_ci		0, 8, NULL},
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_CONSTANT_VS", OP_3DSTATE_GATHER_CONSTANT_VS,
22678c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22688c2ecf20Sopenharmony_ci
22698c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_CONSTANT_GS", OP_3DSTATE_GATHER_CONSTANT_GS,
22708c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22718c2ecf20Sopenharmony_ci
22728c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_CONSTANT_HS", OP_3DSTATE_GATHER_CONSTANT_HS,
22738c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22748c2ecf20Sopenharmony_ci
22758c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_CONSTANT_DS", OP_3DSTATE_GATHER_CONSTANT_DS,
22768c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22778c2ecf20Sopenharmony_ci
22788c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_CONSTANT_PS", OP_3DSTATE_GATHER_CONSTANT_PS,
22798c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22808c2ecf20Sopenharmony_ci
22818c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTF_VS", OP_3DSTATE_DX9_CONSTANTF_VS,
22828c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
22838c2ecf20Sopenharmony_ci
22848c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTF_PS", OP_3DSTATE_DX9_CONSTANTF_PS,
22858c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 11, NULL},
22868c2ecf20Sopenharmony_ci
22878c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTI_VS", OP_3DSTATE_DX9_CONSTANTI_VS,
22888c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22898c2ecf20Sopenharmony_ci
22908c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTI_PS", OP_3DSTATE_DX9_CONSTANTI_PS,
22918c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTB_VS", OP_3DSTATE_DX9_CONSTANTB_VS,
22948c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22958c2ecf20Sopenharmony_ci
22968c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANTB_PS", OP_3DSTATE_DX9_CONSTANTB_PS,
22978c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
22988c2ecf20Sopenharmony_ci
22998c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_LOCAL_VALID_VS", OP_3DSTATE_DX9_LOCAL_VALID_VS,
23008c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23018c2ecf20Sopenharmony_ci
23028c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_LOCAL_VALID_PS", OP_3DSTATE_DX9_LOCAL_VALID_PS,
23038c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23048c2ecf20Sopenharmony_ci
23058c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_GENERATE_ACTIVE_VS", OP_3DSTATE_DX9_GENERATE_ACTIVE_VS,
23068c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23078c2ecf20Sopenharmony_ci
23088c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_GENERATE_ACTIVE_PS", OP_3DSTATE_DX9_GENERATE_ACTIVE_PS,
23098c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23108c2ecf20Sopenharmony_ci
23118c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_EDIT_VS", OP_3DSTATE_BINDING_TABLE_EDIT_VS,
23128c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
23138c2ecf20Sopenharmony_ci
23148c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_EDIT_GS", OP_3DSTATE_BINDING_TABLE_EDIT_GS,
23158c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
23168c2ecf20Sopenharmony_ci
23178c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_EDIT_HS", OP_3DSTATE_BINDING_TABLE_EDIT_HS,
23188c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
23198c2ecf20Sopenharmony_ci
23208c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_EDIT_DS", OP_3DSTATE_BINDING_TABLE_EDIT_DS,
23218c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_EDIT_PS", OP_3DSTATE_BINDING_TABLE_EDIT_PS,
23248c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 9, NULL},
23258c2ecf20Sopenharmony_ci
23268c2ecf20Sopenharmony_ci	{"3DSTATE_VF_INSTANCING", OP_3DSTATE_VF_INSTANCING, F_LEN_VAR, R_RCS,
23278c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci	{"3DSTATE_VF_SGVS", OP_3DSTATE_VF_SGVS, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
23308c2ecf20Sopenharmony_ci		NULL},
23318c2ecf20Sopenharmony_ci
23328c2ecf20Sopenharmony_ci	{"3DSTATE_VF_TOPOLOGY", OP_3DSTATE_VF_TOPOLOGY, F_LEN_VAR, R_RCS,
23338c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23348c2ecf20Sopenharmony_ci
23358c2ecf20Sopenharmony_ci	{"3DSTATE_WM_CHROMAKEY", OP_3DSTATE_WM_CHROMAKEY, F_LEN_VAR, R_RCS,
23368c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23378c2ecf20Sopenharmony_ci
23388c2ecf20Sopenharmony_ci	{"3DSTATE_PS_BLEND", OP_3DSTATE_PS_BLEND, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
23398c2ecf20Sopenharmony_ci		8, NULL},
23408c2ecf20Sopenharmony_ci
23418c2ecf20Sopenharmony_ci	{"3DSTATE_WM_DEPTH_STENCIL", OP_3DSTATE_WM_DEPTH_STENCIL, F_LEN_VAR,
23428c2ecf20Sopenharmony_ci		R_RCS, D_BDW_PLUS, 0, 8, NULL},
23438c2ecf20Sopenharmony_ci
23448c2ecf20Sopenharmony_ci	{"3DSTATE_PS_EXTRA", OP_3DSTATE_PS_EXTRA, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0,
23458c2ecf20Sopenharmony_ci		8, NULL},
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci	{"3DSTATE_RASTER", OP_3DSTATE_RASTER, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
23488c2ecf20Sopenharmony_ci		NULL},
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_ci	{"3DSTATE_SBE_SWIZ", OP_3DSTATE_SBE_SWIZ, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
23518c2ecf20Sopenharmony_ci		NULL},
23528c2ecf20Sopenharmony_ci
23538c2ecf20Sopenharmony_ci	{"3DSTATE_WM_HZ_OP", OP_3DSTATE_WM_HZ_OP, F_LEN_VAR, R_RCS, D_BDW_PLUS, 0, 8,
23548c2ecf20Sopenharmony_ci		NULL},
23558c2ecf20Sopenharmony_ci
23568c2ecf20Sopenharmony_ci	{"3DSTATE_VERTEX_BUFFERS", OP_3DSTATE_VERTEX_BUFFERS, F_LEN_VAR, R_RCS,
23578c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23588c2ecf20Sopenharmony_ci
23598c2ecf20Sopenharmony_ci	{"3DSTATE_VERTEX_ELEMENTS", OP_3DSTATE_VERTEX_ELEMENTS, F_LEN_VAR,
23608c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 8, NULL},
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ci	{"3DSTATE_INDEX_BUFFER", OP_3DSTATE_INDEX_BUFFER, F_LEN_VAR, R_RCS,
23638c2ecf20Sopenharmony_ci		D_BDW_PLUS, ADDR_FIX_1(2), 8, NULL},
23648c2ecf20Sopenharmony_ci
23658c2ecf20Sopenharmony_ci	{"3DSTATE_VF_STATISTICS", OP_3DSTATE_VF_STATISTICS, F_LEN_CONST,
23668c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 1, NULL},
23678c2ecf20Sopenharmony_ci
23688c2ecf20Sopenharmony_ci	{"3DSTATE_VF", OP_3DSTATE_VF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23698c2ecf20Sopenharmony_ci
23708c2ecf20Sopenharmony_ci	{"3DSTATE_CC_STATE_POINTERS", OP_3DSTATE_CC_STATE_POINTERS, F_LEN_VAR,
23718c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 8, NULL},
23728c2ecf20Sopenharmony_ci
23738c2ecf20Sopenharmony_ci	{"3DSTATE_SCISSOR_STATE_POINTERS", OP_3DSTATE_SCISSOR_STATE_POINTERS,
23748c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23758c2ecf20Sopenharmony_ci
23768c2ecf20Sopenharmony_ci	{"3DSTATE_GS", OP_3DSTATE_GS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23778c2ecf20Sopenharmony_ci
23788c2ecf20Sopenharmony_ci	{"3DSTATE_CLIP", OP_3DSTATE_CLIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23798c2ecf20Sopenharmony_ci
23808c2ecf20Sopenharmony_ci	{"3DSTATE_WM", OP_3DSTATE_WM, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23818c2ecf20Sopenharmony_ci
23828c2ecf20Sopenharmony_ci	{"3DSTATE_CONSTANT_GS", OP_3DSTATE_CONSTANT_GS, F_LEN_VAR, R_RCS,
23838c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23848c2ecf20Sopenharmony_ci
23858c2ecf20Sopenharmony_ci	{"3DSTATE_CONSTANT_PS", OP_3DSTATE_CONSTANT_PS, F_LEN_VAR, R_RCS,
23868c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23878c2ecf20Sopenharmony_ci
23888c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLE_MASK", OP_3DSTATE_SAMPLE_MASK, F_LEN_VAR, R_RCS,
23898c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
23908c2ecf20Sopenharmony_ci
23918c2ecf20Sopenharmony_ci	{"3DSTATE_CONSTANT_HS", OP_3DSTATE_CONSTANT_HS, F_LEN_VAR, R_RCS,
23928c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23938c2ecf20Sopenharmony_ci
23948c2ecf20Sopenharmony_ci	{"3DSTATE_CONSTANT_DS", OP_3DSTATE_CONSTANT_DS, F_LEN_VAR, R_RCS,
23958c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
23968c2ecf20Sopenharmony_ci
23978c2ecf20Sopenharmony_ci	{"3DSTATE_HS", OP_3DSTATE_HS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
23988c2ecf20Sopenharmony_ci
23998c2ecf20Sopenharmony_ci	{"3DSTATE_TE", OP_3DSTATE_TE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24008c2ecf20Sopenharmony_ci
24018c2ecf20Sopenharmony_ci	{"3DSTATE_DS", OP_3DSTATE_DS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24028c2ecf20Sopenharmony_ci
24038c2ecf20Sopenharmony_ci	{"3DSTATE_STREAMOUT", OP_3DSTATE_STREAMOUT, F_LEN_VAR, R_RCS,
24048c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
24058c2ecf20Sopenharmony_ci
24068c2ecf20Sopenharmony_ci	{"3DSTATE_SBE", OP_3DSTATE_SBE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24078c2ecf20Sopenharmony_ci
24088c2ecf20Sopenharmony_ci	{"3DSTATE_PS", OP_3DSTATE_PS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24098c2ecf20Sopenharmony_ci
24108c2ecf20Sopenharmony_ci	{"3DSTATE_DRAWING_RECTANGLE", OP_3DSTATE_DRAWING_RECTANGLE, F_LEN_VAR,
24118c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 8, NULL},
24128c2ecf20Sopenharmony_ci
24138c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_PALETTE_LOAD0", OP_3DSTATE_SAMPLER_PALETTE_LOAD0,
24148c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24158c2ecf20Sopenharmony_ci
24168c2ecf20Sopenharmony_ci	{"3DSTATE_CHROMA_KEY", OP_3DSTATE_CHROMA_KEY, F_LEN_VAR, R_RCS, D_ALL,
24178c2ecf20Sopenharmony_ci		0, 8, NULL},
24188c2ecf20Sopenharmony_ci
24198c2ecf20Sopenharmony_ci	{"3DSTATE_DEPTH_BUFFER", OP_3DSTATE_DEPTH_BUFFER, F_LEN_VAR, R_RCS,
24208c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_1(2), 8, NULL},
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci	{"3DSTATE_POLY_STIPPLE_OFFSET", OP_3DSTATE_POLY_STIPPLE_OFFSET,
24238c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24248c2ecf20Sopenharmony_ci
24258c2ecf20Sopenharmony_ci	{"3DSTATE_POLY_STIPPLE_PATTERN", OP_3DSTATE_POLY_STIPPLE_PATTERN,
24268c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24278c2ecf20Sopenharmony_ci
24288c2ecf20Sopenharmony_ci	{"3DSTATE_LINE_STIPPLE", OP_3DSTATE_LINE_STIPPLE, F_LEN_VAR, R_RCS,
24298c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
24308c2ecf20Sopenharmony_ci
24318c2ecf20Sopenharmony_ci	{"3DSTATE_AA_LINE_PARAMS", OP_3DSTATE_AA_LINE_PARAMS, F_LEN_VAR, R_RCS,
24328c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
24338c2ecf20Sopenharmony_ci
24348c2ecf20Sopenharmony_ci	{"3DSTATE_GS_SVB_INDEX", OP_3DSTATE_GS_SVB_INDEX, F_LEN_VAR, R_RCS,
24358c2ecf20Sopenharmony_ci		D_ALL, 0, 8, NULL},
24368c2ecf20Sopenharmony_ci
24378c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLER_PALETTE_LOAD1", OP_3DSTATE_SAMPLER_PALETTE_LOAD1,
24388c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24398c2ecf20Sopenharmony_ci
24408c2ecf20Sopenharmony_ci	{"3DSTATE_MULTISAMPLE", OP_3DSTATE_MULTISAMPLE_BDW, F_LEN_VAR, R_RCS,
24418c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
24428c2ecf20Sopenharmony_ci
24438c2ecf20Sopenharmony_ci	{"3DSTATE_STENCIL_BUFFER", OP_3DSTATE_STENCIL_BUFFER, F_LEN_VAR, R_RCS,
24448c2ecf20Sopenharmony_ci		D_ALL, ADDR_FIX_1(2), 8, NULL},
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci	{"3DSTATE_HIER_DEPTH_BUFFER", OP_3DSTATE_HIER_DEPTH_BUFFER, F_LEN_VAR,
24478c2ecf20Sopenharmony_ci		R_RCS, D_ALL, ADDR_FIX_1(2), 8, NULL},
24488c2ecf20Sopenharmony_ci
24498c2ecf20Sopenharmony_ci	{"3DSTATE_CLEAR_PARAMS", OP_3DSTATE_CLEAR_PARAMS, F_LEN_VAR,
24508c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 8, NULL},
24518c2ecf20Sopenharmony_ci
24528c2ecf20Sopenharmony_ci	{"3DSTATE_PUSH_CONSTANT_ALLOC_VS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
24538c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24548c2ecf20Sopenharmony_ci
24558c2ecf20Sopenharmony_ci	{"3DSTATE_PUSH_CONSTANT_ALLOC_HS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_HS,
24568c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24578c2ecf20Sopenharmony_ci
24588c2ecf20Sopenharmony_ci	{"3DSTATE_PUSH_CONSTANT_ALLOC_DS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_DS,
24598c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24608c2ecf20Sopenharmony_ci
24618c2ecf20Sopenharmony_ci	{"3DSTATE_PUSH_CONSTANT_ALLOC_GS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
24628c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24638c2ecf20Sopenharmony_ci
24648c2ecf20Sopenharmony_ci	{"3DSTATE_PUSH_CONSTANT_ALLOC_PS", OP_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
24658c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24668c2ecf20Sopenharmony_ci
24678c2ecf20Sopenharmony_ci	{"3DSTATE_MONOFILTER_SIZE", OP_3DSTATE_MONOFILTER_SIZE, F_LEN_VAR,
24688c2ecf20Sopenharmony_ci		R_RCS, D_ALL, 0, 8, NULL},
24698c2ecf20Sopenharmony_ci
24708c2ecf20Sopenharmony_ci	{"3DSTATE_SO_DECL_LIST", OP_3DSTATE_SO_DECL_LIST, F_LEN_VAR, R_RCS,
24718c2ecf20Sopenharmony_ci		D_ALL, 0, 9, NULL},
24728c2ecf20Sopenharmony_ci
24738c2ecf20Sopenharmony_ci	{"3DSTATE_SO_BUFFER", OP_3DSTATE_SO_BUFFER, F_LEN_VAR, R_RCS, D_BDW_PLUS,
24748c2ecf20Sopenharmony_ci		ADDR_FIX_2(2, 4), 8, NULL},
24758c2ecf20Sopenharmony_ci
24768c2ecf20Sopenharmony_ci	{"3DSTATE_BINDING_TABLE_POOL_ALLOC",
24778c2ecf20Sopenharmony_ci		OP_3DSTATE_BINDING_TABLE_POOL_ALLOC,
24788c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
24798c2ecf20Sopenharmony_ci
24808c2ecf20Sopenharmony_ci	{"3DSTATE_GATHER_POOL_ALLOC", OP_3DSTATE_GATHER_POOL_ALLOC,
24818c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
24828c2ecf20Sopenharmony_ci
24838c2ecf20Sopenharmony_ci	{"3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC",
24848c2ecf20Sopenharmony_ci		OP_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC,
24858c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_BDW_PLUS, ADDR_FIX_1(1), 8, NULL},
24868c2ecf20Sopenharmony_ci
24878c2ecf20Sopenharmony_ci	{"3DSTATE_SAMPLE_PATTERN", OP_3DSTATE_SAMPLE_PATTERN, F_LEN_VAR, R_RCS,
24888c2ecf20Sopenharmony_ci		D_BDW_PLUS, 0, 8, NULL},
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci	{"PIPE_CONTROL", OP_PIPE_CONTROL, F_LEN_VAR, R_RCS, D_ALL,
24918c2ecf20Sopenharmony_ci		ADDR_FIX_1(2), 8, cmd_handler_pipe_control},
24928c2ecf20Sopenharmony_ci
24938c2ecf20Sopenharmony_ci	{"3DPRIMITIVE", OP_3DPRIMITIVE, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
24948c2ecf20Sopenharmony_ci
24958c2ecf20Sopenharmony_ci	{"PIPELINE_SELECT", OP_PIPELINE_SELECT, F_LEN_CONST, R_RCS, D_ALL, 0,
24968c2ecf20Sopenharmony_ci		1, NULL},
24978c2ecf20Sopenharmony_ci
24988c2ecf20Sopenharmony_ci	{"STATE_PREFETCH", OP_STATE_PREFETCH, F_LEN_VAR, R_RCS, D_ALL,
24998c2ecf20Sopenharmony_ci		ADDR_FIX_1(1), 8, NULL},
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci	{"STATE_SIP", OP_STATE_SIP, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
25028c2ecf20Sopenharmony_ci
25038c2ecf20Sopenharmony_ci	{"STATE_BASE_ADDRESS", OP_STATE_BASE_ADDRESS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
25048c2ecf20Sopenharmony_ci		ADDR_FIX_5(1, 3, 4, 5, 6), 8, NULL},
25058c2ecf20Sopenharmony_ci
25068c2ecf20Sopenharmony_ci	{"OP_3D_MEDIA_0_1_4", OP_3D_MEDIA_0_1_4, F_LEN_VAR, R_RCS, D_ALL,
25078c2ecf20Sopenharmony_ci		ADDR_FIX_1(1), 8, NULL},
25088c2ecf20Sopenharmony_ci
25098c2ecf20Sopenharmony_ci	{"OP_SWTESS_BASE_ADDRESS", OP_SWTESS_BASE_ADDRESS,
25108c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, ADDR_FIX_2(1, 2), 3, NULL},
25118c2ecf20Sopenharmony_ci
25128c2ecf20Sopenharmony_ci	{"3DSTATE_VS", OP_3DSTATE_VS, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
25138c2ecf20Sopenharmony_ci
25148c2ecf20Sopenharmony_ci	{"3DSTATE_SF", OP_3DSTATE_SF, F_LEN_VAR, R_RCS, D_ALL, 0, 8, NULL},
25158c2ecf20Sopenharmony_ci
25168c2ecf20Sopenharmony_ci	{"3DSTATE_CONSTANT_VS", OP_3DSTATE_CONSTANT_VS, F_LEN_VAR, R_RCS, D_BDW_PLUS,
25178c2ecf20Sopenharmony_ci		0, 8, NULL},
25188c2ecf20Sopenharmony_ci
25198c2ecf20Sopenharmony_ci	{"3DSTATE_COMPONENT_PACKING", OP_3DSTATE_COMPONENT_PACKING, F_LEN_VAR, R_RCS,
25208c2ecf20Sopenharmony_ci		D_SKL_PLUS, 0, 8, NULL},
25218c2ecf20Sopenharmony_ci
25228c2ecf20Sopenharmony_ci	{"MEDIA_INTERFACE_DESCRIPTOR_LOAD", OP_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
25238c2ecf20Sopenharmony_ci		F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
25248c2ecf20Sopenharmony_ci
25258c2ecf20Sopenharmony_ci	{"MEDIA_GATEWAY_STATE", OP_MEDIA_GATEWAY_STATE, F_LEN_VAR, R_RCS, D_ALL,
25268c2ecf20Sopenharmony_ci		0, 16, NULL},
25278c2ecf20Sopenharmony_ci
25288c2ecf20Sopenharmony_ci	{"MEDIA_STATE_FLUSH", OP_MEDIA_STATE_FLUSH, F_LEN_VAR, R_RCS, D_ALL,
25298c2ecf20Sopenharmony_ci		0, 16, NULL},
25308c2ecf20Sopenharmony_ci
25318c2ecf20Sopenharmony_ci	{"MEDIA_POOL_STATE", OP_MEDIA_POOL_STATE, F_LEN_VAR, R_RCS, D_ALL,
25328c2ecf20Sopenharmony_ci		0, 16, NULL},
25338c2ecf20Sopenharmony_ci
25348c2ecf20Sopenharmony_ci	{"MEDIA_OBJECT", OP_MEDIA_OBJECT, F_LEN_VAR, R_RCS, D_ALL, 0, 16, NULL},
25358c2ecf20Sopenharmony_ci
25368c2ecf20Sopenharmony_ci	{"MEDIA_CURBE_LOAD", OP_MEDIA_CURBE_LOAD, F_LEN_VAR, R_RCS, D_ALL,
25378c2ecf20Sopenharmony_ci		0, 16, NULL},
25388c2ecf20Sopenharmony_ci
25398c2ecf20Sopenharmony_ci	{"MEDIA_OBJECT_PRT", OP_MEDIA_OBJECT_PRT, F_LEN_VAR, R_RCS, D_ALL,
25408c2ecf20Sopenharmony_ci		0, 16, NULL},
25418c2ecf20Sopenharmony_ci
25428c2ecf20Sopenharmony_ci	{"MEDIA_OBJECT_WALKER", OP_MEDIA_OBJECT_WALKER, F_LEN_VAR, R_RCS, D_ALL,
25438c2ecf20Sopenharmony_ci		0, 16, NULL},
25448c2ecf20Sopenharmony_ci
25458c2ecf20Sopenharmony_ci	{"GPGPU_WALKER", OP_GPGPU_WALKER, F_LEN_VAR, R_RCS, D_ALL,
25468c2ecf20Sopenharmony_ci		0, 8, NULL},
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_ci	{"MEDIA_VFE_STATE", OP_MEDIA_VFE_STATE, F_LEN_VAR, R_RCS, D_ALL, 0, 16,
25498c2ecf20Sopenharmony_ci		NULL},
25508c2ecf20Sopenharmony_ci
25518c2ecf20Sopenharmony_ci	{"3DSTATE_VF_STATISTICS_GM45", OP_3DSTATE_VF_STATISTICS_GM45,
25528c2ecf20Sopenharmony_ci		F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL},
25538c2ecf20Sopenharmony_ci
25548c2ecf20Sopenharmony_ci	{"MFX_PIPE_MODE_SELECT", OP_MFX_PIPE_MODE_SELECT, F_LEN_VAR,
25558c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25568c2ecf20Sopenharmony_ci
25578c2ecf20Sopenharmony_ci	{"MFX_SURFACE_STATE", OP_MFX_SURFACE_STATE, F_LEN_VAR,
25588c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25598c2ecf20Sopenharmony_ci
25608c2ecf20Sopenharmony_ci	{"MFX_PIPE_BUF_ADDR_STATE", OP_MFX_PIPE_BUF_ADDR_STATE, F_LEN_VAR,
25618c2ecf20Sopenharmony_ci		R_VCS, D_BDW_PLUS, 0, 12, NULL},
25628c2ecf20Sopenharmony_ci
25638c2ecf20Sopenharmony_ci	{"MFX_IND_OBJ_BASE_ADDR_STATE", OP_MFX_IND_OBJ_BASE_ADDR_STATE,
25648c2ecf20Sopenharmony_ci		F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
25658c2ecf20Sopenharmony_ci
25668c2ecf20Sopenharmony_ci	{"MFX_BSP_BUF_BASE_ADDR_STATE", OP_MFX_BSP_BUF_BASE_ADDR_STATE,
25678c2ecf20Sopenharmony_ci		F_LEN_VAR, R_VCS, D_BDW_PLUS, ADDR_FIX_3(1, 3, 5), 12, NULL},
25688c2ecf20Sopenharmony_ci
25698c2ecf20Sopenharmony_ci	{"OP_2_0_0_5", OP_2_0_0_5, F_LEN_VAR, R_VCS, D_BDW_PLUS, 0, 12, NULL},
25708c2ecf20Sopenharmony_ci
25718c2ecf20Sopenharmony_ci	{"MFX_STATE_POINTER", OP_MFX_STATE_POINTER, F_LEN_VAR,
25728c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25738c2ecf20Sopenharmony_ci
25748c2ecf20Sopenharmony_ci	{"MFX_QM_STATE", OP_MFX_QM_STATE, F_LEN_VAR,
25758c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25768c2ecf20Sopenharmony_ci
25778c2ecf20Sopenharmony_ci	{"MFX_FQM_STATE", OP_MFX_FQM_STATE, F_LEN_VAR,
25788c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25798c2ecf20Sopenharmony_ci
25808c2ecf20Sopenharmony_ci	{"MFX_PAK_INSERT_OBJECT", OP_MFX_PAK_INSERT_OBJECT, F_LEN_VAR,
25818c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25828c2ecf20Sopenharmony_ci
25838c2ecf20Sopenharmony_ci	{"MFX_STITCH_OBJECT", OP_MFX_STITCH_OBJECT, F_LEN_VAR,
25848c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25858c2ecf20Sopenharmony_ci
25868c2ecf20Sopenharmony_ci	{"MFD_IT_OBJECT", OP_MFD_IT_OBJECT, F_LEN_VAR,
25878c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25888c2ecf20Sopenharmony_ci
25898c2ecf20Sopenharmony_ci	{"MFX_WAIT", OP_MFX_WAIT, F_LEN_VAR,
25908c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 6, NULL},
25918c2ecf20Sopenharmony_ci
25928c2ecf20Sopenharmony_ci	{"MFX_AVC_IMG_STATE", OP_MFX_AVC_IMG_STATE, F_LEN_VAR,
25938c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25948c2ecf20Sopenharmony_ci
25958c2ecf20Sopenharmony_ci	{"MFX_AVC_QM_STATE", OP_MFX_AVC_QM_STATE, F_LEN_VAR,
25968c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
25978c2ecf20Sopenharmony_ci
25988c2ecf20Sopenharmony_ci	{"MFX_AVC_DIRECTMODE_STATE", OP_MFX_AVC_DIRECTMODE_STATE, F_LEN_VAR,
25998c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26008c2ecf20Sopenharmony_ci
26018c2ecf20Sopenharmony_ci	{"MFX_AVC_SLICE_STATE", OP_MFX_AVC_SLICE_STATE, F_LEN_VAR,
26028c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26038c2ecf20Sopenharmony_ci
26048c2ecf20Sopenharmony_ci	{"MFX_AVC_REF_IDX_STATE", OP_MFX_AVC_REF_IDX_STATE, F_LEN_VAR,
26058c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26068c2ecf20Sopenharmony_ci
26078c2ecf20Sopenharmony_ci	{"MFX_AVC_WEIGHTOFFSET_STATE", OP_MFX_AVC_WEIGHTOFFSET_STATE, F_LEN_VAR,
26088c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26098c2ecf20Sopenharmony_ci
26108c2ecf20Sopenharmony_ci	{"MFD_AVC_PICID_STATE", OP_MFD_AVC_PICID_STATE, F_LEN_VAR,
26118c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26128c2ecf20Sopenharmony_ci	{"MFD_AVC_DPB_STATE", OP_MFD_AVC_DPB_STATE, F_LEN_VAR,
26138c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26148c2ecf20Sopenharmony_ci
26158c2ecf20Sopenharmony_ci	{"MFD_AVC_BSD_OBJECT", OP_MFD_AVC_BSD_OBJECT, F_LEN_VAR,
26168c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26178c2ecf20Sopenharmony_ci
26188c2ecf20Sopenharmony_ci	{"MFD_AVC_SLICEADDR", OP_MFD_AVC_SLICEADDR, F_LEN_VAR,
26198c2ecf20Sopenharmony_ci		R_VCS, D_ALL, ADDR_FIX_1(2), 12, NULL},
26208c2ecf20Sopenharmony_ci
26218c2ecf20Sopenharmony_ci	{"MFC_AVC_PAK_OBJECT", OP_MFC_AVC_PAK_OBJECT, F_LEN_VAR,
26228c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26238c2ecf20Sopenharmony_ci
26248c2ecf20Sopenharmony_ci	{"MFX_VC1_PRED_PIPE_STATE", OP_MFX_VC1_PRED_PIPE_STATE, F_LEN_VAR,
26258c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci	{"MFX_VC1_DIRECTMODE_STATE", OP_MFX_VC1_DIRECTMODE_STATE, F_LEN_VAR,
26288c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26298c2ecf20Sopenharmony_ci
26308c2ecf20Sopenharmony_ci	{"MFD_VC1_SHORT_PIC_STATE", OP_MFD_VC1_SHORT_PIC_STATE, F_LEN_VAR,
26318c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26328c2ecf20Sopenharmony_ci
26338c2ecf20Sopenharmony_ci	{"MFD_VC1_LONG_PIC_STATE", OP_MFD_VC1_LONG_PIC_STATE, F_LEN_VAR,
26348c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_ci	{"MFD_VC1_BSD_OBJECT", OP_MFD_VC1_BSD_OBJECT, F_LEN_VAR,
26378c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26388c2ecf20Sopenharmony_ci
26398c2ecf20Sopenharmony_ci	{"MFC_MPEG2_SLICEGROUP_STATE", OP_MFC_MPEG2_SLICEGROUP_STATE, F_LEN_VAR,
26408c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26418c2ecf20Sopenharmony_ci
26428c2ecf20Sopenharmony_ci	{"MFC_MPEG2_PAK_OBJECT", OP_MFC_MPEG2_PAK_OBJECT, F_LEN_VAR,
26438c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26448c2ecf20Sopenharmony_ci
26458c2ecf20Sopenharmony_ci	{"MFX_MPEG2_PIC_STATE", OP_MFX_MPEG2_PIC_STATE, F_LEN_VAR,
26468c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26478c2ecf20Sopenharmony_ci
26488c2ecf20Sopenharmony_ci	{"MFX_MPEG2_QM_STATE", OP_MFX_MPEG2_QM_STATE, F_LEN_VAR,
26498c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26508c2ecf20Sopenharmony_ci
26518c2ecf20Sopenharmony_ci	{"MFD_MPEG2_BSD_OBJECT", OP_MFD_MPEG2_BSD_OBJECT, F_LEN_VAR,
26528c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26538c2ecf20Sopenharmony_ci
26548c2ecf20Sopenharmony_ci	{"MFX_2_6_0_0", OP_MFX_2_6_0_0, F_LEN_VAR, R_VCS, D_ALL,
26558c2ecf20Sopenharmony_ci		0, 16, NULL},
26568c2ecf20Sopenharmony_ci
26578c2ecf20Sopenharmony_ci	{"MFX_2_6_0_9", OP_MFX_2_6_0_9, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
26588c2ecf20Sopenharmony_ci
26598c2ecf20Sopenharmony_ci	{"MFX_2_6_0_8", OP_MFX_2_6_0_8, F_LEN_VAR, R_VCS, D_ALL, 0, 16, NULL},
26608c2ecf20Sopenharmony_ci
26618c2ecf20Sopenharmony_ci	{"MFX_JPEG_PIC_STATE", OP_MFX_JPEG_PIC_STATE, F_LEN_VAR,
26628c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26638c2ecf20Sopenharmony_ci
26648c2ecf20Sopenharmony_ci	{"MFX_JPEG_HUFF_TABLE_STATE", OP_MFX_JPEG_HUFF_TABLE_STATE, F_LEN_VAR,
26658c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26668c2ecf20Sopenharmony_ci
26678c2ecf20Sopenharmony_ci	{"MFD_JPEG_BSD_OBJECT", OP_MFD_JPEG_BSD_OBJECT, F_LEN_VAR,
26688c2ecf20Sopenharmony_ci		R_VCS, D_ALL, 0, 12, NULL},
26698c2ecf20Sopenharmony_ci
26708c2ecf20Sopenharmony_ci	{"VEBOX_STATE", OP_VEB_STATE, F_LEN_VAR, R_VECS, D_ALL, 0, 12, NULL},
26718c2ecf20Sopenharmony_ci
26728c2ecf20Sopenharmony_ci	{"VEBOX_SURFACE_STATE", OP_VEB_SURFACE_STATE, F_LEN_VAR, R_VECS, D_ALL,
26738c2ecf20Sopenharmony_ci		0, 12, NULL},
26748c2ecf20Sopenharmony_ci
26758c2ecf20Sopenharmony_ci	{"VEB_DI_IECP", OP_VEB_DNDI_IECP_STATE, F_LEN_VAR, R_VECS, D_BDW_PLUS,
26768c2ecf20Sopenharmony_ci		0, 12, NULL},
26778c2ecf20Sopenharmony_ci};
26788c2ecf20Sopenharmony_ci
26798c2ecf20Sopenharmony_cistatic void add_cmd_entry(struct intel_gvt *gvt, struct cmd_entry *e)
26808c2ecf20Sopenharmony_ci{
26818c2ecf20Sopenharmony_ci	hash_add(gvt->cmd_table, &e->hlist, e->info->opcode);
26828c2ecf20Sopenharmony_ci}
26838c2ecf20Sopenharmony_ci
26848c2ecf20Sopenharmony_ci/* call the cmd handler, and advance ip */
26858c2ecf20Sopenharmony_cistatic int cmd_parser_exec(struct parser_exec_state *s)
26868c2ecf20Sopenharmony_ci{
26878c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
26888c2ecf20Sopenharmony_ci	const struct cmd_info *info;
26898c2ecf20Sopenharmony_ci	u32 cmd;
26908c2ecf20Sopenharmony_ci	int ret = 0;
26918c2ecf20Sopenharmony_ci
26928c2ecf20Sopenharmony_ci	cmd = cmd_val(s, 0);
26938c2ecf20Sopenharmony_ci
26948c2ecf20Sopenharmony_ci	/* fastpath for MI_NOOP */
26958c2ecf20Sopenharmony_ci	if (cmd == MI_NOOP)
26968c2ecf20Sopenharmony_ci		info = &cmd_info[mi_noop_index];
26978c2ecf20Sopenharmony_ci	else
26988c2ecf20Sopenharmony_ci		info = get_cmd_info(s->vgpu->gvt, cmd, s->engine);
26998c2ecf20Sopenharmony_ci
27008c2ecf20Sopenharmony_ci	if (info == NULL) {
27018c2ecf20Sopenharmony_ci		gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %s, workload=%p\n",
27028c2ecf20Sopenharmony_ci			     cmd, get_opcode(cmd, s->engine),
27038c2ecf20Sopenharmony_ci			     repr_addr_type(s->buf_addr_type),
27048c2ecf20Sopenharmony_ci			     s->engine->name, s->workload);
27058c2ecf20Sopenharmony_ci		return -EBADRQC;
27068c2ecf20Sopenharmony_ci	}
27078c2ecf20Sopenharmony_ci
27088c2ecf20Sopenharmony_ci	s->info = info;
27098c2ecf20Sopenharmony_ci
27108c2ecf20Sopenharmony_ci	trace_gvt_command(vgpu->id, s->engine->id, s->ip_gma, s->ip_va,
27118c2ecf20Sopenharmony_ci			  cmd_length(s), s->buf_type, s->buf_addr_type,
27128c2ecf20Sopenharmony_ci			  s->workload, info->name);
27138c2ecf20Sopenharmony_ci
27148c2ecf20Sopenharmony_ci	if ((info->flag & F_LEN_MASK) == F_LEN_VAR_FIXED) {
27158c2ecf20Sopenharmony_ci		ret = gvt_check_valid_cmd_length(cmd_length(s),
27168c2ecf20Sopenharmony_ci						 info->valid_len);
27178c2ecf20Sopenharmony_ci		if (ret)
27188c2ecf20Sopenharmony_ci			return ret;
27198c2ecf20Sopenharmony_ci	}
27208c2ecf20Sopenharmony_ci
27218c2ecf20Sopenharmony_ci	if (info->handler) {
27228c2ecf20Sopenharmony_ci		ret = info->handler(s);
27238c2ecf20Sopenharmony_ci		if (ret < 0) {
27248c2ecf20Sopenharmony_ci			gvt_vgpu_err("%s handler error\n", info->name);
27258c2ecf20Sopenharmony_ci			return ret;
27268c2ecf20Sopenharmony_ci		}
27278c2ecf20Sopenharmony_ci	}
27288c2ecf20Sopenharmony_ci
27298c2ecf20Sopenharmony_ci	if (!(info->flag & F_IP_ADVANCE_CUSTOM)) {
27308c2ecf20Sopenharmony_ci		ret = cmd_advance_default(s);
27318c2ecf20Sopenharmony_ci		if (ret) {
27328c2ecf20Sopenharmony_ci			gvt_vgpu_err("%s IP advance error\n", info->name);
27338c2ecf20Sopenharmony_ci			return ret;
27348c2ecf20Sopenharmony_ci		}
27358c2ecf20Sopenharmony_ci	}
27368c2ecf20Sopenharmony_ci	return 0;
27378c2ecf20Sopenharmony_ci}
27388c2ecf20Sopenharmony_ci
27398c2ecf20Sopenharmony_cistatic inline bool gma_out_of_range(unsigned long gma,
27408c2ecf20Sopenharmony_ci		unsigned long gma_head, unsigned int gma_tail)
27418c2ecf20Sopenharmony_ci{
27428c2ecf20Sopenharmony_ci	if (gma_tail >= gma_head)
27438c2ecf20Sopenharmony_ci		return (gma < gma_head) || (gma > gma_tail);
27448c2ecf20Sopenharmony_ci	else
27458c2ecf20Sopenharmony_ci		return (gma > gma_tail) && (gma < gma_head);
27468c2ecf20Sopenharmony_ci}
27478c2ecf20Sopenharmony_ci
27488c2ecf20Sopenharmony_ci/* Keep the consistent return type, e.g EBADRQC for unknown
27498c2ecf20Sopenharmony_ci * cmd, EFAULT for invalid address, EPERM for nonpriv. later
27508c2ecf20Sopenharmony_ci * works as the input of VM healthy status.
27518c2ecf20Sopenharmony_ci */
27528c2ecf20Sopenharmony_cistatic int command_scan(struct parser_exec_state *s,
27538c2ecf20Sopenharmony_ci		unsigned long rb_head, unsigned long rb_tail,
27548c2ecf20Sopenharmony_ci		unsigned long rb_start, unsigned long rb_len)
27558c2ecf20Sopenharmony_ci{
27568c2ecf20Sopenharmony_ci
27578c2ecf20Sopenharmony_ci	unsigned long gma_head, gma_tail, gma_bottom;
27588c2ecf20Sopenharmony_ci	int ret = 0;
27598c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = s->vgpu;
27608c2ecf20Sopenharmony_ci
27618c2ecf20Sopenharmony_ci	gma_head = rb_start + rb_head;
27628c2ecf20Sopenharmony_ci	gma_tail = rb_start + rb_tail;
27638c2ecf20Sopenharmony_ci	gma_bottom = rb_start +  rb_len;
27648c2ecf20Sopenharmony_ci
27658c2ecf20Sopenharmony_ci	while (s->ip_gma != gma_tail) {
27668c2ecf20Sopenharmony_ci		if (s->buf_type == RING_BUFFER_INSTRUCTION) {
27678c2ecf20Sopenharmony_ci			if (!(s->ip_gma >= rb_start) ||
27688c2ecf20Sopenharmony_ci				!(s->ip_gma < gma_bottom)) {
27698c2ecf20Sopenharmony_ci				gvt_vgpu_err("ip_gma %lx out of ring scope."
27708c2ecf20Sopenharmony_ci					"(base:0x%lx, bottom: 0x%lx)\n",
27718c2ecf20Sopenharmony_ci					s->ip_gma, rb_start,
27728c2ecf20Sopenharmony_ci					gma_bottom);
27738c2ecf20Sopenharmony_ci				parser_exec_state_dump(s);
27748c2ecf20Sopenharmony_ci				return -EFAULT;
27758c2ecf20Sopenharmony_ci			}
27768c2ecf20Sopenharmony_ci			if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) {
27778c2ecf20Sopenharmony_ci				gvt_vgpu_err("ip_gma %lx out of range."
27788c2ecf20Sopenharmony_ci					"base 0x%lx head 0x%lx tail 0x%lx\n",
27798c2ecf20Sopenharmony_ci					s->ip_gma, rb_start,
27808c2ecf20Sopenharmony_ci					rb_head, rb_tail);
27818c2ecf20Sopenharmony_ci				parser_exec_state_dump(s);
27828c2ecf20Sopenharmony_ci				break;
27838c2ecf20Sopenharmony_ci			}
27848c2ecf20Sopenharmony_ci		}
27858c2ecf20Sopenharmony_ci		ret = cmd_parser_exec(s);
27868c2ecf20Sopenharmony_ci		if (ret) {
27878c2ecf20Sopenharmony_ci			gvt_vgpu_err("cmd parser error\n");
27888c2ecf20Sopenharmony_ci			parser_exec_state_dump(s);
27898c2ecf20Sopenharmony_ci			break;
27908c2ecf20Sopenharmony_ci		}
27918c2ecf20Sopenharmony_ci	}
27928c2ecf20Sopenharmony_ci
27938c2ecf20Sopenharmony_ci	return ret;
27948c2ecf20Sopenharmony_ci}
27958c2ecf20Sopenharmony_ci
27968c2ecf20Sopenharmony_cistatic int scan_workload(struct intel_vgpu_workload *workload)
27978c2ecf20Sopenharmony_ci{
27988c2ecf20Sopenharmony_ci	unsigned long gma_head, gma_tail, gma_bottom;
27998c2ecf20Sopenharmony_ci	struct parser_exec_state s;
28008c2ecf20Sopenharmony_ci	int ret = 0;
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	/* ring base is page aligned */
28038c2ecf20Sopenharmony_ci	if (WARN_ON(!IS_ALIGNED(workload->rb_start, I915_GTT_PAGE_SIZE)))
28048c2ecf20Sopenharmony_ci		return -EINVAL;
28058c2ecf20Sopenharmony_ci
28068c2ecf20Sopenharmony_ci	gma_head = workload->rb_start + workload->rb_head;
28078c2ecf20Sopenharmony_ci	gma_tail = workload->rb_start + workload->rb_tail;
28088c2ecf20Sopenharmony_ci	gma_bottom = workload->rb_start +  _RING_CTL_BUF_SIZE(workload->rb_ctl);
28098c2ecf20Sopenharmony_ci
28108c2ecf20Sopenharmony_ci	s.buf_type = RING_BUFFER_INSTRUCTION;
28118c2ecf20Sopenharmony_ci	s.buf_addr_type = GTT_BUFFER;
28128c2ecf20Sopenharmony_ci	s.vgpu = workload->vgpu;
28138c2ecf20Sopenharmony_ci	s.engine = workload->engine;
28148c2ecf20Sopenharmony_ci	s.ring_start = workload->rb_start;
28158c2ecf20Sopenharmony_ci	s.ring_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
28168c2ecf20Sopenharmony_ci	s.ring_head = gma_head;
28178c2ecf20Sopenharmony_ci	s.ring_tail = gma_tail;
28188c2ecf20Sopenharmony_ci	s.rb_va = workload->shadow_ring_buffer_va;
28198c2ecf20Sopenharmony_ci	s.workload = workload;
28208c2ecf20Sopenharmony_ci	s.is_ctx_wa = false;
28218c2ecf20Sopenharmony_ci
28228c2ecf20Sopenharmony_ci	if (bypass_scan_mask & workload->engine->mask || gma_head == gma_tail)
28238c2ecf20Sopenharmony_ci		return 0;
28248c2ecf20Sopenharmony_ci
28258c2ecf20Sopenharmony_ci	ret = ip_gma_set(&s, gma_head);
28268c2ecf20Sopenharmony_ci	if (ret)
28278c2ecf20Sopenharmony_ci		goto out;
28288c2ecf20Sopenharmony_ci
28298c2ecf20Sopenharmony_ci	ret = command_scan(&s, workload->rb_head, workload->rb_tail,
28308c2ecf20Sopenharmony_ci		workload->rb_start, _RING_CTL_BUF_SIZE(workload->rb_ctl));
28318c2ecf20Sopenharmony_ci
28328c2ecf20Sopenharmony_ciout:
28338c2ecf20Sopenharmony_ci	return ret;
28348c2ecf20Sopenharmony_ci}
28358c2ecf20Sopenharmony_ci
28368c2ecf20Sopenharmony_cistatic int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
28378c2ecf20Sopenharmony_ci{
28388c2ecf20Sopenharmony_ci
28398c2ecf20Sopenharmony_ci	unsigned long gma_head, gma_tail, gma_bottom, ring_size, ring_tail;
28408c2ecf20Sopenharmony_ci	struct parser_exec_state s;
28418c2ecf20Sopenharmony_ci	int ret = 0;
28428c2ecf20Sopenharmony_ci	struct intel_vgpu_workload *workload = container_of(wa_ctx,
28438c2ecf20Sopenharmony_ci				struct intel_vgpu_workload,
28448c2ecf20Sopenharmony_ci				wa_ctx);
28458c2ecf20Sopenharmony_ci
28468c2ecf20Sopenharmony_ci	/* ring base is page aligned */
28478c2ecf20Sopenharmony_ci	if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma,
28488c2ecf20Sopenharmony_ci					I915_GTT_PAGE_SIZE)))
28498c2ecf20Sopenharmony_ci		return -EINVAL;
28508c2ecf20Sopenharmony_ci
28518c2ecf20Sopenharmony_ci	ring_tail = wa_ctx->indirect_ctx.size + 3 * sizeof(u32);
28528c2ecf20Sopenharmony_ci	ring_size = round_up(wa_ctx->indirect_ctx.size + CACHELINE_BYTES,
28538c2ecf20Sopenharmony_ci			PAGE_SIZE);
28548c2ecf20Sopenharmony_ci	gma_head = wa_ctx->indirect_ctx.guest_gma;
28558c2ecf20Sopenharmony_ci	gma_tail = wa_ctx->indirect_ctx.guest_gma + ring_tail;
28568c2ecf20Sopenharmony_ci	gma_bottom = wa_ctx->indirect_ctx.guest_gma + ring_size;
28578c2ecf20Sopenharmony_ci
28588c2ecf20Sopenharmony_ci	s.buf_type = RING_BUFFER_INSTRUCTION;
28598c2ecf20Sopenharmony_ci	s.buf_addr_type = GTT_BUFFER;
28608c2ecf20Sopenharmony_ci	s.vgpu = workload->vgpu;
28618c2ecf20Sopenharmony_ci	s.engine = workload->engine;
28628c2ecf20Sopenharmony_ci	s.ring_start = wa_ctx->indirect_ctx.guest_gma;
28638c2ecf20Sopenharmony_ci	s.ring_size = ring_size;
28648c2ecf20Sopenharmony_ci	s.ring_head = gma_head;
28658c2ecf20Sopenharmony_ci	s.ring_tail = gma_tail;
28668c2ecf20Sopenharmony_ci	s.rb_va = wa_ctx->indirect_ctx.shadow_va;
28678c2ecf20Sopenharmony_ci	s.workload = workload;
28688c2ecf20Sopenharmony_ci	s.is_ctx_wa = true;
28698c2ecf20Sopenharmony_ci
28708c2ecf20Sopenharmony_ci	ret = ip_gma_set(&s, gma_head);
28718c2ecf20Sopenharmony_ci	if (ret)
28728c2ecf20Sopenharmony_ci		goto out;
28738c2ecf20Sopenharmony_ci
28748c2ecf20Sopenharmony_ci	ret = command_scan(&s, 0, ring_tail,
28758c2ecf20Sopenharmony_ci		wa_ctx->indirect_ctx.guest_gma, ring_size);
28768c2ecf20Sopenharmony_ciout:
28778c2ecf20Sopenharmony_ci	return ret;
28788c2ecf20Sopenharmony_ci}
28798c2ecf20Sopenharmony_ci
28808c2ecf20Sopenharmony_cistatic int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
28818c2ecf20Sopenharmony_ci{
28828c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = workload->vgpu;
28838c2ecf20Sopenharmony_ci	struct intel_vgpu_submission *s = &vgpu->submission;
28848c2ecf20Sopenharmony_ci	unsigned long gma_head, gma_tail, gma_top, guest_rb_size;
28858c2ecf20Sopenharmony_ci	void *shadow_ring_buffer_va;
28868c2ecf20Sopenharmony_ci	int ret;
28878c2ecf20Sopenharmony_ci
28888c2ecf20Sopenharmony_ci	guest_rb_size = _RING_CTL_BUF_SIZE(workload->rb_ctl);
28898c2ecf20Sopenharmony_ci
28908c2ecf20Sopenharmony_ci	/* calculate workload ring buffer size */
28918c2ecf20Sopenharmony_ci	workload->rb_len = (workload->rb_tail + guest_rb_size -
28928c2ecf20Sopenharmony_ci			workload->rb_head) % guest_rb_size;
28938c2ecf20Sopenharmony_ci
28948c2ecf20Sopenharmony_ci	gma_head = workload->rb_start + workload->rb_head;
28958c2ecf20Sopenharmony_ci	gma_tail = workload->rb_start + workload->rb_tail;
28968c2ecf20Sopenharmony_ci	gma_top = workload->rb_start + guest_rb_size;
28978c2ecf20Sopenharmony_ci
28988c2ecf20Sopenharmony_ci	if (workload->rb_len > s->ring_scan_buffer_size[workload->engine->id]) {
28998c2ecf20Sopenharmony_ci		void *p;
29008c2ecf20Sopenharmony_ci
29018c2ecf20Sopenharmony_ci		/* realloc the new ring buffer if needed */
29028c2ecf20Sopenharmony_ci		p = krealloc(s->ring_scan_buffer[workload->engine->id],
29038c2ecf20Sopenharmony_ci			     workload->rb_len, GFP_KERNEL);
29048c2ecf20Sopenharmony_ci		if (!p) {
29058c2ecf20Sopenharmony_ci			gvt_vgpu_err("fail to re-alloc ring scan buffer\n");
29068c2ecf20Sopenharmony_ci			return -ENOMEM;
29078c2ecf20Sopenharmony_ci		}
29088c2ecf20Sopenharmony_ci		s->ring_scan_buffer[workload->engine->id] = p;
29098c2ecf20Sopenharmony_ci		s->ring_scan_buffer_size[workload->engine->id] = workload->rb_len;
29108c2ecf20Sopenharmony_ci	}
29118c2ecf20Sopenharmony_ci
29128c2ecf20Sopenharmony_ci	shadow_ring_buffer_va = s->ring_scan_buffer[workload->engine->id];
29138c2ecf20Sopenharmony_ci
29148c2ecf20Sopenharmony_ci	/* get shadow ring buffer va */
29158c2ecf20Sopenharmony_ci	workload->shadow_ring_buffer_va = shadow_ring_buffer_va;
29168c2ecf20Sopenharmony_ci
29178c2ecf20Sopenharmony_ci	/* head > tail --> copy head <-> top */
29188c2ecf20Sopenharmony_ci	if (gma_head > gma_tail) {
29198c2ecf20Sopenharmony_ci		ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm,
29208c2ecf20Sopenharmony_ci				      gma_head, gma_top, shadow_ring_buffer_va);
29218c2ecf20Sopenharmony_ci		if (ret < 0) {
29228c2ecf20Sopenharmony_ci			gvt_vgpu_err("fail to copy guest ring buffer\n");
29238c2ecf20Sopenharmony_ci			return ret;
29248c2ecf20Sopenharmony_ci		}
29258c2ecf20Sopenharmony_ci		shadow_ring_buffer_va += ret;
29268c2ecf20Sopenharmony_ci		gma_head = workload->rb_start;
29278c2ecf20Sopenharmony_ci	}
29288c2ecf20Sopenharmony_ci
29298c2ecf20Sopenharmony_ci	/* copy head or start <-> tail */
29308c2ecf20Sopenharmony_ci	ret = copy_gma_to_hva(vgpu, vgpu->gtt.ggtt_mm, gma_head, gma_tail,
29318c2ecf20Sopenharmony_ci				shadow_ring_buffer_va);
29328c2ecf20Sopenharmony_ci	if (ret < 0) {
29338c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to copy guest ring buffer\n");
29348c2ecf20Sopenharmony_ci		return ret;
29358c2ecf20Sopenharmony_ci	}
29368c2ecf20Sopenharmony_ci	return 0;
29378c2ecf20Sopenharmony_ci}
29388c2ecf20Sopenharmony_ci
29398c2ecf20Sopenharmony_ciint intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload)
29408c2ecf20Sopenharmony_ci{
29418c2ecf20Sopenharmony_ci	int ret;
29428c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = workload->vgpu;
29438c2ecf20Sopenharmony_ci
29448c2ecf20Sopenharmony_ci	ret = shadow_workload_ring_buffer(workload);
29458c2ecf20Sopenharmony_ci	if (ret) {
29468c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to shadow workload ring_buffer\n");
29478c2ecf20Sopenharmony_ci		return ret;
29488c2ecf20Sopenharmony_ci	}
29498c2ecf20Sopenharmony_ci
29508c2ecf20Sopenharmony_ci	ret = scan_workload(workload);
29518c2ecf20Sopenharmony_ci	if (ret) {
29528c2ecf20Sopenharmony_ci		gvt_vgpu_err("scan workload error\n");
29538c2ecf20Sopenharmony_ci		return ret;
29548c2ecf20Sopenharmony_ci	}
29558c2ecf20Sopenharmony_ci	return 0;
29568c2ecf20Sopenharmony_ci}
29578c2ecf20Sopenharmony_ci
29588c2ecf20Sopenharmony_cistatic int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
29598c2ecf20Sopenharmony_ci{
29608c2ecf20Sopenharmony_ci	int ctx_size = wa_ctx->indirect_ctx.size;
29618c2ecf20Sopenharmony_ci	unsigned long guest_gma = wa_ctx->indirect_ctx.guest_gma;
29628c2ecf20Sopenharmony_ci	struct intel_vgpu_workload *workload = container_of(wa_ctx,
29638c2ecf20Sopenharmony_ci					struct intel_vgpu_workload,
29648c2ecf20Sopenharmony_ci					wa_ctx);
29658c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = workload->vgpu;
29668c2ecf20Sopenharmony_ci	struct drm_i915_gem_object *obj;
29678c2ecf20Sopenharmony_ci	int ret = 0;
29688c2ecf20Sopenharmony_ci	void *map;
29698c2ecf20Sopenharmony_ci
29708c2ecf20Sopenharmony_ci	obj = i915_gem_object_create_shmem(workload->engine->i915,
29718c2ecf20Sopenharmony_ci					   roundup(ctx_size + CACHELINE_BYTES,
29728c2ecf20Sopenharmony_ci						   PAGE_SIZE));
29738c2ecf20Sopenharmony_ci	if (IS_ERR(obj))
29748c2ecf20Sopenharmony_ci		return PTR_ERR(obj);
29758c2ecf20Sopenharmony_ci
29768c2ecf20Sopenharmony_ci	/* get the va of the shadow batch buffer */
29778c2ecf20Sopenharmony_ci	map = i915_gem_object_pin_map(obj, I915_MAP_WB);
29788c2ecf20Sopenharmony_ci	if (IS_ERR(map)) {
29798c2ecf20Sopenharmony_ci		gvt_vgpu_err("failed to vmap shadow indirect ctx\n");
29808c2ecf20Sopenharmony_ci		ret = PTR_ERR(map);
29818c2ecf20Sopenharmony_ci		goto put_obj;
29828c2ecf20Sopenharmony_ci	}
29838c2ecf20Sopenharmony_ci
29848c2ecf20Sopenharmony_ci	i915_gem_object_lock(obj, NULL);
29858c2ecf20Sopenharmony_ci	ret = i915_gem_object_set_to_cpu_domain(obj, false);
29868c2ecf20Sopenharmony_ci	i915_gem_object_unlock(obj);
29878c2ecf20Sopenharmony_ci	if (ret) {
29888c2ecf20Sopenharmony_ci		gvt_vgpu_err("failed to set shadow indirect ctx to CPU\n");
29898c2ecf20Sopenharmony_ci		goto unmap_src;
29908c2ecf20Sopenharmony_ci	}
29918c2ecf20Sopenharmony_ci
29928c2ecf20Sopenharmony_ci	ret = copy_gma_to_hva(workload->vgpu,
29938c2ecf20Sopenharmony_ci				workload->vgpu->gtt.ggtt_mm,
29948c2ecf20Sopenharmony_ci				guest_gma, guest_gma + ctx_size,
29958c2ecf20Sopenharmony_ci				map);
29968c2ecf20Sopenharmony_ci	if (ret < 0) {
29978c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to copy guest indirect ctx\n");
29988c2ecf20Sopenharmony_ci		goto unmap_src;
29998c2ecf20Sopenharmony_ci	}
30008c2ecf20Sopenharmony_ci
30018c2ecf20Sopenharmony_ci	wa_ctx->indirect_ctx.obj = obj;
30028c2ecf20Sopenharmony_ci	wa_ctx->indirect_ctx.shadow_va = map;
30038c2ecf20Sopenharmony_ci	return 0;
30048c2ecf20Sopenharmony_ci
30058c2ecf20Sopenharmony_ciunmap_src:
30068c2ecf20Sopenharmony_ci	i915_gem_object_unpin_map(obj);
30078c2ecf20Sopenharmony_ciput_obj:
30088c2ecf20Sopenharmony_ci	i915_gem_object_put(obj);
30098c2ecf20Sopenharmony_ci	return ret;
30108c2ecf20Sopenharmony_ci}
30118c2ecf20Sopenharmony_ci
30128c2ecf20Sopenharmony_cistatic int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
30138c2ecf20Sopenharmony_ci{
30148c2ecf20Sopenharmony_ci	u32 per_ctx_start[CACHELINE_DWORDS] = {0};
30158c2ecf20Sopenharmony_ci	unsigned char *bb_start_sva;
30168c2ecf20Sopenharmony_ci
30178c2ecf20Sopenharmony_ci	if (!wa_ctx->per_ctx.valid)
30188c2ecf20Sopenharmony_ci		return 0;
30198c2ecf20Sopenharmony_ci
30208c2ecf20Sopenharmony_ci	per_ctx_start[0] = 0x18800001;
30218c2ecf20Sopenharmony_ci	per_ctx_start[1] = wa_ctx->per_ctx.guest_gma;
30228c2ecf20Sopenharmony_ci
30238c2ecf20Sopenharmony_ci	bb_start_sva = (unsigned char *)wa_ctx->indirect_ctx.shadow_va +
30248c2ecf20Sopenharmony_ci				wa_ctx->indirect_ctx.size;
30258c2ecf20Sopenharmony_ci
30268c2ecf20Sopenharmony_ci	memcpy(bb_start_sva, per_ctx_start, CACHELINE_BYTES);
30278c2ecf20Sopenharmony_ci
30288c2ecf20Sopenharmony_ci	return 0;
30298c2ecf20Sopenharmony_ci}
30308c2ecf20Sopenharmony_ci
30318c2ecf20Sopenharmony_ciint intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
30328c2ecf20Sopenharmony_ci{
30338c2ecf20Sopenharmony_ci	int ret;
30348c2ecf20Sopenharmony_ci	struct intel_vgpu_workload *workload = container_of(wa_ctx,
30358c2ecf20Sopenharmony_ci					struct intel_vgpu_workload,
30368c2ecf20Sopenharmony_ci					wa_ctx);
30378c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = workload->vgpu;
30388c2ecf20Sopenharmony_ci
30398c2ecf20Sopenharmony_ci	if (wa_ctx->indirect_ctx.size == 0)
30408c2ecf20Sopenharmony_ci		return 0;
30418c2ecf20Sopenharmony_ci
30428c2ecf20Sopenharmony_ci	ret = shadow_indirect_ctx(wa_ctx);
30438c2ecf20Sopenharmony_ci	if (ret) {
30448c2ecf20Sopenharmony_ci		gvt_vgpu_err("fail to shadow indirect ctx\n");
30458c2ecf20Sopenharmony_ci		return ret;
30468c2ecf20Sopenharmony_ci	}
30478c2ecf20Sopenharmony_ci
30488c2ecf20Sopenharmony_ci	combine_wa_ctx(wa_ctx);
30498c2ecf20Sopenharmony_ci
30508c2ecf20Sopenharmony_ci	ret = scan_wa_ctx(wa_ctx);
30518c2ecf20Sopenharmony_ci	if (ret) {
30528c2ecf20Sopenharmony_ci		gvt_vgpu_err("scan wa ctx error\n");
30538c2ecf20Sopenharmony_ci		return ret;
30548c2ecf20Sopenharmony_ci	}
30558c2ecf20Sopenharmony_ci
30568c2ecf20Sopenharmony_ci	return 0;
30578c2ecf20Sopenharmony_ci}
30588c2ecf20Sopenharmony_ci
30598c2ecf20Sopenharmony_cistatic int init_cmd_table(struct intel_gvt *gvt)
30608c2ecf20Sopenharmony_ci{
30618c2ecf20Sopenharmony_ci	unsigned int gen_type = intel_gvt_get_device_type(gvt);
30628c2ecf20Sopenharmony_ci	int i;
30638c2ecf20Sopenharmony_ci
30648c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(cmd_info); i++) {
30658c2ecf20Sopenharmony_ci		struct cmd_entry *e;
30668c2ecf20Sopenharmony_ci
30678c2ecf20Sopenharmony_ci		if (!(cmd_info[i].devices & gen_type))
30688c2ecf20Sopenharmony_ci			continue;
30698c2ecf20Sopenharmony_ci
30708c2ecf20Sopenharmony_ci		e = kzalloc(sizeof(*e), GFP_KERNEL);
30718c2ecf20Sopenharmony_ci		if (!e)
30728c2ecf20Sopenharmony_ci			return -ENOMEM;
30738c2ecf20Sopenharmony_ci
30748c2ecf20Sopenharmony_ci		e->info = &cmd_info[i];
30758c2ecf20Sopenharmony_ci		if (cmd_info[i].opcode == OP_MI_NOOP)
30768c2ecf20Sopenharmony_ci			mi_noop_index = i;
30778c2ecf20Sopenharmony_ci
30788c2ecf20Sopenharmony_ci		INIT_HLIST_NODE(&e->hlist);
30798c2ecf20Sopenharmony_ci		add_cmd_entry(gvt, e);
30808c2ecf20Sopenharmony_ci		gvt_dbg_cmd("add %-30s op %04x flag %x devs %02x rings %02x\n",
30818c2ecf20Sopenharmony_ci			    e->info->name, e->info->opcode, e->info->flag,
30828c2ecf20Sopenharmony_ci			    e->info->devices, e->info->rings);
30838c2ecf20Sopenharmony_ci	}
30848c2ecf20Sopenharmony_ci
30858c2ecf20Sopenharmony_ci	return 0;
30868c2ecf20Sopenharmony_ci}
30878c2ecf20Sopenharmony_ci
30888c2ecf20Sopenharmony_cistatic void clean_cmd_table(struct intel_gvt *gvt)
30898c2ecf20Sopenharmony_ci{
30908c2ecf20Sopenharmony_ci	struct hlist_node *tmp;
30918c2ecf20Sopenharmony_ci	struct cmd_entry *e;
30928c2ecf20Sopenharmony_ci	int i;
30938c2ecf20Sopenharmony_ci
30948c2ecf20Sopenharmony_ci	hash_for_each_safe(gvt->cmd_table, i, tmp, e, hlist)
30958c2ecf20Sopenharmony_ci		kfree(e);
30968c2ecf20Sopenharmony_ci
30978c2ecf20Sopenharmony_ci	hash_init(gvt->cmd_table);
30988c2ecf20Sopenharmony_ci}
30998c2ecf20Sopenharmony_ci
31008c2ecf20Sopenharmony_civoid intel_gvt_clean_cmd_parser(struct intel_gvt *gvt)
31018c2ecf20Sopenharmony_ci{
31028c2ecf20Sopenharmony_ci	clean_cmd_table(gvt);
31038c2ecf20Sopenharmony_ci}
31048c2ecf20Sopenharmony_ci
31058c2ecf20Sopenharmony_ciint intel_gvt_init_cmd_parser(struct intel_gvt *gvt)
31068c2ecf20Sopenharmony_ci{
31078c2ecf20Sopenharmony_ci	int ret;
31088c2ecf20Sopenharmony_ci
31098c2ecf20Sopenharmony_ci	ret = init_cmd_table(gvt);
31108c2ecf20Sopenharmony_ci	if (ret) {
31118c2ecf20Sopenharmony_ci		intel_gvt_clean_cmd_parser(gvt);
31128c2ecf20Sopenharmony_ci		return ret;
31138c2ecf20Sopenharmony_ci	}
31148c2ecf20Sopenharmony_ci	return 0;
31158c2ecf20Sopenharmony_ci}
3116