1 /*
2 * Copyright (c) 2020-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     mhw_mi_xe_xpm_base_impl.h
24 //! \brief    MHW MI interface common base for Xe_XPM_BASE
25 //! \details
26 //!
27 
28 #ifndef __MHW_MI_XE_XPM_BASE_IMPL_H__
29 #define __MHW_MI_XE_XPM_BASE_IMPL_H__
30 
31 #include "mhw_mi_impl.h"
32 #include "mhw_mi_hwcmd_xe_xpm_base.h"
33 #include "mhw_mi_itf.h"
34 #include "mhw_impl.h"
35 
36 namespace mhw
37 {
38 namespace mi
39 {
40 namespace xe_xpm_base
41 {
42 class Impl : public mi::Impl<Cmd>
43 {
44 protected:
45     using base_t = mi::Impl<Cmd>;
46     static constexpr uint32_t m_mmioMaxRelativeOffset = M_MMIO_MAX_RELATIVE_OFFSET;               //!< Max reg relative offset in an engine
47     static constexpr uint32_t m_mmioMediaLowOffset    = M_MMIO_MEDIA_LOW_OFFSET;             //!< Low bound of VDBox and VEBox MMIO offset
48     static constexpr uint32_t m_mmioMediaHighOffset   = M_MMIO_MEDIA_HIGH_OFFSET;             //!< High bound of VDBox and VEBox MMIO offset
49 
50     //! \brief Indicates the MediaReset Parameter.
51     struct
52     {
53         uint32_t watchdogCountThreshold = 0;
54         uint32_t watchdogCountCtrlOffset = 0;
55         uint32_t watchdogCountThresholdOffset = 0;
56     } MediaResetParam;
57 
58 public:
Impl(PMOS_INTERFACE osItf)59     Impl(PMOS_INTERFACE osItf) : base_t(osItf)
60     {
61         MHW_FUNCTION_ENTER;
62 
63         InitMhwMiInterface();
64         InitMmioRegisters();
65     };
66 
GetWatchdogThreshold(PMOS_INTERFACE osInterface)67     void GetWatchdogThreshold(PMOS_INTERFACE osInterface)
68     {
69         MOS_USER_FEATURE_VALUE_DATA userFeatureData = {};
70 
71 #if (_DEBUG || _RELEASE_INTERNAL)
72         // User feature config of watchdog timer threshold
73         MOS_UserFeature_ReadValue_ID(
74             nullptr,
75             __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
76             &userFeatureData,
77             osInterface->pOsContext);
78         if (userFeatureData.u32Data != 0)
79         {
80             MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
81         }
82 #endif
83     }
84 
InitMhwMiInterface()85     void InitMhwMiInterface()
86     {
87         MHW_FUNCTION_ENTER;
88 
89         UseGlobalGtt    = {};
90         MediaResetParam = {};
91 
92         if (this->m_osItf == nullptr)
93         {
94             MHW_ASSERTMESSAGE("Invalid input pointers provided");
95             return;
96         }
97 
98         if (!this->m_osItf->bUsesGfxAddress && !this->m_osItf->bUsesPatchList)
99         {
100             MHW_ASSERTMESSAGE("No valid addressing mode indicated");
101             return;
102         }
103 
104         UseGlobalGtt.m_cs   =
105         UseGlobalGtt.m_vcs  =
106         UseGlobalGtt.m_vecs = MEDIA_IS_WA(this->m_osItf->pfnGetWaTable(this->m_osItf), WaForceGlobalGTT) ||
107             !MEDIA_IS_SKU(this->m_osItf->pfnGetSkuTable(this->m_osItf), FtrPPGTT);
108 
109         MediaResetParam.watchdogCountThreshold = MHW_MI_DEFAULT_WATCHDOG_THRESHOLD_IN_MS;
110 
111         GetWatchdogThreshold(this->m_osItf);
112 
113         if (this->m_osItf->bUsesGfxAddress)
114         {
115             AddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
116         }
117         else // if (pOsInterface->bUsesPatchList)
118         {
119             AddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
120         }
121     }
122 
InitMmioRegisters()123     void InitMmioRegisters()
124     {
125         MHW_FUNCTION_ENTER;
126         MHW_MI_MMIOREGISTERS* mmioRegisters = &m_mmioRegisters;
127 
128         mmioRegisters->generalPurposeRegister0LoOffset  = GP_REGISTER0_LO_OFFSET;
129         mmioRegisters->generalPurposeRegister0HiOffset  = GP_REGISTER0_HI_OFFSET;
130         mmioRegisters->generalPurposeRegister4LoOffset  = GP_REGISTER4_LO_OFFSET;
131         mmioRegisters->generalPurposeRegister4HiOffset  = GP_REGISTER4_HI_OFFSET;
132         mmioRegisters->generalPurposeRegister11LoOffset = GP_REGISTER11_LO_OFFSET;
133         mmioRegisters->generalPurposeRegister11HiOffset = GP_REGISTER11_HI_OFFSET;
134         mmioRegisters->generalPurposeRegister12LoOffset = GP_REGISTER12_LO_OFFSET;
135         mmioRegisters->generalPurposeRegister12HiOffset = GP_REGISTER12_HI_OFFSET;
136     }
137 
138     //!
139 //! \brief    Check RCS and CCS remap offset
140 //! \details  Check if a RCS register offset is set and remap it to RCS/CCS register offset if so.
141 //! \param    [in] reg
142 //!           Register to be checked and converted
143 //! \return   bool
144 //!           Return true if it is RCS register
145 //!
IsRemappingMMIO(uint32_t reg)146     bool IsRemappingMMIO(uint32_t reg)
147     {
148         if (nullptr == this->m_osItf)
149         {
150             MHW_ASSERTMESSAGE("invalid m_osInterface for RemappingMMIO");
151             return false;
152         }
153         MOS_GPU_CONTEXT gpuContext = this->m_osItf->pfnGetGpuContext(this->m_osItf);
154 
155         if (MOS_RCS_ENGINE_USED(gpuContext) &&
156             ((M_MMIO_RCS_HW_FE_REMAP_RANGE_BEGIN <= reg && reg <= M_MMIO_RCS_HW_FE_REMAP_RANGE_END)
157                 || (M_MMIO_RCS_AUX_TBL_REMAP_RANGE_BEGIN <= reg && reg <= M_MMIO_RCS_AUX_TBL_REMAP_RANGE_END)
158                 || (M_MMIO_RCS_TRTT_REMAP_RANGE_BEGIN <= reg && reg <= M_MMIO_RCS_TRTT_REMAP_RANGE_END)
159                 || (M_MMIO_CCS0_HW_FRONT_END_BASE_BEGIN <= reg && reg <= M_MMIO_CCS0_HW_FRONT_END_BASE_END)
160                 || (M_MMIO_CCS1_HW_FRONT_END_BASE_BEGIN <= reg && reg <= M_MMIO_CCS1_HW_FRONT_END_BASE_END)
161                 || (M_MMIO_CCS2_HW_FRONT_END_BASE_BEGIN <= reg && reg <= M_MMIO_CCS2_HW_FRONT_END_BASE_END)
162                 || (M_MMIO_CCS3_HW_FRONT_END_BASE_BEGIN <= reg && reg <= M_MMIO_CCS3_HW_FRONT_END_BASE_END)))
163         {
164             return true;
165         }
166         else
167         {
168             return false;
169         }
170     }
171 
IsRelativeMMIO(uint32_t & reg)172     bool IsRelativeMMIO(uint32_t &reg)
173     {
174         if (nullptr == this->m_osItf)
175         {
176             MHW_ASSERTMESSAGE("invalid m_osInterface for RelativeMMIO");
177             return false;
178         }
179         MOS_GPU_CONTEXT gpuContext = this->m_osItf->pfnGetGpuContext(this->m_osItf);
180 
181         if ((MOS_VCS_ENGINE_USED(gpuContext) || MOS_VECS_ENGINE_USED(gpuContext)) &&
182             (reg >= m_mmioMediaLowOffset && reg < m_mmioMediaHighOffset))
183         {
184             reg &= m_mmioMaxRelativeOffset;
185             return true;
186         }
187         return false;
188     }
189 
SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder,uint32_t codecMode)190     MOS_STATUS SetWatchdogTimerThreshold(uint32_t frameWidth, uint32_t frameHeight, bool isEncoder, uint32_t codecMode) override
191     {
192         MHW_FUNCTION_ENTER;
193         MHW_MI_CHK_NULL(this->m_osItf);
194         if (this->m_osItf->bMediaReset == false ||
195             this->m_osItf->umdMediaResetEnable == false)
196         {
197             return MOS_STATUS_SUCCESS;
198         }
199 
200         if (isEncoder)
201         {
202             if ((frameWidth * frameHeight) >= (7680 * 4320))
203             {
204                 MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_16K_WATCHDOG_THRESHOLD_IN_MS;
205             }
206             else if ((frameWidth * frameHeight) >= (3840 * 2160))
207             {
208                 MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_8K_WATCHDOG_THRESHOLD_IN_MS;
209             }
210             else if ((frameWidth * frameHeight) >= (1920 * 1080))
211             {
212                 MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_4K_WATCHDOG_THRESHOLD_IN_MS;
213             }
214             else
215             {
216                 MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_FHD_WATCHDOG_THRESHOLD_IN_MS;
217             }
218         }
219         else
220         {
221             if ((frameWidth * frameHeight) >= (7680 * 4320))
222             {
223                 MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_8K_WATCHDOG_THRESHOLD_IN_MS;
224             }
225             else if ((frameWidth * frameHeight) >= (3840 * 2160))
226             {
227                 MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_4K_WATCHDOG_THRESHOLD_IN_MS;
228             }
229             else
230             {
231                 MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_720P_WATCHDOG_THRESHOLD_IN_MS;
232             }
233 
234             if ((CODECHAL_STANDARD)codecMode == CODECHAL_AV1)
235             {
236                 // This is temporary solution to address the inappropriate threshold setting for high bit-rate AV1 decode.
237                 // The final solution will incorporate bitstream size, increasing the setting when the bit-rate is high.
238                 MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_AV1_WATCHDOG_THRESHOLD_IN_MS;
239             }
240         }
241 
242         GetWatchdogThreshold(this->m_osItf);
243 
244         return MOS_STATUS_SUCCESS;
245     }
246 
SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)247     MOS_STATUS SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext) override
248     {
249         MHW_FUNCTION_ENTER;
250 
251         switch (gpuContext)
252         {
253             // RCS
254         case MOS_GPU_CONTEXT_RENDER:
255         case MOS_GPU_CONTEXT_RENDER2:
256         case MOS_GPU_CONTEXT_RENDER3:
257         case MOS_GPU_CONTEXT_RENDER4:
258         case MOS_GPU_CONTEXT_COMPUTE:
259         case MOS_GPU_CONTEXT_CM_COMPUTE:
260         case MOS_GPU_CONTEXT_RENDER_RA:
261         case MOS_GPU_CONTEXT_COMPUTE_RA:
262             MediaResetParam.watchdogCountCtrlOffset      = WATCHDOG_COUNT_CTRL_OFFSET_RCS;
263             MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_RCS;
264             break;
265             // VCS0
266         case MOS_GPU_CONTEXT_VIDEO:
267         case MOS_GPU_CONTEXT_VIDEO2:
268         case MOS_GPU_CONTEXT_VIDEO3:
269         case MOS_GPU_CONTEXT_VIDEO4:
270         case MOS_GPU_CONTEXT_VIDEO5:
271         case MOS_GPU_CONTEXT_VIDEO6:
272         case MOS_GPU_CONTEXT_VIDEO7:
273             MediaResetParam.watchdogCountCtrlOffset      = WATCHDOG_COUNT_CTRL_OFFSET_VCS0;
274             MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS0;
275             break;
276             // VCS1
277         case MOS_GPU_CONTEXT_VDBOX2_VIDEO:
278         case MOS_GPU_CONTEXT_VDBOX2_VIDEO2:
279         case MOS_GPU_CONTEXT_VDBOX2_VIDEO3:
280             MediaResetParam.watchdogCountCtrlOffset      = WATCHDOG_COUNT_CTRL_OFFSET_VCS1;
281             MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS1;
282             break;
283             // VECS
284         case MOS_GPU_CONTEXT_VEBOX:
285             MediaResetParam.watchdogCountCtrlOffset      = WATCHDOG_COUNT_CTRL_OFFSET_VECS;
286             MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VECS;
287             break;
288             // Default
289         default:
290             break;
291         }
292 
293         return MOS_STATUS_SUCCESS;
294     }
295 
AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)296     MOS_STATUS AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer) override
297     {
298         MOS_GPU_CONTEXT gpuContext;
299 
300         MHW_FUNCTION_ENTER;
301         MHW_MI_CHK_NULL(this->m_osItf);
302         if (this->m_osItf->bMediaReset == false ||
303             this->m_osItf->umdMediaResetEnable == false)
304         {
305             return MOS_STATUS_SUCCESS;
306         }
307 
308         MHW_MI_CHK_NULL(cmdBuffer);
309 
310         // Set Watchdog Timer Register Offset
311         gpuContext = this->m_osItf->pfnGetGpuContext(this->m_osItf);
312         MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
313 
314         // Send Stop before Start is to help recover from incorrect wdt state if previous submission
315         // cause hang and not have a chance to execute the stop cmd in the end of batch buffer.
316         MHW_MI_CHK_STATUS(AddWatchdogTimerStopCmd(cmdBuffer));
317 
318         //Configure Watchdog timer Threshold
319         auto& par = MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
320         par = {};
321         par.dwData     = MHW_MI_WATCHDOG_COUNTS_PER_MILLISECOND * MediaResetParam.watchdogCountThreshold *
322             (this->m_osItf->bSimIsActive ? 2 : 1);
323         par.dwRegister = MediaResetParam.watchdogCountThresholdOffset;
324         MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(cmdBuffer);
325 
326         MHW_VERBOSEMESSAGE("MediaReset Threshold is %d", MediaResetParam.watchdogCountThreshold * (this->m_osItf->bSimIsActive ? 2 : 1));
327 
328         //Start Watchdog Timer
329         auto& par1 = MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
330         par1 = {};
331         par1.dwData     = MHW_MI_WATCHDOG_ENABLE_COUNTER;
332         par1.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
333         MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(cmdBuffer);
334 
335         return MOS_STATUS_SUCCESS;
336     }
337 
AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)338     MOS_STATUS AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer) override
339     {
340         MOS_GPU_CONTEXT gpuContext;
341 
342         MHW_FUNCTION_ENTER;
343         MHW_MI_CHK_NULL(this->m_osItf);
344         if (this->m_osItf->bMediaReset == false ||
345             this->m_osItf->umdMediaResetEnable == false)
346         {
347             return MOS_STATUS_SUCCESS;
348         }
349 
350         MHW_MI_CHK_NULL(cmdBuffer);
351 
352         // Set Watchdog Timer Register Offset
353         gpuContext = this->m_osItf->pfnGetGpuContext(this->m_osItf);
354         MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
355 
356         //Stop Watchdog Timer
357         auto& par = MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
358         par = {};
359         par.dwData     = MHW_MI_WATCHDOG_DISABLE_COUNTER;
360         par.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
361         MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(cmdBuffer);
362 
363         return MOS_STATUS_SUCCESS;
364     }
365 
GetMmioInterfaces(MHW_MMIO_REGISTER_OPCODE opCode)366     uint32_t GetMmioInterfaces(MHW_MMIO_REGISTER_OPCODE opCode) override
367     {
368         uint32_t mmioRegisters = MHW_MMIO_RCS_AUX_TABLE_NONE;
369 
370         switch (opCode) {
371         case MHW_MMIO_RCS_AUX_TABLE_BASE_LOW:
372             mmioRegisters = M_MMIO_RCS_AUX_TABLE_BASE_LOW;
373             break;
374         case MHW_MMIO_RCS_AUX_TABLE_BASE_HIGH:
375             mmioRegisters = M_MMIO_RCS_AUX_TABLE_BASE_HIGH;
376             break;
377         case MHW_MMIO_RCS_AUX_TABLE_INVALIDATE:
378             mmioRegisters = M_MMIO_RCS_AUX_TABLE_INVALIDATE;
379             break;
380         case MHW_MMIO_VD0_AUX_TABLE_BASE_LOW:
381             mmioRegisters = M_MMIO_VD0_AUX_TABLE_BASE_LOW;
382             break;
383         case MHW_MMIO_VD0_AUX_TABLE_BASE_HIGH:
384             mmioRegisters = M_MMIO_VD0_AUX_TABLE_BASE_HIGH;
385             break;
386         case MHW_MMIO_VD0_AUX_TABLE_INVALIDATE:
387             mmioRegisters = M_MMIO_VD0_AUX_TABLE_INVALIDATE;
388             break;
389         case MHW_MMIO_VD1_AUX_TABLE_BASE_LOW:
390             mmioRegisters = M_MMIO_VD1_AUX_TABLE_BASE_LOW;
391             break;
392         case MHW_MMIO_VD1_AUX_TABLE_BASE_HIGH:
393             mmioRegisters = M_MMIO_VD1_AUX_TABLE_BASE_HIGH;
394             break;
395         case MHW_MMIO_VD1_AUX_TABLE_INVALIDATE:
396             mmioRegisters = M_MMIO_VD1_AUX_TABLE_INVALIDATE;
397             break;
398         case MHW_MMIO_VD2_AUX_TABLE_BASE_LOW:
399             mmioRegisters = M_MMIO_VD2_AUX_TABLE_BASE_LOW;
400             break;
401         case MHW_MMIO_VD2_AUX_TABLE_BASE_HIGH:
402             mmioRegisters = M_MMIO_VD2_AUX_TABLE_BASE_HIGH;
403             break;
404         case MHW_MMIO_VD2_AUX_TABLE_INVALIDATE:
405             mmioRegisters = M_MMIO_VD2_AUX_TABLE_INVALIDATE;
406             break;
407         case MHW_MMIO_VD3_AUX_TABLE_BASE_LOW:
408             mmioRegisters = M_MMIO_VD3_AUX_TABLE_BASE_LOW;
409             break;
410         case MHW_MMIO_VD3_AUX_TABLE_BASE_HIGH:
411             mmioRegisters = M_MMIO_VD3_AUX_TABLE_BASE_HIGH;
412             break;
413         case MHW_MMIO_VD3_AUX_TABLE_INVALIDATE:
414             mmioRegisters = M_MMIO_VD3_AUX_TABLE_INVALIDATE;
415             break;
416         case MHW_MMIO_VE0_AUX_TABLE_BASE_LOW:
417             mmioRegisters = M_MMIO_VE0_AUX_TABLE_BASE_LOW;
418             break;
419         case MHW_MMIO_VE0_AUX_TABLE_BASE_HIGH:
420             mmioRegisters = M_MMIO_VE0_AUX_TABLE_BASE_HIGH;
421             break;
422         case MHW_MMIO_VE0_AUX_TABLE_INVALIDATE:
423             mmioRegisters = M_MMIO_VE0_AUX_TABLE_INVALIDATE;
424             break;
425         case MHW_MMIO_VE1_AUX_TABLE_BASE_LOW:
426             mmioRegisters = M_MMIO_VE1_AUX_TABLE_BASE_LOW;
427             break;
428         case MHW_MMIO_VE1_AUX_TABLE_BASE_HIGH:
429             mmioRegisters = M_MMIO_VE1_AUX_TABLE_BASE_HIGH;
430             break;
431         case MHW_MMIO_VE1_AUX_TABLE_INVALIDATE:
432             mmioRegisters = M_MMIO_VE1_AUX_TABLE_INVALIDATE;
433             break;
434         case MHW_MMIO_CCS0_AUX_TABLE_BASE_LOW:
435             mmioRegisters = M_MMIO_CCS0_AUX_TABLE_BASE_LOW;
436             break;
437         case MHW_MMIO_CCS0_AUX_TABLE_BASE_HIGH:
438             mmioRegisters = M_MMIO_CCS0_AUX_TABLE_BASE_HIGH;
439             break;
440         case MHW_MMIO_CCS0_AUX_TABLE_INVALIDATE:
441             mmioRegisters = M_MMIO_CCS0_AUX_TABLE_INVALIDATE;
442             break;
443         default:
444             MHW_ASSERTMESSAGE("Invalid mmio data provided");;
445             break;
446         }
447 
448         return mmioRegisters;
449     }
450 
AddMiBatchBufferEnd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)451     MOS_STATUS AddMiBatchBufferEnd(
452         PMOS_COMMAND_BUFFER             cmdBuffer,
453         PMHW_BATCH_BUFFER               batchBuffer) override
454     {
455         MHW_FUNCTION_ENTER;
456 
457         if (cmdBuffer == nullptr && batchBuffer == nullptr)
458         {
459             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
460             return MOS_STATUS_NULL_POINTER;
461         }
462 
463         auto waTable = this->m_osItf->pfnGetWaTable(this->m_osItf);
464         MHW_MI_CHK_NULL(waTable);
465 
466         // This WA does not apply for video or other engines, render requirement only
467         bool isRender =
468             MOS_RCS_ENGINE_USED(this->m_osItf->pfnGetGpuContext(this->m_osItf));
469 
470         if (isRender &&
471             (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang) ||
472             MEDIA_IS_WA(waTable, WaAddMediaStateFlushCmd)))
473         {
474             auto& params = MHW_GETPAR_F(MEDIA_STATE_FLUSH)();
475             params = {};
476             MHW_ADDCMD_F(MEDIA_STATE_FLUSH)(cmdBuffer, batchBuffer);
477         }
478 
479         // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level
480         // and 2nd level BB.  It inserts MI_BATCH_BUFFER_END in both cases.
481         // However, since the 2nd level BB always returens to the 1st level BB and
482         // no chained BB scenario in Media, Epilog is only needed in the 1st level BB.
483         // Therefre, here only the 1st level BB case needs an Epilog inserted.
484         if (cmdBuffer && cmdBuffer->is1stLvlBB)
485         {
486             MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(this->m_osItf, cmdBuffer));
487         }
488 
489         auto& params = MHW_GETPAR_F(MI_BATCH_BUFFER_END)();
490         params = {};
491         MHW_ADDCMD_F(MI_BATCH_BUFFER_END)(cmdBuffer, batchBuffer);
492 
493         if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far
494         {
495 #if (_DEBUG || _RELEASE_INTERNAL)
496             batchBuffer->iLastCurrent = batchBuffer->iCurrent;
497 #endif
498         }
499 
500         // Send End Marker command
501         if (this->m_osItf->pfnIsSetMarkerEnabled(this->m_osItf) && cmdBuffer && cmdBuffer->is1stLvlBB)
502         {
503             PMOS_RESOURCE   resMarker = nullptr;
504             resMarker = this->m_osItf->pfnGetMarkerResource(this->m_osItf);
505             MHW_MI_CHK_NULL(resMarker);
506 
507             if (isRender)
508             {
509                 // Send pipe_control to get the timestamp
510                 auto& params = MHW_GETPAR_F(PIPE_CONTROL)();
511                 params = {};
512                 params.presDest = resMarker;
513                 params.dwResourceOffset = sizeof(uint64_t);
514                 params.dwPostSyncOp = MHW_FLUSH_WRITE_TIMESTAMP_REG;
515                 params.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
516                 MHW_ADDCMD_F(PIPE_CONTROL)(cmdBuffer, batchBuffer);
517             }
518             else
519             {
520                 // Send flush_dw to get the timestamp
521                 auto& params = MHW_GETPAR_F(MI_FLUSH_DW)();
522                 params = {};
523                 params.pOsResource = resMarker;
524                 params.dwResourceOffset = sizeof(uint64_t);
525                 params.postSyncOperation = MHW_FLUSH_WRITE_TIMESTAMP_REG;
526                 params.bQWordEnable = 1;
527                 MHW_ADDCMD_F(MI_FLUSH_DW)(cmdBuffer, batchBuffer);
528             }
529 
530             if (!this->m_osItf->apoMosEnabled)
531             {
532                 MOS_SafeFreeMemory(resMarker);
533             }
534         }
535         MHW_MI_CHK_STATUS(this->m_osItf->osCpInterface->PermeateBBPatchForHM());
536 
537         return MOS_STATUS_SUCCESS;
538     }
539 
_MHW_SETCMD_OVERRIDE_DECL(MI_SEMAPHORE_WAIT)540     _MHW_SETCMD_OVERRIDE_DECL(MI_SEMAPHORE_WAIT)
541     {
542         _MHW_SETCMD_CALLBASE(MI_SEMAPHORE_WAIT);
543 
544         cmd.DW0.RegisterPollMode   = params.bRegisterPollMode;
545 
546         return MOS_STATUS_SUCCESS;
547     }
548 
_MHW_SETCMD_OVERRIDE_DECL(PIPE_CONTROL)549     _MHW_SETCMD_OVERRIDE_DECL(PIPE_CONTROL)
550     {
551         _MHW_SETCMD_CALLBASE(PIPE_CONTROL);
552         MEDIA_WA_TABLE *pWaTable = this->m_osItf->pfnGetWaTable(this->m_osItf);
553         MHW_MI_CHK_NULL(pWaTable);
554 
555         if (this->m_currentCmdBuf == nullptr && this->m_currentBatchBuf == nullptr)
556         {
557             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
558             return MOS_STATUS_NULL_POINTER;
559         }
560 
561         cmd.DW1.PipeControlFlushEnable     = params.bKernelFenceEnabled ? false : true;
562         cmd.DW1.CommandStreamerStallEnable = !params.bDisableCSStall;
563         cmd.DW4_5.Value[0]                 = params.dwDataDW1;
564         cmd.DW4_5.Value[1]                 = params.dwDataDW2;
565 
566         if (params.presDest)
567         {
568             cmd.DW1.PostSyncOperation      = params.dwPostSyncOp;
569             cmd.DW1.DestinationAddressType = UseGlobalGtt.m_cs;
570 
571             MHW_RESOURCE_PARAMS resourceParams = {};
572             resourceParams.presResource    = params.presDest;
573             resourceParams.dwOffset        = params.dwResourceOffset;
574             resourceParams.pdwCmd          = &(cmd.DW2.Value);
575             resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW2.Value);
576             resourceParams.dwLsbNum        = MHW_COMMON_MI_PIPE_CONTROL_SHIFT;
577             resourceParams.bIsWritable     = true;
578             resourceParams.HwCommandType   = MOS_PIPE_CONTROL;
579 
580             MHW_MI_CHK_STATUS(AddResourceToCmd(
581                 this->m_osItf,
582                 this->m_currentCmdBuf,
583                 &resourceParams));
584         }
585         else
586         {
587             if (MEDIA_IS_WA(pWaTable, Wa_14010840176))
588             {
589                 cmd.DW0.HdcPipelineFlush                = true;
590                 cmd.DW1.ConstantCacheInvalidationEnable = false;
591             }
592             else
593             {
594                 cmd.DW1.ConstantCacheInvalidationEnable = true;
595             }
596             cmd.DW1.StateCacheInvalidationEnable     = true;
597             cmd.DW1.VfCacheInvalidationEnable        = true;
598             cmd.DW1.InstructionCacheInvalidateEnable = true;
599             cmd.DW1.RenderTargetCacheFlushEnable     = true;
600             cmd.DW1.PostSyncOperation                = cmd.POST_SYNC_OPERATION_NOWRITE;
601         }
602 
603         // Cache flush mode
604         switch (params.dwFlushMode)
605         {
606         // Flush all Write caches
607         case MHW_FLUSH_WRITE_CACHE:
608             cmd.DW1.RenderTargetCacheFlushEnable = true;
609             cmd.DW1.DcFlushEnable                = true;
610             break;
611 
612         // Invalidate all Read-only caches
613         case MHW_FLUSH_READ_CACHE:
614             if (MEDIA_IS_WA(pWaTable, Wa_14010840176))
615             {
616                 cmd.DW0.HdcPipelineFlush                = true;
617                 cmd.DW1.ConstantCacheInvalidationEnable = false;
618             }
619             else
620             {
621                 cmd.DW1.ConstantCacheInvalidationEnable = true;
622             }
623             cmd.DW1.RenderTargetCacheFlushEnable     = false;
624             cmd.DW1.StateCacheInvalidationEnable     = true;
625             cmd.DW1.VfCacheInvalidationEnable        = true;
626             cmd.DW1.InstructionCacheInvalidateEnable = true;
627             break;
628 
629         // Custom flush parameters
630         case MHW_FLUSH_CUSTOM:
631             if (MEDIA_IS_WA(pWaTable, Wa_14010840176) && params.bInvalidateConstantCache)
632             {
633                 cmd.DW0.HdcPipelineFlush                = true;
634                 cmd.DW1.StateCacheInvalidationEnable    = true;
635                 cmd.DW1.ConstantCacheInvalidationEnable = false;
636             }
637             else
638             {
639                 cmd.DW1.StateCacheInvalidationEnable    = params.bInvalidateStateCache;
640                 cmd.DW1.ConstantCacheInvalidationEnable = params.bInvalidateConstantCache;
641             }
642 
643             cmd.DW1.RenderTargetCacheFlushEnable     = params.bFlushRenderTargetCache;
644             cmd.DW1.DcFlushEnable                    = params.bFlushRenderTargetCache;  // same as above
645             cmd.DW1.VfCacheInvalidationEnable        = params.bInvalidateVFECache;
646             cmd.DW1.InstructionCacheInvalidateEnable = params.bInvalidateInstructionCache;
647             cmd.DW1.TlbInvalidate                    = params.bTlbInvalidate;
648             cmd.DW1.TextureCacheInvalidationEnable   = params.bInvalidateTextureCache;
649             break;
650 
651         // No-flush operation requested
652         case MHW_FLUSH_NONE:
653         default:
654             cmd.DW1.RenderTargetCacheFlushEnable = false;
655             break;
656         }
657 
658         // When PIPE_CONTROL stall bit is set, one of the following must also be set, otherwise set stall bit to 0
659         if (cmd.DW1.CommandStreamerStallEnable &&
660             (cmd.DW1.DcFlushEnable == 0 && cmd.DW1.NotifyEnable == 0 && cmd.DW1.PostSyncOperation == 0 &&
661              cmd.DW1.DepthStallEnable == 0 && cmd.DW1.StallAtPixelScoreboard == 0 && cmd.DW1.DepthCacheFlushEnable == 0 &&
662              cmd.DW1.RenderTargetCacheFlushEnable == 0) &&
663             !params.bKernelFenceEnabled)
664         {
665             cmd.DW1.CommandStreamerStallEnable = 0;
666         }
667 
668         cmd.DW1.GenericMediaStateClear       = params.bGenericMediaStateClear;
669         cmd.DW1.IndirectStatePointersDisable = params.bIndirectStatePointersDisable;
670         cmd.DW0.HdcPipelineFlush             = params.bHdcPipelineFlush;
671 
672         return MOS_STATUS_SUCCESS;
673     }
674 
_MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_START)675     _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_START)
676     {
677         _MHW_SETCMD_CALLBASE(MI_BATCH_BUFFER_START);
678         MHW_MI_CHK_NULL(this->m_currentCmdBuf);
679         MHW_MI_CHK_NULL(this->m_currentBatchBuf);
680         MHW_MI_CHK_NULL(this->m_osItf);
681         bool vcsEngineUsed =
682             MOS_VCS_ENGINE_USED(this->m_osItf->pfnGetGpuContext(this->m_osItf));
683 
684         MHW_RESOURCE_PARAMS    resourceParams = {};
685         resourceParams.presResource    = &this->m_currentBatchBuf->OsResource;
686         resourceParams.dwOffset        = this->m_currentBatchBuf->dwOffset;
687         resourceParams.pdwCmd          = cmd.DW1_2.Value;
688         resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW1_2.Value);
689         resourceParams.dwLsbNum        = MHW_COMMON_MI_GENERAL_SHIFT;
690         resourceParams.HwCommandType   = vcsEngineUsed ? MOS_MI_BATCH_BUFFER_START : MOS_MI_BATCH_BUFFER_START_RCS;
691 
692         MHW_MI_CHK_STATUS(AddResourceToCmd(
693             this->m_osItf,
694             this->m_currentCmdBuf,
695             &resourceParams));
696 
697         // Set BB start
698         cmd.DW0.Obj3.SecondLevelBatchBuffer = params.secondLevelBatchBuffer;
699         cmd.DW0.Obj0.AddressSpaceIndicator  = !IsGlobalGttInUse();
700 
701         return MOS_STATUS_SUCCESS;
702     }
703 
__MHW_ADDCMD_DECL(MI_CONDITIONAL_BATCH_BUFFER_END)704     __MHW_ADDCMD_DECL(MI_CONDITIONAL_BATCH_BUFFER_END) override
705     {
706         // Case 1 - Batch buffer condition matches - If this is not present then conditional
707         //          batch buffer will  exit to ring with terminating CP.
708         // Case 2 - Batch buffer condition DOES NOT match - Although this will disable CP
709         //          but after end of conditional batch buffer CP will be re-enabled.
710         MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(this->m_osItf, cmdBuf));
711 
712         base_t::MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(cmdBuf, batchBuf);
713 
714         MHW_MI_CHK_STATUS(m_cpInterface->AddProlog(this->m_osItf, cmdBuf));
715 
716         return MOS_STATUS_SUCCESS;
717     }
718 
_MHW_SETCMD_OVERRIDE_DECL(MI_CONDITIONAL_BATCH_BUFFER_END)719     _MHW_SETCMD_OVERRIDE_DECL(MI_CONDITIONAL_BATCH_BUFFER_END)
720     {
721         _MHW_SETCMD_CALLBASE(MI_CONDITIONAL_BATCH_BUFFER_END);
722 
723         MHW_MI_CHK_NULL(params.presSemaphoreBuffer);
724 
725         cmd.DW0.UseGlobalGtt     = IsGlobalGttInUse();
726         cmd.DW0.CompareSemaphore = 1;  // CompareDataDword is always assumed to be set
727         cmd.DW0.CompareMaskMode  = !params.bDisableCompareMask;
728         if (params.dwParamsType == MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS::ENHANCED_PARAMS)
729         {
730             cmd.DW0.EndCurrentBatchBufferLevel = params.enableEndCurrentBatchBuffLevel;
731             cmd.DW0.CompareOperation           = params.compareOperation;
732         }
733         cmd.DW1.CompareDataDword = params.dwValue;
734 
735         MHW_RESOURCE_PARAMS resourceParams = {};
736         resourceParams.presResource    = params.presSemaphoreBuffer;
737         resourceParams.dwOffset        = params.dwOffset;
738         resourceParams.pdwCmd          = cmd.DW2_3.Value;
739         resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW2_3.Value);
740         resourceParams.dwLsbNum        = MHW_COMMON_MI_CONDITIONAL_BATCH_BUFFER_END_SHIFT;
741         resourceParams.HwCommandType   = MOS_MI_CONDITIONAL_BATCH_BUFFER_END;
742 
743         MHW_MI_CHK_STATUS(AddResourceToCmd(
744             this->m_osItf,
745             this->m_currentCmdBuf,
746             &resourceParams));
747 
748         return MOS_STATUS_SUCCESS;
749     }
750 
_MHW_SETCMD_OVERRIDE_DECL(MI_SET_PREDICATE)751     _MHW_SETCMD_OVERRIDE_DECL(MI_SET_PREDICATE)
752     {
753         _MHW_SETCMD_CALLBASE(MI_SET_PREDICATE);
754         cmd.DW0.PredicateEnable = params.PredicateEnable;
755 
756         return MOS_STATUS_SUCCESS;
757     }
758 
_MHW_SETCMD_OVERRIDE_DECL(MI_STORE_REGISTER_MEM)759     _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_REGISTER_MEM)
760     {
761         _MHW_SETCMD_CALLBASE(MI_STORE_REGISTER_MEM);
762         uint32_t reg = params.dwRegister;
763         if (IsRelativeMMIO(reg))
764         {
765             cmd.DW0.AddCsMmioStartOffset = 1;
766             cmd.DW1.RegisterAddress      = reg >> 2;
767         }
768 
769         if (params.dwOption == CCS_HW_FRONT_END_MMIO_REMAP)
770         {
771             MOS_GPU_CONTEXT gpuContext = m_osItf->pfnGetGpuContext(m_osItf);
772             if (MOS_RCS_ENGINE_USED(gpuContext))
773             {
774                 reg &= M_CCS_HW_FRONT_END_MMIO_MASK;
775                 reg += M_MMIO_CCS0_HW_FRONT_END_BASE_BEGIN;
776             }
777         }
778 
779         cmd.DW0.MmioRemapEnable = IsRemappingMMIO(reg);
780 
781         return MOS_STATUS_SUCCESS;
782     }
783 
_MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_MEM)784     _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_MEM)
785     {
786         _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_MEM);
787         uint32_t reg = params.dwRegister;
788         if (IsRelativeMMIO(reg))
789         {
790             cmd.DW0.AddCsMmioStartOffset = 1;
791             cmd.DW1.RegisterAddress      = reg >> 2;
792         }
793 
794         cmd.DW0.MmioRemapEnable = IsRemappingMMIO(reg);
795 
796         return MOS_STATUS_SUCCESS;
797     }
798 
_MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_IMM)799     _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_IMM)
800     {
801         _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_IMM);
802         uint32_t reg = params.dwRegister;
803         if (IsRelativeMMIO(reg))
804         {
805             cmd.DW0.AddCsMmioStartOffset = 1;
806             cmd.DW1.RegisterOffset       = reg >> 2;
807         }
808 
809         cmd.DW0.MmioRemapEnable = IsRemappingMMIO(reg);
810 
811         return MOS_STATUS_SUCCESS;
812     }
813 
_MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_REG)814     _MHW_SETCMD_OVERRIDE_DECL(MI_LOAD_REGISTER_REG)
815     {
816         _MHW_SETCMD_CALLBASE(MI_LOAD_REGISTER_REG);
817         uint32_t srcReg = params.dwSrcRegister;
818         if (IsRelativeMMIO(srcReg))
819         {
820             cmd.DW0.AddCsMmioStartOffsetSource = 1;
821             cmd.DW1.SourceRegisterAddress      = srcReg >> 2;
822         }
823         uint32_t dstReg = params.dwDstRegister;
824         if (IsRelativeMMIO(dstReg))
825         {
826             cmd.DW0.AddCsMmioStartOffsetDestination = 1;
827             cmd.DW2.DestinationRegisterAddress      = dstReg >> 2;
828         }
829 
830         cmd.DW0.MmioRemapEnableSource      = IsRemappingMMIO(srcReg);
831         cmd.DW0.MmioRemapEnableDestination = IsRemappingMMIO(dstReg);
832 
833         return MOS_STATUS_SUCCESS;
834     }
835 
_MHW_SETCMD_OVERRIDE_DECL(MI_FORCE_WAKEUP)836     _MHW_SETCMD_OVERRIDE_DECL(MI_FORCE_WAKEUP)
837     {
838         _MHW_SETCMD_CALLBASE(MI_FORCE_WAKEUP);
839 
840         cmd.DW1.ForceMediaSlice0Awake = params.bForceMediaSlice0Awake;
841         cmd.DW1.ForceRenderAwake      = params.bForceRenderAwake;
842         cmd.DW1.ForceMediaSlice1Awake = params.bForceMediaSlice1Awake;
843         cmd.DW1.ForceMediaSlice2Awake = params.bForceMediaSlice2Awake;
844         cmd.DW1.ForceMediaSlice3Awake = params.bForceMediaSlice3Awake;
845         cmd.DW1.HevcPowerWellControl  = params.bHEVCPowerWellControl;
846         cmd.DW1.MfxPowerWellControl   = params.bMFXPowerWellControl;
847         cmd.DW1.MaskBits              = params.bForceMediaSlice0AwakeMask;
848         cmd.DW1.MaskBits += (params.bForceRenderAwakeMask << 1);
849         cmd.DW1.MaskBits += (params.bForceMediaSlice1AwakeMask << 2);
850         cmd.DW1.MaskBits += (params.bForceMediaSlice2AwakeMask << 3);
851         cmd.DW1.MaskBits += (params.bForceMediaSlice3AwakeMask << 4);
852         cmd.DW1.MaskBits += (params.bHEVCPowerWellControlMask << 8);
853         cmd.DW1.MaskBits += (params.bMFXPowerWellControlMask << 9);
854 
855         return MOS_STATUS_SUCCESS;
856     }
857 
_MHW_SETCMD_OVERRIDE_DECL(VD_CONTROL_STATE)858     _MHW_SETCMD_OVERRIDE_DECL(VD_CONTROL_STATE)
859     {
860         _MHW_SETCMD_CALLBASE(VD_CONTROL_STATE);
861 
862         if (params.vdencEnabled)
863         {
864             cmd.DW0.MediaInstructionCommand =
865                 mhw::mi::xe_xpm_base::Cmd::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORVDENC;
866             cmd.DW0.MediaInstructionOpcode =
867                 mhw::mi::xe_xpm_base::Cmd::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORVDENC;
868         }
869         else
870         {
871             cmd.DW0.MediaInstructionCommand =
872                 mhw::mi::xe_xpm_base::Cmd::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORHCP;
873             if (params.avpEnabled)
874             {
875                 cmd.DW0.MediaInstructionOpcode =
876                     mhw::mi::xe_xpm_base::Cmd::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORAVP;
877             }
878             else
879             {
880                 cmd.DW0.MediaInstructionOpcode =
881                     mhw::mi::xe_xpm_base::Cmd::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORHCP;
882             }
883 
884             cmd.DW1.PipelineInitialization = params.initialization;
885             cmd.DW2.MemoryImplicitFlush    = params.memoryImplicitFlush;
886             cmd.DW2.ScalableModePipeLock   = params.scalableModePipeLock;
887             cmd.DW2.ScalableModePipeUnlock = params.scalableModePipeUnlock;
888         }
889 
890         return MOS_STATUS_SUCCESS;
891     }
892 
_MHW_SETCMD_OVERRIDE_DECL(MEDIA_STATE_FLUSH)893     _MHW_SETCMD_OVERRIDE_DECL(MEDIA_STATE_FLUSH)
894     {
895         _MHW_SETCMD_CALLBASE(MEDIA_STATE_FLUSH);
896 
897         cmd.DW1.FlushToGo                 = params.bFlushToGo;
898         cmd.DW1.InterfaceDescriptorOffset = params.ui8InterfaceDescriptorOffset;
899 
900 #if (_DEBUG || _RELEASE_INTERNAL)
901         if (this->m_currentBatchBuf)
902         {
903             this->m_currentBatchBuf->iLastCurrent = this->m_currentBatchBuf->iCurrent;
904         }
905 #endif
906 
907         return MOS_STATUS_SUCCESS;
908     }
909 
_MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_END)910     _MHW_SETCMD_OVERRIDE_DECL(MI_BATCH_BUFFER_END)
911     {
912          _MHW_SETCMD_CALLBASE(MI_BATCH_BUFFER_END);
913 
914         return MOS_STATUS_SUCCESS;
915     }
916 
_MHW_SETCMD_OVERRIDE_DECL(MI_FLUSH_DW)917     _MHW_SETCMD_OVERRIDE_DECL(MI_FLUSH_DW)
918     {
919         _MHW_SETCMD_CALLBASE(MI_FLUSH_DW);
920 
921         MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMiFlushDw(this->m_osItf, &cmd));
922         cmd.DW0.VideoPipelineCacheInvalidate = params.bVideoPipelineCacheInvalidate;
923         cmd.DW0.PostSyncOperation            = cmd.POST_SYNC_OPERATION_NOWRITE;
924         cmd.DW3_4.Value[0]                   = params.dwDataDW1;
925 
926         if (!Mos_ResourceIsNull(params.pOsResource))
927         {
928             cmd.DW0.PostSyncOperation        = cmd.POST_SYNC_OPERATION_WRITEIMMEDIATEDATA;
929             cmd.DW1_2.DestinationAddressType = UseGlobalGtt.m_vcs;
930 
931             MHW_RESOURCE_PARAMS resourceParams = {};
932             resourceParams.presResource    = params.pOsResource;
933             resourceParams.dwOffset        = params.dwResourceOffset;
934             resourceParams.pdwCmd          = cmd.DW1_2.Value;
935             resourceParams.dwLocationInCmd = _MHW_CMD_DW_LOCATION(DW1_2.Value);
936             resourceParams.dwLsbNum        = MHW_COMMON_MI_FLUSH_DW_SHIFT;
937             resourceParams.HwCommandType   = MOS_MI_FLUSH_DW;
938             resourceParams.bIsWritable     = true;
939 
940             MHW_MI_CHK_STATUS(AddResourceToCmd(
941                 this->m_osItf,
942                 this->m_currentCmdBuf,
943                 &resourceParams));
944         }
945 
946         if (params.postSyncOperation)
947         {
948             cmd.DW0.PostSyncOperation = params.postSyncOperation;
949         }
950 
951         if (params.dwDataDW2 || params.bQWordEnable)
952         {
953             cmd.DW3_4.Value[1] = params.dwDataDW2;
954         }
955         else
956         {
957             cmd.DW0.DwordLength--;
958         }
959 
960         return MOS_STATUS_SUCCESS;
961     }
962 
_MHW_SETCMD_OVERRIDE_DECL(MI_NOOP)963     _MHW_SETCMD_OVERRIDE_DECL(MI_NOOP)
964     {
965         _MHW_SETCMD_CALLBASE(MI_NOOP);
966 
967         return MOS_STATUS_SUCCESS;
968     }
969 
_MHW_SETCMD_OVERRIDE_DECL(MI_ATOMIC)970     _MHW_SETCMD_OVERRIDE_DECL(MI_ATOMIC)
971     {
972         _MHW_SETCMD_CALLBASE(MI_ATOMIC);
973 
974         return MOS_STATUS_SUCCESS;
975     }
976 
_MHW_SETCMD_OVERRIDE_DECL(MI_STORE_DATA_IMM)977     _MHW_SETCMD_OVERRIDE_DECL(MI_STORE_DATA_IMM)
978     {
979         _MHW_SETCMD_CALLBASE(MI_STORE_DATA_IMM);
980 
981         return MOS_STATUS_SUCCESS;
982     }
983 
__MHW_ADDCMD_DECL(MI_MATH)984     __MHW_ADDCMD_DECL(MI_MATH) override
985     {
986         MHW_FUNCTION_ENTER;
987         const auto &params = __MHW_CMDINFO_M(MI_MATH)->first;
988 
989         if (params.dwNumAluParams == 0 || params.pAluPayload == nullptr)
990         {
991             MHW_ASSERTMESSAGE("MI_MATH requires a valid payload");
992             return MOS_STATUS_INVALID_PARAMETER;
993         }
994 
995         base_t::MHW_ADDCMD_F(MI_MATH)(cmdBuf, batchBuf);
996 
997         return Mhw_AddCommandCmdOrBB(m_osItf, cmdBuf, nullptr, &params.pAluPayload[0],
998             sizeof(MHW_MI_ALU_PARAMS)* params.dwNumAluParams);
999     }
1000 
_MHW_SETCMD_OVERRIDE_DECL(MI_MATH)1001     _MHW_SETCMD_OVERRIDE_DECL(MI_MATH)
1002     {
1003         _MHW_SETCMD_CALLBASE(MI_MATH);
1004 
1005         cmd.DW0.DwordLength = params.dwNumAluParams - 1;
1006 
1007         return MOS_STATUS_SUCCESS;
1008     }
1009 
1010 MEDIA_CLASS_DEFINE_END(mhw__mi__xe_xpm_base__Impl)
1011 };
1012 
1013 }  // namespace xe_xpm_base
1014 }  // namespace mi
1015 }  // namespace mhw
1016 
1017 #endif  // __MHW_MI_XE_XPM_BASE_IMPL_H__
1018