Contribute
Register

Thunderbolt 3 HOTSWAP work (Finally?)

Status
Not open for further replies.
Joined
Aug 17, 2017
Messages
307
Motherboard
ASUS Prime X299 Edition 30
CPU
i9-10980XE
Graphics
RX 5700 XT
Mac
  1. MacBook Pro
Mobile Phone
  1. iOS
Ok, here we are!
After a long search I found something interesting and... a possible way to have Thunderbolt hotswap working!

I start this thread with the hope that finally we can create a definitive guide (or almost) to enable the thunderbolt hot swap.
If it works, it would be a turning point for the whole community!

Originally post by maleorderbride

This is a mini-guide to get Thunderbolt hotswap working. My SSDT is for an ASRock TB3 (JHL6540) card in my X299 motherboard, but I know this also works with the Gigabyte X99 Designare's built-in TB3 port.

Based on the TheRacerMaster's work, and remote.syst3m's idea to change the value of "PCIHotplugCapable", I have TB3 hotswap working. Thunderbolt does not show as loaded in System Profiler, and this is undoubtedly a bit of a hack, but it seems to work and it is quite easy to implement.

TheRacer Master's github work seems to be based on importing MacBookPro14,1 ACPI information. You can find some raw Darwin Dumps here from him that contain DSDTs, SSDTs, and IOreg.

Below is the seemingly relevant bit, pulled from TheRacerMaster's github, with only the "PCIHotplugCapable" value changed to enabled and a few values modified to fit my computer.

Code:
            Device (DSB0)
            {
                Name (_ADR, Zero)  // _ADR: Address
                Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                {
                    If (LNot (Arg2))
                    {
                        Return (Buffer (One)
                        {
                             0x03                                          
                        })
                    }

                    Return (Package (0x02)
                    {
                        "PCIHotplugCapable",
                        One
                    })
                }

I implemented this as an SSDT, but perhaps one could simply inject the single property via Clover arbitrary, or just the DSB0 device with that one property.



1. What you need:

IOregistryExplorer (or IOJones)

MaciASL (use Rehabman's patchmatic)

Thunderbolt working (just without hotswap)



2. Identify the TB device address

2.1 Open IOreg and find your thunderbolt device(s) by typing in "thunderbolt" in the search bar.



2.2. Take note of the address (PCI0.RP05 for me).



2.3. Now clear the thunderbolt search and switch to IOACPIPlane view on the top right of IOreg. Find that same address. You should see a few other entires under it, and make note of whatever does not begin with H (for X99), and any values for X299. In this case, mine are PXSX and SLT5. We are going to prevent these from loading by setting their STA value to Zero so that our devices load instead.



3. Modify stock SSDT

3.1 Download the attached base SSDT and replace any instances of PCI0.RP05 with your actual address. If you have multiple thunderbolt controllers then copy and modify accordingly.



3.2. Replace PXSX and SLT5 with your value(s) from IOACPIPlane view. You might only have one value, in which case you can delete the extra line from the stock SSDT.



That should be it! Reboot and open IOreg again. Look to see if you now have PCIHotplugCapable set to "True" on the right-hand side. If so, then it should be working.



4. Inject USB ports (not required for hotswap)

I also hardcoded the two USB 3.1 ports on my card to clear up some complaints during verbose startup. This was pulled from one of PikerAlpha's blog posts.



I don't think it matters which device you inject this into (DSB2,3,4), but I chose DSB2 based upon the address on my particular card (0x0002000) locatable in IOreg. If I had had 0x0003000 then I would have done DSB3, etc.



If you only have one TB3 port, then you only need HS01 and SSP1.



If you already have an XHC2 device, then name it XHC3, 4, or whatever is appropriate.

Code:
            Device (DSB2)
            {
                Name (_ADR, 0x00020000)  // _ADR: Address
                Device (XHC2)
                {
                    Name (_ADR, Zero)  // _ADR: Address
                    Device (RHUB)
                    {
                        Name (_ADR, Zero)  // _ADR: Address
                        Device (SSP1)
                        {
                            Name (_ADR, One)  // _ADR: Address
                            Name (_UPC, Package (0x04)  // _UPC: USB Port Capabilities
                            {
                                0xFF,
                                0x09,
                                Zero,
                                Zero
                            })
                            Name (_PLD, Package (0x01)  // _PLD: Physical Location of Device
                            {
                                Buffer (0x10)
                                {
                                    /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                    /* 0008 */  0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                                }
                            })
                            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                            {
                                If (LEqual (Arg2, Zero))
                                {
                                    Return (Buffer (One)
                                    {
                                         0x03                                          
                                    })
                                }

                                Return (Package (0x02)
                                {
                                    "UsbCPortNumber",
                                    One
                                })
                            }
                        }

                        Device (SSP2)
                        {
                            Name (_ADR, 0x02)  // _ADR: Address
                            Name (_UPC, Package (0x04)  // _UPC: USB Port Capabilities
                            {
                                0xFF,
                                0x09,
                                Zero,
                                Zero
                            })
                            Name (_PLD, Package (0x01)  // _PLD: Physical Location of Device
                            {
                                Buffer (0x10)
                                {
                                    /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                    /* 0008 */  0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                                }
                            })
                            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                            {
                                If (LEqual (Arg2, Zero))
                                {
                                    Return (Buffer (One)
                                    {
                                         0x03                                          
                                    })
                                }

                                Return (Package (0x02)
                                {
                                    "UsbCPortNumber",
                                    0x02
                                })
                            }
                        }

                        Device (HS01)
                        {
                            Name (_ADR, 0x03)  // _ADR: Address
                            Name (_UPC, Package (0x04)  // _UPC: USB Port Capabilities
                            {
                                0xFF,
                                0x09,
                                Zero,
                                Zero
                            })
                            Name (_PLD, Package (0x01)  // _PLD: Physical Location of Device
                            {
                                Buffer (0x10)
                                {
                                    /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                    /* 0008 */  0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                                }
                            })
                        }

                        Device (HS02)
                        {
                            Name (_ADR, 0x04)  // _ADR: Address
                            Name (_UPC, Package (0x04)  // _UPC: USB Port Capabilities
                            {
                                0xFF,
                                0x09,
                                Zero,
                                Zero
                            })
                            Name (_PLD, Package (0x01)  // _PLD: Physical Location of Device
                            {
                                Buffer (0x10)
                                {
                                    /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                    /* 0008 */  0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                                }
                            })
                        }
                    }
                }
            }


Unfortunately I do not understand much, I have never put my hand on an SSDT... but if someone is practical it could help us create a generic guide for everyone.
Any idea?
 
Ok, here we are!
After a long search I found something interesting and... a possible way to have Thunderbolt hotswap working!

I start this thread with the hope that finally we can create a definitive guide (or almost) to enable the thunderbolt hot swap.
If it works, it would be a turning point for the whole community!

Originally post by maleorderbride




Unfortunately I do not understand much, I have never put my hand on an SSDT... but if someone is practical it could help us create a generic guide for everyone.
Any idea?

Seems to me that it can be successful with Thunderbolt add in cards. Boards like my Z170X-UD5 TH would need a sophisticated ACPI path rename because the controller doesn’t show up as having a PCI address in the boot log. Beyond my coding skills.
 
Can we expect MultiBeast implementation anytime soon or something?
 
is this only working on x299 systems? I currently have a z370 gaming 7, and thunderbolt typically only works when I boot into windows 10 first with my UA Apollo already running then reboot into OSX.
 
Has anyone gotten this working on a Gigabyte Aorus x299 motherboard yet?
 
Status
Not open for further replies.
Back
Top