1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/*
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/debugger/debugger.h"
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "common/StateSaveAreaHeader.h"
#include <cstdint>
#include <memory>
#include <type_traits>
#include <unordered_map>
namespace NEO {
class Device;
class GraphicsAllocation;
class LinearStream;
class OSInterface;
// NOLINTBEGIN
struct StateSaveAreaHeader {
struct SIP::StateSaveArea versionHeader;
union {
struct SIP::intelgt_state_save_area regHeader;
struct SIP::intelgt_state_save_area_V3 regHeaderV3;
uint64_t totalWmtpDataSize;
};
};
// NOLINTEND
#pragma pack(1)
struct SbaTrackedAddresses {
char magic[8] = "sbaarea";
uint64_t reserved1 = 0;
uint8_t version = 0;
uint8_t reserved2[7];
uint64_t generalStateBaseAddress = 0;
uint64_t surfaceStateBaseAddress = 0;
uint64_t dynamicStateBaseAddress = 0;
uint64_t indirectObjectBaseAddress = 0;
uint64_t instructionBaseAddress = 0;
uint64_t bindlessSurfaceStateBaseAddress = 0;
uint64_t bindlessSamplerStateBaseAddress = 0;
};
struct DebugAreaHeader {
char magic[8] = "dbgarea";
uint64_t reserved1 = 0;
uint8_t version = 0;
uint8_t pgsize = 0;
uint8_t size = 0;
uint8_t reserved2 = 0;
uint16_t scratchBegin = 0;
uint16_t scratchEnd = 0;
union {
uint64_t isSharedBitfield = 0;
struct {
uint64_t isShared : 1;
uint64_t reserved3 : 63;
};
};
};
static_assert(sizeof(DebugAreaHeader) == 32u * sizeof(uint8_t));
#pragma pack()
class DebuggerL0 : public NEO::Debugger, NEO::NonCopyableAndNonMovableClass {
public:
static std::unique_ptr<Debugger> create(NEO::Device *device);
DebuggerL0(NEO::Device *device);
~DebuggerL0() override;
NEO::GraphicsAllocation *getSbaTrackingBuffer(uint32_t contextId) {
return perContextSbaAllocations[contextId];
}
NEO::GraphicsAllocation *getModuleDebugArea() {
return moduleDebugArea;
}
uint64_t getSbaTrackingGpuVa() {
return sbaTrackingGpuVa.address;
}
void printTrackedAddresses(uint32_t contextId);
MOCKABLE_VIRTUAL void registerElfAndLinkWithAllocation(NEO::DebugData *debugData, NEO::GraphicsAllocation *isaAllocation);
MOCKABLE_VIRTUAL uint32_t registerElf(NEO::DebugData *debugData);
MOCKABLE_VIRTUAL void notifyCommandQueueCreated(NEO::Device *device);
MOCKABLE_VIRTUAL void notifyCommandQueueDestroyed(NEO::Device *device);
MOCKABLE_VIRTUAL void notifyModuleLoadAllocations(Device *device, const StackVec<NEO::GraphicsAllocation *, 32> &allocs);
MOCKABLE_VIRTUAL void notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t moduleLoadAddress);
MOCKABLE_VIRTUAL void notifyModuleDestroy(uint64_t moduleLoadAddress);
MOCKABLE_VIRTUAL void registerAllocationType(GraphicsAllocation *allocation);
void initSbaTrackingMode();
virtual size_t getSbaAddressLoadCommandsSize() = 0;
virtual void programSbaAddressLoad(NEO::LinearStream &cmdStream, uint64_t sbaGpuVa, bool isBcs) = 0;
MOCKABLE_VIRTUAL bool attachZebinModuleToSegmentAllocations(const StackVec<NEO::GraphicsAllocation *, 32> &kernelAlloc, uint32_t &moduleHandle, uint32_t elfHandle);
MOCKABLE_VIRTUAL bool removeZebinModule(uint32_t moduleHandle);
void initialize();
void setSingleAddressSpaceSbaTracking(bool value) {
singleAddressSpaceSbaTracking = value;
}
bool getSingleAddressSpaceSbaTracking() const override { return singleAddressSpaceSbaTracking; }
struct CommandQueueNotification {
uint32_t subDeviceIndex = 0;
uint32_t subDeviceCount = 0;
};
protected:
static bool initDebuggingInOs(NEO::OSInterface *osInterface);
NEO::Device *device = nullptr;
NEO::GraphicsAllocation *sbaAllocation = nullptr;
std::unordered_map<uint32_t, NEO::GraphicsAllocation *> perContextSbaAllocations;
NEO::AddressRange sbaTrackingGpuVa{};
NEO::GraphicsAllocation *moduleDebugArea = nullptr;
std::vector<uint32_t> commandQueueCount;
std::vector<uint32_t> uuidL0CommandQueueHandle;
bool singleAddressSpaceSbaTracking = false;
std::mutex debuggerL0Mutex;
};
static_assert(std::is_standard_layout<DebuggerL0::CommandQueueNotification>::value, "DebuggerL0::CommandQueueNotification issue");
using DebugerL0CreateFn = DebuggerL0 *(*)(NEO::Device *device);
extern DebugerL0CreateFn debuggerL0Factory[];
template <typename GfxFamily>
class DebuggerL0Hw : public DebuggerL0 {
public:
static DebuggerL0 *allocate(NEO::Device *device);
void captureStateBaseAddress(NEO::LinearStream &cmdStream, SbaAddresses sba, bool useFirstLevelBB) override;
size_t getSbaTrackingCommandsSize(size_t trackedAddressCount) override;
size_t getSbaAddressLoadCommandsSize() override;
void programSbaAddressLoad(NEO::LinearStream &cmdStream, uint64_t sbaGpuVa, bool isBcs) override;
void programSbaTrackingCommandsSingleAddressSpace(NEO::LinearStream &cmdStream, const SbaAddresses &sba, bool useFirstLevelBB);
protected:
DebuggerL0Hw(NEO::Device *device) : DebuggerL0(device){};
};
template <uint32_t coreFamily, typename GfxFamily>
struct DebuggerL0PopulateFactory {
DebuggerL0PopulateFactory() {
debuggerL0Factory[coreFamily] = DebuggerL0Hw<GfxFamily>::allocate;
}
};
} // namespace NEO
|