ThunderboltReset
ThunderboltReset copied to clipboard
Hit "AppleThunderboltNHI::resetNHI: ARC already disabled" all the time
Hi,
I‘m on 10.15.6 (19G73)
I found __ZN27AppleThunderboltIntelPCIHAL15registerWrite32Ejj
and __ZN27AppleThunderboltIntelPCIHAL14registerRead32Ej
are actually doing the job but not
__ZN26AppleThunderboltGenericHAL15registerWrite32Ejj
and __ZN26AppleThunderboltGenericHAL14registerRead32Ej
The latter two seems to be place holders (disassembled and found empty or just return 0xffffffff)


After changing to the former two functions, I still can't get it work. Because of having no knowledge of ICM, I began blind combination trying for REG_FW_STS_ICM_EN_INVERT
, REG_FW_STS_ICM_EN
and REG_FW_STS_ICM_EN_CPU
.
Now my code look like this (symbol already replaced, omitted here for sake of length)
static int PatchedResetHNI(IOService *that) {
DBGLOG(MODULE_SHORT, "AppleThunderboltNHI::resetNHI called");
IOService *hal = that->getProvider();
uint32_t reg = HALRegisterRead32(hal, REG_FW_STS);
DBGLOG(MODULE_SHORT, "AppleThunderboltNHI::resetNHI: REG_FW_STS = 0x%08X", reg);
if (reg & REG_FW_STS_ICM_EN) {
DBGLOG(MODULE_SHORT, "ICM is running, disabling");
// DBGLOG(MODULE_SHORT, "Put ARC to wait for CIO reset event to happen");
// reg |= REG_FW_STS_CIO_RESET_REQ;
// HALRegisterWrite32(hal, REG_FW_STS, reg);
// IODelay(1000000);
// reg = HALRegisterRead32(hal, REG_FW_STS);
// DBGLOG(MODULE_SHORT, "current REG_FW_STS = 0x%08X", reg);
DBGLOG(MODULE_SHORT, "Force stopping ICM");
reg &= ~REG_FW_STS_CIO_RESET_REQ;
reg |= REG_FW_STS_ICM_EN_INVERT;
reg &= ~REG_FW_STS_ICM_EN;
reg &= ~REG_FW_STS_ICM_EN_CPU;
DBGLOG(MODULE_SHORT, "Writing REG_FW_STS = 0x%08X", reg);
HALRegisterWrite32(hal, REG_FW_STS, reg);
DBGLOG(MODULE_SHORT, "Sleep 2 seconds");
IODelay(2000000);
reg = HALRegisterRead32(hal, REG_FW_STS);
DBGLOG(MODULE_SHORT, "current REG_FW_STS = 0x%08X", reg);
DBGLOG(MODULE_SHORT, "ICM Disabled");
} else {
DBGLOG(MODULE_SHORT, "AppleThunderboltNHI::resetNHI: ARC already disabled, bypassing", reg);
}
return reinterpret_cast<ResetNHI_t>(OriginalResetNHI)(that);;
}
In my case, REG_FW_STS
is 0x800001A1
in the beginning, and it is 0xC00001A3
in the end.
It seems the flag REG_FW_STS_ICM_EN
is still 1, but I got logs like this:
18 21:39:06.994831-0400 0x73 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset init: @ (DBG) ThunderboltReset bootstrap DBG-100-2020-08-18
2020-08-18 21:39:06.996560-0400 0x73 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) start
2020-08-18 21:39:07.540575-0400 0x119 Default 0x0 0 0 kernel: (ThunderboltReset) ThunderboltWait: patch not ready yet, delaying thread
2020-08-18 21:39:14.210296-0400 0x119 Default 0x0 0 0 kernel: (ThunderboltReset) ThunderboltWait: patch not ready yet, delaying thread
2020-08-18 21:39:14.475119-0400 0x56d Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) found AppleThunderboltNHI
2020-08-18 21:39:15.228898-0400 0x119 Default 0x0 0 0 kernel: (ThunderboltReset) ThunderboltWait: patch completed, returning
2020-08-18 21:39:15.254342-0400 0x119 Default 0x0 0 0 kernel: (AppleThunderboltNHI) AppleThunderboltGenericHAL::probe
2020-08-18 21:39:15.267798-0400 0x119 Default 0x0 0 0 kernel: (AppleThunderboltNHI) AppleThunderboltGenericHAL::start
2020-08-18 21:39:17.116114-0400 0x755 Default 0x0 0 0 kernel: (AppleThunderboltNHI) AppleThunderboltNHIType3::setupPowerSavings - notification based runtime power management
2020-08-18 21:39:17.116213-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) AppleThunderboltNHI::resetNHI called
2020-08-18 21:39:17.116556-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) AppleThunderboltNHI::resetNHI: REG_FW_STS = 0xC00001A1
2020-08-18 21:39:17.131110-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) ICM is running, disabling
2020-08-18 21:39:17.131675-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Put ARC to wait for CIO reset event to happen
2020-08-18 21:39:18.133902-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Force stopping ICM
2020-08-18 21:39:18.136387-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Writing REG_FW_STS = 0xC00001A2
2020-08-18 21:39:18.136916-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Sleep 1 seconds
2020-08-18 21:39:19.137467-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) ICM Disabled
2020-08-18 21:39:19.138088-0400 0x755 Default 0x0 0 0 kernel: (AppleThunderboltNHI) Thunderbolt 255 PCI - LS=0x7043 LC=0x0040 SS=0x0140 SC=0x0008 PMCSR=0x0000 RT=0xffffffff NLRT=0xffffffff LWRT=0xffffffff PRRT=0xffffffff TRT=0x0000 TNLRT=0x0000 TLWRT=0x0000 TPRRT=0x0000 TLUP=0x0001
2020-08-18 21:39:19.138130-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) AppleThunderboltNHI::resetNHI called
2020-08-18 21:39:19.138147-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) AppleThunderboltNHI::resetNHI: REG_FW_STS = 0xC00001A3
2020-08-18 21:39:19.138151-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) ICM is running, disabling
2020-08-18 21:39:19.138153-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Put ARC to wait for CIO reset event to happen
2020-08-18 21:39:20.139122-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Force stopping ICM
2020-08-18 21:39:20.139125-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Writing REG_FW_STS = 0xC00001A2
2020-08-18 21:39:20.139130-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) Sleep 1 seconds
2020-08-18 21:39:20.820212-0400 0x755 Default 0x0 0 0 kernel: (Lilu) ThunderboltReset tbr: @ (DBG) ICM Disabled
2020-08-18 21:39:23.354631-0400 0x9e0 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltEEPROM::getDROM - Error getting DROM from I/O Registry (0xe00002be)
2020-08-18 21:40:05.220885-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltController::configReadDWord - ERROR: synchronous call on workloop thread.
2020-08-18 21:40:05.220905-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltController::configReadDWord - ERROR: synchronous call on workloop thread.
2020-08-18 21:40:05.220939-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x0)::listenerCallback - Thunderbolt HPD packet for route = 0x0 port = 1 unplug = 1
2020-08-18 21:40:09.827204-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x0)::listenerCallback - Thunderbolt HPD packet for route = 0x0 port = 1 unplug = 0
2020-08-18 21:40:09.832535-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x0)::listenerCallback - Thunderbolt HPD packet for route = 0x0 port = 2 unplug = 0
2020-08-18 21:40:09.840319-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x1)::listenerCallback - Thunderbolt HPD packet for route = 0x1 port = 9 unplug = 0
2020-08-18 21:40:09.840409-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x1)::listenerCallback - Thunderbolt HPD packet for route = 0x1 port = 2 unplug = 0
2020-08-18 21:40:09.840512-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x1)::listenerCallback - Thunderbolt HPD packet for route = 0x1 port = 10 unplug = 0
2020-08-18 21:40:10.316879-0400 0x756 Default 0x0 0 0 kernel: (IOThunderboltFamily) IOThunderboltSwitch<0x0>(0x1)::listenerCallback - Thunderbolt HPD packet for route = 0x1 port = 0 unplug = 0
The IOThunderboltFamily
logs occurs when I unplug and plug the thunderbolt cable, but I won't get any log from IOThunderboltFamily
in other code combinations, and every log except IOThunderboltEEPROM::getDROM - Error getting DROM from I/O Registry (0xe00002be)
can be found in my MacBook as well, which is a good sign I suppose.
I tried to patch IOThunderboltEEPROM::getDROM
to return without any error, basically just patching this
jz
to nop + jmp
, and the log changed to
(IOThunderboltFamily) IOThunderboltSwitchType3(0x0)::readEEPROMInternal - No DROM found. Using default Type 2.1 DROM.
(IOThunderboltFamily) IOThunderboltSwitchType3(0x1)::readEEPROMInternal - No DROM found. Using default Type 2.1 DROM.
And in this case, thunderbolt doesn't work even on startup.
I'm running out of clues now, any help would be appreciated!