Skip to content

Commit

Permalink
feat: Port debug log patches from NootedRed
Browse files Browse the repository at this point in the history
  • Loading branch information
VisualEhrmanntraut committed Oct 21, 2024
1 parent fdb9040 commit cfaaff1
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 32 deletions.
11 changes: 11 additions & 0 deletions NootRX/AMDCommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ enum AMDUCodeID : UInt32 {
kUCodeVCN1 = 0x2A,
};

struct CosReadConfigurationSettingInput {
const char *settingName;
uint32_t settingType;
uint32_t outLen;
void *outPtr;
};

struct CosReadConfigurationSettingOutput {
uint32_t settingLen;
};

//-------- AMD Catalyst Constants --------//

constexpr UInt64 DEVICE_CAP_ENTRY_REV_DONT_CARE = 0xDEADCAFEU;
Expand Down
45 changes: 45 additions & 0 deletions NootRX/HWLibs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ bool HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sl
PANIC_COND(!request.route(patcher, id, slide, size), "HWLibs", "Failed to route psp_cmd_km_submit");
}

if (ADDPR(debugEnabled)) {
RouteRequestPlus request = {"__ZN14AmdTtlServices27cosReadConfigurationSettingEPvP36cos_read_configuration_"
"setting_inputP37cos_read_configuration_setting_output",
wrapCosReadConfigurationSetting, this->orgCosReadConfigurationSetting,
kCosReadConfigurationSettingPattern, kCosReadConfigurationSettingPatternMask};
PANIC_COND(!request.route(patcher, id, slide, size), "HWLibs",
"Failed to route cosReadConfigurationSetting");
}

if (NootRXMain::callback->attributes.isNavi22()) {
if (NootRXMain::callback->attributes.isSonoma1404AndLater()) {
RouteRequestPlus request = {"_smu_11_0_7_send_message_with_parameter",
Expand Down Expand Up @@ -294,6 +303,18 @@ bool HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sl
}
}
}

if (ADDPR(debugEnabled)) {
auto *targetKext =
NootRXMain::callback->attributes.isNavi21() ? &kextRadeonX6800HWLibs : &kextRadeonX6810HWLibs;
const LookupPatchPlus patches[] = {
{targetKext, kAtiPowerPlayServicesConstructorOriginal, kAtiPowerPlayServicesConstructorPatched, 1},
{targetKext, kAmdLogPspOriginal, kAmdLogPspOriginalMask, kAmdLogPspPatched, 1},
};
PANIC_COND(!LookupPatchPlus::applyAll(patcher, patches, slide, size), "HWLibs",
"Failed to apply debug enablement patches");
}

return true;
}

Expand Down Expand Up @@ -462,3 +483,27 @@ CAILResult HWLibs::wrapSmu1107SendMessageWithParameter(void *smum, UInt32 msgId,
return FunctionCast(wrapSmu1107SendMessageWithParameter, callback->orgSmu1107SendMessageWithParameter)(smum, msgId,
param);
}

CAILResult HWLibs::wrapCosReadConfigurationSetting(void *cosHandle, CosReadConfigurationSettingInput *readCfgInput,
CosReadConfigurationSettingOutput *readCfgOutput) {
if (readCfgInput != nullptr && readCfgInput->settingName != nullptr && readCfgInput->outPtr != nullptr &&
readCfgInput->outLen == 4) {
if (strncmp(readCfgInput->settingName, "PP_LogLevel", 12) == 0 ||
strncmp(readCfgInput->settingName, "PP_LogSource", 13) == 0 ||
strncmp(readCfgInput->settingName, "PP_LogDestination", 18) == 0 ||
strncmp(readCfgInput->settingName, "PP_LogField", 12) == 0) {
*static_cast<UInt32 *>(readCfgInput->outPtr) = 0xFFFFFFFF;
if (readCfgOutput != nullptr) { readCfgOutput->settingLen = 4; }
return kCAILResultSuccess;
}
if (strncmp(readCfgInput->settingName, "PP_DumpRegister", 16) == 0 ||
strncmp(readCfgInput->settingName, "PP_DumpSMCTable", 16) == 0 ||
strncmp(readCfgInput->settingName, "PP_LogDumpTableBuffers", 23) == 0) {
*static_cast<UInt32 *>(readCfgInput->outPtr) = 1;
if (readCfgOutput != nullptr) { readCfgOutput->settingLen = 4; }
return kCAILResultSuccess;
}
}
return FunctionCast(wrapCosReadConfigurationSetting, callback->orgCosReadConfigurationSetting)(cosHandle,
readCfgInput, readCfgOutput);
}
23 changes: 23 additions & 0 deletions NootRX/HWLibs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ class HWLibs {

mach_vm_address_t orgPspCmdKmSubmit {0};
mach_vm_address_t orgSmu1107SendMessageWithParameter {0};
mach_vm_address_t orgCosReadConfigurationSetting {0};

static const char *wrapGetMatchProperty(void);
static CAILResult wrapPspCmdKmSubmit(void *ctx, void *cmd, void *outData, void *outResponse);
static CAILResult wrapSmu1107SendMessageWithParameter(void *smum, UInt32 msgId, UInt32 param);
static CAILResult wrapCosReadConfigurationSetting(void *cosHandle, CosReadConfigurationSettingInput *readCfgInput,
CosReadConfigurationSettingOutput *readCfgOutput);
};

//------ Patterns ------//
Expand Down Expand Up @@ -67,6 +70,11 @@ static const UInt8 kSmu1107SendMessageWithParameterPattern14_4[] = {0x55, 0x48,
static const UInt8 kSmu1107SendMessageWithParameterPatternMask14_4[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF};

static const UInt8 kCosReadConfigurationSettingPattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x54,
0x53, 0x48, 0x85, 0xF6, 0x74, 0x00, 0x40, 0x89, 0xD0};
static const UInt8 kCosReadConfigurationSettingPatternMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0xFF, 0xF0};

//------ Patches ------//

// Replace call in `_gc_sw_init` to `_gc_get_hw_version` with constant (0x0A0304).
Expand Down Expand Up @@ -136,3 +144,18 @@ static const UInt8 kSdmaInitFunctionPointerOriginal14_4[] = {0xB8, 0x02, 0x00, 0
static const UInt8 kSdmaInitFunctionPointerOriginalMask14_4[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00};
static const UInt8 kSdmaInitFunctionPointerPatched14_4[] = {0xB8, 0x02, 0x00, 0x00, 0x00, 0x66, 0x90, 0x66, 0x90, 0x90};

// Enable all MCIL debug prints (debugLevel = 0xFFFFFFFF, mostly for PP_Log).
static const UInt8 kAtiPowerPlayServicesConstructorOriginal[] = {0x8B, 0x40, 0x60, 0x48, 0x8D};
static const UInt8 kAtiPowerPlayServicesConstructorPatched[] = {0x83, 0xC8, 0xFF, 0x48, 0x8D};

// Enable printing of all PSP event logs
static const UInt8 kAmdLogPspOriginal[] = {0x83, 0x00, 0x02, 0x0F, 0x85, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x83, 0x00, 0x02, 0x72, 0x00, 0x41, 0x00, 0x00, 0x09, 0x02, 0x18, 0x00, 0x74, 0x00, 0x41, 0x00,
0x00, 0x01, 0x06, 0x10, 0x00, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00};
static const UInt8 kAmdLogPspOriginalMask[] = {0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
static const UInt8 kAmdLogPspPatched[] = {0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66,
0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90,
0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x90};
126 changes: 97 additions & 29 deletions NootRX/X6000FB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,14 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s
{"__ZN24AMDRadeonX6000_AmdLogger15initWithPciInfoEP11IOPCIDevice", wrapInitWithPciInfo,
this->orgInitWithPciInfo},
{"__ZN34AMDRadeonX6000_AmdRadeonController10doGPUPanicEPKcz", wrapDoGPUPanic},
{"_dm_logger_write", wrapDmLoggerWrite, kDmLoggerWritePattern},
};
PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "X6000FB",
"Failed to route debug symbols");
}

if (checkKernelArgument("-NRXDMLogger")) {
RouteRequestPlus request {"_dm_logger_write", wrapDmLoggerWrite, kDmLoggerWritePattern};
PANIC_COND(!request.route(patcher, id, slide, size), "X6000FB", "Failed to route dm_logger_write");
}

PANIC_COND(MachInfo::setKernelWriting(true, KernelPatcher::kernelWriteLock) != KERN_SUCCESS, "X6000FB",
"Failed to enable kernel writing");

*orgAsicCapsTable = {
.familyId = AMDGPU_FAMILY_NAVI,
.deviceId = NootRXMain::callback->deviceID,
Expand All @@ -76,6 +71,37 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s
MachInfo::setKernelWriting(false, KernelPatcher::kernelWriteLock);
DBGLOG("X6000FB", "Applied DDI Caps patches");

if (ADDPR(debugEnabled)) {
auto *logEnableMaskMinors =
patcher.solveSymbol<void *>(id, "__ZN14AmdDalDmLogger19LogEnableMaskMinorsE", slide, size);
patcher.clearError();

if (logEnableMaskMinors == nullptr) {
size_t offset = 0;
PANIC_COND(!KernelPatcher::findPattern(kDalDmLoggerShouldLogPartialPattern,
kDalDmLoggerShouldLogPartialPatternMask, arrsize(kDalDmLoggerShouldLogPartialPattern),
reinterpret_cast<const void *>(slide), size, &offset),
"X6000FB", "Failed to solve LogEnableMaskMinors");
auto *instAddr = reinterpret_cast<UInt8 *>(slide + offset);
// inst + instSize + imm32 = addr
logEnableMaskMinors = instAddr + 7 + *reinterpret_cast<SInt32 *>(instAddr + 3);
}

PANIC_COND(MachInfo::setKernelWriting(true, KernelPatcher::kernelWriteLock) != KERN_SUCCESS, "X6000FB",
"Failed to enable kernel writing");
memset(logEnableMaskMinors, 0xFF, 0x80); // Enable all DalDmLogger logs
MachInfo::setKernelWriting(false, KernelPatcher::kernelWriteLock);

// Enable all Display Core and BiosParserHelper logs
const LookupPatchPlus patches[] = {
{&kextRadeonX6000Framebuffer, kInitPopulateDcInitDataOriginal, kInitPopulateDcInitDataPatched, 1},
{&kextRadeonX6000Framebuffer, kBiosParserHelperInitWithDataOriginal,
kBiosParserHelperInitWithDataPatched, 1},
};
PANIC_COND(!LookupPatchPlus::applyAll(patcher, patches, slide, size), "X6000FB",
"Failed to apply debug enablement patches");
}

return true;
}

Expand All @@ -84,32 +110,74 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s

UInt16 X6000FB::wrapGetEnumeratedRevision() { return NootRXMain::callback->enumRevision; }

bool X6000FB::wrapInitWithPciInfo(void *that, void *param1) {
auto ret = FunctionCast(wrapInitWithPciInfo, callback->orgInitWithPciInfo)(that, param1);
// Hack AMDRadeonX6000_AmdLogger to log everything
getMember<UInt64>(that, 0x28) = ~0ULL;
getMember<UInt32>(that, 0x30) = 0xFF;
bool X6000FB::wrapInitWithPciInfo(void *that, void *pciDevice) {
auto ret = FunctionCast(wrapInitWithPciInfo, callback->orgInitWithPciInfo)(that, pciDevice);
getMember<UInt64>(that, 0x28) = 0xFFFFFFFFFFFFFFFF; // Enable all log types
getMember<UInt32>(that, 0x30) = 0xFF; // Enable all log severities
return ret;
}

void X6000FB::wrapDoGPUPanic() {
DBGLOG("X6000FB", "doGPUPanic << ()");
while (true) { IOSleep(3600000); }
void X6000FB::wrapDoGPUPanic(void *, char const *fmt, ...) {
va_list va;
va_start(va, fmt);
auto *buf = static_cast<char *>(IOMalloc(1000));
bzero(buf, 1000);
vsnprintf(buf, 1000, fmt, va);
va_end(va);

DBGLOG("X6000FB", "doGPUPanic: %s", buf);
IOSleep(10000);
panic("%s", buf);
}

constexpr static const char *LogTypes[] = {"Error", "Warning", "Debug", "DC_Interface", "DTN", "Surface", "HW_Hotplug",
"HW_LKTN", "HW_Mode", "HW_Resume", "HW_Audio", "HW_HPDIRQ", "MST", "Scaler", "BIOS", "BWCalcs", "BWValidation",
"I2C_AUX", "Sync", "Backlight", "Override", "Edid", "DP_Caps", "Resource", "DML", "Mode", "Detect", "LKTN",
"LinkLoss", "Underflow", "InterfaceTrace", "PerfTrace", "DisplayStats"};

void X6000FB::wrapDmLoggerWrite(void *, UInt32 logType, char *fmt, ...) {
va_list args;
va_start(args, fmt);
auto *ns = new char[0x10000];
bzero(ns, 0x10000);
vsnprintf(ns, 0x10000, fmt, args);
va_end(args);
const char *logTypeStr = logType < arrsize(LogTypes) ? LogTypes[logType] : "Info";
kprintf("[%s] %s", logTypeStr, ns);
delete[] ns;
constexpr static const char *LogTypes[] = {
"Error",
"Warning",
"Debug",
"DC_Interface",
"DTN",
"Surface",
"HW_Hotplug",
"HW_LKTN",
"HW_Mode",
"HW_Resume",
"HW_Audio",
"HW_HPDIRQ",
"MST",
"Scaler",
"BIOS",
"BWCalcs",
"BWValidation",
"I2C_AUX",
"Sync",
"Backlight",
"Override",
"Edid",
"DP_Caps",
"Resource",
"DML",
"Mode",
"Detect",
"LKTN",
"LinkLoss",
"Underflow",
"InterfaceTrace",
"PerfTrace",
"DisplayStats",
};

// Needed to prevent stack overflow
void X6000FB::wrapDmLoggerWrite(void *, const UInt32 logType, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
auto *message = static_cast<char *>(IOMalloc(0x1000));
vsnprintf(message, 0x1000, fmt, va);
va_end(va);
auto *epilogue = message[strnlen(message, 0x1000) - 1] == '\n' ? "" : "\n";
if (logType < arrsize(LogTypes)) {
kprintf("[%s]\t%s%s", LogTypes[logType], message, epilogue);
} else {
kprintf("%s%s", message, epilogue);
}
IOFree(message, 0x1000);
}
21 changes: 18 additions & 3 deletions NootRX/X6000FB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class X6000FB {
mach_vm_address_t orgInitWithPciInfo {0};

static UInt16 wrapGetEnumeratedRevision();
static bool wrapInitWithPciInfo(void *that, void *param1);
static void wrapDoGPUPanic();
static void wrapDmLoggerWrite(void *dalLogger, UInt32 logType, char *fmt, ...);
static bool wrapInitWithPciInfo(void *that, void *pciDevice);
static void wrapDoGPUPanic(void *that, char const *fmt, ...);
static void wrapDmLoggerWrite(void *logger, const UInt32 logType, const char *fmt, ...);
};

//------ Patterns ------//
Expand All @@ -28,3 +28,18 @@ static const UInt8 kCailAsicCapsTablePattern[] = {0x6E, 0x00, 0x00, 0x00, 0x98,

static const UInt8 kDmLoggerWritePattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41, 0x54,
0x53, 0x48, 0x81, 0xEC, 0x88, 0x04, 0x00, 0x00};

static const UInt8 kDalDmLoggerShouldLogPartialPattern[] = {0x48, 0x8D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x04, 0x81,
0x0F, 0xA3, 0xD0, 0x0F, 0x92, 0xC0};
static const UInt8 kDalDmLoggerShouldLogPartialPatternMask[] = {0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

//------ Patches ------//

// Enable all Display Core logs
static const UInt8 kInitPopulateDcInitDataOriginal[] = {0x48, 0xB9, 0xDB, 0x1B, 0xFF, 0x7E, 0x10, 0x00, 0x00, 0x00};
static const UInt8 kInitPopulateDcInitDataPatched[] = {0x48, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Enable all AmdBiosParserHelper logs
static const UInt8 kBiosParserHelperInitWithDataOriginal[] = {0x08, 0xC7, 0x07, 0x01, 0x00, 0x00, 0x00};
static const UInt8 kBiosParserHelperInitWithDataPatched[] = {0x08, 0xC7, 0x07, 0xFF, 0x00, 0x00, 0x00};

0 comments on commit cfaaff1

Please sign in to comment.