From 56109b882fa143ea2db790d5491ddea0bbe5cb6b Mon Sep 17 00:00:00 2001 From: Matias Cabral Date: Tue, 27 Sep 2022 12:10:18 +0000 Subject: [PATCH] Support debugger SLM write Resolves: NEO-5998 Signed-off-by: Matias Cabral --- .../tools/source/debug/debug_session_imp.cpp | 102 ++++++- .../tools/source/debug/debug_session_imp.h | 5 + .../debug/linux/prelim/debug_session.cpp | 13 +- .../source/debug/linux/prelim/debug_session.h | 2 + .../sources/debug/debug_session_tests.cpp | 262 ++++++++++++++++-- .../debug/linux/test_debug_api_linux.cpp | 9 +- 6 files changed, 353 insertions(+), 40 deletions(-) diff --git a/level_zero/tools/source/debug/debug_session_imp.cpp b/level_zero/tools/source/debug/debug_session_imp.cpp index 27d0bb4c01..1c30badb9b 100644 --- a/level_zero/tools/source/debug/debug_session_imp.cpp +++ b/level_zero/tools/source/debug/debug_session_imp.cpp @@ -16,8 +16,6 @@ #include "level_zero/core/source/hw_helpers/l0_hw_helper.h" #include "level_zero/include/zet_intel_gpu_debug.h" -#include "common/StateSaveAreaHeader.h" - namespace L0 { DebugSession::DebugSession(const zet_debug_config_t &config, Device *device) : connectedDevice(device) { @@ -1262,7 +1260,6 @@ ze_result_t DebugSessionImp::waitForCmdReady(EuThread::ThreadId threadId, uint16 ze_result_t DebugSessionImp::readSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) { ze_result_t status; SIP::sip_command sipCommand = {0}; - char *output = static_cast(buffer); status = waitForCmdReady(threadId, sipRetryCount); if (status != ZE_RESULT_SUCCESS) { @@ -1271,7 +1268,7 @@ ze_result_t DebugSessionImp::readSLMMemory(EuThread::ThreadId threadId, const ze uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag); - // SIP accesses SLM in read units of slmSendBytesSize at offset units of the same size + // SIP accesses SLM in units of slmSendBytesSize at offset units of the same size uint32_t offsetUnits = static_cast(std::ceil(static_cast(offset) / slmSendBytesSize)); uint32_t frontPadding = offset % slmSendBytesSize; uint32_t remainingSlmSendUnits = static_cast(std::ceil(static_cast(size) / slmSendBytesSize)); @@ -1283,12 +1280,11 @@ ze_result_t DebugSessionImp::readSLMMemory(EuThread::ThreadId threadId, const ze } } - uint32_t maxUnitsPerLoop = EXCHANGE_BUFFER_SIZE / slmSendBytesSize; uint32_t loops = static_cast(std::ceil(static_cast(remainingSlmSendUnits) / maxUnitsPerLoop)); - char *tmpBuffer = new char[remainingSlmSendUnits * slmSendBytesSize]; + std::unique_ptr tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]); uint32_t readUnits = 0; - uint32_t bytesAlreadRead = 0; + uint32_t bytesAlreadyRead = 0; sipCommand.offset = offsetUnits; @@ -1305,38 +1301,114 @@ ze_result_t DebugSessionImp::readSLMMemory(EuThread::ThreadId threadId, const ze status = cmdRegisterAccessHelper(threadId, sipCommand, true); if (status != ZE_RESULT_SUCCESS) { - delete[] tmpBuffer; return status; } status = resumeImp(std::vector{threadId}, threadId.tileIndex); if (status != ZE_RESULT_SUCCESS) { - delete[] tmpBuffer; return status; } status = waitForCmdReady(threadId, sipRetryCount); if (status != ZE_RESULT_SUCCESS) { - delete[] tmpBuffer; return status; } status = cmdRegisterAccessHelper(threadId, sipCommand, false); if (status != ZE_RESULT_SUCCESS) { - delete[] tmpBuffer; return status; } - memcpy_s(tmpBuffer + bytesAlreadRead, readUnits * slmSendBytesSize, sipCommand.buffer, readUnits * slmSendBytesSize); + memcpy_s(tmpBuffer.get() + bytesAlreadyRead, readUnits * slmSendBytesSize, sipCommand.buffer, readUnits * slmSendBytesSize); remainingSlmSendUnits -= readUnits; sipCommand.offset += readUnits; - bytesAlreadRead += readUnits * slmSendBytesSize; + bytesAlreadyRead += readUnits * slmSendBytesSize; } - memcpy_s(output, size, tmpBuffer + frontPadding, size); + memcpy_s(buffer, size, tmpBuffer.get() + frontPadding, size); - delete[] tmpBuffer; + return ZE_RESULT_SUCCESS; +} + +ze_result_t DebugSessionImp::writeSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) { + ze_result_t status; + SIP::sip_command sipCommand = {0}; + + uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag); + // SIP accesses SLM in units of slmSendBytesSize at offset units of the same size + uint32_t offsetUnits = static_cast(std::ceil(static_cast(offset) / slmSendBytesSize)); + uint32_t frontPadding = offset % slmSendBytesSize; + uint32_t remainingSlmSendUnits = static_cast(std::ceil(static_cast(size) / slmSendBytesSize)); + size_t tailPadding = (size % slmSendBytesSize) ? slmSendBytesSize - (size % slmSendBytesSize) : 0; + + if (frontPadding) { + offsetUnits--; + + if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) { + remainingSlmSendUnits++; + } + } + + std::unique_ptr tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]); + + if ((frontPadding || tailPadding)) { + + zet_debug_memory_space_desc_t allignedDesc = *desc; + allignedDesc.address = desc->address - frontPadding; + size_t allignedSize = remainingSlmSendUnits * slmSendBytesSize; + + status = readSLMMemory(threadId, &allignedDesc, allignedSize, tmpBuffer.get()); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + } + + memcpy_s(tmpBuffer.get() + frontPadding, size, buffer, size); + + status = waitForCmdReady(threadId, sipRetryCount); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + uint32_t loops = static_cast(std::ceil(static_cast(remainingSlmSendUnits) / maxUnitsPerLoop)); + + uint32_t writeUnits = 0; + uint32_t bytesAlreadyWritten = 0; + + sipCommand.offset = offsetUnits; + + for (uint32_t loop = 0; loop < loops; loop++) { + + if (remainingSlmSendUnits >= maxUnitsPerLoop) { + writeUnits = maxUnitsPerLoop; + } else { + writeUnits = remainingSlmSendUnits; + } + + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::SLM_WRITE); + sipCommand.size = static_cast(writeUnits); + memcpy_s(sipCommand.buffer, writeUnits * slmSendBytesSize, tmpBuffer.get() + bytesAlreadyWritten, writeUnits * slmSendBytesSize); + + status = cmdRegisterAccessHelper(threadId, sipCommand, true); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + status = resumeImp(std::vector{threadId}, threadId.tileIndex); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + status = waitForCmdReady(threadId, sipRetryCount); + if (status != ZE_RESULT_SUCCESS) { + return status; + } + + remainingSlmSendUnits -= writeUnits; + sipCommand.offset += writeUnits; + bytesAlreadyWritten += writeUnits * slmSendBytesSize; + } return ZE_RESULT_SUCCESS; } diff --git a/level_zero/tools/source/debug/debug_session_imp.h b/level_zero/tools/source/debug/debug_session_imp.h index 8235286b67..7c538efe13 100644 --- a/level_zero/tools/source/debug/debug_session_imp.h +++ b/level_zero/tools/source/debug/debug_session_imp.h @@ -11,6 +11,8 @@ #include "level_zero/tools/source/debug/debug_session.h" +#include "common/StateSaveAreaHeader.h" + #include #include #include @@ -80,6 +82,8 @@ struct DebugSessionImp : DebugSession { virtual ze_result_t writeGpuMemory(uint64_t memoryHandle, const char *input, size_t size, uint64_t gpuVa) = 0; ze_result_t readSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer); + ze_result_t writeSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, + size_t size, const void *buffer); ze_result_t validateThreadAndDescForMemoryAccess(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc); @@ -160,6 +164,7 @@ struct DebugSessionImp : DebugSession { constexpr static uint16_t slmAddressSpaceTag = 28; constexpr static uint16_t slmSendBytesSize = 16; constexpr static uint16_t sipRetryCount = 10; + uint32_t maxUnitsPerLoop = EXCHANGE_BUFFER_SIZE / slmSendBytesSize; }; } // namespace L0 diff --git a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp index 9dc1249362..354e38a7f9 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp @@ -1568,10 +1568,19 @@ ze_result_t DebugSessionLinux::writeMemory(ze_device_thread_t thread, const zet_ return status; } - if (desc->type != ZET_DEBUG_MEMORY_SPACE_TYPE_DEFAULT) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + if (desc->type == ZET_DEBUG_MEMORY_SPACE_TYPE_DEFAULT) { + status = writeDefaultMemory(thread, desc, size, buffer); + } else { + auto threadId = convertToThreadId(thread); + status = writeSLMMemory(threadId, desc, size, buffer); } + return status; +} + +ze_result_t DebugSessionLinux::writeDefaultMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) { + ze_result_t status; + auto deviceBitfield = connectedDevice->getNEODevice()->getDeviceBitfield(); bool isa = tryWriteIsa(deviceBitfield, desc, size, buffer, status); diff --git a/level_zero/tools/source/debug/linux/prelim/debug_session.h b/level_zero/tools/source/debug/linux/prelim/debug_session.h index f94f3e02c8..a8162761ee 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.h +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.h @@ -267,6 +267,8 @@ struct DebugSessionLinux : DebugSessionImp { ze_result_t accessDefaultMemForThreadAll(const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer, bool write); ze_result_t readDefaultMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer); + ze_result_t writeDefaultMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, + size_t size, const void *buffer); MOCKABLE_VIRTUAL int threadControl(const std::vector &threads, uint32_t tile, ThreadControlCmd threadCmd, std::unique_ptr &bitmask, size_t &bitmaskSize); diff --git a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp index 019c27bc0d..22e59b5367 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp @@ -63,6 +63,7 @@ struct MockDebugSession : public L0::DebugSessionImp { using L0::DebugSessionImp::readStateSaveAreaHeader; using L0::DebugSessionImp::tileAttachEnabled; using L0::DebugSessionImp::tileSessions; + using L0::DebugSessionImp::writeSLMMemory; MockDebugSession(const zet_debug_config_t &config, L0::Device *device) : MockDebugSession(config, device, true) {} @@ -235,29 +236,36 @@ struct MockDebugSession : public L0::DebugSessionImp { if (write && (command.command == static_cast(NEO::SipKernel::COMMAND::SLM_READ) || command.command == static_cast(NEO::SipKernel::COMMAND::SLM_WRITE))) { - cmdResgisterWrittenForSLM = true; + cmdResgisterWrittenForSLM = command.command; if (forceCmdAccessFail) { return ZE_RESULT_FORCE_UINT32; } } - if (cmdResgisterWrittenForSLM) { + if (cmdResgisterWrittenForSLM != static_cast(NEO::SipKernel::COMMAND::RESUME)) { cmdRegisterAccessCount++; } if (!forceSlmCmdNotReady) { - if (cmdRegisterAccessCount == 3) { //Data is made available by SIP - command.command = 1; // NEO::SipKernel::COMMAND::READY - uint64_t offset = command.offset * 16; - uint32_t size = command.size * 16; + if (cmdRegisterAccessCount == 3) { // SIP restores cmd to READY - memcpy_s(command.buffer, size, slMemory + offset, size); + uint64_t offset = command.offset * slmSendBytesSize; + uint32_t size = command.size * slmSendBytesSize; + if (cmdResgisterWrittenForSLM == static_cast(NEO::SipKernel::COMMAND::SLM_READ)) { + memcpy_s(command.buffer, size, slMemory + offset, size); + } else if (cmdResgisterWrittenForSLM == static_cast(NEO::SipKernel::COMMAND::SLM_WRITE)) { + memcpy_s(slMemory + offset, size, command.buffer, size); + cmdRegisterAccessCount = 0; + cmdResgisterWrittenForSLM = static_cast(NEO::SipKernel::COMMAND::RESUME); + } + + command.command = static_cast(NEO::SipKernel::COMMAND::READY); auto *regdesc = &(reinterpret_cast(this->stateSaveAreaHeader.data()))->regHeader.cmd; this->registersAccessHelper(this->allThreads[threadId].get(), regdesc, 0, 1, &command, true); - } else if (cmdRegisterAccessCount == 4) { // Reading the data + } else if (cmdRegisterAccessCount == 4) { // Reading the data does an extra call to retrieve the data cmdRegisterAccessCount = 0; - cmdResgisterWrittenForSLM = false; + cmdResgisterWrittenForSLM = static_cast(NEO::SipKernel::COMMAND::RESUME); if (!memcmp(slMemory, "FailReadingData", strlen("FailReadingData"))) { return ZE_RESULT_FORCE_UINT32; } @@ -337,7 +345,7 @@ struct MockDebugSession : public L0::DebugSessionImp { std::vector cleanRootSessionDeviceIndices; int cmdRegisterAccessCount = 0; - bool cmdResgisterWrittenForSLM = false; + uint32_t cmdResgisterWrittenForSLM = static_cast(NEO::SipKernel::COMMAND::RESUME); bool forceSlmCmdNotReady = false; bool forceCmdAccessFail = false; bool slmTesting = false; @@ -2146,9 +2154,9 @@ TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenReadingSLMThenReadis dumpRegisterState(); auto *regdesc = &(reinterpret_cast(session->stateSaveAreaHeader.data()))->regHeader.cmd; - SIP::sip_command resumeCommand = {0}; - resumeCommand.command = 1; // NEO::SipKernel::COMMAND::READY; - session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &resumeCommand, true); + SIP::sip_command sipCommand = {0}; + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::READY); + session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &sipCommand, true); zet_debug_memory_space_desc_t desc; desc.address = 0x10000000; @@ -2191,9 +2199,11 @@ TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenReadingSLMThenReadis EXPECT_EQ(output[i], session->slMemory[i + 0xf]); } memset(output, 0, EXCHANGE_BUFFER_SIZE * 3); + + session->slmTesting = false; } -TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenReadingSLMThenTestFailConditions) { +TEST_F(DebugSessionRegistersAccessTest, GivenCommandNotReadyOrFailureInCmdAccessOrFailFromAttClearWhenReadingSlmThenErrorIsReturned) { session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2); { @@ -2213,9 +2223,9 @@ TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenReadingSLMThenTestFa dumpRegisterState(); auto *regdesc = &(reinterpret_cast(session->stateSaveAreaHeader.data()))->regHeader.cmd; - SIP::sip_command resumeCommand = {0}; - resumeCommand.command = 1; // NEO::SipKernel::COMMAND::READY; - session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &resumeCommand, true); + SIP::sip_command sipCommand = {0}; + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::READY); + session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &sipCommand, true); zet_debug_memory_space_desc_t desc; desc.address = 0x10000000; @@ -2248,8 +2258,226 @@ TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenReadingSLMThenTestFa session->stateSaveAreaHeader[0] = '!'; retVal = session->readSLMMemory(thread0, &desc, readSize, output); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, retVal); + + session->slmTesting = false; } +TEST_F(DebugSessionRegistersAccessTest, GivenSipVersion2WhenWritingSLMThenWritesSuccessfull) { + session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2); + + { + auto pStateSaveAreaHeader = reinterpret_cast(session->stateSaveAreaHeader.data()); + auto size = pStateSaveAreaHeader->versionHeader.size * 8 + + pStateSaveAreaHeader->regHeader.state_area_offset + + pStateSaveAreaHeader->regHeader.state_save_size * 16; + session->stateSaveAreaHeader.resize(size); + session->slmTesting = true; + } + int i; + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + EuThread::ThreadId thread0(0, 0, 0, 0, 0); + + std::vector threads; + threads.push_back(thread0); + + dumpRegisterState(); + + auto *regdesc = &(reinterpret_cast(session->stateSaveAreaHeader.data()))->regHeader.cmd; + SIP::sip_command sipCommand = {0}; + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::READY); + session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &sipCommand, true); + + zet_debug_memory_space_desc_t desc; + desc.address = 0x10000000; + desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_SLM; + + session->skipWriteResumeCommand = false; + + char input1[EXCHANGE_BUFFER_SIZE * 2]; + memset(input1, 0xff, EXCHANGE_BUFFER_SIZE * 2); + + int inputSize = 7; + + auto retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i], input1[i]); + } + for (i = inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + inputSize = 23; + + retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i], input1[i]); + } + for (i = inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + inputSize = 7; + int offset = 0x05; + desc.address = 0x10000000 + offset; + + retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < offset; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i + offset], input1[i]); + } + for (i = offset + inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + inputSize = 27; + offset = 0x0f; + desc.address = 0x10000000 + offset; + + retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < offset; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i + offset], input1[i]); + } + for (i = offset + inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + inputSize = 25; + offset = 0x07; + desc.address = 0x10000000 + offset; + + retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < offset; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i + offset], input1[i]); + } + for (i = offset + inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + inputSize = EXCHANGE_BUFFER_SIZE + 16 + 8; + offset = 0x03; + desc.address = 0x10000000 + offset; + + retVal = session->writeSLMMemory(thread0, &desc, inputSize, input1); + EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); + + for (i = 0; i < offset; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + for (i = 0; i < inputSize; i++) { + EXPECT_EQ(session->slMemory[i + offset], input1[i]); + } + for (i = offset + inputSize + 1; i < session->slmSize; i++) { + EXPECT_EQ(session->slMemory[i], i & 127); + } + // Restore SLM content + for (i = 0; i < session->slmSize; i++) { + session->slMemory[i] = i & 127; + } + + session->slmTesting = false; +} + +TEST_F(DebugSessionRegistersAccessTest, GivenCommandNotReadyOrFailureInCmdAccessOrFailFromAttClearWhenWritingSlmThenErrorIsReturned) { + session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2); + + { + auto pStateSaveAreaHeader = reinterpret_cast(session->stateSaveAreaHeader.data()); + auto size = pStateSaveAreaHeader->versionHeader.size * 8 + + pStateSaveAreaHeader->regHeader.state_area_offset + + pStateSaveAreaHeader->regHeader.state_save_size * 16; + session->stateSaveAreaHeader.resize(size); + session->slmTesting = true; + } + + EuThread::ThreadId thread0(0, 0, 0, 0, 0); + + std::vector threads; + threads.push_back(thread0); + + dumpRegisterState(); + + auto *regdesc = &(reinterpret_cast(session->stateSaveAreaHeader.data()))->regHeader.cmd; + SIP::sip_command sipCommand = {0}; + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::READY); + session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &sipCommand, true); + + zet_debug_memory_space_desc_t desc; + desc.address = 0x10000000; + desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_SLM; + + session->skipWriteResumeCommand = false; + + constexpr int writeSize = 16; + char input[writeSize]; + + session->resumeImpResult = ZE_RESULT_ERROR_UNKNOWN; + auto retVal = session->writeSLMMemory(thread0, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, retVal); + session->resumeImpResult = ZE_RESULT_SUCCESS; + + session->forceCmdAccessFail = true; + retVal = session->writeSLMMemory(thread0, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_FORCE_UINT32, retVal); + session->forceCmdAccessFail = false; + + session->forceSlmCmdNotReady = true; + retVal = session->writeSLMMemory(thread0, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); + + sipCommand.command = static_cast(NEO::SipKernel::COMMAND::RESUME); + session->registersAccessHelper(session->allThreads[thread0].get(), regdesc, 0, 1, &sipCommand, true); + + retVal = session->writeSLMMemory(thread0, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); + + desc.address = 0x1000000f; //force a read + retVal = session->writeSLMMemory(thread0, &desc, writeSize, input); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); + session->forceSlmCmdNotReady = false; + + session->slmTesting = false; +} TEST_F(DebugSessionRegistersAccessTest, GivenBindlessSipVersion2WhenCallingResumeThenResumeInCmdRegisterIsWritten) { session->debugArea.reserved1 = 1u; session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2); diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp index 260de2bc62..7ba0082eb7 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp @@ -2054,12 +2054,6 @@ TEST_F(DebugApiLinuxTest, WhenCallingWriteMemoryForExpectedFailureCasesThenError retVal = session->writeMemory(thread, &desc, size, output); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); - - session->ensureThreadStopped(thread); - desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_SLM; - desc.address = 0x10000000; - retVal = session->writeMemory(thread, &desc, size, output); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, retVal); } TEST_F(DebugApiLinuxTest, GivenErrorFromVmOpenWhenCallingReadGpuMemoryThenCloseIsNotCalledAndErrorReturned) { @@ -6409,6 +6403,9 @@ TEST_F(DebugApiRegistersAccessTest, GivenSipNotUpdatingSipCmdThenAccessToSlmFail auto retVal = session->readMemory(thread, &desc, bufferSize, output); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); + + retVal = session->writeMemory(thread, &desc, bufferSize, output); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal); } TEST_F(DebugApiRegistersAccessTest, GivenNoVmHandleWhenReadingSystemRoutineIdentThenFalseIsReturned) {