I'm working on an EFI driver to fix the PCIe 2.0 link rate issue. It's gotten a little out of hand - I added the pci ids database from pciutils to recreate the output of
pcitree.sh in EFI Shell. I'm currently working on adding code to search for hidden PCIe devices of Thunderbolt add-in cards. I would like the code to at least enable the USB of my GC-ALPINE RIDGE (to replace the startup.nsh method).
I'd be interested in testing if could get slot 4 to PCIe Gen 2.0 for my Titan-Ridge.
Attached is a test driver.
Try the release version.
Put FixPCIeLinkRate.efi on a EFI partition somewhere (or any partition that is formatted as MS-DOS - FAT). The partition I use is the one that
fs0:
would navigate me to in the EFI Shell.
Run the EFI Shell (rEFInd or RefindPlus or OpenCore).
Change the mode to the widest/tallest mode (type
mode
for a list of modes; I use
mode 320 84
on my 2560x1600 display).
Use the
cd
command to go to the directory containing the efi driver file.
Load the efi driver file like this:
load -nc FixPCIeLinkRate.efi
You'll see a list of your PCI devices with their max and current link rate/width. It will try to increase the link rate to the max for any device that appears to not by using their max.
The reason the load command is used is because I made it a EFI driver file instead of a EFI app - even though it doesn't add any protocols. Since it doesn't add any protocols, the -nc option is used to speed up the command (because no reconnecting of devices is required).
If you are satisfied with the result, you can move FixPCIeLinkRate.efi to the rEFInd or RefindPlus or OpenCore drivers folder or you can add a path to the driver in the Driver#### / DriverOrder boot variables (search for instructions elsewhere in the forum). I haven't tried these methods yet.
If there's an issue, you can try saving the output to a text file (you can only write files to FAT formatted partitions) like this:
load -nc FixPCIeLinkRate.efi > FixPCIeLinkRate.txt
The debug version is a lot more verbose - it log everything it does to the screen. If you have a problem with the release version, saving the output of the debug version to a text file may help to find where the problem might be in the code.
Here is the result for my MacPro3,1:
Code:
+[0000]
+-00:00.0 # g1x4 [8086:4003] [060000] Host bridge : Intel Corporation 5400 Chipset Memory Controller Hub
++00:01.0-[01-10] # g2x16 > g1x16 [8086:4021] [060400] PCI bridge (Normal decode) : Intel Corporation 5400 Chipset PCI Express Port 1
|`+01:00.0-[02-10] # g3x16 > g1x16 [10B5:8747] [060400] PCI bridge (Normal decode) : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
# g2x16 (updated parent)
# g3x16 > g2x16 (updated child)
| ++02:08.0-[03-08] # g3x8 > g3x4 [10B5:8747] [060400] PCI bridge (Normal decode) : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
| |`+03:00.0-[04-08] # g3x4 [8086:15EA] [060400] PCI bridge (Normal decode) : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
| | ++04:00.0-[05] # g1x4 [8086:15EA] [060400] PCI bridge (Normal decode) : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
| | |`-05:00.0 # g1x4 [8086:15EB] [088000] System peripheral : Intel Corporation JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018]
| | ++04:01.0-[06] # g1x4 [8086:15EA] [060400] PCI bridge (Normal decode) : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
| | ++04:02.0-[07] # g1x4 [8086:15EA] [060400] PCI bridge (Normal decode) : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
| | |`-07:00.0 # g1x4 [8086:15EC] [0C0330] USB controller (XHCI) : Intel Corporation JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018]
| | `+04:04.0-[08] # g1x4 [8086:15EA] [060400] PCI bridge (Normal decode) : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
| ++02:09.0-[09-0E] # g3x8 > g3x4 [10B5:8747] [060400] PCI bridge (Normal decode) : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
| |`+09:00.0-[0A-0E] # g3x4 [8086:1136] [060400] PCI bridge (Normal decode) : Intel Corporation Thunderbolt 4 Bridge [Maple Ridge 4C 2020]
| | ++0A:00.0-[0B] # g1x4 [8086:1136] [060400] PCI bridge (Normal decode) : Intel Corporation Thunderbolt 4 Bridge [Maple Ridge 4C 2020]
| | |`-0B:00.0 # g1x4 [8086:1137] [0C0340] USB controller (USB4 Host Interface) : Intel Corporation Thunderbolt 4 NHI [Maple Ridge 4C 2020]
| | ++0A:01.0-[0C] # g1x4 [8086:1136] [060400] PCI bridge (Normal decode) : Intel Corporation Thunderbolt 4 Bridge [Maple Ridge 4C 2020]
| | ++0A:02.0-[0D] # g1x4 > g0x4 [8086:1136] [060400] PCI bridge (Normal decode) : Intel Corporation Thunderbolt 4 Bridge [Maple Ridge 4C 2020]
| | |`-0D:00.0 # g1x4 [8086:1138] [0C0330] USB controller (XHCI) : Intel Corporation Thunderbolt 4 USB Controller [Maple Ridge 4C 2020]
| | `+0A:03.0-[0E] # g1x4 [8086:1136] [060400] PCI bridge (Normal decode) : Intel Corporation Thunderbolt 4 Bridge [Maple Ridge 4C 2020]
| ++02:10.0-[0F] # g3x8 [10B5:8747] [060400] PCI bridge (Normal decode) : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
| |+-0F:00.0 # g3x16 > g3x8 [10DE:17C2] [030000] VGA compatible controller (VGA controller) : NVIDIA Corporation GM200 [GeForce GTX TITAN X]
| |`-0F:00.1 # g3x16 > g3x8 [10DE:0FB0] [040300] Audio device : NVIDIA Corporation GM200 High Definition Audio
| `+02:11.0-[10] # g3x8 > g3x4 [10B5:8747] [060400] PCI bridge (Normal decode) : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
| `+10:00.0-[00] # g3x4 [FFFF:FFFF] [060400] PCI bridge (Normal decode) : Illegal Vendor ID Device
| ++24:00.0-[00] # g1x4 [8086:1578] [060400] PCI bridge (Normal decode) : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
| |`-25:00.0 # g1x4 [8086:1577] [088000] System peripheral : Intel Corporation DSL6540 Thunderbolt 3 NHI [Alpine Ridge 4C 2015]
| ++24:01.0-[00] # g1x4 [8086:1578] [060400] PCI bridge (Normal decode) : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
| ++24:02.0-[00] # g1x4 [8086:1578] [060400] PCI bridge (Normal decode) : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
| |`-25:00.0 # g1x4 [8086:15B6] [0C0330] USB controller (XHCI) : Intel Corporation DSL6540 USB 3.1 Controller [Alpine Ridge]
| `+24:04.0-[00] # g1x4 [8086:1578] [060400] PCI bridge (Normal decode) : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
++00:05.0-[11] # g2x16 [8086:4025] [060400] PCI bridge (Normal decode) : Intel Corporation 5400 Chipset PCI Express Port 5
|+-11:00.0 # g2x16 [10DE:1180] [030000] VGA compatible controller (VGA controller) : NVIDIA Corporation GK104 [GeForce GTX 680]
|`-11:00.1 # g2x16 [10DE:0E0A] [040300] Audio device : NVIDIA Corporation GK104 HDMI Audio Controller
++00:09.0-[12-1A] # g2x4 > g1x4 [8086:4029] [060400] PCI bridge (Normal decode) : Intel Corporation 5400 Chipset PCI Express Port 9
|++12:00.0-[13-19] # g1x8 > g1x4 [8086:3500] [060400] PCI bridge (Normal decode) : Intel Corporation 6311ESB/6321ESB PCI Express Upstream Port
||++13:00.0-[14-17] # g1x4 [8086:3510] [060400] PCI bridge (Normal decode) : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E1
|||`+14:00.0-[15-17] # g2x4 > g1x4 [12D8:2308] [060400] PCI bridge (Normal decode) : Pericom Semiconductor Device
||| ++15:01.0-[16] # g2x2 [12D8:2308] [060400] PCI bridge (Normal decode) : Pericom Semiconductor Device
||| |`-16:00.0 # g2x2 [1B21:1242] [0C0330] USB controller (XHCI) : ASMedia Technology Inc. ASM1142 USB 3.1 Host Controller
||| `+15:02.0-[17] # g2x2 [12D8:2308] [060400] PCI bridge (Normal decode) : Pericom Semiconductor Device
||| `-17:00.0 # g2x2 [1B21:0625] [010601] SATA controller (AHCI 1.0) : ASMedia Technology Inc. Device
||++13:01.0-[18] # g1x4 > g1x1 [8086:3514] [060400] PCI bridge (Normal decode) : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E2
|||+-18:00.0 # g1x1 [125B:9100] [070002] Serial controller (16550) : Asix Electronics Corporation AX99100 PCIe to Multi I/O Controller
|||`-18:00.2 # g1x1 [125B:9100] [070002] Serial controller (16550) : Asix Electronics Corporation AX99100 PCIe to Multi I/O Controller
||`+13:02.0-[19] # g1x4 [8086:3518] [060400] PCI bridge (Normal decode) : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E3
|| +-19:00.0 # g1x4 [8086:1096] [020000] Ethernet controller : Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper)
|| `-19:00.1 # g1x4 [8086:1096] [020000] Ethernet controller : Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper)
|`+12:00.3-[1A] # g1x8 > g1x4 [8086:350C] [060400] PCI bridge (Normal decode) : Intel Corporation 6311ESB/6321ESB PCI Express to PCI-X Bridge
+-00:0F.0 # g0x0 [8086:402F] [088000] System peripheral : Intel Corporation 5400 Chipset QuickData Technology Device
+-00:10.0 # [8086:4030] [060000] Host bridge : Intel Corporation 5400 Chipset FSB Registers
+-00:10.1 # [8086:4030] [060000] Host bridge : Intel Corporation 5400 Chipset FSB Registers
+-00:10.2 # [8086:4030] [060000] Host bridge : Intel Corporation 5400 Chipset FSB Registers
+-00:10.3 # [8086:4030] [060000] Host bridge : Intel Corporation 5400 Chipset FSB Registers
+-00:10.4 # [8086:4030] [060000] Host bridge : Intel Corporation 5400 Chipset FSB Registers
+-00:11.0 # [8086:4031] [060000] Host bridge : Intel Corporation 5400 Chipset CE/SF Registers
+-00:15.0 # [8086:4035] [060000] Host bridge : Intel Corporation 5400 Chipset FBD Registers
+-00:15.1 # [8086:4035] [060000] Host bridge : Intel Corporation 5400 Chipset FBD Registers
+-00:16.0 # [8086:4036] [060000] Host bridge : Intel Corporation 5400 Chipset FBD Registers
+-00:16.1 # [8086:4036] [060000] Host bridge : Intel Corporation 5400 Chipset FBD Registers
+-00:1B.0 # g0x0 [8086:269A] [040300] Audio device : Intel Corporation 631xESB/632xESB High Definition Audio Controller
++00:1C.0-[1B] # g1x1 > g1x0 [8086:2690] [060400] PCI bridge (Normal decode) : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 1
++00:1C.1-[1C] # g1x1 > g1x0 [8086:2692] [060400] PCI bridge (Normal decode) : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 2
++00:1C.2-[1D-1E] # g1x1 [8086:2694] [060400] PCI bridge (Normal decode) : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 3
|`+1D:00.0-[1E] # g1x1 [104C:823E] [060400] PCI bridge (Normal decode) : Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express]
| `-1E:00.0 # [104C:823F] [0C0010] FireWire (IEEE 1394) (OHCI) : Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express]
++00:1C.3-[1F] # g1x1 [8086:2696] [060400] PCI bridge (Normal decode) : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 4
|`-1F:00.0 # g1x1 [14E4:4328] [028000] Network controller : Broadcom Inc. and subsidiaries BCM4321 802.11a/b/g/n (AirPort Extreme)
+-00:1D.0 # [8086:2688] [0C0300] USB controller (UHCI) : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #1
+-00:1D.1 # [8086:2689] [0C0300] USB controller (UHCI) : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #2
+-00:1D.2 # [8086:268A] [0C0300] USB controller (UHCI) : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #3
+-00:1D.3 # [8086:268B] [0C0300] USB controller (UHCI) : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #4
+-00:1D.7 # [8086:268C] [0C0320] USB controller (EHCI) : Intel Corporation 631xESB/632xESB/3100 Chipset EHCI USB2 Controller
++00:1E.0-[20] # [8086:244E] [060401] PCI bridge (Subtractive decode) : Intel Corporation 82801 PCI Bridge
+-00:1F.0 # [8086:2670] [060100] ISA bridge : Intel Corporation 631xESB/632xESB/3100 Chipset LPC Interface Controller
+-00:1F.1 # [8086:269E] [01018F] IDE interface (PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering) : Intel Corporation 631xESB/632xESB IDE Controller
+-00:1F.2 # [8086:2681] [010601] SATA controller (AHCI 1.0) : Intel Corporation 631xESB/632xESB SATA AHCI Controller
`-00:1F.3 # [8086:269B] [0C0500] SMBus : Intel Corporation 631xESB/632xESB/3100 Chipset SMBus Controller
load: Image fs0:\drivers\FixPCIeLinkRate.efi loaded at 79B7D000 - Success
There's a few things to notice here:
The driver is large (1.9 MB) because it includes the pci ids database (converted to C code).
The output is not as pretty as my pcitree.sh script. I had to use ASCII characters (+ + | ` -) because even though EFI supports unicode (UCS-2 which is similar to UTF-16) characters (┬ ├ │ └ ─), the EFI Shell's font doesn't include non-ASCII characters? Does the Shell included with Open Core have the same issue?
My Mac Pro has a Netstor NA255A connected to slot 2. The highest link rate shared by the parent root port (00:01.0 capable of gen 3) and the child device (01:00.0 capable of gen 2) is gen 2 which is greater than the current link rate of gen 1 so the code tries to set the link rate to gen 2. When link training completes, it shows the updated link rates of the parent and child. If the link rate didn't update then there may be an issue.
The Netstor contains an unmodified Nvidia Titan X (Maxwell) - I would like to make a driver that can make this work as a boot screen on MacPro3,1 even without RefindPlus or OpenCore.
The Netstor contains unmodified GC-TITAN RIDGE, ThunderboltEX 4, and GC-ALPINE RIDGE. The first two allow USB and Displayport Alt Mode. The GC-ALPINE RIDGE is hidden at boot - the parent device (02:11.0) has a secondary/subordinate bus (-[10]) that points to the GC-ALPINE RIDGE but the vendor and product ID are FFFF:FFFF so EFI doesn't enumerate the device. FixPCIeLinkRate.efi can detect it because only the vendor and product ID are FFFF. FixPCIeLinkRate.efi can read the other PCIe registers - if they are not FFFF then there's a device there (10:00.0-[00]). The upstream bridge of the GC-TITAN RIDGE has no secondary bus or subordinate bus (they are set to [00]). FixPCIeLinkRate.efi assigns buses in that case to search for children. The way the renumbering works is: it finds the largest range of unused buses (in my case, it's 21-FF since the last bus assigned is 20 for the non-existant children of 00:1E.0) and then renumbers the entire chain using those bus numbers:
Code:
┬[0000] ┬[0000]
└┬00:01.0-[01-10] └┬00:01.0-[21-FF]
└┬01:00.0-[02-10] └┬21:00.0-[22-FF]
└┬02:11.0-[10] └┬22:11.0-[23-FF]
└┬10:00.0-[00] └┬23:00.0-[24-FF]
Now it can detect the children on bus 24. After detecting the children, it restores the original bus numbers because there are other buses in this chain and EFI devices already using those buses. It might be bad if one of those devices contained the display or EFI partition - I should probably add a nvram variable to disable the search for children. To make the renumbering permanent, a method to destruct those devices and reenumerate would be required and I don't think that's doable in MacPro3,1 EFI? The renumbering of buses may be easier if the Thunderbolt add-in card is in a root port - but the same problem of other devices existing in the chain still remains for the GC-TITAN RIDGE and ThunderboltEX 4 case. The process of detecting children continues for each new bridge that doesn't have a secondary/subordinate bus assigned - so the next level of children will appear on bus 25. If they had children then they would all appear as bus 26. Of course, if they were properly enumerated, each would have a different bus number (i.e. only one child would have bus 25). Anyway, FixPCIeLinkRate.efi only shows the original bus numbers in the final output (except for the detected children at bus 24 and up).
I am currently adding code to unhide the GC-ALPINE RIDGE. macOS will then be able to properly enumerate it and its immediate children (the XHCI and NHI), including the USB XHCI so I can connect USB devices to it. After that, I'll see if there's a way to make the Thunderbolt cards enable downstream Thunderbolt devices. Then the child scan should be able to find those PCIe devices. Currently, I have all the Thunderbolt code from edk2-platforms compiling but it's not all usable since it's dependant on certain motherboards (PCH registers, GPIO hardware, NVRAM variables, ACPI, etc.) and some of that code is not meant for the dxe stage. Adding code to earlier EFI stages (pei, etc.) requires firmware modification? For hackintoshes, people are adding Mac EFI Thunderbolt drivers to PC BIOS.... I won't be trying that.
Udate: FixPCIeLinkRate.efi source code on GitHub