Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLS) work on mobile Coffee Lake platforms running macOS 13.4 or later #113

Merged
merged 23 commits into from Jun 10, 2023

Conversation

0xFireWolf
Copy link
Contributor

@0xFireWolf 0xFireWolf commented Jun 1, 2023

Abstract:

Apple has "accidentally" simplified the implementation of the functions, ReadRegister32 and WriteRegister32, in Coffee Lake's framebuffer driver shipped by macOS 13.4, so the compiler chose to inline invocations of those functions as many as possible. As a result, hwSetBacklight() no longer invokes WriteRegister32 to update backlight registers; instead it modifies the register value via mapped memory directly, making itself an inline helper. LightUpEDP() and hwSetPanelPower() that invoke hwSetBacklight() now have the definition of hwSetBacklight() embedded in themselves. As such, the WriteRegister32 hooks registered by the Backlight Registers Fix (BLR) and the Backlight Smoother (BLS) submodules no longer work. This PR adds a new patch submodule (BLT), as an alternative to BLR, that reverts the optimizations done by the compiler in aforementioned three functions, thus fixing the 3-minute dark screen issue and making BLS work properly again on Coffee Lake platforms running macOS 13.4.

Affected System Versions:

  • macOS Ventura 13.4 (22F66)
  • macOS Sonoma 14.0 DP1 (23A5257q)

Affected Users:

Users who have laptops using Coffee Lake's graphics driver and running macOS 13.4 and are experiencing the 3-minute dark screen issue should consider to enable this fix.

New Boot Argument and Device Property:

  • You can enable this new submodule by adding the boot argument -igfxblt or the device property enable-backlight-registers-alternative-fix to IGPU.
  • If you rely on the Backlight Registers Fix (BLR) on macOS 13.4, you now need to add -igfxblt instead of -igfxblr to the boot arguments.
  • If you wish to use the Backlight Smoother (BLS) on macOS 13.4, you need to add both -igfxblt and -igfxbls to the boot arguments.
  • If you want to use both BLR and BLS on macOS 13.4, you need to add both -igfxblt and -igfxbls to the boot arguments.

Related Issues:

Additional Notes:

  • Ice Lake platforms are not affected because WriteRegister32 are not inlined in backlight related functions.
  • Kaby Lake platforms may be affected, but it is hard to fix the write operation on the register 0xC8250 due to the space limit.

Let me know if there are any errors or typos I made in this PR.
Please take your time to review it. Thank you.

-- FireWolf


This PR has undergone a major revision on Jun 5. You can find the description of the deprecated Backlight Registers Supplemental Fix (BRS) submodule below, but please be aware that BRS will be removed from this PR before merged, and thus the boot argument -igfxbrs and the equivalent device property enable-backlight-registers-supplemental-fix will be removed as well.

Deprecated description of the Backlight Registers Supplemental Fix (BRS) submodule

Abstract:

Apple has "accidentally" simplified the implementation of the functions, ReadRegister32 and WriteRegister32, in Coffee Lake's framebuffer driver shipped by macOS 13.4, so the compiler chose to inline invocations of those functions as many as possible. As a result, hwSetBacklight() no longer invokes WriteRegister32 to update backlight registers; instead it modifies the register value via mapped memory directly, making itself an inline helper. LightUpEDP() and hwSetPanelPower() that invoke hwSetBacklight() now have the definition of hwSetBacklight() embedded in themselves. As such, the WriteRegister32 hooks registered by the Backlight Registers Fix (BLR) and the Backlight Smoother (BLS) submodules no longer work. This PR adds a new patch submodule (BRS) that reverts the optimizations done by the compiler in aforementioned three functions, thus making both BLR and BLS work properly on Coffee Lake platforms running macOS 13.4.

New Boot Argument and Device Property:

  • You can enable this new submodule by adding the boot argument -igfxbrs or the device property enable-backlight-registers-supplemental-fix to IGPU.
  • If you rely on the Backlight Registers Fix (BLR) on macOS 13.4, you need to add both -igfxblr and -igfxbrs to the boot arguments.
  • If you are using the Backlight Smoother (BLS) on macOS 13.4, you need to add both -igfxbls and -igfxbrs to the boot arguments.
  • If you are using both BLR and BLS, you need to add all three boot arguments.

Limitations:

  • This new submodule contains assembly patches specific to the Coffee Lake framebuffer driver on macOS 13.4. If Apple simplifies the implementation in macOS 13.5 or later again, I will provide the new set of patches or consider to automate this process.

Related Issues:

Additional Notes:

  • Ice Lake platforms are not affected because WriteRegister32 are not inlined in backlight related functions.
  • Kaby Lake platforms may be affected, but it is hard to fix the write operation on the register 0xC8250 due to the space limit.
  • So far, only BLR and BLS register hooks on WriterRegister32, but this new change in the driver to some extent makes these two submodules fragile.

Let me know if there are any errors or typos I made in this PR.
Please take your time to review it. Thank you.

-- FireWolf

Changelog.md Outdated Show resolved Hide resolved
@Edwardwich
Copy link

Edwardwich commented Jun 1, 2023

when I use -igfxbrs system always in reboot lop
CPU i5 8265u

…fore calling `hwSetBacklight()` in `hwSetPanelPower()`.
@0xFireWolf
Copy link
Contributor Author

when I use -igfxbrs system always in reboot lop CPU i5 8265u

Please try the latest version and see if the kernel panic still exists.

@ameenjuz
Copy link

ameenjuz commented Jun 1, 2023

when I use -igfxbrs system always in reboot lop CPU i5 8265u

Please try the latest version and see if the kernel panic still exists.

I think this latest commit fixed the problem
I don't get kernel panic anymore
Thanks good job

@0xFireWolf
Copy link
Contributor Author

I think this latest commit fixed the problem I don't get kernel panic anymore Thanks good job

I appreciate your quick confirmation.

@vit9696
Copy link
Collaborator

vit9696 commented Jun 1, 2023

Ouch, this looks nice functional wise, but we will run into so many issues maintaining this that I really would like to find some other approach or at least use some sort of pattern matching to recognise the patch areas. Do you have an idb for the driver, maybe I have some idea if I give it a look…

@0xFireWolf
Copy link
Contributor Author

Ouch, this looks nice functional wise, but we will run into so many issues maintaining this that I really would like to find some other approach or at least use some sort of pattern matching to recognise the patch areas. Do you have an idb for the driver, maybe I have some idea if I give it a look…

AppleIntelCFLGraphicsFramebuffer_134.i64.zip

Sure, here you are. Please take your time. I do feel that it is possible to automate the patch, but it would be complicated.

//
// Supplemental Patch 1: Use WriteRegister32() to modify the register `BXT_BLC_PWM_FREQ1` instead of modifying mapped memory directly
//
// Function: AppleIntelFramebufferController::hwSetBacklight()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppleIntelFramebufferController::hwSetBacklight is rather short, maybe it is more reasonable to solve the field offsets and simply rewrite the function ourselves?

  • We do not have Camelia, so Camelia backlight calls should not matter for us.
  • We have our own logic for setting backlight based on passed backlight level (a2 argument), so two other ifs and MMIO ops also do not matter for us.

What we are left with is:

  • mov [rbx+2E78h], r14d backlight level set in the end of the function.
  • mov rcx, [rbx+1A08h] MMIO space.

Perhaps do it the other way?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also be smarter and perform offset detection in dynamic.

For this you could:

  1. Allocate a 16K object A to then use it as a dummy AppleIntelFramebufferController.
  2. Fill the object with 32-bit 0x00000001 values all over.
  3. Allocate another 16K object B to then use it as a dummy memory space
  4. Fill first 0x500 64-bit values of A with pointers to (B - 0xC8254) + 8 * i for MMIO space.
  5. Disable CamelliaBase::SetDPCDBacklight by temporarily patching it out (e.g. C3).
  6. Execute AppleIntelFramebufferController::hwSetBacklight with object A and let's say pass 255.
  7. Find the 32-bit value 0x000000FF in object A, this will be your backlight level offset.
  8. Find the 32-bit value 0x000000FF in object B, this will be your MMIO base offset, which you should be able to reverse by applying the formula: offset - 4 - B_base.

Now you have both offsets you need, so you can just reimplement AppleIntelFramebufferController::hwSetBacklight.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppleIntelFramebufferController::hwSetBacklight is rather short, maybe it is more reasonable to solve the field offsets and simply rewrite the function ourselves?

I carefully revisited hwSetBacklight and its callers LightUpEDP and hwSetPanelPower, and I think that finding the offset of each required member field and rewriting hwSetBacklight is the right approach to this issue.

We have our own logic for setting backlight based on passed backlight level, so two other ifs and MMIO ops also do not matter for us.

Yes, we do have own logic for updating registers at 0xc8254 and 0xc8258, but I am not sure which two MMIO ops you referred to do not matter. Here is Apple's implementation and my thoughts are...

  • Operations related to Camellia can be removed from our implementation.
    • i.e., No need to resolve the member field at 0x2e60.
  • Operations related to checking whether the register address is valid can be removed.
    • i.e., No need to resolve the member field at 0x1d30.
  • Operations related to fetching the base address of the MMIO region can be removed, because we will invoke the original WriteRegister32() explicitly.
    • i.e., No need to resolve the member field at 0x1a08.
  • Using Apple's PWM frequency leads to the 3-minute dark screen, so our implementation will use the frequency set by the firmware and thus won't write to the frequency register at 0xc8254.
    • i.e., No need to resolve the member field at 0x2e84.
  • Apple's PWM frequency divider is hard coded to 0xFFFF and stores in the member field at 0x2e80, but there is no guarantee that the value remains the same forever.
    • i.e., Need to resolve the member field at 0x2e80.
  • hwSetPanelPower and LightUpEDP always invoke hwSetBacklight with the brightness value stored in the member field at 0x2e78, so it's weird that hwSetBacklight just stores the same value to that member field again, but I think it's better to keep this in our implementation.
    • i.e., Need to resolve the member field at 0x2e78.
IOReturn AppleIntelFramebufferController::hwSetBacklight(UInt32 brightness)
{
    // Guard: Check if Camellia is present
    // The member field at 0x2e60 has a type of `CamelliaBase*`
    if (this->field_0x2e60 != nullptr)
    {
        this->field_0x2e60->SetDPCDBacklight(brightness);
    }

    // Guard: Check whether the register address `0xc8254` is valid
    // Note that this check is implemented in `WriteRegister32()`
    // The member field at 0x1d30 stores the length of the MMIO region, 
    // initialized by `AppleIntelFramebufferController::start()`
    if (0xc8254 <= this->field_0x1d30 - 4)
    {
        // The member field at 0x1a08 stores the base address of the MMIO region
        // The member field at 0x2e84 stores Apple's PWM frequency which is 
        // either 0x56CE or 0x4571 depending upon whether the raw frequency is used
        // (i.e., whether the bit 8 is set in the register `SFUSE_STRAP` at 0xc2014)
        // Set the PWM frequency
        *reinterpret_cast<UInt32*>(this->field_0x1a08 + 0xc8254) = this->field_0x2e84;
    }

    // Guard: Check whether the register address `0xc8258` is valid
    if (0xc8258 <= this->field_0x1d30 - 4)
    {
        // The member field at 0x2e80 stores Apple's PWM frequency divider
        // which is set to 0xFFFF in `AppleIntelFramebufferController::getOSInformation()`
        // Set the new duty value
        *reinterpret_cast<UInt32*>(this->field_0x1a08 + 0xc8258) = this->field_0x2e84 * brightness / this->field_0x2e80;
    }

    // Store the new brightness level to the member field at 0x2e78
    this->field_0x2e78 = brightness;

    return kIOReturnSuccess;
}

Your proposed approach that uses dummy controller objects is really interesting, but I think it's better to disassemble hwSetBacklight(), identify the offsets of the divider and the brightness level and implement the backlight registers fix in our hwSetBacklight() wrapper. Now the problem lies in the caller site. I managed to disassemble those two callers and generate the assembly patch for each of them at runtime so that they will call hwSetBacklight() explicitly. I have added a new patch submodule to reflect the new changes and can confirm that it works on my machine properly. It would be great if you can review it and provide suggestions on making the new submodule easier to maintain in future. Once you approve the new changes, I will remove the supplemental fix from the WEG.

@Alectardy98
Copy link

thank you! this was exactly what i needed

@lifecom
Copy link

lifecom commented Jun 3, 2023

Hello. How I can convert it to kext?

…d generates assembly patch so that each function invokes `hwSetBacklight()` explicitly, providing an alternative solution to the backlight issue on Coffee Lake platforms running macOS 13.4.
@0xFireWolf 0xFireWolf changed the title Add a new submodule to make Backlight Registers Fix (BLR) and Backlight Smoother (BLR) work on macOS 13.4 Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLR) work on mobile Coffee Lake platforms running macOS 13.4 Jun 5, 2023
@0xFireWolf 0xFireWolf changed the title Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLR) work on mobile Coffee Lake platforms running macOS 13.4 Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLS) work on mobile Coffee Lake platforms running macOS 13.4 Jun 5, 2023
@0xFireWolf
Copy link
Contributor Author

I can confirm that WriteRegister32 and hwSetBacklight are inlined in the Coffee Lake framebuffer driver shipped by macOS Sonoma 14.0 DP1 as well. Will check if the submodule can identify the offsets correctly on the new system later.

@ameenjuz
Copy link

ameenjuz commented Jun 6, 2023

I can confirm that WriteRegister32 and hwSetBacklight are inlined in the Coffee Lake framebuffer driver shipped by macOS Sonoma 14.0 DP1 as well. Will check if the submodule can identify the offsets correctly on the new system later.

once again -igfxblt or -igfxblr break on macOS Sonoma 14 I can confirmed because I have running coffe lake graphics I m waiting 3 minute black screen during boot
please fix this

@0xFireWolf 0xFireWolf changed the title Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLS) work on mobile Coffee Lake platforms running macOS 13.4 Add a new submodule as an alternative to Backlight Registers Fix (BLR), fixing the 3-minute dark screen issue and making Backlight Smoother (BLS) work on mobile Coffee Lake platforms running macOS 13.4 or later Jun 6, 2023
@0xFireWolf
Copy link
Contributor Author

once again -igfxblt or -igfxblr break on macOS Sonoma 14 I can confirmed because I have running coffe lake graphics I m waiting 3 minute black screen during boot please fix this

@ameenjuz The new patch submodule can identify the offsets and generate the assembly patch for macOS 14.0, so I have removed the strict check of the current kernel version. Please give the latest version a try and see if it fixes the issue on macOS 14.0 properly.

@Edwardwich
Copy link

once again -igfxblt or -igfxblr break on macOS Sonoma 14 I can confirmed because I have running coffe lake graphics I m waiting 3 minute black screen during boot please fix this

@ameenjuz The new patch submodule can identify the offsets and generate the assembly patch for macOS 14.0, so I have removed the strict check of the current kernel version. Please give the latest version a try and see if it fixes the issue on macOS 14.0 properly.

It's not fix in CPU i5 8265u

@0xFireWolf
Copy link
Contributor Author

It's not fix in CPU i5 8265u

@Edwardwich If you are using the Kaby Lake graphics driver, then as clearly indicated in the main post, this submodule is NOT applicable to your laptop.

@Edwardwich
Copy link

Edwardwich commented Jun 6, 2023

It's not fix in CPU i5 8265u

@Edwardwich If you are using the Kaby Lake graphics driver, then as clearly indicated in the main post, this submodule is NOT applicable to your laptop.
its gpu patch :
Screenshot 2023-06-06 at 11 40 24
nvram :
Screenshot 2023-06-06 at 11 40 39

@narcyzzo
Copy link

narcyzzo commented Jun 6, 2023

tested on i5-8300h, new patch works without any issue, thanks

@mesh17
Copy link

mesh17 commented Jun 6, 2023

I can confirm that WriteRegister32 and hwSetBacklight are inlined in the Coffee Lake framebuffer driver shipped by macOS Sonoma 14.0 DP1 as well. Will check if the submodule can identify the offsets correctly on the new system later.

+1 Can confirm the new patch to be working on 9750h , had some issues with the 1st patch where the laptop panicked after sleep and restarted , it works perfectly now!
thankyou for the quick fix and support @0xFireWolf :)

Screenshot 2023-06-06 at 6 30 26 PM

@ameenjuz
Copy link

ameenjuz commented Jun 6, 2023

@0xFireWolf worked on macOS Sonoma 14 and macOS 13.5 Beta 2
when I use these boot arg -lilubetaall -wegbeta -igfxblt -igfxblr worked both of version 14 and 13.5

@0xFireWolf
Copy link
Contributor Author

@0xFireWolf worked on macOS Sonoma 14 and macOS 13.5 Beta 2 when I use these boot arg -lilubetaall -wegbeta -igfxblt -igfxblr worked both of version 14 and 13.5

macOS Ventura 13.5 DP1 and DP2 are not affected, so you only need -igfxblr.

@ameenjuz
Copy link

ameenjuz commented Jun 6, 2023

@0xFireWolf worked on macOS Sonoma 14 and macOS 13.5 Beta 2 when I use these boot arg -lilubetaall -wegbeta -igfxblt -igfxblr worked both of version 14 and 13.5

macOS Ventura 13.5 DP1 and DP2 are not affected, so you only need -igfxblr.
I know 13.5 beta 2 not affected
I have running dual boot I need both boot arg -igfxblt -igfxblr

@0xFireWolf
Copy link
Contributor Author

I know 13.5 beta 2 not affected
I have running dual boot I need both boot arg -igfxblt -igfxblr

I see. Thanks for testing the patch.

@StefanAlMare
Copy link

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

@0xFireWolf
Copy link
Contributor Author

The equivalent for -igfxbrs on DeviceProperties?

@StefanAlMare Search for "New Boot Argument and Device Property" in the main post.

@narcyzzo
Copy link

narcyzzo commented Jun 7, 2023

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

its not needed on this platform

@StefanAlMare
Copy link

StefanAlMare commented Jun 7, 2023

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

its not needed on this platform

Your opinion. Starting with certain beta Ventura I lost backlight the first 3 minutes until today when I compiled whatevergreen from https://github.com/0xFireWolf/WhateverGreen/tree/squashed and applied the DeviceProperties from this page. I'm now waiting for Whatevergreen-master with this submodule inside.

@narcyzzo
Copy link

narcyzzo commented Jun 7, 2023

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

its not needed on this platform

Your opinion. Starting with certain beta Ventura I lost backlight the first 3 minutes until today when I compiled whatevergreen from https://github.com/0xFireWolf/WhateverGreen/tree/squashed and applied the DeviceProperties from this page. I'm now waiting for Whatevergreen-master with this submodule inside.

interesting then i run Sonoma now without any issues without any BLR fixes for this CPU igpu

@StefanAlMare
Copy link

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

its not needed on this platform

Your opinion. Starting with certain beta Ventura I lost backlight the first 3 minutes until today when I compiled whatevergreen from https://github.com/0xFireWolf/WhateverGreen/tree/squashed and applied the DeviceProperties from this page. I'm now waiting for Whatevergreen-master with this submodule inside.

interesting then i run Sonoma now without any issues without any BLR fixes for this CPU igpu

Like you said, interesting! Please give me your IGPU config.

@ameenjuz
Copy link

ameenjuz commented Jun 7, 2023

interesting then i run Sonoma now without any issues without any BLR fixes for this CPU igpu

like you said,
share your experience what did you change/

@mietl
Copy link

mietl commented Jun 9, 2023

It works for i5-10210U, Sonoma, Dell Vostro 5490. The equivalent for -igfxbrs on DeviceProperties? Thank you!

its not needed on this platform

Your opinion. Starting with certain beta Ventura I lost backlight the first 3 minutes until today when I compiled whatevergreen from https://github.com/0xFireWolf/WhateverGreen/tree/squashed and applied the DeviceProperties from this page. I'm now waiting for Whatevergreen-master with this submodule inside.

interesting then i run Sonoma now without any issues without any BLR fixes for this CPU igpu

Like you said, interesting! Please give me your IGPU config.

Can you share the files you compiled? I am an outsider.

@0xFireWolf
Copy link
Contributor Author

Can you share the files you compiled? I am an outsider.

You can always find the latest version under each CI run of this PR. For example, you can download the kext (artifacts) at https://github.com/acidanthera/WhateverGreen/actions/runs/5192008217.

@mietl
Copy link

mietl commented Jun 9, 2023

Can you share the files you compiled? I am an outsider.

You can always find the latest version under each CI run of this PR. For example, you can download the kext (artifacts) at https://github.com/acidanthera/WhateverGreen/actions/runs/5192008217.

Thank you🙏.

@vit9696 vit9696 merged commit 70ade87 into acidanthera:master Jun 10, 2023
3 checks passed
@vit9696
Copy link
Collaborator

vit9696 commented Jun 10, 2023

This looks much better now. I am positive there may be ways to make it even more reliable, but for now let's see for how long it holds. Thanks!

@xlivans
Copy link

xlivans commented Jul 25, 2023

In version 13.5 pushed on July 25th, - igfxblt failed and - igfxblr returned to normal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet