1 /*===================== begin_copyright_notice ==================================
2 
3 * Copyright (c) 2024, Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 
23 ======================= end_copyright_notice ==================================*/
24 //!
25 //! \file     mhw_mi_hwcmd_xe2_lpm_base_next.h
26 //! \brief    Auto-generated constructors for MHW and states.
27 //! \details  This file may not be included outside of XE2_LPM_BASE as other components
28 //!           should use MHW interface to interact with MHW commands and states.
29 //!
30 #ifndef __MHW_MI_HWCMD_XE2_LPM_BASE_NEXT_H__
31 #define __MHW_MI_HWCMD_XE2_LPM_BASE_NEXT_H__
32 
33 #include "mhw_hwcmd.h"
34 #pragma once
35 #pragma pack(1)
36 
37 namespace mhw
38 {
39 namespace mi
40 {
41 namespace xe2_lpm_base_next
42 {
43     struct Cmd
44     {
45     public:
46     // Internal Macros
47     #define __CODEGEN_MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
48     #define __CODEGEN_BITFIELD(l, h) (h) - (l) + 1
49     #define __CODEGEN_OP_LENGTH_BIAS 2
50     #define __CODEGEN_OP_LENGTH(x) (uint32_t)((__CODEGEN_MAX(x, __CODEGEN_OP_LENGTH_BIAS)) - __CODEGEN_OP_LENGTH_BIAS)
51 
GetOpLengthCmd52         static uint32_t GetOpLength(uint32_t uiLength)
53         {
54             return __CODEGEN_OP_LENGTH(uiLength);
55         }
56 
57             //!
58         //! \brief MI_BATCH_BUFFER_END
59         //! \details
60         //!     The MI_BATCH_BUFFER_END command is used to terminate the execution of
61         //!     commands stored in a batch buffer initiated using a
62         //!     MI_BATCH_BUFFER_START command.
63         //!
64         //!     SW must ensure it buffers the size of the command buffer beyond this
65         //!     command. The command buffer for the command streamer is 0.5KB.
66         //!
67         //!     SW must ensure it buffers the size of the command buffer beyond this
68         //!     command. The command buffer for the command streamer is 1 KB.
69         //!
70         struct MI_BATCH_BUFFER_END_CMD
71         {
72             union
73             {
74                 struct
75                 {
76                     uint32_t EndContext : __CODEGEN_BITFIELD(0, 0);         //!< End Context
77                     uint32_t Reserved1 : __CODEGEN_BITFIELD(1, 14);         //!< Reserved
78                     uint32_t PredicateEnable : __CODEGEN_BITFIELD(15, 15);  //!< Predicate Enable
79                     uint32_t Reserved16 : __CODEGEN_BITFIELD(16, 22);       //!< Reserved
80                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);  //!< MI_COMMAND_OPCODE
81                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);      //!< COMMAND_TYPE
82                 };
83                 uint32_t Value;
84             } DW0;
85 
86             //! \name Local enumerations
87 
88             enum MI_COMMAND_OPCODE
89             {
90                 MI_COMMAND_OPCODE_MIBATCHBUFFEREND = 10,  //!< No additional details
91             };
92 
93             enum COMMAND_TYPE
94             {
95                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
96             };
97 
98             //! \name Initializations
99 
100             //! \brief Explicit member initialization function
MI_BATCH_BUFFER_END_CMDCmd::MI_BATCH_BUFFER_END_CMD101             MI_BATCH_BUFFER_END_CMD()
102             {
103                 DW0.Value = 0x05000000;
104                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIBATCHBUFFEREND;
105                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
106             }
107 
108             static const size_t dwSize   = 1;
109             static const size_t byteSize = 4;
110         };
111 
112         //!
113         //! \brief MI_NOOP
114         //! \details
115         //!     The MI_NOOP command basically performs a "no operation" in the command
116         //!     stream and is typically used to pad the command stream (e.g., in order
117         //!     to pad out a batch buffer to a QWord boundary). However, there is one
118         //!     minor (optional) function this command can perform - a 22-bit value can
119         //!     be loaded into the MI NOPID register. This provides a general-purpose
120         //!     command stream tagging ("breadcrumb") mechanism (e.g., to provide
121         //!     sequencing information for a subsequent breakpoint interrupt).
122         //!
123         struct MI_NOOP_CMD
124         {
125             union
126             {
127                 struct
128                 {
129                     uint32_t IdentificationNumber : __CODEGEN_BITFIELD(0, 21);                      //!< Identification Number
130                     uint32_t IdentificationNumberRegisterWriteEnable : __CODEGEN_BITFIELD(22, 22);  //!< IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE
131                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                          //!< MI_COMMAND_OPCODE
132                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                              //!< COMMAND_TYPE
133                 };
134                 uint32_t Value;
135             } DW0;
136 
137             //! \name Local enumerations
138 
139             //! \brief IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE
140             //! \details
141             //!     This field enables the value in the Identification Number field to be
142             //!     written into the MI NOPID register. If disabled, that register is
143             //!     unmodified - making this command an effective "no operation" function.
144             enum IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE
145             {
146                 IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE_UNNAMED0 = 0,  //!< Do not write the NOP_ID register
147                 IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE_UNNAMED1 = 1,  //!< Write th NOP_ID Register
148             };
149 
150             enum MI_COMMAND_OPCODE
151             {
152                 MI_COMMAND_OPCODE_MINOOP = 0,  //!< No additional details
153             };
154 
155             enum COMMAND_TYPE
156             {
157                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
158             };
159 
160             //! \name Initializations
161 
162             //! \brief Explicit member initialization function
MI_NOOP_CMDCmd::MI_NOOP_CMD163             MI_NOOP_CMD()
164             {
165                 DW0.Value = 0x00000000;
166                 //DW0.IdentificationNumberRegisterWriteEnable      = IDENTIFICATION_NUMBER_REGISTER_WRITE_ENABLE_DISABLE;
167                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MINOOP;
168                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
169             }
170 
171             static const size_t dwSize   = 1;
172             static const size_t byteSize = 4;
173         };
174 
175         //!
176         //! \brief MI_ARB_CHECK
177         //! \details
178         //!     This command allows software to enable or disable pre-fetch mechanism
179         //!     for command buffers in hardware.
180         //!
181         //!     The command allows software to add preemption points in the ring buffer.
182         //!     The command streamer will preempt in the case arbitration is enabled,
183         //!     there is a pending execution list and this command is currently being
184         //!     parsed.
185         //!
186         //!     MI_ARB_CHK command can be programmed in a ring buffer or batch buffer.
187         //!
188         //!     MI_ARB_CHK command must not be programmed in INDIRECT_CTX and
189         //!     BB_PER_CTX_PTR buffers.
190         //!
191         //!
192         struct MI_ARB_CHECK_CMD
193         {
194             union
195             {
196                 struct
197                 {
198                     uint32_t PreParserDisable : __CODEGEN_BITFIELD(0, 0);   //!< PRE_PARSER_DISABLE
199                     uint32_t Reserved1 : __CODEGEN_BITFIELD(1, 7);          //!< Reserved
200                     uint32_t MaskBits : __CODEGEN_BITFIELD(8, 15);          //!< Mask Bits
201                     uint32_t Reserved16 : __CODEGEN_BITFIELD(16, 22);       //!< Reserved
202                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);  //!< MI_COMMAND_OPCODE
203                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);      //!< COMMAND_TYPE
204                 };
205                 uint32_t Value;
206             } DW0;
207 
208             //! \name Local enumerations
209 
210             //! \brief PRE_PARSER_DISABLE
211             //! \details
212             //!     This command allows software to enable or disable pre-parserof
213             //!     command buffer functionality from within a command sequence on per
214             //!     context basis. This ability allows the command stream to prefetch batch
215             //!     buffers that are yet to be parsed by looking ahead in the command FIFO.
216             //!     Even with this disabled, driver will have to ensure it does not
217             //!     self-modify commands already prefetched into the command buffer within
218             //!     the same batch buffer.
219             enum PRE_PARSER_DISABLE
220             {
221                 PRE_PARSER_DISABLE_UNNAMED0 = 0,  //!< When reset early fetch and parsing of future command buffersis enabled in hardware when "Pre-Fetch Disable" in GFX_MODE register is not set.
222                 PRE_PARSER_DISABLE_UNNAMED1 = 1,  //!< When set early fetch and parsing of future command buffers is disabled in hardware.
223             };
224 
225             enum MI_COMMAND_OPCODE
226             {
227                 MI_COMMAND_OPCODE_MIARBCHECK = 5,  //!< No additional details
228             };
229 
230             enum COMMAND_TYPE
231             {
232                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
233             };
234 
235             //! \name Initializations
236 
237             //! \brief Explicit member initialization function
MI_ARB_CHECK_CMDCmd::MI_ARB_CHECK_CMD238             MI_ARB_CHECK_CMD()
239             {
240                 DW0.Value = 0x02800000;
241                 //DW0.PreParserDisable                             = PRE_PARSER_DISABLE_UNNAMED0;
242                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIARBCHECK;
243                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
244             }
245 
246             static const size_t dwSize   = 1;
247             static const size_t byteSize = 4;
248         };
249 
250         //!
251         //! \brief MI_LOAD_REGISTER_IMM
252         //! \details
253         //!     The MI_LOAD_REGISTER_IMM command requests a write of up to a DWord
254         //!     constant supplied in the command to the specified Register Offset (i.e.,
255         //!     offset into Memory-Mapped Register Range).
256         //!       Any offset that is to a destination outside of the GT core will allow
257         //!     the parser to continue once the cycle is at the GT boundry and not
258         //!     destination.  Any other address will ensure the destination is updated
259         //!     prior to parsing the next command
260         //!
261         //!     Many MMIO bits require the engine to be IDLE prior to updating the
262         //!     value.  Command streamer does not implicitly put in a pipeline flush in
263         //!     the cases a MMIO bit requires the engine to be IDLE.  In the case there
264         //!     was a 3DPRIMITIVE command or GPGPU_WALKER command without any stalling
265         //!     PIPE_CONTROL, one must be inserted prior to a MI_LOAD_REGISTER_IMMEDIATE
266         //!     that is updating a bit that requires the engine to be IDLE.
267         //!
268         //!     When executed from a non-privileged batch buffer, MMIO writes are only
269         //!     allowed to the registers listed in User Mode Non-Privileged Registers
270         //!     for the corresponding engine, any writes targeting the register not
271         //!     listed in the User Mode Non-Privileged Register will convert this
272         //!     command to a NOOP.
273         //!
274         //!     The following addresses should NOT be used for LRIs:
275         //!       0x8800 - 0x88FF
276         //!     >= 0xC0000
277         //!
278         //!       Limited LRI cycles to the Display Engine (0x40000-0xBFFFF) are
279         //!     allowed, but must be spaced to allow only one pending at a time. This
280         //!     can be done by issuing an SRM to the same address immediately after each
281         //!     LRI.
282         //!
283         //!     Programming an MMIO register is equivalent to programming a non-pipeline
284         //!     state to the hardware and hence an explicit stalling flush needs to be
285         //!     programmed prior to programming this command. However for certain MMIO
286         //!     registers based on their functionality doing an explicit stalling flush
287         //!     is exempted. Listed below are the exempted registers.
288         //!       3DPRIM_END_OFFSET - Auto Draw End Offset
289         //!     3DPRIM_START_VERTEX - Load Indirect Start Vertex
290         //!     3DPRIM_VERTEX_COUNT - Load Indirect Vertex Count
291         //!     3DPRIM_INSTANCE_COUNT - Load Indirect Instance Count
292         //!     3DPRIM_START_INSTANCE - Load Indirect Start Instance
293         //!     3DPRIM_BASE_VERTEX - Load Indirect Base Vertex
294         //!     3DPRIM_XP0 - Load Indirect Extended Parameter 0
295         //!     3DPRIM_XP1 - Load Indirect Extended Parameter 1
296         //!     3DPRIM_XP2 - Load Indirect Extended Parameter 2
297         //!
298         //!
299         struct MI_LOAD_REGISTER_IMM_CMD
300         {
301             union
302             {
303                 struct
304                 {
305                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);             //!< DWORD_LENGTH
306                     uint32_t ByteWriteDisables : __CODEGEN_BITFIELD(8, 11);      //!< Byte Write Disables
307                     uint32_t ForcePosted : __CODEGEN_BITFIELD(12, 12);           //!< Force Posted
308                     uint32_t Reserved13 : __CODEGEN_BITFIELD(13, 16);            //!< Reserved
309                     uint32_t MmioRemapEnable : __CODEGEN_BITFIELD(17, 17);       //!< MMIO_REMAP_ENABLE
310                     uint32_t Reserved18 : __CODEGEN_BITFIELD(18, 18);            //!< Reserved
311                     uint32_t AddCsMmioStartOffset : __CODEGEN_BITFIELD(19, 19);  //!< ADD_CS_MMIO_START_OFFSET
312                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 22);            //!< Reserved
313                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);       //!< MI_COMMAND_OPCODE
314                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);           //!< COMMAND_TYPE
315                 };
316                 uint32_t Value;
317             } DW0;
318             union
319             {
320                 struct
321                 {
322                     uint32_t Reserved32 : __CODEGEN_BITFIELD(0, 1);       //!< Reserved
323                     uint32_t RegisterOffset : __CODEGEN_BITFIELD(2, 22);  //!< Register Offset
324                     uint32_t Reserved55 : __CODEGEN_BITFIELD(23, 31);     //!< Reserved
325                 };
326                 uint32_t Value;
327             } DW1;
328             union
329             {
330                 struct
331                 {
332                     uint32_t DataDword;  //!< Data DWord
333                 };
334                 uint32_t Value;
335             } DW2;
336 
337             //! \name Local enumerations
338 
339             //! \brief MMIO_REMAP_ENABLE
340             //! \details
341             //!     This bit provides a mechanism in HW to remap the MMIO address in the
342             //!     MI command to the engine instance on which the command is getting
343             //!     executed, remapping in HW is done using engine specific remap table.
344             //!     Render and Compute engine share a common remapping table to facilitate
345             //!     remapping across engines, where as a dedicated remap table for each of
346             //!     Video Decode and Video Enhancement engine class.
347             //!       A MMIO remapping table per engine class is created with
348             //!     MMIO address belonging to multiple instances of an engine within an
349             //!     engine class. However Render and Compute engine share a common remapping
350             //!     table to facilitate remapping across engines, where as a dedicated remap
351             //!     table for each of Video Decode and Video Enhancement engine class.
352             //!       This mode provides mechanism for SW to always use MMIO
353             //!     address belonging to fixed instance (instance zero) with in an engine
354             //!     class during command buffer creation agnostic to the instance on which
355             //!     it will get scheduled. This willalso allow context interoperability
356             //!     across instances with in an engine class and extends to across engines
357             //!     in case of Render and Compute.
358             enum MMIO_REMAP_ENABLE
359             {
360                 MMIO_REMAP_ENABLE_UNNAMED0 = 0,  //!< MMIO remapping will not be applied to the MMIO address.
361                 MMIO_REMAP_ENABLE_UNNAMED1 = 1,  //!< MMIO remapping will be applied to the MMIO address prior to using for any other functionality of the command.
362             };
363 
364             //! \brief ADD_CS_MMIO_START_OFFSET
365             //! \details
366             //!     This bit controls the functionality of the "Register Address" field
367             //!     in the command.
368             enum ADD_CS_MMIO_START_OFFSET
369             {
370                 ADD_CS_MMIO_START_OFFSET_UNNAMED0 = 0,  //!< "Register Address" field in the command is absolute and not an offset from the executing command streamer MMIO start offset..
371                 ADD_CS_MMIO_START_OFFSET_UNNAMED1 = 1,  //!< "Register Address" field in the command is treated as an offset from the executing Command Streamers MMIO start offset. Bits [22:2] of the "Register Address" are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer. However, during context restore bits [11:2] of the "Register Address" are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer. Refer "Register Access and User Mode Privilege Access" section to get the list of all the instances of the Command Streamers and their associated MMIO Start Offset's./ Command executed from Ring Buffer or Batch BufferExample: MI_LOAD_REGISTER_IMMEDIATE, ADD_CS_MMIO_START_OFFSET: true, Data:0xABCD, Register Address: 0x00_2000The above command when executed on RenderCS will result in a write to MMIO offset 0x00_4000 (0x00_2000 + 0x00_2000) instead to 0x00_2000. Note that RenderCS MMIO start offset is 0x2000. For illustration table below shows the result of this command executed from few instances of the command streamers from differentengines.<div>
372             };
373 
374             enum MI_COMMAND_OPCODE
375             {
376                 MI_COMMAND_OPCODE_MILOADREGISTERIMM = 34,  //!< No additional details
377             };
378 
379             enum COMMAND_TYPE
380             {
381                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
382             };
383 
384             //! \name Initializations
385 
386             //! \brief Explicit member initialization function
MI_LOAD_REGISTER_IMM_CMDCmd::MI_LOAD_REGISTER_IMM_CMD387             MI_LOAD_REGISTER_IMM_CMD()
388             {
389                 DW0.Value = 0x11000001;
390                 //DW0.DwordLength                                  = GetOpLength(dwSize);
391                 //DW0.MmioRemapEnable                              = MMIO_REMAP_ENABLE_UNNAMED0;
392                 //DW0.AddCsMmioStartOffset                         = ADD_CS_MMIO_START_OFFSET_UNNAMED0;
393                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MILOADREGISTERIMM;
394                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
395 
396                 DW1.Value = 0x00000000;
397 
398                 DW2.Value = 0x00000000;
399             }
400 
401             static const size_t dwSize   = 3;
402             static const size_t byteSize = 12;
403         };
404 
405         //!
406         //! \brief MI_LOAD_REGISTER_MEM
407         //! \details
408         //!     The MI_LOAD_REGISTER_MEM command requests from a memory location and
409         //!     stores that DWord to a register.
410         //!
411         //!     The command temporarily halts commands that will cause cycles down the
412         //!     3D pipeline.
413         //!
414         //!     The following addresses should NOT be used for MMIO writes:
415         //!       0x8800 - 0x88FF
416         //!     >= 0xC0000
417         //!
418         //!       Limited MMIO writes cycles to the Display Engine 0x40000-0xBFFFF) are
419         //!     allowed, but must be spaced to allow only one pending at a time. This
420         //!     can be done by issuing an SRM to the same address immediately after each
421         //!     MMIO write.
422         //!
423         //!     This command should not be used within a non-privilege batch buffer to
424         //!     access global virtual space, doing so will be treated as privilege
425         //!     access violation. Refer "User Mode Privilege Command" in
426         //!     MI_BATCH_BUFFER_START command section to know HW behavior on
427         //!     encountering privilege access violation.
428         //!
429         //!     This command is not allowed to update the privilege register range when
430         //!     executed from a non-privilege batch buffer.
431         //!
432         struct MI_LOAD_REGISTER_MEM_CMD
433         {
434             union
435             {
436                 struct
437                 {
438                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                        //!< DWORD_LENGTH
439                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 15);                         //!< Reserved
440                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(16, 16);  //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
441                     uint32_t MmioRemapEnable : __CODEGEN_BITFIELD(17, 17);                  //!< MMIO_REMAP_ENABLE
442                     uint32_t Reserved18 : __CODEGEN_BITFIELD(18, 18);                       //!< Reserved
443                     uint32_t AddCsMmioStartOffset : __CODEGEN_BITFIELD(19, 19);             //!< ADD_CS_MMIO_START_OFFSET
444                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 20);                       //!< Reserved
445                     uint32_t AsyncModeEnable : __CODEGEN_BITFIELD(21, 21);                  //!< Async Mode Enable
446                     uint32_t UseGlobalGtt : __CODEGEN_BITFIELD(22, 22);                     //!< Use Global GTT
447                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                  //!< MI_COMMAND_OPCODE
448                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                      //!< COMMAND_TYPE
449                 };
450                 uint32_t Value;
451             } DW0;
452             union
453             {
454                 struct
455                 {
456                     uint32_t Reserved32 : __CODEGEN_BITFIELD(0, 1);        //!< Reserved
457                     uint32_t RegisterAddress : __CODEGEN_BITFIELD(2, 22);  //!< Register Address
458                     uint32_t Reserved55 : __CODEGEN_BITFIELD(23, 31);      //!< Reserved
459                 };
460                 uint32_t Value;
461             } DW1;
462             union
463             {
464                 struct
465                 {
466                     uint64_t Reserved64 : __CODEGEN_BITFIELD(0, 1);      //!< Reserved
467                     uint64_t MemoryAddress : __CODEGEN_BITFIELD(2, 63);  //!< Memory Address
468                 };
469                 uint32_t Value[2];
470             } DW2_3;
471 
472             //! \name Local enumerations
473 
474             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
475             //! \details
476             //!     This bit controls the memory read address computation for fetching
477             //!     the value fromthe memory to be loaded in to the register.
478             //!     The final memory readaddress is computed by
479             //!     adding the Workload PartitionID times the "Address Offset"to the memory
480             //!     address mentioned in the command.
481             //!     Workload Partition ID gets programmed through WPARIDregister and the
482             //!     Address Offset gets programmed through CS_MI_ADDRESS_OFFSET.
483             //!
484             //!     Example: {Final Memory Read
485             //!     Address[47:2], 2'b00} = (  Workload Partition ID
486             //!     * "Address Offset") + {Memory Write Address [47:2], 2'b00}
487             //!
488             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
489             {
490                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!<   There is no offset added to the memory write address.
491                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!< style="text-align:justify; margin:0in 0in 0.0001pt">    The final memory address is computed based on the   Workload Partition ID.
492             };
493 
494             //! \brief MMIO_REMAP_ENABLE
495             //! \details
496             //!     This bit provides a mechanism in HW to remap the MMIO address in the
497             //!     MI command to the engine instance on which the command is getting
498             //!     executed, remapping in HW is done using engine specific remap table.
499             //!     Render and Compute engine share a common remapping table to facilitate
500             //!     remapping across engines, where as a dedicated remap table for each of
501             //!     Video Decode and Video Enhancement engine class.
502             //!       A MMIO remapping table per engine class is created with
503             //!     MMIO address belonging to multiple instances of an engine within an
504             //!     engine class. However Render and Compute engine share a common remapping
505             //!     table to facilitate remapping across engines, where as a dedicated remap
506             //!     table for each of Video Decode and Video Enhancement engine class.
507             //!       This mode provides mechanism for SW to always use MMIO
508             //!     address belonging to fixed instance (instance zero) with in an engine
509             //!     class during command buffer creation agnostic to the instance on which
510             //!     it will get scheduled. This willalso allow context interoperability
511             //!     across instances with in an engine class and extends to across engines
512             //!     in case of Render and Compute.
513             enum MMIO_REMAP_ENABLE
514             {
515                 MMIO_REMAP_ENABLE_UNNAMED0 = 0,  //!< MMIO remapping will not be applied to the MMIO address.
516                 MMIO_REMAP_ENABLE_UNNAMED1 = 1,  //!< MMIO remapping will be applied to the MMIO address prior to using for any other functionality of the command.
517             };
518 
519             //! \brief ADD_CS_MMIO_START_OFFSET
520             //! \details
521             //!     This bit controls the functionality of the Register Address field in the
522             //!     command.
523             enum ADD_CS_MMIO_START_OFFSET
524             {
525                 ADD_CS_MMIO_START_OFFSET_UNNAMED0 = 0,  //!< Register Address field in the command is absolute and not an offset from the executing command streamer MMIO start offset.
526                 ADD_CS_MMIO_START_OFFSET_UNNAMED1 = 1,  //!< Register Address field in the command is treated as an offset from the executing Command Streamers MMIO start offset.Bits [22:2] of the Register Address are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer.Example: MI_LOAD_REGISTER_MEM, ADD_CS_MMIO_START_OFFSET: true, Memory Address:0xABCD, Register Address: 0x1C_0030The above command when executed on RenderCS will result in a write to MMIO offset 0x1C_2030 (0x00_2000 + 0x1C_0030) instead to 0x1C_0030. Note that RenderCS MMIO start offset is 0x2000.
527             };
528 
529             enum MI_COMMAND_OPCODE
530             {
531                 MI_COMMAND_OPCODE_MILOADREGISTERMEM = 41,  //!< No additional details
532             };
533 
534             enum COMMAND_TYPE
535             {
536                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
537             };
538 
539             //! \name Initializations
540 
541             //! \brief Explicit member initialization function
MI_LOAD_REGISTER_MEM_CMDCmd::MI_LOAD_REGISTER_MEM_CMD542             MI_LOAD_REGISTER_MEM_CMD()
543             {
544                 DW0.Value = 0x14800002;
545                 //DW0.DwordLength                                  = GetOpLength(dwSize);
546                 //DW0.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
547                 //DW0.MmioRemapEnable                              = MMIO_REMAP_ENABLE_UNNAMED0;
548                 //DW0.AddCsMmioStartOffset                         = ADD_CS_MMIO_START_OFFSET_UNNAMED0;
549                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MILOADREGISTERMEM;
550                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
551 
552                 DW1.Value = 0x00000000;
553 
554                 DW2_3.Value[0] = DW2_3.Value[1] = 0x00000000;
555             }
556 
557             static const size_t dwSize   = 4;
558             static const size_t byteSize = 16;
559         };
560 
561         //!
562         //! \brief MI_LOAD_REGISTER_REG
563         //! \details
564         //!     The MI_LOAD_REGISTER_REG command reads from a source register location
565         //!     and writes that value to a destination register location.
566         //!
567         //!     Any offset that is to a destination outside of the GT core will allow
568         //!     the parser to continue once the cycle is at the GT boundry and not
569         //!     destination. Any other address will ensure the destination is updated
570         //!     prior to parsing the next command
571         //!
572         //!
573         //!     The command temporarily halts commands that will cause cycles down the
574         //!     3D pipeline.
575         //!
576         //!     Destination register with mask implemented (Ex: Some registers have bits
577         //!     [31:16] as mask bits and bits[15:0] as data) will not get updated unless
578         //!     the  value read from source register has the bits corresponding to the
579         //!     mask bits set. Note that any mask implemented register when read returns
580         //!     "0" for the bits corresponding to mask location. When the source and
581         //!     destination are mask implemented registers, destination register will
582         //!     not get updated with the source register contents.
583         //!
584         //!     This command is not allowed to update the privilege register range when
585         //!     executed from a non-privilege batch buffer.
586         //!
587         struct MI_LOAD_REGISTER_REG_CMD
588         {
589             union
590             {
591                 struct
592                 {
593                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                        //!< DWORD_LENGTH
594                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 15);                         //!< Reserved
595                     uint32_t MmioRemapEnableSource : __CODEGEN_BITFIELD(16, 16);            //!< MMIO_REMAP_ENABLE_SOURCE
596                     uint32_t MmioRemapEnableDestination : __CODEGEN_BITFIELD(17, 17);       //!< MMIO_REMAP_ENABLE_DESTINATION
597                     uint32_t AddCsMmioStartOffsetSource : __CODEGEN_BITFIELD(18, 18);       //!< ADD_CS_MMIO_START_OFFSET_SOURCE
598                     uint32_t AddCsMmioStartOffsetDestination : __CODEGEN_BITFIELD(19, 19);  //!< ADD_CS_MMIO_START_OFFSET_DESTINATION
599                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 22);                       //!< Reserved
600                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                  //!< MI_COMMAND_OPCODE
601                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                      //!< COMMAND_TYPE
602                 };
603                 uint32_t Value;
604             } DW0;
605             union
606             {
607                 struct
608                 {
609                     uint32_t Reserved32 : __CODEGEN_BITFIELD(0, 1);              //!< Reserved
610                     uint32_t SourceRegisterAddress : __CODEGEN_BITFIELD(2, 22);  //!< Source Register Address
611                     uint32_t Reserved55 : __CODEGEN_BITFIELD(23, 31);            //!< Reserved
612                 };
613                 uint32_t Value;
614             } DW1;
615             union
616             {
617                 struct
618                 {
619                     uint32_t Reserved64 : __CODEGEN_BITFIELD(0, 1);                   //!< Reserved
620                     uint32_t DestinationRegisterAddress : __CODEGEN_BITFIELD(2, 22);  //!< Destination Register Address
621                     uint32_t Reserved87 : __CODEGEN_BITFIELD(23, 31);                 //!< Reserved
622                 };
623                 uint32_t Value;
624             } DW2;
625 
626             //! \name Local enumerations
627 
628             //! \brief MMIO_REMAP_ENABLE_SOURCE
629             //! \details
630             //!     This bit provides a mechanism in HW to remap the "Source
631             //!     Register"MMIO address in the MI command to the engine instance on which
632             //!     the command is getting executed, remapping in HW is done using engine
633             //!     specific remap table. Render and Compute engine share a common remapping
634             //!     table to facilitate remapping across engines, where as a dedicated remap
635             //!     table for each of Video Decode and Video Enhancement engine class.
636             //!       A MMIO remapping table per engine class is created with
637             //!     MMIO address belonging to multiple instances of an engine within an
638             //!     engine class. However Render and Compute engine share a common remapping
639             //!     table to facilitate remapping across engines, where as a dedicated remap
640             //!     table for each of Video Decode and Video Enhancement engine class.
641             //!       This mode provides mechanism for SW to always use MMIO
642             //!     address belonging to fixed instance (instance zero) with in an engine
643             //!     class during command buffer creation agnostic to the instance on which
644             //!     it will get scheduled. This willalso allow context interoperability
645             //!     across instances with in an engine class and extends to across engines
646             //!     in case of Render and Compute.
647             enum MMIO_REMAP_ENABLE_SOURCE
648             {
649                 MMIO_REMAP_ENABLE_SOURCE_UNNAMED0 = 0,  //!< MMIO remapping will not be applied to the MMIO address.
650                 MMIO_REMAP_ENABLE_SOURCE_UNNAMED1 = 1,  //!< MMIO remapping will be applied to the MMIO address prior to using for any other functionality of the command.
651             };
652 
653             //! \brief MMIO_REMAP_ENABLE_DESTINATION
654             //! \details
655             //!     This bit provides a mechanism in HW to remap the " Destination
656             //!     Register" MMIO address in the MI command to the engine instance on which
657             //!     the command is getting executed, remapping in HW is done using engine
658             //!     specific remap table. Render and Compute engine share a common remapping
659             //!     table to facilitate remapping across engines, where as a dedicated remap
660             //!     table for each of Video Decode and Video Enhancement engine class.
661             //!       A MMIO remapping table per engine class is created with
662             //!     MMIO address belonging to multiple instances of an engine within an
663             //!     engine class. However Render and Compute engine share a common remapping
664             //!     table to facilitate remapping across engines, where as a dedicated remap
665             //!     table for each of Video Decode and Video Enhancement engine class.
666             //!       This mode provides mechanism for SW to always use MMIO
667             //!     address belonging to fixed instance (instance zero) with in an engine
668             //!     class during command buffer creation agnostic to the instance on which
669             //!     it will get scheduled. This willalso allow context interoperability
670             //!     across instances with in an engine class and extends to across engines
671             //!     in case of Render and Compute.
672             enum MMIO_REMAP_ENABLE_DESTINATION
673             {
674                 MMIO_REMAP_ENABLE_DESTINATION_UNNAMED0 = 0,  //!< MMIO remapping will not be applied to the MMIO address.
675                 MMIO_REMAP_ENABLE_DESTINATION_UNNAMED1 = 1,  //!< MMIO remapping will be applied to the MMIO address prior to using for any other functionality of the command.
676             };
677 
678             //! \brief ADD_CS_MMIO_START_OFFSET_SOURCE
679             //! \details
680             //!     This bit controls the functionality of the Register Address Source
681             //!     field in the command.
682             enum ADD_CS_MMIO_START_OFFSET_SOURCE
683             {
684                 ADD_CS_MMIO_START_OFFSET_SOURCE_UNNAMED0 = 0,  //!< Register Address field in the command is absolute and not an offset from the executing command streamer MMIO start offset.
685                 ADD_CS_MMIO_START_OFFSET_SOURCE_UNNAMED1 = 1,  //!< Source Register Address field in the command is treated as an offset from the executing Command Streamers MMIO start offset. Bits [22:2] of the Source Register Address are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer./>Example: MI_LOAD_REGISTER_REGISTER_REG, DEST_ADD_CS_MMIO_START_OFFSET: false, SRC_ADD_CS_MMIO_START_OFFSET:true, Source Register Address:0x1C_0130, Destination Register Address: 0x1C_0030/>The above command when executed on RenderCS will result in a MMIO read from 0x1C _2130 instead of read from 0x1C_0130 and write to MMIO offset 0x1C_0030. Note that RenderCS MMIO start offset is 0x2000.
686             };
687 
688             //! \brief ADD_CS_MMIO_START_OFFSET_DESTINATION
689             //! \details
690             //!     This bit controls the functionality of the Register Address
691             //!     Destination field in the command.
692             enum ADD_CS_MMIO_START_OFFSET_DESTINATION
693             {
694                 ADD_CS_MMIO_START_OFFSET_DESTINATION_UNNAMED0 = 0,  //!< Destination Register Address field in the command is absolute and not an offset from the executing command streamer MMIO start offset.
695                 ADD_CS_MMIO_START_OFFSET_DESTINATION_UNNAMED1 = 1,  //!< Destination Register Address field in the command is treated as an offset from the executing Command Streamers MMIO start offset. Bits [22:2] of the Destination Register Address are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer./>Example: MI_LOAD_REGISTER_REGISTER_REG, DEST_ADD_CS_MMIO_START_OFFSET: true, SRC_ADD_CS_MMIO_START_OFFSET:true, Source Register Address:0x1C_0130, Destination Register Address: 0x1C_0030/>The above command when executed on RenderCS will result in a MMIO read from 0x1C_2130 (0x00_2000 + 0x1C_0130) and write to MMIO offset 0x1C_2030 (0x00_2000 + 0x1C_0030) instead of read from 0x1C_0130 and write to 0x1C_0030. Note that RenderCS MMIO start offset is 0x2000.
696             };
697 
698             enum MI_COMMAND_OPCODE
699             {
700                 MI_COMMAND_OPCODE_MILOADREGISTERREG = 42,  //!< No additional details
701             };
702 
703             enum COMMAND_TYPE
704             {
705                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
706             };
707 
708             //! \name Initializations
709 
710             //! \brief Explicit member initialization function
MI_LOAD_REGISTER_REG_CMDCmd::MI_LOAD_REGISTER_REG_CMD711             MI_LOAD_REGISTER_REG_CMD()
712             {
713                 DW0.Value = 0x15000001;
714                 //DW0.DwordLength                                  = GetOpLength(dwSize);
715                 //DW0.MmioRemapEnableSource                        = MMIO_REMAP_ENABLE_SOURCE_UNNAMED0;
716                 //DW0.MmioRemapEnableDestination                   = MMIO_REMAP_ENABLE_DESTINATION_UNNAMED0;
717                 //DW0.AddCsMmioStartOffsetSource                   = ADD_CS_MMIO_START_OFFSET_SOURCE_UNNAMED0;
718                 //DW0.AddCsMmioStartOffsetDestination              = ADD_CS_MMIO_START_OFFSET_DESTINATION_UNNAMED0;
719                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MILOADREGISTERREG;
720                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
721 
722                 DW1.Value = 0x00000000;
723 
724                 DW2.Value = 0x00000000;
725             }
726 
727             static const size_t dwSize   = 3;
728             static const size_t byteSize = 12;
729         };
730 
731         //!
732         //! \brief MI_STORE_REGISTER_MEM
733         //! \details
734         //!     The MI_STORE_REGISTER_MEM command requests a register read from a
735         //!     specified memory mapped register location in the device and store of
736         //!     that DWord to memory. The register address is specified along with the
737         //!     command to perform the read.
738         //!
739         //!     The command temporarily halts command execution.
740         //!     The memory address for the write is snooped on the host bus.
741         //!     This command should not be used from within a "non-privilege" batch
742         //!     buffer to access global virtual space. doing so will be treated as
743         //!     privilege access violation. Refer "User Mode Privilege Command" in
744         //!     MI_BATCH_BUFFER_START command section to know HW behavior on
745         //!     encountering privilege access violation. This command can be used within
746         //!     ring buffers and/or "privilege" batch buffers to access global virtual
747         //!     space.
748         //!     This command will cause undefined data to be written to memory if given
749         //!     register addresses for the PGTBL_CTL_0 or FENCE registers.
750         //!
751         //!
752         struct MI_STORE_REGISTER_MEM_CMD
753         {
754             union
755             {
756                 struct
757                 {
758                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                        //!< DWORD_LENGTH
759                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 15);                         //!< Reserved
760                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(16, 16);  //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
761                     uint32_t MmioRemapEnable : __CODEGEN_BITFIELD(17, 17);                  //!< MMIO_REMAP_ENABLE
762                     uint32_t Reserved18 : __CODEGEN_BITFIELD(18, 18);                       //!< Reserved
763                     uint32_t AddCsMmioStartOffset : __CODEGEN_BITFIELD(19, 19);             //!< ADD_CS_MMIO_START_OFFSET
764                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 20);                       //!< Reserved
765                     uint32_t PredicateEnable : __CODEGEN_BITFIELD(21, 21);                  //!< Predicate Enable
766                     uint32_t UseGlobalGtt : __CODEGEN_BITFIELD(22, 22);                     //!< Use Global GTT
767                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                  //!< MI_COMMAND_OPCODE
768                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                      //!< COMMAND_TYPE
769                 };
770                 uint32_t Value;
771             } DW0;
772             union
773             {
774                 struct
775                 {
776                     uint32_t Reserved32 : __CODEGEN_BITFIELD(0, 1);        //!< Reserved
777                     uint32_t RegisterAddress : __CODEGEN_BITFIELD(2, 22);  //!< Register Address
778                     uint32_t Reserved55 : __CODEGEN_BITFIELD(23, 31);      //!< Reserved
779                 };
780                 uint32_t Value;
781             } DW1;
782             union
783             {
784                 struct
785                 {
786                     uint64_t Reserved64 : __CODEGEN_BITFIELD(0, 1);      //!< Reserved
787                     uint64_t MemoryAddress : __CODEGEN_BITFIELD(2, 63);  //!< Memory Address
788                 };
789                 uint32_t Value[2];
790             } DW2_3;
791 
792             //! \name Local enumerations
793 
794             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
795             //! \details
796             //!     style="text-align:justify; margin:0in 0in 0.0001pt"><span
797             //!     style="font-size:11pt">style="font-family:Calibri,
798             //!     sans-serif">This bit controls the memory
799             //!     write address computation for the store data update. The final memory
800             //!     write address is computed by adding the   Workload
801             //!     Partition ID<span
802             //!     style="font-family:Calibri, sans-serif">
803             //!     times the "Address Offset"to the memory address mentioned in the
804             //!     command. Workload Partition ID<span
805             //!     style="font-size:11pt">style="font-family:Calibri,
806             //!     sans-serif"> gets programmed in the
807             //!     WPARIDregister <span
808             //!     style="font-family:&quot;Calibri&quot;,sans-serif">and the Address
809             //!     Offset gets programmed through CS_MI_ADDRESS_OFFSET
810             //!     registerstyle="font-family:Calibri,
811             //!     sans-serif">.
812             //!     style="text-align:justify; margin:0in 0in 0.0001pt">
813             //!     style="text-align:justify; margin:0in 0in 0.0001pt"><span
814             //!     style="font-size:11pt">style="font-family:Calibri,
815             //!     sans-serif">Example: {Final Memory Write
816             //!     Address[47:2], 2'b00} = (  Workload Partition
817             //!     IDstyle="font-family:Calibri,
818             //!     sans-serif">* Address Offset) + {Memory
819             //!     Write Address [47:2], 2'b00}
820             //!     style="text-align:justify; margin:0in 0in 0.0001pt">
821             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
822             {
823                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!<   There is no offset added to the memory write address.
824                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!<   The final memory address is computed based on the Virtual Engine ID.
825             };
826 
827             //! \brief MMIO_REMAP_ENABLE
828             //! \details
829             //!     This bit provides a mechanism in HW to remap the MMIO address in the
830             //!     MI command to the engine instance on which the command is getting
831             //!     executed, remapping in HW is done using engine specific remap table.
832             //!     Render and Compute engine share a common remapping table to facilitate
833             //!     remapping across engines, where as a dedicated remap table for each of
834             //!     Video Decode and Video Enhancement engine class.
835             //!       A MMIO remapping table per engine class is created with
836             //!     MMIO address belonging to multiple instances of an engine within an
837             //!     engine class. However Render and Compute engine share a common remapping
838             //!     table to facilitate remapping across engines, where as a dedicated remap
839             //!     table for each of Video Decode and Video Enhancement engine class.
840             //!       This mode provides mechanism for SW to always use MMIO
841             //!     address belonging to fixed instance (instance zero) with in an engine
842             //!     class during command buffer creation agnostic to the instance on which
843             //!     it will get scheduled. This will also allow context interoperability
844             //!     across instances with in an engine class and extends to across engines
845             //!     in case of Render and Compute.
846             enum MMIO_REMAP_ENABLE
847             {
848                 MMIO_REMAP_ENABLE_UNNAMED0 = 0,  //!< MMIO remapping will not be applied to the MMIO address.
849                 MMIO_REMAP_ENABLE_UNNAMED1 = 1,  //!< MMIO remapping will be applied to the MMIO address prior to using for any other functionality of the command.
850             };
851 
852             //! \brief ADD_CS_MMIO_START_OFFSET
853             //! \details
854             //!     This bit controls the functionality of the Register Address field in
855             //!     the command.
856             enum ADD_CS_MMIO_START_OFFSET
857             {
858                 ADD_CS_MMIO_START_OFFSET_UNNAMED0 = 0,  //!< Register Address field in the command is absolute and not an offset from the executing command streamer MMIO start offset.
859                 ADD_CS_MMIO_START_OFFSET_UNNAMED1 = 1,  //!< Register Address field in the command is treated as an offset from the executing Command Streamers MMIO start offset. Bits [22:2] of the Register Address are considered as dword offset to be added to the MMIO start offset of the corresponding command streamer./>Example: MI_STORE_REGISTER_MEM, ADD_CS_MMIO_START_OFFSET: true, Memory Address:0xABCD, Register Address: 0x1C_0030/>The above command when executed on RenderCS will result in updating the memory address with the content of the MMIO offset 0x1C_2030 (0x00_2000 + 0x1C_0030) instead to 0x1C_0030. Note that RenderCS MMIO start offset is 0x2000.
860             };
861 
862             enum MI_COMMAND_OPCODE
863             {
864                 MI_COMMAND_OPCODE_MISTOREREGISTERMEM = 36,  //!< No additional details
865             };
866 
867             enum COMMAND_TYPE
868             {
869                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
870             };
871 
872             //! \name Initializations
873 
874             //! \brief Explicit member initialization function
MI_STORE_REGISTER_MEM_CMDCmd::MI_STORE_REGISTER_MEM_CMD875             MI_STORE_REGISTER_MEM_CMD()
876             {
877                 DW0.Value = 0x12000002;
878                 //DW0.DwordLength                                  = GetOpLength(dwSize);
879                 //DW0.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
880                 //DW0.MmioRemapEnable                              = MMIO_REMAP_ENABLE_UNNAMED0;
881                 //DW0.AddCsMmioStartOffset                         = ADD_CS_MMIO_START_OFFSET_UNNAMED0;
882                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MISTOREREGISTERMEM;
883                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
884 
885                 DW1.Value = 0x00000000;
886 
887                 DW2_3.Value[0] = DW2_3.Value[1] = 0x00000000;
888             }
889 
890             static const size_t dwSize   = 4;
891             static const size_t byteSize = 16;
892         };
893 
894         //!
895         //! \brief MI_BATCH_BUFFER_START
896         //! \details
897         //!     The MI_BATCH_BUFFER_START command is used to initiate the execution of
898         //!     commands stored in a batch buffer. For restrictions on the location of
899         //!     batch buffers, see Batch Buffers in the Device Programming Interface
900         //!     chapter of MI Functions. The batch buffer can be specified as privileged
901         //!     or non-privileged, determining the operations considered valid when
902         //!     initiated from within the buffer and any attached (chained) batch
903         //!     buffers. See Batch Buffer Protection in the Device Programming Interface
904         //!     chapter of MI Functions.
905         //!
906         //!     A batch buffer initiated with this command must end either with a
907         //!     MI_BATCH_BUFFER_END command or by chaining to another batch buffer with
908         //!     an MI_BATCH_BUFFER_START command.
909         //!
910         //!     It is essential that the address location beyond the current page be
911         //!     populated inside the GTT. HW performs over-fetch of the command
912         //!     addresses and any over-fetch requires a valid TLB entry. A single extra
913         //!     page beyond the batch buffer is sufficient.
914         //!
915         //!       Hardware has DMA engine to fetch the command buffer data from memory.
916         //!     DMA engine pre-fetches eight cacheline worth of command data in to its
917         //!     storage and keeps it ready to be executed, it keeps fetching command
918         //!     data as and when space is available in the storage upon execution of
919         //!     commands. In case of batch buffer execution, DMA engine stops
920         //!     prefetching the command data only on executing MI_BATCH_BUFFER_END
921         //!     command and MI_BATCH_BUFFER_START in case of chained batch buffers.
922         //!     Software must ensure memory pages are made available accounting for the
923         //!     hardware pre-fetched memory addresses.
924         //!
925         //!       Example:
926         //!
927         //!       When MI_BATCH_BUFFER_END or MI_BATCH_BUFFER_START is more than eight
928         //!     cachelines (512 Bytes) away from the page boundary, nothing special has
929         //!     to be done by SW.
930         //!
931         //!       When MI_BATCH_BUFFER_END or MI_BATCH_BUFFER_START is less than or
932         //!     equal to eight cachelines (512 Bytes) from the page boundary, SW must
933         //!     ensure the next page is made available as part of the batch buffer. This
934         //!     will ensure the memory address is populated and will not result in fault
935         //!     when the hardware ends up pre-fetching data from the next page prior to
936         //!     execution of MI_BATCH_BUFFER_END or MI_BATCH_BUFFER_START command.
937         //!
938         //!     SW must ensure it buffers the size of the batch buffer includes
939         //!     additional buffer equal to the command buffer beyond the end. The
940         //!     command buffer for the command streamer is 0.5KB.
941         //!
942         //!     SW must ensure it buffers the size of the batch buffer includes
943         //!     additional buffer equal to the command buffer beyond the end. The
944         //!     command buffer for the command streamer is 1 KB.
945         //!
946         struct MI_BATCH_BUFFER_START_CMD
947         {
948             union
949             {
950                 struct
951                 {
952                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);            //!< DWORD_LENGTH,
953                     uint32_t AddressSpaceIndicator : __CODEGEN_BITFIELD(8, 8);  //!< ADDRESS_SPACE_INDICATOR,
954                     uint32_t Reserved9 : __CODEGEN_BITFIELD(9, 31);             //!< Reserved,
955                 } Obj0;
956                 struct
957                 {
958                     uint32_t Reserved0 : __CODEGEN_BITFIELD(0, 8);                             //!< Reserved,
959                     uint32_t Reserved9 : __CODEGEN_BITFIELD(9, 9);                             //!< Reserved,
960                     uint32_t Reserved10 : __CODEGEN_BITFIELD(10, 14);                          //!< Reserved,
961                     uint32_t PredicationEnable : __CODEGEN_BITFIELD(15, 15);                   //!< Predication Enable,
962                     uint32_t Reserved16 : __CODEGEN_BITFIELD(16, 18);                          //!< Reserved,
963                     uint32_t EnableCommandCache : __CODEGEN_BITFIELD(19, 19);                  //!< ENABLE_COMMAND_CACHE,
964                     uint32_t PoshEnable : __CODEGEN_BITFIELD(20, 20);                          //!< POSH_ENABLE,
965                     uint32_t PoshStart : __CODEGEN_BITFIELD(21, 21);                           //!< POSH_START,
966                     uint32_t Reserved22 : __CODEGEN_BITFIELD(22, 22);                          //!< Reserved,
967                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                     //!< MI_COMMAND_OPCODE,
968                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                         //!< COMMAND_TYPE,
969                 } Obj1;
970                 struct
971                 {
972                     uint32_t Reserved0 : __CODEGEN_BITFIELD(0, 21);                //!< Reserved,
973                     uint32_t NestedLevelBatchBuffer : __CODEGEN_BITFIELD(22, 22);  //!< NESTED_LEVEL_BATCH_BUFFER, MI_MODE:NestedBatchBufferEnable=='1'
974                     uint32_t Reserved23 : __CODEGEN_BITFIELD(23, 31);              //!< Reserved, MI_MODE:NestedBatchBufferEnable=='1'
975                 } Obj2;
976                 struct
977                 {
978                     uint32_t Reserved0 : __CODEGEN_BITFIELD(0, 21);                //!< Reserved, MI_MODE:NestedBatchBufferEnable=='1'
979                     uint32_t SecondLevelBatchBuffer : __CODEGEN_BITFIELD(22, 22);  //!< SECOND_LEVEL_BATCH_BUFFER, MI_MODE:NestedBatchBufferEnable=='0'
980                     uint32_t Reserved23 : __CODEGEN_BITFIELD(23, 31);              //!< Reserved, MI_MODE:NestedBatchBufferEnable=='0'
981                 } Obj3;
982                 uint32_t Value;
983             } DW0;
984             union
985             {
986                 struct
987                 {
988                     uint64_t Reserved32 : __CODEGEN_BITFIELD(0, 1);                //!< Reserved
989                     uint64_t BatchBufferStartAddress : __CODEGEN_BITFIELD(2, 63);  //!< Batch Buffer Start Address
990                 };
991                 uint32_t Value[2];
992             } DW1_2;
993 
994             //! \name Local enumerations
995 
996             //! \brief ADDRESS_SPACE_INDICATOR
997             //! \details
998             //!     Batch buffers accessed via PPGTT are considered as non-privileged.
999             //!     Certain operations (e.g., MI_STORE_DATA_IMM commands to GGTT memory) are
1000             //!     prohibited within non-privileged buffers. More details mentioned in User
1001             //!     Mode Privileged command section. When MI_BATCH_BUFFER_START command is
1002             //!     executed from within a batch buffer (i.e., is a "chained" or "second
1003             //!     level" batch buffer command), the current active batch buffer's "Address
1004             //!     Space Indicator" and this field determine the "Address Space Indicator"
1005             //!     of the next buffer in the chain.
1006             //!
1007             //!     Chained or Second level batch buffer can be in GGTT or
1008             //!     PPGTT if the parent batch buffer is in GGTT.
1009 
1010             //!     Chained or Second level batch buffer can only be in
1011             //!     PPGTT if the parent batch buffer is in PPGTT. This is enforced by
1012             //!     Hardware.
1013 
1014             //!
1015             enum ADDRESS_SPACE_INDICATOR
1016             {
1017                 ADDRESS_SPACE_INDICATOR_GGTT  = 0,  //!< This batch buffer is located in GGTT memory and is privileged.
1018                 ADDRESS_SPACE_INDICATOR_PPGTT = 1,  //!< This batch buffer is located in PPGTT memory and is Non-Privileged.
1019             };
1020 
1021             enum ENABLE_COMMAND_CACHE
1022             {
1023                 ENABLE_COMMAND_CACHE_UNNAMED0 = 0,  //!< Command Cache disable
1024                 ENABLE_COMMAND_CACHE_UNNAMED1 = 1,  //!< Command Cache enabled
1025             };
1026 
1027             //! \brief POSH_ENABLE
1028             //! \details
1029             //!     <p> "POSH Enable" field in the MI_BATCH_BUFFER_START command is a hint
1030             //!     to POCS to traverse (parse, don’t execute) the batch buffer to look for
1031             //!     "POSH Start" batch buffers. "POSH Enable" field is only inherited to the
1032             //!     chained batch buffer and doesn’t get inherit to the next level batch
1033             //!     buffers unlike "POSH Start" field. "POSH Enable" field must be
1034             //!     explicitly set in the MI_BATCH_BUFFER_START command which calls the next
1035             //!     level batch buffers in order for the POCS to parse them to look for
1036             //!     "POSH Start" batch buffers. "POSH Start" field  takes precedence over
1037             //!     the "POSH Enable" field in POCS.</p>
1038             //!     <p>Example:</p>
1039             //!     <ul>
1040             //!         <li>Once "POSH Enable" is encountered in a first level batch buffer,
1041             //!     POCS will traverse the whole of the first level batch buffers (including
1042             //!     chained first level) to check for "POSH Start" field in
1043             //!     MI_BATCH_BUFFER_START command. POCS by default will not traverse the
1044             //!     second level batch buffers. SW must explicitly set the "POSH Enable"
1045             //!     field for the second level batch buffer called from first level batch
1046             //!     buffer if the second level batch buffer have to be traversed by
1047             //!     POCS.</li>
1048             //!         <li>Similarly, Once "POSH Enable" is encountered in a second level
1049             //!     batch buffer, POCS will traverse the whole of the second level batch
1050             //!     buffers (including chained second level) to check for "POSH Start" field
1051             //!     in MI_BATCH_BUFFER_START command. POCS by default will not traverse the
1052             //!     third level batch buffers. SW must explicitly set the "POSH Enable"
1053             //!     field for the third level batch buffer called from second level batch
1054             //!     buffer if the third level batch buffer have to be traversed by
1055             //!     POCS.</li>
1056             //!         <li>Similarly, Once "POSH Enable" is encountered in a third level
1057             //!     batch buffer, POCS will traverse the whole of the third level batch
1058             //!     buffers (including chained second level) to check for "POSH Start" field
1059             //!     in MI_BATCH_BUFFER_START command.</li>
1060             //!     </ul>
1061             //!
1062             //!     <p>RCS ignores "POSH Enable" field and has no implications due to the
1063             //!     "POSH Enable" field set in the MI_BATCH_BUFFER_START command.</p>
1064             enum POSH_ENABLE
1065             {
1066                 POSH_ENABLE_UNNAMED0 = 0,  //!< Batch buffer is  not "POSH Enable".
1067                 POSH_ENABLE_UNNAMED1 = 1,  //!< Batch buffer is "POSH Enable"/
1068             };
1069 
1070             //! \brief POSH_START
1071             //! \details
1072             //!     <p>Batch buffers dedicated to be executed by POSH pipe are indicated by
1073             //!     setting the field "POSH Start" in the MI_BATCH_BUFFER_START command
1074             //!     header. Once "POSH Start" is set in a batch buffer all the following
1075             //!     chained batch buffers and next level batch buffers will implicitly
1076             //!     inherit the "POSH Start" field value. Once "POSH Start" is set in a
1077             //!     batch buffer all the following command sequences are to be
1078             //!     <b>executed</b> by POCS until the corresponding batch buffer sequencing
1079             //!     is terminated through
1080             //!     MI_BATCH_BUFFER_END/MI_CONDITIONAL_BATCH_BUFFER_END command.</p>
1081             //!     <p>Example:</p>
1082             //!     <ul>
1083             //!         <li>Once "POSH Start" is encountered in a first level batch buffer
1084             //!     by POCS, it will get reset only when the first level batch buffer
1085             //!     execution is terminated through batch buffer end and the command
1086             //!     execution sequence goes back to the ring buffer,</li>
1087             //!         <li>Similarly, once "POSH Start" is encountered in a second level
1088             //!     batch buffer by POCS, it will get reset only when the second level batch
1089             //!     buffer execution is terminated through batch buffer end and the command
1090             //!     execution sequence goes back to the first level buffer,</li>
1091             //!         <li>Similarly, once when "POSH Start" is encountered in a third
1092             //!     level batch buffer by POCS, it will get reset only when the third level
1093             //!     batch buffer execution is terminated through batch buffer end and the
1094             //!     command execution sequence goes back to the second level batch
1095             //!     buffer.</li>
1096             //!     </ul>
1097             //!
1098             //!     <p>Command sequences executed from the "POSH Start" batch buffer may
1099             //!     lead to chained batch buffers or next level batch buffers.  Batch
1100             //!     buffers executed by POCS may have MI Commands, 3DSATE commands and
1101             //!     3DPRIMTIVE commands for POSH pipe. RCS on parsing MI_BATCH_BUFFER_START
1102             //!     command with "POSH Start" enabled NOOPS the command and moves on the
1103             //!     following command.</p>
1104             enum POSH_START
1105             {
1106                 POSH_START_UNNAMED0 = 0,  //!< Batch buffer is not "POSH Start" enabled.
1107                 POSH_START_UNNAMED1 = 1,  //!< Batch buffer is "POSH Start" enabled.
1108             };
1109 
1110             //! \brief NESTED_LEVEL_BATCH_BUFFER
1111             //! \details
1112             //!     If this bit is set, the command streamer will move to the next level
1113             //!     of batch buffer. Once it executes a MI_BATCH_BUFFER_END in the next
1114             //!     level, it will return to the batch buffer executing this command and
1115             //!     execute the next command.
1116             //!     If clear then itwill remain in the same batch buffer level and on
1117             //!     executingMI_BATCH_BUFFER_END, it will return to the previous level.
1118             //!     Otherwise known as batch buffer chaining.
1119             //!     Hardware supports threelevels of nesting, namely First Level, Second
1120             //!     Level and Third Level.
1121             //!     This bit must not be set in any of the MI_BATCH_BUFFER_START commands
1122             //!     programmed as part of the 3rd level batch buffer's command sequence.
1123             //!
1124             enum NESTED_LEVEL_BATCH_BUFFER
1125             {
1126                 NESTED_LEVEL_BATCH_BUFFER_CHAIN  = 0,  //!< Stay in the same batch buffer level.
1127                 NESTED_LEVEL_BATCH_BUFFER_NESTED = 1,  //!< Move to the next level of batch buffer.
1128             };
1129 
1130             //! \brief SECOND_LEVEL_BATCH_BUFFER
1131             //! \details
1132             //!     The command streamer contains three storage elements; one for the
1133             //!     ring head address, one for the batch head address, and one for the
1134             //!     second level batch head address. When performing batch buffer chaining,
1135             //!     hardware simply updates the head pointer of the first level batch
1136             //!     address storage. There is no stack in hardware. When this bit is set,
1137             //!     hardware uses the 2nd level batch head address storage element. Chaining
1138             //!     of second level batch buffers is supported. A chained second level batch
1139             //!     buffer is inferred in hardware when aMI_BATCH_BUFFER_START command with
1140             //!     "Second Level Batch Buffer" bit field set is executed from a second
1141             //!     level batch buffer, hardware simply updates the head pointer of the
1142             //!     second level batch address storage. Upon MI_BATCH_BUFFER_END, it will
1143             //!     automatically return to the first level batch buffer address. This
1144             //!     allows hardware to mimic a simple 3-level stack.
1145             enum SECOND_LEVEL_BATCH_BUFFER
1146             {
1147                 SECOND_LEVEL_BATCH_BUFFER_FIRSTLEVELBATCH  = 0,  //!< Place the batch buffer address in the 1st (traditional) level batch address storage element.
1148                 SECOND_LEVEL_BATCH_BUFFER_SECONDLEVELBATCH = 1,  //!< Place the batch buffer address in the second-level batch address storage element.
1149             };
1150 
1151             enum MI_COMMAND_OPCODE
1152             {
1153                 MI_COMMAND_OPCODE_MIBATCHBUFFERSTART = 49,  //!< No additional details
1154             };
1155 
1156             enum COMMAND_TYPE
1157             {
1158                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1159             };
1160 
1161             //! \name Initializations
1162 
1163             //! \brief Explicit member initialization function
MI_BATCH_BUFFER_START_CMDCmd::MI_BATCH_BUFFER_START_CMD1164             MI_BATCH_BUFFER_START_CMD()
1165             {
1166                 DW0.Value = 0;
1167                 DW0.Obj0.DwordLength = GetOpLength(dwSize);
1168                 DW0.Obj0.AddressSpaceIndicator = ADDRESS_SPACE_INDICATOR_GGTT;
1169                 DW0.Obj1.EnableCommandCache = ENABLE_COMMAND_CACHE_UNNAMED0;
1170                 DW0.Obj1.PoshEnable = POSH_ENABLE_UNNAMED0;
1171                 DW0.Obj1.PoshStart = POSH_START_UNNAMED0;
1172                 DW0.Obj1.MiCommandOpcode = MI_COMMAND_OPCODE_MIBATCHBUFFERSTART;
1173                 DW0.Obj1.CommandType = COMMAND_TYPE_MICOMMAND;
1174                 DW0.Obj2.NestedLevelBatchBuffer = NESTED_LEVEL_BATCH_BUFFER_CHAIN;
1175                 DW0.Obj3.SecondLevelBatchBuffer = SECOND_LEVEL_BATCH_BUFFER_FIRSTLEVELBATCH;
1176                 DW1_2.Value[0] = DW1_2.Value[1] = 0x00000000;
1177                 //DW0.Value                                        = 0x18800001;
1178                 //DW0.Obj0.DwordLength                             = GetOpLength(dwSize);
1179                 //DW0.Obj0.AddressSpaceIndicator                   = ADDRESS_SPACE_INDICATOR_GGTT;
1180                 //DW0.Obj0.IndirectAddressEnable                   = INDIRECT_ADDRESS_ENABLE_USEINLINEADDRESS;
1181                 //DW0.Obj0.EnableCommandCache                      = ENABLE_COMMAND_CACHE_UNNAMED0;
1182                 //DW0.Obj1.NestedLevelBatchBuffer                  = NESTED_LEVEL_BATCH_BUFFER_CHAIN;
1183                 //DW0.Obj2.SecondLevelBatchBuffer                  = SECOND_LEVEL_BATCH_BUFFER_FIRSTLEVELBATCH;
1184                 //DW0.Obj3.MiCommandOpcode                         = MI_COMMAND_OPCODE_MIBATCHBUFFERSTART;
1185                 //DW0.Obj3.CommandType                             = COMMAND_TYPE_MICOMMAND;
1186             }
1187 
1188             static const size_t dwSize   = 3;
1189             static const size_t byteSize = 12;
1190         };
1191 
1192         //!
1193         //! \brief MI_SET_PREDICATE
1194         //! \details
1195         //!
1196         //!     This command provides a mechanism to NOOP a section of commands
1197         //!     programmed in the command buffer. This command on execution evaluates
1198         //!     the predication status based on the following predication conditions
1199         //!     enabled.
1200         //!
1201         //!     Predication status gets set if any of the above fields satisfy the
1202         //!     predicate condition. On predicate status set, HW NOOPS the subsequent
1203         //!     commands parsed until the predicate status is re-evaluated and reset on
1204         //!     executing next MI_SET_PREDICATE command. However the following commands
1205         //!     are exception which can be programmed to be or not be predicated as part
1206         //!     of the predication flow enforced by MI_SET_PREDICATE command.
1207         //!
1208         //!     MI_BATCH_BUFFER_START
1209         //!
1210         //!     MI_BATCH_BUFFER_END
1211         //!
1212         //!     MI_CONDITIONAL_BATCH_BUFFER_END
1213         //!
1214         //!     MI_SET_PREDICATE command will always get executed by HW irrespective of
1215         //!     the predication status.
1216         //!
1217         //!       MI_SET_PREDCIATE commands predication status is context save/restored
1218         //!     through MMIO register MI_SET_PREDICATE_RESULT to retain its
1219         //!     functionality across the context switches. Predication based of
1220         //!     MI_SET_PREDICATE_RESULT is only applied to the commands that are
1221         //!     executed from Ring Buffer and Batch Buffer and doesnt apply to any other
1222         //!     sources (context restore, Work Around Batch Buffers) of commands.
1223         //!
1224         //!       MI_SET_PREDICATE predication scope must be confined within a Batch
1225         //!     Buffer to set of commands.
1226         //!     MI_SET_PREDICATE with Predicate Enable Must always have a corresponding
1227         //!     MI_SET_PREDICATE with Predicate Disable within the same Batch Buffer.
1228         //!
1229         //!
1230         struct MI_SET_PREDICATE_CMD
1231         {
1232             union
1233             {
1234                 struct
1235                 {
1236                     uint32_t PredicateEnable : __CODEGEN_BITFIELD(0, 3);        //!< PREDICATE_ENABLE
1237                     uint32_t PredicateEnableWparid : __CODEGEN_BITFIELD(4, 5);  //!< PREDICATE_ENABLE_WPARID
1238                     uint32_t Reserved6 : __CODEGEN_BITFIELD(6, 22);             //!< Reserved
1239                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);      //!< MI_COMMAND_OPCODE
1240                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);          //!< COMMAND_TYPE
1241                 };
1242                 uint32_t Value;
1243             } DW0;
1244 
1245             //! \name Local enumerations
1246 
1247             enum PREDICATE_ENABLE
1248             {
1249                 PREDICATE_ENABLE_PREDICATEDISABLE   = 0,   //!< Predication is Disabled and CS will process commands as usual.
1250                 PREDICATE_ENABLE_NOOPONRESULT2CLEAR = 1,   //!< Following Commands will be NOOPED by CS only if the MI_PREDICATE_RESULT_2 is clear.
1251                 PREDICATE_ENABLE_NOOPONRESULT2SET   = 2,   //!< Following Commands will be NOOPED by CS only if the MI_PREDICATE_RESULT_2 is set.
1252                 PREDICATE_ENABLE_NOOPALWAYS         = 15,  //!< Following Commands will be NOOPED by CS unconditionally.
1253             };
1254 
1255             //! \brief PREDICATE_ENABLE_WPARID
1256             //! \details
1257             //!
1258             //!     This field enables the predication based on the outcome
1259             //!     of value resulting in bitwise AND of the bits in the WPARID and the
1260             //!     PREDICATION_MASK Mask Register. WPARID and PREDICATION_MASK are
1261             //!     non-privileged registers and context save/restored on a context
1262             //!     switch.
1263             //!
1264             enum PREDICATE_ENABLE_WPARID
1265             {
1266                 PREDICATE_ENABLE_WPARID_NOOPNEVER           = 0,  //!< The predication status due to this field doesnt contribute to the overall predication status of MI_SET_PREDICATE command.
1267                 PREDICATE_ENABLE_WPARID_NOOPONZEROVALUE     = 1,  //!< Predicate if (WPARID AND PREDICATE_MASK) == 0
1268                 PREDICATE_ENABLE_WPARID_NOOPONNON_ZEROVALUE = 2,  //!< Predicate if (WPARID AND PREDICATE_MASK) != 0
1269             };
1270 
1271             enum MI_COMMAND_OPCODE
1272             {
1273                 MI_COMMAND_OPCODE_MISETPREDICATE = 1,  //!< No additional details
1274             };
1275 
1276             enum COMMAND_TYPE
1277             {
1278                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1279             };
1280 
1281             //! \name Initializations
1282 
1283             //! \brief Explicit member initialization function
MI_SET_PREDICATE_CMDCmd::MI_SET_PREDICATE_CMD1284             MI_SET_PREDICATE_CMD()
1285             {
1286                 DW0.Value = 0x00800000;
1287                 //DW0.PredicateEnable                              = PREDICATE_ENABLE_NOOPNEVER;
1288                 //DW0.PredicateEnableWparid                        = PREDICATE_ENABLE_WPARID_NOOPNEVER;
1289                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MISETPREDICATE;
1290                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
1291             }
1292 
1293             static const size_t dwSize   = 1;
1294             static const size_t byteSize = 4;
1295         };
1296 
1297         //!
1298         //! \brief MI_COPY_MEM_MEM
1299         //! \details
1300         //!     The MI_COPY_MEM_MEM command reads a DWord from memory and stores the
1301         //!     value of that DWord to back to memory.   The source and destination
1302         //!     addresses are specified in the command. The command temporarily halts
1303         //!     command execution.
1304         //!
1305         //!     This command should not be used within a "non-privileged" batch buffer
1306         //!     to access global virtual space; doing so will be treated as privilege
1307         //!     access violation. Refer to the "User Mode Privilege Command" in
1308         //!     MI_BATCH_BUFFER_START command section to learn more about HW behavior on
1309         //!     encountering a privilege access violation.  This command can be used
1310         //!     within ring buffers and/or privilege batch buffers to access global
1311         //!     virtual space.
1312         //!
1313         struct MI_COPY_MEM_MEM_CMD
1314         {
1315             union
1316             {
1317                 struct
1318                 {
1319                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                //!< DWORD_LENGTH
1320                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 20);                 //!< Reserved
1321                     uint32_t UseGlobalGttDestination : __CODEGEN_BITFIELD(21, 21);  //!< USE_GLOBAL_GTT_DESTINATION
1322                     uint32_t UseGlobalGttSource : __CODEGEN_BITFIELD(22, 22);       //!< USE_GLOBAL_GTT_SOURCE
1323                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);          //!< MI_COMMAND_OPCODE
1324                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);              //!< COMMAND_TYPE
1325                 };
1326                 uint32_t Value;
1327             } DW0;
1328             union
1329             {
1330                 struct
1331                 {
1332                     uint64_t Reserved32 : __CODEGEN_BITFIELD(0, 1);                 //!< Reserved
1333                     uint64_t DestinationMemoryAddress : __CODEGEN_BITFIELD(2, 63);  //!< Destination Memory Address
1334                 };
1335                 uint32_t Value[2];
1336             } DW1_2;
1337             union
1338             {
1339                 struct
1340                 {
1341                     uint64_t Reserved96 : __CODEGEN_BITFIELD(0, 1);            //!< Reserved
1342                     uint64_t SourceMemoryAddress : __CODEGEN_BITFIELD(2, 63);  //!< Source Memory Address
1343                 };
1344                 uint32_t Value[2];
1345             } DW3_4;
1346 
1347             //! \name Local enumerations
1348 
1349             //! \brief USE_GLOBAL_GTT_DESTINATION
1350             //! \details
1351             //!     It is allowed for this bit to be set when executing this command from a
1352             //!     privileged (secure) batch buffer or ring buffer. This bit must be clear
1353             //!     when programmed from within a non-privileged batch buffer. This bit must
1354             //!     be 1 if the Per Process GTT Enable bit is clear.
1355             enum USE_GLOBAL_GTT_DESTINATION
1356             {
1357                 USE_GLOBAL_GTT_DESTINATION_PERPROCESSGRAPHICSADDRESS = 0,  //!< No additional details
1358                 USE_GLOBAL_GTT_DESTINATION_GLOBALGRAPHICSADDRESS     = 1,  //!< This command will use the global GTT to translate the Address and this command must be executing from a privileged (secure) batch buffer.
1359             };
1360 
1361             //! \brief USE_GLOBAL_GTT_SOURCE
1362             //! \details
1363             //!     It is allowed for this bit to be set when executing this command from a
1364             //!     privileged (secure) batch buffer or ring buffer. This bit must be clear
1365             //!     when programmed from within a non-privileged batch buffer. This bit must
1366             //!     be 1 if the Per Process GTT Enable bit is clear.
1367             enum USE_GLOBAL_GTT_SOURCE
1368             {
1369                 USE_GLOBAL_GTT_SOURCE_PERPROCESSGRAPHICSADDRESS = 0,  //!< No additional details
1370                 USE_GLOBAL_GTT_SOURCE_GLOBALGRAPHICSADDRESS     = 1,  //!< This command will use the global GTT to translate the Address and this command must be executing from a privileged (secure) batch buffer.
1371             };
1372 
1373             enum MI_COMMAND_OPCODE
1374             {
1375                 MI_COMMAND_OPCODE_MIMEMTOMEM = 46,  //!< No additional details
1376             };
1377 
1378             enum COMMAND_TYPE
1379             {
1380                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1381             };
1382 
1383             //! \name Initializations
1384 
1385             //! \brief Explicit member initialization function
MI_COPY_MEM_MEM_CMDCmd::MI_COPY_MEM_MEM_CMD1386             MI_COPY_MEM_MEM_CMD()
1387             {
1388                 DW0.Value = 0x17000003;
1389                 //DW0.DwordLength                                  = GetOpLength(dwSize);
1390                 //DW0.UseGlobalGttDestination                      = USE_GLOBAL_GTT_DESTINATION_PERPROCESSGRAPHICSADDRESS;
1391                 //DW0.UseGlobalGttSource                           = USE_GLOBAL_GTT_SOURCE_PERPROCESSGRAPHICSADDRESS;
1392                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MICOPYMEMMEM;
1393                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
1394 
1395                 DW1_2.Value[0] = DW1_2.Value[1] = 0x00000000;
1396 
1397                 DW3_4.Value[0] = DW3_4.Value[1] = 0x00000000;
1398             }
1399 
1400             static const size_t dwSize   = 5;
1401             static const size_t byteSize = 20;
1402         };
1403 
1404         //!
1405         //! \brief MI_STORE_DATA_IMM
1406         //! \details
1407         //!     The MI_STORE_DATA_IMM command requests a write of the QWord constant
1408         //!     supplied in the packet to the specified Memory Address. As the write
1409         //!     targets a System Memory Address, the write operation is coherent with
1410         //!     the CPU cache (i.e., the processor cache is snooped).
1411         //!
1412         //!     This command supports writing to multiple consecutive dwords or qwords
1413         //!     memory locations from the starting address.
1414         //!
1415         //!     This command should not be used within a "non-privilege" batch buffer to
1416         //!     access global virtual space, doing so will be treated as privilege
1417         //!     access violation. Refer "User Mode Privilege Command" in
1418         //!     MI_BATCH_BUFFER_START command section to know HW behavior on
1419         //!     encountering privilege access violation. This command can be used within
1420         //!     ring buffers and/or privilege batch buffers to access global virtual
1421         //!     space.
1422         //!
1423         //!     This command can be used for general software synchronization through
1424         //!     variables in cacheable memory (i.e., where software does not need to
1425         //!     poll un-cached memory or device registers).
1426         //!
1427         //!     This command simply initiates the write operation with command execution
1428         //!     proceeding normally. Although the write operation is guaranteed to
1429         //!     complete eventually, there is no mechanism to synchronize command
1430         //!     execution with the completion (or even initiation) of these operations.
1431         //!
1432         struct MI_STORE_DATA_IMM_CMD
1433         {
1434             union
1435             {
1436                 struct
1437                 {
1438                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 9);                        //!< DWORD_LENGTH
1439                     uint32_t ForceWriteCompletionCheck : __CODEGEN_BITFIELD(10, 10);        //!< FORCE_WRITE_COMPLETION_CHECK
1440                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(11, 11);  //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1441                     uint32_t Reserved12 : __CODEGEN_BITFIELD(12, 20);                       //!< Reserved
1442                     uint32_t StoreQword : __CODEGEN_BITFIELD(21, 21);                       //!< Store Qword
1443                     uint32_t UseGlobalGtt : __CODEGEN_BITFIELD(22, 22);                     //!< Use Global GTT
1444                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                  //!< MI_COMMAND_OPCODE
1445                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                      //!< COMMAND_TYPE
1446                 };
1447                 uint32_t Value;
1448             } DW0;
1449             union
1450             {
1451                 struct
1452                 {
1453                     uint64_t CoreModeEnable : __CODEGEN_BITFIELD(0, 0);  //!< Core Mode Enable
1454                     uint64_t Reserved33 : __CODEGEN_BITFIELD(1, 1);      //!< Reserved
1455                     uint64_t Address : __CODEGEN_BITFIELD(2, 63);        //!< Address
1456                 };
1457                 uint32_t Value[2];
1458             } DW1_2;
1459             union
1460             {
1461                 struct
1462                 {
1463                     uint32_t DataDword0;  //!< Data DWord 0
1464                 };
1465                 uint32_t Value;
1466             } DW3;
1467             union
1468             {
1469                 struct
1470                 {
1471                     uint32_t DataDword1;  //!< Data DWord 1
1472                 };
1473                 uint32_t Value;
1474             } DW4;
1475 
1476             //! \name Local enumerations
1477 
1478             //! \brief FORCE_WRITE_COMPLETION_CHECK
1479             //! \details
1480             //!     This bit controls the write completion checks done by command streamer
1481             //!     on executing this command.
1482             enum FORCE_WRITE_COMPLETION_CHECK
1483             {
1484                 FORCE_WRITE_COMPLETION_CHECK_UNNAMED0 = 0,  //!< All writes resulting from this command are posted writes and no ordering are completion of writes is explicitly guaranteed by command streamer.
1485                 FORCE_WRITE_COMPLETION_CHECK_UNNAMED1 = 1,  //!< Followng the last write from this command, Command Streamer will wait for all previous writes are completed and in global observable domain before moving to next command.
1486             };
1487 
1488             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1489             //! \details
1490             //!     This bit controls the memory write address computation for the store data update.
1491             //!     The final memory write address is computed by adding the
1492             //!     Workload Partition ID times the Address
1493             //!     Offset to the memory address mentioned in the command.
1494             //!     Workload Partition ID gets programmed in
1495             //!     the WPARIDregister and the Address Offset gets programmed through
1496             //!     CS_MI_ADDRESS_OFFSET register.
1497             //!     Example for store dword/qword:
1498             //!     {Final Memory Write Address[47:2], `b00} = (
1499             //!     Workload Partition ID* "Address Offset" + {Memory Write Address [47:2],`b00}
1500             //!
1501             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1502             {
1503                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!<   There is no offset added to the memory write address.
1504                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!< style="text-align:justify; margin:0in 0in 0.0001pt">    The final memory address is computed based on the Virtual Engine ID.
1505             };
1506 
1507             enum MI_COMMAND_OPCODE
1508             {
1509                 MI_COMMAND_OPCODE_MISTOREDATAIMM = 32,  //!< No additional details
1510             };
1511 
1512             enum COMMAND_TYPE
1513             {
1514                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1515             };
1516 
1517             //! \name Initializations
1518 
1519             //! \brief Explicit member initialization function
MI_STORE_DATA_IMM_CMDCmd::MI_STORE_DATA_IMM_CMD1520             MI_STORE_DATA_IMM_CMD()
1521             {
1522                 DW0.Value = 0x10000003;
1523                 //DW0.DwordLength                                  = GetOpLength(dwSize);
1524                 //DW0.ForceWriteCompletionCheck                    = FORCE_WRITE_COMPLETION_CHECK_UNNAMED0;
1525                 //DW0.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
1526                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MISTOREDATAIMM;
1527                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
1528 
1529                 DW1_2.Value[0] = DW1_2.Value[1] = 0x00000000;
1530 
1531                 DW3.Value = 0x00000000;
1532 
1533                 DW4.Value = 0x00000000;
1534             }
1535 
1536             static const size_t dwSize   = 5;
1537             static const size_t byteSize = 20;
1538         };
1539 
1540         //!
1541         //! \brief MI_SEMAPHORE_SIGNAL
1542         //! \details
1543         //!     An engine on executing this command generates a signal (interrupt) to
1544         //!     the GUC (scheduler or FW) by reporting the Producer Token Number
1545         //!     programmed in SEMAPHORE_TOKEN register. Each engine implements its own
1546         //!     SEMAPHORE_TOKEN register. SEMAPHORE_TOKEN register is privileged and
1547         //!     context save/restored. Scheduler can take appropriate action on decoding
1548         //!     the reported Producer Token Number. Typically MI_ATOMIC (non-posted)
1549         //!     command will be used to update the memory semaphore before signaling the
1550         //!     consumer context.
1551         //!       Each engine implements SEMAPHORE_SIGNAL_PORT register for receiving
1552         //!     semaphore signal from the scheduler (SW or FW). A write to the
1553         //!     SEMAPHORE_SIGNAL_PORT with data as 0xFFFF_FFFF is decoded as semaphore
1554         //!     signal received by the corresponding engine. An engine waiting on
1555         //!     un-successful MI_SEMAPHORE_WAIT (signal mode) command will reacquire the
1556         //!     semaphore data from memory and re-evaluate the semaphore comparison on
1557         //!     receiving the semaphore signal. SEMAPHORE_SIGNAL_PORT register is
1558         //!     privileged. Writing to the SEMAPHORE_SIGNAL_PORT of an idle engine (no
1559         //!     context) does not trigger any action in HW and is of no use.
1560         //!       SEMAPHORE_TOKEN, MI_SEMAPHORE_SIGNAL, SEMAPHORE_SIGNAL_PORT and
1561         //!     MI_SEMAPHORE_WAIT together can be used to create semaphores between
1562         //!     producer context and consumer context. MI_SEMPAHORE_SIGNAL command from
1563         //!     a producer context can be used to signal a consumer context waiting on
1564         //!     MI_SEMAPHORE_WAIT (signal mode) command through scheduler (SW or FW).
1565         //!       Typically MI_ATOMIC (non-posted) command will be used to update the
1566         //!     memory semaphore by the producer context before signaling the consumer
1567         //!     context.
1568         //!     Scheduler on receiving the signal will process the Producer Token Number
1569         //!     and if required will signal the consumer context running on an engine by
1570         //!     writing 0xFFFF_FFFF to the corresponding engines SEMAPHORE_SIGNAL_PORT.
1571         //!     A consumer context will wait on MI_SEMAPHORE_WAIT (signal mode) command
1572         //!     until the semaphore comparison is successful. An engine waiting on
1573         //!     un-successful MI_SEMAPHORE_WAIT (signal mode) command will reacquire the
1574         //!     semaphore data from memory and re-evaluate the semaphore comparison on
1575         //!     receiving the semaphore signal.MI_SEMAPHORE_WAIT command has Wait Token
1576         //!     Number as inline data programmed by the SW. Context switched out an
1577         //!     un-successful MI_SEMAPHORE_WAIT command will report Wait Token Number as
1578         //!     Wait Detail field in the CSB structure.
1579         //!
1580         //!     Workaround
1581         //!
1582         //!     : Post-Sync operation bit must not be set when Target Engine Select is
1583         //!     set to RCS.
1584         //!
1585         struct MI_SEMAPHORE_SIGNAL_CMD
1586         {
1587             union
1588             {
1589                 struct
1590                 {
1591                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);          //!< DWORD_LENGTH
1592                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 20);           //!< Reserved
1593                     uint32_t PostSyncOperation : __CODEGEN_BITFIELD(21, 21);  //!< POST_SYNC_OPERATION
1594                     uint32_t Reserved22 : __CODEGEN_BITFIELD(22, 22);         //!< Reserved
1595                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);    //!< MI_COMMAND_OPCODE
1596                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);        //!< COMMAND_TYPE
1597                 };
1598                 uint32_t Value;
1599             } DW0;
1600             union
1601             {
1602                 struct
1603                 {
1604                     uint32_t Reserved32;  //!< Reserved
1605                 };
1606                 uint32_t Value;
1607             } DW1;
1608 
1609             //! \name Local enumerations
1610 
1611             //! \brief POST_SYNC_OPERATION
1612             //! \details
1613             //!     Any desired pipeline flush operation can be achieved by programming
1614             //!     PIPE_CONTROL command prior to this command.
1615             //!       When this bit is set Command Streamer sends a flush down
1616             //!     the pipe and the atomic operation is saved as post sync operation.
1617             //!     Command streamer goes on executing the following commands. Atomic
1618             //!     operation saved as post sync operation is executed at some point later
1619             //!     on completion of corresponding flush issued.
1620             //!       When this bit is set atomic semaphore signal operation will
1621             //!     be out of order with rest of the MI commands programmed in the ring
1622             //!     buffer or batch buffer, it will be in order with respect to the post
1623             //!     sync operations resulting due to PIPE_CONTROL command.
1624             enum POST_SYNC_OPERATION
1625             {
1626                 POST_SYNC_OPERATION_NOPOSTSYNCOPERATION = 0,  //!< Command is executed as usual.
1627                 POST_SYNC_OPERATION_POSTSYNCOPERATION   = 1,  //!< MI_SEMAPHORE_SIGNAL command is executed as a pipelined PIPE_CONTROL flush command with Semaphore Signal as post sync operation. Flush completion only guarantees the workload prior to this command is pushed till Windower unit and completion of any outstanding flushes issued prior to this command.
1628             };
1629 
1630             enum MI_COMMAND_OPCODE
1631             {
1632                 MI_COMMAND_OPCODE_MISEMAPHORESIGNAL = 27,  //!< No additional details
1633             };
1634 
1635             enum COMMAND_TYPE
1636             {
1637                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1638             };
1639 
1640             //! \name Initializations
1641 
1642             //! \brief Explicit member initialization function
MI_SEMAPHORE_SIGNAL_CMDCmd::MI_SEMAPHORE_SIGNAL_CMD1643             MI_SEMAPHORE_SIGNAL_CMD()
1644             {
1645                 DW0.Value = 0x0d800000;
1646                 //DW0.DwordLength                                  = GetOpLength(dwSize);
1647                 //DW0.PostSyncOperation                            = POST_SYNC_OPERATION_NOPOSTSYNCOPERATION;
1648                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MISEMAPHORESIGNAL;
1649                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
1650 
1651                 DW1.Value = 0x00000000;
1652             }
1653 
1654             static const size_t dwSize   = 2;
1655             static const size_t byteSize = 8;
1656         };
1657 
1658         //!
1659         //! \brief MI_SEMAPHORE_WAIT
1660         //! \details
1661         //!
1662         //!     This command supports memory based Semaphore WAIT. Memory based
1663         //!     semaphores will be used for synchronization between the Producer and the
1664         //!     Consumer contexts. Producer and Consumer Contexts could be running on
1665         //!     different engines or on the same engine inside GT. Producer Context
1666         //!     implements a Signal and Consumer context implements a Wait.
1667         //!     Command Streamer on parsing this command fetches data from the Semaphore
1668         //!     Address mentioned in this command and compares it with the inline
1669         //!     Semaphore Data Dword.
1670         //!     If comparison passes, the command streamer moves to the next command.
1671         //!     If comparison fails Command streamer switches out the context. Context
1672         //!     switch can be inhibited by setting "Inhibit Synchronous Context Switch"
1673         //!     in CTXT_SR_CTL register.
1674         //!     If "Inhibit Synchronous context Switch" is enabled and comparison fails,
1675         //!     Command Streamer evaluates the Compare Operation based on the Wait Mode
1676         //!     until the compare operation is true or Wait is canceled by SW.
1677         //!     CS generates semaphore wait interrupt to the scheduler when
1678         //!     MI_SEMAPHORE_WAIT command is un-successful and when "Inhibit Synchronous
1679         //!     Context Switch" is set. Scheduler can use this interrupt to preempt the
1680         //!     context waiting on semaphore wait.
1681         //!
1682         //!     MI_SEMAPHORE_WAIT command also supports register based Semaphore WAIT.
1683         //!     Command Streamer on parsing this command fetches data from the MMIO
1684         //!     offset mentioned in this command and compares it with the inline
1685         //!     Semaphore Data Dword. This functionality is supported when Register Poll
1686         //!     bit is set in the command header. In register poll mode of operation
1687         //!     Wait Mode supported is always Poll mode and no Signal mode is supported.
1688         //!       If comparison passes, the command streamer moves to the next command.
1689         //!     Unlike in Memory based semaphore, there is no context switch on an
1690         //!     un-successful semaphore wait in Register Poll mode, however preemption
1691         //!     is supported on unsuccessful semaphore wait in Register Poll mode.
1692         //!     Semaphore wait interrupt is not generated by default on wait
1693         //!     un-successful in Register Poll mode. However interrupt generation can be
1694         //!     enabled by setting debug mode bit Semaphore Interrupt Enable in Register
1695         //!     Poll Mode in register CSFE_CHICKEN1
1696         //!     Also unlike in Memory based semaphore, generation of an interrupt for a
1697         //!     semaphore wait in "Register Poll" mode is not dependent on the value of
1698         //!     bit "Inhibit Synchronous Context Switch" in register "CTXT_SR_CTL"
1699         //!     Register Poll mode of Semaphore Wait command operation is non-privileged
1700         //!     and will be supported from PPGTT batch buffers.
1701         //!     HW will trigger Render DOP CG on semaphore wait unsuccessful by default
1702         //!     and can be disabled if not desired by programming Register Poll Mode
1703         //!     Semaphore Wait Event IDLE message Disable bit in INSTPM register. Note
1704         //!     that Render DOP CG will not be triggered on register semaphore wait
1705         //!     un-successfull from INDIRECT_CTX pointer or BB_PER_CTX_PTR buffers.
1706         //!
1707         //!     MI_SEMAPHORE_WAIT command must not be used in the middle of a tile pass
1708         //!     on the posh pipe.
1709         //!
1710         //!     Workaround
1711         //!
1712         //!     : [All Command Streamers][Ring Buffer Mode of Scheduling]:
1713         //!     MI_SEMAPHORE_WAIT command must be always programmed with Wait Mode set
1714         //!     to Polling Mode Or MI_SEMAPHORE_WAIT command with Wait Mode set to
1715         //!     Polling Mode can be programmed when Semaphore Wait Event IDLE message
1716         //!     Disable bit in RC_PSMI_CTRL register is set to disable Idle messaging on
1717         //!     unsuccessful MI_SEMPAHORE_WAIT.
1718         //!
1719         struct MI_SEMAPHORE_WAIT_CMD
1720         {
1721             union
1722             {
1723                 struct
1724                 {
1725                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                        //!< DWORD_LENGTH
1726                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 11);                         //!< Reserved
1727                     uint32_t CompareOperation : __CODEGEN_BITFIELD(12, 14);                 //!< COMPARE_OPERATION
1728                     uint32_t WaitMode : __CODEGEN_BITFIELD(15, 15);                         //!< WAIT_MODE
1729                     uint32_t RegisterPollMode : __CODEGEN_BITFIELD(16, 16);                 //!< REGISTER_POLL_MODE
1730                     uint32_t IndirectSemaphoreDataDword : __CODEGEN_BITFIELD(17, 17);       //!< INDIRECT_SEMAPHORE_DATA_DWORD
1731                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(18, 18);  //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1732                     uint32_t Reserved19 : __CODEGEN_BITFIELD(19, 21);                       //!< Reserved
1733                     uint32_t MemoryType : __CODEGEN_BITFIELD(22, 22);                       //!< MEMORY_TYPE
1734                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                  //!< MI_COMMAND_OPCODE
1735                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                      //!< COMMAND_TYPE
1736                 };
1737                 uint32_t Value;
1738             } DW0;
1739             union
1740             {
1741                 struct
1742                 {
1743                     uint32_t SemaphoreDataDword;  //!< Semaphore Data Dword
1744                 };
1745                 uint32_t Value;
1746             } DW1;
1747             union
1748             {
1749                 struct
1750                 {
1751                     uint64_t Reserved64 : __CODEGEN_BITFIELD(0, 1);         //!< Reserved
1752                     uint64_t SemaphoreAddress : __CODEGEN_BITFIELD(2, 63);  //!< Semaphore Address
1753                 };
1754                 uint32_t Value[2];
1755             } DW2_3;
1756             union
1757             {
1758                 struct
1759                 {
1760                     uint32_t Reserved128 : __CODEGEN_BITFIELD(0, 1);      //!< Reserved
1761                     uint32_t WaitTokenNumber : __CODEGEN_BITFIELD(2, 9);  //!< Wait Token Number
1762                     uint32_t Reserved138 : __CODEGEN_BITFIELD(10, 31);    //!< Reserved
1763                 };
1764                 uint32_t Value;
1765             } DW4;
1766 
1767             //! \name Local enumerations
1768 
1769             //! \brief COMPARE_OPERATION
1770             //! \details
1771             //!     This field specifies the operation that will be executed to create the
1772             //!     result that will either allow the context to continue or wait.
1773             enum COMPARE_OPERATION
1774             {
1775                 COMPARE_OPERATION_SADGREATERTHANSDD        = 0,  //!< If Indirect fetched data is greater than inline data then continue.
1776                 COMPARE_OPERATION_SADGREATERTHANOREQUALSDD = 1,  //!< If Indirect fetched data is greater than or equal to inline data then continue.
1777                 COMPARE_OPERATION_SADLESSTHANSDD           = 2,  //!< If Indirect fetched data is less than inline data then continue.
1778                 COMPARE_OPERATION_SADLESSTHANOREQUALSDD    = 3,  //!< If Indirect fetched data is less than or equal to inline data then continue.
1779                 COMPARE_OPERATION_SADEQUALSDD              = 4,  //!< If Indirect fetched data is equalto inline data then continue.
1780                 COMPARE_OPERATION_SADNOTEQUALSDD           = 5,  //!< If Indirect fetched data is not equal to inline data then continue.
1781             };
1782 
1783             //! \brief WAIT_MODE
1784             //! \details
1785             //!     This bit specifies the WAIT behavior when the semaphore comparison fails
1786             //!     and before the context is switched out.
1787             enum WAIT_MODE
1788             {
1789                 WAIT_MODE_SIGNALMODE  = 0,  //!< In this mode HW will reacquire the semaphore data from memory for evaluating semaphore wait condition on receiving SIGNAL.Scheduler or SW can generate a SIGNAL to an engine by writing a value 0xFFFF_FFFF to the engines corresponding SEMAPHORE_SIGNAL_PORT register.
1790                 WAIT_MODE_POLLINGMODE = 1,  //!< In this mode HW periodically reads the semaphore data from memory for comparison until it is context switched out. Periodicity will be mentioned in a SEMA_WAIT_POLL register.
1791             };
1792 
1793             //! \brief REGISTER_POLL_MODE
1794             //! \details
1795             //!     This field control the seamphore wait behavior of polling from memory
1796             //!     vs MMIO register.
1797             enum REGISTER_POLL_MODE
1798             {
1799                 REGISTER_POLL_MODE_MEMORYPOLL   = 0,  //!< In this mode HW will functional as in regular mode and checks for semaphore data in memory.
1800                 REGISTER_POLL_MODE_REGISTERPOLL = 1,  //!< In this mode HW periodically reads the semaphore data from MMIO register instead of memory for comparison until the condition is satisfied. Periodicity will be mentioned in a SEMA_WAIT_POLL register.When operating in register poll mode, DW2 Semaphore Address (bits 22:2) carries the register MMIO offset to be polled.In register poll mode Memory Type field of this command are ignored by HW.
1801             };
1802 
1803             //! \brief INDIRECT_SEMAPHORE_DATA_DWORD
1804             //! \details
1805             //!     This bit controls the "Semaphore Data Dword" to be used for comparison
1806             //!     in register poll mode of operation.
1807             enum INDIRECT_SEMAPHORE_DATA_DWORD
1808             {
1809                 INDIRECT_SEMAPHORE_DATA_DWORD_UNNAMED0 = 0,  //!< Inline data from the command is considered as "Semaphore Data Dword" for comparison.
1810                 INDIRECT_SEMAPHORE_DATA_DWORD_UNNAMED1 = 1,  //!< Value available in GPR0 (Lower Dword) register is considered as "Semaphore Data Dword" for comparison instead of inline data in the command.
1811             };
1812 
1813             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1814             //! \details
1815             //!     This bit controls the memory read address computation for fetching the dat value from the
1816             //!     memory for semaphore comparison. The final memory readaddress is
1817             //!     computed by adding the Workload Partition ID"times the Address Offset to
1818             //!     the memory address mentioned in the command. Workload Partition ID gets
1819             //!     programmed through WPARID register and the Address Offset gets
1820             //!     programmed through CS_MI_ADDRESS_OFFSET register.
1821             //!
1822             //!     Example: Final Memory Read
1823             //!     Address[47:2] = ( Workload Partition ID * Address Offset)
1824             //!     + Memory Read Address[47:2]
1825             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
1826             {
1827                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!<   There is no offset added to the memory read address.
1828                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!< style="text-align:justify; margin:0in 0in 0.0001pt">    The final memory address is computed based on the Virtual Engine ID.
1829             };
1830 
1831             //! \brief MEMORY_TYPE
1832             //! \details
1833             //!     This bit will be ignored and treated as if clear when executing from a
1834             //!     non-privileged batch buffer. It is allowed for this bit to be clear when
1835             //!     executing this command from a privileged (secure) batch buffer. This bit
1836             //!     must be 1 if the Per Process GTT Enable bit is clear.
1837             enum MEMORY_TYPE
1838             {
1839                 MEMORY_TYPE_PERPROCESSGRAPHICSADDRESS = 0,  //!< No additional details
1840                 MEMORY_TYPE_GLOBALGRAPHICSADDRESS     = 1,  //!< This command will use the global GTT to translate the Address and this command must beexecuting from a privileged (secure) batch buffer.
1841             };
1842 
1843             enum MI_COMMAND_OPCODE
1844             {
1845                 MI_COMMAND_OPCODE_MISEMAPHOREWAIT = 28,  //!< No additional details
1846             };
1847 
1848             enum COMMAND_TYPE
1849             {
1850                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
1851             };
1852 
1853             //! \name Initializations
1854 
1855             //! \brief Explicit member initialization function
MI_SEMAPHORE_WAIT_CMDCmd::MI_SEMAPHORE_WAIT_CMD1856             MI_SEMAPHORE_WAIT_CMD()
1857             {
1858                 DW0.Value = 0x0e010003;
1859                 //DW0.DwordLength                                  = GetOpLength(dwSize);
1860                 //DW0.CompareOperation                             = COMPARE_OPERATION_SADGREATERTHANSDD;
1861                 //DW0.WaitMode                                     = WAIT_MODE_SIGNALMODE;
1862                 //DW0.RegisterPollMode                             = REGISTER_POLL_MODE_REGISTERPOLL;
1863                 //DW0.IndirectSemaphoreDataDword                   = INDIRECT_SEMAPHORE_DATA_DWORD_UNNAMED0;
1864                 //DW0.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
1865                 //DW0.MemoryType                                   = MEMORY_TYPE_PERPROCESSGRAPHICSADDRESS;
1866                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MISEMAPHOREWAIT;
1867                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
1868 
1869                 DW1.Value = 0x00000000;
1870 
1871                 DW2_3.Value[0] = DW2_3.Value[1] = 0x00000000;
1872 
1873                 DW4.Value = 0x00000000;
1874             }
1875 
1876             static const size_t dwSize   = 5;
1877             static const size_t byteSize = 20;
1878         };
1879 
1880         //!
1881         //! \brief MI_CONDITIONAL_BATCH_BUFFER_END
1882         //! \details
1883         //!     The MI_CONDITIONAL_BATCH_BUFFER_END command is used to conditionally
1884         //!     terminate the execution of commands stored in a batch buffer initiated
1885         //!     using a MI_BATCH_BUFFER_START command.Termination of the current level
1886         //!     of batch buffer from which MI_CONDITIONAL_BATCH_BUFFER_END is executed
1887         //!     or termination of all levels of batch buffer behavior is controlled by
1888         //!     the End Current Batch Buffer Level bit in the command header.
1889         //!
1890         //!     Any updates to the memory location exercised by this command must be
1891         //!     ensured to be coherent in memory prior to programming of this command.
1892         //!     If the memory location is being updated by a prior executed MI command
1893         //!     (ex: MI_STORE_REGISTER_MEM ..etc) on the same engine, SW must follow one
1894         //!     of the below programming note prior to programming of this command to
1895         //!     ensure data is coherent in memory.
1896         //!
1897         //!     Option1: Programming of "4" dummy MI_STORE_DATA_IMM (write to scratch
1898         //!     space) commands prior to programming of this command. Example:
1899         //!     MI_STORE_REGISTE_MEM (0x2288, 0x2CF0_0000)   MI_STORE_DATA_IMM (4 times)
1900         //!     (Dummy data, Scratch Address)
1901         //!     MI_CONDITIONAL_BATCH_BUFFER_END(0x2CF0_0000)
1902         //!
1903         //!     Option2: Programming of a PIPE_CONTROL with Post-Sync Operation selected
1904         //!     to Write Immediate Data to scratch space address with Command Streamer
1905         //!     Stall Enable set prior to programming of this command. Example:
1906         //!     MI_STORE_REGISTE_MEM (0x2288, 0x2CF0_0000)   PIPE_CONTROL (Stall, Write
1907         //!     Immediate Data), MI_CONDITIONAL_BATCH_BUFFER_END(0x2CF0_0000)
1908         //!
1909         //!     Option3: MI_ATOMIC (write to scratch space) with "CS STALL" set prior to
1910         //!     programming of this command. Example: MI_STORE_REGISTE_MEM (0x2288,
1911         //!     0x2CF0_0000)   MI_ATOMIC (MOV, Dummy data, Scratch Address),
1912         //!     MI_CONDITIONAL_BATCH_BUFFER_END(0x2CF0_0000)
1913         //!
1914         struct MI_CONDITIONAL_BATCH_BUFFER_END_CMD
1915         {
1916             union
1917             {
1918                 struct
1919                 {
1920                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                               //!< DWORD_LENGTH
1921                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 11);                                //!< Reserved
1922                     uint32_t CompareOperation : __CODEGEN_BITFIELD(12, 14);                        //!< COMPARE_OPERATION
1923                     uint32_t PredicateEnable : __CODEGEN_BITFIELD(15, 15);                         //!< Predicate Enable
1924                     uint32_t Reserved16 : __CODEGEN_BITFIELD(16, 17);                              //!< Reserved
1925                     uint32_t EndCurrentBatchBufferLevel : __CODEGEN_BITFIELD(18, 18);              //!< END_CURRENT_BATCH_BUFFER_LEVEL
1926                     uint32_t CompareMaskMode : __CODEGEN_BITFIELD(19, 19);                         //!< COMPARE_MASK_MODE
1927                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 20);                              //!< Reserved20
1928                     uint32_t CompareSemaphore : __CODEGEN_BITFIELD(21, 21);                        //!< COMPARE_SEMAPHORE
1929                     uint32_t UseGlobalGtt : __CODEGEN_BITFIELD(22, 22);                            //!< USE_GLOBAL_GTT
1930                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);                         //!< MI_COMMAND_OPCODE
1931                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                             //!< COMMAND_TYPE
1932                 };
1933                 uint32_t Value;
1934             } DW0;
1935             union
1936             {
1937                 struct
1938                 {
1939                     uint32_t CompareDataDword;  //!< Compare Data Dword
1940                 };
1941                 uint32_t Value;
1942             } DW1;
1943             union
1944             {
1945                 struct
1946                 {
1947                     uint64_t Reserved64 : __CODEGEN_BITFIELD(0, 2);       //!< Reserved
1948                     uint64_t CompareAddress : __CODEGEN_BITFIELD(3, 63);  //!< Compare Address
1949                 };
1950                 uint32_t Value[2];
1951             } DW2_3;
1952 
1953             //! \name Local enumerations
1954 
1955             //! \brief COMPARE_OPERATION
1956             //! \details
1957             //!     This field specifies the operation that will be executed to create
1958             //!     the result that will either allow to continue or terminate the batch
1959             //!     buffer.
1960             //!       />
1961             //!       MAD = Memory Address Data Dword
1962             //!       IDD  =Inline Data Dword
1963             enum COMPARE_OPERATION
1964             {
1965                 COMPARE_OPERATION_MADGREATERTHANIDD        = 0,  //!< If Indirect fetched data is greater than inline data then continue.
1966                 COMPARE_OPERATION_MADGREATERTHANOREQUALIDD = 1,  //!< If Indirect fetched data is greater than or equal to inline data then continue.
1967                 COMPARE_OPERATION_MADLESSTHANIDD           = 2,  //!< If Indirect fetched data is less than inline data then continue.
1968                 COMPARE_OPERATION_MADLESSTHANOREQUALIDD    = 3,  //!< If Indirect fetched data is less than or equal to inline data then continue.
1969                 COMPARE_OPERATION_MADEQUALIDD              = 4,  //!< If Indirect fetched data is equal to inline data then continue.
1970                 COMPARE_OPERATION_MADNOTEQUALIDD           = 5,  //!< If Indirect fetched data is not equal to inline data then continue.
1971             };
1972 
1973             //! \brief END_CURRENT_BATCH_BUFFER_LEVEL
1974             //! \details
1975             //!     This field specifies if the current level of the batch buffer execution
1976             //!     must or the complete batch (including parent) buffer execution must be
1977             //!     terminated on compare operation evaluating false.
1978             enum END_CURRENT_BATCH_BUFFER_LEVEL
1979             {
1980                 END_CURRENT_BATCH_BUFFER_LEVEL_UNNAMED0 = 0,  //!< Execution of the command result in termination of all levels of batch buffer and command execution returns to the ring buffer.
1981                 END_CURRENT_BATCH_BUFFER_LEVEL_UNNAMED1 = 1,  //!< Execution of the command results in terminating the batch buffer level from which this command has been executed and command execution returns to the previous/parent batch buffer.Ex:when executed from a first level batch buffer, execution of batch buffer is terminated and the command execution resumes to the ring buffer. This is similar to as if MI_BATCH_BUFFER_END command was executed from first level batch buffer.when executed from a second level batch buffer, execution of second level batch buffer is terminated and the command execution resumes to the first level batch buffer. This is similar to as if MI_BATCH_BUFFER_END command was executed from second level batch buffer.when executed from a third level batch buffer (if supported), execution of third level batch buffer is terminated and the command execution resumes to the second level batch buffer. This is similar to as if MI_BATCH_BUFFER_END command was executed from third level batch buffer.
1982             };
1983 
1984             //! \brief COMPARE_MASK_MODE
1985             //! \details
1986             //!     When "Compare Mask Mode" is enabled, "Compare Address" must be qword
1987             //!     aligned.
1988             enum COMPARE_MASK_MODE
1989             {
1990                 COMPARE_MASK_MODE_COMPAREMASKMODEDISABLED = 0,  //!< Compare address points to Dword in memory consisting of Data Dword(DW0). HW will compare Data Dword(DW0) against Semaphore Data Dword.
1991                 COMPARE_MASK_MODE_COMPAREMASKMODEENABLED  = 1,  //!< Compare address points to Qword in memory consisting of compare Mask (DW0) and Data Dword(DW1). HW will do AND operation on Mask(DW0) with Data Dword(DW1) and then compare the result against Semaphore Data Dword.
1992             };
1993 
1994             //! \brief COMPARE_BUFFER_ENC_MEMORY_READ_ENABLE
1995             //! \details
1996             //!     If set, the read to memory for the comparison value will be from
1997             //!     enc memory. Otherwise the fetch is made from non-enc memory.
1998             enum COMPARE_BUFFER_ENC_MEMORY_READ_ENABLE
1999             {
2000                 COMPARE_BUFFER_ENC_MEMORY_READ_ENABLE_UNNAMED0 = 0,  //!< No additional details
2001             };
2002 
2003             //! \brief COMPARE_SEMAPHORE
2004             //! \details
2005             //!     This bit provides a means to enable or disable compare operation.
2006             enum COMPARE_SEMAPHORE
2007             {
2008                 COMPARE_SEMAPHORE_UNNAMED0 = 0,  //!< This command will be treated as NOOP and usual batch buffer execution flow continues.
2009                 COMPARE_SEMAPHORE_UNNAMED1 = 1,  //!< The data from the Compare Data Dword (inline) is compared to the data in memory pointed by the Compare Address as per the Compare Operation. Based on the outcome of the compare operation it may result in either continue execution of the batch buffer or it may result in termination of the batch buffer.
2010             };
2011 
2012             //! \brief USE_GLOBAL_GTT
2013             //! \details
2014             //!     If set, this command will use the global GTT to translate the Compare
2015             //!     Address and this command must be executing from a privileged
2016             //!     (secure) batch buffer. If clear, the PPGTT will be used to translate the
2017             //!     Compare Address.
2018             enum USE_GLOBAL_GTT
2019             {
2020                 USE_GLOBAL_GTT_UNNAMED0 = 0,  //!< No additional details
2021             };
2022 
2023             enum MI_COMMAND_OPCODE
2024             {
2025                 MI_COMMAND_OPCODE_MICONDITIONALBATCHBUFFEREND = 54,  //!< No additional details
2026             };
2027 
2028             enum COMMAND_TYPE
2029             {
2030                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
2031             };
2032 
2033             //! \name Initializations
2034 
2035             //! \brief Explicit member initialization function
MI_CONDITIONAL_BATCH_BUFFER_END_CMDCmd::MI_CONDITIONAL_BATCH_BUFFER_END_CMD2036             MI_CONDITIONAL_BATCH_BUFFER_END_CMD()
2037             {
2038                 DW0.Value = 0x1b000002;
2039                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2040                 //DW0.CompareOperation                             = COMPARE_OPERATION_MADGREATERTHANIDD;
2041                 //DW0.EndCurrentBatchBufferLevel                   = END_CURRENT_BATCH_BUFFER_LEVEL_UNNAMED0;
2042                 //DW0.CompareMaskMode                              = COMPARE_MASK_MODE_COMPAREMASKMODEDISABLED;
2043                 //DW0.CompareBufferEncMemoryReadEnable             = COMPARE_BUFFER_ENC_MEMORY_READ_ENABLE_UNNAMED0;
2044                 //DW0.CompareSemaphore                             = COMPARE_SEMAPHORE_UNNAMED0;
2045                 //DW0.UseGlobalGtt                                 = USE_GLOBAL_GTT_UNNAMED0;
2046                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MICONDITIONALBATCHBUFFEREND;
2047                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
2048 
2049                 DW1.Value = 0x00000000;
2050 
2051                 DW2_3.Value[0] = DW2_3.Value[1] = 0x00000000;
2052             }
2053 
2054             static const size_t dwSize   = 4;
2055             static const size_t byteSize = 16;
2056         };
2057 
2058         //!
2059         //! \brief MI_ATOMIC
2060         //! \details
2061         //!     MI_ATOMIC is used to carry atomic operation on data in graphics memory.
2062         //!     Atomic operations are supported on data granularity of 4B, 8B and 16B.
2063         //!     The atomic operation leads to a read-modify-write operation on the data
2064         //!     in graphics memory with the option of returning value. The data in
2065         //!     graphics memory is modified by doing arithmetic and logical operation
2066         //!     with the inline/indirect data provided with the MI_ATOMIC command.
2067         //!     Inline/Indirect provided in the command can be one or two operands based
2068         //!     on the atomic operation. Ex: Atomic-Compare operation needs two operands
2069         //!     while Atomic-Add operation needs single operand and Atomic-increment
2070         //!     requires no operand. Refer "Atomics" sub-section of "L3 Cache and URB"
2071         //!     section for detailed atomic operations supported. Atomic
2072         //!     operations can be enabled to return value by setting "Return Data
2073         //!     Control" field in the command, return data is stored to CS_GPR
2074         //!     registers.
2075         //!       CS_GPR4/5 registers are updated with memory Return Data based on the
2076         //!     "Data Size". Each GPR register is qword in size and occupies two MMIO
2077         //!     registers.
2078         //!       Note: Any references to CS_GPR registers in the command should be
2079         //!     understood as the CS_GPR registers belonging to the corresponding
2080         //!     engines *CS_GPR registers.
2081         //!
2082         //!     Indirect Source Operands:
2083         //!
2084         //!       Operand1 is sourced from [CS_GPR1, CS_GPR0]
2085         //!       Operand2 is sourced from [CS_GPR3, CS_GPR2]
2086         //!       Read return Data is stored in [CS_GPR_5, CS_GPR4]
2087         //!
2088         //!     When "Data Size" is DWORD lower dword of CS_GPR4 (Qword) is updated with
2089         //!     the dword data returned from memory. When "Data Size" is QWORD only
2090         //!     CS_GPR4 (Qword) is updated with the qword data returned from memory.
2091         //!     When the data size is OCTWORD CS_GPR4/5 are updated with the OCTWORD
2092         //!     data returned from memory. CS_GPR4 is loaded with lower qword returned
2093         //!     from memory and CS_GPR5 is loaded with upper qword returned from memory.
2094         //!
2095         //!     When Inline Data mode is not set, Dwords 3..10 must not be included as
2096         //!     part of the command. Dword Length field in the header must be programmed
2097         //!     accordingly.
2098         //!
2099         //!     When Inline Data Mode is set, Dwords3..10 must be included based on the
2100         //!     Data Size field of the header. Both Operand-1 and Operand-2 dwords must
2101         //!     be programmed based on the Data Size field. Operand-2 must be programmed
2102         //!     to 0x0 if the atomic operation doesn't require it. Dword Length field in
2103         //!     the header must be programmed accordingly.
2104         //!
2105         struct MI_ATOMIC_CMD
2106         {
2107             union
2108             {
2109                 struct
2110                 {
2111                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);          //!< DWORD_LENGTH
2112                     uint32_t AtomicOpcode : __CODEGEN_BITFIELD(8, 15);        //!< ATOMIC OPCODE
2113                     uint32_t ReturnDataControl : __CODEGEN_BITFIELD(16, 16);  //!< Return Data Control
2114                     uint32_t CsStall : __CODEGEN_BITFIELD(17, 17);            //!< CS STALL
2115                     uint32_t InlineData : __CODEGEN_BITFIELD(18, 18);         //!< Inline Data
2116                     uint32_t DataSize : __CODEGEN_BITFIELD(19, 20);           //!< DATA_SIZE
2117                     uint32_t PostSyncOperation : __CODEGEN_BITFIELD(21, 21);  //!< POST_SYNC_OPERATION
2118                     uint32_t MemoryType : __CODEGEN_BITFIELD(22, 22);         //!< MEMORY_TYPE
2119                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);    //!< MI_COMMAND_OPCODE
2120                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);        //!< COMMAND_TYPE
2121                 };
2122                 uint32_t Value;
2123             } DW0;
2124             union
2125             {
2126                 struct
2127                 {
2128                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(0, 0);  //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2129                     uint32_t Reserved33 : __CODEGEN_BITFIELD(1, 1);                       //!< Reserved
2130                     uint32_t MemoryAddress : __CODEGEN_BITFIELD(2, 31);                   //!< Memory Address
2131                 };
2132                 uint32_t Value;
2133             } DW1;
2134             union
2135             {
2136                 struct
2137                 {
2138                     uint32_t MemoryAddressHigh : __CODEGEN_BITFIELD(0, 15);  //!< Memory Address High
2139                     uint32_t Reserved80 : __CODEGEN_BITFIELD(16, 31);        //!< Reserved
2140                 };
2141                 uint32_t Value;
2142             } DW2;
2143             union
2144             {
2145                 struct
2146                 {
2147                     uint32_t Operand1DataDword0;  //!< Operand1 Data Dword 0
2148                 };
2149                 uint32_t Value;
2150             } DW3;
2151             union
2152             {
2153                 struct
2154                 {
2155                     uint32_t Operand2DataDword0;  //!< Operand2 Data Dword 0
2156                 };
2157                 uint32_t Value;
2158             } DW4;
2159             union
2160             {
2161                 struct
2162                 {
2163                     uint32_t Operand1DataDword1;  //!< Operand1 Data Dword 1
2164                 };
2165                 uint32_t Value;
2166             } DW5;
2167             union
2168             {
2169                 struct
2170                 {
2171                     uint32_t Operand2DataDword1;  //!< Operand2 Data Dword 1
2172                 };
2173                 uint32_t Value;
2174             } DW6;
2175             union
2176             {
2177                 struct
2178                 {
2179                     uint32_t Operand1DataDword2;  //!< Operand1 Data Dword 2
2180                 };
2181                 uint32_t Value;
2182             } DW7;
2183             union
2184             {
2185                 struct
2186                 {
2187                     uint32_t Operand2DataDword2;  //!< Operand2 Data Dword 2
2188                 };
2189                 uint32_t Value;
2190             } DW8;
2191             union
2192             {
2193                 struct
2194                 {
2195                     uint32_t Operand1DataDword3;  //!< Operand1 Data Dword 3
2196                 };
2197                 uint32_t Value;
2198             } DW9;
2199             union
2200             {
2201                 struct
2202                 {
2203                     uint32_t Operand2DataDword3;  //!< Operand2 Data Dword 3
2204                 };
2205                 uint32_t Value;
2206             } DW10;
2207 
2208             //! \name Local enumerations
2209 
2210             //! \brief DATA_SIZE
2211             //! \details
2212             //!     This field indicates the size of the operand in dword/qword/octword on
2213             //!     which atomic operation will be performed. Data size must match with the
2214             //!     Atomic Opcode. Operation Data size could be 4B, 8B or 16B
2215             enum DATA_SIZE
2216             {
2217                 DATA_SIZE_DWORD   = 0,  //!< Operand size used by Atomic Operation is DWORD.
2218                 DATA_SIZE_QWORD   = 1,  //!< Operand Size used by Atomic Operation is QWORD.
2219                 DATA_SIZE_OCTWORD = 2,  //!< Operand Size used by Atomic Operation is OCTWORD.
2220             };
2221 
2222             //! \brief POST_SYNC_OPERATION
2223             //! \details
2224             //!     Any desired pipeline flush operation can be achieved by programming
2225             //!     PIPE_CONTROL command prior to this command.
2226             enum POST_SYNC_OPERATION
2227             {
2228                 POST_SYNC_OPERATION_NOPOSTSYNCOPERATION = 0,  //!< Command is executed as usual.
2229                 POST_SYNC_OPERATION_POSTSYNCOPERATION   = 1,  //!< MI_ATOMIC command is executed as a pipelined PIPE_CONTROL flush command with Atomics operation as post sync operation. Flush completion only guarantees the workload prior to this command is pushed till Windower unit and completion of any outstanding flushes issued prior to this command.When this bit set following restiriciton apply to atomic operation:Non-Compare atomic operations are supported on data granularity of 4B and 8B. DW3 is the lower dword of the operand and DW4 is the upper dword of the operand for the atomic operation.Compare atomic operations are supported on data granularity of 4B. DW3 is Operand-0 and DW4 is Operand-1 for the atomic operation.Atomic operations to GGTT/PPGTT memory surface are supported.Only Inline data mode for atomic operand is supported, no support for indirect data mode.No support for Return Data Control functionality.No support for atomic operations on data granularity of 16B.No support for compare atomic operations on data granularity of 8B.
2230             };
2231 
2232             //! \brief MEMORY_TYPE
2233             //! \details
2234             //!     This bit will be ignored and treated as if clear when executing from a
2235             //!     non-privileged batch buffer. It is allowed for this bit to be clear when
2236             //!     executing this command from a privileged (secure) batch buffer. This bit
2237             //!     must be 1 if the Per Process GTT Enable bit is clear.
2238             enum MEMORY_TYPE
2239             {
2240                 MEMORY_TYPE_PERPROCESSGRAPHICSADDRESS = 0,  //!< No additional details
2241                 MEMORY_TYPE_GLOBALGRAPHICSADDRESS     = 1,  //!< This command will use the global GTT to translate the Address and this command must be executing from a privileged (secure) batch buffer.
2242             };
2243 
2244             enum MI_COMMAND_OPCODE
2245             {
2246                 MI_COMMAND_OPCODE_MIATOMIC = 47,  //!< No additional details
2247             };
2248 
2249             enum COMMAND_TYPE
2250             {
2251                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
2252             };
2253 
2254             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2255             //! \details
2256             //!     This bit controls the memory write address computation for the atomic operation.
2257             //!     The final memory write address is computed by adding the Workload PartitionID
2258             //!     times the Address Offset to the memory address mentioned in the command.
2259             //!
2260             //!      Workload Partition ID gets programmed through
2261             //!     WPARIDregister and the Address Offset gets programmed through
2262             //!     CS_MI_ADDRESS_OFFSET register..
2263             //!      Example: Final Memory Write Address[47:2] = (Workload Partition ID
2264             //!      * "Address Offset") + Memory Write Address [47:2]
2265             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2266             {
2267                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!< There is no offset added to the memory write address.
2268                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!< The final memory address is computed based on the Workload Partition ID
2269             };
2270 
2271             //! \name Initializations
2272 
2273             //! \brief Explicit member initialization function
MI_ATOMIC_CMDCmd::MI_ATOMIC_CMD2274             MI_ATOMIC_CMD()
2275             {
2276                 DW0.Value = 0x17800009;
2277                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2278                 //DW0.AtomicOpcode                                 = 0;
2279                 //DW0.DataSize                                     = DATA_SIZE_DWORD;
2280                 //DW0.PostSyncOperation                            = POST_SYNC_OPERATION_NOPOSTSYNCOPERATION;
2281                 //DW0.MemoryType                                   = MEMORY_TYPE_PERPROCESSGRAPHICSADDRESS;
2282                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIATOMIC;
2283                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
2284 
2285                 DW1.Value = 0x00000000;
2286                 //DW1.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
2287 
2288                 DW2.Value = 0x00000000;
2289 
2290                 DW3.Value = 0x00000000;
2291 
2292                 DW4.Value = 0x00000000;
2293 
2294                 DW5.Value = 0x00000000;
2295 
2296                 DW6.Value = 0x00000000;
2297 
2298                 DW7.Value = 0x00000000;
2299 
2300                 DW8.Value = 0x00000000;
2301 
2302                 DW9.Value = 0x00000000;
2303 
2304                 DW10.Value = 0x00000000;
2305             }
2306 
2307             static const size_t dwSize   = 11;
2308             static const size_t byteSize = 44;
2309         };
2310         //!
2311         //! \brief MI_MATH
2312         //! \details
2313         //!     The MI_MATH command allows SW to send instruction to ALU in Any Command
2314         //!     Streamer.
2315         //!     MI_MATH command is the means by which ALU can be accessed. ALU
2316         //!     instructions form the data payload of MI_MATH command, ALU instruction
2317         //!     is dword in size. MI_MATH Dword Length should be programmed based on the
2318         //!     number of ALU instruction packed, max number is limited by the max Dword
2319         //!     Length supported. When MI_MATH command is parsed by command streamer it
2320         //!     outputs the payload dwords (ALU instructions) to the ALU. ALU takes
2321         //!     single clock to process any given instruction. Refer to "Command
2322         //!     Streamer (CS) ALU Programming" section in Command Streamer Programming.
2323         //!
2324         struct MI_MATH_CMD
2325         {
2326             union
2327             {
2328                 struct
2329                 {
2330                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                //!< DWord Length
2331                     uint32_t MemoryObjectControlState : __CODEGEN_BITFIELD(8, 14);  //!< Memory Object Control State
2332                     uint32_t PredicationEnable : __CODEGEN_BITFIELD(15, 15);        //!< Predication Enable
2333                     uint32_t Reserved16 : __CODEGEN_BITFIELD(16, 22);               //!< Reserved
2334                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);          //!< MI_COMMAND_OPCODE
2335                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);              //!< COMMAND_TYPE
2336                 };
2337                 uint32_t Value;
2338             } DW0;
2339 
2340             //! \name Local enumerations
2341 
2342             enum MI_COMMAND_OPCODE
2343             {
2344                 MI_COMMAND_OPCODE_MIMATH = 26,  //!< No additional details
2345             };
2346 
2347             enum COMMAND_TYPE
2348             {
2349                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
2350             };
2351 
2352             //! \name Initializations
2353 
2354             //! \brief Explicit member initialization function
MI_MATH_CMDCmd::MI_MATH_CMD2355             MI_MATH_CMD()
2356             {
2357                 DW0.Value = 0x0d000000;
2358                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIMATH;
2359                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
2360             }
2361 
2362             static const size_t dwSize   = 1;
2363             static const size_t byteSize = 4;
2364         };
2365 
2366         //!
2367         //! \brief MI_FLUSH_DW
2368         //! \details
2369         //!     The MI_FLUSH_DW command is used to perform an internal "flush"
2370         //!     operation. The parser pauses on an internal flush until all drawing
2371         //!     engines have completed any pending operations. In addition, this command
2372         //!     can also be used to:Flush any dirty data to memory. Invalidate the TLB
2373         //!     cache inside the hardware Usage note: After this command is completed
2374         //!     with a Store DWord enabled, CPU access to graphics memory will be
2375         //!     coherent (assuming the Render Cache flush is not inhibited).
2376         //!
2377         struct MI_FLUSH_DW_CMD
2378         {
2379             union
2380             {
2381                 //!< DWORD 0
2382                 struct
2383                 {
2384                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 5);                   //!< DWORD_LENGTH
2385                     uint32_t Reserved6 : __CODEGEN_BITFIELD(6, 6);                     //!< Reserved
2386                     uint32_t VideoPipelineCacheInvalidate : __CODEGEN_BITFIELD(7, 7);  //!< Video Pipeline Cache invalidate
2387                     uint32_t NotifyEnable : __CODEGEN_BITFIELD(8, 8);                  //!< Notify Enable
2388                     uint32_t FlushLlc : __CODEGEN_BITFIELD(9, 9);                      //!< Flush LLC
2389                     uint32_t Reserved10 : __CODEGEN_BITFIELD(10, 13);                  //!< Reserved
2390                     uint32_t PostSyncOperation : __CODEGEN_BITFIELD(14, 15);           //!< POST_SYNC_OPERATION
2391                     uint32_t FlushCcs : __CODEGEN_BITFIELD(16, 16);                    //!< Flush CCS
2392                     uint32_t Reserved17 : __CODEGEN_BITFIELD(17, 17);                  //!< Reserved
2393                     uint32_t TlbInvalidate : __CODEGEN_BITFIELD(18, 18);               //!< TLB Invalidate
2394                     uint32_t FlushPpc : __CODEGEN_BITFIELD(19, 19);                    //!< Flush PPC
2395                     uint32_t Reserved20 : __CODEGEN_BITFIELD(20, 20);                  //!< Reserved
2396                     uint32_t StoreDataIndex : __CODEGEN_BITFIELD(21, 21);              //!< Store Data Index
2397                     uint32_t Reserved22 : __CODEGEN_BITFIELD(22, 22);                  //!< Reserved
2398                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);             //!< MI_COMMAND_OPCODE
2399                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                 //!< COMMAND_TYPE
2400                 };
2401                 uint32_t Value;
2402             } DW0;
2403             union
2404             {
2405                 //!< DWORD 1..2
2406                 struct
2407                 {
2408                 uint64_t                 Reserved32                                       : __CODEGEN_BITFIELD( 0,  1)    ; //!< Reserved
2409                 uint64_t                 DestinationAddressType                           : __CODEGEN_BITFIELD( 2,  2)    ; //!< DESTINATION_ADDRESS_TYPE
2410                 uint64_t                 DestinationAddress                               : __CODEGEN_BITFIELD( 3, 47)    ; //!< Destination Address
2411                 uint64_t                 Reserved80                                       : __CODEGEN_BITFIELD(48, 63)    ; //!< Reserved
2412                 };
2413                 uint32_t Value[2];
2414             } DW1_2;
2415             union
2416             {
2417                 //!< DWORD 3..4
2418                 struct
2419                 {
2420                     uint64_t ImmediateData;  //!< Immediate Data
2421                 };
2422                 uint32_t Value[2];
2423             } DW3_4;
2424 
2425             //! \name Local enumerations
2426 
2427             //! \brief POST_SYNC_OPERATION
2428             //! \details
2429             //!     BitFieldDesc
2430             enum POST_SYNC_OPERATION
2431             {
2432                 POST_SYNC_OPERATION_NOWRITE            = 0,  //!< No write occurs as a result of this instruction. This can be used to implement a "trap" operation, etc.
2433                 POST_SYNC_OPERATION_WRITEIMMEDIATEDATA = 1,  //!< HW implicitly detects the Data size to be Qword or Dword to be written to memory based on the command dword length programmed  . When Dword Length indicates Qword, Writes the QWord containing Immediate Data Low, High DWs to the Destination Address . When Dword Length indicates Dword, Writes the DWord containing Immediate Data Low to the Destination Address
2434                 POST_SYNC_OPERATION_UNNAMED3           = 3,  //!< Write the TIMESTAMP register to the Destination Address. The upper 28 bits of the TIMESTAMP register are tied to '0'.
2435             };
2436 
2437             enum MI_COMMAND_OPCODE
2438             {
2439                 MI_COMMAND_OPCODE_MIFLUSHDW = 38,  //!< No additional details
2440             };
2441 
2442             enum COMMAND_TYPE
2443             {
2444                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
2445             };
2446 
2447             //! \brief DESTINATION_ADDRESS_TYPE
2448             //! \details
2449             //!     Defines address space of Destination Address
2450             enum DESTINATION_ADDRESS_TYPE
2451             {
2452                 DESTINATION_ADDRESS_TYPE_PPGTT = 0,  //!< Use PPGTT address space for DW write
2453                 DESTINATION_ADDRESS_TYPE_GGTT  = 1,  //!< Use GGTT address space for DW write
2454             };
2455 
2456             //! \name Initializations
2457 
2458             //! \brief Explicit member initialization function
MI_FLUSH_DW_CMDCmd::MI_FLUSH_DW_CMD2459             MI_FLUSH_DW_CMD()
2460             {
2461                 DW0.Value = 0x13000003;
2462                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2463                 //DW0.PostSyncOperation                            = POST_SYNC_OPERATION_NOWRITE;
2464                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIFLUSHDW;
2465                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
2466 
2467                 DW1_2.Value[0] = DW1_2.Value[1] = 0;
2468                 DW1_2.DestinationAddressType = DESTINATION_ADDRESS_TYPE_PPGTT;
2469 
2470                 DW3_4.Value[0] = DW3_4.Value[1] = 0x00000000;
2471             }
2472 
2473             static const size_t dwSize   = 5;
2474             static const size_t byteSize = 20;
2475         };
2476 
2477         //!
2478         //! \brief MI_FORCE_WAKEUP
2479         //! \details
2480         //!     This command is used to communicate Force Wakeup request to PM unit. No
2481         //!     functionality is performed by this command when none of the mask bits
2482         //!     are set and is equivalent to NOOP. Example for usage model: VCS Ring
2483         //!     Buffer: MI_FORCE_WAKEUP (Force Render Awake set to '1')
2484         //!     MI_SEMPAHORE_SIGNAL (Signal context id 0xABC to Render Command Streamer)
2485         //!     MI_FORCE_WAKEUP (Force Render Awake set to '0') MI_BATCH_BUFFER_START
2486         //!     STATE Commands .. .. MI_FORCE_WAKEUP (Force Render Awake set to '1')
2487         //!     MI_LOAD_REGISTER_IMMEDIATE (Load register 0x23XX in render command
2488         //!     streamer with data 0xFFF) MI_FORCE_WAKEUP (Force Render Awake set to
2489         //!     '0') .. MI_BATCH_BUFFER_END
2490         //!
2491         //!     This command must not be programmed in the command stream for Render
2492         //!     Engine Command Streamer or Position Commmand Streamer or Compute Engine
2493         //!     Command Streamer.
2494         //!
2495         struct MI_FORCE_WAKEUP_CMD
2496         {
2497             union
2498             {
2499                 struct
2500                 {
2501                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);        //!< DWORD_LENGTH
2502                     uint32_t Reserved8 : __CODEGEN_BITFIELD(8, 22);         //!< Reserved
2503                     uint32_t MiCommandOpcode : __CODEGEN_BITFIELD(23, 28);  //!< MI_COMMAND_OPCODE
2504                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);      //!< COMMAND_TYPE
2505                 };
2506                 uint32_t Value;
2507             } DW0;
2508             union
2509             {
2510                 struct
2511                 {
2512                     uint32_t ForceMediaSlice0Awake : __CODEGEN_BITFIELD(0, 0);  //!< Force Media-Slice0 Awake
2513                     uint32_t ForceRenderAwake : __CODEGEN_BITFIELD(1, 1);       //!< Force Render Awake
2514                     uint32_t ForceMediaSlice1Awake : __CODEGEN_BITFIELD(2, 2);  //!< Force Media-Slice1 Awake
2515                     uint32_t ForceMediaSlice2Awake : __CODEGEN_BITFIELD(3, 3);  //!< Force Media-Slice2 Awake
2516                     uint32_t ForceMediaSlice3Awake : __CODEGEN_BITFIELD(4, 4);  //!< Force Media-Slice3 Awake
2517                     uint32_t Reserved37 : __CODEGEN_BITFIELD(5, 7);             //!< Reserved
2518                     uint32_t HevcPowerWellControl : __CODEGEN_BITFIELD(8, 8);   //!< HEVC_POWER_WELL_CONTROL
2519                     uint32_t MfxPowerWellControl : __CODEGEN_BITFIELD(9, 9);    //!< MFX_POWER_WELL_CONTROL
2520                     uint32_t Reserved42 : __CODEGEN_BITFIELD(10, 15);           //!< Reserved
2521                     uint32_t MaskBits : __CODEGEN_BITFIELD(16, 31);             //!< Mask Bits
2522                 };
2523                 uint32_t Value;
2524             } DW1;
2525 
2526             //! \name Local enumerations
2527 
2528             enum MI_COMMAND_OPCODE
2529             {
2530                 MI_COMMAND_OPCODE_MIFORCEWAKEUP = 29,  //!< No additional details
2531             };
2532 
2533             enum COMMAND_TYPE
2534             {
2535                 COMMAND_TYPE_MICOMMAND = 0,  //!< No additional details
2536             };
2537 
2538             //! \brief HEVC_POWER_WELL_CONTROL
2539             //! \details
2540             //!     This Bit controls whether or not the HEVC Power Well is powered.  When
2541             //!     this bit is unmasked, all force awake bits programming are ignored.
2542             enum HEVC_POWER_WELL_CONTROL
2543             {
2544                 HEVC_POWER_WELL_CONTROL_DISABLEPOWERWELL = 0,  //!< No additional details
2545                 HEVC_POWER_WELL_CONTROL_ENABLEPOWERWELL  = 1,  //!< No additional details
2546             };
2547 
2548             //! \brief MFX_POWER_WELL_CONTROL
2549             //! \details
2550             //!     This Bit controls whether or not the MFX Power Well is powered.  When
2551             //!     this bit is unmasked, all force awake bits programming are ignored.
2552             enum MFX_POWER_WELL_CONTROL
2553             {
2554                 MFX_POWER_WELL_CONTROL_DISABLEPOWERWELL = 0,  //!< No additional details
2555                 MFX_POWER_WELL_CONTROL_ENABLEPOWERWELL  = 1,  //!< No additional details
2556             };
2557 
2558             //! \name Initializations
2559 
2560             //! \brief Explicit member initialization function
MI_FORCE_WAKEUP_CMDCmd::MI_FORCE_WAKEUP_CMD2561             MI_FORCE_WAKEUP_CMD()
2562             {
2563                 DW0.Value = 0x0e800000;
2564                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2565                 //DW0.MiCommandOpcode                              = MI_COMMAND_OPCODE_MIFORCEWAKEUP;
2566                 //DW0.CommandType                                  = COMMAND_TYPE_MICOMMAND;
2567 
2568                 DW1.Value = 0x00000000;
2569                 //DW1.HevcPowerWellControl                         = HEVC_POWER_WELL_CONTROL_DISABLEPOWERWELL;
2570                 //DW1.MfxPowerWellControl                          = MFX_POWER_WELL_CONTROL_DISABLEPOWERWELL;
2571             }
2572 
2573             static const size_t dwSize   = 2;
2574             static const size_t byteSize = 8;
2575         };
2576 
2577         //!
2578         //! \brief PIPE_CONTROL
2579         //! \details
2580         //!     The PIPE_CONTROL command is used to effect the synchronization described
2581         //!     above.
2582         //!
2583         //!     SW must follow below programming restrictions when programming
2584         //!     PIPE_CONTROL command for ComputeCS:
2585         //!       "Command Streamer Stall Enable" must be always set.
2586         //!     Post Sync Operations must not be set to Write PS Depth Count
2587         //!     Following bits must not be set when programmed for ComputeCS"Render
2588         //!     Target Cache Flush Enable", "Depth Cache Flush Enable" and "Tile Cache
2589         //!     Flush Enable"
2590         //!     "Depth Stall Enable", Stall at Pixel Scoreboard and "PSD Sync Enable".
2591         //!     "OVR Tile 0 Flush", "TBIMR Force Batch Closure", "AMFS Flush Enable" "VF
2592         //!     Cache Invalidation Enable" and "Global Snapshot Count Reset".
2593         //!
2594         struct PIPE_CONTROL_CMD
2595         {
2596             union
2597             {
2598                 struct
2599                 {
2600                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 7);                          //!< DWORD_LENGTH
2601                     uint32_t PredicateEnable : __CODEGEN_BITFIELD(8, 8);                      //!< Predicate Enable
2602                     uint32_t DataportFlush : __CODEGEN_BITFIELD(9, 9);                        //!< Dataport Flush
2603                     uint32_t L3ReadOnlyCacheInvalidationEnable : __CODEGEN_BITFIELD(10, 10);  //!< L3 Read Only Cache Invalidation Enable
2604                     uint32_t UnTypedDataPortCacheFlush : __CODEGEN_BITFIELD(11, 11);          //!< Un-Typed Data-Port Cache Flush
2605                     uint32_t Reserved12 : __CODEGEN_BITFIELD(12, 12);                         //!< Reserved
2606                     uint32_t CompressionControlSurfaceCcsFlush : __CODEGEN_BITFIELD(13, 13);  //!< Compression Control Surface (CCS) Flush
2607                     uint32_t WorkloadPartitionIdOffsetEnable : __CODEGEN_BITFIELD(14, 14);    //!< WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2608                     uint32_t Reserved15 : __CODEGEN_BITFIELD(15, 15);                         //!< Reserved
2609                     uint32_t _3DCommandSubOpcode : __CODEGEN_BITFIELD(16, 23);                //!< _3D_COMMAND_SUB_OPCODE
2610                     uint32_t _3DCommandOpcode : __CODEGEN_BITFIELD(24, 26);                   //!< _3D_COMMAND_OPCODE
2611                     uint32_t CommandSubtype : __CODEGEN_BITFIELD(27, 28);                     //!< COMMAND_SUBTYPE
2612                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);                        //!< COMMAND_TYPE
2613                 };
2614                 uint32_t Value;
2615             } DW0;
2616             union
2617             {
2618                 struct
2619                 {
2620                     uint32_t DepthCacheFlushEnable : __CODEGEN_BITFIELD(0, 0);               //!< DEPTH_CACHE_FLUSH_ENABLE
2621                     uint32_t StallAtPixelScoreboard : __CODEGEN_BITFIELD(1, 1);              //!< STALL_AT_PIXEL_SCOREBOARD
2622                     uint32_t StateCacheInvalidationEnable : __CODEGEN_BITFIELD(2, 2);        //!< State Cache Invalidation Enable
2623                     uint32_t ConstantCacheInvalidationEnable : __CODEGEN_BITFIELD(3, 3);     //!< Constant Cache Invalidation Enable
2624                     uint32_t VfCacheInvalidationEnable : __CODEGEN_BITFIELD(4, 4);           //!< VF Cache Invalidation Enable
2625                     uint32_t DcFlushEnable : __CODEGEN_BITFIELD(5, 5);                       //!< DC  Flush Enable
2626                     uint32_t Reserved38 : __CODEGEN_BITFIELD(6, 6);                          //!< Reserved
2627                     uint32_t PipeControlFlushEnable : __CODEGEN_BITFIELD(7, 7);              //!< Pipe Control Flush Enable
2628                     uint32_t NotifyEnable : __CODEGEN_BITFIELD(8, 8);                        //!< Notify Enable
2629                     uint32_t IndirectStatePointersDisable : __CODEGEN_BITFIELD(9, 9);        //!< Indirect State Pointers Disable
2630                     uint32_t TextureCacheInvalidationEnable : __CODEGEN_BITFIELD(10, 10);    //!< Texture Cache Invalidation Enable
2631                     uint32_t InstructionCacheInvalidateEnable : __CODEGEN_BITFIELD(11, 11);  //!< Instruction Cache Invalidate Enable
2632                     uint32_t RenderTargetCacheFlushEnable : __CODEGEN_BITFIELD(12, 12);      //!< RENDER_TARGET_CACHE_FLUSH_ENABLE
2633                     uint32_t DepthStallEnable : __CODEGEN_BITFIELD(13, 13);                  //!< DEPTH_STALL_ENABLE
2634                     uint32_t PostSyncOperation : __CODEGEN_BITFIELD(14, 15);                 //!< POST_SYNC_OPERATION
2635                     uint32_t GenericMediaStateClear : __CODEGEN_BITFIELD(16, 16);            //!< Generic Media State Clear
2636                     uint32_t PssStallSyncEnable : __CODEGEN_BITFIELD(17, 17);                //!< PSS Stall Sync Enable
2637                     uint32_t TlbInvalidate : __CODEGEN_BITFIELD(18, 18);                     //!< TLB Invalidate
2638                     uint32_t DepthStallSyncEnable : __CODEGEN_BITFIELD(19, 19);              //!< Depth Stall Sync Enable
2639                     uint32_t CommandStreamerStallEnable : __CODEGEN_BITFIELD(20, 20);        //!< Command Streamer Stall Enable
2640                     uint32_t StoreDataIndex : __CODEGEN_BITFIELD(21, 21);                    //!< Store Data Index
2641                     uint32_t Reserved54 : __CODEGEN_BITFIELD(22, 22);                        //!< Reserved
2642                     uint32_t LriPostSyncOperation : __CODEGEN_BITFIELD(23, 23);              //!< LRI_POST_SYNC_OPERATION
2643                     uint32_t DestinationAddressType : __CODEGEN_BITFIELD(24, 24);            //!< DESTINATION_ADDRESS_TYPE
2644                     uint32_t AmfsFlushEnable : __CODEGEN_BITFIELD(25, 25);                   //!< AMFS Flush Enable
2645                     uint32_t FlushLlc : __CODEGEN_BITFIELD(26, 26);                          //!< Flush LLC
2646                     uint32_t Reserved59 : __CODEGEN_BITFIELD(27, 27);                        //!< Reserved
2647                     uint32_t TileCacheFlushEnable : __CODEGEN_BITFIELD(28, 28);              //!< TILE_CACHE_FLUSH_ENABLE
2648                     uint32_t CommandCacheInvalidateEnable : __CODEGEN_BITFIELD(29, 29);      //!< Command Cache Invalidate Enable
2649                     uint32_t L3FabricFlush : __CODEGEN_BITFIELD(30, 30);                     //!< L3_FABRIC_FLUSH
2650                     uint32_t TbimrForceBatchClosure : __CODEGEN_BITFIELD(31, 31);            //!< TBIMR_FORCE_BATCH_CLOSURE
2651                 };
2652                 uint32_t Value;
2653             } DW1;
2654             union
2655             {
2656                 struct
2657                 {
2658                     uint32_t Reserved64 : __CODEGEN_BITFIELD(0, 1);  //!< Reserved
2659                     uint32_t Address : __CODEGEN_BITFIELD(2, 31);    //!< Address
2660                 };
2661                 uint32_t Value;
2662             } DW2;
2663             union
2664             {
2665                 struct
2666                 {
2667                     uint32_t AddressHigh;  //!< Address High
2668                 };
2669                 uint32_t Value;
2670             } DW3;
2671             union
2672             {
2673                 struct
2674                 {
2675                     uint64_t ImmediateData;  //!< Immediate Data
2676                 };
2677                 uint32_t Value[2];
2678             } DW4_5;
2679 
2680             //! \name Local enumerations
2681 
2682             //! \brief WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2683             //! \details
2684             //!     This bit controls the memory write address computation for the store data update.
2685             //!     The final memory write address is computed by adding the Workload
2686             //!     Partition ID times the Address Offset to the memory address mentioned in the command.
2687             //!     Workload Partition ID gets programmed through
2688             //!     WPARIDregister and the Address Offset gets programmed through
2689             //!     CS_MI_ADDRESS_OFFSET register..
2690             //!     Example: Final Memory Write Address[47:2] = ( Workload Partition ID * "Address Offset")
2691             //!     + Memory Write Address [47:2]
2692             enum WORKLOAD_PARTITION_ID_OFFSET_ENABLE
2693             {
2694                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0 = 0,  //!<   There is no offset added to the memory write address.
2695                 WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED1 = 1,  //!<   The final memory address is computed based on the Workload Partition ID
2696             };
2697 
2698             enum _3D_COMMAND_SUB_OPCODE
2699             {
2700                 _3D_COMMAND_SUB_OPCODE_PIPECONTROL = 0,  //!< No additional details
2701             };
2702 
2703             enum _3D_COMMAND_OPCODE
2704             {
2705                 _3D_COMMAND_OPCODE_PIPECONTROL = 2,  //!< No additional details
2706             };
2707 
2708             enum COMMAND_SUBTYPE
2709             {
2710                 COMMAND_SUBTYPE_GFXPIPE3D = 3,  //!< No additional details
2711             };
2712 
2713             enum COMMAND_TYPE
2714             {
2715                 COMMAND_TYPE_GFXPIPE = 3,  //!< No additional details
2716             };
2717 
2718             //! \brief DEPTH_CACHE_FLUSH_ENABLE
2719             //! \details
2720             //!     Setting this bit enables flushing (i.e. writing back the dirty lines to
2721             //!     memory and invalidating the tags) of depth related caches. This bit
2722             //!     applies to HiZ cache, Stencil cache and depth cache.
2723             enum DEPTH_CACHE_FLUSH_ENABLE
2724             {
2725                 DEPTH_CACHE_FLUSH_ENABLE_FLUSHDISABLED = 0,  //!< Depth relates caches (HiZ, Stencil and Depth) are NOT flushed.
2726                 DEPTH_CACHE_FLUSH_ENABLE_FLUSHENABLED  = 1,  //!< Depth relates caches (HiZ, Stencil and Depth) are flushed.
2727             };
2728 
2729             //! \brief STALL_AT_PIXEL_SCOREBOARD
2730             //! \details
2731             //!     Defines the behavior of PIPE_CONTROL command at the pixel scoreboard.
2732             enum STALL_AT_PIXEL_SCOREBOARD
2733             {
2734                 STALL_AT_PIXEL_SCOREBOARD_DISABLE = 0,  //!< Stall at the pixel scoreboard is disabled.
2735                 STALL_AT_PIXEL_SCOREBOARD_ENABLE  = 1,  //!< Stall at the pixel scoreboard is enabled.
2736             };
2737 
2738             //! \brief RENDER_TARGET_CACHE_FLUSH_ENABLE
2739             //! \details
2740             //!     Setting this bit will force Render Cache to be flushed to memory
2741             //!     prior to this synchronization point completing. This bit must be set for
2742             //!     all write fence sync operations to assure that results from operations
2743             //!     initiated prior to this command are visible in memory once software
2744             //!     observes this synchronization.
2745             enum RENDER_TARGET_CACHE_FLUSH_ENABLE
2746             {
2747                 RENDER_TARGET_CACHE_FLUSH_ENABLE_DISABLEFLUSH = 0,  //!< Render Target Cache is NOT flushed.
2748                 RENDER_TARGET_CACHE_FLUSH_ENABLE_ENABLEFLUSH  = 1,  //!< Render Target Cache is flushed.
2749             };
2750 
2751             //! \brief DEPTH_STALL_ENABLE
2752             //! \details
2753             //!     This bit must be set when obtaining a "visible pixel" count to
2754             //!     preclude the possible inclusion in the PS_DEPTH_COUNT value written to
2755             //!     memory of some fraction of pixels from objects initiated after the
2756             //!     PIPE_CONTROL command.
2757             enum DEPTH_STALL_ENABLE
2758             {
2759                 DEPTH_STALL_ENABLE_DISABLE = 0,  //!< 3D pipeline will not stall subsequent primitives at the Depth Test stage.
2760                 DEPTH_STALL_ENABLE_ENABLE  = 1,  //!< 3D pipeline will stall any subsequent primitives at the Depth Test stage until the Sync and Post-Sync operations complete.
2761             };
2762 
2763             //! \brief POST_SYNC_OPERATION
2764             //! \details
2765             //!     This field specifies an optional action to be taken upon completion of
2766             //!     the synchronization operation.
2767             enum POST_SYNC_OPERATION
2768             {
2769                 POST_SYNC_OPERATION_NOWRITE            = 0,  //!< No write occurs as a result of this instruction. This can be used to implement a "trap" operation, etc.
2770                 POST_SYNC_OPERATION_WRITEIMMEDIATEDATA = 1,  //!< Write the QWord containing Immediate Data Low, High DWs to the Destination Address
2771                 POST_SYNC_OPERATION_WRITEPSDEPTHCOUNT  = 2,  //!< Write the 64-bit PS_DEPTH_COUNT register to the Destination Address
2772                 POST_SYNC_OPERATION_WRITETIMESTAMP     = 3,  //!< Write the 64-bit TIMESTAMP register(i.e. "Reported Timestamp Count" 0x2358 for render pipe) to the Destination Address.
2773             };
2774 
2775             //! \brief LRI_POST_SYNC_OPERATION
2776             //! \details
2777             //!     This bit caues a post sync operation with an LRI (Load Register
2778             //!     Immediate) operation. If this bit is set then the Post-Sync Operation
2779             //!     field must be cleared.
2780             enum LRI_POST_SYNC_OPERATION
2781             {
2782                 LRI_POST_SYNC_OPERATION_NOLRIOPERATION         = 0,  //!< No LRI operation occurs as a result of this instruction. The Post-Sync Operation field is valid and may be used to specify an operation.
2783                 LRI_POST_SYNC_OPERATION_MMIOWRITEIMMEDIATEDATA = 1,  //!< Write the DWord contained in Immediate Data Low (DW3) to the MMIO offset specified in the Address field.
2784             };
2785 
2786             //! \brief DESTINATION_ADDRESS_TYPE
2787             //! \details
2788             //!     Defines address space of Destination Address
2789             enum DESTINATION_ADDRESS_TYPE
2790             {
2791                 DESTINATION_ADDRESS_TYPE_PPGTT = 0,  //!< Use PPGTT address space for DW write
2792                 DESTINATION_ADDRESS_TYPE_GGTT  = 1,  //!< Use GGTT address space for DW write
2793             };
2794 
2795             //! \brief TILE_CACHE_FLUSH_ENABLE
2796             //! \details
2797             //!     Setting this bit will force Tile Cache (contains both color and depth
2798             //!     data) to be flushed to memory prior to this synchronization point
2799             //!     completing. This bit must be set for all write fence sync operations to
2800             //!     assure that results from operations initiated prior to this command are
2801             //!     visible in memory once software observes this synchronization.
2802             //!       />
2803             enum TILE_CACHE_FLUSH_ENABLE
2804             {
2805                 TILE_CACHE_FLUSH_ENABLE_UNNAMED0 = 0,  //!< Tile Cache is not flushed.
2806                 TILE_CACHE_FLUSH_ENABLE_UNNAMED1 = 1,  //!< Tile cache is flushed.
2807             };
2808 
2809             //! \brief L3_FABRIC_FLUSH
2810             //! \details
2811             //!     L3 Fabric Flush will ensure all the pending transactions in the L3
2812             //!     Fabric are flushed to global observation point. HW does implicit L3
2813             //!     Fabric Flush on all stalling flushes (both explicit and implicit) and on
2814             //!     PIPECONTROL having Post Sync Operation enabled. This bit provides an
2815             //!     explicit control for debug purpose.
2816             //!       />
2817             enum L3_FABRIC_FLUSH
2818             {
2819                 L3_FABRIC_FLUSH_UNNAMED0 = 0,  //!< HW will not force a "L3 Fabric Flush" on completion of flush and will only do on need basis.
2820                 L3_FABRIC_FLUSH_UNNAMED1 = 1,  //!< HW will do a L3 Fabric Flush on completion of flush for the corresponding PIPECONTROL. Setting this bit will force HW to send a marker downstream for a flush completion.
2821             };
2822 
2823             //! \brief TBIMR_FORCE_BATCH_CLOSURE
2824             //! \details
2825             //!     This bit forces SF to close the batch. This bit must be set with a post
2826             //!     sync operation.
2827             enum TBIMR_FORCE_BATCH_CLOSURE
2828             {
2829                 TBIMR_FORCE_BATCH_CLOSURE_NOBATCHCLOSURE = 0,  //!< SF will not close the batch on receiving marker.
2830                 TBIMR_FORCE_BATCH_CLOSURE_CLOSEBATCH     = 1,  //!< SF will close the batch on receiving the marker associated with this command.
2831             };
2832 
2833             //! \name Initializations
2834 
2835             //! \brief Explicit member initialization function
PIPE_CONTROL_CMDCmd::PIPE_CONTROL_CMD2836             PIPE_CONTROL_CMD()
2837             {
2838                 DW0.Value = 0x7a000004;
2839                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2840                 //DW0.WorkloadPartitionIdOffsetEnable              = WORKLOAD_PARTITION_ID_OFFSET_ENABLE_UNNAMED0;
2841                 //DW0._3DCommandSubOpcode                          = _3D_COMMAND_SUB_OPCODE_PIPECONTROL;
2842                 //DW0._3DCommandOpcode                             = _3D_COMMAND_OPCODE_PIPECONTROL;
2843                 //DW0.CommandSubtype                               = COMMAND_SUBTYPE_GFXPIPE3D;
2844                 //DW0.CommandType                                  = COMMAND_TYPE_GFXPIPE;
2845 
2846                 DW1.Value = 0x00000000;
2847                 //DW1.DepthCacheFlushEnable                        = DEPTH_CACHE_FLUSH_ENABLE_FLUSHDISABLED;
2848                 //DW1.StallAtPixelScoreboard                       = STALL_AT_PIXEL_SCOREBOARD_DISABLE;
2849                 //DW1.RenderTargetCacheFlushEnable                 = RENDER_TARGET_CACHE_FLUSH_ENABLE_DISABLEFLUSH;
2850                 //DW1.DepthStallEnable                             = DEPTH_STALL_ENABLE_DISABLE;
2851                 //DW1.PostSyncOperation                            = POST_SYNC_OPERATION_NOWRITE;
2852                 //DW1.LriPostSyncOperation                         = LRI_POST_SYNC_OPERATION_NOLRIOPERATION;
2853                 //DW1.DestinationAddressType                       = DESTINATION_ADDRESS_TYPE_PPGTT;
2854                 //DW1.TbimrForceBatchClosure                       = TBIMR_FORCE_BATCH_CLOSURE_NOBATCHCLOSURE;
2855 
2856                 DW2.Value = 0x00000000;
2857 
2858                 DW3.Value = 0x00000000;
2859 
2860                 DW4_5.Value[0] = DW4_5.Value[1] = 0x00000000;
2861             }
2862 
2863             static const size_t dwSize   = 6;
2864             static const size_t byteSize = 24;
2865         };
2866 
2867         //!
2868         //! \brief MFX_WAIT
2869         //! \details
2870         //!     This command can be considered the same as an MI_NOOPexcept that the
2871         //!     command parser will not parse the next command until the
2872         //!     followinghappens    AVC or VC1 BSD mode: The command will stall the
2873         //!     parser until completion of theBSD object
2874         //!       IT, encoder, and MPEG2 BSD mode: The command will stall the parser
2875         //!     until theobject package is sent down the pipelineThis command should be
2876         //!     used to ensure thepreemption enable window occurs during the time the
2877         //!     object command is being executeddown the pipeline.
2878         //!
2879         struct MFX_WAIT_CMD
2880         {
2881             union
2882             {
2883                 struct
2884                 {
2885                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 5);          //!< DWORD_LENGTH
2886                     uint32_t Reserved6 : __CODEGEN_BITFIELD(6, 7);            //!< Reserved
2887                     uint32_t MfxSyncControlFlag : __CODEGEN_BITFIELD(8, 8);   //!< MFX Sync Control Flag
2888                     uint32_t Reserved9 : __CODEGEN_BITFIELD(9, 9);            //!< Reserved
2889                     uint32_t Reserved10 : __CODEGEN_BITFIELD(10, 15);         //!< Reserved
2890                     uint32_t SubOpcode : __CODEGEN_BITFIELD(16, 26);          //!< SUB_OPCODE
2891                     uint32_t CommandSubtype : __CODEGEN_BITFIELD(27, 28);     //!< COMMAND_SUBTYPE
2892                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);        //!< COMMAND_TYPE
2893                 };
2894                 uint32_t Value;
2895             } DW0;
2896 
2897             //! \name Local enumerations
2898 
2899             enum SUB_OPCODE
2900             {
2901                 SUB_OPCODE_MFXWAIT = 0,  //!< No additional details
2902             };
2903 
2904             enum COMMAND_SUBTYPE
2905             {
2906                 COMMAND_SUBTYPE_MFXSINGLEDW = 1,  //!< No additional details
2907             };
2908 
2909             enum COMMAND_TYPE
2910             {
2911                 COMMAND_TYPE_PARALLELVIDEOPIPE = 3,  //!< No additional details
2912             };
2913 
2914             //! \name Initializations
2915 
2916             //! \brief Explicit member initialization function
MFX_WAIT_CMDCmd::MFX_WAIT_CMD2917             MFX_WAIT_CMD()
2918             {
2919                 DW0.Value = 0x68000000;
2920                 //DW0.DwordLength                                  = GetOpLength(dwSize);
2921                 //DW0.SubOpcode                                    = SUB_OPCODE_MFXWAIT;
2922                 //DW0.CommandSubtype                               = COMMAND_SUBTYPE_MFXSINGLEDW;
2923                 //DW0.CommandType                                  = COMMAND_TYPE_PARALLELVIDEOPIPE;
2924             }
2925 
2926             static const size_t dwSize   = 1;
2927             static const size_t byteSize = 4;
2928         };
2929 
2930         //!
2931         //! \brief VD_CONTROL_STATE
2932         //! \details
2933         //!     This command can be used in HCPpipe.  For HCP, it is selected with the
2934         //!     Media Instruction Opcode "7h".   Each command has assigned a media
2935         //!     instruction command as defined in DWord 0, BitField 22:16. It will be
2936         //!     different between HCP.
2937         //!
2938         //!     This command is used to modify the control of HCP pipe. It can be
2939         //!     inserted anywhere within a frame. It can be inserted multiple times
2940         //!     within a frame as well.
2941         //!
2942         struct VD_CONTROL_STATE_CMD
2943         {
2944             union
2945             {
2946                 struct
2947                 {
2948                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 11);               //!< DWORD_LENGTH
2949                     uint32_t Reserved12 : __CODEGEN_BITFIELD(12, 15);               //!< Reserved
2950                     uint32_t MediaInstructionCommand : __CODEGEN_BITFIELD(16, 22);  //!< MEDIA_INSTRUCTION_COMMAND
2951                     uint32_t MediaInstructionOpcode : __CODEGEN_BITFIELD(23, 26);   //!< MEDIA_INSTRUCTION_OPCODE
2952                     uint32_t PipelineType : __CODEGEN_BITFIELD(27, 28);             //!< PIPELINE_TYPE
2953                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);              //!< COMMAND_TYPE
2954                 };
2955                 uint32_t Value;
2956             } DW0;
2957             union
2958             {
2959                 struct
2960                 {
2961                     uint32_t PipelineInitialization : __CODEGEN_BITFIELD(0, 0);                       //!< Pipeline Initialization
2962                     uint32_t VdboxPipelineArchitectureClockgateDisable : __CODEGEN_BITFIELD(1, 1);    //!< VDBOX_PIPELINE_ARCHITECTURE_CLOCKGATE_DISABLE
2963                     uint32_t Reserved1 : __CODEGEN_BITFIELD(2, 27);                                   //!< Reserved
2964                     uint32_t MfxDopClockgateControlWithEnableAsDefault : __CODEGEN_BITFIELD(28, 28);  //!< MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
2965                     uint32_t HcpDopClockgateControlWithEnableAsDefault : __CODEGEN_BITFIELD(29, 29);  //!< HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
2966                     uint32_t Reserved30 : __CODEGEN_BITFIELD(30, 31);                                 //!< Reserved
2967                 };
2968                 uint32_t Value;
2969             } DW1;
2970             union
2971             {
2972                 struct
2973                 {
2974                     uint32_t ScalableModePipeLock : __CODEGEN_BITFIELD(0, 0);    //!< Scalable Mode Pipe Lock
2975                     uint32_t ScalableModePipeUnlock : __CODEGEN_BITFIELD(1, 1);  //!< Scalable Mode Pipe Unlock
2976                     uint32_t MemoryImplicitFlush : __CODEGEN_BITFIELD(2, 2);     //!< Memory Implicit Flush
2977                     uint32_t Reserved35 : __CODEGEN_BITFIELD(3, 31);             //!< Reserved
2978                 };
2979                 uint32_t Value;
2980             } DW2;
2981 
2982             //! \name Local enumerations
2983 
2984             enum MEDIA_INSTRUCTION_COMMAND
2985             {
2986                 MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORHCP   = 10,  //!< No additional details
2987                 MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORVDENC = 11,  //!< No additional details
2988             };
2989 
2990             //! \brief MEDIA_INSTRUCTION_OPCODE
2991             //! \details
2992             //!     Codec/Engine Name = HCP = 7h
2993             enum MEDIA_INSTRUCTION_OPCODE
2994             {
2995                 MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORVDENC = 1,  //!< No additional details
2996                 MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORAVP   = 3,  //!< No additional details
2997                 MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORHCP   = 7,  //!< No additional details
2998             };
2999 
3000             enum PIPELINE_TYPE
3001             {
3002                 PIPELINE_TYPE_UNNAMED2 = 2,  //!< No additional details
3003             };
3004 
3005             enum COMMAND_TYPE
3006             {
3007                 COMMAND_TYPE_PARALLELVIDEOPIPE = 3,  //!< No additional details
3008             };
3009 
3010             //! \name Local enumerations
3011 
3012             //! \brief MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
3013             //! \details
3014             //!     This bit control the DOP clockgate for MFX pipe. When this bit is set
3015             //!     to "0", the MFX DOP clockgate is enabled. MFX DOP clockgate is disabled
3016             //!     when this bit is set to "1"
3017             enum MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
3018             {
3019                 MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_ENABLE  = 0,  //!< No additional details
3020                 MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_DISABLE = 1,  //!< No additional details
3021             };
3022 
3023             //! \brief HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
3024             //! \details
3025             //!     This bit control the DOP clockgate for HCP pipe. When this bit is set
3026             //!     to "0", the HCP DOP clockgate is enabled. HCP DOP clockgate is disabled
3027             //!     when this bit is set to "1"
3028             enum HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT
3029             {
3030                 HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_ENABLE  = 0,  //!< No additional details
3031                 HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_DISABLE = 1,  //!< No additional details
3032             };
3033 
3034             //! \name Initializations
3035 
3036             //! \brief Explicit member initialization function
VD_CONTROL_STATE_CMDCmd::VD_CONTROL_STATE_CMD3037             VD_CONTROL_STATE_CMD()
3038             {
3039                 DW0.Value = 0x738a0001;
3040                 //DW0.DwordLength                                  = GetOpLength(dwSize);
3041                 //DW0.MediaInstructionCommand                      = MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATE;
3042                 //DW0.MediaInstructionOpcode                       = MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORHCP;
3043                 //DW0.PipelineType                                 = PIPELINE_TYPE_UNNAMED2;
3044                 //DW0.CommandType                                  = COMMAND_TYPE_PARALLELVIDEOPIPE;
3045 
3046                 DW1.Value = 0x00000000;
3047                 //DW0.MfxDopClockgateControlWithEnableAsDefault    = MFX_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_ENABLE;
3048                 //DW0.HcpDopClockgateControlWithEnableAsDefault    = HCP_DOP_CLOCKGATE_CONTROL_WITH_ENABLE_AS_DEFAULT_ENABLE;
3049 
3050                 DW2.Value = 0x00000000;
3051             }
3052 
3053             static const size_t dwSize   = 3;
3054             static const size_t byteSize = 12;
3055         };
3056 
3057         //!
3058 //! \brief MEDIA_STATE_FLUSH
3059 //! \details
3060 //!     This command updates the Message Gateway state. In particular, it
3061 //!     updates the state for a selected Interface Descriptor.
3062 //!
3063 //!     This command can be considered same as a MI_Flush except that only media
3064 //!     parser will get flushed instead of the entire 3D/media render pipeline.
3065 //!     The command should be programmed prior to new Media state, curbe and/or
3066 //!     interface descriptor commands when switching to a new context or
3067 //!     programming new state for the same context. With this command, pipelined
3068 //!     state change is allowed for the media pipe.
3069 //!
3070 //!     Be cautious when using this command when child_present flag in the media
3071 //!     state is enabled. This is because that CURBE state as well as Interface
3072 //!     Descriptor state are shared between root threads and child threads.
3073 //!     Changing these states while child threads are generated on the fly may
3074 //!     cause unexpected behavior. Combining with MI_ARB_ON/OFF command, it is
3075 //!     possible to support interruptability with the following command sequence
3076 //!     where interrupt may be allowed only when MI_ARB_ON_OFF is ON:
3077 //!
3078 //!     <pre>MEDIA_STATE_FLUSH
3079 //!     VFE_STATE  VFE will hold CS if watermark isn't met
3080 //!     MI_ARB_OFF  There must be at least one VFE command before this one
3081 //!     MEDIA_OBJECT ... MI_ARB_ON</pre>
3082 //!
3083         struct MEDIA_STATE_FLUSH_CMD
3084         {
3085             union
3086             {
3087                 //!< DWORD 0
3088                 struct
3089                 {
3090                     uint32_t DwordLength : __CODEGEN_BITFIELD(0, 15);          //!< DWORD_LENGTH
3091                     uint32_t Subopcode : __CODEGEN_BITFIELD(16, 23);           //!< SUBOPCODE
3092                     uint32_t MediaCommandOpcode : __CODEGEN_BITFIELD(24, 26);  //!< MEDIA_COMMAND_OPCODE
3093                     uint32_t Pipeline : __CODEGEN_BITFIELD(27, 28);            //!< PIPELINE
3094                     uint32_t CommandType : __CODEGEN_BITFIELD(29, 31);         //!< COMMAND_TYPE
3095                 };
3096                 uint32_t Value;
3097             } DW0;
3098             union
3099             {
3100                 //!< DWORD 1
3101                 struct
3102                 {
3103                     uint32_t InterfaceDescriptorOffset : __CODEGEN_BITFIELD(0, 5);  //!< Interface Descriptor Offset
3104                     uint32_t Reserved38 : __CODEGEN_BITFIELD(6, 6);                 //!< Reserved
3105                     uint32_t FlushToGo : __CODEGEN_BITFIELD(7, 7);                  //!< Flush to GO
3106                     uint32_t Reserved40 : __CODEGEN_BITFIELD(8, 31);                //!< Reserved
3107                 };
3108                 uint32_t Value;
3109             } DW1;
3110 
3111             //! \name Local enumerations
3112 
3113             enum SUBOPCODE
3114             {
3115                 SUBOPCODE_MEDIASTATEFLUSHSUBOP = 4,  //!< No additional details
3116             };
3117 
3118             enum MEDIA_COMMAND_OPCODE
3119             {
3120                 MEDIA_COMMAND_OPCODE_MEDIASTATEFLUSH = 0,  //!< No additional details
3121             };
3122 
3123             enum PIPELINE
3124             {
3125                 PIPELINE_MEDIA = 2,  //!< No additional details
3126             };
3127 
3128             enum COMMAND_TYPE
3129             {
3130                 COMMAND_TYPE_GFXPIPE = 3,  //!< No additional details
3131             };
3132 
3133             //! \name Initializations
3134 
3135             //! \brief Explicit member initialization function
MEDIA_STATE_FLUSH_CMDCmd::MEDIA_STATE_FLUSH_CMD3136             MEDIA_STATE_FLUSH_CMD()
3137             {
3138                 DW0.Value = 0;
3139                 DW0.DwordLength = GetOpLength(dwSize);
3140                 DW0.Subopcode = SUBOPCODE_MEDIASTATEFLUSHSUBOP;
3141                 DW0.MediaCommandOpcode = MEDIA_COMMAND_OPCODE_MEDIASTATEFLUSH;
3142                 DW0.Pipeline = PIPELINE_MEDIA;
3143                 DW0.CommandType = COMMAND_TYPE_GFXPIPE;
3144 
3145                 DW1.Value = 0;
3146             }
3147 
3148             static const size_t dwSize = 2;
3149             static const size_t byteSize = 8;
3150         };
3151 
3152     };
3153 }  // namesapce xe2_lpm_base_next
3154 }  // namespace mi
3155 }  // namespace mhw
3156 
3157 #pragma pack()
3158 
3159 #endif  // __MHW_MI_HWCMD_XE2_LPM_BASE_NEXT_H__