2022-03-29 23:39:27 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021-2022 Intel Corporation
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-08-05 20:46:52 +08:00
|
|
|
#include "shared/source/built_ins/sip.h"
|
|
|
|
|
2022-03-29 23:39:27 +08:00
|
|
|
#include "level_zero/tools/source/debug/debug_session.h"
|
|
|
|
|
|
|
|
#include <atomic>
|
2022-07-15 21:30:56 +08:00
|
|
|
#include <condition_variable>
|
2022-03-29 23:39:27 +08:00
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
2022-07-29 19:26:12 +08:00
|
|
|
#include <unordered_set>
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
namespace SIP {
|
|
|
|
struct StateSaveAreaHeader;
|
|
|
|
struct regset_desc;
|
|
|
|
struct sr_ident;
|
|
|
|
struct sip_command;
|
|
|
|
} // namespace SIP
|
|
|
|
|
|
|
|
namespace L0 {
|
|
|
|
|
|
|
|
struct DebugSessionImp : DebugSession {
|
|
|
|
|
|
|
|
enum class Error {
|
|
|
|
Success,
|
|
|
|
ThreadsRunning,
|
|
|
|
Unknown
|
|
|
|
};
|
|
|
|
|
2022-07-29 19:26:12 +08:00
|
|
|
DebugSessionImp(const zet_debug_config_t &config, Device *device) : DebugSession(config, device) {
|
|
|
|
tileAttachEnabled = NEO::DebugManager.flags.ExperimentalEnableTileAttach.get();
|
|
|
|
}
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
ze_result_t interrupt(ze_device_thread_t thread) override;
|
|
|
|
ze_result_t resume(ze_device_thread_t thread) override;
|
|
|
|
|
|
|
|
ze_result_t readRegisters(ze_device_thread_t thread, uint32_t type, uint32_t start, uint32_t count, void *pRegisterValues) override;
|
|
|
|
ze_result_t writeRegisters(ze_device_thread_t thread, uint32_t type, uint32_t start, uint32_t count, void *pRegisterValues) override;
|
2022-07-15 21:30:56 +08:00
|
|
|
ze_result_t readEvent(uint64_t timeout, zet_debug_event_t *event) override;
|
2022-03-29 23:39:27 +08:00
|
|
|
|
2022-07-29 19:26:12 +08:00
|
|
|
DebugSession *attachTileDebugSession(Device *device) override;
|
|
|
|
void detachTileDebugSession(DebugSession *tileSession) override;
|
|
|
|
bool areAllTileDebugSessionDetached() override;
|
|
|
|
|
2022-09-23 22:56:32 +08:00
|
|
|
void setAttachMode(bool isRootAttach) override {
|
|
|
|
if (isRootAttach) {
|
|
|
|
tileAttachEnabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 01:33:23 +08:00
|
|
|
virtual void attachTile() = 0;
|
|
|
|
virtual void detachTile() = 0;
|
|
|
|
virtual void cleanRootSessionAfterDetach(uint32_t deviceIndex) = 0;
|
|
|
|
|
2022-03-29 23:39:27 +08:00
|
|
|
static const SIP::regset_desc *getSbaRegsetDesc();
|
|
|
|
static uint32_t typeToRegsetFlags(uint32_t type);
|
|
|
|
constexpr static int64_t interruptTimeout = 2000;
|
|
|
|
|
2022-07-15 21:30:56 +08:00
|
|
|
using ApiEventQueue = std::queue<zet_debug_event_t>;
|
|
|
|
|
2022-03-29 23:39:27 +08:00
|
|
|
protected:
|
2022-07-14 00:57:18 +08:00
|
|
|
MOCKABLE_VIRTUAL ze_result_t readRegistersImp(EuThread::ThreadId thread, uint32_t type, uint32_t start, uint32_t count, void *pRegisterValues);
|
|
|
|
MOCKABLE_VIRTUAL ze_result_t writeRegistersImp(EuThread::ThreadId thread, uint32_t type, uint32_t start, uint32_t count, void *pRegisterValues);
|
2022-03-29 23:39:27 +08:00
|
|
|
Error resumeThreadsWithinDevice(uint32_t deviceIndex, ze_device_thread_t physicalThread);
|
|
|
|
MOCKABLE_VIRTUAL bool writeResumeCommand(const std::vector<EuThread::ThreadId> &threadIds);
|
2022-07-27 03:02:54 +08:00
|
|
|
void applyResumeWa(uint8_t *bitmask, size_t bitmaskSize);
|
2022-03-29 23:39:27 +08:00
|
|
|
MOCKABLE_VIRTUAL bool checkThreadIsResumed(const EuThread::ThreadId &threadID);
|
|
|
|
|
2022-07-15 02:14:46 +08:00
|
|
|
virtual ze_result_t resumeImp(const std::vector<EuThread::ThreadId> &threads, uint32_t deviceIndex) = 0;
|
2022-03-29 23:39:27 +08:00
|
|
|
virtual ze_result_t interruptImp(uint32_t deviceIndex) = 0;
|
|
|
|
|
|
|
|
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;
|
2022-08-05 20:46:52 +08:00
|
|
|
ze_result_t readSLMMemory(EuThread::ThreadId threadId, const zet_debug_memory_space_desc_t *desc,
|
|
|
|
size_t size, void *buffer);
|
|
|
|
|
2022-07-14 00:05:36 +08:00
|
|
|
ze_result_t validateThreadAndDescForMemoryAccess(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc);
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
virtual void enqueueApiEvent(zet_debug_event_t &debugEvent) = 0;
|
2022-08-23 19:17:12 +08:00
|
|
|
MOCKABLE_VIRTUAL bool readSystemRoutineIdent(EuThread *thread, uint64_t vmHandle, SIP::sr_ident &srMagic);
|
2022-03-29 23:39:27 +08:00
|
|
|
|
2022-07-14 00:57:18 +08:00
|
|
|
ze_result_t readSbaRegisters(EuThread::ThreadId thread, uint32_t start, uint32_t count, void *pRegisterValues);
|
2022-03-29 23:39:27 +08:00
|
|
|
MOCKABLE_VIRTUAL bool isForceExceptionOrForceExternalHaltOnlyExceptionReason(uint32_t *cr0);
|
|
|
|
void sendInterrupts();
|
|
|
|
MOCKABLE_VIRTUAL void markPendingInterruptsOrAddToNewlyStoppedFromRaisedAttention(EuThread::ThreadId threadId, uint64_t memoryHandle);
|
|
|
|
MOCKABLE_VIRTUAL void fillResumeAndStoppedThreadsFromNewlyStopped(std::vector<EuThread::ThreadId> &resumeThreads, std::vector<EuThread::ThreadId> &stoppedThreadsToReport);
|
|
|
|
MOCKABLE_VIRTUAL void generateEventsAndResumeStoppedThreads();
|
|
|
|
MOCKABLE_VIRTUAL void resumeAccidentallyStoppedThreads(const std::vector<EuThread::ThreadId> &threadIds);
|
|
|
|
MOCKABLE_VIRTUAL void generateEventsForStoppedThreads(const std::vector<EuThread::ThreadId> &threadIds);
|
|
|
|
MOCKABLE_VIRTUAL void generateEventsForPendingInterrupts();
|
|
|
|
|
|
|
|
const SIP::StateSaveAreaHeader *getStateSaveAreaHeader();
|
2022-06-29 22:40:45 +08:00
|
|
|
void validateAndSetStateSaveAreaHeader(const std::vector<char> &data);
|
2022-03-29 23:39:27 +08:00
|
|
|
virtual void readStateSaveAreaHeader(){};
|
|
|
|
|
2022-08-23 19:17:12 +08:00
|
|
|
virtual uint64_t getContextStateSaveAreaGpuVa(uint64_t memoryHandle) = 0;
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
ze_result_t registersAccessHelper(const EuThread *thread, const SIP::regset_desc *regdesc,
|
|
|
|
uint32_t start, uint32_t count, void *pRegisterValues, bool write);
|
2022-08-05 20:46:52 +08:00
|
|
|
MOCKABLE_VIRTUAL ze_result_t cmdRegisterAccessHelper(const EuThread::ThreadId &threadId, SIP::sip_command &command, bool write);
|
|
|
|
ze_result_t waitForCmdReady(EuThread::ThreadId threadId, uint16_t retryCount);
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
const SIP::regset_desc *typeToRegsetDesc(uint32_t type);
|
2022-06-15 01:32:28 +08:00
|
|
|
uint32_t getRegisterSize(uint32_t type);
|
|
|
|
|
2022-03-29 23:39:27 +08:00
|
|
|
size_t calculateThreadSlotOffset(EuThread::ThreadId threadId);
|
|
|
|
size_t calculateRegisterOffsetInThreadSlot(const SIP::regset_desc *const regdesc, uint32_t start);
|
|
|
|
|
|
|
|
void newAttentionRaised(uint32_t deviceIndex) {
|
|
|
|
if (expectedAttentionEvents > 0) {
|
|
|
|
expectedAttentionEvents--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void checkTriggerEventsForAttention() {
|
|
|
|
if (pendingInterrupts.size() > 0 || newlyStoppedThreads.size()) {
|
|
|
|
if (expectedAttentionEvents == 0) {
|
|
|
|
triggerEvents = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-05 20:46:52 +08:00
|
|
|
bool isValidGpuAddress(const zet_debug_memory_space_desc_t *desc) const;
|
2022-03-29 23:39:27 +08:00
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL int64_t getTimeDifferenceMilliseconds(std::chrono::high_resolution_clock::time_point time) {
|
|
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
|
|
auto timeDifferenceMs = std::chrono::duration_cast<std::chrono::milliseconds>(now - time).count();
|
|
|
|
return timeDifferenceMs;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::chrono::high_resolution_clock::time_point interruptTime;
|
|
|
|
std::atomic<bool> interruptSent = false;
|
|
|
|
std::atomic<bool> triggerEvents = false;
|
|
|
|
|
|
|
|
uint32_t expectedAttentionEvents = 0;
|
|
|
|
|
|
|
|
std::mutex interruptMutex;
|
|
|
|
std::mutex threadStateMutex;
|
|
|
|
std::queue<ze_device_thread_t> interruptRequests;
|
|
|
|
std::vector<std::pair<ze_device_thread_t, bool>> pendingInterrupts;
|
|
|
|
std::vector<EuThread::ThreadId> newlyStoppedThreads;
|
|
|
|
std::vector<char> stateSaveAreaHeader;
|
2022-07-15 21:30:56 +08:00
|
|
|
|
2022-08-19 23:11:22 +08:00
|
|
|
std::vector<std::pair<DebugSessionImp *, bool>> tileSessions; // DebugSession, attached
|
2022-07-29 19:26:12 +08:00
|
|
|
bool tileAttachEnabled = false;
|
2022-08-17 02:21:08 +08:00
|
|
|
bool tileSessionsEnabled = false;
|
2022-07-29 19:26:12 +08:00
|
|
|
|
2022-07-15 21:30:56 +08:00
|
|
|
ThreadHelper asyncThread;
|
|
|
|
std::mutex asyncThreadMutex;
|
|
|
|
|
|
|
|
ApiEventQueue apiEvents;
|
|
|
|
std::condition_variable apiEventCondition;
|
2022-08-05 20:46:52 +08:00
|
|
|
constexpr static uint16_t slmAddressSpaceTag = 28;
|
|
|
|
constexpr static uint16_t slmSendBytesSize = 16;
|
|
|
|
constexpr static uint16_t sipRetryCount = 10;
|
2022-03-29 23:39:27 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace L0
|