Contribute
Register

Thunderbolt 3 HOTSWAP work (Finally?)

Joined
Aug 17, 2017
Messages
196
Motherboard
Z370 AORUS Ultra Gaming
CPU
I7-8700K
Graphics
GTX 970
Mac
MacBook Pro
Mobile Phone
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?
 
Joined
May 31, 2016
Messages
682
Motherboard
Z170X-UD5 TH
CPU
i7-6700K
Graphics
GTX 1080
Mac
iMac, MacBook, MacBook Pro, Mac mini
Classic Mac
PowerBook, Quadra
Mobile Phone
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




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.
 
Joined
Sep 17, 2017
Messages
69
Motherboard
Gigabyte Z270X- Gaming 5
CPU
i7-i7700
Graphics
RX Vega 64
Mac
iMac
Can we expect MultiBeast implementation anytime soon or something?
 
Joined
Aug 17, 2017
Messages
196
Motherboard
Z370 AORUS Ultra Gaming
CPU
I7-8700K
Graphics
GTX 970
Mac
MacBook Pro
Mobile Phone
iOS
Hi @canyondust and @Robvas, I apologize for the absence. In light of the new discoveries, I move the whole discussion on this thread.
I hope will be helpful!
 
Joined
May 11, 2018
Messages
34
Motherboard
Z370 Gaming 7
CPU
i7-8700K
Graphics
RX 580
Mac
MacBook Pro, Mac Pro
Mobile Phone
iOS
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.
 
Joined
Aug 16, 2012
Messages
6
Motherboard
Gigabyte Aorus x299 Ultra Gaming 1.0
CPU
i7-7820X
Graphics
Radeon RX 580
Has anyone gotten this working on a Gigabyte Aorus x299 motherboard yet?
 
Top