Source Level Debugger - add MI_LOAD_REG debug cmds

- add 2 MI_LOAD_REGISTER_IMM cmds in preamble when debugger
is active

Change-Id: I4dd46a3c01fc95feadf8a12728ce801efe506e05
This commit is contained in:
Hoppe, Mateusz 2018-04-13 11:50:57 +02:00 committed by sys_ocldev
parent 079f94cd2d
commit 87f0dcda36
5 changed files with 148 additions and 2 deletions

View File

@ -88,7 +88,9 @@ void PreambleHelper<SKLFamily>::programThreadArbitration(LinearStream *pCommandS
template <>
size_t PreambleHelper<SKLFamily>::getAdditionalCommandsSize(const Device &device) {
return PreemptionHelper::getRequiredPreambleSize<SKLFamily>(device) + sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL);
size_t totalSize = PreemptionHelper::getRequiredPreambleSize<SKLFamily>(device) + sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL);
totalSize += getKernelDebuggingCommandsSize(device.isSourceLevelDebuggerActive());
return totalSize;
}
template struct PreambleHelper<SKLFamily>;

View File

@ -50,8 +50,10 @@ struct PreambleHelper {
static void programVFEState(LinearStream *pCommandStream, const HardwareInfo &hwInfo, int scratchSize, uint64_t scratchAddress);
static void programPreamble(LinearStream *pCommandStream, Device &device, uint32_t l3Config,
uint32_t requiredThreadArbitrationPolicy, GraphicsAllocation *preemptionCsr);
static void programKernelDebugging(LinearStream *pCommandStream);
static uint32_t getL3Config(const HardwareInfo &hwInfo, bool useSLM);
static size_t getAdditionalCommandsSize(const Device &device);
static size_t getKernelDebuggingCommandsSize(bool debuggingActive);
static void programGenSpecificPreambleWorkArounds(LinearStream *pCommandStream, const HardwareInfo &hwInfo);
static uint32_t getUrbEntryAllocationSize();
};
@ -78,4 +80,14 @@ struct L3CNTLRegisterOffset {
static const uint32_t registerOffset;
};
namespace DebugModeRegisterOffset {
static constexpr uint32_t registerOffset = 0x20ec;
static constexpr uint32_t debugEnabledValue = (1 << 6) | (1 << 22);
}; // namespace DebugModeRegisterOffset
namespace TdDebugControlRegisterOffset {
static constexpr uint32_t registerOffset = 0xe400;
static constexpr uint32_t debugEnabledValue = (1 << 4) | (1 << 7);
}; // namespace TdDebugControlRegisterOffset
} // namespace OCLRT

View File

@ -47,7 +47,8 @@ void PreambleHelper<GfxFamily>::programGenSpecificPreambleWorkArounds(LinearStre
template <typename GfxFamily>
size_t PreambleHelper<GfxFamily>::getAdditionalCommandsSize(const Device &device) {
return 0;
size_t totalSize = getKernelDebuggingCommandsSize(device.isSourceLevelDebuggerActive());
return totalSize;
}
template <typename GfxFamily>
@ -84,6 +85,9 @@ void PreambleHelper<GfxFamily>::programPreamble(LinearStream *pCommandStream, De
programL3(pCommandStream, l3Config);
programThreadArbitration(pCommandStream, requiredThreadArbitrationPolicy);
programPreemption(pCommandStream, device, preemptionCsr);
if (device.isSourceLevelDebuggerActive()) {
programKernelDebugging(pCommandStream);
}
programGenSpecificPreambleWorkArounds(pCommandStream, device.getHardwareInfo());
}
@ -96,4 +100,26 @@ template <typename GfxFamily>
uint32_t PreambleHelper<GfxFamily>::getUrbEntryAllocationSize() {
return 0x782;
}
template <typename GfxFamily>
void PreambleHelper<GfxFamily>::programKernelDebugging(LinearStream *pCommandStream) {
auto pCmd = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(pCommandStream->getSpace(sizeof(MI_LOAD_REGISTER_IMM)));
*pCmd = MI_LOAD_REGISTER_IMM::sInit();
pCmd->setRegisterOffset(DebugModeRegisterOffset::registerOffset);
pCmd->setDataDword(DebugModeRegisterOffset::debugEnabledValue);
auto pCmd2 = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(pCommandStream->getSpace(sizeof(MI_LOAD_REGISTER_IMM)));
*pCmd2 = MI_LOAD_REGISTER_IMM::sInit();
pCmd2->setRegisterOffset(TdDebugControlRegisterOffset::registerOffset);
pCmd2->setDataDword(TdDebugControlRegisterOffset::debugEnabledValue);
}
template <typename GfxFamily>
size_t PreambleHelper<GfxFamily>::getKernelDebuggingCommandsSize(bool debuggingActive) {
if (debuggingActive) {
return 2 * sizeof(MI_LOAD_REGISTER_IMM);
}
return 0;
}
} // namespace OCLRT

View File

@ -57,3 +57,17 @@ GEN9TEST_F(PreambleTestGen9, givenMidThreadPreemptionAndDisabledDebuggingWhenPre
GEN9TEST_F(PreambleTestGen9, givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturned) {
SourceLevelDebuggerPreambleTest<FamilyType>::givenDisabledPreemptionAndDisabledDebuggingWhenPreambleSizeIsQueriedThenCorrecrSizeIsReturnedTest();
}
GEN9TEST_F(PreambleTestGen9, givenKernelDebuggingActiveAndDisabledPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAndStateSipAreInlcuded) {
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
mockDevice->setSourceLevelDebuggerActive(false);
size_t withoutDebugging = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
mockDevice->setSourceLevelDebuggerActive(true);
size_t withDebugging = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
EXPECT_LT(withoutDebugging, withDebugging);
size_t diff = withDebugging - withoutDebugging;
size_t sizeExpected = sizeof(typename FamilyType::STATE_SIP) + 2 * sizeof(typename FamilyType::MI_LOAD_REGISTER_IMM);
EXPECT_EQ(sizeExpected, diff);
}

View File

@ -24,6 +24,7 @@
#include "runtime/helpers/preamble.h"
#include "runtime/utilities/stackvec.h"
#include "unit_tests/gen_common/test.h"
#include "unit_tests/helpers/hw_parse.h"
#include "unit_tests/mocks/mock_device.h"
#include "unit_tests/mocks/mock_graphics_allocation.h"
@ -74,3 +75,94 @@ HWTEST_F(PreambleTest, PreemptionIsTakenIntoAccountWhenProgrammingPreamble) {
&preemptionBuffer[0], &preemptionBuffer[preemptionStream.getUsed()]);
EXPECT_NE(&preambleBuffer[preambleStream.getUsed()], it);
}
HWTEST_F(PreambleTest, givenActiveKernelDebuggingWhenPreambleKernelDebuggingCommandsSizeIsQueriedThenCorrectSizeIsReturned) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
auto size = PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(true);
auto sizeExpected = 2 * sizeof(MI_LOAD_REGISTER_IMM);
EXPECT_EQ(sizeExpected, size);
}
HWTEST_F(PreambleTest, givenInactiveKernelDebuggingWhenPreambleKernelDebuggingCommandsSizeIsQueriedThenZeroIsReturned) {
auto size = PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(false);
EXPECT_EQ(0u, size);
}
HWTEST_F(PreambleTest, whenKernelDebuggingCommandsAreProgrammedThenCorrectCommandsArePlacedIntoStream) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
auto bufferSize = PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(true);
auto buffer = std::unique_ptr<char[]>(new char[bufferSize]);
LinearStream stream(buffer.get(), bufferSize);
PreambleHelper<FamilyType>::programKernelDebugging(&stream);
HardwareParse hwParser;
hwParser.parseCommands<FamilyType>(stream);
auto cmdList = hwParser.getCommandsList<MI_LOAD_REGISTER_IMM>();
ASSERT_EQ(2u, cmdList.size());
auto it = cmdList.begin();
MI_LOAD_REGISTER_IMM *pCmd = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*it);
EXPECT_EQ(DebugModeRegisterOffset::registerOffset, pCmd->getRegisterOffset());
EXPECT_EQ(DebugModeRegisterOffset::debugEnabledValue, pCmd->getDataDword());
it++;
pCmd = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*it);
EXPECT_EQ(TdDebugControlRegisterOffset::registerOffset, pCmd->getRegisterOffset());
EXPECT_EQ(TdDebugControlRegisterOffset::debugEnabledValue, pCmd->getDataDword());
}
HWTEST_F(PreambleTest, givenKernelDebuggingActiveWhenPreambleIsProgrammedThenProgramKernelDebuggingIsCalled) {
typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
mockDevice->setPreemptionMode(PreemptionMode::Disabled);
mockDevice->setSourceLevelDebuggerActive(false);
StackVec<char, 8192> preambleBuffer(8192);
LinearStream preambleStream(&*preambleBuffer.begin(), preambleBuffer.size());
PreambleHelper<FamilyType>::programPreamble(&preambleStream, *mockDevice, 0U,
ThreadArbitrationPolicy::RoundRobin, nullptr);
HardwareParse hwParser;
hwParser.parseCommands<FamilyType>(preambleStream);
auto cmdList = hwParser.getCommandsList<MI_LOAD_REGISTER_IMM>();
auto miLoadRegImmCountWithoutDebugging = cmdList.size();
mockDevice->setSourceLevelDebuggerActive(true);
StackVec<char, 8192> preambleBuffer2(8192);
preambleStream.replaceBuffer(&*preambleBuffer2.begin(), preambleBuffer2.size());
PreambleHelper<FamilyType>::programPreamble(&preambleStream, *mockDevice, 0U,
ThreadArbitrationPolicy::RoundRobin, nullptr);
HardwareParse hwParser2;
hwParser2.parseCommands<FamilyType>(preambleStream);
cmdList = hwParser2.getCommandsList<MI_LOAD_REGISTER_IMM>();
auto miLoadRegImmCountWithDebugging = cmdList.size();
ASSERT_LT(miLoadRegImmCountWithoutDebugging, miLoadRegImmCountWithDebugging);
EXPECT_EQ(2u, miLoadRegImmCountWithDebugging - miLoadRegImmCountWithoutDebugging);
}
HWTEST_F(PreambleTest, givenKernelDebuggingActiveAndMidThreadPreemptionWhenGetAdditionalCommandsSizeIsCalledThen2MiLoadRegisterImmCmdsAreAdded) {
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
mockDevice->setPreemptionMode(PreemptionMode::MidThread);
mockDevice->setSourceLevelDebuggerActive(false);
size_t withoutDebugging = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
mockDevice->setSourceLevelDebuggerActive(true);
size_t withDebugging = PreambleHelper<FamilyType>::getAdditionalCommandsSize(*mockDevice);
EXPECT_LT(withoutDebugging, withDebugging);
size_t diff = withDebugging - withoutDebugging;
size_t sizeExpected = 2 * sizeof(typename FamilyType::MI_LOAD_REGISTER_IMM);
EXPECT_EQ(sizeExpected, diff);
}