I'm not so concerned about that part just yet; I can't get it to respond on hotplug correctly again. I've been looking through Apple's implementation and I've found that Apple's Thunderbolt related _GPE (_L55) calls stuff like "GGII" and "SGII" with what looks like some sort of delay, before calling "AMPE" (AMPE simply Notifies NHI0 with 0, which is a Bus check). Note: CMPE is what Apple makes non-Darwin OSes call instead, which notifies PEG1 (RP15 in our case) with a bus check instead of specifically NHI0.
Here's the GPE:
Code:
Method (_L55, 0, NotSerialized) // _Lxx: Level-Triggered GPE
{
If (!OSDW ())
{
If ((\_SB.PCI0.PEG1.POC0 == One))
{
Return (Zero)
}
Sleep (0x0190)
If ((\_SB.PCI0.PEG1.WTLT () == One))
{
\_SB.PCI0.PEG1.ICMS ()
}
Else
{
\_SB.SGOV (0x01070004, Zero, \_SB.SGDO (0x01070004), If (\_SB.PCI0.PEG1.UPMB)
{
\_SB.PCI0.PEG1.UPMB = Zero
Sleep (One)
})
}
Else
{
}
\_SB.PCI0.PEG1.CMPE ()
}
Else
{
If ((\_SB.GGII == 0x01070015))
{
One
\_SB.SGII (0x01070015, Zero)
}
Else
{
\_SB.SGII (0x01070015, One)
}
\_SB.PCI0.PEG1.UPSB.AMPE ()
}
}
AMPE is on UPSB
Code:
Method (AMPE, 0, Serialized)
{
Notify (\_SB.PCI0.PEG1.UPSB.DSB0.NHI0, Zero)
}
Could that be it?
Alternatively, I've found in AppleThunderboltNHI that the only TB3 TypeC ACPI methods that actually exist are:
SXFP
MUST
XRST
RTPC
TRPE
These are all on NHI0 in ACPI.
The rest in the kext (XRIN, XRIL, others) I know are for TB1 & TB2 ports. SXFP I can't tell what it does (no idea what SGOV and SGDO are), but it used to be a force-power method:
Code:
Method (SXFP, 1, Serialized) //Don't think this actually does anything
{
If ((Arg0 == Zero))
{
If ((GGDV == 0x01070007))
{
One
SGOV (0x01070007, Zero, SGDO (0x01070007), Sleep (0x64))
}
SGOV (0x01070004, Zero, SGDO (0x01070004))
}
}
MUST I don't know if we need to worry about (notifies XHC that it's a USB device instead of a TB device).
XRST looks like it does nothing. Nothing seems to call it from ACPI.
RTPC might be related to removing thunderbolt, though all it does is set the variable RTBT. Nothing seems to call it from ACPI.
TRPE is MASSIVE:
Code:
Method (TRPE, 2, Serialized)
{
If (OSDW ())
{
If ((Arg0 <= One))
{
If ((Arg0 == Zero))
{
\_SB.PCI0.PEG1.PUPD (Zero, 0x02)
\_SB.PCI0.PEG1.PSTA = 0x03
SGOV (0x01070004, Zero, SGDO (0x01070004), Else
{
Local0 = Zero
If (((GGOV == 0x01070004) && Zero))
{
(GGDV == 0x01070004)
Zero
\_SB.PCI0.PEG1.PSTA = Zero
While (One)
{
SGDI (0x01070004)
Local1 = Zero
Sleep (0x1E)
\_SB.PCI0.PEG1.PUPD (One, 0x02)
Local2 = (Timer + 0x00989680)
While ((Timer <= Local2))
{
If ((\_SB.PCI0.PEG1.LACR == Zero))
{
If ((\_SB.PCI0.PEG1.LTRN != One))
{
Break
}
}
ElseIf (((\_SB.PCI0.PEG1.LTRN != One) && (\_SB.PCI0.PEG1.LACT == One)))
{
Break
}
Sleep (0x0A)
}
Sleep (Arg1)
While ((Timer <= Local2))
{
If ((\_SB.PCI0.PEG1.UPSB.AVND != 0xFFFFFFFF))
{
Local1 = One
Break
}
Sleep (0x0A)
}
If ((Local1 == One))
{
MABT = One
Break
}
If ((Local0 == 0x04))
{
Return (Zero)
}
Local0++
SGOV (0x01070004, Zero, SGDO (0x01070004), Sleep (0x03E8))
}
If ((\_SB.PCI0.PEG1.CSPD != 0x03))
{
If ((\_SB.PCI0.PEG1.SSPD == 0x03))
{
If ((\_SB.PCI0.PEG1.UPSB.SSPD == 0x03))
{
If ((\_SB.PCI0.PEG1.TSPD != 0x03))
{
\_SB.PCI0.PEG1.TSPD = 0x03
}
If ((\_SB.PCI0.PEG1.UPSB.TSPD != 0x03))
{
\_SB.PCI0.PEG1.UPSB.TSPD = 0x03
}
\_SB.PCI0.PEG1.LRTN = One
Local2 = (Timer + 0x00989680)
While ((Timer <= Local2))
{
If ((\_SB.PCI0.PEG1.LACR == Zero))
{
If (((\_SB.PCI0.PEG1.LTRN != One) && (\_SB.PCI0.PEG1.UPSB.AVND != 0xFFFFFFFF)))
{
Local1 = One
Break
}
}
ElseIf ((((\_SB.PCI0.PEG1.LTRN != One) && (\_SB.PCI0.PEG1.LACT == One)) && (\_SB.PCI0.PEG1.UPSB.AVND != 0xFFFFFFFF)))
{
Local1 = One
Break
}
Sleep (0x0A)
}
}
}
}
}
})
}
}
}
Return (Zero)
}
But nothing calls it from ACPI. Would be nice if all we needed was just AMPE...
EDIT: I think the flow of control for Apple's drivers is something like this:
Plug in device --> GPE _L55 notifies NHI through AMPE --> NHI wakes up, driver checks bus. If not a TB device, driver calls MUST from ACPI (can drivers even do that?) --> USB takes over
If it IS a TB device, driver calls... TRPE, SXFP, XRST (RTPC is likely for removal). But I don't know which one yet or in what order.
I'm not sure how Dell is differentiating between a USB device and a TB device on the same port. Maybe it expects the OS to do that?