Move aub and tbx code to shared

Related-To: NEO-3964

Change-Id: Ice978e582721498d7496f989767ce7d6f5f4caf4
Signed-off-by: Filip Hazubski <filip.hazubski@intel.com>
This commit is contained in:
Filip Hazubski
2020-10-16 12:10:52 +02:00
committed by sys_ocldev
parent ccd5abfbfd
commit ca5f34133b
109 changed files with 153 additions and 177 deletions

View File

@@ -0,0 +1,28 @@
#
# Copyright (C) 2019-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(NEO_CORE_AUB_MEM_DUMP
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/aub_alloc_dump.h
${CMAKE_CURRENT_SOURCE_DIR}/aub_alloc_dump.inl
${CMAKE_CURRENT_SOURCE_DIR}/aub_data.h
${CMAKE_CURRENT_SOURCE_DIR}/aub_header.h
${CMAKE_CURRENT_SOURCE_DIR}/aub_mem_dump.cpp
${CMAKE_CURRENT_SOURCE_DIR}/aub_mem_dump.h
${CMAKE_CURRENT_SOURCE_DIR}/aub_mem_dump.inl
${CMAKE_CURRENT_SOURCE_DIR}/aub_services.h
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/context_flags.cpp
${CMAKE_CURRENT_SOURCE_DIR}/page_table_entry_bits.h
)
if(NOT DEFINED AUB_STREAM_PROJECT_NAME)
list(APPEND NEO_CORE_AUB_MEM_DUMP
${CMAKE_CURRENT_SOURCE_DIR}/aub_stream_stubs.cpp
)
endif()
set_property(GLOBAL PROPERTY NEO_CORE_AUB_MEM_DUMP ${NEO_CORE_AUB_MEM_DUMP})
add_subdirectories()

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/aub_mem_dump/aub_mem_dump.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/gmm_helper/resource_info.h"
#include "shared/source/memory_manager/graphics_allocation.h"
using namespace NEO;
namespace aub_stream {
struct SurfaceInfo;
}
namespace AubAllocDump {
enum DumpFormat {
NONE,
BUFFER_BIN,
BUFFER_TRE,
IMAGE_BMP,
IMAGE_TRE,
};
inline bool isWritableBuffer(GraphicsAllocation &gfxAllocation) {
return (gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::BUFFER ||
gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::BUFFER_COMPRESSED ||
gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY ||
gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR ||
gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::MAP_ALLOCATION ||
gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::SVM_GPU) &&
gfxAllocation.isMemObjectsAllocationWithWritableFlags();
}
inline bool isWritableImage(GraphicsAllocation &gfxAllocation) {
return (gfxAllocation.getAllocationType() == GraphicsAllocation::AllocationType::IMAGE) &&
gfxAllocation.isMemObjectsAllocationWithWritableFlags();
}
inline DumpFormat getDumpFormat(GraphicsAllocation &gfxAllocation) {
auto dumpBufferFormat = DebugManager.flags.AUBDumpBufferFormat.get();
auto dumpImageFormat = DebugManager.flags.AUBDumpImageFormat.get();
auto isDumpableBuffer = isWritableBuffer(gfxAllocation);
auto isDumpableImage = isWritableImage(gfxAllocation);
auto dumpFormat = DumpFormat::NONE;
if (isDumpableBuffer) {
if (0 == dumpBufferFormat.compare("BIN")) {
dumpFormat = DumpFormat::BUFFER_BIN;
} else if (0 == dumpBufferFormat.compare("TRE")) {
dumpFormat = DumpFormat::BUFFER_TRE;
}
} else if (isDumpableImage) {
if (0 == dumpImageFormat.compare("BMP")) {
dumpFormat = DumpFormat::IMAGE_BMP;
} else if (0 == dumpImageFormat.compare("TRE")) {
dumpFormat = DumpFormat::IMAGE_TRE;
}
}
return dumpFormat;
}
inline bool isBufferDumpFormat(DumpFormat dumpFormat) {
return (AubAllocDump::DumpFormat::BUFFER_BIN == dumpFormat) || (dumpFormat == AubAllocDump::DumpFormat::BUFFER_TRE);
}
inline bool isImageDumpFormat(DumpFormat dumpFormat) {
return (AubAllocDump::DumpFormat::IMAGE_BMP == dumpFormat) || (dumpFormat == AubAllocDump::DumpFormat::IMAGE_TRE);
}
template <typename GfxFamily>
aub_stream::SurfaceInfo *getDumpSurfaceInfo(GraphicsAllocation &gfxAllocation, DumpFormat dumpFormat);
template <typename GfxFamily>
uint32_t getImageSurfaceTypeFromGmmResourceType(GMM_RESOURCE_TYPE gmmResourceType);
template <typename GfxFamily>
void dumpBufferInBinFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context);
template <typename GfxFamily>
void dumpImageInBmpFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context);
template <typename GfxFamily>
void dumpBufferInTreFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context);
template <typename GfxFamily>
void dumpImageInTreFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context);
template <typename GfxFamily>
void dumpAllocation(DumpFormat dumpFormat, GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context);
} // namespace AubAllocDump

View File

@@ -0,0 +1,217 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/aub_mem_dump/aub_alloc_dump.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/gmm_helper/gmm_helper.h"
#include "third_party/aub_stream/headers/aubstream.h"
using namespace NEO;
using namespace aub_stream;
namespace AubAllocDump {
template <typename GfxFamily>
uint32_t getImageSurfaceTypeFromGmmResourceType(GMM_RESOURCE_TYPE gmmResourceType) {
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
auto surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_NULL;
switch (gmmResourceType) {
case GMM_RESOURCE_TYPE::RESOURCE_1D:
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D;
break;
case GMM_RESOURCE_TYPE::RESOURCE_2D:
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_2D;
break;
case GMM_RESOURCE_TYPE::RESOURCE_3D:
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D;
break;
default:
DEBUG_BREAK_IF(true);
break;
}
return surfaceType;
}
template <typename GfxFamily>
SurfaceInfo *getDumpSurfaceInfo(GraphicsAllocation &gfxAllocation, DumpFormat dumpFormat) {
SurfaceInfo *surfaceInfo = nullptr;
if (isBufferDumpFormat(dumpFormat)) {
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
using SURFACE_FORMAT = typename RENDER_SURFACE_STATE::SURFACE_FORMAT;
surfaceInfo = new SurfaceInfo();
surfaceInfo->address = GmmHelper::decanonize(gfxAllocation.getGpuAddress());
surfaceInfo->width = static_cast<uint32_t>(gfxAllocation.getUnderlyingBufferSize());
surfaceInfo->height = 1;
surfaceInfo->pitch = static_cast<uint32_t>(gfxAllocation.getUnderlyingBufferSize());
surfaceInfo->format = SURFACE_FORMAT::SURFACE_FORMAT_RAW;
surfaceInfo->tilingType = RENDER_SURFACE_STATE::TILE_MODE_LINEAR;
surfaceInfo->surftype = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_BUFFER;
surfaceInfo->compressed = GraphicsAllocation::AllocationType::BUFFER_COMPRESSED == gfxAllocation.getAllocationType();
surfaceInfo->dumpType = (AubAllocDump::DumpFormat::BUFFER_TRE == dumpFormat) ? dumpType::tre : dumpType::bin;
} else if (isImageDumpFormat(dumpFormat)) {
auto gmm = gfxAllocation.getDefaultGmm();
if (gmm->gmmResourceInfo->getNumSamples() > 1) {
return nullptr;
}
surfaceInfo = new SurfaceInfo();
surfaceInfo->address = GmmHelper::decanonize(gfxAllocation.getGpuAddress());
surfaceInfo->width = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseWidth());
surfaceInfo->height = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseHeight());
surfaceInfo->pitch = static_cast<uint32_t>(gmm->gmmResourceInfo->getRenderPitch());
surfaceInfo->format = gmm->gmmResourceInfo->getResourceFormatSurfaceState();
surfaceInfo->tilingType = gmm->gmmResourceInfo->getTileModeSurfaceState();
surfaceInfo->surftype = getImageSurfaceTypeFromGmmResourceType<GfxFamily>(gmm->gmmResourceInfo->getResourceType());
surfaceInfo->compressed = gmm->isRenderCompressed;
surfaceInfo->dumpType = (AubAllocDump::DumpFormat::IMAGE_TRE == dumpFormat) ? dumpType::tre : dumpType::bmp;
}
return surfaceInfo;
}
template <typename GfxFamily>
void dumpBufferInBinFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context) {
AubMemDump::AubCaptureBinaryDumpHD cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.Header.Type = 0x7;
cmd.Header.Opcode = 0x1;
cmd.Header.SubOp = 0x15;
cmd.Header.DwordLength = ((sizeof(cmd) - sizeof(cmd.Header)) / sizeof(uint32_t)) - 1;
cmd.setHeight(1);
cmd.setWidth(gfxAllocation.getUnderlyingBufferSize());
cmd.setBaseAddr(gfxAllocation.getGpuAddress());
cmd.setPitch(gfxAllocation.getUnderlyingBufferSize());
cmd.GttType = 1;
cmd.DirectoryHandle = context;
stream->write(reinterpret_cast<char *>(&cmd), sizeof(cmd));
}
template <typename GfxFamily>
void dumpImageInBmpFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context) {
auto gmm = gfxAllocation.getDefaultGmm();
AubMemDump::AubCmdDumpBmpHd cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.Header.Type = 0x7;
cmd.Header.Opcode = 0x1;
cmd.Header.SubOp = 0x44;
cmd.Header.DwordLength = ((sizeof(cmd) - sizeof(cmd.Header)) / sizeof(uint32_t)) - 1;
cmd.Xmin = 0;
cmd.Ymin = 0;
auto pitch = gmm->gmmResourceInfo->getRenderPitch();
auto bitsPerPixel = gmm->gmmResourceInfo->getBitsPerPixel();
auto pitchInPixels = static_cast<uint32_t>(8 * pitch / bitsPerPixel);
cmd.BufferPitch = pitchInPixels;
cmd.BitsPerPixel = bitsPerPixel;
cmd.Format = gmm->gmmResourceInfo->getResourceFormatSurfaceState();
cmd.Xsize = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseWidth());
cmd.Ysize = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseHeight());
cmd.setBaseAddr(gfxAllocation.getGpuAddress());
cmd.Secure = 0;
cmd.UseFence = 0;
auto flagInfo = gmm->gmmResourceInfo->getResourceFlags()->Info;
cmd.TileOn = flagInfo.TiledW || flagInfo.TiledX || flagInfo.TiledY || flagInfo.TiledYf || flagInfo.TiledYs;
cmd.WalkY = flagInfo.TiledY;
cmd.UsePPGTT = 1;
cmd.Use32BitDump = 1; // Dump out in 32bpp vs 24bpp
cmd.UseFullFormat = 1;
cmd.DirectoryHandle = context;
stream->write(reinterpret_cast<char *>(&cmd), sizeof(cmd));
}
template <typename GfxFamily>
void dumpBufferInTreFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context) {
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
using SURFACE_FORMAT = typename RENDER_SURFACE_STATE::SURFACE_FORMAT;
AubMemDump::CmdServicesMemTraceDumpCompress cmd;
memset(&cmd, 0, sizeof(AubMemDump::CmdServicesMemTraceDumpCompress));
cmd.dwordCount = (sizeof(AubMemDump::CmdServicesMemTraceDumpCompress) - 1) / 4;
cmd.instructionSubOpcode = 0x10;
cmd.instructionOpcode = 0x2e;
cmd.instructionType = 0x7;
cmd.setSurfaceAddress(gfxAllocation.getGpuAddress());
cmd.surfaceWidth = static_cast<uint32_t>(gfxAllocation.getUnderlyingBufferSize());
cmd.surfaceHeight = 1;
cmd.surfacePitch = static_cast<uint32_t>(gfxAllocation.getUnderlyingBufferSize());
cmd.surfaceFormat = SURFACE_FORMAT::SURFACE_FORMAT_RAW;
cmd.dumpType = AubMemDump::CmdServicesMemTraceDumpCompress::DumpTypeValues::Tre;
cmd.surfaceTilingType = RENDER_SURFACE_STATE::TILE_MODE_LINEAR;
cmd.surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_BUFFER;
cmd.algorithm = AubMemDump::CmdServicesMemTraceDumpCompress::AlgorithmValues::Uncompressed;
cmd.gttType = 1;
cmd.directoryHandle = context;
stream->write(reinterpret_cast<char *>(&cmd), sizeof(cmd));
}
template <typename GfxFamily>
void dumpImageInTreFormat(GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context) {
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
auto gmm = gfxAllocation.getDefaultGmm();
if ((gmm->gmmResourceInfo->getNumSamples() > 1) || (gmm->isRenderCompressed)) {
DEBUG_BREAK_IF(true); //unsupported
return;
}
auto surfaceType = getImageSurfaceTypeFromGmmResourceType<GfxFamily>(gmm->gmmResourceInfo->getResourceType());
AubMemDump::CmdServicesMemTraceDumpCompress cmd;
memset(&cmd, 0, sizeof(AubMemDump::CmdServicesMemTraceDumpCompress));
cmd.dwordCount = (sizeof(AubMemDump::CmdServicesMemTraceDumpCompress) - 1) / 4;
cmd.instructionSubOpcode = 0x10;
cmd.instructionOpcode = 0x2e;
cmd.instructionType = 0x7;
cmd.setSurfaceAddress(gfxAllocation.getGpuAddress());
cmd.surfaceWidth = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseWidth());
cmd.surfaceHeight = static_cast<uint32_t>(gmm->gmmResourceInfo->getBaseHeight());
cmd.surfacePitch = static_cast<uint32_t>(gmm->gmmResourceInfo->getRenderPitch());
cmd.surfaceFormat = gmm->gmmResourceInfo->getResourceFormatSurfaceState();
cmd.dumpType = AubMemDump::CmdServicesMemTraceDumpCompress::DumpTypeValues::Tre;
cmd.surfaceTilingType = gmm->gmmResourceInfo->getTileModeSurfaceState();
cmd.surfaceType = surfaceType;
cmd.algorithm = AubMemDump::CmdServicesMemTraceDumpCompress::AlgorithmValues::Uncompressed;
cmd.gttType = 1;
cmd.directoryHandle = context;
stream->write(reinterpret_cast<char *>(&cmd), sizeof(cmd));
}
template <typename GfxFamily>
void dumpAllocation(DumpFormat dumpFormat, GraphicsAllocation &gfxAllocation, AubMemDump::AubFileStream *stream, uint32_t context) {
switch (dumpFormat) {
case DumpFormat::BUFFER_BIN:
dumpBufferInBinFormat<GfxFamily>(gfxAllocation, stream, context);
break;
case DumpFormat::BUFFER_TRE:
dumpBufferInTreFormat<GfxFamily>(gfxAllocation, stream, context);
break;
case DumpFormat::IMAGE_BMP:
dumpImageInBmpFormat<GfxFamily>(gfxAllocation, stream, context);
break;
case DumpFormat::IMAGE_TRE:
dumpImageInTreFormat<GfxFamily>(gfxAllocation, stream, context);
break;
default:
break;
}
}
} // namespace AubAllocDump

View File

@@ -0,0 +1,15 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
struct AubGTTData {
bool present;
bool localMemory;
};

View File

@@ -0,0 +1,121 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
#include <type_traits>
#ifndef WIN32
#pragma pack(4)
#else
#pragma pack(push, 4)
#endif
inline void setMisalignedUint64(uint64_t *address, const uint64_t value) {
uint32_t *addressBits = reinterpret_cast<uint32_t *>(address);
addressBits[0] = static_cast<uint32_t>(value);
addressBits[1] = static_cast<uint32_t>(value >> 32);
}
inline uint64_t getMisalignedUint64(const uint64_t *address) {
const uint32_t *addressBits = reinterpret_cast<const uint32_t *>(address);
return static_cast<uint64_t>(static_cast<uint64_t>(addressBits[1]) << 32) | addressBits[0];
}
struct AubCmdHdr {
uint32_t DwordLength : 16,
SubOp : 7,
Opcode : 6,
Type : 3;
};
static_assert(4 == sizeof(AubCmdHdr), "Invalid size for AubCmdHdr");
struct AubCmdDumpBmpHd {
AubCmdHdr Header;
uint32_t Xmin;
uint32_t Ymin;
uint32_t BufferPitch;
uint32_t BitsPerPixel : 8,
Format : 8,
Reserved_0 : 16;
uint32_t Xsize;
uint32_t Ysize;
uint64_t BaseAddr;
uint32_t Secure : 1,
UseFence : 1,
TileOn : 1,
WalkY : 1,
UsePPGTT : 1,
Use32BitDump : 1,
UseFullFormat : 1,
Reserved_1 : 25;
uint32_t DirectoryHandle;
uint64_t getBaseAddr() const {
return getMisalignedUint64(&this->BaseAddr);
}
void setBaseAddr(const uint64_t baseAddr) {
setMisalignedUint64(&this->BaseAddr, baseAddr);
}
};
static_assert(44 == sizeof(AubCmdDumpBmpHd), "Invalid size for AubCmdDumpBmpHd");
struct AubPpgttContextCreate {
AubCmdHdr Header;
uint32_t Handle;
uint32_t AdvancedContext : 1,
SixtyFourBit : 1,
Reserved_31_2 : 30;
uint64_t PageDirPointer[4];
};
static_assert(44 == sizeof(AubPpgttContextCreate), "Invalid size for AubPpgttContextCreate");
struct AubCaptureBinaryDumpHD {
AubCmdHdr Header;
uint64_t BaseAddr;
uint64_t Width;
uint64_t Height;
uint64_t Pitch;
uint32_t SurfaceType : 4,
GttType : 2,
Reserved_31_6 : 26;
uint32_t DirectoryHandle;
uint32_t ReservedDW1;
uint32_t ReservedDW2;
char OutputFile[4];
uint64_t getBaseAddr() const {
return getMisalignedUint64(&this->BaseAddr);
}
void setBaseAddr(const uint64_t baseAddr) {
setMisalignedUint64(&this->BaseAddr, baseAddr);
}
uint64_t getWidth() const {
return getMisalignedUint64(&this->Width);
}
void setWidth(const uint64_t width) {
setMisalignedUint64(&this->Width, width);
}
uint64_t getHeight() const {
return getMisalignedUint64(&this->Height);
}
void setHeight(const uint64_t height) {
setMisalignedUint64(&this->Height, height);
}
uint64_t getPitch() const {
return getMisalignedUint64(&this->Pitch);
}
void setPitch(const uint64_t pitch) {
setMisalignedUint64(&this->Pitch, pitch);
}
};
static_assert(56 == sizeof(AubCaptureBinaryDumpHD), "Invalid size for AubCaptureBinaryDumpHD");
#ifndef WIN32
#pragma pack()
#else
#pragma pack(pop)
#endif

View File

@@ -0,0 +1,190 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "aub_mem_dump.h"
#include "shared/source/aub/aub_helper.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/ptr_math.h"
namespace AubMemDump {
const uint64_t g_pageMask = ~(4096ull - 1);
const size_t g_dwordCountMax = 65536;
// Some page table constants used in virtualizing the page tables.
// clang-format off
// 32 bit page table traits
const uint64_t PageTableTraits<32>::physicalMemory = 0; // 1ull <<addressingBits;
const uint64_t PageTableTraits<32>::numPTEntries = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS);
const uint64_t PageTableTraits<32>::sizePT = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<32>::ptBaseAddress = BIT(38);
const uint64_t PageTableTraits<32>::numPDEntries = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS - PageTableTraits<32>::NUM_PTE_BITS);
const uint64_t PageTableTraits<32>::sizePD = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS - PageTableTraits<32>::NUM_PTE_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<32>::pdBaseAddress = BIT(37);
const uint64_t PageTableTraits<32>::numPDPEntries = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS - PageTableTraits<32>::NUM_PTE_BITS - PageTableTraits<32>::NUM_PDE_BITS);
const uint64_t PageTableTraits<32>::sizePDP = BIT(PageTableTraits<32>::addressingBits - PageTableTraits<32>::NUM_OFFSET_BITS - PageTableTraits<32>::NUM_PTE_BITS - PageTableTraits<32>::NUM_PDE_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<32>::pdpBaseAddress = BIT(36);
// 48 bit page table traits
const uint64_t PageTableTraits<48>::physicalMemory = 0; // 1ull <<addressingBits;
const uint64_t PageTableTraits<48>::numPTEntries = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS);
const uint64_t PageTableTraits<48>::sizePT = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<48>::ptBaseAddress = BIT(32);
const uint64_t PageTableTraits<48>::numPDEntries = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS - PageTableTraits<48>::NUM_PTE_BITS);
const uint64_t PageTableTraits<48>::sizePD = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS - PageTableTraits<48>::NUM_PTE_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<48>::pdBaseAddress = BIT(31);
const uint64_t PageTableTraits<48>::numPDPEntries = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS - PageTableTraits<48>::NUM_PTE_BITS - PageTableTraits<48>::NUM_PDE_BITS);
const uint64_t PageTableTraits<48>::sizePDP = BIT(PageTableTraits<48>::addressingBits - PageTableTraits<48>::NUM_OFFSET_BITS - PageTableTraits<48>::NUM_PTE_BITS - PageTableTraits<48>::NUM_PDE_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<48>::pdpBaseAddress = BIT(30);
const uint64_t PageTableTraits<48>::numPML4Entries = BIT(NUM_PML4_BITS);
const uint64_t PageTableTraits<48>::sizePML4 = BIT(NUM_PML4_BITS) * sizeof(uint64_t);
const uint64_t PageTableTraits<48>::pml4BaseAddress = BIT(29);
// clang-format on
void LrcaHelper::setRingTail(void *pLRCIn, uint32_t ringTail) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetRingRegisters + offsetRingTail);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2030);
*pLRCA++ = ringTail;
}
void LrcaHelper::setRingHead(void *pLRCIn, uint32_t ringHead) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetRingRegisters + offsetRingHead);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2034);
*pLRCA++ = ringHead;
}
void LrcaHelper::setRingBase(void *pLRCIn, uint32_t ringBase) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetRingRegisters + offsetRingBase);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2038);
*pLRCA++ = ringBase;
}
void LrcaHelper::setRingCtrl(void *pLRCIn, uint32_t ringCtrl) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetRingRegisters + offsetRingCtrl);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x203c);
*pLRCA++ = ringCtrl;
}
void LrcaHelper::setPDP0(void *pLRCIn, uint64_t address) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetPageTableRegisters + offsetPDP0);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2274);
*pLRCA++ = address >> 32;
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2270);
*pLRCA++ = address & 0xffffffff;
}
void LrcaHelper::setPDP1(void *pLRCIn, uint64_t address) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetPageTableRegisters + offsetPDP1);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x227c);
*pLRCA++ = address >> 32;
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2278);
*pLRCA++ = address & 0xffffffff;
}
void LrcaHelper::setPDP2(void *pLRCIn, uint64_t address) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetPageTableRegisters + offsetPDP2);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2284);
*pLRCA++ = address >> 32;
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2280);
*pLRCA++ = address & 0xffffffff;
}
void LrcaHelper::setPDP3(void *pLRCIn, uint64_t address) const {
auto pLRCA = ptrOffset(reinterpret_cast<uint32_t *>(pLRCIn),
offsetContext + offsetPageTableRegisters + offsetPDP3);
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x228c);
*pLRCA++ = address >> 32;
*pLRCA++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2288);
*pLRCA++ = address & 0xffffffff;
}
void LrcaHelper::setPML4(void *pLRCIn, uint64_t address) const {
setPDP0(pLRCIn, address);
}
void LrcaHelper::initialize(void *pLRCIn) const {
auto pLRCABase = reinterpret_cast<uint32_t *>(pLRCIn);
// Initialize to known but benign garbage
for (size_t i = 0; i < sizeLRCA / sizeof(uint32_t); i++) {
pLRCABase[i] = 0x1;
}
auto pLRCA = ptrOffset(pLRCABase, offsetContext);
// Initialize the ring context of the LRCA
auto pLRI = ptrOffset(pLRCA, offsetLRI0);
auto numRegs = numRegsLRI0;
*pLRI++ = 0x11001000 | (2 * numRegs - 1);
uint32_t ctxSrCtlValue = 0x00010001; // Inhibit context-restore
setContextSaveRestoreFlags(ctxSrCtlValue);
while (numRegs-- > 0) {
*pLRI++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2244); // CTXT_SR_CTL
*pLRI++ = ctxSrCtlValue;
}
// Initialize the other LRI
DEBUG_BREAK_IF(offsetLRI1 != 0x21 * sizeof(uint32_t));
pLRI = ptrOffset(pLRCA, offsetLRI1);
numRegs = numRegsLRI1;
*pLRI++ = 0x11001000 | (2 * numRegs - 1);
while (numRegs-- > 0) {
*pLRI++ = AubMemDump::computeRegisterOffset(mmioBase, 0x20d8); // DEBUG
*pLRI++ = 0x00200020;
}
DEBUG_BREAK_IF(offsetLRI2 != 0x41 * sizeof(uint32_t));
pLRI = ptrOffset(pLRCA, offsetLRI2);
numRegs = numRegsLRI2;
*pLRI++ = 0x11000000 | (2 * numRegs - 1);
while (numRegs-- > 0) {
*pLRI++ = AubMemDump::computeRegisterOffset(mmioBase, 0x2094); // NOP ID
*pLRI++ = 0x00000000;
}
setRingHead(pLRCIn, 0);
setRingTail(pLRCIn, 0);
setRingBase(pLRCIn, 0);
setRingCtrl(pLRCIn, 0);
setPDP0(pLRCIn, 0);
setPDP1(pLRCIn, 0);
setPDP2(pLRCIn, 0);
setPDP3(pLRCIn, 0);
}
void AubStream::writeMMIO(uint32_t offset, uint32_t value) {
auto dbgOffset = NEO::DebugManager.flags.AubDumpOverrideMmioRegister.get();
if (dbgOffset > 0) {
if (offset == static_cast<uint32_t>(dbgOffset)) {
offset = static_cast<uint32_t>(dbgOffset);
value = static_cast<uint32_t>(NEO::DebugManager.flags.AubDumpOverrideMmioRegisterValue.get());
}
}
writeMMIOImpl(offset, value);
}
} // namespace AubMemDump

View File

@@ -0,0 +1,405 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
#include <cstdio>
#include <fstream>
#include <mutex>
#include <string>
#ifndef BIT
#define BIT(x) (((uint64_t)1) << (x))
#endif
#include "shared/source/aub_mem_dump/aub_data.h"
namespace NEO {
class AubHelper;
}
namespace AubMemDump {
#include "aub_services.h"
constexpr uint32_t rcsRegisterBase = 0x2000;
inline uint32_t computeRegisterOffset(uint32_t mmioBase, uint32_t rcsRegisterOffset) {
return mmioBase + rcsRegisterOffset - rcsRegisterBase;
}
template <typename Cmd>
inline void setAddress(Cmd &cmd, uint64_t address) {
cmd.address = address;
}
template <>
inline void setAddress(CmdServicesMemTraceMemoryCompare &cmd, uint64_t address) {
cmd.address = static_cast<uint32_t>(address);
cmd.addressHigh = static_cast<uint32_t>(address >> 32);
}
union IAPageTableEntry {
struct
{
uint64_t Present : 1; //[0]
uint64_t Writable : 1; //[1]
uint64_t UserSupervisor : 1; //[2]
uint64_t PWT : 1; //[3]
uint64_t PCD : 1; //[4]
uint64_t Accessed : 1; //[5]
uint64_t Dirty : 1; //[6]
uint64_t PAT : 1; //[7]
uint64_t Global : 1; //[8]
uint64_t Reserved_9 : 1; //[9]
uint64_t Reserved_10 : 1; //[10]
uint64_t Reserved_11 : 1; //[11]
uint64_t PhysicalAddress : 27; //[38:12]
uint64_t Reserved_51_39 : 13; //[51:39]
uint64_t Ignored : 11; //[62:52]
uint64_t ExecuteDisable : 1; //[63]
} pageConfig;
uint32_t dwordData[2];
uint64_t uiData;
};
union MiGttEntry {
struct
{
uint64_t Present : 1; //[0]
uint64_t LocalMemory : 1; //[1]
uint64_t FunctionNumber : 10; //[11:2]
uint64_t PhysicalAddress : 35; //[46:12]
uint64_t Ignored : 17; //[63:47]
} pageConfig;
uint32_t dwordData[2];
uint64_t uiData;
};
// Use the latest DeviceValues enumerations available
typedef CmdServicesMemTraceVersion::DeviceValues DeviceValues;
typedef CmdServicesMemTraceVersion::SteppingValues SteppingValues;
typedef CmdServicesMemTraceMemoryWrite::AddressSpaceValues AddressSpaceValues;
typedef CmdServicesMemTraceMemoryWrite::DataTypeHintValues DataTypeHintValues;
typedef CmdServicesMemTraceMemoryDump::TilingValues TilingValues;
typedef CmdServicesMemTraceMemoryWrite::RepeatMemoryValues RepeatMemoryValues;
typedef CmdServicesMemTraceRegisterWrite::MessageSourceIdValues MessageSourceIdValues;
typedef CmdServicesMemTraceRegisterWrite::RegisterSizeValues RegisterSizeValues;
typedef CmdServicesMemTraceRegisterWrite::RegisterSpaceValues RegisterSpaceValues;
typedef CmdServicesMemTraceMemoryPoll::DataSizeValues DataSizeValues;
template <int deviceIn, int addressingBitsIn>
struct Traits {
typedef struct AubStream Stream;
enum {
addressingBits = addressingBitsIn,
device = deviceIn
};
};
struct AubStream {
virtual void open(const char *filePath) = 0;
virtual void close() = 0;
virtual bool init(uint32_t stepping, uint32_t device) = 0;
virtual void createContext(const AubPpgttContextCreate &cmd) {}
virtual void writeMemory(uint64_t physAddress, const void *memory, size_t sizeToDumpThisIteration, uint32_t addressSpace, uint32_t hint) = 0;
virtual void writeMemoryWriteHeader(uint64_t physAddress, size_t size, uint32_t addressSpace, uint32_t hint) = 0;
virtual void writeMemoryWriteHeader(uint64_t physAddress, size_t size, uint32_t addressSpace) {
writeMemoryWriteHeader(physAddress, size, addressSpace, CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceNotype);
}
virtual void writePTE(uint64_t physAddress, uint64_t entry, uint32_t addressSpace) = 0;
virtual void writeGTT(uint32_t offset, uint64_t entry) = 0;
void writeMMIO(uint32_t offset, uint32_t value);
virtual void registerPoll(uint32_t registerOffset, uint32_t mask, uint32_t value, bool pollNotEqual, uint32_t timeoutAction) = 0;
virtual ~AubStream() = default;
protected:
virtual void writeMMIOImpl(uint32_t offset, uint32_t value) = 0;
};
struct AubFileStream : public AubStream {
void open(const char *filePath) override;
void close() override;
bool init(uint32_t stepping, uint32_t device) override;
void createContext(const AubPpgttContextCreate &cmd) override;
void writeMemory(uint64_t physAddress, const void *memory, size_t size, uint32_t addressSpace, uint32_t hint) override;
void writeMemoryWriteHeader(uint64_t physAddress, size_t size, uint32_t addressSpace, uint32_t hint) override;
void writePTE(uint64_t physAddress, uint64_t entry, uint32_t addressSpace) override;
void writeGTT(uint32_t offset, uint64_t entry) override;
void writeMMIOImpl(uint32_t offset, uint32_t value) override;
void registerPoll(uint32_t registerOffset, uint32_t mask, uint32_t value, bool pollNotEqual, uint32_t timeoutAction) override;
MOCKABLE_VIRTUAL bool isOpen() const { return fileHandle.is_open(); }
MOCKABLE_VIRTUAL const std::string &getFileName() const { return fileName; }
MOCKABLE_VIRTUAL void write(const char *data, size_t size);
MOCKABLE_VIRTUAL void flush();
MOCKABLE_VIRTUAL void expectMMIO(uint32_t mmioRegister, uint32_t expectedValue);
MOCKABLE_VIRTUAL void expectMemory(uint64_t physAddress, const void *memory, size_t size,
uint32_t addressSpace, uint32_t compareOperation);
MOCKABLE_VIRTUAL bool addComment(const char *message);
MOCKABLE_VIRTUAL std::unique_lock<std::mutex> lockStream();
std::ofstream fileHandle;
std::string fileName;
std::mutex mutex;
};
template <int addressingBits>
struct PageTableTraits {
};
template <>
struct PageTableTraits<32> {
// clang-format off
enum {
addressingBits = 32,
NUM_OFFSET_BITS = 12,
NUM_PTE_BITS = 9,
NUM_PDE_BITS = 9,
NUM_PDP_BITS = addressingBits - NUM_PDE_BITS - NUM_PTE_BITS - NUM_OFFSET_BITS,
};
static const uint64_t physicalMemory;
static const uint64_t numPTEntries;
static const uint64_t sizePT;
static const uint64_t ptBaseAddress;
static const uint64_t numPDEntries;
static const uint64_t sizePD;
static const uint64_t pdBaseAddress;
static const uint64_t numPDPEntries;
static const uint64_t sizePDP;
static const uint64_t pdpBaseAddress;
// clang-format on
};
template <>
struct PageTableTraits<48> {
// clang-format off
enum {
addressingBits = 48,
NUM_OFFSET_BITS = PageTableTraits<32>::NUM_OFFSET_BITS,
NUM_PTE_BITS = PageTableTraits<32>::NUM_PTE_BITS,
NUM_PDE_BITS = PageTableTraits<32>::NUM_PDE_BITS,
NUM_PDP_BITS = PageTableTraits<32>::NUM_PDP_BITS,
NUM_PML4_BITS = addressingBits - NUM_PDP_BITS - NUM_PDE_BITS - NUM_PTE_BITS - NUM_OFFSET_BITS
};
static const uint64_t physicalMemory;
static const uint64_t numPTEntries;
static const uint64_t sizePT;
static const uint64_t ptBaseAddress;
static const uint64_t numPDEntries;
static const uint64_t sizePD;
static const uint64_t pdBaseAddress;
static const uint64_t numPDPEntries;
static const uint64_t sizePDP;
static const uint64_t pdpBaseAddress;
static const uint64_t numPML4Entries;
static const uint64_t sizePML4;
static const uint64_t pml4BaseAddress;
// clang-format on
};
template <typename Traits>
struct AubPageTableHelper {
typedef AubMemDump::PageTableTraits<Traits::addressingBits> PageTableTraits;
enum {
addressingBits = Traits::addressingBits
};
static inline uint32_t ptrToGGTT(const void *memory) {
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(memory));
}
static inline uintptr_t ptrToPPGTT(const void *memory) {
return reinterpret_cast<uintptr_t>(memory);
}
static inline uint64_t getPTEAddress(uint64_t ptIndex) {
return PageTableTraits::ptBaseAddress + ptIndex * sizeof(uint64_t);
}
static inline uint64_t getPDEAddress(uint64_t pdIndex) {
return PageTableTraits::pdBaseAddress + pdIndex * sizeof(uint64_t);
}
static inline uint64_t getPDPAddress(uint64_t pdpIndex) {
return PageTableTraits::pdpBaseAddress + pdpIndex * sizeof(uint64_t);
}
};
template <typename Traits>
struct AubPageTableHelper32 : public AubPageTableHelper<Traits>, PageTableTraits<32> {
typedef AubPageTableHelper<Traits> BaseClass;
static void createContext(typename Traits::Stream &stream, uint32_t context);
static uint64_t reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
size_t blockSize, uint64_t physAddress,
uint64_t additionalBits, const NEO::AubHelper &aubHelper);
static void fixupLRC(uint8_t *pLrc);
};
template <typename Traits>
struct AubPageTableHelper64 : public AubPageTableHelper<Traits>, PageTableTraits<48> {
typedef AubPageTableHelper<Traits> BaseClass;
static inline uint64_t getPML4Address(uint64_t pml4Index) {
return pml4BaseAddress + pml4Index * sizeof(uint64_t);
}
static void createContext(typename Traits::Stream &stream, uint32_t context);
static uint64_t reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
size_t blockSize, uint64_t physAddress,
uint64_t additionalBits, const NEO::AubHelper &aubHelper);
static void fixupLRC(uint8_t *pLrc);
};
template <typename TraitsIn>
struct AubDump : public std::conditional<TraitsIn::addressingBits == 32, AubPageTableHelper32<TraitsIn>, AubPageTableHelper64<TraitsIn>>::type {
using Traits = TraitsIn;
using AddressType = typename std::conditional<Traits::addressingBits == 32, uint32_t, uint64_t>::type;
using BaseHelper = typename std::conditional<Traits::addressingBits == 32, AubPageTableHelper32<Traits>, AubPageTableHelper64<Traits>>::type;
using Stream = typename Traits::Stream;
typedef union _MiContextDescriptorReg_ {
struct {
uint64_t Valid : 1; //[0]
uint64_t ForcePageDirRestore : 1; //[1]
uint64_t ForceRestore : 1; //[2]
uint64_t Legacy : 1; //[3]
uint64_t ADor64bitSupport : 1; //[4] Selects 64-bit PPGTT in Legacy mode
uint64_t LlcCoherencySupport : 1; //[5]
uint64_t FaultSupport : 2; //[7:6]
uint64_t PrivilegeAccessOrPPGTT : 1; //[8] Selects PPGTT in Legacy mode
uint64_t FunctionType : 3; //[11:9]
uint64_t LogicalRingCtxAddress : 20; //[31:12]
uint64_t ContextID : 32; //[63:32]
} sData;
uint32_t ulData[2];
uint64_t qwordData[2 / 2];
} MiContextDescriptorReg, *pMiContextDescriptorReg;
// Write a block of memory to a given address space using an optional hint
static void addMemoryWrite(Stream &stream, uint64_t addr, const void *memory, size_t blockSize, int addressSpace, int hint = DataTypeHintValues::TraceNotype);
static uint64_t reserveAddressGGTT(Stream &stream, uint32_t addr, size_t size, uint64_t physStart, AubGTTData data);
static uint64_t reserveAddressGGTT(Stream &stream, const void *memory, size_t size, uint64_t physStart, AubGTTData data);
static void reserveAddressGGTTAndWriteMmeory(Stream &stream, uintptr_t gfxAddress, const void *memory, uint64_t physAddress,
size_t size, size_t offset, uint64_t additionalBits, const NEO::AubHelper &aubHelper);
static void setGttEntry(MiGttEntry &entry, uint64_t address, AubGTTData data);
private:
static uint64_t reserveAddress(Stream &stream, uint32_t addr, size_t size, unsigned int addressSpace /* = AddressSpaceValues::TraceGttEntry*/, uint64_t physStart, AubGTTData data);
};
struct LrcaHelper {
LrcaHelper(uint32_t base) : mmioBase(base) {
}
int aubHintLRCA = DataTypeHintValues::TraceNotype;
int aubHintCommandBuffer = DataTypeHintValues::TraceCommandBuffer;
int aubHintBatchBuffer = DataTypeHintValues::TraceBatchBuffer;
const char *name = "XCS";
uint32_t mmioBase = 0;
size_t sizeLRCA = 0x2000;
uint32_t alignLRCA = 0x1000;
uint32_t offsetContext = 0x1000;
uint32_t offsetLRI0 = 0x01 * sizeof(uint32_t);
uint32_t numRegsLRI0 = 14;
uint32_t numNoops0 = 3;
uint32_t offsetLRI1 = offsetLRI0 + (1 + numRegsLRI0 * 2 + numNoops0) * sizeof(uint32_t); //offsetLRI == 0x21 * sizeof(uint32_t);
uint32_t numRegsLRI1 = 9;
uint32_t numNoops1 = 13;
uint32_t offsetLRI2 = offsetLRI1 + (1 + numRegsLRI1 * 2 + numNoops1) * sizeof(uint32_t); //offsetLR2 == 0x41 * sizeof(uint32_t);
uint32_t numRegsLRI2 = 1;
uint32_t offsetRingRegisters = offsetLRI0 + (3 * sizeof(uint32_t));
uint32_t offsetRingHead = 0x0 * sizeof(uint32_t);
uint32_t offsetRingTail = 0x2 * sizeof(uint32_t);
uint32_t offsetRingBase = 0x4 * sizeof(uint32_t);
uint32_t offsetRingCtrl = 0x6 * sizeof(uint32_t);
uint32_t offsetPageTableRegisters = offsetLRI1 + (3 * sizeof(uint32_t));
uint32_t offsetPDP0 = 0xc * sizeof(uint32_t);
uint32_t offsetPDP1 = 0x8 * sizeof(uint32_t);
uint32_t offsetPDP2 = 0x4 * sizeof(uint32_t);
uint32_t offsetPDP3 = 0x0 * sizeof(uint32_t);
void initialize(void *pLRCIn) const;
void setRingHead(void *pLRCIn, uint32_t ringHead) const;
void setRingTail(void *pLRCIn, uint32_t ringTail) const;
void setRingBase(void *pLRCIn, uint32_t ringBase) const;
void setRingCtrl(void *pLRCIn, uint32_t ringCtrl) const;
void setPDP0(void *pLRCIn, uint64_t address) const;
void setPDP1(void *pLRCIn, uint64_t address) const;
void setPDP2(void *pLRCIn, uint64_t address) const;
void setPDP3(void *pLRCIn, uint64_t address) const;
void setPML4(void *pLRCIn, uint64_t address) const;
MOCKABLE_VIRTUAL void setContextSaveRestoreFlags(uint32_t &value) const;
};
struct LrcaHelperRcs : public LrcaHelper {
LrcaHelperRcs(uint32_t base) : LrcaHelper(base) {
aubHintLRCA = DataTypeHintValues::TraceLogicalRingContextRcs;
aubHintCommandBuffer = DataTypeHintValues::TraceCommandBufferPrimary;
aubHintBatchBuffer = DataTypeHintValues::TraceBatchBufferPrimary;
sizeLRCA = 0x11000;
name = "RCS";
}
};
struct LrcaHelperBcs : public LrcaHelper {
LrcaHelperBcs(uint32_t base) : LrcaHelper(base) {
aubHintLRCA = DataTypeHintValues::TraceLogicalRingContextBcs;
aubHintCommandBuffer = DataTypeHintValues::TraceCommandBufferBlt;
aubHintBatchBuffer = DataTypeHintValues::TraceBatchBufferBlt;
name = "BCS";
}
};
struct LrcaHelperVcs : public LrcaHelper {
LrcaHelperVcs(uint32_t base) : LrcaHelper(base) {
aubHintLRCA = DataTypeHintValues::TraceLogicalRingContextVcs;
aubHintCommandBuffer = DataTypeHintValues::TraceCommandBufferMfx;
aubHintBatchBuffer = DataTypeHintValues::TraceBatchBufferMfx;
name = "VCS";
}
};
struct LrcaHelperVecs : public LrcaHelper {
LrcaHelperVecs(uint32_t base) : LrcaHelper(base) {
aubHintLRCA = DataTypeHintValues::TraceLogicalRingContextVecs;
name = "VECS";
}
};
struct LrcaHelperCcs : public LrcaHelper {
LrcaHelperCcs(uint32_t base) : LrcaHelper(base) {
aubHintLRCA = DataTypeHintValues::TraceLogicalRingContextCcs;
name = "CCS";
}
};
extern const uint64_t g_pageMask;
extern const size_t g_dwordCountMax;
} // namespace AubMemDump

View File

@@ -0,0 +1,363 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/aub/aub_helper.h"
#include "shared/source/helpers/constants.h"
#include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/ptr_math.h"
#include "aub_mem_dump.h"
#include <algorithm>
#include <cstring>
namespace AubMemDump {
template <typename Traits>
void AubPageTableHelper32<Traits>::fixupLRC(uint8_t *pLRC) {
uint32_t pdAddress;
pdAddress = BaseClass::getPDEAddress(0x600) >> 32;
*(uint32_t *)(pLRC + 0x1094) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0x600) & 0xffffffff;
*(uint32_t *)(pLRC + 0x109c) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0x400) >> 32;
*(uint32_t *)(pLRC + 0x10a4) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0x400) & 0xffffffff;
*(uint32_t *)(pLRC + 0x10ac) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0x200) >> 32;
*(uint32_t *)(pLRC + 0x10b4) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0x200) & 0xffffffff;
*(uint32_t *)(pLRC + 0x10bc) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0) >> 32;
*(uint32_t *)(pLRC + 0x10c4) = pdAddress;
pdAddress = BaseClass::getPDEAddress(0) & 0xffffffff;
*(uint32_t *)(pLRC + 0x10cc) = pdAddress;
}
template <typename Traits>
void AubPageTableHelper64<Traits>::fixupLRC(uint8_t *pLRC) {
uint32_t pml4Address = getPML4Address(0) >> 32;
*(uint32_t *)(pLRC + 0x10c4) = pml4Address;
pml4Address = getPML4Address(0) & 0xffffffff;
*(uint32_t *)(pLRC + 0x10cc) = pml4Address;
}
// Write a block of memory to a given address space using an optional hint
template <typename Traits>
void AubDump<Traits>::addMemoryWrite(typename Traits::Stream &stream, uint64_t addr, const void *memory, size_t sizeRemaining, int addressSpace, int hint) {
// We can only dump a relatively small amount per CmdServicesMemTraceMemoryWrite
auto sizeMemoryWriteHeader = sizeof(CmdServicesMemTraceMemoryWrite) - sizeof(CmdServicesMemTraceMemoryWrite::data);
auto blockSizeMax = g_dwordCountMax * sizeof(uint32_t) - sizeMemoryWriteHeader;
if (hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextRcs ||
hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextBcs ||
hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextVcs ||
hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextVecs) {
DEBUG_BREAK_IF(sizeRemaining <= 0x10cc);
uint8_t *pLRC = reinterpret_cast<uint8_t *>(const_cast<void *>(memory));
BaseHelper::fixupLRC(pLRC);
}
// loop to dump all of the blocks
while (sizeRemaining > 0) {
auto sizeThisIteration = std::min(blockSizeMax, sizeRemaining);
stream.writeMemory(addr, memory, sizeThisIteration, addressSpace, hint);
sizeRemaining -= sizeThisIteration;
memory = (uint8_t *)memory + sizeThisIteration;
addr += sizeThisIteration;
}
}
// Reserve memory in the GGTT.
template <typename Traits>
uint64_t AubDump<Traits>::reserveAddress(typename Traits::Stream &stream, uint32_t addr, size_t size, unsigned int addressSpace, uint64_t physStart, AubGTTData data) {
auto startPage = addr & g_pageMask;
auto endPage = (addr + size - 1) & g_pageMask;
auto numPages = (uint32_t)(((endPage - startPage) / 4096) + 1);
// Can only handle 16 bits of dwordCount.
DEBUG_BREAK_IF(!(numPages > 0 && (numPages + 4) < 65536));
auto gttTableOffset = static_cast<uint32_t>((((uint32_t)startPage) / 4096) * sizeof(MiGttEntry));
// Write header
{
typedef AubMemDump::CmdServicesMemTraceMemoryWrite CmdServicesMemTraceMemoryWrite;
stream.writeMemoryWriteHeader(gttTableOffset, numPages * sizeof(AubMemDump::MiGttEntry), addressSpace, CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceNotype);
}
uint64_t physAddress = physStart;
while (startPage <= endPage) {
MiGttEntry entry;
setGttEntry(entry, physAddress, data);
stream.writeGTT(gttTableOffset, entry.uiData);
gttTableOffset += sizeof(entry);
physAddress += 4096;
startPage += 4096;
}
return physStart;
}
template <typename Traits>
uint64_t AubDump<Traits>::reserveAddressGGTT(typename Traits::Stream &stream, uint32_t addr, size_t size, uint64_t physStart, AubGTTData data) {
return AubDump<Traits>::reserveAddress(stream, addr, size, AddressSpaceValues::TraceGttEntry, physStart, data);
}
template <typename Traits>
uint64_t AubDump<Traits>::reserveAddressGGTT(typename Traits::Stream &stream, const void *memory, size_t size, uint64_t physStart, AubGTTData data) {
auto gfxAddress = BaseHelper::ptrToGGTT(memory);
return AubDump<Traits>::reserveAddress(stream, gfxAddress, size, AddressSpaceValues::TraceGttEntry, physStart, data);
}
template <typename Traits>
void AubDump<Traits>::reserveAddressGGTTAndWriteMmeory(typename Traits::Stream &stream, uintptr_t gfxAddress,
const void *memory, uint64_t physAddress,
size_t size, size_t offset,
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
auto vmAddr = (gfxAddress + offset) & ~(MemoryConstants::pageSize - 1);
auto pAddr = physAddress & ~(MemoryConstants::pageSize - 1);
AubDump<Traits>::reserveAddressPPGTT(stream, vmAddr, MemoryConstants::pageSize, pAddr, additionalBits, aubHelper);
int hint = NEO::AubHelper::getMemTrace(additionalBits);
AubDump<Traits>::addMemoryWrite(stream, physAddress,
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(memory) + offset),
size, hint);
}
template <typename Traits>
void AubDump<Traits>::setGttEntry(MiGttEntry &entry, uint64_t address, AubGTTData data) {
entry.uiData = 0;
entry.pageConfig.PhysicalAddress = address / 4096;
entry.pageConfig.Present = data.present;
entry.pageConfig.LocalMemory = data.localMemory;
}
template <typename Traits>
uint64_t AubPageTableHelper32<Traits>::reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
size_t blockSize, uint64_t physAddress,
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
auto startAddress = gfxAddress;
auto endAddress = gfxAddress + blockSize - 1;
auto startPTE = startAddress >> 12;
auto endPTE = endAddress >> 12;
auto numPTEs = endPTE - startPTE + 1;
auto startPDE = startPTE >> 9;
auto endPDE = endPTE >> 9;
auto numPDEs = endPDE - startPDE + 1;
// Process the PD entries
bool writePDE = true;
if (writePDE) {
auto startAddress = BaseClass::getPDEAddress(startPDE);
auto addressSpace = aubHelper.getMemTraceForPdEntry();
auto hint = aubHelper.getDataHintForPdEntry();
stream.writeMemoryWriteHeader(startAddress, numPDEs * sizeof(uint64_t),
addressSpace, hint);
auto currPDE = startPDE;
auto physPage = BaseClass::getPTEAddress(startPTE) & g_pageMask;
while (currPDE <= endPDE) {
auto pde = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
stream.writePTE(startAddress, pde, addressSpace);
startAddress += sizeof(pde);
physPage += 4096;
currPDE++;
}
}
// Process the PT entries
bool writePTE = true;
if (writePTE) {
auto startAddress = BaseClass::getPTEAddress(startPTE);
auto addressSpace = aubHelper.getMemTraceForPtEntry();
auto hint = aubHelper.getDataHintForPtEntry();
stream.writeMemoryWriteHeader(startAddress, numPTEs * sizeof(uint64_t),
addressSpace, hint);
auto currPTE = startPTE;
auto physPage = physAddress & g_pageMask;
while (currPTE <= endPTE) {
auto pte = physPage | additionalBits;
stream.writePTE(startAddress, pte, addressSpace);
startAddress += sizeof(pte);
physPage += 4096;
currPTE++;
}
}
return physAddress;
}
template <typename Traits>
uint64_t AubPageTableHelper64<Traits>::reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
size_t blockSize, uint64_t physAddress,
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
auto startAddress = gfxAddress;
auto endAddress = gfxAddress + blockSize - 1;
auto startPTE = startAddress >> 12;
auto endPTE = endAddress >> 12;
auto numPTEs = endPTE - startPTE + 1;
auto startPDE = startPTE >> 9;
auto endPDE = endPTE >> 9;
auto numPDEs = endPDE - startPDE + 1;
auto startPDP = startPDE >> 9;
auto endPDP = endPDE >> 9;
auto numPDPs = endPDP - startPDP + 1;
auto startPML4 = startPDP >> 9;
auto endPML4 = endPDP >> 9;
auto numPML4s = endPML4 - startPML4 + 1;
// Process the PML4 entries
bool writePML4 = true;
if (writePML4) {
auto startAddress = getPML4Address(startPML4);
auto addressSpace = aubHelper.getMemTraceForPml4Entry();
auto hint = aubHelper.getDataHintForPml4Entry();
stream.writeMemoryWriteHeader(startAddress, numPML4s * sizeof(uint64_t),
addressSpace, hint);
auto currPML4 = startPML4;
auto physPage = BaseClass::getPDPAddress(startPDP) & g_pageMask;
while (currPML4 <= endPML4) {
auto pml4 = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
stream.writePTE(startAddress, pml4, addressSpace);
startAddress += sizeof(pml4);
physPage += 4096;
currPML4++;
}
}
// Process the PDP entries
bool writePDPE = true;
if (writePDPE) {
auto startAddress = BaseClass::getPDPAddress(startPDP);
auto addressSpace = aubHelper.getMemTraceForPdpEntry();
auto hint = aubHelper.getDataHintForPdpEntry();
stream.writeMemoryWriteHeader(startAddress, numPDPs * sizeof(uint64_t),
addressSpace, hint);
auto currPDP = startPDP;
auto physPage = BaseClass::getPDEAddress(startPDE) & g_pageMask;
while (currPDP <= endPDP) {
auto pdp = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
stream.writePTE(startAddress, pdp, addressSpace);
startAddress += sizeof(pdp);
physPage += 4096;
currPDP++;
}
}
// Process the PD entries
bool writePDE = true;
if (writePDE) {
auto startAddress = BaseClass::getPDEAddress(startPDE);
auto addressSpace = aubHelper.getMemTraceForPdEntry();
auto hint = aubHelper.getDataHintForPdEntry();
stream.writeMemoryWriteHeader(startAddress, numPDEs * sizeof(uint64_t),
addressSpace, hint);
auto currPDE = startPDE;
auto physPage = BaseClass::getPTEAddress(startPTE) & g_pageMask;
while (currPDE <= endPDE) {
auto pde = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
stream.writePTE(startAddress, pde, addressSpace);
startAddress += sizeof(pde);
physPage += 4096;
currPDE++;
}
}
// Process the PT entries
bool writePTE = true;
if (writePTE) {
auto startAddress = BaseClass::getPTEAddress(startPTE);
auto addressSpace = aubHelper.getMemTraceForPtEntry();
auto hint = aubHelper.getDataHintForPtEntry();
stream.writeMemoryWriteHeader(startAddress, numPTEs * sizeof(uint64_t),
addressSpace, hint);
auto currPTE = startPTE;
auto physPage = physAddress & g_pageMask;
while (currPTE <= endPTE) {
auto pte = physPage | additionalBits;
stream.writePTE(startAddress, pte, addressSpace);
startAddress += sizeof(pte);
physPage += 4096;
currPTE++;
}
}
return physAddress;
}
template <typename Traits>
void AubPageTableHelper32<Traits>::createContext(typename Traits::Stream &stream, uint32_t context) {
AubPpgttContextCreate cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.Header.Type = 0x7;
cmd.Header.Opcode = 0x1;
cmd.Header.SubOp = 0x14;
cmd.Header.DwordLength = ((sizeof(cmd) - sizeof(cmd.Header)) / sizeof(uint32_t)) - 1;
cmd.Handle = context;
cmd.AdvancedContext = false;
cmd.SixtyFourBit = 0;
cmd.PageDirPointer[0] = BaseClass::getPDEAddress(0x000);
cmd.PageDirPointer[1] = BaseClass::getPDEAddress(0x200);
cmd.PageDirPointer[2] = BaseClass::getPDEAddress(0x400);
cmd.PageDirPointer[3] = BaseClass::getPDEAddress(0x600);
stream.createContext(cmd);
}
template <typename Traits>
void AubPageTableHelper64<Traits>::createContext(typename Traits::Stream &stream, uint32_t context) {
AubPpgttContextCreate cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.Header.Type = 0x7;
cmd.Header.Opcode = 0x1;
cmd.Header.SubOp = 0x14;
cmd.Header.DwordLength = ((sizeof(cmd) - sizeof(cmd.Header)) / sizeof(uint32_t)) - 1;
cmd.Handle = context;
cmd.AdvancedContext = false;
cmd.SixtyFourBit = 1;
cmd.PageDirPointer[0] = getPML4Address(0);
stream.createContext(cmd);
}
} // namespace AubMemDump

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "third_party/aub_stream/headers/aub_manager.h"
#include "third_party/aub_stream/headers/aubstream.h"
namespace aub_stream_stubs {
uint16_t tbxServerPort = 4321;
std::string tbxServerIp = "127.0.0.1";
bool tbxFrontdoorMode = false;
} // namespace aub_stream_stubs
namespace aub_stream {
AubManager *AubManager::create(uint32_t productFamily, uint32_t devicesCount, uint64_t memoryBankSizeInGB, uint32_t stepping, bool localMemorySupported, uint32_t streamMode, uint64_t gpuAddressSpace) {
return nullptr;
}
extern "C" {
void injectMMIOList(MMIOList mmioList){};
void setTbxServerPort(uint16_t port) { aub_stream_stubs::tbxServerPort = port; };
void setTbxServerIp(std::string server) {
// better to avoid reassigning global variables which assume memory allocations since
// we could step into false-positive memory leak detection with embedded leak check helper
if (aub_stream_stubs::tbxServerIp != server)
aub_stream_stubs::tbxServerIp = server;
};
void setTbxFrontdoorMode(bool frontdoor) { aub_stream_stubs::tbxFrontdoorMode = frontdoor; }
}
} // namespace aub_stream

View File

@@ -0,0 +1,13 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/aub_mem_dump/aub_mem_dump.h"
namespace AubMemDump {
void LrcaHelper::setContextSaveRestoreFlags(uint32_t &ctxSrCtlValue) const {
}
} // namespace AubMemDump

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
#include <limits>
namespace PageTableEntry {
const uint32_t presentBit = 0;
const uint32_t writableBit = 1;
const uint32_t userSupervisorBit = 2;
const uint32_t localMemoryBit = 11;
const uint64_t nonValidBits = std::numeric_limits<uint64_t>::max();
} // namespace PageTableEntry