mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
Add SIP version check
Make SLM access a single template function Resolves: NEO-7335 Signed-off-by: Matias Cabral <matias.a.cabral@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
4dfdbd612d
commit
467119931c
@@ -856,18 +856,41 @@ ze_result_t DebugSessionImp::readEvent(uint64_t timeout, zet_debug_event_t *outp
|
||||
return ZE_RESULT_NOT_READY;
|
||||
}
|
||||
|
||||
void DebugSessionImp::validateAndSetStateSaveAreaHeader(const std::vector<char> &data) {
|
||||
void DebugSessionImp::validateAndSetStateSaveAreaHeader(uint64_t vmHandle, uint64_t gpuVa) {
|
||||
auto headerSize = sizeof(SIP::StateSaveAreaHeader);
|
||||
std::vector<char> data(headerSize);
|
||||
auto retVal = readGpuMemory(vmHandle, data.data(), headerSize, gpuVa);
|
||||
|
||||
if (retVal != ZE_RESULT_SUCCESS) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal);
|
||||
return;
|
||||
}
|
||||
|
||||
auto pStateSaveArea = reinterpret_cast<const SIP::StateSaveAreaHeader *>(data.data());
|
||||
if (0 == strcmp(pStateSaveArea->versionHeader.magic, "tssarea")) {
|
||||
size_t size = pStateSaveArea->versionHeader.size * 8u;
|
||||
DEBUG_BREAK_IF(size != sizeof(SIP::StateSaveAreaHeader));
|
||||
stateSaveAreaHeader.assign(data.begin(), data.begin() + size);
|
||||
PRINT_DEBUGGER_INFO_LOG("Context State Save Area : version == %d.%d.%d\n", (int)pStateSaveArea->versionHeader.version.major, (int)pStateSaveArea->versionHeader.version.minor, (int)pStateSaveArea->versionHeader.version.patch);
|
||||
slmSipVersionCheck();
|
||||
} else {
|
||||
PRINT_DEBUGGER_ERROR_LOG("Setting Context State Save Area: failed to match magic numbers\n", "");
|
||||
}
|
||||
}
|
||||
|
||||
void DebugSessionImp::slmSipVersionCheck() {
|
||||
|
||||
SIP::version sipVersion = getStateSaveAreaHeader()->versionHeader.version;
|
||||
if ((sipVersion.major < minSlmSipVersion.major) ||
|
||||
((sipVersion.major == minSlmSipVersion.major) && (sipVersion.minor < minSlmSipVersion.minor)) ||
|
||||
((sipVersion.major == minSlmSipVersion.major) && (sipVersion.minor == minSlmSipVersion.minor) && (sipVersion.patch < minSlmSipVersion.patch))) {
|
||||
|
||||
sipSupportsSlm = false;
|
||||
} else {
|
||||
sipSupportsSlm = true;
|
||||
}
|
||||
}
|
||||
|
||||
const SIP::StateSaveAreaHeader *DebugSessionImp::getStateSaveAreaHeader() {
|
||||
if (stateSaveAreaHeader.empty()) {
|
||||
readStateSaveAreaHeader();
|
||||
@@ -1274,153 +1297,4 @@ ze_result_t DebugSessionImp::waitForCmdReady(EuThread::ThreadId threadId, uint16
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
status = waitForCmdReady(threadId, sipRetryCount);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag);
|
||||
|
||||
// SIP accesses SLM in units of slmSendBytesSize at offset allignment of slmSendBytesSize
|
||||
uint32_t frontPadding = offset % slmSendBytesSize;
|
||||
uint64_t alignedOffset = offset - frontPadding;
|
||||
uint32_t remainingSlmSendUnits = static_cast<uint32_t>(std::ceil(static_cast<float>(size) / slmSendBytesSize));
|
||||
|
||||
if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) {
|
||||
remainingSlmSendUnits++;
|
||||
}
|
||||
|
||||
uint32_t loops = static_cast<uint32_t>(std::ceil(static_cast<float>(remainingSlmSendUnits) / maxUnitsPerLoop));
|
||||
|
||||
std::unique_ptr<char[]> tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]);
|
||||
uint32_t readUnits = 0;
|
||||
uint32_t bytesAlreadyRead = 0;
|
||||
|
||||
sipCommand.offset = alignedOffset;
|
||||
|
||||
for (uint32_t loop = 0; loop < loops; loop++) {
|
||||
|
||||
if (remainingSlmSendUnits >= maxUnitsPerLoop) {
|
||||
readUnits = maxUnitsPerLoop;
|
||||
} else {
|
||||
readUnits = remainingSlmSendUnits;
|
||||
}
|
||||
|
||||
sipCommand.command = static_cast<uint32_t>(NEO::SipKernel::COMMAND::SLM_READ);
|
||||
sipCommand.size = static_cast<uint32_t>(readUnits);
|
||||
|
||||
status = cmdRegisterAccessHelper(threadId, sipCommand, true);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = resumeImp(std::vector<EuThread::ThreadId>{threadId}, threadId.tileIndex);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = waitForCmdReady(threadId, sipRetryCount);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cmdRegisterAccessHelper(threadId, sipCommand, false);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy_s(tmpBuffer.get() + bytesAlreadyRead, readUnits * slmSendBytesSize, sipCommand.buffer, readUnits * slmSendBytesSize);
|
||||
|
||||
remainingSlmSendUnits -= readUnits;
|
||||
bytesAlreadyRead += readUnits * slmSendBytesSize;
|
||||
sipCommand.offset += readUnits * slmSendBytesSize;
|
||||
}
|
||||
|
||||
memcpy_s(buffer, size, tmpBuffer.get() + frontPadding, size);
|
||||
|
||||
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 allignment of slmSendBytesSize
|
||||
uint32_t frontPadding = offset % slmSendBytesSize;
|
||||
uint64_t alignedOffset = offset - frontPadding;
|
||||
uint32_t remainingSlmSendUnits = static_cast<uint32_t>(std::ceil(static_cast<float>(size) / slmSendBytesSize));
|
||||
size_t tailPadding = (size % slmSendBytesSize) ? slmSendBytesSize - (size % slmSendBytesSize) : 0;
|
||||
|
||||
if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) {
|
||||
remainingSlmSendUnits++;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]);
|
||||
|
||||
if ((frontPadding || tailPadding)) {
|
||||
|
||||
zet_debug_memory_space_desc_t alignedDesc = *desc;
|
||||
alignedDesc.address = desc->address - frontPadding;
|
||||
size_t alignedSize = remainingSlmSendUnits * slmSendBytesSize;
|
||||
|
||||
status = readSLMMemory(threadId, &alignedDesc, alignedSize, 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<uint32_t>(std::ceil(static_cast<float>(remainingSlmSendUnits) / maxUnitsPerLoop));
|
||||
|
||||
uint32_t writeUnits = 0;
|
||||
uint32_t bytesAlreadyWritten = 0;
|
||||
|
||||
sipCommand.offset = alignedOffset;
|
||||
|
||||
for (uint32_t loop = 0; loop < loops; loop++) {
|
||||
|
||||
if (remainingSlmSendUnits >= maxUnitsPerLoop) {
|
||||
writeUnits = maxUnitsPerLoop;
|
||||
} else {
|
||||
writeUnits = remainingSlmSendUnits;
|
||||
}
|
||||
|
||||
sipCommand.command = static_cast<uint32_t>(NEO::SipKernel::COMMAND::SLM_WRITE);
|
||||
sipCommand.size = static_cast<uint32_t>(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<EuThread::ThreadId>{threadId}, threadId.tileIndex);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = waitForCmdReady(threadId, sipRetryCount);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
remainingSlmSendUnits -= writeUnits;
|
||||
bytesAlreadyWritten += writeUnits * slmSendBytesSize;
|
||||
sipCommand.offset += writeUnits * slmSendBytesSize;
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/built_ins/sip.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include "level_zero/tools/source/debug/debug_session.h"
|
||||
|
||||
@@ -80,10 +81,9 @@ struct DebugSessionImp : DebugSession {
|
||||
|
||||
virtual ze_result_t readGpuMemory(uint64_t memoryHandle, char *output, size_t size, uint64_t gpuVa) = 0;
|
||||
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);
|
||||
|
||||
template <class bufferType, bool write>
|
||||
ze_result_t slmMemoryAccess(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, bufferType buffer);
|
||||
|
||||
ze_result_t validateThreadAndDescForMemoryAccess(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc);
|
||||
|
||||
@@ -101,13 +101,15 @@ struct DebugSessionImp : DebugSession {
|
||||
MOCKABLE_VIRTUAL void generateEventsForPendingInterrupts();
|
||||
|
||||
const SIP::StateSaveAreaHeader *getStateSaveAreaHeader();
|
||||
void validateAndSetStateSaveAreaHeader(const std::vector<char> &data);
|
||||
void validateAndSetStateSaveAreaHeader(uint64_t vmHandle, uint64_t gpuVa);
|
||||
virtual void readStateSaveAreaHeader(){};
|
||||
|
||||
virtual uint64_t getContextStateSaveAreaGpuVa(uint64_t memoryHandle) = 0;
|
||||
|
||||
ze_result_t registersAccessHelper(const EuThread *thread, const SIP::regset_desc *regdesc,
|
||||
uint32_t start, uint32_t count, void *pRegisterValues, bool write);
|
||||
|
||||
void slmSipVersionCheck();
|
||||
MOCKABLE_VIRTUAL ze_result_t cmdRegisterAccessHelper(const EuThread::ThreadId &threadId, SIP::sip_command &command, bool write);
|
||||
MOCKABLE_VIRTUAL ze_result_t waitForCmdReady(EuThread::ThreadId threadId, uint16_t retryCount);
|
||||
|
||||
@@ -151,6 +153,8 @@ struct DebugSessionImp : DebugSession {
|
||||
std::vector<std::pair<ze_device_thread_t, bool>> pendingInterrupts;
|
||||
std::vector<EuThread::ThreadId> newlyStoppedThreads;
|
||||
std::vector<char> stateSaveAreaHeader;
|
||||
SIP::version minSlmSipVersion = {2, 0, 0};
|
||||
bool sipSupportsSlm = false;
|
||||
|
||||
std::vector<std::pair<DebugSessionImp *, bool>> tileSessions; // DebugSession, attached
|
||||
bool tileAttachEnabled = false;
|
||||
@@ -167,4 +171,105 @@ struct DebugSessionImp : DebugSession {
|
||||
uint32_t maxUnitsPerLoop = EXCHANGE_BUFFER_SIZE / slmSendBytesSize;
|
||||
};
|
||||
|
||||
template <class bufferType, bool write>
|
||||
ze_result_t DebugSessionImp::slmMemoryAccess(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc, size_t size, bufferType buffer) {
|
||||
ze_result_t status;
|
||||
|
||||
if (!sipSupportsSlm) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_VERSION;
|
||||
}
|
||||
|
||||
SIP::sip_command sipCommand = {0};
|
||||
|
||||
uint64_t offset = desc->address & maxNBitValue(slmAddressSpaceTag);
|
||||
// SIP accesses SLM in units of slmSendBytesSize at offset allignment of slmSendBytesSize
|
||||
uint32_t frontPadding = offset % slmSendBytesSize;
|
||||
uint64_t alignedOffset = offset - frontPadding;
|
||||
uint32_t remainingSlmSendUnits = static_cast<uint32_t>(std::ceil(static_cast<float>(size) / slmSendBytesSize));
|
||||
|
||||
if ((size + frontPadding) > (remainingSlmSendUnits * slmSendBytesSize)) {
|
||||
remainingSlmSendUnits++;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> tmpBuffer(new char[remainingSlmSendUnits * slmSendBytesSize]);
|
||||
|
||||
if constexpr (write) {
|
||||
size_t tailPadding = (size % slmSendBytesSize) ? slmSendBytesSize - (size % slmSendBytesSize) : 0;
|
||||
if ((frontPadding || tailPadding)) {
|
||||
zet_debug_memory_space_desc_t alignedDesc = *desc;
|
||||
alignedDesc.address = desc->address - frontPadding;
|
||||
size_t alignedSize = remainingSlmSendUnits * slmSendBytesSize;
|
||||
|
||||
status = slmMemoryAccess<void *, false>(threadId, &alignedDesc, alignedSize, 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<uint32_t>(std::ceil(static_cast<float>(remainingSlmSendUnits) / maxUnitsPerLoop));
|
||||
uint32_t accessUnits = 0;
|
||||
uint32_t countReadyBytes = 0;
|
||||
sipCommand.offset = alignedOffset;
|
||||
|
||||
for (uint32_t loop = 0; loop < loops; loop++) {
|
||||
|
||||
if (remainingSlmSendUnits >= maxUnitsPerLoop) {
|
||||
accessUnits = maxUnitsPerLoop;
|
||||
} else {
|
||||
accessUnits = remainingSlmSendUnits;
|
||||
}
|
||||
|
||||
if constexpr (write) {
|
||||
sipCommand.command = static_cast<uint32_t>(NEO::SipKernel::COMMAND::SLM_WRITE);
|
||||
sipCommand.size = static_cast<uint32_t>(accessUnits);
|
||||
memcpy_s(sipCommand.buffer, accessUnits * slmSendBytesSize, tmpBuffer.get() + countReadyBytes, accessUnits * slmSendBytesSize);
|
||||
} else {
|
||||
sipCommand.command = static_cast<uint32_t>(NEO::SipKernel::COMMAND::SLM_READ);
|
||||
sipCommand.size = static_cast<uint32_t>(accessUnits);
|
||||
}
|
||||
|
||||
status = cmdRegisterAccessHelper(threadId, sipCommand, true);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = resumeImp(std::vector<EuThread::ThreadId>{threadId}, threadId.tileIndex);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = waitForCmdReady(threadId, sipRetryCount);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if constexpr (!write) { // Read need an extra access to retrieve data
|
||||
status = cmdRegisterAccessHelper(threadId, sipCommand, false);
|
||||
if (status != ZE_RESULT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy_s(tmpBuffer.get() + countReadyBytes, accessUnits * slmSendBytesSize, sipCommand.buffer, accessUnits * slmSendBytesSize);
|
||||
}
|
||||
|
||||
remainingSlmSendUnits -= accessUnits;
|
||||
countReadyBytes += accessUnits * slmSendBytesSize;
|
||||
sipCommand.offset += accessUnits * slmSendBytesSize;
|
||||
}
|
||||
|
||||
if constexpr (!write) {
|
||||
memcpy_s(buffer, size, tmpBuffer.get() + frontPadding, size);
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
@@ -781,14 +781,8 @@ void DebugSessionLinux::readStateSaveAreaHeader() {
|
||||
if (totalSize < headerSize) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("Context State Save Area size incorrect\n", "");
|
||||
return;
|
||||
}
|
||||
std::vector<char> data(headerSize);
|
||||
auto retVal = readGpuMemory(vm, data.data(), headerSize, gpuVa);
|
||||
|
||||
if (retVal != 0) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal);
|
||||
} else {
|
||||
validateAndSetStateSaveAreaHeader(data);
|
||||
validateAndSetStateSaveAreaHeader(vm, gpuVa);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1610,7 +1604,7 @@ ze_result_t DebugSessionLinux::readMemory(ze_device_thread_t thread, const zet_d
|
||||
status = readDefaultMemory(thread, desc, size, buffer);
|
||||
} else {
|
||||
auto threadId = convertToThreadId(thread);
|
||||
status = readSLMMemory(threadId, desc, size, buffer);
|
||||
status = slmMemoryAccess<void *, false>(threadId, desc, size, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1652,7 +1646,7 @@ ze_result_t DebugSessionLinux::writeMemory(ze_device_thread_t thread, const zet_
|
||||
status = writeDefaultMemory(thread, desc, size, buffer);
|
||||
} else {
|
||||
auto threadId = convertToThreadId(thread);
|
||||
status = writeSLMMemory(threadId, desc, size, buffer);
|
||||
status = slmMemoryAccess<const void *, true>(threadId, desc, size, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -459,7 +459,7 @@ ze_result_t DebugSessionWindows::readMemory(ze_device_thread_t thread, const zet
|
||||
status = readDefaultMemory(thread, desc, size, buffer);
|
||||
} else {
|
||||
auto threadId = convertToThreadId(thread);
|
||||
status = readSLMMemory(threadId, desc, size, buffer);
|
||||
status = slmMemoryAccess<void *, false>(threadId, desc, size, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -504,7 +504,7 @@ ze_result_t DebugSessionWindows::writeMemory(ze_device_thread_t thread, const ze
|
||||
status = writeDefaultMemory(thread, desc, size, buffer);
|
||||
} else {
|
||||
auto threadId = convertToThreadId(thread);
|
||||
status = writeSLMMemory(threadId, desc, size, buffer);
|
||||
status = slmMemoryAccess<const void *, true>(threadId, desc, size, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -714,16 +714,7 @@ void DebugSessionWindows::readStateSaveAreaHeader() {
|
||||
memoryHandle = *allContexts.begin();
|
||||
}
|
||||
|
||||
auto headerSize = sizeof(SIP::StateSaveAreaHeader);
|
||||
std::vector<char> data(headerSize);
|
||||
auto retVal = readGpuMemory(memoryHandle, data.data(), headerSize, gpuVa);
|
||||
|
||||
if (retVal != ZE_RESULT_SUCCESS) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal);
|
||||
return;
|
||||
}
|
||||
|
||||
validateAndSetStateSaveAreaHeader(data);
|
||||
validateAndSetStateSaveAreaHeader(memoryHandle, gpuVa);
|
||||
}
|
||||
|
||||
} // namespace L0
|
||||
|
||||
Reference in New Issue
Block a user