* Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved.
*/
#ifdef MS_DEBUGGER
#ifndef liblldb_DEVICE_CONTEXT_H_
#define liblldb_DEVICE_CONTEXT_H_
#include "lldb/Utility/Status.h"
#include "lldb/Utility/MessageDefines.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/lldb-private-types.h"
#include <condition_variable>
#include <lldb/Host/Socket.h>
#include "Plugins/Process/Utility/RegisterInfoPOSIX_ascend.h"
#include <mutex>
namespace lldb_private {
enum class CmdType {
ENABLE_DEBUG_MODE = 0,
DISABLE_DEBUG_MODE = 1,
SET_HARD_BREAKPOINT = 2,
UNSET_HARD_BREAKPOINT = 3,
INVALID_INSTR_CACHE = 4,
SINGLE_STEP_DEVICE = 5,
RESUME_DEVICE = 6,
SUSPEND_DEVICE = 7,
GET_DEVICES_INFO = 8,
GET_CORES_INFO = 9,
READ_REGISTER = 10,
READ_LOCAL_MEMORY = 11,
GET_WARP_INFO = 12,
TASK_KILL = 14,
INTERRUPT_EVENT = 101,
};
struct DebugRecvInfo {
uint8_t phase;
uint8_t reserved[3];
uint16_t sq_index;
uint16_t sq_head;
CmdType cmd_type;
uint32_t return_val;
uint32_t msg_id;
uint8_t recv_msg[44];
};
struct TsDeviceInfo {
uint64_t aic_bitmap;
uint64_t aiv_bitmap;
};
struct CoreInfoParam {
uint16_t info_idx;
uint8_t require_err_info;
uint8_t reserve;
};
struct CoreErrorInfo {
uint64_t aix_error_bitmap0;
uint32_t aix_error_bitmap1;
uint32_t aix_error_bitmap2;
uint64_t aix_error_bitmap3;
uint32_t aix_error_bitmap4;
uint64_t aix_error_bitmap5;
};
struct CoreMaskInfo {
uint32_t magic {0U};
uint32_t aic_mask {0U};
uint64_t aiv_mask {0U};
};
struct InvalidCacheParam {
uint8_t enable_all;
uint8_t redirect_ifu;
uint8_t reserve[2];
uint64_t virt_addr;
CoreMaskInfo core_info;
};
class DeviceContext : public RegisterDataInterface {
public:
class Factory {
public:
static std::shared_ptr<DeviceContext> GetDeviceContext(const std::string &soc_version, ::pid_t pid, int device_id);
};
typedef std::function<void(const DebugRecvInfo &info)> Callback;
DeviceContext(const ::pid_t pid, const uint32_t device_id);
~DeviceContext();
virtual Status Init();
virtual Status Resume(const InterruptPosInfo &pos_info) const;
virtual size_t ReadMemory(lldb::addr_t addr, size_t size, const MemoryTypeInfo &memory_type_info,
const InterruptPosInfo &pos_info, void *out);
virtual Status SingleStep(const InterruptPosInfo &pos_info) const;
virtual Status SetSoftwareBreakpoint(lldb::addr_t addr);
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, uint16_t stream_id,
const InterruptPosInfo &pos_info) const {
return Status("Unsupport hardware breakpoint.");
}
virtual Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr, uint16_t stream_id,
const InterruptPosInfo &pos_info) const {
return Status("Unsupport hardware breakpoint.");
}
Status ReadRegister(const RegisterInfo *reg_info, const InterruptPosInfo &pos_info, RegisterValue &value) const;
Status ReadRegister(uint64_t addr, const RegisterInfo *reg_info,
uint32_t core_id, CoreType core_type, RegisterValue &value) const override;
virtual Status GetDeviceInfo(DeviceInfo &device_info);
virtual Status GetCoresInfo(std::vector<CoreInfo> &cores_info);
virtual Status GetWarpsInfo(std::vector<WarpInfo> &warps_info, const InterruptPosInfo &m_pos_info) const {
return Status("Unsupport query warps info.");
}
virtual Status GetWarpInfo(WarpInfo &info, uint16_t warp_id, const InterruptPosInfo &m_pos_info) const {
return Status("Unsupport query warp info.");
}
virtual Status CheckRegisterAddr(CoreType core_type, uint64_t addr) const = 0;
virtual void SetBreakpointCallback(const Callback &callback);
virtual bool StartListenThread();
virtual Status EnableDebugMode();
virtual Status InvalidInstrCache(const lldb::addr_t &addr,
const InterruptPosInfo &pos_info,
uint8_t redirect_ifu = 0) const;
virtual size_t ReadLocalMemory(lldb::addr_t addr, size_t size, const MemoryTypeInfo &memory_type_info,
const InterruptPosInfo &pos_info, void *data);
virtual size_t ReadGlobalMemory(lldb::addr_t addr, size_t size, void *data);
virtual size_t WriteGlobalMemory(lldb::addr_t addr, size_t size, const void *data);
virtual bool SupportDirectlySetSwBp() { return false; }
virtual SocType GetSocType() = 0;
void SetCanRun(bool can);
virtual bool UseSpecifiedCore(uint32_t aic_mask, uint64_t aiv_mask, CoreMaskInfo &maskInfo);
virtual Status TaskKill(uint32_t stream_id);
virtual MemType DeviceAddressClassToMemType(const DeviceAddressClass address_class) const;
virtual bool IsValidStack(lldb::addr_t addr, size_t size);
virtual MemType GetStackMemType() const = 0;
Status BaseSqCqComm(CmdType type, const uint8_t *data = nullptr, const uint8_t len = 0,
uint8_t *out = nullptr, uint8_t out_len = 0) const;
void SetSocket(const Socket *client_socket);
bool IsDeviceIdMatched(const uint32_t device_id) const;
bool IsTgidMatched(const int32_t tgid) const;
void UpdateTgid(const int32_t tgid);
protected:
int32_t m_drv_fd;
int32_t m_pid;
uint32_t m_device_id;
Callback m_bp_callback;
bool m_close;
HostThread m_listen_thread;
std::vector<CoreInfo> m_cores_info;
uint32_t m_num_cores;
std::mutex m_mtx;
std::condition_variable m_cv;
Status m_init_err;
const Socket *m_client_socket = nullptr;
std::unique_ptr<RegisterInfoPOSIX_ascend> m_reg_info_up;
private:
lldb::thread_result_t RunListenThread();
};
}
#endif
#endif