Skip to content

Commit

Permalink
Fix VCN (at least partially) (#35)
Browse files Browse the repository at this point in the history
* Patch VAAcceleratorInfo::identify to return Navi10

Signed-off-by: Visual <[email protected]>

* Patch offsets in Vcn2DecCommand

Signed-off-by: Visual <[email protected]>

* Fix commands in Vcn2EncCommand

Signed-off-by: Visual <[email protected]>

* Remove Input/Output format cmds in Vcn2EncAvcCommand

Signed-off-by: Visual <[email protected]>

* Clean up findAndReplace calls

Signed-off-by: Visual <[email protected]>

* Patch VAFactory::createGraphicsEngine

Signed-off-by: Visual <[email protected]>

* Patch VAFactory::create*VP

Signed-off-by: Visual <[email protected]>

* Patch VAFactory::createImageBlt

Signed-off-by: Visual <[email protected]>

---------

Signed-off-by: Visual <[email protected]>
  • Loading branch information
VisualEhrmanntraut authored Apr 14, 2023
1 parent 3dc0c1c commit 2eb093a
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
74 changes: 74 additions & 0 deletions NootedRed/kern_nred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,80 @@ void NRed::csValidatePage(vnode *vp, memory_object_t pager, memory_object_offset
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, kBoardIdOriginal,
arrsize(kBoardIdOriginal), kBoardIdPatched, arrsize(kBoardIdPatched))))
DBGLOG("nred", "Patched 'board-id' -> 'hwgva-id'");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kVAAcceleratorInfoIdentifyOriginal, kVAAcceleratorInfoIdentifyPatched)))
DBGLOG("nred", "Patched VAAcceleratorInfo::identify");

if (UNLIKELY(KernelPatcher::findAndReplaceWithMask(const_cast<void *>(data), PAGE_SIZE,
kVAFactoryCreateGraphicsEngineOriginal, arrsize(kVAFactoryCreateGraphicsEngineOriginal),
kVAFactoryCreateGraphicsEngineMask, arrsize(kVAFactoryCreateGraphicsEngineMask),
kVAFactoryCreateGraphicsEnginePatched, arrsize(kVAFactoryCreateGraphicsEnginePatched), nullptr, 0,
1, 0)))
DBGLOG("nred", "Patched VAFactory::createGraphicsEngine");

if (UNLIKELY(KernelPatcher::findAndReplaceWithMask(const_cast<void *>(data), PAGE_SIZE,
kVAFactoryCreateVPOriginal, arrsize(kVAFactoryCreateVPOriginal), kVAFactoryCreateVPMask,
arrsize(kVAFactoryCreateVPMask), kVAFactoryCreateVPPatched, arrsize(kVAFactoryCreateVPPatched),
nullptr, 0, 0, 0)))
DBGLOG("nred", "Patched VAFactory::create*VP");

if (UNLIKELY(KernelPatcher::findAndReplaceWithMask(const_cast<void *>(data), PAGE_SIZE,
kVAFactoryCreateImageBltOriginal, arrsize(kVAFactoryCreateImageBltOriginal),
kVAFactoryCreateImageBltMask, arrsize(kVAFactoryCreateImageBltMask),
kVAFactoryCreateImageBltPatched, arrsize(kVAFactoryCreateImageBltPatched), nullptr, 0, 1, 0)))
DBGLOG("nred", "Patched VAFactory::createImageBlt");

if (callback->chipType < ChipType::Renoir) {
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, kWriteUvdNoOpOriginal,
kWriteUvdNoOpPatched)))
DBGLOG("nred", "Patched writeUvdNoOp");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kWriteUvdEngineStartOriginal, kWriteUvdEngineStartPatched)))
DBGLOG("nred", "Patched writeUvdEngineStart");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kWriteUvdGpcomVcpuCmdOriginal, kWriteUvdGpcomVcpuCmdPatched)))
DBGLOG("nred", "Patched writeUvdGpcomVcpuCmdOriginal");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kWriteUvdGpcomVcpuData0Original, kWriteUvdGpcomVcpuData0Patched)))
DBGLOG("nred", "Patched writeUvdGpcomVcpuData0Original");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kWriteUvdGpcomVcpuData1Original, kWriteUvdGpcomVcpuData1Patched)))
DBGLOG("nred", "Patched writeUvdGpcomVcpuData1Original");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddEncodePacketOriginal, kAddEncodePacketPatched)))
DBGLOG("nred", "Patched addEncodePacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddSliceHeaderPacketOriginal, kAddSliceHeaderPacketPatched)))
DBGLOG("nred", "Patched addSliceHeaderPacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddIntraRefreshPacketOriginal, kAddIntraRefreshPacketPatched)))
DBGLOG("nred", "Patched addIntraRefreshPacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddContextBufferPacketOriginal, kAddContextBufferPacketPatched)))
DBGLOG("nred", "Patched addContextBufferPacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddBitstreamBufferPacketOriginal, kAddBitstreamBufferPacketPatched)))
DBGLOG("nred", "Patched addBitstreamBufferPacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kAddFeedbackBufferPacketOriginal, kAddFeedbackBufferPacketPatched)))
DBGLOG("nred", "Patched addFeedbackBufferPacket");

if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE,
kBuildGeneralCommandOriginal, arrsize(kBuildGeneralCommandOriginal),
kBuildGeneralCommandPatched, arrsize(kBuildGeneralCommandPatched))))
DBGLOG("nred", "Patched buildGeneralCommand");
}
} else if (UNLIKELY(!strncmp(path, kCoreLSKDMSEPath, arrsize(kCoreLSKDMSEPath))) ||
UNLIKELY(!strncmp(path, kCoreLSKDPath, arrsize(kCoreLSKDPath)))) {
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, kCoreLSKDOriginal,
Expand Down
104 changes: 104 additions & 0 deletions NootedRed/kern_patches.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,91 @@ static const uint8_t kChannelTypesOriginal[] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x
static const uint8_t kCailAsicCapsTableOriginal[] = {0x98, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};

/**
* `VAAcceleratorInfo::identify`
* AMDRadeonVADriver2.bundle
* The device info identification fails, as the device id is not present in the function.
* Patch fallback "error" value (0x12) to Navi 10 (0xC).
*/
static const uint8_t kVAAcceleratorInfoIdentifyOriginal[] = {0xBB, 0x12, 0x00, 0x00, 0x00, 0x89, 0xD8, 0x48, 0x83, 0xC4,
0x08};
static const uint8_t kVAAcceleratorInfoIdentifyPatched[] = {0xBB, 0xC, 0x00, 0x00, 0x00, 0x89, 0xD8, 0x48, 0x83, 0xC4,
0x08};

/** `Vcn2DecCommand::writeUvdNoOp` */
static const uint8_t kWriteUvdNoOpOriginal[] = {0xBE, 0x3F, 0x05, 0x00, 0x00, 0xFF, 0x50, 0x20};
static const uint8_t kWriteUvdNoOpPatched[] = {0xBE, 0xFF, 0x81, 0x00, 0x00, 0xFF, 0x50, 0x20};

/** `Vcn2DecCommand::writeUvdEngineStart` */
static const uint8_t kWriteUvdEngineStartOriginal[] = {0xBE, 0x06, 0x05, 0x00, 0x00, 0xFF, 0x50, 0x20};
static const uint8_t kWriteUvdEngineStartPatched[] = {0xBE, 0xC6, 0x81, 0x00, 0x00, 0xFF, 0x50, 0x20};

/** `Vcn2DecCommand::writeUvdGpcomVcpuCmd` */
static const uint8_t kWriteUvdGpcomVcpuCmdOriginal[] = {0xBE, 0x03, 0x05, 0x00, 0x00, 0xFF, 0x50, 0x20};
static const uint8_t kWriteUvdGpcomVcpuCmdPatched[] = {0xBE, 0xC3, 0x81, 0x00, 0x00, 0xFF, 0x50, 0x20};

/** `Vcn2DecCommand::writeUvdGpcomVcpuData0` */
static const uint8_t kWriteUvdGpcomVcpuData0Original[] = {0xBE, 0x04, 0x05, 0x00, 0x00, 0xFF, 0x50, 0x20};
static const uint8_t kWriteUvdGpcomVcpuData0Patched[] = {0xBE, 0xC4, 0x81, 0x00, 0x00, 0xFF, 0x50, 0x20};

/** `Vcn2DecCommand::writeUvdGpcomVcpuData1` */
static const uint8_t kWriteUvdGpcomVcpuData1Original[] = {0xBE, 0x05, 0x05, 0x00, 0x00, 0xFF, 0x50, 0x20};
static const uint8_t kWriteUvdGpcomVcpuData1Patched[] = {0xBE, 0xC5, 0x81, 0x00, 0x00, 0xFF, 0x50, 0x20};

/** `Vcn2EncCommand::addEncodePacket` */
static const uint8_t kAddEncodePacketOriginal[] = {0xBE, 0x0F, 0x00, 0x00, 0x00, 0xBA, 0x2C, 0x00, 0x00, 0x00};
static const uint8_t kAddEncodePacketPatched[] = {0xBE, 0x0B, 0x00, 0x00, 0x00, 0xBA, 0x2C, 0x00, 0x00, 0x00};

/** `Vcn2EncCommand::addSliceHeaderPacket` */
static const uint8_t kAddSliceHeaderPacketOriginal[] = {0xBE, 0x0B, 0x00, 0x00, 0x00, 0xBA, 0xC0, 0x00, 0x00, 0x00};
static const uint8_t kAddSliceHeaderPacketPatched[] = {0xBE, 0x0A, 0x00, 0x00, 0x00, 0xBA, 0xC0, 0x00, 0x00, 0x00};

/** `Vcn2EncCommand::addIntraRefreshPacket` */
static const uint8_t kAddIntraRefreshPacketOriginal[] = {0xBE, 0x10, 0x00, 0x00, 0x00, 0xBA, 0x0C, 0x00, 0x00, 0x00};
static const uint8_t kAddIntraRefreshPacketPatched[] = {0xBE, 0x0C, 0x00, 0x00, 0x00, 0xBA, 0x0C, 0x00, 0x00, 0x00};

/** `Vcn2EncCommand::addContextBufferPacket` */
static const uint8_t kAddContextBufferPacketOriginal[] = {0xBE, 0x11, 0x00, 0x00, 0x00, 0xBA, 0x58, 0x02, 0x00, 0x00};
static const uint8_t kAddContextBufferPacketPatched[] = {0xBE, 0x0D, 0x00, 0x00, 0x00, 0xBA, 0x58, 0x02, 0x00, 0x00};

/** `Vcn2EncCommand::addBitstreamBufferPacket` */
static const uint8_t kAddBitstreamBufferPacketOriginal[] = {0xBE, 0x12, 0x00, 0x00, 0x00, 0xBA, 0x14, 0x00, 0x00, 0x00};
static const uint8_t kAddBitstreamBufferPacketPatched[] = {0xBE, 0x0E, 0x00, 0x00, 0x00, 0xBA, 0x14, 0x00, 0x00, 0x00};

/** `Vcn2EncCommand::addFeedbackBufferPacket` */
static const uint8_t kAddFeedbackBufferPacketOriginal[] = {0xBE, 0x15, 0x00, 0x00, 0x00, 0xBA, 0x14, 0x00, 0x00, 0x00};
static const uint8_t kAddFeedbackBufferPacketPatched[] = {0xBE, 0x10, 0x00, 0x00, 0x00, 0xBA, 0x14, 0x00, 0x00, 0x00};

/** `Vcn2EncAvcCommand::buildGeneralCommand` */
static const uint8_t kBuildGeneralCommandOriginal[] = {0x41, 0x01, 0xC4, 0x41, 0x80, 0x7F, 0x14, 0x00, 0x74, 0x0B, 0x4C,
0x89, 0xF7};
static const uint8_t kBuildGeneralCommandPatched[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90};

/** `VAFactory::createGraphicsEngine` */
static const uint8_t kVAFactoryCreateGraphicsEngineOriginal[] = {0x48, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0x8B, 0x40,
0x0C, 0x83, 0xF8, 0x07, 0x77, 0x00};
static const uint8_t kVAFactoryCreateGraphicsEngineMask[] = {0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00};
static const uint8_t kVAFactoryCreateGraphicsEnginePatched[] = {0x48, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00};

/** `VAFactory::create*VP` */
static const uint8_t kVAFactoryCreateVPOriginal[] = {0x83, 0xFE, 0x07, 0x77, 0x00, 0x89, 0xF0, 0x48, 0x8D, 0x0D, 0x00,
0x00, 0x00, 0x00};
static const uint8_t kVAFactoryCreateVPMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00};
static const uint8_t kVAFactoryCreateVPPatched[] = {0xBE, 0x04, 0x00, 0x00, 0x00};

/** `VAFactory::createImageBlt` */
static const uint8_t kVAFactoryCreateImageBltOriginal[] = {0x48, 0x89, 0xF7, 0x48, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00,
0x8B, 0x40, 0x0C, 0x48, 0x83, 0xF8, 0x07, 0x77, 0x00, 0x48, 0x8D, 0x0D, 0x00, 0x00, 0x00, 0x00};
static const uint8_t kVAFactoryCreateImageBltMask[] = {0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
static const uint8_t kVAFactoryCreateImageBltPatched[] = {0x48, 0x89, 0xF7, 0x48, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00};

static_assert(arrsize(kAGDPFBCountCheckOriginal) == arrsize(kAGDPFBCountCheckPatched));
static_assert(arrsize(kAGDPBoardIDKeyOriginal) == arrsize(kAGDPBoardIDKeyPatched));
static_assert(arrsize(kFullAsicResetOriginal) == arrsize(kFullAsicResetPatched));
Expand All @@ -129,5 +214,24 @@ static_assert(arrsize(kEnableTimestampInterruptOriginal) == arrsize(kEnableTimes
static_assert(arrsize(kGetSchedulerCallOriginal) == arrsize(kGetSchedulerCallPatched));
static_assert(arrsize(kIsDeviceValidCallOriginal) == arrsize(kIsDeviceValidCallPatched));
static_assert(arrsize(kCoreLSKDOriginal) == arrsize(kCoreLSKDPatched));
static_assert(arrsize(kVAAcceleratorInfoIdentifyOriginal) == arrsize(kVAAcceleratorInfoIdentifyPatched));
static_assert(arrsize(kWriteUvdNoOpOriginal) == arrsize(kWriteUvdNoOpPatched));
static_assert(arrsize(kWriteUvdEngineStartOriginal) == arrsize(kWriteUvdEngineStartPatched));
static_assert(arrsize(kWriteUvdGpcomVcpuCmdOriginal) == arrsize(kWriteUvdGpcomVcpuCmdPatched));
static_assert(arrsize(kWriteUvdGpcomVcpuData0Original) == arrsize(kWriteUvdGpcomVcpuData0Patched));
static_assert(arrsize(kWriteUvdGpcomVcpuData1Original) == arrsize(kWriteUvdGpcomVcpuData1Patched));
static_assert(arrsize(kAddEncodePacketOriginal) == arrsize(kAddEncodePacketPatched));
static_assert(arrsize(kAddSliceHeaderPacketOriginal) == arrsize(kAddSliceHeaderPacketPatched));
static_assert(arrsize(kAddIntraRefreshPacketOriginal) == arrsize(kAddIntraRefreshPacketPatched));
static_assert(arrsize(kAddContextBufferPacketOriginal) == arrsize(kAddContextBufferPacketPatched));
static_assert(arrsize(kAddBitstreamBufferPacketOriginal) == arrsize(kAddBitstreamBufferPacketPatched));
static_assert(arrsize(kAddFeedbackBufferPacketOriginal) == arrsize(kAddFeedbackBufferPacketPatched));
static_assert(arrsize(kBuildGeneralCommandOriginal) < arrsize(kBuildGeneralCommandPatched));
static_assert(arrsize(kVAFactoryCreateGraphicsEngineOriginal) == arrsize(kVAFactoryCreateGraphicsEngineMask));
static_assert(arrsize(kVAFactoryCreateGraphicsEngineOriginal) > arrsize(kVAFactoryCreateGraphicsEnginePatched));
static_assert(arrsize(kVAFactoryCreateVPOriginal) == arrsize(kVAFactoryCreateVPMask));
static_assert(arrsize(kVAFactoryCreateVPOriginal) > arrsize(kVAFactoryCreateVPPatched));
static_assert(arrsize(kVAFactoryCreateImageBltOriginal) == arrsize(kVAFactoryCreateImageBltMask));
static_assert(arrsize(kVAFactoryCreateImageBltOriginal) > arrsize(kVAFactoryCreateImageBltPatched));

#endif /* kern_patches_hpp */

0 comments on commit 2eb093a

Please sign in to comment.