1 /* 2 * Copyright (c) 2024, 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 encode_check_huc_load_packet.cpp 24 //! \brief 25 //! 26 27 #include "encode_check_huc_load_packet.h" 28 29 namespace encode 30 { Init()31 MOS_STATUS EncodeCheckHucLoadPkt::Init() 32 { 33 ENCODE_FUNC_CALL(); 34 35 ENCODE_CHK_NULL_RETURN(m_pipeline); 36 m_allocator = m_pipeline->GetEncodeAllocator(); 37 ENCODE_CHK_NULL_RETURN(m_allocator); 38 39 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 40 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 41 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 42 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 43 allocParamsForBufferLinear.Format = Format_Buffer; 44 45 // HUC STATUS 2 Buffer for HuC status check in COND_BB_END 46 allocParamsForBufferLinear.dwBytes = sizeof(uint64_t); 47 allocParamsForBufferLinear.pBufName = "Huc authentication status Buffer"; 48 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE; 49 PMOS_RESOURCE allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 50 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 51 m_hucAuthBuf = allocatedbuffer; 52 53 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 54 { 55 // VDENC uses second level batch buffer 56 MOS_ZeroMemory(&m_2ndLevelBB[j], sizeof(MHW_BATCH_BUFFER)); 57 m_2ndLevelBB[j].bSecondLevel = true; 58 ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb( 59 m_hwInterface->GetOsInterface(), 60 &m_2ndLevelBB[j], 61 nullptr, 62 CODECHAL_CACHELINE_SIZE)); 63 } 64 65 return MOS_STATUS_SUCCESS; 66 } 67 ~EncodeCheckHucLoadPkt()68 EncodeCheckHucLoadPkt::~EncodeCheckHucLoadPkt() 69 { 70 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface); 71 72 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 73 { 74 MOS_STATUS eStatus = Mhw_FreeBb(m_hwInterface->GetOsInterface(), &m_2ndLevelBB[j], nullptr); 75 ENCODE_ASSERT(eStatus == MOS_STATUS_SUCCESS); 76 } 77 } 78 AddForceWakeup(MOS_COMMAND_BUFFER * cmdBuffer)79 MOS_STATUS EncodeCheckHucLoadPkt::AddForceWakeup(MOS_COMMAND_BUFFER *cmdBuffer) 80 { 81 ENCODE_FUNC_CALL(); 82 83 auto &forceWakeupParams = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)(); 84 forceWakeupParams = {}; 85 forceWakeupParams.bMFXPowerWellControl = true; 86 forceWakeupParams.bMFXPowerWellControlMask = true; 87 forceWakeupParams.bHEVCPowerWellControl = true; 88 forceWakeupParams.bHEVCPowerWellControlMask = true; 89 90 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(cmdBuffer)); 91 92 return MOS_STATUS_SUCCESS; 93 } 94 SendPrologCmds(MOS_COMMAND_BUFFER * cmdBuffer)95 MOS_STATUS EncodeCheckHucLoadPkt::SendPrologCmds(MOS_COMMAND_BUFFER *cmdBuffer) 96 { 97 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 98 99 ENCODE_FUNC_CALL(); 100 bool mmcEnabled = false; 101 #ifdef _MMC_SUPPORTED 102 EncodeMemComp *mmcState = m_pipeline->GetMmcState(); 103 ENCODE_CHK_NULL_RETURN(mmcState); 104 mmcEnabled = mmcState->IsMmcEnabled(); 105 ENCODE_CHK_STATUS_RETURN(mmcState->SendPrologCmd(cmdBuffer, false)); 106 #endif 107 108 MHW_GENERIC_PROLOG_PARAMS genericPrologParams; 109 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams)); 110 ENCODE_CHK_NULL_RETURN(m_hwInterface); 111 genericPrologParams.pOsInterface = m_hwInterface->GetOsInterface(); 112 genericPrologParams.pvMiInterface = nullptr; 113 genericPrologParams.bMmcEnabled = mmcEnabled; 114 ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(cmdBuffer, &genericPrologParams, m_miItf)); 115 116 return eStatus; 117 } 118 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)119 MOS_STATUS EncodeCheckHucLoadPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase) 120 { 121 ENCODE_FUNC_CALL(); 122 123 // add media reset check 100ms, which equals to 1080p WDT threshold 124 ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(1920, 1080, true)); 125 126 bool firstTaskInPhase = packetPhase & firstPacket; 127 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) 128 { 129 ENCODE_CHK_STATUS_RETURN(AddForceWakeup(commandBuffer)); 130 // Send command buffer header at the beginning (OS dependent) 131 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(commandBuffer)); 132 } 133 134 // program 2nd level chained BB for Huc auth 135 m_batchBuf = &m_2ndLevelBB[m_pipeline->m_currRecycledBufIdx]; 136 ENCODE_CHK_NULL_RETURN(m_batchBuf); 137 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(&(m_batchBuf->OsResource)); 138 ENCODE_CHK_NULL_RETURN(data); 139 140 MOS_COMMAND_BUFFER hucAuthCmdBuffer = {}; 141 hucAuthCmdBuffer.pCmdBase = (uint32_t *)data; 142 hucAuthCmdBuffer.pCmdPtr = hucAuthCmdBuffer.pCmdBase; 143 hucAuthCmdBuffer.iRemaining = m_batchBuf->iSize; 144 hucAuthCmdBuffer.OsResource = m_batchBuf->OsResource; 145 hucAuthCmdBuffer.cmdBuf1stLvl = commandBuffer; 146 147 //pak check huc status command 148 ENCODE_CHK_STATUS_RETURN(PackHucAuthCmds(hucAuthCmdBuffer)); 149 150 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(&(m_batchBuf->OsResource))); 151 152 // BB start for 2nd level BB 153 auto &miBatchBufferStartParams = m_miItf->MHW_GETPAR_F(MI_BATCH_BUFFER_START)(); 154 miBatchBufferStartParams = {}; 155 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START)(commandBuffer, m_batchBuf)); 156 157 return MOS_STATUS_SUCCESS; 158 } 159 PackHucAuthCmds(MOS_COMMAND_BUFFER & cmdBuffer)160 MOS_STATUS EncodeCheckHucLoadPkt::PackHucAuthCmds(MOS_COMMAND_BUFFER &cmdBuffer) 161 { 162 ENCODE_FUNC_CALL(); 163 164 ENCODE_CHK_NULL_RETURN(m_hucItf); 165 auto mmioRegisters = m_hucItf->GetMmioRegisters(m_vdboxIndex); 166 ENCODE_CHK_NULL_RETURN(mmioRegisters); 167 168 // Write HuC Load Info Mask 169 auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)(); 170 storeDataParams = {}; 171 storeDataParams.pOsResource = m_hucAuthBuf; 172 storeDataParams.dwResourceOffset = 0; 173 storeDataParams.dwValue = m_hucLoadInfoMask; 174 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(&cmdBuffer)); 175 176 // Store Huc Auth register 177 auto &miStoreRegMemParams = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)(); 178 miStoreRegMemParams = {}; 179 miStoreRegMemParams.presStoreBuffer = m_hucAuthBuf; 180 miStoreRegMemParams.dwOffset = sizeof(uint32_t); 181 miStoreRegMemParams.dwRegister = mmioRegisters->hucLoadInfoOffset; 182 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer)); 183 184 // Flush the engine to ensure memory written out 185 auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)(); 186 flushDwParams = {}; 187 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer)); 188 189 // Check Huc load status: if equals to 0 continue chained BB until reset, otherwise send BB end cmd. 190 auto &conditionalBatchBufferEndParams = m_miItf->MHW_GETPAR_F(MI_CONDITIONAL_BATCH_BUFFER_END)(); 191 conditionalBatchBufferEndParams = {}; 192 conditionalBatchBufferEndParams.presSemaphoreBuffer = m_hucAuthBuf; 193 conditionalBatchBufferEndParams.dwOffset = 0; 194 conditionalBatchBufferEndParams.dwValue = 0; 195 conditionalBatchBufferEndParams.bDisableCompareMask = false; 196 conditionalBatchBufferEndParams.dwParamsType = mhw::mi::MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS::ENHANCED_PARAMS; 197 conditionalBatchBufferEndParams.enableEndCurrentBatchBuffLevel = true; 198 conditionalBatchBufferEndParams.compareOperation = COMPARE_OPERATION_MADEQUALIDD; 199 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(&cmdBuffer)); 200 201 // Chained BB loop 202 auto &miBatchBufferStartParams = m_miItf->MHW_GETPAR_F(MI_BATCH_BUFFER_START)(); 203 miBatchBufferStartParams = {}; 204 miBatchBufferStartParams.secondLevelBatchBuffer = false; 205 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START)(&cmdBuffer, m_batchBuf)); 206 207 return MOS_STATUS_SUCCESS; 208 } 209 } 210