blob: 0e911debfe5c874719f8e8e53b8a9667bc7fbf54 [file] [log] [blame]
/*
* Copyright (c) 2019, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file mos_util_debug_next.cpp
//! \brief Common OS debug across different platform
//! \details Common OS debug across different platform
//!
#include "mos_util_debug_next.h"
#if MOS_MESSAGES_ENABLED
#include "mos_utilities_next.h"
extern const MOS_USER_FEATURE_VALUE_ID pcComponentUserFeatureKeys[MOS_COMPONENT_COUNT][3];
extern const uint8_t subComponentCount[MOS_COMPONENT_COUNT];
//!
//! \brief HLT file name template
//!
const char * const MosUtilDebug::m_mosLogPathTemplate = MOS_LOG_PATH_TEMPLATE;
//!
//! \brief DDI dump file name template
//!
const char * const MosUtilDebug::m_DdiLogPathTemplate = "%s\\ddi_dump_%d.%s";
const char * const *MosUtilDebug::m_mosLogLevelName = MOS_LogLevelName;
const char * const *MosUtilDebug::m_mosComponentName = MOS_ComponentName;
const MOS_USER_FEATURE_VALUE_ID (*const MosUtilDebug::m_pcComponentUserFeatureKeys)[3] = pcComponentUserFeatureKeys;
const uint8_t* const MosUtilDebug::m_subComponentCount = subComponentCount;
MOS_MESSAGE_PARAMS MosUtilDebug::m_mosMsgParams = {};
MOS_MESSAGE_PARAMS MosUtilDebug::m_mosMsgParamsDdiDump = {};
void MosUtilDebug::MosSetSubCompMessageLevel(MOS_COMPONENT_ID compID, uint8_t subCompID, MOS_MESSAGE_LEVEL msgLevel)
{
if (compID >= MOS_COMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid component %d.", compID);
return;
}
if (subCompID >= MOS_MAX_SUBCOMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid sub-component %d.", subCompID);
return;
}
if (msgLevel >= MOS_MESSAGE_LVL_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid msg level %d.", msgLevel);
return;
}
m_mosMsgParams.components[compID].subComponents[subCompID].uiMessageLevel = msgLevel;
}
void MosUtilDebug::MosSetCompMessageLevel(MOS_COMPONENT_ID compID, MOS_MESSAGE_LEVEL msgLevel)
{
if (compID >= MOS_COMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid component %d.", compID);
return;
}
if (msgLevel >= MOS_MESSAGE_LVL_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid msg level %d.", msgLevel);
return;
}
m_mosMsgParams.components[compID].component.uiMessageLevel = msgLevel;
}
void MosUtilDebug::MosSetCompMessageLevelAll(MOS_MESSAGE_LEVEL msgLevel)
{
if (msgLevel >= MOS_MESSAGE_LVL_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid msg level %d.", msgLevel);
return;
}
uint32_t i = 0;
for(i = 0; i < MOS_COMPONENT_COUNT; i++)
{
MosSetCompMessageLevel((MOS_COMPONENT_ID)i, msgLevel);
}
}
void MosUtilDebug::MosSubCompAssertEnableDisable(MOS_COMPONENT_ID compID, uint8_t subCompID, int32_t bEnable)
{
if (compID >= MOS_COMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid component %d.", compID);
return;
}
if (subCompID >= MOS_MAX_SUBCOMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid sub-component %d.", subCompID);
return;
}
m_mosMsgParams.components[compID].subComponents[subCompID].bAssertEnabled = bEnable;
}
void MosUtilDebug::MosCompAssertEnableDisable(MOS_COMPONENT_ID compID, int32_t bEnable)
{
if (compID >= MOS_COMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid component %d.", compID);
return;
}
m_mosMsgParams.components[compID].component.bAssertEnabled = bEnable;
}
void MosUtilDebug::MosMessageInitComponent(MOS_COMPONENT_ID compID, MOS_CONTEXT_HANDLE mosCtx)
{
uint32_t uiCompUserFeatureSetting = 0;
uint64_t uiSubCompUserFeatureSetting = 0;
uint8_t i = 0;
MOS_USER_FEATURE_VALUE_ID MessageKey = __MOS_USER_FEATURE_KEY_INVALID_ID;
MOS_USER_FEATURE_VALUE_ID BySubComponentsKey = __MOS_USER_FEATURE_KEY_INVALID_ID;
MOS_USER_FEATURE_VALUE_ID SubComponentsKey = __MOS_USER_FEATURE_KEY_INVALID_ID;
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
MOS_USER_FEATURE_VALUE_WRITE_DATA UserFeatureWriteData;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
if (compID >= MOS_COMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid component %d.", compID);
return;
}
MessageKey = m_pcComponentUserFeatureKeys[compID][0];
BySubComponentsKey = m_pcComponentUserFeatureKeys[compID][1];
SubComponentsKey = m_pcComponentUserFeatureKeys[compID][2];
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
MessageKey,
&UserFeatureData,
mosCtx);
// If the user feature key was not found, create it with the default value.
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUtilities::MosZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
UserFeatureWriteData.Value.u32Data = UserFeatureData.u32Data;
UserFeatureWriteData.ValueID = MessageKey;
MosUtilities::MosUserFeatureWriteValuesID(nullptr, &UserFeatureWriteData, 1, mosCtx);
}
uiCompUserFeatureSetting = UserFeatureData.u32Data;
// Extract the 3-bit message level and 1-bit assert flag setting for this component.
MosSetCompMessageLevel(compID, (MOS_MESSAGE_LEVEL) (uiCompUserFeatureSetting & 0x7));
MosCompAssertEnableDisable(compID, (uiCompUserFeatureSetting >> 3) & 0x1);
// Check if sub-components should be set seperately.
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
BySubComponentsKey,
&UserFeatureData,
mosCtx);
// If the user feature key was not found, create it with default (0) value.
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUtilities::MosZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
UserFeatureWriteData.Value.u32Data = UserFeatureData.u32Data;
UserFeatureWriteData.ValueID = BySubComponentsKey;
MosUtilities::MosUserFeatureWriteValuesID(nullptr, &UserFeatureWriteData, 1, mosCtx);
}
m_mosMsgParams.components[compID].bBySubComponent = UserFeatureData.u32Data;
// Set sub components:
if (m_mosMsgParams.components[compID].bBySubComponent)
{
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
SubComponentsKey,
&UserFeatureData,
mosCtx);
// If the user feature key was not found, create it with default (0) value.
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUtilities::MosZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
UserFeatureWriteData.Value.u64Data = UserFeatureData.u64Data;
UserFeatureWriteData.ValueID = SubComponentsKey;
MosUtilities::MosUserFeatureWriteValuesID(nullptr, &UserFeatureWriteData, 1, mosCtx);
}
uiSubCompUserFeatureSetting = UserFeatureData.u64Data;
for(i = 0; i < m_subComponentCount[compID]; i++)
{
// Extract the 3-bit message level and 1-bit assert flag setting for each sub-comp
// from the user feature key and populate to the MOS message params structure
MosSetSubCompMessageLevel(compID, i, (MOS_MESSAGE_LEVEL)(uiSubCompUserFeatureSetting & 0x7));
MosSubCompAssertEnableDisable(compID, i, (uiSubCompUserFeatureSetting >> 3) & 0x1);
uiSubCompUserFeatureSetting = (uiSubCompUserFeatureSetting >> 4);
}
}
}
MOS_STATUS MosUtilDebug::MosHLTInit(MOS_CONTEXT_HANDLE mosCtx)
{
uint32_t nPID = 0;
char hltFileName[MOS_MAX_HLT_FILENAME_LEN] = {0};
MOS_USER_FEATURE_VALUE UserFeatureValue = __NULL_USER_FEATURE_VALUE__;
char fileNamePrefix[MOS_MAX_HLT_FILENAME_LEN];
int32_t bUseHybridLogTrace = false;
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
MOS_USER_FEATURE_VALUE_WRITE_DATA UserFeatureWriteData;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
if (m_mosMsgParams.uiCounter != 0)
{
MOS_OS_NORMALMESSAGE("HLT settings already set.");
return MOS_STATUS_UNKNOWN;
}
m_mosMsgParams.bUseHybridLogTrace = false;
m_mosMsgParams.pLogFile = nullptr;
m_mosMsgParams.pTraceFile = nullptr;
// Check if HLT should be enabled.
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
__MOS_USER_FEATURE_KEY_MESSAGE_HLT_ENABLED_ID,
&UserFeatureData,
mosCtx);
// If the user feature key was not found, create it with the default value.
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUtilities::MosZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
UserFeatureWriteData.Value.u32Data = UserFeatureData.u32Data;
UserFeatureWriteData.ValueID = __MOS_USER_FEATURE_KEY_MESSAGE_HLT_ENABLED_ID;
MosUtilities::MosUserFeatureWriteValuesID(nullptr, &UserFeatureWriteData, 1, mosCtx);
}
bUseHybridLogTrace = MosUtilities::m_mosUltFlag ? 1 : UserFeatureData.u32Data;
// Dumping memory mapped regions to trace file disabled for now
// Need to add new user feature key or derive from the above key.
m_mosMsgParams.bEnableMaps = 0;
if (!bUseHybridLogTrace)
{
MOS_OS_NORMALMESSAGE("HLT not enabled.");
return MOS_STATUS_SUCCESS; //[SH]: Check this.
}
nPID = MosUtilities::m_mosUltFlag ? 0 : MosUtilities::MosGetPid();
// Get logfile directory.
MosLogFileNamePrefix(fileNamePrefix, mosCtx);
MosUtilities::MosSecureStringPrint(hltFileName, MOS_MAX_HLT_FILENAME_LEN, MOS_MAX_HLT_FILENAME_LEN-1, m_mosLogPathTemplate, fileNamePrefix, nPID, "log");
#if defined(LINUX) || defined(ANDROID)
eStatus = MosUtilities::MosCreateDirectory(fileNamePrefix);
if (MOS_FAILED(eStatus))
{
MOS_OS_NORMALMESSAGE("Failed to create output directory. Status = %d", eStatus);
}
#endif
eStatus = MosUtilities::MosSecureFileOpen(&m_mosMsgParams.pLogFile, hltFileName, "w");
if (MOS_FAILED(eStatus))
{
MOS_OS_NORMALMESSAGE("Failed to open log file '%s'.", hltFileName);
m_mosMsgParams.pLogFile = nullptr;
}
if(m_mosMsgParams.pLogFile == nullptr)
{
return MOS_STATUS_HLT_INIT_FAILED;
}
// Only if logfile init succeeded, bUseHybridLogTrace is set.
m_mosMsgParams.bUseHybridLogTrace = true;
// Output preface information
MosHltpPreface(m_mosMsgParams.pLogFile);
MOS_OS_NORMALMESSAGE("HLT initialized successfuly (%s).", hltFileName);
//[SH]: Trace and log are enabled with the same key right now. This can be changed to enable/disable them independently.
MosUtilities::MosSecureStringPrint(hltFileName, MOS_MAX_HLT_FILENAME_LEN, MOS_MAX_HLT_FILENAME_LEN-1, m_mosLogPathTemplate, fileNamePrefix, nPID, "hlt");
eStatus = MosUtilities::MosSecureFileOpen(&m_mosMsgParams.pTraceFile, hltFileName, "w");
if (MOS_FAILED(eStatus))
{
MOS_OS_NORMALMESSAGE("Failed to open trace file '%s'.", hltFileName);
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilDebug::MosDDIDumpInit(MOS_CONTEXT_HANDLE mosCtx)
{
char fileNamePrefix[MOS_MAX_HLT_FILENAME_LEN];
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
char cDDIDumpFilePath[MOS_MAX_HLT_FILENAME_LEN] = { 0 };
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
m_mosMsgParamsDdiDump.bUseHybridLogTrace = false;
m_mosMsgParamsDdiDump.pLogFile = nullptr;
m_mosMsgParamsDdiDump.pTraceFile = nullptr;
//Check if DDI dump is enabled
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_ENCODE_DDI_DUMP_ENABLE_ID,
&UserFeatureData,
mosCtx);
if (UserFeatureData.i32Data == 1)
{
//Check for the DDI dump path from the user feature key
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_DDI_DUMP_DIRECTORY_ID,
&UserFeatureData,
mosCtx);
// set-up DDI dump file name
MosUtilities::MosSecureStringPrint(cDDIDumpFilePath, MOS_MAX_HLT_FILENAME_LEN, MOS_MAX_HLT_FILENAME_LEN - 1, m_DdiLogPathTemplate,
(UserFeatureData.StringData.uSize > 0) ? UserFeatureData.StringData.pStringData : fileNamePrefix, MosUtilities::MosGetPid(), "log");
eStatus = MosUtilities::MosSecureFileOpen(&m_mosMsgParamsDdiDump.pLogFile, cDDIDumpFilePath, "w");
if (MOS_FAILED(eStatus))
{
MOS_OS_NORMALMESSAGE("Failed to open log file '%s'.", cDDIDumpFilePath);
m_mosMsgParamsDdiDump.pLogFile = nullptr;
}
}
return MOS_STATUS_SUCCESS;
}
void MosUtilDebug::MosMessageInit(MOS_CONTEXT_HANDLE mosCtx)
{
uint8_t i = 0;
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
MOS_USER_FEATURE_VALUE_WRITE_DATA UserFeatureWriteData;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
if(m_mosMsgParams.uiCounter == 0) // first time only
{
// Set all sub component messages to critical level by default.
MosSetCompMessageLevelAll(MOS_MESSAGE_LVL_CRITICAL);
// Set print level and asserts for each component
for(i = 0; i < MOS_COMPONENT_COUNT; i++)
{
MosMessageInitComponent((MOS_COMPONENT_ID)i, mosCtx);
}
// Check if MOS messages are enabled
MosUtilities::MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUtilities::MosUserFeatureReadValueID(
nullptr,
__MOS_USER_FEATURE_KEY_MESSAGE_PRINT_ENABLED_ID,
&UserFeatureData,
mosCtx);
// If the user feature key was not found, create it with default value.
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUtilities::MosZeroMemory(&UserFeatureWriteData, sizeof(UserFeatureWriteData));
UserFeatureWriteData.Value.i32Data = UserFeatureData.i32Data;
UserFeatureWriteData.ValueID = __MOS_USER_FEATURE_KEY_MESSAGE_PRINT_ENABLED_ID;
MosUtilities::MosUserFeatureWriteValuesID(nullptr, &UserFeatureWriteData, 1, mosCtx);
}
m_mosMsgParams.bUseOutputDebugString = UserFeatureData.i32Data;
if (MosUtilities::m_mosUltFlag)
{
MosSetCompMessageLevelAll(MOS_MESSAGE_LVL_DISABLED);
MosSetCompMessageLevel(MOS_COMPONENT_OS, MOS_MESSAGE_LVL_MEMNINJA);
m_mosMsgParams.bUseOutputDebugString = 0;
m_mosMsgParams.components[MOS_COMPONENT_OS].bBySubComponent = 0;
MosCompAssertEnableDisable(MOS_COMPONENT_CM, 0);
}
MosHLTInit(mosCtx);
MosDDIDumpInit(mosCtx);
// all above action should not be covered by memninja since its destroy is behind memninja counter report to test result.
MosUtilities::m_mosMemAllocCounter = 0;
MosUtilities::m_mosMemAllocFakeCounter = 0;
MosUtilities::m_mosMemAllocCounterGfx = 0;
MOS_OS_VERBOSEMESSAGE("MemNinja leak detection begin");
}
// uiCounter's thread safety depends on global_lock in VPG_Initialize
m_mosMsgParams.uiCounter++; // Will be zero initially since it is part of a global structure.
}
void MosUtilDebug::MosHLTClose()
{
if(m_mosMsgParams.pTraceFile != nullptr)
{
fclose(m_mosMsgParams.pTraceFile);
m_mosMsgParams.pTraceFile = nullptr;
MOS_OS_NORMALMESSAGE("Trace file is closed.");
}
if(m_mosMsgParams.pLogFile != nullptr)
{
MOS_OS_NORMALMESSAGE("Log file is closing, total services %d.",
m_mosMsgParams.uiCounter);
fclose(m_mosMsgParams.pLogFile);
m_mosMsgParams.pLogFile = nullptr;
}
}
void MosUtilDebug::MosDDIDumpClose()
{
if (m_mosMsgParamsDdiDump.pLogFile != nullptr)
{
fclose(m_mosMsgParamsDdiDump.pLogFile);
m_mosMsgParamsDdiDump.pLogFile = nullptr;
MOS_OS_NORMALMESSAGE("Encode DDI Dump file closing");
}
}
void MosUtilDebug::MosMessageClose()
{
// uiCounter's thread safety depends on global_lock in VPG_Terminate
if(m_mosMsgParams.uiCounter == 1)
{
MosDDIDumpClose();
MosHLTClose();
MosUtilities::MosZeroMemory(&m_mosMsgParams, sizeof(MOS_MESSAGE_PARAMS));
}
else
{
m_mosMsgParams.uiCounter--;
}
}
int32_t MosUtilDebug::MosShouldPrintMessage(
MOS_MESSAGE_LEVEL level,
MOS_COMPONENT_ID compID,
uint8_t subCompID,
const char * const message)
{
if (message == nullptr)
{
return false;
}
if (compID >= MOS_COMPONENT_COUNT ||
subCompID >= MOS_MAX_SUBCOMPONENT_COUNT ||
level >= MOS_MESSAGE_LVL_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid compoent ID %d, subCompID %d, and msg level %d.", compID, subCompID, level);
return false;
}
// Check if message level set for comp (and if needed for subcomp) is equal or greater than requested level
if (m_mosMsgParams.components[compID].component.uiMessageLevel < level)
{
return false;
}
if (m_mosMsgParams.components[compID].bBySubComponent &&
m_mosMsgParams.components[compID].subComponents[subCompID].uiMessageLevel < level)
{
return false;
}
return true;
}
#if MOS_ASSERT_ENABLED
int32_t MosUtilDebug::MosShouldAssert(MOS_COMPONENT_ID compID, uint8_t subCompID)
{
if (compID >= MOS_COMPONENT_COUNT ||
subCompID >= MOS_MAX_SUBCOMPONENT_COUNT)
{
MOS_OS_ASSERTMESSAGE("Invalid compoent ID %d, subCompID %d", compID, subCompID);
return false;
}
if (!m_mosMsgParams.components[compID].component.bAssertEnabled)
{
return false;
}
if (m_mosMsgParams.components[compID].bBySubComponent &&
!m_mosMsgParams.components[compID].subComponents[subCompID].bAssertEnabled)
{
return false;
}
return true;
}
#endif // MOS_ASSERT_ENABLED
#endif // MOS_MESSAGES_ENABLED