>> A complex but much better solution
In order to avoid such issues, we need a smarter way to solve this problem. Recall that the first framebuffer port of 0x3E9B0000
has a type of LVDS, indicating that port 0 is an internal display. Therefore, a better solution is to write the custom link rate value if and only if the graphics driver is reading DPCD of the built-in display. In other words, we only apply the fix if and only if the current framebuffer number is 0. This is doable because the field at 0x1dc
in a framebuffer instance exactly represents the port number. Although this solution introduces an if-else statement (a comparison and a conditional jump in assembly), it has no negative impact on any externally connected displays.
//
// [Better Solution]
//
// Assembly code of conditionally setting a custom maximum link rate value to the `dpcd_caps` buffer
// @Author: FireWolf
//
cmpl $0x0, 0x1dc(%r12) // 9 bytes if ( (*(UInt32*) framebuffer->field_0x1dc) != 0 )
jne loc_8db1 // 2 bytes then start to verify the current link rate value
movb $0x14, -0x3F(%rbp) // 4 bytes else dpcd_caps->maxLinkRate = 0x14
As a rule of thumb, we need to find a place where the probability of register allocations being changed in future releases is relatively slow and global variables or constants (e.g. string literal) that highly depend on the offset are not referenced. A good place for the patch above is where the driver prints the OUI information of a display before starting to verify the link rate. Now let's take a look at what the assembly code looks like after the patch is applied.
//
// Assembly code after the patch is applied
//
008d9d xorl %eax, %eax
008d9f movq %r14, %rdi // arg0: "[IGFB][INFO ] %X %X %X %X \\n"
008da2 cmpl $0x0, 0x1dc(%r12) // **NEW:** Check the framebuffer port number
008dab jne loc_8db1 // **NEW:** If not 0, then jump to 0x8db1
008dad movb $0x14, var_3F(%rbp) // **NEW:** Else write the custom link rate
// loc_8db1: (Print the config version and verify the link rate)
008db1 movl 0x1dc(%r12), %esi // arg1: %rsi = framebuffer->field_0x1dc (fb port number)
008db9 movzxb 0x2386(%r12), %edx // arg2: %rdx = framebuffer->field_0x2386 ([1].4)
008dc2 movzxb 0x2385(%r12), %ecx // arg3: %rcx = framebuffer->field_0x2385 (1.[4])
008dcb leaq aIgfbinfoFbdDis, %rdi // arg0: %rdi =
"[IGFB][INFO ] FB%d: Display port config ver is %d.%d\\n"
008dd2 xorl %eax, %eax
008dd4 call _kprintf // Print to the kernel logs
008dd9 movb var_3F(%rbp), %al // %rax = dpcd_caps->maxLinkRate (dpcd_caps[1])
008ddc cmpb $0x13, %al // -> Start to verify the link rate
008dde jg loc_8df5 // -> Handle each case of link rate
For laptops with a built-in 4K display, I would recommend to use 0x14 (HBR2, 5.4 Gbps) as the maximum link rate.
For laptops with a built-in 1080p display, I would recommend to use 0x0A (HBR, 2.7 Gbps) instead.
If those values don't work on your devices, you may want to try 0x06 (RBR, 1.62 Gbps) and 0x1E (HBR3, 8.4 Gbps) instead.
In other words, you just replace the last two bytes C1 14
with C1 06
or C1 1E
accordingly.
Clover KextsToPatch [Binary]
Supported OS: macOS Mojave 10.14, 10.14.1, 10.14.2
Info: Set the maximum link rate in DPCD buffer to 0x14 (HBR2) for laptops with 4K display
Name: AppleIntelCFLGraphicsFramebuffer
Find: E8 00 00 00 00 48 83 C3 04 48 83 FB 08 72 D0
Repl: 41 83 BC 24 DC 01 00 00 00 75 04 C6 45 C1 14
Info: Set the maximum link rate in DPCD buffer to 0x0A (HBR) for laptops with 1080p or below display
Name: AppleIntelCFLGraphicsFramebuffer
Find: E8 00 00 00 00 48 83 C3 04 48 83 FB 08 72 D0
Repl: 41 83 BC 24 DC 01 00 00 00 75 04 C6 45 C1 0A
Clover KextsToPatch [Property List]
Supported OS: macOS Mojave 10.14, 10.14.1, 10.14.2
<key>KextsToPatch</key>
<array>
<dict>
<key>Comment</key>
<string>Set the maximum link rate in DPCD buffer to 0x14 (HBR2) for laptops with 4K display (by FireWolf)</string>
<key>Disabled</key>
<false/>
<key>Find</key>
<data>
6AAAAABIg8MESIP7CHLQ
</data>
<key>InfoPlistPatch</key>
<false/>
<key>Name</key>
<string>AppleIntelCFLGraphicsFramebuffer</string>
<key>Replace</key>
<data>
QYO8JNwBAAAAdQTGRcEU
</data>
</dict>
<dict>
<key>Comment</key>
<string>Set the maximum link rate in DPCD buffer to 0x0A (HBR) for laptops with 1080p or below display (by FireWolf)</string>
<key>Disabled</key>
<false/>
<key>Find</key>
<data>
6AAAAABIg8MESIP7CHLQ
</data>
<key>InfoPlistPatch</key>
<false/>
<key>Name</key>
<string>AppleIntelCFLGraphicsFramebuffer</string>
<key>Replace</key>
<data>
QYO8JNwBAAAAdQTGRcEK
</data>
</dict>
</array>