2017-12-21 00:45:38 +01:00
|
|
|
/*
|
2021-05-16 20:51:16 +02:00
|
|
|
* Copyright (C) 2018-2021 Intel Corporation
|
2017-12-21 00:45:38 +01:00
|
|
|
*
|
2018-09-18 09:11:08 +02:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 00:45:38 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-10-16 12:10:52 +02:00
|
|
|
#include "shared/source/aub/aub_helper.h"
|
2021-12-07 11:22:25 +00:00
|
|
|
#include "shared/source/aub_mem_dump/aub_mem_dump.h"
|
2020-04-02 11:28:38 +02:00
|
|
|
#include "shared/source/helpers/constants.h"
|
2020-02-23 22:44:01 +01:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
2020-02-24 10:22:30 +01:00
|
|
|
|
2017-12-21 00:45:38 +01:00
|
|
|
#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 ||
|
2021-03-18 12:41:04 +01:00
|
|
|
hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextVecs ||
|
|
|
|
hint == CmdServicesMemTraceMemoryWrite::DataTypeHintValues::TraceLogicalRingContextCcs) {
|
2017-12-21 00:45:38 +01:00
|
|
|
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>
|
2018-05-09 15:25:01 +02:00
|
|
|
uint64_t AubDump<Traits>::reserveAddress(typename Traits::Stream &stream, uint32_t addr, size_t size, unsigned int addressSpace, uint64_t physStart, AubGTTData data) {
|
2017-12-21 00:45:38 +01:00
|
|
|
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;
|
2018-05-09 15:25:01 +02:00
|
|
|
setGttEntry(entry, physAddress, data);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
stream.writeGTT(gttTableOffset, entry.uiData);
|
|
|
|
gttTableOffset += sizeof(entry);
|
|
|
|
|
|
|
|
physAddress += 4096;
|
|
|
|
startPage += 4096;
|
|
|
|
}
|
|
|
|
|
|
|
|
return physStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-05-09 15:25:01 +02:00
|
|
|
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);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-05-09 15:25:01 +02:00
|
|
|
uint64_t AubDump<Traits>::reserveAddressGGTT(typename Traits::Stream &stream, const void *memory, size_t size, uint64_t physStart, AubGTTData data) {
|
2017-12-21 00:45:38 +01:00
|
|
|
auto gfxAddress = BaseHelper::ptrToGGTT(memory);
|
2018-05-09 15:25:01 +02:00
|
|
|
return AubDump<Traits>::reserveAddress(stream, gfxAddress, size, AddressSpaceValues::TraceGttEntry, physStart, data);
|
2018-03-05 22:16:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-09-14 05:31:37 -07:00
|
|
|
void AubDump<Traits>::reserveAddressGGTTAndWriteMmeory(typename Traits::Stream &stream, uintptr_t gfxAddress,
|
|
|
|
const void *memory, uint64_t physAddress,
|
2019-02-19 09:20:43 +01:00
|
|
|
size_t size, size_t offset,
|
2019-03-26 11:59:46 +01:00
|
|
|
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
|
2018-03-05 22:16:21 +01:00
|
|
|
auto vmAddr = (gfxAddress + offset) & ~(MemoryConstants::pageSize - 1);
|
|
|
|
auto pAddr = physAddress & ~(MemoryConstants::pageSize - 1);
|
|
|
|
|
2019-02-19 09:20:43 +01:00
|
|
|
AubDump<Traits>::reserveAddressPPGTT(stream, vmAddr, MemoryConstants::pageSize, pAddr, additionalBits, aubHelper);
|
2018-03-05 22:16:21 +01:00
|
|
|
|
2019-03-26 11:59:46 +01:00
|
|
|
int hint = NEO::AubHelper::getMemTrace(additionalBits);
|
2018-08-20 15:54:20 +02:00
|
|
|
|
2018-03-05 22:16:21 +01:00
|
|
|
AubDump<Traits>::addMemoryWrite(stream, physAddress,
|
|
|
|
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(memory) + offset),
|
2018-08-20 15:54:20 +02:00
|
|
|
size, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-06-21 14:54:59 +02:00
|
|
|
void AubDump<Traits>::setGttEntry(MiGttEntry &entry, uint64_t address, AubGTTData data) {
|
2018-05-09 15:25:01 +02:00
|
|
|
entry.uiData = 0;
|
|
|
|
entry.pageConfig.PhysicalAddress = address / 4096;
|
|
|
|
entry.pageConfig.Present = data.present;
|
2018-06-21 14:54:59 +02:00
|
|
|
entry.pageConfig.LocalMemory = data.localMemory;
|
2018-05-09 15:25:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-09-14 05:31:37 -07:00
|
|
|
uint64_t AubPageTableHelper32<Traits>::reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
|
|
|
|
size_t blockSize, uint64_t physAddress,
|
2019-03-26 11:59:46 +01:00
|
|
|
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
|
2017-12-21 00:45:38 +01:00
|
|
|
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) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = BaseClass::getPDEAddress(startPDE);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPdEntry();
|
|
|
|
auto hint = aubHelper.getDataHintForPdEntry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPDEs * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPDE = startPDE;
|
|
|
|
auto physPage = BaseClass::getPTEAddress(startPTE) & g_pageMask;
|
|
|
|
while (currPDE <= endPDE) {
|
2019-03-26 11:59:46 +01:00
|
|
|
auto pde = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pde, addressSpace);
|
|
|
|
startAddress += sizeof(pde);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
physPage += 4096;
|
|
|
|
currPDE++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the PT entries
|
|
|
|
bool writePTE = true;
|
|
|
|
if (writePTE) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = BaseClass::getPTEAddress(startPTE);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPtEntry();
|
|
|
|
auto hint = aubHelper.getDataHintForPtEntry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPTEs * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPTE = startPTE;
|
|
|
|
auto physPage = physAddress & g_pageMask;
|
|
|
|
while (currPTE <= endPTE) {
|
2018-05-09 15:25:01 +02:00
|
|
|
auto pte = physPage | additionalBits;
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pte, addressSpace);
|
|
|
|
startAddress += sizeof(pte);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
physPage += 4096;
|
|
|
|
currPTE++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return physAddress;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Traits>
|
2018-09-14 05:31:37 -07:00
|
|
|
uint64_t AubPageTableHelper64<Traits>::reserveAddressPPGTT(typename Traits::Stream &stream, uintptr_t gfxAddress,
|
|
|
|
size_t blockSize, uint64_t physAddress,
|
2019-03-26 11:59:46 +01:00
|
|
|
uint64_t additionalBits, const NEO::AubHelper &aubHelper) {
|
2017-12-21 00:45:38 +01:00
|
|
|
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) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = getPML4Address(startPML4);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPml4Entry();
|
|
|
|
auto hint = aubHelper.getDataHintForPml4Entry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPML4s * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPML4 = startPML4;
|
|
|
|
auto physPage = BaseClass::getPDPAddress(startPDP) & g_pageMask;
|
|
|
|
while (currPML4 <= endPML4) {
|
2019-03-26 11:59:46 +01:00
|
|
|
auto pml4 = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pml4, addressSpace);
|
|
|
|
startAddress += sizeof(pml4);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
physPage += 4096;
|
|
|
|
currPML4++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the PDP entries
|
|
|
|
bool writePDPE = true;
|
|
|
|
if (writePDPE) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = BaseClass::getPDPAddress(startPDP);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPdpEntry();
|
|
|
|
auto hint = aubHelper.getDataHintForPdpEntry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPDPs * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPDP = startPDP;
|
|
|
|
auto physPage = BaseClass::getPDEAddress(startPDE) & g_pageMask;
|
|
|
|
while (currPDP <= endPDP) {
|
2019-03-26 11:59:46 +01:00
|
|
|
auto pdp = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pdp, addressSpace);
|
|
|
|
startAddress += sizeof(pdp);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
physPage += 4096;
|
|
|
|
currPDP++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the PD entries
|
|
|
|
bool writePDE = true;
|
|
|
|
if (writePDE) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = BaseClass::getPDEAddress(startPDE);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPdEntry();
|
|
|
|
auto hint = aubHelper.getDataHintForPdEntry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPDEs * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPDE = startPDE;
|
|
|
|
auto physPage = BaseClass::getPTEAddress(startPTE) & g_pageMask;
|
|
|
|
while (currPDE <= endPDE) {
|
2019-03-26 11:59:46 +01:00
|
|
|
auto pde = physPage | NEO::AubHelper::getPTEntryBits(additionalBits);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pde, addressSpace);
|
|
|
|
startAddress += sizeof(pde);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
physPage += 4096;
|
|
|
|
currPDE++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process the PT entries
|
|
|
|
bool writePTE = true;
|
|
|
|
if (writePTE) {
|
2018-11-09 23:00:58 -08:00
|
|
|
auto startAddress = BaseClass::getPTEAddress(startPTE);
|
|
|
|
auto addressSpace = aubHelper.getMemTraceForPtEntry();
|
|
|
|
auto hint = aubHelper.getDataHintForPtEntry();
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writeMemoryWriteHeader(startAddress, numPTEs * sizeof(uint64_t),
|
|
|
|
addressSpace, hint);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
auto currPTE = startPTE;
|
|
|
|
auto physPage = physAddress & g_pageMask;
|
|
|
|
while (currPTE <= endPTE) {
|
2018-05-09 15:25:01 +02:00
|
|
|
auto pte = physPage | additionalBits;
|
2017-12-21 00:45:38 +01:00
|
|
|
|
2018-11-09 23:00:58 -08:00
|
|
|
stream.writePTE(startAddress, pte, addressSpace);
|
|
|
|
startAddress += sizeof(pte);
|
2017-12-21 00:45:38 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-05-09 15:25:01 +02:00
|
|
|
} // namespace AubMemDump
|