5K iMac and UEFI: Fixing the dreaded output limitation
In today’s blog post, I wanted to discuss our recent adventure into trying to finally resolve 5k output support in UEFI on 5k iMacs with OpenCore Legacy Patcher!
Background Information
For those unfamiliar with the 5k iMac situation, I’ll try to best summarize here.
With the 2014 5k iMac, Apple implemented a semi-custom dual DisplayPort 1.2 Display Controller to drive a 5k screen. However, due to how this was implemented, Apple knew they needed to be careful with how non-Apple controlled environments reacted with the display.
So their solution was fairly simple: when the machine boots up, Apple’s firmware will render the Boot Picker in 5120x2880 via this dual DP stream. However if at any point a non-Apple UEFI entry is loaded, force the Display Controller into a compatibility mode.
This compatibility mode would try to emulate more generic displays by limiting itself to a single DisplayPort 1.2 stream and drive the display at 3840x2160:
Display | Resolution | Model | Vendor ID | Product ID | Supported Timings |
---|---|---|---|---|---|
Stock | 5120x2880 | APP Model ae03 | 1552 | 44547 | Missing from EDID (labeled dummy block) |
Compatibility Mode | 3840x2160 | APP Model ae01 | 1552 | 44545 | 3840x2160, 3200x1800, 2560x1440 |
At the time of release back in 2014, there was no solution to re-enabling the dual DisplayPort stream after booting. Thus users booting Windows or Linux had 5k output out of their reach, as well as users of boot managers such as GRUB.
Affected Models
Originally I had believed this issue to be limited to only 2014-2016 iMacs, however, upon closer inspection of IORegistry dumps of new iMacs we can see this issue affects all 5k iMac models not support Display Stream Compression (ie. all pre-2020 iMacs)
Looking at iMacPro1,1’s IORegistry dump (IORegistryExplorer), we can see that there are 6 total framebuffers present:
Here we see that both ATY,Japura@0
and ATY,Japura@1
are being used to drive the 5k Display. A further breakdown of the framebuffers for those interested:
Framebuffer | Display Type | Connector Type | Connector Type (Hex) |
---|---|---|---|
ATY,Japura@0 | Internal LCD | LVDS | 0x2 |
ATY,Japura@1 | Internal LCD | LVDS | 0x2 |
ATY,Japura@2 | External Display (Thunderbolt Controller 1) | DisplayPort 1.2 | 0x400 |
ATY,Japura@3 | External Display (Thunderbolt Controller 1) | DisplayPort 1.2 | 0x400 |
ATY,Japura@4 | External Display (Thunderbolt Controller 2) | DisplayPort 1.2 | 0x400 |
ATY,Japura@5 | External Display (Thunderbolt Controller 2) | DisplayPort 1.2 | 0x400 |
Once we boot through an “unsupported” UEFI entry, we see macOS is rendered at 4k and IOService changes:
Framebuffer | Display Type | Connector Type | Connector Type (Hex) |
---|---|---|---|
ATY,Japura@0 | Internal LCD | LVDS | 0x2 |
ATY,Japura@1 | Empty | LVDS | 0x2 |
ATY,Japura@2 | External Display (Thunderbolt Controller 1) | DisplayPort 1.2 | 0x400 |
ATY,Japura@3 | External Display (Thunderbolt Controller 1) | DisplayPort 1.2 | 0x400 |
ATY,Japura@4 | External Display (Thunderbolt Controller 2) | DisplayPort 1.2 | 0x400 |
ATY,Japura@5 | External Display (Thunderbolt Controller 2) | DisplayPort 1.2 | 0x400 |
- Regarding the Thunderbolt 3 ports running at DisplayPort 1.2, this is an unfortunate limitation of the Alpine Ridge Thunderbolt controller used in the iMac Pro. The Vega 10 GPU shipped with the iMac Pro does officially support DisplayPort 1.4
Now with the iMac20,x series, this is the first iMac to be released with official support for Display Stream Compression (DSC) which would be required to run a 5k panel with 10bit color over a single cable. This is actually the exact same reason Apple couldn’t update iMac18,x or iMac19,x with a new single stream panel, as Displayport 1.4 by default does not support enough bandwidth to reach 10bit with 5k.
- DSC was first introduced with AMD’s Navi line, and currently only Navi and Apple Silicon GPUs support DSC in macOS.
Framebuffer | Display Type | Connector Type | Connector Type (Hex) |
---|---|---|---|
ATY,Keelback@0 | Internal LCD | LVDS | 0x2 |
ATY,Keelback@1 | External Display (Thunderbolt Controller 1) | DisplayPort 1.4 | 0x400 |
ATY,Keelback@2 | External Display (Thunderbolt Controller 1/2) | DisplayPort 1.4 | 0x400 |
ATY,Keelback@3 | External Display (Thunderbolt Controller 2) | DisplayPort 1.4 | 0x400 |
Interestingly enough it seems some AliExpress sellers are now offering single stream DisplayPort 1.4 DSC controller boards for the 5k iMac displays via the R1811 Driver Board.
Apple’s Solution
After some noticeable complaints online from users regarding Windows 5k support, Apple in late 2015 decided to release a BootCamp driver update that included a new AMD GPU Driver:
The main change Apple/AMD added with this driver was the ability to force the Display Controller back into the dual DisplayPort Stream (ae03 ID).
With this change, we can see a significant reduction in online discussion of Apple’s 4k shenanigans as the majority of users would no longer experience it. However, even with this new AMD driver, both Linux and 3rd party boot manager users were still out of luck.
Making our own Work-Around
Looking at the situation Apple has placed us, we really had 2 options to try and resolve this issue:
- Trick the firmware into thinking we’re only ever booting a “supported” environment
- Try to reset the Display Controller in OS back to a dual 5k Stream
The latter would require me to reverse and reimplement the mechanism employed by the Windows AMD driver which I knew would not be simple or quick. Thus the more straightforward option was to try and trick the firmware.
How Apple seemed to have designed the firmware’s entry detection was to check the signature of every UEFI application loaded. This means we cannot simply rename ourselves to boot.efi
and pray that the iMac would like us. Instead, we needed to find a way to report ourselves as Apple’s signature.
With the suggestion of vit9696, we have 2 realistic options:
- Chain-load via the legacy FileVault 2 implementation of OS X 10.9
- Chain-load via Apple’s Hardware Diagnostic Tools
After extensive testing, Apple’s Hardware Diagnostic Tools ended up being the winner!
The exact workaround used was fairly simple:
Apple’s Hardware Diagnostics is loaded by invoking /System/Library/CoreServices/.diagnostics/diags.efi
. From here, numerous other drivers are subsequently called to set up the environment. Drivers located in /System/Library/CoreServices/.diagnostics/Drivers/HardwareDrivers/
are loaded via an encrypted file buffer allowing us to hide OpenCore and still pass as a native Apple driver.
We specifically chose /System/Library/CoreServices/.diagnostics/Drivers/HardwareDrivers/Product.efi
to be our loader as it’s the first driver to be called by diags.efi
. From here, our secret Product.efi
calls EFI/OC/OpenCore.efi
present on the same partition and loads OpenCore in glorious 5k resolution!
From here, all is golden. I was able to load macOS Monterey on my unsupported 2014 5k iMac15,1 via OpenCore Legacy Patcher. Additionally, with Monterey and my AirPlay to Mac Patch, the iMac was able to be used as a 4k display!
Closing Thoughts
Having now worked through all this to finally get 5k output working, it’s a bit frustrating having to use such a hacky method of loading OpenCore with the firmware downgrading the display. However, the fact we’ve been able to resolve this greatly helps future development of OpenCore Legacy Patcher as well as potentially allowing Linux users to finally experience 5K natively. I’m excited to see whether the Linux community can use this to their advantage.
And big thank you to @turbomacs for greatly helping in this adventure by donating a 2014 5k iMac! Without their gracious donation, I wouldn’t be able to work on such a strange issue.