957 lines
47 KiB
C++
957 lines
47 KiB
C++
/*
|
|
* Copyright (C) 2021-2025 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "shared/source/built_ins/built_ins.h"
|
|
#include "shared/source/command_stream/command_stream_receiver.h"
|
|
#include "shared/source/debugger/debugger_l0.h"
|
|
#include "shared/source/helpers/aligned_memory.h"
|
|
#include "shared/source/helpers/gfx_core_helper.h"
|
|
#include "shared/source/memory_manager/memory_allocation.h"
|
|
#include "shared/source/os_interface/os_context.h"
|
|
#include "shared/test/common/fixtures/device_fixture.h"
|
|
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
|
#include "shared/test/common/helpers/engine_descriptor_helper.h"
|
|
#include "shared/test/common/helpers/variable_backup.h"
|
|
#include "shared/test/common/libult/global_environment.h"
|
|
#include "shared/test/common/mocks/mock_builtins.h"
|
|
#include "shared/test/common/mocks/mock_compiler_product_helper.h"
|
|
#include "shared/test/common/mocks/mock_compilers.h"
|
|
#include "shared/test/common/mocks/mock_device.h"
|
|
#include "shared/test/common/mocks/mock_execution_environment.h"
|
|
#include "shared/test/common/mocks/mock_io_functions.h"
|
|
#include "shared/test/common/mocks/mock_memory_manager.h"
|
|
#include "shared/test/common/mocks/mock_os_context.h"
|
|
#include "shared/test/common/mocks/mock_release_helper.h"
|
|
#include "shared/test/common/mocks/mock_sip.h"
|
|
#include "shared/test/common/test_macros/hw_test.h"
|
|
#include "shared/test/common/test_macros/test.h"
|
|
|
|
#include "common/StateSaveAreaHeader.h"
|
|
|
|
#include <map>
|
|
|
|
using namespace NEO;
|
|
namespace NEO {
|
|
extern std::map<std::string, std::stringstream> virtualFileList;
|
|
}
|
|
|
|
struct RawBinarySipFixture : public DeviceWithoutSipFixture {
|
|
void setUp() {
|
|
debugManager.flags.LoadBinarySipFromFile.set("dummy_file.bin");
|
|
|
|
backupSipInitType = std::make_unique<VariableBackup<bool>>(&MockSipData::useMockSip, false);
|
|
backupSipClassType = std::make_unique<VariableBackup<SipClassType>>(&SipKernel::classType);
|
|
|
|
backupFopenReturned = std::make_unique<VariableBackup<FILE *>>(&IoFunctions::mockFopenReturned);
|
|
backupFtellReturned = std::make_unique<VariableBackup<long int>>(&IoFunctions::mockFtellReturn, 128);
|
|
backupFreadReturned = std::make_unique<VariableBackup<size_t>>(&IoFunctions::mockFreadReturn, 128u);
|
|
|
|
backupFopenCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockFopenCalled, 0u);
|
|
backupFseekCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockFseekCalled, 0u);
|
|
backupFtellCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockFtellCalled, 0u);
|
|
backupRewindCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockRewindCalled, 0u);
|
|
backupFreadCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockFreadCalled, 0u);
|
|
backupFcloseCalled = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::mockFcloseCalled, 0u);
|
|
backupFailAfterNFopenCount = std::make_unique<VariableBackup<uint32_t>>(&IoFunctions::failAfterNFopenCount, 0u);
|
|
|
|
DeviceWithoutSipFixture::setUp();
|
|
}
|
|
|
|
void tearDown() {
|
|
DeviceWithoutSipFixture::tearDown();
|
|
}
|
|
|
|
DebugManagerStateRestore dbgRestorer;
|
|
|
|
std::unique_ptr<VariableBackup<bool>> backupSipInitType;
|
|
std::unique_ptr<VariableBackup<SipClassType>> backupSipClassType;
|
|
|
|
std::unique_ptr<VariableBackup<FILE *>> backupFopenReturned;
|
|
std::unique_ptr<VariableBackup<long int>> backupFtellReturned;
|
|
std::unique_ptr<VariableBackup<size_t>> backupFreadReturned;
|
|
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFopenCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFseekCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFtellCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupRewindCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFreadCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFcloseCalled;
|
|
std::unique_ptr<VariableBackup<uint32_t>> backupFailAfterNFopenCount;
|
|
};
|
|
|
|
TEST(SipBinaryFromFile, givenFilenameWhenCreatingHeaderFilenameThenSuffixIsAddedBeforeExtension) {
|
|
std::string fileName = "abc.bin";
|
|
auto headerName = MockSipKernel::createHeaderFilename(fileName);
|
|
EXPECT_EQ("abc_header.bin", headerName);
|
|
}
|
|
|
|
TEST(SipBinaryFromFile, givenFilenameWithoutExtnesionWhenCreatingHeaderFilenameThenSuffixIsAdded) {
|
|
std::string fileName = "abc";
|
|
auto headerName = MockSipKernel::createHeaderFilename(fileName);
|
|
EXPECT_EQ("abc_header", headerName);
|
|
}
|
|
|
|
using RawBinarySipTest = Test<RawBinarySipFixture>;
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenInitSipKernelThenSipIsLoadedFromFile) {
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(2u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
auto sipAllocation = SipKernel::getSipKernel(*pDevice, nullptr).getSipAllocation();
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
auto header = SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaHeader();
|
|
EXPECT_NE(0u, header.size());
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenFileHeaderMissingWhenInitSipKernelThenSipIsLoadedFromFileWithoutHeader) {
|
|
IoFunctions::failAfterNFopenCount = 1;
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(2u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
auto sipAllocation = SipKernel::getSipKernel(*pDevice, nullptr).getSipAllocation();
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
auto header = SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaHeader();
|
|
EXPECT_EQ(0u, header.size());
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenDebuggerAndRawBinaryFileWhenInitSipKernelThenDbgSipIsLoadedFromFile) {
|
|
pDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(pDevice);
|
|
auto currentSipKernelType = SipKernel::getSipKernelType(*pDevice);
|
|
bool ret = SipKernel::initSipKernel(currentSipKernelType, *pDevice);
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(2u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_LE(SipKernelType::dbgCsr, currentSipKernelType);
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(currentSipKernelType);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
auto sipAllocation = SipKernel::getSipKernel(*pDevice, nullptr).getSipAllocation();
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenOpenFileFailsThenSipIsNotLoadedFromFile) {
|
|
IoFunctions::mockFopenReturned = nullptr;
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_FALSE(ret);
|
|
|
|
EXPECT_EQ(1u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(0u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(0u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(0u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(0u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(0u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
EXPECT_EQ(nullptr, sipKernel);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenTellSizeDiffrentThanBytesReadThenSipIsNotCreated) {
|
|
IoFunctions::mockFtellReturn = 28;
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_FALSE(ret);
|
|
|
|
EXPECT_EQ(1u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
EXPECT_EQ(nullptr, sipKernel);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenBytesReadIsZeroThenSipIsNotCreated) {
|
|
IoFunctions::mockFreadReturn = 0u;
|
|
IoFunctions::mockFtellReturn = 0;
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_FALSE(ret);
|
|
|
|
EXPECT_EQ(1u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
EXPECT_EQ(nullptr, sipKernel);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenAllocationCreationFailsThenSipIsNotCreated) {
|
|
pDevice->executionEnvironment->memoryManager.reset(new FailMemoryManager(0, *pDevice->executionEnvironment));
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_FALSE(ret);
|
|
|
|
EXPECT_EQ(1u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(1u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
EXPECT_EQ(nullptr, sipKernel);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenInitSipKernelTwiceThenSipIsLoadedFromFileAndCreatedOnce) {
|
|
bool ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(2u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFcloseCalled);
|
|
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
auto &refSipKernel = SipKernel::getSipKernel(*pDevice, nullptr);
|
|
EXPECT_EQ(sipKernel, &refSipKernel);
|
|
|
|
auto sipAllocation = refSipKernel.getSipAllocation();
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
ret = SipKernel::initSipKernel(SipKernelType::csr, *pDevice);
|
|
EXPECT_TRUE(ret);
|
|
|
|
EXPECT_EQ(2u, IoFunctions::mockFopenCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFseekCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFtellCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockRewindCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFreadCalled);
|
|
EXPECT_EQ(2u, IoFunctions::mockFcloseCalled);
|
|
|
|
auto secondSipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, secondSipKernel);
|
|
auto secondStoredAllocation = sipKernel->getSipAllocation();
|
|
EXPECT_NE(nullptr, secondStoredAllocation);
|
|
EXPECT_EQ(sipKernel, secondSipKernel);
|
|
EXPECT_EQ(storedAllocation, secondStoredAllocation);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenGettingHeaplessDebugSipThenSipIsLoadedFromFile) {
|
|
|
|
auto compilerHelper = std::unique_ptr<MockCompilerProductHelper>(new MockCompilerProductHelper());
|
|
auto releaseHelper = std::unique_ptr<MockReleaseHelper>(new MockReleaseHelper());
|
|
compilerHelper->isHeaplessModeEnabledResult = true;
|
|
pDevice->getRootDeviceEnvironmentRef().compilerProductHelper.reset(compilerHelper.release());
|
|
pDevice->getRootDeviceEnvironmentRef().releaseHelper.reset(releaseHelper.release());
|
|
auto sipAllocation = SipKernel::getDebugSipKernel(*pDevice).getSipAllocation();
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::dbgHeapless);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
auto header = SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaHeader();
|
|
EXPECT_NE(0u, header.size());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenGettingBindlessDebugSipThenSipIsLoadedFromFile) {
|
|
|
|
auto compilerHelper = std::unique_ptr<MockCompilerProductHelper>(new MockCompilerProductHelper());
|
|
auto releaseHelper = std::unique_ptr<MockReleaseHelper>(new MockReleaseHelper());
|
|
compilerHelper->isHeaplessModeEnabledResult = false;
|
|
pDevice->getRootDeviceEnvironmentRef().compilerProductHelper.reset(compilerHelper.release());
|
|
pDevice->getRootDeviceEnvironmentRef().releaseHelper.reset(releaseHelper.release());
|
|
auto sipAllocation = SipKernel::getDebugSipKernel(*pDevice).getSipAllocation();
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::dbgBindless);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
auto header = SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaHeader();
|
|
EXPECT_NE(0u, header.size());
|
|
}
|
|
|
|
TEST_F(RawBinarySipTest, givenRawBinaryFileWhenGettingDebugSipWithContextThenSipIsLoadedFromFile) {
|
|
auto executionEnvironment = pDevice->getExecutionEnvironment();
|
|
const uint32_t contextId = 0u;
|
|
std::unique_ptr<OsContext> osContext(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
pDevice->getRootDeviceIndex(), contextId,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, pDevice->getDeviceBitfield())));
|
|
osContext->setDefaultContext(true);
|
|
|
|
auto sipAllocation = NEO::SipKernel::getDebugSipKernel(*pDevice, osContext.get()).getSipAllocation();
|
|
|
|
uint32_t sipIndex;
|
|
auto &compilerProductHelper = pDevice->getRootDeviceEnvironment().getHelper<CompilerProductHelper>();
|
|
if (compilerProductHelper.isHeaplessModeEnabled(*defaultHwInfo)) {
|
|
sipIndex = static_cast<uint32_t>(SipKernelType::dbgHeapless);
|
|
} else {
|
|
sipIndex = static_cast<uint32_t>(SipKernelType::dbgBindless);
|
|
}
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, sipKernel);
|
|
auto storedAllocation = sipKernel->getSipAllocation();
|
|
|
|
EXPECT_NE(nullptr, storedAllocation);
|
|
EXPECT_EQ(storedAllocation, sipAllocation);
|
|
|
|
auto header = SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaHeader();
|
|
EXPECT_NE(0u, header.size());
|
|
}
|
|
|
|
struct HexadecimalHeaderSipKernel : public SipKernel {
|
|
using SipKernel::getSipKernelImpl;
|
|
using SipKernel::initHexadecimalArraySipKernel;
|
|
};
|
|
|
|
using HexadecimalHeaderSipTest = Test<DeviceWithoutSipFixture>;
|
|
|
|
TEST_F(HexadecimalHeaderSipTest, whenInitHexadecimalArraySipKernelIsCalledThenSipKernelIsCorrect) {
|
|
VariableBackup<SipClassType> backupSipClassType(&SipKernel::classType, SipClassType::hexadecimalHeaderFile);
|
|
|
|
EXPECT_TRUE(HexadecimalHeaderSipKernel::initHexadecimalArraySipKernel(SipKernelType::csr, *pDevice));
|
|
EXPECT_EQ(SipKernelType::csr, SipKernel::getSipKernelType(*pDevice));
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
const auto expectedSipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
ASSERT_NE(nullptr, expectedSipKernel);
|
|
|
|
const auto &sipKernel = HexadecimalHeaderSipKernel::getSipKernelImpl(*pDevice);
|
|
EXPECT_EQ(expectedSipKernel, &sipKernel);
|
|
|
|
auto expectedSipAllocation = expectedSipKernel->getSipAllocation();
|
|
auto sipAllocation = sipKernel.getSipAllocation();
|
|
EXPECT_EQ(expectedSipAllocation, sipAllocation);
|
|
}
|
|
|
|
TEST_F(HexadecimalHeaderSipTest, givenFailMemoryManagerWhenInitHexadecimalArraySipKernelIsCalledThenSipKernelIsNullptr) {
|
|
pDevice->executionEnvironment->memoryManager.reset(new FailMemoryManager(0, *pDevice->executionEnvironment));
|
|
EXPECT_FALSE(HexadecimalHeaderSipKernel::initHexadecimalArraySipKernel(SipKernelType::csr, *pDevice));
|
|
|
|
uint32_t sipIndex = static_cast<uint32_t>(SipKernelType::csr);
|
|
auto sipKernel = pDevice->getRootDeviceEnvironment().sipKernels[sipIndex].get();
|
|
EXPECT_EQ(nullptr, sipKernel);
|
|
}
|
|
|
|
TEST_F(HexadecimalHeaderSipTest, whenInitHexadecimalArraySipKernelIsCalledTwiceThenSipKernelIsCreatedOnce) {
|
|
VariableBackup<SipClassType> backupSipClassType(&SipKernel::classType, SipClassType::hexadecimalHeaderFile);
|
|
EXPECT_TRUE(HexadecimalHeaderSipKernel::initHexadecimalArraySipKernel(SipKernelType::csr, *pDevice));
|
|
|
|
const auto &sipKernel = HexadecimalHeaderSipKernel::getSipKernelImpl(*pDevice);
|
|
EXPECT_TRUE(HexadecimalHeaderSipKernel::initHexadecimalArraySipKernel(SipKernelType::csr, *pDevice));
|
|
|
|
const auto &sipKernel2 = HexadecimalHeaderSipKernel::getSipKernelImpl(*pDevice);
|
|
EXPECT_EQ(&sipKernel, &sipKernel2);
|
|
|
|
auto sipAllocation = sipKernel.getSipAllocation();
|
|
auto sipAllocation2 = sipKernel2.getSipAllocation();
|
|
EXPECT_EQ(sipAllocation, sipAllocation2);
|
|
}
|
|
|
|
struct StateSaveAreaSipTest : Test<RawBinarySipFixture> {
|
|
void SetUp() override {
|
|
RawBinarySipFixture::setUp();
|
|
MockSipData::useMockSip = true;
|
|
stateSaveAreaHeaderBackup = MockSipData::mockSipKernel->mockStateSaveAreaHeader;
|
|
}
|
|
void TearDown() override {
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = std::move(stateSaveAreaHeaderBackup);
|
|
RawBinarySipFixture::tearDown();
|
|
}
|
|
VariableBackup<bool> backupSipInitType{&MockSipData::useMockSip};
|
|
std::vector<char> stateSaveAreaHeaderBackup;
|
|
};
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenEmptyStateSaveAreaHeaderWhenGetStateSaveAreaSizeCalledThenZeroSizeIsReturned) {
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader.clear();
|
|
EXPECT_EQ(0u, SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
}
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenCorruptedStateSaveAreaHeaderWhenGetStateSaveAreaSizeCalledThenZeroSizeIsReturned) {
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = {'g', 'a', 'r', 'b', 'a', 'g', 'e'};
|
|
EXPECT_EQ(0u, SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
}
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenCorrectStateSaveAreaHeaderWhenGetStateSaveAreaSizeCalledThenCorrectDbgSurfaceSizeIsReturned) {
|
|
auto hwInfo = pDevice->getHardwareInfo();
|
|
auto numSlices = NEO::GfxCoreHelper::getHighestEnabledSlice(hwInfo);
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(1);
|
|
EXPECT_EQ(0x1800u * numSlices * 2 * 16 * 7 + alignUp(sizeof(SIP::StateSaveAreaHeader), MemoryConstants::pageSize), SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);
|
|
EXPECT_EQ(0x1800u * numSlices * 8 * 7 + alignUp(sizeof(SIP::StateSaveAreaHeader), MemoryConstants::pageSize), SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(3);
|
|
auto fifoSize = 100 * sizeof(SIP::fifo_node);
|
|
auto stateSaveSize = 0x1800u * numSlices * 8 * 7 + sizeof(NEO::StateSaveAreaHeader);
|
|
EXPECT_EQ(alignUp(fifoSize + stateSaveSize, MemoryConstants::pageSize), SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
}
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenStateSaveAreaHeaderVersion4WhenGetStateSaveAreaSizeCalledThenTotalWmtpDataSizeIsReturned) {
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(4);
|
|
auto header = reinterpret_cast<SIP::StateSaveAreaHeader *>(MockSipData::mockSipKernel->mockStateSaveAreaHeader.data());
|
|
header->versionHeader.version.major = 4u;
|
|
EXPECT_EQ(MockSipData::totalWmtpDataSize, SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
}
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenStateSaveAreaHeaderVersion4WhenGetSipKernelIsCalledForCsrSipThenPreemptionSurfaceSizeIsUpdated) {
|
|
auto stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(4);
|
|
MockCompilerDebugVars debugVars = {};
|
|
debugVars.stateSaveAreaHeaderToReturn = stateSaveAreaHeader.data();
|
|
debugVars.stateSaveAreaHeaderToReturnSize = stateSaveAreaHeader.size();
|
|
gEnvironment->igcPushDebugVars(debugVars);
|
|
std::unique_ptr<void, void (*)(void *)> igcDebugVarsAutoPop{&gEnvironment, [](void *) -> void { gEnvironment->igcPopDebugVars(); }};
|
|
|
|
auto hwInfo = pDevice->getRootDeviceEnvironment().getMutableHardwareInfo();
|
|
hwInfo->capabilityTable.requiredPreemptionSurfaceSize = static_cast<size_t>(MockSipData::totalWmtpDataSize * 4);
|
|
EXPECT_NE(hwInfo->capabilityTable.requiredPreemptionSurfaceSize, MockSipData::totalWmtpDataSize);
|
|
|
|
auto builtins = pDevice->getBuiltIns();
|
|
EXPECT_EQ(MockSipData::totalWmtpDataSize, builtins->getSipKernel(SipKernelType::csr, *pDevice).getStateSaveAreaSize(pDevice));
|
|
EXPECT_EQ(hwInfo->capabilityTable.requiredPreemptionSurfaceSize, MockSipData::totalWmtpDataSize);
|
|
}
|
|
|
|
TEST_F(StateSaveAreaSipTest, givenNotsupportedStateSaveAreaHeaderVersionWhenGetStateSaveAreaSizeCalledThenNoSizeIsReturned) {
|
|
VariableBackup<bool> backupSipInitType(&MockSipData::useMockSip, true);
|
|
MockSipData::mockSipKernel->mockStateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(1);
|
|
auto header = reinterpret_cast<SIP::StateSaveAreaHeader *>(MockSipData::mockSipKernel->mockStateSaveAreaHeader.data());
|
|
header->versionHeader.version.major = 5u;
|
|
EXPECT_EQ(0u, SipKernel::getSipKernel(*pDevice, nullptr).getStateSaveAreaSize(pDevice));
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenDebuggerAndUseBindlessDebugSipWhenGettingSipTypeThenDebugBindlessTypeIsReturned) {
|
|
DebugManagerStateRestore restorer;
|
|
NEO::debugManager.flags.UseBindlessDebugSip.set(1);
|
|
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
mockDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(mockDevice.get());
|
|
|
|
auto sipType = NEO::SipKernel::getSipKernelType(*mockDevice);
|
|
|
|
auto &compilerProductHelper = mockDevice->getCompilerProductHelper();
|
|
auto heaplessEnabled = compilerProductHelper.isHeaplessModeEnabled(*defaultHwInfo);
|
|
if (heaplessEnabled) {
|
|
EXPECT_EQ(SipKernelType::dbgHeapless, sipType);
|
|
|
|
} else {
|
|
EXPECT_EQ(SipKernelType::dbgBindless, sipType);
|
|
}
|
|
}
|
|
|
|
TEST(DebugHeaplessSip, givenDebuggerAndUseHeaplessModeWhenGettingSipTypeThenDebugHeaplessTypeIsReturned) {
|
|
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
mockDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(mockDevice.get());
|
|
auto compilerHelper = std::unique_ptr<MockCompilerProductHelper>(new MockCompilerProductHelper());
|
|
auto releaseHelper = std::unique_ptr<MockReleaseHelper>(new MockReleaseHelper());
|
|
compilerHelper->isHeaplessModeEnabledResult = true;
|
|
mockDevice->executionEnvironment->rootDeviceEnvironments[0]->compilerProductHelper.reset(compilerHelper.release());
|
|
mockDevice->executionEnvironment->rootDeviceEnvironments[0]->releaseHelper.reset(releaseHelper.release());
|
|
|
|
auto sipType = NEO::SipKernel::getSipKernelType(*mockDevice);
|
|
|
|
EXPECT_EQ(SipKernelType::dbgHeapless, sipType);
|
|
}
|
|
|
|
TEST(Sip, WhenGettingTypeThenCorrectTypeIsReturned) {
|
|
std::vector<char> ssaHeader;
|
|
SipKernel csr{SipKernelType::csr, nullptr, ssaHeader};
|
|
EXPECT_EQ(SipKernelType::csr, csr.getType());
|
|
|
|
SipKernel dbgCsr{SipKernelType::dbgCsr, nullptr, ssaHeader};
|
|
EXPECT_EQ(SipKernelType::dbgCsr, dbgCsr.getType());
|
|
|
|
SipKernel dbgCsrLocal{SipKernelType::dbgCsrLocal, nullptr, ssaHeader};
|
|
EXPECT_EQ(SipKernelType::dbgCsrLocal, dbgCsrLocal.getType());
|
|
|
|
SipKernel undefined{SipKernelType::count, nullptr, ssaHeader};
|
|
EXPECT_EQ(SipKernelType::count, undefined.getType());
|
|
}
|
|
|
|
TEST(Sip, givenDebuggingInactiveWhenSipTypeIsQueriedThenCsrSipTypeIsReturned) {
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto sipType = SipKernel::getSipKernelType(*mockDevice);
|
|
EXPECT_EQ(SipKernelType::csr, sipType);
|
|
}
|
|
|
|
TEST(DebugSip, givenDebuggingActiveWhenSipTypeIsQueriedThenDbgCsrSipTypeIsReturned) {
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice.get());
|
|
|
|
mockDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(mockDevice.get());
|
|
|
|
auto sipType = SipKernel::getSipKernelType(*mockDevice);
|
|
EXPECT_LE(SipKernelType::dbgCsr, sipType);
|
|
}
|
|
|
|
TEST(DebugSip, givenBuiltInsWhenDbgCsrSipIsRequestedThenCorrectSipKernelIsReturned) {
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &builtins = *mockDevice->getBuiltIns();
|
|
auto &sipKernel = builtins.getSipKernel(SipKernelType::dbgCsr, *mockDevice);
|
|
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
EXPECT_EQ(SipKernelType::dbgCsr, sipKernel.getType());
|
|
}
|
|
|
|
TEST(DebugSip, givenDebugSipIsRequestedThenCorrectSipKernelIsReturned) {
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &sipKernel = NEO::SipKernel::getDebugSipKernel(*mockDevice);
|
|
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
auto &compilerProductHelper = mockDevice->getRootDeviceEnvironment().getHelper<CompilerProductHelper>();
|
|
if (compilerProductHelper.isHeaplessModeEnabled(*defaultHwInfo)) {
|
|
EXPECT_EQ(SipKernelType::dbgHeapless, sipKernel.getType());
|
|
} else {
|
|
EXPECT_EQ(SipKernelType::dbgBindless, sipKernel.getType());
|
|
}
|
|
|
|
EXPECT_FALSE(sipKernel.getStateSaveAreaHeader().empty());
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenContextWhenBindlessDebugSipIsRequestedThenCorrectSipKernelIsReturned) {
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
const uint32_t contextId = 0u;
|
|
std::unique_ptr<OsContext> osContext(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), contextId,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext->setDefaultContext(true);
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &sipKernel = NEO::SipKernel::getDebugSipKernel(*mockDevice, &csr->getOsContext());
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
|
|
auto contextSip = builtIns->perContextSipKernels[contextId].first.get();
|
|
|
|
EXPECT_NE(nullptr, contextSip);
|
|
EXPECT_EQ(SipKernelType::dbgBindless, contextSip->getType());
|
|
EXPECT_NE(nullptr, contextSip->getSipAllocation());
|
|
EXPECT_FALSE(contextSip->getStateSaveAreaHeader().empty());
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenOfflineDebuggingModeWhenGettingSipForContextThenCorrectSipKernelIsReturned) {
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
|
VariableBackup<bool> mockSipBackup(&MockSipData::useMockSip, false);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
const uint32_t contextId = 0u;
|
|
std::unique_ptr<OsContext> osContext(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), contextId,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext->setDefaultContext(true);
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &sipKernel = NEO::SipKernel::getSipKernel(*mockDevice, &csr->getOsContext());
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
|
|
auto contextSip = builtIns->perContextSipKernels[contextId].first.get();
|
|
|
|
EXPECT_NE(nullptr, contextSip);
|
|
EXPECT_EQ(SipKernelType::dbgBindless, contextSip->getType());
|
|
EXPECT_NE(nullptr, contextSip->getSipAllocation());
|
|
EXPECT_FALSE(contextSip->getStateSaveAreaHeader().empty());
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenTwoContextsWhenBindlessDebugSipIsRequestedThenEachSipKernelIsAssignedToADifferentContextId) {
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
const uint32_t context0Id = 0u;
|
|
std::unique_ptr<OsContext> osContext0(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), context0Id,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext0->setDefaultContext(true);
|
|
|
|
const uint32_t context1Id = 1u;
|
|
std::unique_ptr<OsContext> osContext1(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), context1Id,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext1->setDefaultContext(true);
|
|
|
|
auto &sipKernel1 = NEO::SipKernel::getDebugSipKernel(*mockDevice, osContext1.get());
|
|
auto &sipKernel0 = NEO::SipKernel::getDebugSipKernel(*mockDevice, osContext0.get());
|
|
EXPECT_NE(sipKernel0.getSipAllocation(), sipKernel1.getSipAllocation());
|
|
|
|
auto context0SipKernel = builtIns->perContextSipKernels[context0Id].first.get();
|
|
auto context1SipKernel = builtIns->perContextSipKernels[context1Id].first.get();
|
|
EXPECT_NE(context0SipKernel, context1SipKernel);
|
|
|
|
const auto alloc0Id = static_cast<MemoryAllocation *>(context0SipKernel->getSipAllocation())->id;
|
|
const auto alloc1Id = static_cast<MemoryAllocation *>(context1SipKernel->getSipAllocation())->id;
|
|
EXPECT_NE(alloc0Id, alloc1Id);
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenFailingSipAllocationWhenBindlessDebugSipWithContextIsRequestedThenSipAllocationInSipKernelIsNull) {
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
auto mockMemoryManager = new MockMemoryManager();
|
|
mockMemoryManager->isMockHostMemoryManager = true;
|
|
mockMemoryManager->forceFailureInPrimaryAllocation = true;
|
|
executionEnvironment->memoryManager.reset(mockMemoryManager);
|
|
|
|
const uint32_t contextId = 0u;
|
|
std::unique_ptr<OsContext> osContext(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), contextId,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext->setDefaultContext(true);
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &sipKernel = NEO::SipKernel::getDebugSipKernel(*mockDevice, &csr->getOsContext());
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
|
|
auto contextSip = builtIns->perContextSipKernels[contextId].first.get();
|
|
|
|
EXPECT_NE(nullptr, contextSip);
|
|
EXPECT_EQ(SipKernelType::dbgBindless, contextSip->getType());
|
|
EXPECT_EQ(nullptr, contextSip->getSipAllocation());
|
|
EXPECT_FALSE(contextSip->getStateSaveAreaHeader().empty());
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenCorrectSipKernelWhenReleasingAllocationManuallyThenFreeGraphicsMemoryIsSkippedOnDestruction) {
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
const uint32_t contextId = 0u;
|
|
std::unique_ptr<OsContext> osContext(OsContext::create(executionEnvironment->rootDeviceEnvironments[0]->osInterface.get(),
|
|
mockDevice->getRootDeviceIndex(), contextId,
|
|
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular}, PreemptionMode::ThreadGroup, mockDevice->getDeviceBitfield())));
|
|
osContext->setDefaultContext(true);
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
[[maybe_unused]] auto &sipKernel = NEO::SipKernel::getDebugSipKernel(*mockDevice, &csr->getOsContext());
|
|
|
|
mockDevice->getMemoryManager()->freeGraphicsMemory(builtIns->perContextSipKernels[contextId].first.get()->getSipAllocation());
|
|
builtIns->perContextSipKernels[contextId].first.reset(nullptr);
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenOfflineDebuggingModeWhenSipIsInitializedThenBinaryIsParsed) {
|
|
MockCompilerDebugVars igcDebugVars;
|
|
uint32_t binary[20] = {0};
|
|
binary[2] = 0xcafebead;
|
|
binary[6] = 0xcafebead;
|
|
igcDebugVars.binaryToReturnSize = sizeof(binary);
|
|
igcDebugVars.binaryToReturn = binary;
|
|
gEnvironment->igcPushDebugVars(igcDebugVars);
|
|
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
auto osContext = std::make_unique<OsContextMock>(0, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::regular}));
|
|
osContext->debuggableContext = true;
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
mockDevice->getBuiltIns()->getSipKernel(SipKernelType::dbgBindless, *mockDevice);
|
|
|
|
auto sipKernel = builtIns->sipKernels[static_cast<uint32_t>(SipKernelType::dbgBindless)].first.get();
|
|
|
|
EXPECT_NE(nullptr, sipKernel);
|
|
|
|
EXPECT_EQ(2u, sipKernel->getCtxOffset());
|
|
EXPECT_EQ(6u, sipKernel->getPidOffset());
|
|
EXPECT_EQ(sizeof(binary), sipKernel->getBinary().size());
|
|
|
|
gEnvironment->igcPopDebugVars();
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenOfflineDebuggingModeAndInvalidSipWhenSipIsInitializedThenContextIdOffsetsAreZero) {
|
|
MockCompilerDebugVars igcDebugVars;
|
|
uint32_t binary[20] = {0};
|
|
binary[19] = 0xcafebead;
|
|
igcDebugVars.binaryToReturnSize = sizeof(binary);
|
|
igcDebugVars.binaryToReturn = binary;
|
|
gEnvironment->igcPushDebugVars(igcDebugVars);
|
|
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
auto osContext = std::make_unique<OsContextMock>(0, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_RCS, EngineUsage::regular}));
|
|
osContext->debuggableContext = true;
|
|
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
mockDevice->getBuiltIns()->getSipKernel(SipKernelType::dbgBindless, *mockDevice);
|
|
|
|
auto sipKernel = builtIns->sipKernels[static_cast<uint32_t>(SipKernelType::dbgBindless)].first.get();
|
|
|
|
EXPECT_NE(nullptr, sipKernel);
|
|
|
|
EXPECT_EQ(0u, sipKernel->getCtxOffset());
|
|
EXPECT_EQ(0u, sipKernel->getPidOffset());
|
|
EXPECT_EQ(sizeof(binary), sipKernel->getBinary().size());
|
|
|
|
gEnvironment->igcPopDebugVars();
|
|
}
|
|
|
|
TEST(DebugBindlessSip, givenOfflineDebuggingModeWhenDebugSipForContextIsCreatedThenContextIdIsPatched) {
|
|
MockCompilerDebugVars igcDebugVars;
|
|
uint32_t binary[20] = {0};
|
|
binary[2] = 0xcafebead;
|
|
binary[6] = 0xcafebead;
|
|
igcDebugVars.binaryToReturnSize = sizeof(binary);
|
|
igcDebugVars.binaryToReturn = binary;
|
|
gEnvironment->igcPushDebugVars(igcDebugVars);
|
|
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(executionEnvironment->rootDeviceEnvironments[0].get(), builtIns);
|
|
executionEnvironment->setDebuggingMode(DebuggingMode::offline);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
auto osContext = std::make_unique<OsContextMock>(0, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::regular}));
|
|
osContext->debuggableContext = true;
|
|
osContext->offlineDumpCtxId = uint64_t(0xAA) << 32 | 0xBB;
|
|
auto csr = mockDevice->createCommandStreamReceiver();
|
|
csr->setupContext(*osContext);
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
// ensure once_flag has not already been satisfied
|
|
auto contextId = osContext->getContextId();
|
|
auto it = builtIns->perContextSipKernels.find(contextId);
|
|
if (it != builtIns->perContextSipKernels.end()) {
|
|
mockDevice->getMemoryManager()->freeGraphicsMemory(it->second.first->getSipAllocation());
|
|
|
|
builtIns->perContextSipKernels.erase(contextId);
|
|
}
|
|
builtIns->perContextSipKernels.erase(contextId);
|
|
|
|
auto &sipKernel = NEO::SipKernel::getDebugSipKernel(*mockDevice, &csr->getOsContext());
|
|
|
|
EXPECT_NE(nullptr, &sipKernel);
|
|
|
|
EXPECT_EQ(0u, sipKernel.getCtxOffset());
|
|
EXPECT_EQ(0u, sipKernel.getPidOffset());
|
|
EXPECT_EQ(0u, sipKernel.getBinary().size());
|
|
|
|
uint32_t *patchedBinary = reinterpret_cast<uint32_t *>(sipKernel.getSipAllocation()->getUnderlyingBuffer());
|
|
uint32_t low = static_cast<uint32_t>(osContext->getOfflineDumpContextId(0) & 0xFFFFFFFFu);
|
|
uint32_t high = static_cast<uint32_t>((osContext->getOfflineDumpContextId(0) >> 32) & 0xFFFFFFFFu);
|
|
EXPECT_EQ(low, patchedBinary[2]);
|
|
EXPECT_EQ(high, patchedBinary[6]);
|
|
|
|
gEnvironment->igcPopDebugVars();
|
|
}
|
|
class SipKernelMock : public SipKernel {
|
|
public:
|
|
using SipKernel::selectSipClassType;
|
|
};
|
|
|
|
using DebugBuiltinSipTest = Test<DeviceFixture>;
|
|
|
|
TEST_F(DebugBuiltinSipTest, givenDebuggerWhenInitSipKernelThenDbgSipIsLoadedFromBuiltin) {
|
|
VariableBackup<bool> mockSipBackup(&MockSipData::useMockSip, false);
|
|
pDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(pDevice);
|
|
auto sipKernelType = SipKernel::getSipKernelType(*pDevice);
|
|
EXPECT_TRUE(SipKernel::initSipKernel(sipKernelType, *pDevice));
|
|
EXPECT_LE(SipKernelType::dbgCsr, sipKernelType);
|
|
|
|
auto sipAllocation = SipKernel::getSipKernel(*pDevice, nullptr).getSipAllocation();
|
|
EXPECT_NE(nullptr, sipAllocation);
|
|
EXPECT_EQ(SipKernelMock::classType, SipClassType::builtins);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(DebugBuiltinSipTest, givenDebugFlagForForceSipClassWhenInitSipKernelThenProperSipClassIsSet) {
|
|
VariableBackup<bool> mockSipBackup(&MockSipData::useMockSip, false);
|
|
VariableBackup sipClassBackup(&SipKernelMock::classType);
|
|
DebugManagerStateRestore restorer;
|
|
|
|
debugManager.flags.ForceSipClass.set(static_cast<int32_t>(SipClassType::builtins));
|
|
EXPECT_TRUE(SipKernel::initSipKernel(SipKernelType::csr, *pDevice));
|
|
EXPECT_EQ(SipKernelMock::classType, SipClassType::builtins);
|
|
|
|
debugManager.flags.ForceSipClass.set(static_cast<int32_t>(SipClassType::hexadecimalHeaderFile));
|
|
EXPECT_TRUE(SipKernel::initSipKernel(SipKernelType::csr, *pDevice));
|
|
EXPECT_EQ(SipKernelMock::classType, SipClassType::hexadecimalHeaderFile);
|
|
|
|
SipKernel::freeSipKernels(&pDevice->getRootDeviceEnvironmentRef(), pDevice->getMemoryManager());
|
|
}
|
|
|
|
TEST_F(DebugBuiltinSipTest, givenDumpSipHeaderFileWhenGettingSipKernelThenSipHeaderFileIsCreated) {
|
|
DebugManagerStateRestore restorer;
|
|
NEO::debugManager.flags.DumpSipHeaderFile.set("sip");
|
|
|
|
pDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(pDevice);
|
|
|
|
auto &builtins = *pDevice->getBuiltIns();
|
|
builtins.getSipKernel(SipKernelType::dbgCsr, *pDevice);
|
|
|
|
EXPECT_EQ(1u, NEO::virtualFileList.size());
|
|
EXPECT_TRUE(NEO::virtualFileList.find("sip_header.bin") != NEO::virtualFileList.end());
|
|
}
|
|
|
|
TEST(SipTest, whenForcingBuiltinSipClassThenPreemptionSurfaceSizeIsSetBasedOnStateSaveAreaHeader) {
|
|
DebugManagerStateRestore restorer;
|
|
debugManager.flags.ForceSipClass.set(static_cast<int32_t>(SipClassType::builtins));
|
|
auto executionEnvironment = MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
|
|
auto &rootDeviceEnvironment = *executionEnvironment->rootDeviceEnvironments[0];
|
|
constexpr uint32_t initialPreemptionSurfaceSize = 0xdeadbeef;
|
|
rootDeviceEnvironment.getMutableHardwareInfo()->capabilityTable.requiredPreemptionSurfaceSize = initialPreemptionSurfaceSize;
|
|
auto builtIns = new NEO::MockBuiltins();
|
|
builtIns->callBaseGetSipKernel = true;
|
|
MockRootDeviceEnvironment::resetBuiltins(&rootDeviceEnvironment, builtIns);
|
|
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get(), executionEnvironment, 0u));
|
|
|
|
EXPECT_NE(nullptr, mockDevice);
|
|
|
|
auto &sipKernel = rootDeviceEnvironment.builtins->getSipKernel(NEO::SipKernelType::csr, *mockDevice);
|
|
|
|
auto preemptionSurfaceSize = rootDeviceEnvironment.getHardwareInfo()->capabilityTable.requiredPreemptionSurfaceSize;
|
|
EXPECT_NE(initialPreemptionSurfaceSize, preemptionSurfaceSize);
|
|
EXPECT_EQ(sipKernel.getStateSaveAreaSize(mockDevice.get()), preemptionSurfaceSize);
|
|
}
|
|
|
|
using DebugExternalLibSipTest = Test<DeviceFixture>;
|
|
|
|
HWTEST2_F(DebugExternalLibSipTest, givenDebuggerWhenInitSipKernelThenDbgSipIsLoadedFromBuiltIns, IsAtMostXe3Core) {
|
|
DebugManagerStateRestore restorer;
|
|
debugManager.flags.GetSipBinaryFromExternalLib.set(1);
|
|
VariableBackup<bool> mockSipBackup(&MockSipData::useMockSip, false);
|
|
pDevice->executionEnvironment->rootDeviceEnvironments[0]->initDebuggerL0(pDevice);
|
|
std::string fileName = "unk";
|
|
SipKernelMock::selectSipClassType(fileName, *pDevice);
|
|
EXPECT_EQ(SipKernelMock::classType, SipClassType::builtins);
|
|
}
|
|
|
|
TEST_F(DebugExternalLibSipTest, givenGetSipBinaryFromExternalLibRetunsTrueWhenGetSipExternalLibInterfaceIsCalledThenNullptrReturned) {
|
|
DebugManagerStateRestore restorer;
|
|
debugManager.flags.GetSipBinaryFromExternalLib.set(1);
|
|
EXPECT_EQ(nullptr, pDevice->getSipExternalLibInterface());
|
|
}
|